effect 3.13.12 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LayerMap/package.json +6 -0
- package/dist/cjs/Array.js +29 -2
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/DateTime.js +16 -1
- package/dist/cjs/DateTime.js.map +1 -1
- package/dist/cjs/Effect.js +45 -3
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js +35 -1
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/FiberSet.js +14 -2
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/HashMap.js +11 -1
- package/dist/cjs/HashMap.js.map +1 -1
- package/dist/cjs/Layer.js +6 -1
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/LayerMap.js +183 -0
- package/dist/cjs/LayerMap.js.map +1 -0
- package/dist/cjs/MutableHashMap.js +36 -4
- package/dist/cjs/MutableHashMap.js.map +1 -1
- package/dist/cjs/MutableRef.js.map +1 -1
- package/dist/cjs/Runtime.js.map +1 -1
- package/dist/cjs/TestClock.js +3 -2
- package/dist/cjs/TestClock.js.map +1 -1
- package/dist/cjs/Tracer.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/channel/channelExecutor.js +6 -1
- package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
- package/dist/cjs/internal/core-effect.js +13 -2
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/core.js +2 -1
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +3 -1
- package/dist/cjs/internal/dateTime.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +5 -0
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/hashMap.js +3 -1
- package/dist/cjs/internal/hashMap.js.map +1 -1
- package/dist/cjs/internal/layer.js +7 -3
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/rcMap.js +11 -1
- package/dist/cjs/internal/rcMap.js.map +1 -1
- package/dist/cjs/internal/runtime.js +21 -21
- package/dist/cjs/internal/runtime.js.map +1 -1
- package/dist/cjs/internal/tracer.js +6 -2
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Array.d.ts +58 -0
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/Data.d.ts +4 -4
- package/dist/dts/Data.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +15 -0
- package/dist/dts/DateTime.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +66 -0
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +30 -0
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/HashMap.d.ts +31 -0
- package/dist/dts/HashMap.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +12 -0
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/LayerMap.d.ts +242 -0
- package/dist/dts/LayerMap.d.ts.map +1 -0
- package/dist/dts/MutableHashMap.d.ts +22 -0
- package/dist/dts/MutableHashMap.d.ts.map +1 -1
- package/dist/dts/MutableRef.d.ts +1 -0
- package/dist/dts/MutableRef.d.ts.map +1 -1
- package/dist/dts/Runtime.d.ts +144 -10
- package/dist/dts/Runtime.d.ts.map +1 -1
- package/dist/dts/TestClock.d.ts +3 -2
- package/dist/dts/TestClock.d.ts.map +1 -1
- package/dist/dts/Tracer.d.ts +1 -0
- package/dist/dts/Tracer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/channel/channelExecutor.d.ts.map +1 -1
- package/dist/dts/internal/core-effect.d.ts.map +1 -1
- package/dist/dts/internal/layer.d.ts.map +1 -1
- package/dist/esm/Array.js +28 -1
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/DateTime.js +15 -0
- package/dist/esm/DateTime.js.map +1 -1
- package/dist/esm/Effect.js +42 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js +33 -0
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/FiberSet.js +13 -1
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/HashMap.js +10 -0
- package/dist/esm/HashMap.js.map +1 -1
- package/dist/esm/Layer.js +5 -0
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/LayerMap.js +172 -0
- package/dist/esm/LayerMap.js.map +1 -0
- package/dist/esm/MutableHashMap.js +33 -3
- package/dist/esm/MutableHashMap.js.map +1 -1
- package/dist/esm/MutableRef.js.map +1 -1
- package/dist/esm/Runtime.js.map +1 -1
- package/dist/esm/TestClock.js +3 -2
- package/dist/esm/TestClock.js.map +1 -1
- package/dist/esm/Tracer.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/channel/channelExecutor.js +6 -1
- package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
- package/dist/esm/internal/core-effect.js +10 -0
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/core.js +2 -1
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/dateTime.js +2 -0
- package/dist/esm/internal/dateTime.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +5 -0
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/hashMap.js +2 -0
- package/dist/esm/internal/hashMap.js.map +1 -1
- package/dist/esm/internal/layer.js +6 -2
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/rcMap.js +11 -1
- package/dist/esm/internal/rcMap.js.map +1 -1
- package/dist/esm/internal/runtime.js +21 -15
- package/dist/esm/internal/runtime.js.map +1 -1
- package/dist/esm/internal/tracer.js +6 -2
- package/dist/esm/internal/tracer.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +9 -1
- package/src/Array.ts +69 -1
- package/src/Data.ts +4 -4
- package/src/DateTime.ts +16 -0
- package/src/Effect.ts +143 -0
- package/src/Either.ts +36 -0
- package/src/FiberSet.ts +14 -1
- package/src/HashMap.ts +32 -0
- package/src/Layer.ts +14 -0
- package/src/LayerMap.ts +396 -0
- package/src/MutableHashMap.ts +45 -3
- package/src/MutableRef.ts +0 -2
- package/src/Runtime.ts +158 -20
- package/src/TestClock.ts +10 -3
- package/src/Tracer.ts +1 -0
- package/src/index.ts +5 -0
- package/src/internal/channel/channelExecutor.ts +11 -4
- package/src/internal/core-effect.ts +15 -0
- package/src/internal/core.ts +2 -1
- package/src/internal/dateTime.ts +3 -0
- package/src/internal/effect/circular.ts +5 -0
- package/src/internal/hashMap.ts +9 -0
- package/src/internal/layer.ts +14 -2
- package/src/internal/rcMap.ts +13 -3
- package/src/internal/runtime.ts +104 -38
- package/src/internal/tracer.ts +8 -1
- package/src/internal/version.ts +1 -1
package/src/LayerMap.ts
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 3.14.0
|
|
3
|
+
* @experimental
|
|
4
|
+
*/
|
|
5
|
+
import * as Context from "./Context.js"
|
|
6
|
+
import type * as Duration from "./Duration.js"
|
|
7
|
+
import * as Effect from "./Effect.js"
|
|
8
|
+
import { identity } from "./Function.js"
|
|
9
|
+
import * as Layer from "./Layer.js"
|
|
10
|
+
import * as RcMap from "./RcMap.js"
|
|
11
|
+
import * as Scope from "./Scope.js"
|
|
12
|
+
import type { Mutable } from "./Types.js"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @since 3.14.0
|
|
16
|
+
* @category Symbols
|
|
17
|
+
*/
|
|
18
|
+
export const TypeId: unique symbol = Symbol.for("effect/LayerMap")
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @since 3.14.0
|
|
22
|
+
* @category Symbols
|
|
23
|
+
*/
|
|
24
|
+
export type TypeId = typeof TypeId
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @since 3.14.0
|
|
28
|
+
* @category Models
|
|
29
|
+
* @experimental
|
|
30
|
+
*/
|
|
31
|
+
export interface LayerMap<in K, in out I, out S, out E = never> {
|
|
32
|
+
readonly [TypeId]: TypeId
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The internal RcMap that stores the resources.
|
|
36
|
+
*/
|
|
37
|
+
readonly rcMap: RcMap.RcMap<K, readonly [Context.Context<I>, S], E>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves an instance of the resource associated with the key.
|
|
41
|
+
*/
|
|
42
|
+
get(key: K): Effect.Effect<S, E, Scope.Scope>
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Provides an instance of the resource associated with the key
|
|
46
|
+
* to the given effect.
|
|
47
|
+
*/
|
|
48
|
+
provide(key: K): <A, EX, R>(effect: Effect.Effect<A, EX, R>) => Effect.Effect<A, EX | E, Exclude<R, I>>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Invalidates the resource associated with the key.
|
|
52
|
+
*/
|
|
53
|
+
invalidate(key: K): Effect.Effect<void>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @since 3.14.0
|
|
58
|
+
* @category Constructors
|
|
59
|
+
* @experimental
|
|
60
|
+
*
|
|
61
|
+
* A `LayerMap` allows you to create a map of Layer's that can be used to
|
|
62
|
+
* dynamically access resources based on a key.
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { Completions } from "@effect/ai"
|
|
66
|
+
* import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
|
|
67
|
+
* import { FetchHttpClient } from "@effect/platform"
|
|
68
|
+
* import { NodeRuntime } from "@effect/platform-node"
|
|
69
|
+
* import { Config, Effect, Layer, LayerMap } from "effect"
|
|
70
|
+
*
|
|
71
|
+
* // create the openai client layer
|
|
72
|
+
* const OpenAiLayer = OpenAiClient.layerConfig({
|
|
73
|
+
* apiKey: Config.redacted("OPENAI_API_KEY")
|
|
74
|
+
* }).pipe(Layer.provide(FetchHttpClient.layer))
|
|
75
|
+
*
|
|
76
|
+
* // create a service that wraps a LayerMap
|
|
77
|
+
* class AiClients extends LayerMap.Service<AiClients>()("AiClients", {
|
|
78
|
+
* // this LayerMap will provide the ai Completions service
|
|
79
|
+
* provides: Completions.Completions,
|
|
80
|
+
*
|
|
81
|
+
* // define the lookup function for the layer map
|
|
82
|
+
* //
|
|
83
|
+
* // The returned Layer will be used to provide the Completions service for the
|
|
84
|
+
* // given model.
|
|
85
|
+
* lookup: (model: OpenAiCompletions.Model) => OpenAiCompletions.layer({ model }),
|
|
86
|
+
*
|
|
87
|
+
* // If a layer is not used for a certain amount of time, it can be removed
|
|
88
|
+
* idleTimeToLive: "5 seconds",
|
|
89
|
+
*
|
|
90
|
+
* // Supply the dependencies for the layers in the LayerMap
|
|
91
|
+
* dependencies: [OpenAiLayer]
|
|
92
|
+
* }) {}
|
|
93
|
+
*
|
|
94
|
+
* // usage
|
|
95
|
+
* Effect.gen(function*() {
|
|
96
|
+
* // access and use the generic Completions service
|
|
97
|
+
* const ai = yield* Completions.Completions
|
|
98
|
+
* const response = yield* ai.create("Hello, world!")
|
|
99
|
+
* console.log(response.text)
|
|
100
|
+
* }).pipe(
|
|
101
|
+
* // use the AiClients service to provide a variant of the Completions service
|
|
102
|
+
* AiClients.provide("gpt-4o"),
|
|
103
|
+
* // provide the LayerMap service
|
|
104
|
+
* Effect.provide(AiClients.Default),
|
|
105
|
+
* NodeRuntime.runMain
|
|
106
|
+
* )
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export const make: <
|
|
110
|
+
Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
|
|
111
|
+
K,
|
|
112
|
+
L extends Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>
|
|
113
|
+
>(
|
|
114
|
+
tagOrAccessor: Accessor,
|
|
115
|
+
lookup: (key: K) => L,
|
|
116
|
+
options?: {
|
|
117
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
118
|
+
} | undefined
|
|
119
|
+
) => Effect.Effect<
|
|
120
|
+
LayerMap<
|
|
121
|
+
K,
|
|
122
|
+
Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
|
|
123
|
+
Effect.Effect.Success<Accessor>,
|
|
124
|
+
Effect.Effect.Error<Accessor> | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
|
|
125
|
+
>,
|
|
126
|
+
never,
|
|
127
|
+
Scope.Scope | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
|
|
128
|
+
> = Effect.fnUntraced(function*<I, S, K, EL, RL, E = never>(
|
|
129
|
+
tagOrAccessor: Effect.Effect<S, E, I>,
|
|
130
|
+
lookup: (key: K) => Layer.Layer<Exclude<I, Scope.Scope>, EL, RL>,
|
|
131
|
+
options?: {
|
|
132
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
133
|
+
} | undefined
|
|
134
|
+
) {
|
|
135
|
+
const context = yield* Effect.context<never>()
|
|
136
|
+
|
|
137
|
+
// If we are inside another layer build, use the current memo map,
|
|
138
|
+
// otherwise create a new one.
|
|
139
|
+
const memoMap = context.unsafeMap.has(Layer.CurrentMemoMap.key)
|
|
140
|
+
? Context.get(context, Layer.CurrentMemoMap)
|
|
141
|
+
: yield* Layer.makeMemoMap
|
|
142
|
+
|
|
143
|
+
const rcMap = yield* RcMap.make({
|
|
144
|
+
lookup: Effect.fnUntraced(function*(key: K) {
|
|
145
|
+
const scope = yield* Effect.scope
|
|
146
|
+
const context = yield* (Layer.buildWithMemoMap(lookup(key), memoMap, scope) as Effect.Effect<
|
|
147
|
+
Context.Context<Exclude<I, Scope.Scope>>
|
|
148
|
+
>)
|
|
149
|
+
const service = yield* (Effect.provide(tagOrAccessor, context) as Effect.Effect<S>)
|
|
150
|
+
return [context, service] as const
|
|
151
|
+
}),
|
|
152
|
+
idleTimeToLive: options?.idleTimeToLive
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
return identity<LayerMap<K, Exclude<I, Scope.Scope>, S, any>>({
|
|
156
|
+
[TypeId]: TypeId,
|
|
157
|
+
rcMap,
|
|
158
|
+
get: (key) => Effect.map(RcMap.get(rcMap, key), ([, service]) => service),
|
|
159
|
+
provide: (key) => (effect) =>
|
|
160
|
+
Effect.scopedWith((scope) =>
|
|
161
|
+
Effect.flatMap(
|
|
162
|
+
Scope.extend(RcMap.get(rcMap, key), scope),
|
|
163
|
+
([context]) => Effect.provide(effect, context)
|
|
164
|
+
)
|
|
165
|
+
),
|
|
166
|
+
invalidate: (key) => RcMap.invalidate(rcMap, key)
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @since 3.14.0
|
|
172
|
+
* @category Constructors
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
export const fromRecord = <
|
|
176
|
+
Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
|
|
177
|
+
const Layers extends Record<string, Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>>
|
|
178
|
+
>(
|
|
179
|
+
tagOrAccessor: Accessor,
|
|
180
|
+
layers: Layers,
|
|
181
|
+
options?: {
|
|
182
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
183
|
+
} | undefined
|
|
184
|
+
): Effect.Effect<
|
|
185
|
+
LayerMap<
|
|
186
|
+
keyof Layers,
|
|
187
|
+
Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
|
|
188
|
+
Effect.Effect.Success<Accessor>,
|
|
189
|
+
| Effect.Effect.Error<Accessor>
|
|
190
|
+
| (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
|
|
191
|
+
>,
|
|
192
|
+
never,
|
|
193
|
+
Scope.Scope | (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
|
|
194
|
+
> => make(tagOrAccessor, (key: keyof Layers) => layers[key], options)
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @since 3.14.0
|
|
198
|
+
* @category Service
|
|
199
|
+
*/
|
|
200
|
+
export interface TagClass<
|
|
201
|
+
in out Self,
|
|
202
|
+
in out Id extends string,
|
|
203
|
+
in out K,
|
|
204
|
+
in out I,
|
|
205
|
+
in out S,
|
|
206
|
+
in out E,
|
|
207
|
+
in out R,
|
|
208
|
+
in out Deps extends Layer.Layer<any, any, any>
|
|
209
|
+
> extends Context.TagClass<Self, Id, LayerMap<K, I, S, E>> {
|
|
210
|
+
/**
|
|
211
|
+
* A default layer for the `LayerMap` service.
|
|
212
|
+
*/
|
|
213
|
+
readonly Default: Layer.Layer<
|
|
214
|
+
Self,
|
|
215
|
+
(Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never),
|
|
216
|
+
| Exclude<R, (Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _A : never)>
|
|
217
|
+
| (Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
|
|
218
|
+
>
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* A default layer for the `LayerMap` service without the dependencies provided.
|
|
222
|
+
*/
|
|
223
|
+
readonly DefaultWithoutDependencies: Layer.Layer<Self, never, R>
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Retrieves an instance of the resource associated with the key.
|
|
227
|
+
*/
|
|
228
|
+
readonly get: (key: K) => Effect.Effect<S, E, Scope.Scope | Self>
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Provides an instance of the resource associated with the key to the given
|
|
232
|
+
* effect.
|
|
233
|
+
*/
|
|
234
|
+
readonly provide: (
|
|
235
|
+
key: K
|
|
236
|
+
) => <A, EX, R>(effect: Effect.Effect<A, EX, R>) => Effect.Effect<A, EX | E, Exclude<R, I> | Self>
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Invalidates the resource associated with the key.
|
|
240
|
+
*/
|
|
241
|
+
readonly invalidate: (key: K) => Effect.Effect<void, never, Self>
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @since 3.14.0
|
|
246
|
+
* @category Service
|
|
247
|
+
* @experimental
|
|
248
|
+
*
|
|
249
|
+
* Create a `LayerMap` service that provides a dynamic set of resources based on
|
|
250
|
+
* a key.
|
|
251
|
+
*
|
|
252
|
+
* ```ts
|
|
253
|
+
* import { Completions } from "@effect/ai"
|
|
254
|
+
* import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
|
|
255
|
+
* import { FetchHttpClient } from "@effect/platform"
|
|
256
|
+
* import { NodeRuntime } from "@effect/platform-node"
|
|
257
|
+
* import { Config, Effect, Layer, LayerMap } from "effect"
|
|
258
|
+
*
|
|
259
|
+
* // create the openai client layer
|
|
260
|
+
* const OpenAiLayer = OpenAiClient.layerConfig({
|
|
261
|
+
* apiKey: Config.redacted("OPENAI_API_KEY")
|
|
262
|
+
* }).pipe(Layer.provide(FetchHttpClient.layer))
|
|
263
|
+
*
|
|
264
|
+
* // create a service that wraps a LayerMap
|
|
265
|
+
* class AiClients extends LayerMap.Service<AiClients>()("AiClients", {
|
|
266
|
+
* // this LayerMap will provide the ai Completions service
|
|
267
|
+
* provides: Completions.Completions,
|
|
268
|
+
*
|
|
269
|
+
* // define the lookup function for the layer map
|
|
270
|
+
* //
|
|
271
|
+
* // The returned Layer will be used to provide the Completions service for the
|
|
272
|
+
* // given model.
|
|
273
|
+
* lookup: (model: OpenAiCompletions.Model) => OpenAiCompletions.layer({ model }),
|
|
274
|
+
*
|
|
275
|
+
* // If a layer is not used for a certain amount of time, it can be removed
|
|
276
|
+
* idleTimeToLive: "5 seconds",
|
|
277
|
+
*
|
|
278
|
+
* // Supply the dependencies for the layers in the LayerMap
|
|
279
|
+
* dependencies: [OpenAiLayer]
|
|
280
|
+
* }) {}
|
|
281
|
+
*
|
|
282
|
+
* // usage
|
|
283
|
+
* Effect.gen(function*() {
|
|
284
|
+
* // access and use the generic Completions service
|
|
285
|
+
* const ai = yield* Completions.Completions
|
|
286
|
+
* const response = yield* ai.create("Hello, world!")
|
|
287
|
+
* console.log(response.text)
|
|
288
|
+
* }).pipe(
|
|
289
|
+
* // use the AiClients service to provide a variant of the Completions service
|
|
290
|
+
* AiClients.provide("gpt-4o"),
|
|
291
|
+
* // provide the LayerMap service
|
|
292
|
+
* Effect.provide(AiClients.Default),
|
|
293
|
+
* NodeRuntime.runMain
|
|
294
|
+
* )
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
export const Service = <Self>() =>
|
|
298
|
+
<
|
|
299
|
+
const Id extends string,
|
|
300
|
+
Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
|
|
301
|
+
Lookup extends {
|
|
302
|
+
readonly lookup: (key: any) => Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>
|
|
303
|
+
} | {
|
|
304
|
+
readonly layers: Record<string, Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>>
|
|
305
|
+
},
|
|
306
|
+
const Deps extends ReadonlyArray<Layer.Layer<any, any, any>> = []
|
|
307
|
+
>(
|
|
308
|
+
id: Id,
|
|
309
|
+
options: Lookup & {
|
|
310
|
+
readonly provides: Accessor
|
|
311
|
+
readonly dependencies?: Deps | undefined
|
|
312
|
+
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
313
|
+
}
|
|
314
|
+
): TagClass<
|
|
315
|
+
Self,
|
|
316
|
+
Id,
|
|
317
|
+
Lookup extends { readonly lookup: (key: infer K) => any } ? K
|
|
318
|
+
: Lookup extends { readonly layers: infer Layers } ? keyof Layers
|
|
319
|
+
: never,
|
|
320
|
+
Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
|
|
321
|
+
Effect.Effect.Success<Accessor>,
|
|
322
|
+
Effect.Effect.Error<Accessor> | Service.Error<Lookup>,
|
|
323
|
+
Service.Context<Lookup>,
|
|
324
|
+
Deps[number]
|
|
325
|
+
> => {
|
|
326
|
+
const Err = globalThis.Error as any
|
|
327
|
+
const limit = Err.stackTraceLimit
|
|
328
|
+
Err.stackTraceLimit = 2
|
|
329
|
+
const creationError = new Err()
|
|
330
|
+
Err.stackTraceLimit = limit
|
|
331
|
+
|
|
332
|
+
function TagClass() {}
|
|
333
|
+
const TagClass_ = TagClass as any as Mutable<TagClass<Self, Id, string, any, any, any, any, any>>
|
|
334
|
+
Object.setPrototypeOf(TagClass, Object.getPrototypeOf(Context.GenericTag<Self, any>(id)))
|
|
335
|
+
TagClass.key = id
|
|
336
|
+
Object.defineProperty(TagClass, "stack", {
|
|
337
|
+
get() {
|
|
338
|
+
return creationError.stack
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
TagClass_.get = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.get(key))
|
|
342
|
+
TagClass_.provide = (key: string) => (effect) =>
|
|
343
|
+
Effect.flatMap(TagClass_, (layerMap) => layerMap.provide(key)(effect))
|
|
344
|
+
TagClass_.invalidate = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.invalidate(key))
|
|
345
|
+
|
|
346
|
+
TagClass_.DefaultWithoutDependencies = Layer.scoped(
|
|
347
|
+
TagClass_,
|
|
348
|
+
"lookup" in options
|
|
349
|
+
? make(options.provides, options.lookup, options)
|
|
350
|
+
: fromRecord(options.provides, options.layers as any, options)
|
|
351
|
+
)
|
|
352
|
+
TagClass_.Default = options.dependencies && options.dependencies.length > 0 ?
|
|
353
|
+
Layer.provide(TagClass_.DefaultWithoutDependencies, options.dependencies as any) :
|
|
354
|
+
TagClass_.DefaultWithoutDependencies
|
|
355
|
+
|
|
356
|
+
return TagClass as any
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @since 3.14.0
|
|
361
|
+
* @category Service
|
|
362
|
+
* @experimental
|
|
363
|
+
*/
|
|
364
|
+
export declare namespace Service {
|
|
365
|
+
/**
|
|
366
|
+
* @since 3.14.0
|
|
367
|
+
* @category Service
|
|
368
|
+
* @experimental
|
|
369
|
+
*/
|
|
370
|
+
export type Key<Options> = Options extends { readonly lookup: (key: infer K) => any } ? K
|
|
371
|
+
: Options extends { readonly layers: infer Layers } ? keyof Layers
|
|
372
|
+
: never
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @since 3.14.0
|
|
376
|
+
* @category Service
|
|
377
|
+
* @experimental
|
|
378
|
+
*/
|
|
379
|
+
export type Layers<Options> = Options extends { readonly lookup: (key: infer _K) => infer Layers } ? Layers
|
|
380
|
+
: Options extends { readonly layers: infer Layers } ? Layers[keyof Layers]
|
|
381
|
+
: never
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @since 3.14.0
|
|
385
|
+
* @category Service
|
|
386
|
+
* @experimental
|
|
387
|
+
*/
|
|
388
|
+
export type Error<Options> = Layers<Options> extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* @since 3.14.0
|
|
392
|
+
* @category Service
|
|
393
|
+
* @experimental
|
|
394
|
+
*/
|
|
395
|
+
export type Context<Options> = Layers<Options> extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never
|
|
396
|
+
}
|
package/src/MutableHashMap.ts
CHANGED
|
@@ -180,13 +180,29 @@ export const get: {
|
|
|
180
180
|
* @category elements
|
|
181
181
|
*/
|
|
182
182
|
export const keys = <K, V>(self: MutableHashMap<K, V>): Array<K> => {
|
|
183
|
-
const keys
|
|
184
|
-
for (const
|
|
185
|
-
|
|
183
|
+
const keys = Array.from(self.referential.keys())
|
|
184
|
+
for (const bucket of self.buckets.values()) {
|
|
185
|
+
for (let i = 0, len = bucket.length; i < len; i++) {
|
|
186
|
+
keys.push(bucket[i][0])
|
|
187
|
+
}
|
|
186
188
|
}
|
|
187
189
|
return keys
|
|
188
190
|
}
|
|
189
191
|
|
|
192
|
+
/**
|
|
193
|
+
* @since 3.8.0
|
|
194
|
+
* @category elements
|
|
195
|
+
*/
|
|
196
|
+
export const values = <K, V>(self: MutableHashMap<K, V>): Array<V> => {
|
|
197
|
+
const values = Array.from(self.referential.values())
|
|
198
|
+
for (const bucket of self.buckets.values()) {
|
|
199
|
+
for (let i = 0, len = bucket.length; i < len; i++) {
|
|
200
|
+
values.push(bucket[i][1])
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return values
|
|
204
|
+
}
|
|
205
|
+
|
|
190
206
|
const getFromBucket = <K, V>(
|
|
191
207
|
self: MutableHashMap<K, V>,
|
|
192
208
|
bucket: NonEmptyArray<readonly [K & Equal.Equal, V]>,
|
|
@@ -474,3 +490,29 @@ export const clear = <K, V>(self: MutableHashMap<K, V>) => {
|
|
|
474
490
|
export const size = <K, V>(self: MutableHashMap<K, V>): number => {
|
|
475
491
|
return self.referential.size + self.bucketsSize
|
|
476
492
|
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* @since 2.0.0
|
|
496
|
+
*/
|
|
497
|
+
export const isEmpty = <K, V>(self: MutableHashMap<K, V>): boolean => size(self) === 0
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* @since 2.0.0
|
|
501
|
+
*/
|
|
502
|
+
export const forEach: {
|
|
503
|
+
/**
|
|
504
|
+
* @since 2.0.0
|
|
505
|
+
*/
|
|
506
|
+
<K, V>(f: (value: V, key: K) => void): (self: MutableHashMap<K, V>) => void
|
|
507
|
+
/**
|
|
508
|
+
* @since 2.0.0
|
|
509
|
+
*/
|
|
510
|
+
<K, V>(self: MutableHashMap<K, V>, f: (value: V, key: K) => void): void
|
|
511
|
+
} = dual(2, <K, V>(self: MutableHashMap<K, V>, f: (value: V, key: K) => void) => {
|
|
512
|
+
self.referential.forEach(f)
|
|
513
|
+
for (const bucket of self.buckets.values()) {
|
|
514
|
+
for (const [key, value] of bucket) {
|
|
515
|
+
f(value, key)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
})
|
package/src/MutableRef.ts
CHANGED
package/src/Runtime.ts
CHANGED
|
@@ -81,9 +81,28 @@ export interface RunForkOptions {
|
|
|
81
81
|
* @since 2.0.0
|
|
82
82
|
* @category execution
|
|
83
83
|
*/
|
|
84
|
-
export const runFork:
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
export const runFork: {
|
|
85
|
+
/**
|
|
86
|
+
* Executes the effect using the provided Scheduler or using the global
|
|
87
|
+
* Scheduler if not provided
|
|
88
|
+
*
|
|
89
|
+
* @since 2.0.0
|
|
90
|
+
* @category execution
|
|
91
|
+
*/
|
|
92
|
+
<R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>, options?: RunForkOptions | undefined) => Fiber.RuntimeFiber<A, E>
|
|
93
|
+
/**
|
|
94
|
+
* Executes the effect using the provided Scheduler or using the global
|
|
95
|
+
* Scheduler if not provided
|
|
96
|
+
*
|
|
97
|
+
* @since 2.0.0
|
|
98
|
+
* @category execution
|
|
99
|
+
*/
|
|
100
|
+
<R, A, E>(
|
|
101
|
+
runtime: Runtime<R>,
|
|
102
|
+
effect: Effect.Effect<A, E, R>,
|
|
103
|
+
options?: RunForkOptions | undefined
|
|
104
|
+
): Fiber.RuntimeFiber<A, E>
|
|
105
|
+
} = internal.unsafeFork
|
|
87
106
|
|
|
88
107
|
/**
|
|
89
108
|
* Executes the effect synchronously returning the exit.
|
|
@@ -94,8 +113,28 @@ export const runFork: <R>(
|
|
|
94
113
|
* @since 2.0.0
|
|
95
114
|
* @category execution
|
|
96
115
|
*/
|
|
97
|
-
export const runSyncExit:
|
|
98
|
-
|
|
116
|
+
export const runSyncExit: {
|
|
117
|
+
/**
|
|
118
|
+
* Executes the effect synchronously returning the exit.
|
|
119
|
+
*
|
|
120
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
121
|
+
* program.
|
|
122
|
+
*
|
|
123
|
+
* @since 2.0.0
|
|
124
|
+
* @category execution
|
|
125
|
+
*/
|
|
126
|
+
<A, E, R>(runtime: Runtime<R>, effect: Effect.Effect<A, E, R>): Exit.Exit<A, E>
|
|
127
|
+
/**
|
|
128
|
+
* Executes the effect synchronously returning the exit.
|
|
129
|
+
*
|
|
130
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
131
|
+
* program.
|
|
132
|
+
*
|
|
133
|
+
* @since 2.0.0
|
|
134
|
+
* @category execution
|
|
135
|
+
*/
|
|
136
|
+
<R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>) => Exit.Exit<A, E>
|
|
137
|
+
} = internal.unsafeRunSyncExit
|
|
99
138
|
|
|
100
139
|
/**
|
|
101
140
|
* Executes the effect synchronously throwing in case of errors or async boundaries.
|
|
@@ -106,7 +145,28 @@ export const runSyncExit: <R>(runtime: Runtime<R>) => <A, E>(effect: Effect.Effe
|
|
|
106
145
|
* @since 2.0.0
|
|
107
146
|
* @category execution
|
|
108
147
|
*/
|
|
109
|
-
export const runSync:
|
|
148
|
+
export const runSync: {
|
|
149
|
+
/**
|
|
150
|
+
* Executes the effect synchronously throwing in case of errors or async boundaries.
|
|
151
|
+
*
|
|
152
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
153
|
+
* program.
|
|
154
|
+
*
|
|
155
|
+
* @since 2.0.0
|
|
156
|
+
* @category execution
|
|
157
|
+
*/
|
|
158
|
+
<A, E, R>(runtime: Runtime<R>, effect: Effect.Effect<A, E, R>): A
|
|
159
|
+
/**
|
|
160
|
+
* Executes the effect synchronously throwing in case of errors or async boundaries.
|
|
161
|
+
*
|
|
162
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
163
|
+
* program.
|
|
164
|
+
*
|
|
165
|
+
* @since 2.0.0
|
|
166
|
+
* @category execution
|
|
167
|
+
*/
|
|
168
|
+
<R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>) => A
|
|
169
|
+
} = internal.unsafeRunSync
|
|
110
170
|
|
|
111
171
|
/**
|
|
112
172
|
* @since 2.0.0
|
|
@@ -126,10 +186,37 @@ export interface RunCallbackOptions<in A, in E = never> extends RunForkOptions {
|
|
|
126
186
|
* @since 2.0.0
|
|
127
187
|
* @category execution
|
|
128
188
|
*/
|
|
129
|
-
export const runCallback:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
189
|
+
export const runCallback: {
|
|
190
|
+
/**
|
|
191
|
+
* Executes the effect asynchronously, eventually passing the exit value to
|
|
192
|
+
* the specified callback.
|
|
193
|
+
*
|
|
194
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
195
|
+
* program.
|
|
196
|
+
*
|
|
197
|
+
* @since 2.0.0
|
|
198
|
+
* @category execution
|
|
199
|
+
*/
|
|
200
|
+
<R>(runtime: Runtime<R>): <A, E>(
|
|
201
|
+
effect: Effect.Effect<A, E, R>,
|
|
202
|
+
options?: RunCallbackOptions<A, E> | undefined
|
|
203
|
+
) => (fiberId?: FiberId.FiberId, options?: RunCallbackOptions<A, E> | undefined) => void
|
|
204
|
+
/**
|
|
205
|
+
* Executes the effect asynchronously, eventually passing the exit value to
|
|
206
|
+
* the specified callback.
|
|
207
|
+
*
|
|
208
|
+
* This method is effectful and should only be invoked at the edges of your
|
|
209
|
+
* program.
|
|
210
|
+
*
|
|
211
|
+
* @since 2.0.0
|
|
212
|
+
* @category execution
|
|
213
|
+
*/
|
|
214
|
+
<R, A, E>(
|
|
215
|
+
runtime: Runtime<R>,
|
|
216
|
+
effect: Effect.Effect<A, E, R>,
|
|
217
|
+
options?: RunCallbackOptions<A, E> | undefined
|
|
218
|
+
): (fiberId?: FiberId.FiberId, options?: RunCallbackOptions<A, E> | undefined) => void
|
|
219
|
+
} = internal.unsafeRunCallback
|
|
133
220
|
|
|
134
221
|
/**
|
|
135
222
|
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
@@ -142,10 +229,36 @@ export const runCallback: <R>(
|
|
|
142
229
|
* @since 2.0.0
|
|
143
230
|
* @category execution
|
|
144
231
|
*/
|
|
145
|
-
export const runPromise:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
232
|
+
export const runPromise: {
|
|
233
|
+
/**
|
|
234
|
+
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
235
|
+
* with the value of the effect once the effect has been executed, or will be
|
|
236
|
+
* rejected with the first error or exception throw by the effect.
|
|
237
|
+
*
|
|
238
|
+
* This method is effectful and should only be used at the edges of your
|
|
239
|
+
* program.
|
|
240
|
+
*
|
|
241
|
+
* @since 2.0.0
|
|
242
|
+
* @category execution
|
|
243
|
+
*/
|
|
244
|
+
<R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal } | undefined) => Promise<A>
|
|
245
|
+
/**
|
|
246
|
+
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
247
|
+
* with the value of the effect once the effect has been executed, or will be
|
|
248
|
+
* rejected with the first error or exception throw by the effect.
|
|
249
|
+
*
|
|
250
|
+
* This method is effectful and should only be used at the edges of your
|
|
251
|
+
* program.
|
|
252
|
+
*
|
|
253
|
+
* @since 2.0.0
|
|
254
|
+
* @category execution
|
|
255
|
+
*/
|
|
256
|
+
<R, A, E>(
|
|
257
|
+
runtime: Runtime<R>,
|
|
258
|
+
effect: Effect.Effect<A, E, R>,
|
|
259
|
+
options?: { readonly signal?: AbortSignal } | undefined
|
|
260
|
+
): Promise<A>
|
|
261
|
+
} = internal.unsafeRunPromise
|
|
149
262
|
|
|
150
263
|
/**
|
|
151
264
|
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
@@ -157,12 +270,37 @@ export const runPromise: <R>(
|
|
|
157
270
|
* @since 2.0.0
|
|
158
271
|
* @category execution
|
|
159
272
|
*/
|
|
160
|
-
export const runPromiseExit:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
273
|
+
export const runPromiseExit: {
|
|
274
|
+
/**
|
|
275
|
+
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
276
|
+
* with the `Exit` state of the effect once the effect has been executed.
|
|
277
|
+
*
|
|
278
|
+
* This method is effectful and should only be used at the edges of your
|
|
279
|
+
* program.
|
|
280
|
+
*
|
|
281
|
+
* @since 2.0.0
|
|
282
|
+
* @category execution
|
|
283
|
+
*/
|
|
284
|
+
<R>(runtime: Runtime<R>): <A, E>(
|
|
285
|
+
effect: Effect.Effect<A, E, R>,
|
|
286
|
+
options?: { readonly signal?: AbortSignal } | undefined
|
|
287
|
+
) => Promise<Exit.Exit<A, E>>
|
|
288
|
+
/**
|
|
289
|
+
* Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
|
|
290
|
+
* with the `Exit` state of the effect once the effect has been executed.
|
|
291
|
+
*
|
|
292
|
+
* This method is effectful and should only be used at the edges of your
|
|
293
|
+
* program.
|
|
294
|
+
*
|
|
295
|
+
* @since 2.0.0
|
|
296
|
+
* @category execution
|
|
297
|
+
*/
|
|
298
|
+
<R, A, E>(
|
|
299
|
+
runtime: Runtime<R>,
|
|
300
|
+
effect: Effect.Effect<A, E, R>,
|
|
301
|
+
options?: { readonly signal?: AbortSignal } | undefined
|
|
302
|
+
): Promise<Exit.Exit<A, E>>
|
|
303
|
+
} = internal.unsafeRunPromiseExit
|
|
166
304
|
|
|
167
305
|
/**
|
|
168
306
|
* @since 2.0.0
|