DEV Community

Mirela Prifti for Effect

Posted on • Originally published at effect.website on

Effect 3.14 (Release)

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 )

Enter fullscreen mode Exit fullscreen mode

@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"))

Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

Option transpose apis

Effect.transposeMapOption

Applies an Effect on an Option and transposes the result.

  • If the Option is None, the resulting Effect will immediately succeed with a None value.
  • If the Option is Some, the effectful operation will be executed on the inner value, and its result wrapped in a Some.

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 }

Enter fullscreen mode Exit fullscreen mode

Top comments (0)