Lesson 04 of 6 in Effect, one function at a time
Feed a layer with Layer.provide
Feed one layer's output into another layer.
A layer builds a service. Layer.provide feeds one layer’s output into another layer that needs it, so the chain is wired in one place.
import { Context, Effect, Layer } from "effect";
class Clock extends Context.Service<Clock, { readonly now: () => number }>()(
"Clock",
) {}
class Logger extends Context.Service<
Logger,
{ readonly log: (line: string) => void }
>()("Logger") {}
const ClockLive = Layer.succeed(Clock, { now: () => Date.now() });
const LoggerLive = Layer.effect(
Logger,
Effect.gen(function* () {
const clock = yield* Clock;
return { log: (line: string) => console.log(clock.now(), line) };
}),
);
const AppLayer = LoggerLive.pipe(Layer.provide(ClockLive));
const program = Effect.gen(function* () {
const logger = yield* Logger;
logger.log("started");
});
Effect.runPromise(program.pipe(Effect.provide(AppLayer)));
Three things to notice:
Loggerneeds aClock, and the layer type says so.Layer.provide(ClockLive)satisfies that need and leavesLoggeras the output.- The program names only
Logger. It never seesClock.
If you forget the provide step, the compiler stops you before the program runs. That is the point of putting dependencies in the types.