effect 4.0.0-rc.118 → 4.0.1
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/README.md +17 -4
- package/dist/Array.d.ts +25 -25
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +16 -16
- package/dist/Array.js.map +1 -1
- package/dist/Cache.d.ts.map +1 -1
- package/dist/Cache.js +20 -16
- package/dist/Cache.js.map +1 -1
- package/dist/Cause.d.ts.map +1 -1
- package/dist/Cause.js +1 -1
- package/dist/Cause.js.map +1 -1
- package/dist/Chunk.d.ts +26 -26
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Chunk.js +15 -15
- package/dist/Chunk.js.map +1 -1
- package/dist/Effect.d.ts +167 -39
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +16 -10
- package/dist/Effect.js.map +1 -1
- package/dist/HashRing.d.ts.map +1 -1
- package/dist/HashRing.js +13 -5
- package/dist/HashRing.js.map +1 -1
- package/dist/MutableHashMap.d.ts.map +1 -1
- package/dist/MutableHashMap.js +4 -22
- package/dist/MutableHashMap.js.map +1 -1
- package/dist/Option.d.ts +17 -17
- package/dist/Option.d.ts.map +1 -1
- package/dist/Option.js +6 -6
- package/dist/Option.js.map +1 -1
- package/dist/Pool.d.ts +9 -5
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +34 -41
- package/dist/Pool.js.map +1 -1
- package/dist/Queue.d.ts +19 -2
- package/dist/Queue.d.ts.map +1 -1
- package/dist/Queue.js +9 -4
- package/dist/Queue.js.map +1 -1
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +16 -1
- package/dist/RcMap.js.map +1 -1
- package/dist/Record.d.ts +14 -14
- package/dist/Record.d.ts.map +1 -1
- package/dist/Record.js +10 -10
- package/dist/Record.js.map +1 -1
- package/dist/Schema.d.ts +37 -21
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +29 -10
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +116 -97
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +3 -1
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +3 -1
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +24 -16
- package/dist/ScopedCache.js.map +1 -1
- package/dist/Stream.d.ts +45 -6
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +55 -44
- package/dist/Stream.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts +8 -0
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +13 -2
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +402 -402
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpSchema.js +1 -1
- package/dist/ai/McpSchema.js.map +1 -1
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +11 -3
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +22 -12
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +1 -0
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +1 -0
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +1 -0
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +1 -0
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2024_11_05.js +3 -1
- package/dist/ai/internal/mcpSchema/v2024_11_05.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +16 -3
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +32 -8
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +2 -1
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Sharding.d.ts +5 -2
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +15 -8
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +36 -16
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +30 -44
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +63 -62
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/cluster/internal/interruptors.js +8 -0
- package/dist/cluster/internal/interruptors.js.map +1 -1
- package/dist/cluster/internal/resourceMap.js +39 -14
- package/dist/cluster/internal/resourceMap.js.map +1 -1
- package/dist/cluster/internal/resourceRef.js +168 -87
- package/dist/cluster/internal/resourceRef.js.map +1 -1
- package/dist/http/HttpEffect.d.ts +1 -0
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +29 -22
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +3 -2
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +14 -0
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts +1 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +4 -4
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +1 -0
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +1 -0
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/internal/core.js +43 -2
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/dateTime.js +1 -1
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +138 -165
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/rcRef.js +59 -23
- package/dist/internal/rcRef.js.map +1 -1
- package/dist/internal/schema/annotations.js +1 -7
- package/dist/internal/schema/annotations.js.map +1 -1
- package/dist/internal/schema/codegen.js +56 -28
- package/dist/internal/schema/codegen.js.map +1 -1
- package/dist/internal/schema/fromJsonSchemaDocument.js +11 -8
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +10 -30
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +1 -15
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toEquivalence.js +4 -3
- package/dist/internal/schema/toEquivalence.js.map +1 -1
- package/dist/internal/schema/toFormatter.js +4 -4
- package/dist/internal/schema/toFormatter.js.map +1 -1
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +6 -2
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomRpc.d.ts +3 -3
- package/dist/reactivity/AtomRpc.d.ts.map +1 -1
- package/dist/rpc/Rpc.d.ts +2 -2
- package/dist/rpc/Rpc.d.ts.map +1 -1
- package/dist/rpc/RpcClient.d.ts +7 -7
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +21 -16
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcMessage.d.ts +1 -1
- package/dist/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +2 -2
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/rpc/Utils.d.ts +2 -3
- package/dist/rpc/Utils.d.ts.map +1 -1
- package/dist/rpc/Utils.js +3 -4
- package/dist/rpc/Utils.js.map +1 -1
- package/dist/schema/SchemaCompiler/runtime.js +6 -1
- package/dist/schema/SchemaCompiler/runtime.js.map +1 -1
- package/dist/testing/TestSchema.d.ts +234 -6
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js +244 -25
- package/dist/testing/TestSchema.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/DurableDeferred.js +1 -1
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/Workflow.js +1 -1
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +2 -0
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +1 -0
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +1 -1
- package/src/Array.ts +31 -31
- package/src/Cache.ts +22 -16
- package/src/Cause.ts +1 -1
- package/src/Chunk.ts +29 -29
- package/src/Effect.ts +170 -39
- package/src/HashRing.ts +14 -5
- package/src/MutableHashMap.ts +4 -24
- package/src/Option.ts +19 -19
- package/src/Pool.ts +28 -36
- package/src/Queue.ts +26 -6
- package/src/RcMap.ts +26 -2
- package/src/Record.ts +20 -20
- package/src/Schema.ts +48 -24
- package/src/SchemaAST.ts +135 -115
- package/src/SchemaRepresentation.ts +3 -1
- package/src/ScopedCache.ts +27 -16
- package/src/Stream.ts +158 -88
- package/src/ai/LanguageModel.ts +27 -2
- package/src/ai/McpSchema.ts +3 -3
- package/src/ai/McpServer.ts +12 -3
- package/src/ai/Response.ts +27 -12
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +1 -0
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +1 -0
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +1 -0
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +1 -0
- package/src/ai/internal/mcpSchema/v2024_11_05.ts +4 -2
- package/src/cluster/ClusterWorkflowEngine.ts +26 -5
- package/src/cluster/MessageStorage.ts +22 -5
- package/src/cluster/Sharding.ts +32 -28
- package/src/cluster/SqlMessageStorage.ts +45 -21
- package/src/cluster/SqlRunnerStorage.ts +85 -113
- package/src/cluster/internal/entityManager.ts +68 -80
- package/src/cluster/internal/interruptors.ts +13 -0
- package/src/cluster/internal/resourceMap.ts +55 -17
- package/src/cluster/internal/resourceRef.ts +189 -96
- package/src/http/HttpEffect.ts +15 -9
- package/src/http/HttpMiddleware.ts +8 -2
- package/src/http/HttpStaticServer.ts +16 -0
- package/src/http/HttpTraceContext.ts +8 -4
- package/src/http-api/HttpApiError.ts +1 -0
- package/src/internal/core.ts +56 -2
- package/src/internal/dateTime.ts +3 -1
- package/src/internal/effect.ts +146 -173
- package/src/internal/rcRef.ts +83 -33
- package/src/internal/schema/annotations.ts +0 -9
- package/src/internal/schema/codegen.ts +90 -43
- package/src/internal/schema/fromJsonSchemaDocument.ts +5 -3
- package/src/internal/schema/toCodeDocument.ts +10 -47
- package/src/internal/schema/toCodec.ts +3 -16
- package/src/internal/schema/toEquivalence.ts +4 -5
- package/src/internal/schema/toFormatter.ts +4 -6
- package/src/reactivity/Atom.ts +6 -2
- package/src/reactivity/AtomRpc.ts +5 -5
- package/src/rpc/Rpc.ts +2 -2
- package/src/rpc/RpcClient.ts +35 -32
- package/src/rpc/RpcMessage.ts +1 -1
- package/src/rpc/RpcServer.ts +2 -1
- package/src/rpc/Utils.ts +4 -10
- package/src/schema/SchemaCompiler/runtime.ts +17 -1
- package/src/testing/TestSchema.ts +315 -63
- package/src/testing/index.ts +1 -0
- package/src/workflow/DurableDeferred.ts +1 -1
- package/src/workflow/Workflow.ts +1 -1
- package/src/workflow/WorkflowEngine.ts +4 -0
package/src/internal/effect.ts
CHANGED
|
@@ -50,7 +50,7 @@ import type { Primitive } from "./core.ts"
|
|
|
50
50
|
import {
|
|
51
51
|
args,
|
|
52
52
|
causeAnnotate,
|
|
53
|
-
|
|
53
|
+
causeCombine,
|
|
54
54
|
causeEmpty,
|
|
55
55
|
causeFromReasons,
|
|
56
56
|
CauseImpl,
|
|
@@ -238,48 +238,6 @@ export const causeAnnotations = <E>(
|
|
|
238
238
|
return Context.makeUnsafe(map)
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
const dedupeReasons = <E>(
|
|
242
|
-
self: ReadonlyArray<Cause.Reason<E>>,
|
|
243
|
-
that: ReadonlyArray<Cause.Reason<E>>
|
|
244
|
-
): Array<Cause.Reason<E>> => {
|
|
245
|
-
// Keep deduplication local so causeCombine does not retain Array.ts in the core bundle.
|
|
246
|
-
// Snapshot both arrays before invoking user-defined hash or equality methods.
|
|
247
|
-
const buckets = new Map<number, Array<Cause.Reason<E>>>()
|
|
248
|
-
const out: Array<Cause.Reason<E>> = []
|
|
249
|
-
for (const reason of self.concat(that)) {
|
|
250
|
-
const hash = Hash.hash(reason)
|
|
251
|
-
const bucket = buckets.get(hash)
|
|
252
|
-
if (bucket === undefined) {
|
|
253
|
-
buckets.set(hash, [reason])
|
|
254
|
-
} else if (bucket.some((previous) => Equal.equals(previous, reason))) {
|
|
255
|
-
continue
|
|
256
|
-
} else {
|
|
257
|
-
bucket.push(reason)
|
|
258
|
-
}
|
|
259
|
-
out.push(reason)
|
|
260
|
-
}
|
|
261
|
-
return out
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/** @internal */
|
|
265
|
-
export const causeCombine: {
|
|
266
|
-
<E2>(that: Cause.Cause<E2>): <E>(self: Cause.Cause<E>) => Cause.Cause<E | E2>
|
|
267
|
-
<E, E2>(self: Cause.Cause<E>, that: Cause.Cause<E2>): Cause.Cause<E | E2>
|
|
268
|
-
} = dual(
|
|
269
|
-
2,
|
|
270
|
-
<E, E2>(self: Cause.Cause<E>, that: Cause.Cause<E2>): Cause.Cause<E | E2> => {
|
|
271
|
-
if (self.reasons.length === 0) {
|
|
272
|
-
return that as Cause.Cause<E | E2>
|
|
273
|
-
} else if (that.reasons.length === 0) {
|
|
274
|
-
return self as Cause.Cause<E | E2>
|
|
275
|
-
}
|
|
276
|
-
const newCause = new CauseImpl<E | E2>(
|
|
277
|
-
dedupeReasons<E | E2>(self.reasons, that.reasons)
|
|
278
|
-
)
|
|
279
|
-
return Equal.equals(self, newCause) ? self : newCause
|
|
280
|
-
}
|
|
281
|
-
)
|
|
282
|
-
|
|
283
241
|
/** @internal */
|
|
284
242
|
export const causeMap: {
|
|
285
243
|
<E, E2>(f: (error: NoInfer<E>) => E2): (self: Cause.Cause<E>) => Cause.Cause<E2>
|
|
@@ -504,6 +462,21 @@ const fiberVariance = {
|
|
|
504
462
|
|
|
505
463
|
const fiberIdStore = { id: 0 }
|
|
506
464
|
|
|
465
|
+
interface AsyncContext {
|
|
466
|
+
runInAsyncScope<This, Arg, R>(fn: (this: This, arg: Arg) => R, thisArg: This, arg: Arg): R
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const AsyncResource: (new(type: string) => AsyncContext) | undefined = (() => {
|
|
470
|
+
try {
|
|
471
|
+
return (globalThis as any).process?.getBuiltinModule?.("node:async_hooks")?.AsyncResource
|
|
472
|
+
} catch {
|
|
473
|
+
return undefined
|
|
474
|
+
}
|
|
475
|
+
})()
|
|
476
|
+
|
|
477
|
+
const captureAsyncContext = (): AsyncContext | undefined =>
|
|
478
|
+
AsyncResource === undefined ? undefined : new AsyncResource("effect/Fiber")
|
|
479
|
+
|
|
507
480
|
/** @internal */
|
|
508
481
|
export const getCurrentFiber = (): Fiber.Fiber<any, any> | undefined => (globalThis as any)[currentFiberTypeId]
|
|
509
482
|
|
|
@@ -526,6 +499,7 @@ export class FiberImpl<A = any, E = any> implements Fiber.Fiber<A, E> {
|
|
|
526
499
|
this._running = false
|
|
527
500
|
this._deferredInterrupt = false
|
|
528
501
|
this._parent = undefined
|
|
502
|
+
this._asyncContext = undefined
|
|
529
503
|
this.cache.runtimeMetrics?.recordFiberStart(this.context)
|
|
530
504
|
}
|
|
531
505
|
|
|
@@ -545,6 +519,7 @@ export class FiberImpl<A = any, E = any> implements Fiber.Fiber<A, E> {
|
|
|
545
519
|
declare _running: boolean
|
|
546
520
|
declare _deferredInterrupt: boolean
|
|
547
521
|
declare _parent: FiberImpl<any, any> | undefined
|
|
522
|
+
declare _asyncContext: AsyncContext | undefined
|
|
548
523
|
|
|
549
524
|
// set in setContext
|
|
550
525
|
declare context: Context.Context<never>
|
|
@@ -605,6 +580,10 @@ export class FiberImpl<A = any, E = any> implements Fiber.Fiber<A, E> {
|
|
|
605
580
|
evaluate(effect: Primitive): void {
|
|
606
581
|
if (this._exit) {
|
|
607
582
|
return
|
|
583
|
+
} else if (this._asyncContext !== undefined) {
|
|
584
|
+
const asyncContext = this._asyncContext
|
|
585
|
+
this._asyncContext = undefined
|
|
586
|
+
return asyncContext.runInAsyncScope(this.evaluate, this, effect)
|
|
608
587
|
} else if (this._yielded !== undefined) {
|
|
609
588
|
const yielded = this._yielded as () => void
|
|
610
589
|
this._yielded = undefined
|
|
@@ -612,6 +591,7 @@ export class FiberImpl<A = any, E = any> implements Fiber.Fiber<A, E> {
|
|
|
612
591
|
}
|
|
613
592
|
const exit = this.runLoop(effect)
|
|
614
593
|
if (exit === Yield) {
|
|
594
|
+
this._asyncContext = captureAsyncContext()
|
|
615
595
|
return
|
|
616
596
|
}
|
|
617
597
|
// the interruptChildren middleware is added in Effect.forkChild, so it can be
|
|
@@ -1122,20 +1102,22 @@ export const tryPromise = <A, E = Cause.UnknownError>(
|
|
|
1122
1102
|
? ((cause: unknown) => new UnknownError(cause, "An error occurred in Effect.tryPromise"))
|
|
1123
1103
|
: options.catch
|
|
1124
1104
|
return callbackOptions<A, E>(function(resume, signal) {
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1105
|
+
// Defer the catcher until the fiber restores its async context.
|
|
1106
|
+
const failWithCatch = (cause: unknown) =>
|
|
1107
|
+
suspend(() => {
|
|
1108
|
+
try {
|
|
1109
|
+
return fail(internalCall(() => catcher(cause)) as E)
|
|
1110
|
+
} catch (err) {
|
|
1111
|
+
return die(err)
|
|
1112
|
+
}
|
|
1113
|
+
})
|
|
1132
1114
|
try {
|
|
1133
1115
|
f(signal!).then(
|
|
1134
1116
|
(a) => resume(succeed(a)),
|
|
1135
|
-
failWithCatch
|
|
1117
|
+
(e) => resume(failWithCatch(e))
|
|
1136
1118
|
)
|
|
1137
1119
|
} catch (err) {
|
|
1138
|
-
failWithCatch(err)
|
|
1120
|
+
resume(failWithCatch(err))
|
|
1139
1121
|
}
|
|
1140
1122
|
}, f.length !== 0)
|
|
1141
1123
|
}
|
|
@@ -1156,7 +1138,7 @@ const callbackOptions: <A, E = never, R = never>(
|
|
|
1156
1138
|
this: Scheduler.Scheduler,
|
|
1157
1139
|
resume: (effect: Effect.Effect<A, E, R>) => void,
|
|
1158
1140
|
signal?: AbortSignal
|
|
1159
|
-
) => void | Effect.Effect<void,
|
|
1141
|
+
) => void | Effect.Effect<void, E, R>,
|
|
1160
1142
|
withSignal: boolean
|
|
1161
1143
|
) => Effect.Effect<A, E, R> = (function() {
|
|
1162
1144
|
const Proto = makePrimitiveProto({
|
|
@@ -1214,7 +1196,7 @@ const asyncFinalizer: (
|
|
|
1214
1196
|
},
|
|
1215
1197
|
[contE](cause, _fiber) {
|
|
1216
1198
|
return hasInterrupts(cause)
|
|
1217
|
-
? flatMap(this[args](), () => failCause(cause))
|
|
1199
|
+
? flatMap(combineFinalizerCause(exitFailCause(cause), this[args]()), () => failCause(cause))
|
|
1218
1200
|
: failCause(cause)
|
|
1219
1201
|
}
|
|
1220
1202
|
})
|
|
@@ -1225,7 +1207,7 @@ export const callback = <A, E = never, R = never>(
|
|
|
1225
1207
|
this: Scheduler.Scheduler,
|
|
1226
1208
|
resume: (effect: Effect.Effect<A, E, R>) => void,
|
|
1227
1209
|
signal: AbortSignal
|
|
1228
|
-
) => void | Effect.Effect<void,
|
|
1210
|
+
) => void | Effect.Effect<void, E, R>
|
|
1229
1211
|
): Effect.Effect<A, E, R> => callbackOptions(register as any, register.length >= 2)
|
|
1230
1212
|
|
|
1231
1213
|
/** @internal */
|
|
@@ -1632,13 +1614,15 @@ export const raceAll = <Eff extends Effect.Effect<any, any, any>>(
|
|
|
1632
1614
|
Effect.Error<Eff>,
|
|
1633
1615
|
Effect.Services<Eff>
|
|
1634
1616
|
> =>
|
|
1635
|
-
withFiber((parent) =>
|
|
1636
|
-
|
|
1617
|
+
withFiber((parent) => {
|
|
1618
|
+
const fibers = new Set<Fiber.Fiber<any, any>>()
|
|
1619
|
+
// Read fibers on exit to include losers forked after the race settles.
|
|
1620
|
+
onExitUnsafe(parent, () => fibers.size === 0 ? undefined : fiberInterruptAll(fibers))
|
|
1621
|
+
return callback((resume) => {
|
|
1637
1622
|
const effects = Arr.fromIterable(all)
|
|
1638
1623
|
const len = effects.length
|
|
1639
1624
|
let doneCount = 0
|
|
1640
1625
|
let done = false
|
|
1641
|
-
const fibers = new Set<Fiber.Fiber<any, any>>()
|
|
1642
1626
|
const failures: Array<Cause.Reason<any>> = []
|
|
1643
1627
|
const onExit = (exit: Exit.Exit<any, any>, fiber: Fiber.Fiber<any, any>, i: number) => {
|
|
1644
1628
|
doneCount++
|
|
@@ -1651,11 +1635,7 @@ export const raceAll = <Eff extends Effect.Effect<any, any, any>>(
|
|
|
1651
1635
|
}
|
|
1652
1636
|
const isWinner = !done
|
|
1653
1637
|
done = true
|
|
1654
|
-
resume(
|
|
1655
|
-
fibers.size === 0
|
|
1656
|
-
? exit
|
|
1657
|
-
: flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit)
|
|
1658
|
-
)
|
|
1638
|
+
resume(exit)
|
|
1659
1639
|
if (isWinner && options?.onWinner) {
|
|
1660
1640
|
options.onWinner({ fiber, index: i, parentFiber: parent })
|
|
1661
1641
|
}
|
|
@@ -1670,10 +1650,8 @@ export const raceAll = <Eff extends Effect.Effect<any, any, any>>(
|
|
|
1670
1650
|
})
|
|
1671
1651
|
if (done) break
|
|
1672
1652
|
}
|
|
1673
|
-
|
|
1674
|
-
return fiberInterruptAll(fibers)
|
|
1675
1653
|
})
|
|
1676
|
-
)
|
|
1654
|
+
})
|
|
1677
1655
|
|
|
1678
1656
|
/** @internal */
|
|
1679
1657
|
export const raceAllFirst = <Eff extends Effect.Effect<any, any, any>>(
|
|
@@ -1690,19 +1668,11 @@ export const raceAllFirst = <Eff extends Effect.Effect<any, any, any>>(
|
|
|
1690
1668
|
Effect.Error<Eff>,
|
|
1691
1669
|
Effect.Services<Eff>
|
|
1692
1670
|
> =>
|
|
1693
|
-
withFiber((parent) =>
|
|
1694
|
-
|
|
1671
|
+
withFiber((parent) => {
|
|
1672
|
+
const fibers = new Set<Fiber.Fiber<any, any>>()
|
|
1673
|
+
onExitUnsafe(parent, () => fibers.size === 0 ? undefined : fiberInterruptAll(fibers))
|
|
1674
|
+
return callback((resume) => {
|
|
1695
1675
|
let done = false
|
|
1696
|
-
const fibers = new Set<Fiber.Fiber<any, any>>()
|
|
1697
|
-
const onExit = (exit: Exit.Exit<any, any>) => {
|
|
1698
|
-
done = true
|
|
1699
|
-
resume(
|
|
1700
|
-
fibers.size === 0
|
|
1701
|
-
? exit
|
|
1702
|
-
: flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit)
|
|
1703
|
-
)
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1706
1676
|
let i = 0
|
|
1707
1677
|
for (const effect of all) {
|
|
1708
1678
|
if (done) break
|
|
@@ -1712,16 +1682,15 @@ export const raceAllFirst = <Eff extends Effect.Effect<any, any, any>>(
|
|
|
1712
1682
|
fiber.addObserver((exit) => {
|
|
1713
1683
|
fibers.delete(fiber)
|
|
1714
1684
|
const isWinner = !done
|
|
1715
|
-
|
|
1685
|
+
done = true
|
|
1686
|
+
resume(exit)
|
|
1716
1687
|
if (isWinner && options?.onWinner) {
|
|
1717
1688
|
options.onWinner({ fiber, index, parentFiber: parent })
|
|
1718
1689
|
}
|
|
1719
1690
|
})
|
|
1720
1691
|
}
|
|
1721
|
-
|
|
1722
|
-
return fiberInterruptAll(fibers)
|
|
1723
1692
|
})
|
|
1724
|
-
)
|
|
1693
|
+
})
|
|
1725
1694
|
|
|
1726
1695
|
/** @internal */
|
|
1727
1696
|
export const race: {
|
|
@@ -4470,48 +4439,78 @@ export const cachedInvalidateWithTTL: {
|
|
|
4470
4439
|
self: Effect.Effect<A, E, R>,
|
|
4471
4440
|
ttl: Duration.Input | ((exit: Exit.Exit<A, E>) => Duration.Input)
|
|
4472
4441
|
): Effect.Effect<[Effect.Effect<A, E, R>, Effect.Effect<void>]> =>
|
|
4473
|
-
sync(() =>
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4442
|
+
sync(() =>
|
|
4443
|
+
makeCachedUnsafe(
|
|
4444
|
+
self,
|
|
4445
|
+
typeof ttl === "function"
|
|
4446
|
+
? (exit: Exit.Exit<A, E>) => Duration.toMillis(Duration.fromInputUnsafe(ttl(exit)))
|
|
4447
|
+
: constant(Duration.toMillis(Duration.fromInputUnsafe(ttl)))
|
|
4448
|
+
)
|
|
4449
|
+
))
|
|
4450
|
+
|
|
4451
|
+
const infiniteTTL = constant(Infinity)
|
|
4452
|
+
|
|
4453
|
+
interface CachedRun<A, E> {
|
|
4454
|
+
fiber: FiberImpl<A, E> | undefined
|
|
4455
|
+
awaiters: number
|
|
4456
|
+
}
|
|
4457
|
+
|
|
4458
|
+
const makeCachedUnsafe = <A, E, R>(
|
|
4459
|
+
self: Effect.Effect<A, E, R>,
|
|
4460
|
+
ttlMillis: (exit: Exit.Exit<A, E>) => number
|
|
4461
|
+
): [Effect.Effect<A, E, R>, Effect.Effect<void>] => {
|
|
4462
|
+
let expiresAt = 0
|
|
4463
|
+
let exit: Exit.Exit<A, E> | undefined
|
|
4464
|
+
let current: CachedRun<A, E> | undefined
|
|
4465
|
+
|
|
4466
|
+
const join = (fiber: Fiber.Fiber<unknown, unknown>, run: CachedRun<A, E>): Effect.Effect<A, E> => {
|
|
4467
|
+
run.awaiters++
|
|
4468
|
+
onExitUnsafe(fiber, () => {
|
|
4469
|
+
// Abandon the run once every caller has left, unless it already finished.
|
|
4470
|
+
if (--run.awaiters > 0 || current !== run) return
|
|
4471
|
+
// Detach it first so new callers start a fresh run instead of joining
|
|
4472
|
+
// one that is being interrupted.
|
|
4473
|
+
current = undefined
|
|
4474
|
+
return fiberInterrupt(run.fiber!)
|
|
4475
|
+
})
|
|
4476
|
+
return fiberJoin(run.fiber!)
|
|
4477
|
+
}
|
|
4478
|
+
|
|
4479
|
+
return [
|
|
4480
|
+
withFiber((fiber) => {
|
|
4481
|
+
if (current !== undefined) return join(fiber, current)
|
|
4482
|
+
if (
|
|
4483
|
+
exit !== undefined &&
|
|
4484
|
+
(expiresAt === Infinity || fiber.getRef(ClockRef).currentTimeMillisUnsafe() < expiresAt)
|
|
4485
|
+
) {
|
|
4486
|
+
return exit
|
|
4487
|
+
}
|
|
4488
|
+
exit = undefined
|
|
4489
|
+
const clock = fiber.getRef(ClockRef)
|
|
4490
|
+
const run: CachedRun<A, E> = { fiber: undefined, awaiters: 0 }
|
|
4491
|
+
current = run
|
|
4492
|
+
run.fiber = forkUnsafe(
|
|
4493
|
+
fiber,
|
|
4494
|
+
onExitPrimitive(self, (exit_) => {
|
|
4495
|
+
// An abandoned run must not overwrite or clear a replacement run.
|
|
4496
|
+
if (current !== run) return
|
|
4497
|
+
current = undefined
|
|
4498
|
+
// Interruption is abandonment, so it is never cached.
|
|
4499
|
+
if (exitHasInterrupts(exit_)) return
|
|
4500
|
+
const duration = ttlMillis(exit_)
|
|
4501
|
+
expiresAt = duration === Infinity ? Infinity : clock.currentTimeMillisUnsafe() + duration
|
|
4502
|
+
exit = exit_
|
|
4503
|
+
}),
|
|
4504
|
+
true,
|
|
4505
|
+
true
|
|
4506
|
+
)
|
|
4507
|
+
return run.fiber._exit ?? join(fiber, run)
|
|
4508
|
+
}),
|
|
4509
|
+
sync(() => {
|
|
4510
|
+
exit = undefined
|
|
4511
|
+
})
|
|
4512
|
+
]
|
|
4513
|
+
}
|
|
4515
4514
|
|
|
4516
4515
|
/** @internal */
|
|
4517
4516
|
export const cachedWithTTL: {
|
|
@@ -4538,23 +4537,7 @@ export const cachedWithTTL: {
|
|
|
4538
4537
|
|
|
4539
4538
|
/** @internal */
|
|
4540
4539
|
export const cached = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Effect.Effect<A, E, R>> =>
|
|
4541
|
-
sync(() =>
|
|
4542
|
-
const latch = makeLatchUnsafe(false)
|
|
4543
|
-
let started = false
|
|
4544
|
-
let exit: Exit.Exit<A, E> | undefined
|
|
4545
|
-
const wait = flatMap(latch.await, () => exit!)
|
|
4546
|
-
return withFiber((fiber) => {
|
|
4547
|
-
if (exit !== undefined) return exit
|
|
4548
|
-
if (started) return wait
|
|
4549
|
-
started = true
|
|
4550
|
-
onExitUnsafe<A, E>(fiber, (result) =>
|
|
4551
|
-
sync(() => {
|
|
4552
|
-
exit = result
|
|
4553
|
-
latch.openUnsafe()
|
|
4554
|
-
}))
|
|
4555
|
-
return self
|
|
4556
|
-
})
|
|
4557
|
-
})
|
|
4540
|
+
sync(() => makeCachedUnsafe(self, infiniteTTL)[0])
|
|
4558
4541
|
|
|
4559
4542
|
// ----------------------------------------------------------------------------
|
|
4560
4543
|
// interruption
|
|
@@ -4719,19 +4702,19 @@ export const partition: {
|
|
|
4719
4702
|
<A, B, E, R>(
|
|
4720
4703
|
f: (a: A, i: number) => Effect.Effect<B, E, R>,
|
|
4721
4704
|
options?: { readonly concurrency?: Concurrency | undefined }
|
|
4722
|
-
): (elements: Iterable<A>) => Effect.Effect<[
|
|
4705
|
+
): (elements: Iterable<A>) => Effect.Effect<[passes: Array<B>, fails: Array<E>], never, R>
|
|
4723
4706
|
<A, B, E, R>(
|
|
4724
4707
|
elements: Iterable<A>,
|
|
4725
4708
|
f: (a: A, i: number) => Effect.Effect<B, E, R>,
|
|
4726
4709
|
options?: { readonly concurrency?: Concurrency | undefined }
|
|
4727
|
-
): Effect.Effect<[
|
|
4710
|
+
): Effect.Effect<[passes: Array<B>, fails: Array<E>], never, R>
|
|
4728
4711
|
} = dual(
|
|
4729
4712
|
(args) => isIterable(args[0]) && !isEffect(args[0]),
|
|
4730
4713
|
<A, B, E, R>(
|
|
4731
4714
|
elements: Iterable<A>,
|
|
4732
4715
|
f: (a: A, i: number) => Effect.Effect<B, E, R>,
|
|
4733
4716
|
options?: { readonly concurrency?: Concurrency | undefined }
|
|
4734
|
-
): Effect.Effect<[
|
|
4717
|
+
): Effect.Effect<[passes: Array<B>, fails: Array<E>], never, R> =>
|
|
4735
4718
|
map(
|
|
4736
4719
|
forEach(elements, (a, i) => result(f(a, i)), options),
|
|
4737
4720
|
(results) => Arr.partition(results, identity)
|
|
@@ -4820,11 +4803,11 @@ export const validate: {
|
|
|
4820
4803
|
): Effect.Effect<Array<B> | void, Arr.NonEmptyArray<E>, R> =>
|
|
4821
4804
|
flatMap(
|
|
4822
4805
|
partition(elements, f, { concurrency: options?.concurrency }),
|
|
4823
|
-
([
|
|
4824
|
-
if (Arr.isArrayNonEmpty(
|
|
4825
|
-
return fail(
|
|
4806
|
+
([passes, fails]) => {
|
|
4807
|
+
if (Arr.isArrayNonEmpty(fails)) {
|
|
4808
|
+
return fail(fails)
|
|
4826
4809
|
}
|
|
4827
|
-
return options?.discard ? void_ : succeed(
|
|
4810
|
+
return options?.discard ? void_ : succeed(passes)
|
|
4828
4811
|
}
|
|
4829
4812
|
)
|
|
4830
4813
|
)
|
|
@@ -5085,7 +5068,6 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5085
5068
|
let parentFiber: Fiber.Fiber<any, any> | undefined
|
|
5086
5069
|
let fibers: Set<Fiber.Fiber<any, any>> | undefined
|
|
5087
5070
|
let resume: ((effect: Effect.Effect<void, E | E2, R>) => void) | undefined
|
|
5088
|
-
let interrupted = false
|
|
5089
5071
|
let terminal: Exit.Exit<void, E | E2> | void
|
|
5090
5072
|
let effect: Effect.Effect<X, E, R> | undefined
|
|
5091
5073
|
|
|
@@ -5093,9 +5075,8 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5093
5075
|
const defect = exitDie(error)
|
|
5094
5076
|
terminal = defect
|
|
5095
5077
|
done = true
|
|
5096
|
-
interrupted = true
|
|
5097
5078
|
return fibers && fibers.size > 0
|
|
5098
|
-
? flatMap(uninterruptible(fiberInterruptAll(Array.from(fibers))), () => defect)
|
|
5079
|
+
? flatMap(uninterruptible(fiberInterruptAll(Array.from(fibers))), () => terminal ?? defect)
|
|
5099
5080
|
: defect
|
|
5100
5081
|
}
|
|
5101
5082
|
|
|
@@ -5105,12 +5086,9 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5105
5086
|
const item = items[index]
|
|
5106
5087
|
const eff = effect ?? onItem(state, item, index)
|
|
5107
5088
|
|
|
5108
|
-
// fast case (already an exit)
|
|
5109
5089
|
if (effectIsExit(eff)) {
|
|
5110
5090
|
terminal = step(state, item, eff, index)
|
|
5111
5091
|
if (terminal) break
|
|
5112
|
-
|
|
5113
|
-
// We have an effect, so enter "async" mode
|
|
5114
5092
|
} else if (!parentFiber) {
|
|
5115
5093
|
return callback((cb) => {
|
|
5116
5094
|
parentFiber = getCurrentFiber()!
|
|
@@ -5125,15 +5103,15 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5125
5103
|
}
|
|
5126
5104
|
if (result) return cb(result)
|
|
5127
5105
|
return suspend(() => {
|
|
5128
|
-
terminal
|
|
5129
|
-
|
|
5130
|
-
|
|
5106
|
+
terminal ??= exitVoid
|
|
5107
|
+
return flatMap(
|
|
5108
|
+
fibers ? fiberInterruptAll(fibers) : void_,
|
|
5109
|
+
() => terminal?._tag === "Failure" ? terminal : void_
|
|
5110
|
+
)
|
|
5131
5111
|
})
|
|
5132
5112
|
})
|
|
5133
|
-
|
|
5134
|
-
// Fork the effect with concurrency > 1
|
|
5135
5113
|
} else {
|
|
5136
|
-
// Clear the
|
|
5114
|
+
// Clear the effect cached before the parent fiber was available.
|
|
5137
5115
|
effect = undefined
|
|
5138
5116
|
|
|
5139
5117
|
const fiber = forkUnsafe(parentFiber, eff, true, true, "inherit")
|
|
@@ -5143,7 +5121,6 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5143
5121
|
continue
|
|
5144
5122
|
}
|
|
5145
5123
|
|
|
5146
|
-
// Add the fiber to the Set
|
|
5147
5124
|
fibers!.add(fiber)
|
|
5148
5125
|
|
|
5149
5126
|
const currentIndex = index
|
|
@@ -5151,22 +5128,17 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5151
5128
|
fibers!.delete(fiber)
|
|
5152
5129
|
try {
|
|
5153
5130
|
if (terminal) {
|
|
5154
|
-
if (
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
} else {
|
|
5160
|
-
terminal = exitFailCause(causeFromReasons([reason]))
|
|
5161
|
-
}
|
|
5131
|
+
if (exit._tag === "Failure") {
|
|
5132
|
+
const reasons = exit.cause.reasons.filter((reason) => reason._tag !== "Interrupt")
|
|
5133
|
+
if (reasons.length > 0) {
|
|
5134
|
+
const cause = causeFromReasons(reasons)
|
|
5135
|
+
terminal = exitFailCause(terminal._tag === "Failure" ? causeCombine(terminal.cause, cause) : cause)
|
|
5162
5136
|
}
|
|
5163
5137
|
}
|
|
5164
5138
|
} else {
|
|
5165
5139
|
const result = step(state, item, exit, currentIndex)
|
|
5166
5140
|
if (result) {
|
|
5167
|
-
terminal = result
|
|
5168
|
-
? exitFailCause(causeFromReasons(result.cause.reasons.slice()))
|
|
5169
|
-
: result
|
|
5141
|
+
terminal = result
|
|
5170
5142
|
go()
|
|
5171
5143
|
}
|
|
5172
5144
|
}
|
|
@@ -5182,7 +5154,6 @@ const iterateConcurrentImpl = <S, A, X, E, R, E2>(options: IterateOptions<S, A,
|
|
|
5182
5154
|
}
|
|
5183
5155
|
})
|
|
5184
5156
|
|
|
5185
|
-
// Check if we have reached the concurrency limit
|
|
5186
5157
|
if (fibers!.size < concurrency) continue
|
|
5187
5158
|
paused = true
|
|
5188
5159
|
index++
|
|
@@ -5556,6 +5527,8 @@ export const forkUnsafe = <FA, FE, A, E, R>(
|
|
|
5556
5527
|
if (immediate) {
|
|
5557
5528
|
child.evaluate(effect as any)
|
|
5558
5529
|
} else {
|
|
5530
|
+
// Preserve the fork context rather than the dispatcher's context.
|
|
5531
|
+
child._asyncContext = captureAsyncContext()
|
|
5559
5532
|
parentRuntime.currentDispatcher.scheduleTask(() => child.evaluate(effect as any), 0)
|
|
5560
5533
|
}
|
|
5561
5534
|
if (!daemon && !child._exit) {
|