Hoisting Dependencies from Service Methods to Layer

Is there any convenient way to hoist dependencies from service methods to the layer?

I have the following working example:

import { FileSystem } from "@effect/platform"
import { NodeFileSystem } from "@effect/platform-node"
import { Context, Effect, Layer } from "effect"

class Config extends Context.Tag("Config")<Config, { cacheDir: string }>() {}

class Logger extends Context.Tag("Logger")<Logger, { log: (msg: string) => void }>() {}

const lookup = (key: string) =>
  Effect.gen(function*() {
    const fs = yield* FileSystem.FileSystem
    const logger = yield* Logger
    logger.log("hello")
    const config = yield* Config
    return yield* fs.readFileString(`${config.cacheDir}/${key}`)
  })

class Cache extends Effect.Service<Cache>()("app/Cache", {
  effect: Effect.gen(function*() {
    const layer = Layer.mergeAll(
      Layer.succeed(Config, yield* Config),
      Layer.succeed(Logger, yield* Logger),
      Layer.succeed(FileSystem.FileSystem, yield* FileSystem.FileSystem)
    )
    return {
      lookup: (key: string) => lookup(key).pipe(Effect.provide(layer))
    } as const
  }),
  dependencies: [NodeFileSystem.layer]
}) {}


The premise is that the cache lookup function is defined outside of the layer. While it works, I'm sensing there might be another pattern or way to go about it

https://effect.website/play/#8a375f91e45e

Thanks!
Was this page helpful?