Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/calm-spoons-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": minor
---

expose the Layer.MemoMap via Layer.CurrentMemoMap to the layers being built
57 changes: 57 additions & 0 deletions .changeset/tricky-apricots-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
"effect": minor
---

add LayerMap module

A `LayerMap` allows you to create a map of Layer's that can be used to
dynamically access resources based on a key.

Here is an example of how you can use a `LayerMap` to create a service that
provides access to multiple OpenAI completions services.

```ts
import { Completions } from "@effect/ai"
import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
import { FetchHttpClient } from "@effect/platform"
import { NodeRuntime } from "@effect/platform-node"
import { Config, Effect, Layer, LayerMap } from "effect"

// create the openai client layer
const OpenAiLayer = OpenAiClient.layerConfig({
apiKey: Config.redacted("OPENAI_API_KEY")
}).pipe(Layer.provide(FetchHttpClient.layer))

// create a service that wraps a LayerMap
class AiClients extends LayerMap.Service<AiClients>()("AiClients", {
// this LayerMap will provide the ai Completions service
provides: Completions.Completions,

// define the lookup function for the layer map
//
// The returned Layer will be used to provide the Completions service for the
// given model.
lookup: (model: OpenAiCompletions.Model) =>
OpenAiCompletions.layer({ model }),

// If a layer is not used for a certain amount of time, it can be removed
idleTimeToLive: "5 seconds",

// Supply the dependencies for the layers in the LayerMap
dependencies: [OpenAiLayer]
}) {}

// usage
Effect.gen(function* () {
// access and use the generic Completions service
const ai = yield* Completions.Completions
const response = yield* ai.create("Hello, world!")
console.log(response.text)
}).pipe(
// use the AiClients service to provide a variant of the Completions service
AiClients.provide("gpt-4o"),
// provide the LayerMap service
Effect.provide(AiClients.Default),
NodeRuntime.runMain
)
```
14 changes: 14 additions & 0 deletions packages/effect/src/Layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ export interface MemoMap {
) => Effect.Effect<Context.Context<ROut>, E, RIn>
}

/**
* @since 3.13.0
* @category models
*/
export interface CurrentMemoMap {
readonly _: unique symbol
}

/**
* @since 3.13.0
* @category models
*/
export const CurrentMemoMap: Context.Reference<CurrentMemoMap, MemoMap> = internal.CurrentMemoMap

/**
* Returns `true` if the specified value is a `Layer`, `false` otherwise.
*
Expand Down
Loading