effect 3.15.4 → 3.16.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/ExecutionPlan/package.json +6 -0
- package/dist/cjs/Array.js +67 -5
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/BigDecimal.js +150 -1
- package/dist/cjs/BigDecimal.js.map +1 -1
- package/dist/cjs/Chunk.js +16 -3
- package/dist/cjs/Chunk.js.map +1 -1
- package/dist/cjs/Config.js +16 -2
- package/dist/cjs/Config.js.map +1 -1
- package/dist/cjs/Effect.js +31 -3
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/ExecutionPlan.js +108 -0
- package/dist/cjs/ExecutionPlan.js.map +1 -0
- package/dist/cjs/HashMap.js +18 -1
- package/dist/cjs/HashMap.js.map +1 -1
- package/dist/cjs/Iterable.js +27 -1
- package/dist/cjs/Iterable.js.map +1 -1
- package/dist/cjs/LayerMap.js +86 -64
- package/dist/cjs/LayerMap.js.map +1 -1
- package/dist/cjs/Schedule.js +7 -1
- package/dist/cjs/Schedule.js.map +1 -1
- package/dist/cjs/Stream.js +15 -2
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/config.js +18 -1
- package/dist/cjs/internal/config.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +1 -4
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/executionPlan.js +68 -0
- package/dist/cjs/internal/executionPlan.js.map +1 -0
- package/dist/cjs/internal/hashMap.js +3 -1
- package/dist/cjs/internal/hashMap.js.map +1 -1
- package/dist/cjs/internal/metric/polling.js +3 -4
- package/dist/cjs/internal/metric/polling.js.map +1 -1
- package/dist/cjs/internal/schedule.js +66 -25
- package/dist/cjs/internal/schedule.js.map +1 -1
- package/dist/cjs/internal/stream.js +60 -10
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Array.d.ts +110 -0
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/BigDecimal.d.ts +235 -0
- package/dist/dts/BigDecimal.d.ts.map +1 -1
- package/dist/dts/Chunk.d.ts +13 -0
- package/dist/dts/Chunk.d.ts.map +1 -1
- package/dist/dts/Config.d.ts +38 -1
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +99 -27
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/ExecutionPlan.d.ts +213 -0
- package/dist/dts/ExecutionPlan.d.ts.map +1 -0
- package/dist/dts/HashMap.d.ts +52 -0
- package/dist/dts/HashMap.d.ts.map +1 -1
- package/dist/dts/Iterable.d.ts +49 -0
- package/dist/dts/Iterable.d.ts.map +1 -1
- package/dist/dts/LayerMap.d.ts +79 -72
- package/dist/dts/LayerMap.d.ts.map +1 -1
- package/dist/dts/Schedule.d.ts +26 -0
- package/dist/dts/Schedule.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +57 -2
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/index.d.ts +5 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/executionPlan.d.ts +2 -0
- package/dist/dts/internal/executionPlan.d.ts.map +1 -0
- package/dist/dts/internal/hashMap.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Array.js +65 -3
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/BigDecimal.js +148 -0
- package/dist/esm/BigDecimal.js.map +1 -1
- package/dist/esm/Chunk.js +15 -2
- package/dist/esm/Chunk.js.map +1 -1
- package/dist/esm/Config.js +15 -1
- package/dist/esm/Config.js.map +1 -1
- package/dist/esm/Effect.js +29 -1
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/ExecutionPlan.js +99 -0
- package/dist/esm/ExecutionPlan.js.map +1 -0
- package/dist/esm/HashMap.js +17 -0
- package/dist/esm/HashMap.js.map +1 -1
- package/dist/esm/Iterable.js +26 -0
- package/dist/esm/Iterable.js.map +1 -1
- package/dist/esm/LayerMap.js +86 -64
- package/dist/esm/LayerMap.js.map +1 -1
- package/dist/esm/Schedule.js +5 -0
- package/dist/esm/Schedule.js.map +1 -1
- package/dist/esm/Stream.js +13 -0
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/config.js +16 -0
- package/dist/esm/internal/config.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +0 -3
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/executionPlan.js +59 -0
- package/dist/esm/internal/executionPlan.js.map +1 -0
- package/dist/esm/internal/hashMap.js +2 -0
- package/dist/esm/internal/hashMap.js.map +1 -1
- package/dist/esm/internal/metric/polling.js +3 -4
- package/dist/esm/internal/metric/polling.js.map +1 -1
- package/dist/esm/internal/schedule.js +61 -23
- package/dist/esm/internal/schedule.js.map +1 -1
- package/dist/esm/internal/stream.js +57 -7
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +9 -1
- package/src/Array.ts +147 -4
- package/src/BigDecimal.ts +355 -0
- package/src/Chunk.ts +28 -3
- package/src/Config.ts +40 -1
- package/src/Effect.ts +145 -36
- package/src/ExecutionPlan.ts +302 -0
- package/src/HashMap.ts +56 -0
- package/src/Iterable.ts +66 -0
- package/src/LayerMap.ts +126 -114
- package/src/Schedule.ts +32 -0
- package/src/Stream.ts +51 -2
- package/src/index.ts +6 -0
- package/src/internal/config.ts +55 -0
- package/src/internal/effect/circular.ts +0 -15
- package/src/internal/executionPlan.ts +114 -0
- package/src/internal/hashMap.ts +6 -0
- package/src/internal/metric/polling.ts +3 -4
- package/src/internal/schedule.ts +169 -50
- package/src/internal/stream.ts +140 -15
- package/src/internal/version.ts +1 -1
package/src/LayerMap.ts
CHANGED
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
import * as Context from "./Context.js"
|
|
6
6
|
import type * as Duration from "./Duration.js"
|
|
7
7
|
import * as Effect from "./Effect.js"
|
|
8
|
+
import * as FiberRefsPatch from "./FiberRefsPatch.js"
|
|
8
9
|
import { identity } from "./Function.js"
|
|
10
|
+
import * as core from "./internal/core.js"
|
|
9
11
|
import * as Layer from "./Layer.js"
|
|
10
12
|
import * as RcMap from "./RcMap.js"
|
|
13
|
+
import * as Runtime from "./Runtime.js"
|
|
11
14
|
import * as Scope from "./Scope.js"
|
|
12
15
|
import type { Mutable } from "./Types.js"
|
|
13
16
|
|
|
@@ -28,24 +31,26 @@ export type TypeId = typeof TypeId
|
|
|
28
31
|
* @category Models
|
|
29
32
|
* @experimental
|
|
30
33
|
*/
|
|
31
|
-
export interface LayerMap<in K, in out I, out
|
|
34
|
+
export interface LayerMap<in K, in out I, out E = never> {
|
|
32
35
|
readonly [TypeId]: TypeId
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
38
|
* The internal RcMap that stores the resources.
|
|
36
39
|
*/
|
|
37
|
-
readonly rcMap: RcMap.RcMap<K,
|
|
40
|
+
readonly rcMap: RcMap.RcMap<K, {
|
|
41
|
+
readonly layer: Layer.Layer<I, E>
|
|
42
|
+
readonly runtimeEffect: Effect.Effect<Runtime.Runtime<I>, E, Scope.Scope>
|
|
43
|
+
}, E>
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
|
-
* Retrieves
|
|
46
|
+
* Retrieves a Layer for the resources associated with the key.
|
|
41
47
|
*/
|
|
42
|
-
get(key: K):
|
|
48
|
+
get(key: K): Layer.Layer<I, E>
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
|
-
*
|
|
46
|
-
* to the given effect.
|
|
51
|
+
* Retrieves a Runtime for the resources associated with the key.
|
|
47
52
|
*/
|
|
48
|
-
|
|
53
|
+
runtime(key: K): Effect.Effect<Runtime.Runtime<I>, E, Scope.Scope>
|
|
49
54
|
|
|
50
55
|
/**
|
|
51
56
|
* Invalidates the resource associated with the key.
|
|
@@ -62,56 +67,54 @@ export interface LayerMap<in K, in out I, out S, out E = never> {
|
|
|
62
67
|
* dynamically access resources based on a key.
|
|
63
68
|
*
|
|
64
69
|
* ```ts
|
|
65
|
-
* import { Completions } from "@effect/ai"
|
|
66
|
-
* import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
|
|
67
|
-
* import { FetchHttpClient } from "@effect/platform"
|
|
68
70
|
* import { NodeRuntime } from "@effect/platform-node"
|
|
69
|
-
* import {
|
|
71
|
+
* import { Context, Effect, FiberRef, Layer, LayerMap } from "effect"
|
|
70
72
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* }).pipe(Layer.provide(FetchHttpClient.layer))
|
|
73
|
+
* class Greeter extends Context.Tag("Greeter")<Greeter, {
|
|
74
|
+
* greet: Effect.Effect<string>
|
|
75
|
+
* }>() {}
|
|
75
76
|
*
|
|
76
77
|
* // create a service that wraps a LayerMap
|
|
77
|
-
* class
|
|
78
|
-
* // this LayerMap will provide the ai Completions service
|
|
79
|
-
* provides: Completions.Completions,
|
|
80
|
-
*
|
|
78
|
+
* class GreeterMap extends LayerMap.Service<GreeterMap>()("GreeterMap", {
|
|
81
79
|
* // define the lookup function for the layer map
|
|
82
80
|
* //
|
|
83
|
-
* // The returned Layer will be used to provide the
|
|
84
|
-
* // given
|
|
85
|
-
* lookup: (
|
|
81
|
+
* // The returned Layer will be used to provide the Greeter service for the
|
|
82
|
+
* // given name.
|
|
83
|
+
* lookup: (name: string) =>
|
|
84
|
+
* Layer.succeed(Greeter, {
|
|
85
|
+
* greet: Effect.succeed(`Hello, ${name}!`)
|
|
86
|
+
* }).pipe(
|
|
87
|
+
* Layer.merge(Layer.locallyScoped(FiberRef.currentConcurrency, 123))
|
|
88
|
+
* ),
|
|
86
89
|
*
|
|
87
90
|
* // If a layer is not used for a certain amount of time, it can be removed
|
|
88
91
|
* idleTimeToLive: "5 seconds",
|
|
89
92
|
*
|
|
90
93
|
* // Supply the dependencies for the layers in the LayerMap
|
|
91
|
-
* dependencies: [
|
|
94
|
+
* dependencies: []
|
|
92
95
|
* }) {}
|
|
93
96
|
*
|
|
94
97
|
* // usage
|
|
95
|
-
* Effect.gen(function*() {
|
|
96
|
-
* // access and use the
|
|
97
|
-
* const
|
|
98
|
-
*
|
|
99
|
-
* console.log(response.text)
|
|
98
|
+
* const program: Effect.Effect<void, never, GreeterMap> = Effect.gen(function*() {
|
|
99
|
+
* // access and use the Greeter service
|
|
100
|
+
* const greeter = yield* Greeter
|
|
101
|
+
* yield* Effect.log(yield* greeter.greet)
|
|
100
102
|
* }).pipe(
|
|
101
|
-
* // use the
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
103
|
+
* // use the GreeterMap service to provide a variant of the Greeter service
|
|
104
|
+
* Effect.provide(GreeterMap.get("John"))
|
|
105
|
+
* )
|
|
106
|
+
*
|
|
107
|
+
* // run the program
|
|
108
|
+
* program.pipe(
|
|
109
|
+
* Effect.provide(GreeterMap.Default),
|
|
105
110
|
* NodeRuntime.runMain
|
|
106
111
|
* )
|
|
107
112
|
* ```
|
|
108
113
|
*/
|
|
109
114
|
export const make: <
|
|
110
|
-
Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
|
|
111
115
|
K,
|
|
112
|
-
L extends Layer.Layer<
|
|
116
|
+
L extends Layer.Layer<any, any, any>
|
|
113
117
|
>(
|
|
114
|
-
tagOrAccessor: Accessor,
|
|
115
118
|
lookup: (key: K) => L,
|
|
116
119
|
options?: {
|
|
117
120
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
@@ -119,15 +122,13 @@ export const make: <
|
|
|
119
122
|
) => Effect.Effect<
|
|
120
123
|
LayerMap<
|
|
121
124
|
K,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Effect.Effect.Error<Accessor> | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
|
|
125
|
+
L extends Layer.Layer<infer _A, infer _E, infer _R> ? _A : never,
|
|
126
|
+
L extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never
|
|
125
127
|
>,
|
|
126
128
|
never,
|
|
127
129
|
Scope.Scope | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
|
|
128
|
-
> = Effect.fnUntraced(function*<I,
|
|
129
|
-
|
|
130
|
-
lookup: (key: K) => Layer.Layer<Exclude<I, Scope.Scope>, EL, RL>,
|
|
130
|
+
> = Effect.fnUntraced(function*<I, K, EL, RL>(
|
|
131
|
+
lookup: (key: K) => Layer.Layer<I, EL, RL>,
|
|
131
132
|
options?: {
|
|
132
133
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
133
134
|
} | undefined
|
|
@@ -141,28 +142,43 @@ export const make: <
|
|
|
141
142
|
: yield* Layer.makeMemoMap
|
|
142
143
|
|
|
143
144
|
const rcMap = yield* RcMap.make({
|
|
144
|
-
lookup:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
lookup: (key: K) =>
|
|
146
|
+
Effect.scopeWith((scope) => Effect.diffFiberRefs(Layer.buildWithMemoMap(lookup(key), memoMap, scope))).pipe(
|
|
147
|
+
Effect.map(([patch, context]) => ({
|
|
148
|
+
layer: Layer.scopedContext(
|
|
149
|
+
core.withFiberRuntime<Context.Context<I>, any, Scope.Scope>((fiber) => {
|
|
150
|
+
const scope = Context.unsafeGet(fiber.currentContext, Scope.Scope)
|
|
151
|
+
const oldRefs = fiber.getFiberRefs()
|
|
152
|
+
const newRefs = FiberRefsPatch.patch(patch, fiber.id(), oldRefs)
|
|
153
|
+
const revert = FiberRefsPatch.diff(newRefs, oldRefs)
|
|
154
|
+
fiber.setFiberRefs(newRefs)
|
|
155
|
+
return Effect.as(
|
|
156
|
+
Scope.addFinalizerExit(scope, () => {
|
|
157
|
+
fiber.setFiberRefs(FiberRefsPatch.patch(revert, fiber.id(), fiber.getFiberRefs()))
|
|
158
|
+
return Effect.void
|
|
159
|
+
}),
|
|
160
|
+
context
|
|
161
|
+
)
|
|
162
|
+
})
|
|
163
|
+
),
|
|
164
|
+
runtimeEffect: Effect.withFiberRuntime<Runtime.Runtime<I>, any, Scope.Scope>((fiber) => {
|
|
165
|
+
const fiberRefs = FiberRefsPatch.patch(patch, fiber.id(), fiber.getFiberRefs())
|
|
166
|
+
return Effect.succeed(Runtime.make({
|
|
167
|
+
context,
|
|
168
|
+
fiberRefs,
|
|
169
|
+
runtimeFlags: Runtime.defaultRuntime.runtimeFlags
|
|
170
|
+
}))
|
|
171
|
+
})
|
|
172
|
+
} as const))
|
|
173
|
+
),
|
|
152
174
|
idleTimeToLive: options?.idleTimeToLive
|
|
153
175
|
})
|
|
154
176
|
|
|
155
|
-
return identity<LayerMap<K, Exclude<I, Scope.Scope>,
|
|
177
|
+
return identity<LayerMap<K, Exclude<I, Scope.Scope>, any>>({
|
|
156
178
|
[TypeId]: TypeId,
|
|
157
179
|
rcMap,
|
|
158
|
-
get: (key) => Effect.map(RcMap.get(rcMap, key), (
|
|
159
|
-
|
|
160
|
-
Effect.scopedWith((scope) =>
|
|
161
|
-
Effect.flatMap(
|
|
162
|
-
Scope.extend(RcMap.get(rcMap, key), scope),
|
|
163
|
-
([context]) => Effect.provide(effect, context)
|
|
164
|
-
)
|
|
165
|
-
),
|
|
180
|
+
get: (key) => Layer.unwrapScoped(Effect.map(RcMap.get(rcMap, key), ({ layer }) => layer)),
|
|
181
|
+
runtime: (key) => Effect.flatMap(RcMap.get(rcMap, key), ({ runtimeEffect }) => runtimeEffect),
|
|
166
182
|
invalidate: (key) => RcMap.invalidate(rcMap, key)
|
|
167
183
|
})
|
|
168
184
|
})
|
|
@@ -173,10 +189,8 @@ export const make: <
|
|
|
173
189
|
* @experimental
|
|
174
190
|
*/
|
|
175
191
|
export const fromRecord = <
|
|
176
|
-
|
|
177
|
-
const Layers extends Record<string, Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>>
|
|
192
|
+
const Layers extends Record<string, Layer.Layer<any, any, any>>
|
|
178
193
|
>(
|
|
179
|
-
tagOrAccessor: Accessor,
|
|
180
194
|
layers: Layers,
|
|
181
195
|
options?: {
|
|
182
196
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
@@ -184,14 +198,12 @@ export const fromRecord = <
|
|
|
184
198
|
): Effect.Effect<
|
|
185
199
|
LayerMap<
|
|
186
200
|
keyof Layers,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
| Effect.Effect.Error<Accessor>
|
|
190
|
-
| (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
|
|
201
|
+
Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _A : never,
|
|
202
|
+
Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never
|
|
191
203
|
>,
|
|
192
204
|
never,
|
|
193
205
|
Scope.Scope | (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
|
|
194
|
-
> => make(
|
|
206
|
+
> => make((key: keyof Layers) => layers[key], options)
|
|
195
207
|
|
|
196
208
|
/**
|
|
197
209
|
* @since 3.14.0
|
|
@@ -202,11 +214,10 @@ export interface TagClass<
|
|
|
202
214
|
in out Id extends string,
|
|
203
215
|
in out K,
|
|
204
216
|
in out I,
|
|
205
|
-
in out S,
|
|
206
217
|
in out E,
|
|
207
218
|
in out R,
|
|
208
219
|
in out Deps extends Layer.Layer<any, any, any>
|
|
209
|
-
> extends Context.TagClass<Self, Id, LayerMap<K, I,
|
|
220
|
+
> extends Context.TagClass<Self, Id, LayerMap<K, I, E>> {
|
|
210
221
|
/**
|
|
211
222
|
* A default layer for the `LayerMap` service.
|
|
212
223
|
*/
|
|
@@ -223,17 +234,14 @@ export interface TagClass<
|
|
|
223
234
|
readonly DefaultWithoutDependencies: Layer.Layer<Self, never, R>
|
|
224
235
|
|
|
225
236
|
/**
|
|
226
|
-
* Retrieves
|
|
237
|
+
* Retrieves a Layer for the resources associated with the key.
|
|
227
238
|
*/
|
|
228
|
-
readonly get: (key: K) =>
|
|
239
|
+
readonly get: (key: K) => Layer.Layer<I, E, Self>
|
|
229
240
|
|
|
230
241
|
/**
|
|
231
|
-
*
|
|
232
|
-
* effect.
|
|
242
|
+
* Retrieves a Runtime for the resources associated with the key.
|
|
233
243
|
*/
|
|
234
|
-
readonly
|
|
235
|
-
key: K
|
|
236
|
-
) => <A, EX, R>(effect: Effect.Effect<A, EX, R>) => Effect.Effect<A, EX | E, Exclude<R, I> | Self>
|
|
244
|
+
readonly runtime: (key: K) => Effect.Effect<Runtime.Runtime<I>, E, Scope.Scope | Self>
|
|
237
245
|
|
|
238
246
|
/**
|
|
239
247
|
* Invalidates the resource associated with the key.
|
|
@@ -250,46 +258,46 @@ export interface TagClass<
|
|
|
250
258
|
* a key.
|
|
251
259
|
*
|
|
252
260
|
* ```ts
|
|
253
|
-
* import { Completions } from "@effect/ai"
|
|
254
|
-
* import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
|
|
255
|
-
* import { FetchHttpClient } from "@effect/platform"
|
|
256
261
|
* import { NodeRuntime } from "@effect/platform-node"
|
|
257
|
-
* import {
|
|
262
|
+
* import { Context, Effect, FiberRef, Layer, LayerMap } from "effect"
|
|
258
263
|
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
* }).pipe(Layer.provide(FetchHttpClient.layer))
|
|
264
|
+
* class Greeter extends Context.Tag("Greeter")<Greeter, {
|
|
265
|
+
* greet: Effect.Effect<string>
|
|
266
|
+
* }>() {}
|
|
263
267
|
*
|
|
264
268
|
* // create a service that wraps a LayerMap
|
|
265
|
-
* class
|
|
266
|
-
* // this LayerMap will provide the ai Completions service
|
|
267
|
-
* provides: Completions.Completions,
|
|
268
|
-
*
|
|
269
|
+
* class GreeterMap extends LayerMap.Service<GreeterMap>()("GreeterMap", {
|
|
269
270
|
* // define the lookup function for the layer map
|
|
270
271
|
* //
|
|
271
|
-
* // The returned Layer will be used to provide the
|
|
272
|
-
* // given
|
|
273
|
-
* lookup: (
|
|
272
|
+
* // The returned Layer will be used to provide the Greeter service for the
|
|
273
|
+
* // given name.
|
|
274
|
+
* lookup: (name: string) =>
|
|
275
|
+
* Layer.succeed(Greeter, {
|
|
276
|
+
* greet: Effect.succeed(`Hello, ${name}!`)
|
|
277
|
+
* }).pipe(
|
|
278
|
+
* Layer.merge(Layer.locallyScoped(FiberRef.currentConcurrency, 123))
|
|
279
|
+
* ),
|
|
274
280
|
*
|
|
275
281
|
* // If a layer is not used for a certain amount of time, it can be removed
|
|
276
282
|
* idleTimeToLive: "5 seconds",
|
|
277
283
|
*
|
|
278
284
|
* // Supply the dependencies for the layers in the LayerMap
|
|
279
|
-
* dependencies: [
|
|
285
|
+
* dependencies: []
|
|
280
286
|
* }) {}
|
|
281
287
|
*
|
|
282
288
|
* // usage
|
|
283
|
-
* Effect.gen(function*() {
|
|
284
|
-
* // access and use the
|
|
285
|
-
* const
|
|
286
|
-
*
|
|
287
|
-
* console.log(response.text)
|
|
289
|
+
* const program: Effect.Effect<void, never, GreeterMap> = Effect.gen(function*() {
|
|
290
|
+
* // access and use the Greeter service
|
|
291
|
+
* const greeter = yield* Greeter
|
|
292
|
+
* yield* Effect.log(yield* greeter.greet)
|
|
288
293
|
* }).pipe(
|
|
289
|
-
* // use the
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
294
|
+
* // use the GreeterMap service to provide a variant of the Greeter service
|
|
295
|
+
* Effect.provide(GreeterMap.get("John"))
|
|
296
|
+
* )
|
|
297
|
+
*
|
|
298
|
+
* // run the program
|
|
299
|
+
* program.pipe(
|
|
300
|
+
* Effect.provide(GreeterMap.Default),
|
|
293
301
|
* NodeRuntime.runMain
|
|
294
302
|
* )
|
|
295
303
|
* ```
|
|
@@ -297,17 +305,15 @@ export interface TagClass<
|
|
|
297
305
|
export const Service = <Self>() =>
|
|
298
306
|
<
|
|
299
307
|
const Id extends string,
|
|
300
|
-
Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
|
|
301
308
|
Lookup extends {
|
|
302
|
-
readonly lookup: (key: any) => Layer.Layer<
|
|
309
|
+
readonly lookup: (key: any) => Layer.Layer<any, any, any>
|
|
303
310
|
} | {
|
|
304
|
-
readonly layers: Record<string, Layer.Layer<
|
|
311
|
+
readonly layers: Record<string, Layer.Layer<any, any, any>>
|
|
305
312
|
},
|
|
306
313
|
const Deps extends ReadonlyArray<Layer.Layer<any, any, any>> = []
|
|
307
314
|
>(
|
|
308
315
|
id: Id,
|
|
309
316
|
options: Lookup & {
|
|
310
|
-
readonly provides: Accessor
|
|
311
317
|
readonly dependencies?: Deps | undefined
|
|
312
318
|
readonly idleTimeToLive?: Duration.DurationInput | undefined
|
|
313
319
|
}
|
|
@@ -317,9 +323,8 @@ export const Service = <Self>() =>
|
|
|
317
323
|
Lookup extends { readonly lookup: (key: infer K) => any } ? K
|
|
318
324
|
: Lookup extends { readonly layers: infer Layers } ? keyof Layers
|
|
319
325
|
: never,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
Effect.Effect.Error<Accessor> | Service.Error<Lookup>,
|
|
326
|
+
Service.Success<Lookup>,
|
|
327
|
+
Service.Error<Lookup>,
|
|
323
328
|
Service.Context<Lookup>,
|
|
324
329
|
Deps[number]
|
|
325
330
|
> => {
|
|
@@ -330,7 +335,7 @@ export const Service = <Self>() =>
|
|
|
330
335
|
Err.stackTraceLimit = limit
|
|
331
336
|
|
|
332
337
|
function TagClass() {}
|
|
333
|
-
const TagClass_ = TagClass as any as Mutable<TagClass<Self, Id, string, any, any, any, any
|
|
338
|
+
const TagClass_ = TagClass as any as Mutable<TagClass<Self, Id, string, any, any, any, any>>
|
|
334
339
|
Object.setPrototypeOf(TagClass, Object.getPrototypeOf(Context.GenericTag<Self, any>(id)))
|
|
335
340
|
TagClass.key = id
|
|
336
341
|
Object.defineProperty(TagClass, "stack", {
|
|
@@ -338,21 +343,21 @@ export const Service = <Self>() =>
|
|
|
338
343
|
return creationError.stack
|
|
339
344
|
}
|
|
340
345
|
})
|
|
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
|
|
|
346
347
|
TagClass_.DefaultWithoutDependencies = Layer.scoped(
|
|
347
348
|
TagClass_,
|
|
348
349
|
"lookup" in options
|
|
349
|
-
? make(options.
|
|
350
|
-
: fromRecord(options.
|
|
350
|
+
? make(options.lookup, options)
|
|
351
|
+
: fromRecord(options.layers as any, options)
|
|
351
352
|
)
|
|
352
353
|
TagClass_.Default = options.dependencies && options.dependencies.length > 0 ?
|
|
353
354
|
Layer.provide(TagClass_.DefaultWithoutDependencies, options.dependencies as any) :
|
|
354
355
|
TagClass_.DefaultWithoutDependencies
|
|
355
356
|
|
|
357
|
+
TagClass_.get = (key: string) => Layer.unwrapScoped(Effect.map(TagClass_, (layerMap) => layerMap.get(key)))
|
|
358
|
+
TagClass_.runtime = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.runtime(key))
|
|
359
|
+
TagClass_.invalidate = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.invalidate(key))
|
|
360
|
+
|
|
356
361
|
return TagClass as any
|
|
357
362
|
}
|
|
358
363
|
|
|
@@ -380,6 +385,13 @@ export declare namespace Service {
|
|
|
380
385
|
: Options extends { readonly layers: infer Layers } ? Layers[keyof Layers]
|
|
381
386
|
: never
|
|
382
387
|
|
|
388
|
+
/**
|
|
389
|
+
* @since 3.14.0
|
|
390
|
+
* @category Service
|
|
391
|
+
* @experimental
|
|
392
|
+
*/
|
|
393
|
+
export type Success<Options> = Layers<Options> extends Layer.Layer<infer _A, infer _E, infer _R> ? _A : never
|
|
394
|
+
|
|
383
395
|
/**
|
|
384
396
|
* @since 3.14.0
|
|
385
397
|
* @category Service
|
package/src/Schedule.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as internal from "./internal/schedule.js"
|
|
|
14
14
|
import type * as Option from "./Option.js"
|
|
15
15
|
import type { Pipeable } from "./Pipeable.js"
|
|
16
16
|
import type { Predicate } from "./Predicate.js"
|
|
17
|
+
import type * as Ref from "./Ref.js"
|
|
17
18
|
import type * as ScheduleDecision from "./ScheduleDecision.js"
|
|
18
19
|
import type * as Intervals from "./ScheduleIntervals.js"
|
|
19
20
|
import type * as Types from "./Types.js"
|
|
@@ -140,6 +141,7 @@ export declare namespace Schedule {
|
|
|
140
141
|
*/
|
|
141
142
|
export interface ScheduleDriver<out Out, in In = unknown, out R = never> extends Schedule.DriverVariance<Out, In, R> {
|
|
142
143
|
readonly state: Effect.Effect<unknown>
|
|
144
|
+
readonly iterationMeta: Ref.Ref<IterationMetadata>
|
|
143
145
|
readonly last: Effect.Effect<Out, Cause.NoSuchElementException>
|
|
144
146
|
readonly reset: Effect.Effect<void>
|
|
145
147
|
next(input: In): Effect.Effect<Out, Option.Option<never>, R>
|
|
@@ -3705,3 +3707,33 @@ export const zipWith: {
|
|
|
3705
3707
|
f: (out: Out, out2: Out2) => Out3
|
|
3706
3708
|
): Schedule<Out3, In & In2, R | R2>
|
|
3707
3709
|
} = internal.zipWith
|
|
3710
|
+
|
|
3711
|
+
/**
|
|
3712
|
+
* @since 3.15.0
|
|
3713
|
+
* @category models
|
|
3714
|
+
*/
|
|
3715
|
+
export interface CurrentIterationMetadata {
|
|
3716
|
+
readonly _: unique symbol
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3719
|
+
/**
|
|
3720
|
+
* @since 3.15.0
|
|
3721
|
+
* @category models
|
|
3722
|
+
*/
|
|
3723
|
+
export interface IterationMetadata {
|
|
3724
|
+
readonly input: unknown
|
|
3725
|
+
readonly recurrence: number
|
|
3726
|
+
readonly start: number
|
|
3727
|
+
readonly now: number
|
|
3728
|
+
readonly elapsed: Duration.Duration
|
|
3729
|
+
readonly elapsedSincePrevious: Duration.Duration
|
|
3730
|
+
}
|
|
3731
|
+
|
|
3732
|
+
/**
|
|
3733
|
+
* @since 3.15.0
|
|
3734
|
+
* @category models
|
|
3735
|
+
*/
|
|
3736
|
+
export const CurrentIterationMetadata: Context.Reference<
|
|
3737
|
+
CurrentIterationMetadata,
|
|
3738
|
+
IterationMetadata
|
|
3739
|
+
> = internal.CurrentIterationMetadata
|
package/src/Stream.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type * as Deferred from "./Deferred.js"
|
|
|
9
9
|
import type * as Duration from "./Duration.js"
|
|
10
10
|
import type * as Effect from "./Effect.js"
|
|
11
11
|
import type * as Either from "./Either.js"
|
|
12
|
+
import type { ExecutionPlan } from "./ExecutionPlan.js"
|
|
12
13
|
import type * as Exit from "./Exit.js"
|
|
13
14
|
import type { LazyArg } from "./Function.js"
|
|
14
15
|
import type * as GroupBy from "./GroupBy.js"
|
|
@@ -7351,7 +7352,7 @@ export const retry: {
|
|
|
7351
7352
|
* @since 2.0.0
|
|
7352
7353
|
* @category utils
|
|
7353
7354
|
*/
|
|
7354
|
-
<
|
|
7355
|
+
<E, R2, X>(policy: Schedule.Schedule<X, NoInfer<E>, R2>): <A, R>(self: Stream<A, E, R>) => Stream<A, E, R2 | R>
|
|
7355
7356
|
/**
|
|
7356
7357
|
* When the stream fails, retry it according to the given schedule
|
|
7357
7358
|
*
|
|
@@ -7364,9 +7365,57 @@ export const retry: {
|
|
|
7364
7365
|
* @since 2.0.0
|
|
7365
7366
|
* @category utils
|
|
7366
7367
|
*/
|
|
7367
|
-
<A, E, R, X,
|
|
7368
|
+
<A, E, R, X, R2>(self: Stream<A, E, R>, policy: Schedule.Schedule<X, NoInfer<E>, R2>): Stream<A, E, R2 | R>
|
|
7368
7369
|
} = internal.retry
|
|
7369
7370
|
|
|
7371
|
+
/**
|
|
7372
|
+
* Apply an `ExecutionPlan` to the stream, which allows you to fallback to
|
|
7373
|
+
* different resources in case of failure.
|
|
7374
|
+
*
|
|
7375
|
+
* If you have a stream that could fail with partial results, you can use
|
|
7376
|
+
* the `preventFallbackOnPartialStream` option to prevent contamination of
|
|
7377
|
+
* the final stream with partial results.
|
|
7378
|
+
*
|
|
7379
|
+
* @since 3.16.0
|
|
7380
|
+
* @category Error handling
|
|
7381
|
+
* @experimental
|
|
7382
|
+
*/
|
|
7383
|
+
export const withExecutionPlan: {
|
|
7384
|
+
/**
|
|
7385
|
+
* Apply an `ExecutionPlan` to the stream, which allows you to fallback to
|
|
7386
|
+
* different resources in case of failure.
|
|
7387
|
+
*
|
|
7388
|
+
* If you have a stream that could fail with partial results, you can use
|
|
7389
|
+
* the `preventFallbackOnPartialStream` option to prevent contamination of
|
|
7390
|
+
* the final stream with partial results.
|
|
7391
|
+
*
|
|
7392
|
+
* @since 3.16.0
|
|
7393
|
+
* @category Error handling
|
|
7394
|
+
* @experimental
|
|
7395
|
+
*/
|
|
7396
|
+
<Input, R2, Provides, PolicyE>(
|
|
7397
|
+
policy: ExecutionPlan<{ provides: Provides; input: Input; error: PolicyE; requirements: R2 }>,
|
|
7398
|
+
options?: { readonly preventFallbackOnPartialStream?: boolean | undefined }
|
|
7399
|
+
): <A, E extends Input, R>(self: Stream<A, E, R>) => Stream<A, E | PolicyE, R2 | Exclude<R, Provides>>
|
|
7400
|
+
/**
|
|
7401
|
+
* Apply an `ExecutionPlan` to the stream, which allows you to fallback to
|
|
7402
|
+
* different resources in case of failure.
|
|
7403
|
+
*
|
|
7404
|
+
* If you have a stream that could fail with partial results, you can use
|
|
7405
|
+
* the `preventFallbackOnPartialStream` option to prevent contamination of
|
|
7406
|
+
* the final stream with partial results.
|
|
7407
|
+
*
|
|
7408
|
+
* @since 3.16.0
|
|
7409
|
+
* @category Error handling
|
|
7410
|
+
* @experimental
|
|
7411
|
+
*/
|
|
7412
|
+
<A, E extends Input, R, R2, Input, Provides, PolicyE>(
|
|
7413
|
+
self: Stream<A, E, R>,
|
|
7414
|
+
policy: ExecutionPlan<{ provides: Provides; input: Input; error: PolicyE; requirements: R2 }>,
|
|
7415
|
+
options?: { readonly preventFallbackOnPartialStream?: boolean | undefined }
|
|
7416
|
+
): Stream<A, E | PolicyE, R2 | Exclude<R, Provides>>
|
|
7417
|
+
} = internal.withExecutionPlan
|
|
7418
|
+
|
|
7370
7419
|
/**
|
|
7371
7420
|
* Runs the sink on the stream to produce either the sink's result or an error.
|
|
7372
7421
|
*
|
package/src/index.ts
CHANGED
|
@@ -263,6 +263,12 @@ export * as Equal from "./Equal.js"
|
|
|
263
263
|
*/
|
|
264
264
|
export * as Equivalence from "./Equivalence.js"
|
|
265
265
|
|
|
266
|
+
/**
|
|
267
|
+
* @since 3.16.0
|
|
268
|
+
* @experimental
|
|
269
|
+
*/
|
|
270
|
+
export * as ExecutionPlan from "./ExecutionPlan.js"
|
|
271
|
+
|
|
266
272
|
/**
|
|
267
273
|
* @since 2.0.0
|
|
268
274
|
*/
|
package/src/internal/config.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as Brand from "../Brand.js"
|
|
1
2
|
import * as Chunk from "../Chunk.js"
|
|
2
3
|
import type * as Config from "../Config.js"
|
|
3
4
|
import * as ConfigError from "../ConfigError.js"
|
|
@@ -192,6 +193,33 @@ export const url = (name?: string): Config.Config<URL> => {
|
|
|
192
193
|
return name === undefined ? config : nested(config, name)
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
/** @internal */
|
|
197
|
+
export const port = (name?: string): Config.Config<number> => {
|
|
198
|
+
const config = primitive(
|
|
199
|
+
"a network port property",
|
|
200
|
+
(text) => {
|
|
201
|
+
const result = Number(text)
|
|
202
|
+
|
|
203
|
+
if (
|
|
204
|
+
Number.isNaN(result) ||
|
|
205
|
+
result.toString() !== text.toString() ||
|
|
206
|
+
!Number.isInteger(result) ||
|
|
207
|
+
result < 1 ||
|
|
208
|
+
result > 65535
|
|
209
|
+
) {
|
|
210
|
+
return Either.left(
|
|
211
|
+
configError.InvalidData(
|
|
212
|
+
[],
|
|
213
|
+
`Expected a network port value but received ${text}`
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
return Either.right(result)
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
return name === undefined ? config : nested(config, name)
|
|
221
|
+
}
|
|
222
|
+
|
|
195
223
|
/** @internal */
|
|
196
224
|
export const array = <A>(config: Config.Config<A>, name?: string): Config.Config<Array<A>> => {
|
|
197
225
|
return pipe(chunk(config, name), map(Chunk.toArray))
|
|
@@ -444,6 +472,33 @@ export const redacted = <A>(
|
|
|
444
472
|
return map(config, redacted_.make)
|
|
445
473
|
}
|
|
446
474
|
|
|
475
|
+
/** @internal */
|
|
476
|
+
export const branded: {
|
|
477
|
+
<A, B extends Brand.Branded<A, any>>(
|
|
478
|
+
constructor: Brand.Brand.Constructor<B>
|
|
479
|
+
): (config: Config.Config<A>) => Config.Config<B>
|
|
480
|
+
<B extends Brand.Branded<string, any>>(
|
|
481
|
+
name: string | undefined,
|
|
482
|
+
constructor: Brand.Brand.Constructor<B>
|
|
483
|
+
): Config.Config<B>
|
|
484
|
+
<A, B extends Brand.Branded<A, any>>(
|
|
485
|
+
config: Config.Config<A>,
|
|
486
|
+
constructor: Brand.Brand.Constructor<B>
|
|
487
|
+
): Config.Config<B>
|
|
488
|
+
} = dual(2, <A, B extends Brand.Brand.Constructor<any>>(
|
|
489
|
+
nameOrConfig: Config.Config<NoInfer<A>> | string | undefined,
|
|
490
|
+
constructor: B
|
|
491
|
+
) => {
|
|
492
|
+
const config: Config.Config<string | A> = isConfig(nameOrConfig) ? nameOrConfig : string(nameOrConfig)
|
|
493
|
+
|
|
494
|
+
return mapOrFail(config, (a) =>
|
|
495
|
+
constructor.either(a).pipe(
|
|
496
|
+
Either.mapLeft((brandErrors) =>
|
|
497
|
+
configError.InvalidData([], brandErrors.map((brandError) => brandError.message).join("\n"))
|
|
498
|
+
)
|
|
499
|
+
))
|
|
500
|
+
})
|
|
501
|
+
|
|
447
502
|
/** @internal */
|
|
448
503
|
export const hashSet = <A>(config: Config.Config<A>, name?: string): Config.Config<HashSet.HashSet<A>> => {
|
|
449
504
|
const newConfig = map(chunk(config), HashSet.fromIterable)
|
|
@@ -18,7 +18,6 @@ import { pipeArguments } from "../../Pipeable.js"
|
|
|
18
18
|
import * as Predicate from "../../Predicate.js"
|
|
19
19
|
import * as Readable from "../../Readable.js"
|
|
20
20
|
import type * as Ref from "../../Ref.js"
|
|
21
|
-
import type * as Schedule from "../../Schedule.js"
|
|
22
21
|
import { currentScheduler } from "../../Scheduler.js"
|
|
23
22
|
import type * as Scope from "../../Scope.js"
|
|
24
23
|
import type * as Supervisor from "../../Supervisor.js"
|
|
@@ -31,7 +30,6 @@ import * as internalFiber from "../fiber.js"
|
|
|
31
30
|
import * as fiberRuntime from "../fiberRuntime.js"
|
|
32
31
|
import { globalScope } from "../fiberScope.js"
|
|
33
32
|
import * as internalRef from "../ref.js"
|
|
34
|
-
import * as schedule_ from "../schedule.js"
|
|
35
33
|
import * as supervisor from "../supervisor.js"
|
|
36
34
|
|
|
37
35
|
/** @internal */
|
|
@@ -477,19 +475,6 @@ export const raceFirst = dual<
|
|
|
477
475
|
(effect: Effect.Effect<Exit.Exit<A | A2, E | E2>, never, R | R2>) => core.flatten(effect)
|
|
478
476
|
))
|
|
479
477
|
|
|
480
|
-
/** @internal */
|
|
481
|
-
export const scheduleForked = dual<
|
|
482
|
-
<Out, R2>(
|
|
483
|
-
schedule: Schedule.Schedule<Out, unknown, R2>
|
|
484
|
-
) => <A, E, R>(
|
|
485
|
-
self: Effect.Effect<A, E, R>
|
|
486
|
-
) => Effect.Effect<Fiber.RuntimeFiber<Out, E>, never, R | R2 | Scope.Scope>,
|
|
487
|
-
<A, E, R, Out, R2>(
|
|
488
|
-
self: Effect.Effect<A, E, R>,
|
|
489
|
-
schedule: Schedule.Schedule<Out, unknown, R2>
|
|
490
|
-
) => Effect.Effect<Fiber.RuntimeFiber<Out, E>, never, R | R2 | Scope.Scope>
|
|
491
|
-
>(2, (self, schedule) => pipe(self, schedule_.schedule_Effect(schedule), forkScoped))
|
|
492
|
-
|
|
493
478
|
/** @internal */
|
|
494
479
|
export const supervised = dual<
|
|
495
480
|
<X>(supervisor: Supervisor.Supervisor<X>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|