Effect 3.14 has been released! This release includes a number of new features and improvements. Here’s a summary of what’s new:
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.
1 import { Completions } from "@effect/ai" 2 import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai" 3 import { FetchHttpClient } from "@effect/platform" 4 import { NodeRuntime } from "@effect/platform-node" 5 import { Config, Effect, Layer, LayerMap } from "effect" 6 7 // create the openai client layer 8 const OpenAiLayer = OpenAiClient.layerConfig({ 9 apiKey: Config.redacted("OPENAI_API_KEY") 10 }).pipe(Layer.provide(FetchHttpClient.layer)) 11 12 // create a service that wraps a LayerMap 13 class AiClients extends LayerMap.Service<AiClients>()("AiClients", { 14 // this LayerMap will provide the ai Completions service 15 provides: Completions.Completions, 16 17 // define the lookup function for the layer map 18 // 19 // The returned Layer will be used to provide the Completions service for the 20 // given model. 21 lookup: (model: OpenAiCompletions.Model) => 22 OpenAiCompletions.layer({ model }), 23 24 // If a layer is not used for a certain amount of time, it can be removed 25 idleTimeToLive: "5 seconds", 26 27 // Supply the dependencies for the layers in the LayerMap 28 dependencies: [OpenAiLayer] 29 }) {} 30 31 // usage 32 Effect.gen(function* () { 33 // access and use the generic Completions service 34 const ai = yield* Completions.Completions 35 const response = yield* ai.create("Hello, world!") 36 console.log(response.text) 37 }).pipe( 38 // use the AiClients service to provide a variant of the Completions service 39 AiClients.provide("gpt-4o"), 40 // provide the LayerMap service 41 Effect.provide(AiClients.Default), 42 NodeRuntime.runMain 43 ) @effect/rpc refactor
The @effect/rpc package has undergone a refactor to improve the ergonomics of the API, and to make it more modular.
To read more about the changes, take a look at the README.
Effect.linkSpanCurrent
Effect.linkSpanCurrent allows you to link a span to the current span in the context.
1 import { Effect } from "effect" 2 3 Effect.gen(function* () { 4 const childSpan = yield* Effect.makeSpan("linked") 5 // link the "linked" span to the "parent" span 6 yield* Effect.linkSpanCurrent(childSpan) 7 }).pipe(Effect.withSpan("parent")) Dual Runtime apis
All of the Runtime.run* apis from the Runtime module now have dual signatures.
1 import { Effect, Runtime } from "effect" 2 3 const program = Effect.log("Hello, World!") 4 5 // You can run the effect by passing all arguments 6 Runtime.runFork(Runtime.defaultRuntime, program) 7 8 // Or using partial application 9 Runtime.runFork(Runtime.defaultRuntime)(program) Option transpose apis
Effect.transposeMapOption
Applies an Effect on an Option and transposes the result.
- If the
OptionisNone, the resultingEffectwill immediately succeed with aNonevalue. - If the
OptionisSome, the effectful operation will be executed on the inner value, and its result wrapped in aSome.
1 import { Effect, Option, pipe } from "effect" 2 3 // ┌─── Effect<Option<number>, never, never>> 4 // ▼ 5 const noneResult = pipe( 6 Option.none(), 7 Effect.transposeMapOption(() => Effect.succeed(42)) // will not be executed 8 ) 9 console.log(Effect.runSync(noneResult)) 10 // Output: { _id: 'Option', _tag: 'None' } 11 12 // ┌─── Effect<Option<number>, never, never>> 13 // ▼ 14 const someSuccessResult = pipe( 15 Option.some(42), 16 Effect.transposeMapOption((value) => Effect.succeed(value * 2)) 17 ) 18 console.log(Effect.runSync(someSuccessResult)) 19 // Output: { _id: 'Option', _tag: 'Some', value: 84 }
Top comments (0)