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/dist/internal/effect.js
CHANGED
|
@@ -17,7 +17,7 @@ import * as Result from "../Result.js";
|
|
|
17
17
|
import * as Scheduler from "../Scheduler.js";
|
|
18
18
|
import * as Tracer from "../Tracer.js";
|
|
19
19
|
import { internalCall } from "../Utils.js";
|
|
20
|
-
import { args, causeAnnotate,
|
|
20
|
+
import { args, causeAnnotate, causeCombine, causeEmpty, causeFromReasons, CauseImpl, constEmptyAnnotations, contA, contAll, contE, evaluate, exitDie, exitFail, exitFailCause, exitSucceed, ExitTypeId, Fail, InterruptorStackTrace, isCause, isDieReason, isEffect, isFailReason, isInterruptReason, isNoSuchElementError, makePrimitive, makePrimitiveProto, NoSuchElementError, ReasonBase, StackTraceKey as CauseStackTrace, TaggedError, withFiber, Yield } from "./core.js";
|
|
21
21
|
import * as doNotation from "./doNotation.js";
|
|
22
22
|
import * as InternalMetric from "./metric.js";
|
|
23
23
|
import * as InternalRecord from "./record.js";
|
|
@@ -126,35 +126,6 @@ export const causeAnnotations = self => {
|
|
|
126
126
|
}
|
|
127
127
|
return Context.makeUnsafe(map);
|
|
128
128
|
};
|
|
129
|
-
const dedupeReasons = (self, that) => {
|
|
130
|
-
// Keep deduplication local so causeCombine does not retain Array.ts in the core bundle.
|
|
131
|
-
// Snapshot both arrays before invoking user-defined hash or equality methods.
|
|
132
|
-
const buckets = new Map();
|
|
133
|
-
const out = [];
|
|
134
|
-
for (const reason of self.concat(that)) {
|
|
135
|
-
const hash = Hash.hash(reason);
|
|
136
|
-
const bucket = buckets.get(hash);
|
|
137
|
-
if (bucket === undefined) {
|
|
138
|
-
buckets.set(hash, [reason]);
|
|
139
|
-
} else if (bucket.some(previous => Equal.equals(previous, reason))) {
|
|
140
|
-
continue;
|
|
141
|
-
} else {
|
|
142
|
-
bucket.push(reason);
|
|
143
|
-
}
|
|
144
|
-
out.push(reason);
|
|
145
|
-
}
|
|
146
|
-
return out;
|
|
147
|
-
};
|
|
148
|
-
/** @internal */
|
|
149
|
-
export const causeCombine = /*#__PURE__*/dual(2, (self, that) => {
|
|
150
|
-
if (self.reasons.length === 0) {
|
|
151
|
-
return that;
|
|
152
|
-
} else if (that.reasons.length === 0) {
|
|
153
|
-
return self;
|
|
154
|
-
}
|
|
155
|
-
const newCause = new CauseImpl(dedupeReasons(self.reasons, that.reasons));
|
|
156
|
-
return Equal.equals(self, newCause) ? self : newCause;
|
|
157
|
-
});
|
|
158
129
|
/** @internal */
|
|
159
130
|
export const causeMap = /*#__PURE__*/dual(2, (self, f) => {
|
|
160
131
|
let hasFail = false;
|
|
@@ -332,6 +303,14 @@ const fiberVariance = {
|
|
|
332
303
|
const fiberIdStore = {
|
|
333
304
|
id: 0
|
|
334
305
|
};
|
|
306
|
+
const AsyncResource = /*#__PURE__*/(() => {
|
|
307
|
+
try {
|
|
308
|
+
return globalThis.process?.getBuiltinModule?.("node:async_hooks")?.AsyncResource;
|
|
309
|
+
} catch {
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
})();
|
|
313
|
+
const captureAsyncContext = () => AsyncResource === undefined ? undefined : new AsyncResource("effect/Fiber");
|
|
335
314
|
/** @internal */
|
|
336
315
|
export const getCurrentFiber = () => globalThis[currentFiberTypeId];
|
|
337
316
|
/** @internal */
|
|
@@ -350,6 +329,7 @@ export class FiberImpl {
|
|
|
350
329
|
this._running = false;
|
|
351
330
|
this._deferredInterrupt = false;
|
|
352
331
|
this._parent = undefined;
|
|
332
|
+
this._asyncContext = undefined;
|
|
353
333
|
this.cache.runtimeMetrics?.recordFiberStart(this.context);
|
|
354
334
|
}
|
|
355
335
|
get [FiberTypeId]() {
|
|
@@ -406,6 +386,10 @@ export class FiberImpl {
|
|
|
406
386
|
evaluate(effect) {
|
|
407
387
|
if (this._exit) {
|
|
408
388
|
return;
|
|
389
|
+
} else if (this._asyncContext !== undefined) {
|
|
390
|
+
const asyncContext = this._asyncContext;
|
|
391
|
+
this._asyncContext = undefined;
|
|
392
|
+
return asyncContext.runInAsyncScope(this.evaluate, this, effect);
|
|
409
393
|
} else if (this._yielded !== undefined) {
|
|
410
394
|
const yielded = this._yielded;
|
|
411
395
|
this._yielded = undefined;
|
|
@@ -413,6 +397,7 @@ export class FiberImpl {
|
|
|
413
397
|
}
|
|
414
398
|
const exit = this.runLoop(effect);
|
|
415
399
|
if (exit === Yield) {
|
|
400
|
+
this._asyncContext = captureAsyncContext();
|
|
416
401
|
return;
|
|
417
402
|
}
|
|
418
403
|
// the interruptChildren middleware is added in Effect.forkChild, so it can be
|
|
@@ -782,17 +767,18 @@ export const tryPromise = options => {
|
|
|
782
767
|
const f = typeof options === "function" ? options : options.try;
|
|
783
768
|
const catcher = typeof options === "function" ? cause => new UnknownError(cause, "An error occurred in Effect.tryPromise") : options.catch;
|
|
784
769
|
return callbackOptions(function (resume, signal) {
|
|
785
|
-
|
|
770
|
+
// Defer the catcher until the fiber restores its async context.
|
|
771
|
+
const failWithCatch = cause => suspend(() => {
|
|
786
772
|
try {
|
|
787
|
-
|
|
773
|
+
return fail(internalCall(() => catcher(cause)));
|
|
788
774
|
} catch (err) {
|
|
789
|
-
|
|
775
|
+
return die(err);
|
|
790
776
|
}
|
|
791
|
-
};
|
|
777
|
+
});
|
|
792
778
|
try {
|
|
793
|
-
f(signal).then(a => resume(succeed(a)), failWithCatch);
|
|
779
|
+
f(signal).then(a => resume(succeed(a)), e => resume(failWithCatch(e)));
|
|
794
780
|
} catch (err) {
|
|
795
|
-
failWithCatch(err);
|
|
781
|
+
resume(failWithCatch(err));
|
|
796
782
|
}
|
|
797
783
|
}, f.length !== 0);
|
|
798
784
|
};
|
|
@@ -852,7 +838,7 @@ const asyncFinalizer = /*#__PURE__*/makePrimitive({
|
|
|
852
838
|
}
|
|
853
839
|
},
|
|
854
840
|
[contE](cause, _fiber) {
|
|
855
|
-
return hasInterrupts(cause) ? flatMap(this[args](), () => failCause(cause)) : failCause(cause);
|
|
841
|
+
return hasInterrupts(cause) ? flatMap(combineFinalizerCause(exitFailCause(cause), this[args]()), () => failCause(cause)) : failCause(cause);
|
|
856
842
|
}
|
|
857
843
|
});
|
|
858
844
|
/** @internal */
|
|
@@ -1079,73 +1065,75 @@ export const asVoid = self => new ContImpl(self, returnPayload, exitVoid);
|
|
|
1079
1065
|
/** @internal */
|
|
1080
1066
|
export const sandbox = self => catchCause(self, fail);
|
|
1081
1067
|
/** @internal */
|
|
1082
|
-
export const raceAll = (all, options) => withFiber(parent =>
|
|
1083
|
-
const effects = Arr.fromIterable(all);
|
|
1084
|
-
const len = effects.length;
|
|
1085
|
-
let doneCount = 0;
|
|
1086
|
-
let done = false;
|
|
1068
|
+
export const raceAll = (all, options) => withFiber(parent => {
|
|
1087
1069
|
const fibers = new Set();
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1070
|
+
// Read fibers on exit to include losers forked after the race settles.
|
|
1071
|
+
onExitUnsafe(parent, () => fibers.size === 0 ? undefined : fiberInterruptAll(fibers));
|
|
1072
|
+
return callback(resume => {
|
|
1073
|
+
const effects = Arr.fromIterable(all);
|
|
1074
|
+
const len = effects.length;
|
|
1075
|
+
let doneCount = 0;
|
|
1076
|
+
let done = false;
|
|
1077
|
+
const failures = [];
|
|
1078
|
+
const onExit = (exit, fiber, i) => {
|
|
1079
|
+
doneCount++;
|
|
1080
|
+
if (exit._tag === "Failure") {
|
|
1081
|
+
failures.push(...exit.cause.reasons);
|
|
1082
|
+
if (doneCount >= len) {
|
|
1083
|
+
resume(failCause(causeFromReasons(failures)));
|
|
1084
|
+
}
|
|
1085
|
+
return;
|
|
1095
1086
|
}
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1098
|
-
const isWinner = !done;
|
|
1099
|
-
done = true;
|
|
1100
|
-
resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit));
|
|
1101
|
-
if (isWinner && options?.onWinner) {
|
|
1102
|
-
options.onWinner({
|
|
1103
|
-
fiber,
|
|
1104
|
-
index: i,
|
|
1105
|
-
parentFiber: parent
|
|
1106
|
-
});
|
|
1107
|
-
}
|
|
1108
|
-
};
|
|
1109
|
-
for (let i = 0; i < len; i++) {
|
|
1110
|
-
const fiber = forkUnsafe(parent, effects[i], true, true, false);
|
|
1111
|
-
fibers.add(fiber);
|
|
1112
|
-
fiber.addObserver(exit => {
|
|
1113
|
-
fibers.delete(fiber);
|
|
1114
|
-
onExit(exit, fiber, i);
|
|
1115
|
-
});
|
|
1116
|
-
if (done) break;
|
|
1117
|
-
}
|
|
1118
|
-
return fiberInterruptAll(fibers);
|
|
1119
|
-
}));
|
|
1120
|
-
/** @internal */
|
|
1121
|
-
export const raceAllFirst = (all, options) => withFiber(parent => callback(resume => {
|
|
1122
|
-
let done = false;
|
|
1123
|
-
const fibers = new Set();
|
|
1124
|
-
const onExit = exit => {
|
|
1125
|
-
done = true;
|
|
1126
|
-
resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit));
|
|
1127
|
-
};
|
|
1128
|
-
let i = 0;
|
|
1129
|
-
for (const effect of all) {
|
|
1130
|
-
if (done) break;
|
|
1131
|
-
const index = i++;
|
|
1132
|
-
const fiber = forkUnsafe(parent, effect, true, true, false);
|
|
1133
|
-
fibers.add(fiber);
|
|
1134
|
-
fiber.addObserver(exit => {
|
|
1135
|
-
fibers.delete(fiber);
|
|
1136
1087
|
const isWinner = !done;
|
|
1137
|
-
|
|
1088
|
+
done = true;
|
|
1089
|
+
resume(exit);
|
|
1138
1090
|
if (isWinner && options?.onWinner) {
|
|
1139
1091
|
options.onWinner({
|
|
1140
1092
|
fiber,
|
|
1141
|
-
index,
|
|
1093
|
+
index: i,
|
|
1142
1094
|
parentFiber: parent
|
|
1143
1095
|
});
|
|
1144
1096
|
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1097
|
+
};
|
|
1098
|
+
for (let i = 0; i < len; i++) {
|
|
1099
|
+
const fiber = forkUnsafe(parent, effects[i], true, true, false);
|
|
1100
|
+
fibers.add(fiber);
|
|
1101
|
+
fiber.addObserver(exit => {
|
|
1102
|
+
fibers.delete(fiber);
|
|
1103
|
+
onExit(exit, fiber, i);
|
|
1104
|
+
});
|
|
1105
|
+
if (done) break;
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
});
|
|
1109
|
+
/** @internal */
|
|
1110
|
+
export const raceAllFirst = (all, options) => withFiber(parent => {
|
|
1111
|
+
const fibers = new Set();
|
|
1112
|
+
onExitUnsafe(parent, () => fibers.size === 0 ? undefined : fiberInterruptAll(fibers));
|
|
1113
|
+
return callback(resume => {
|
|
1114
|
+
let done = false;
|
|
1115
|
+
let i = 0;
|
|
1116
|
+
for (const effect of all) {
|
|
1117
|
+
if (done) break;
|
|
1118
|
+
const index = i++;
|
|
1119
|
+
const fiber = forkUnsafe(parent, effect, true, true, false);
|
|
1120
|
+
fibers.add(fiber);
|
|
1121
|
+
fiber.addObserver(exit => {
|
|
1122
|
+
fibers.delete(fiber);
|
|
1123
|
+
const isWinner = !done;
|
|
1124
|
+
done = true;
|
|
1125
|
+
resume(exit);
|
|
1126
|
+
if (isWinner && options?.onWinner) {
|
|
1127
|
+
options.onWinner({
|
|
1128
|
+
fiber,
|
|
1129
|
+
index,
|
|
1130
|
+
parentFiber: parent
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1149
1137
|
/** @internal */
|
|
1150
1138
|
export const race = /*#__PURE__*/dual(args => isEffect(args[1]), (self, that, options) => raceAll([self, that], options));
|
|
1151
1139
|
/** @internal */
|
|
@@ -1930,61 +1918,55 @@ export const acquireDisposable = acquire => acquireRelease(acquire, resource =>
|
|
|
1930
1918
|
// Caching
|
|
1931
1919
|
// ----------------------------------------------------------------------------
|
|
1932
1920
|
/** @internal */
|
|
1933
|
-
export const cachedInvalidateWithTTL = /*#__PURE__*/dual(2, (self, ttl) => sync(() =>
|
|
1934
|
-
|
|
1935
|
-
|
|
1921
|
+
export const cachedInvalidateWithTTL = /*#__PURE__*/dual(2, (self, ttl) => sync(() => makeCachedUnsafe(self, typeof ttl === "function" ? exit => Duration.toMillis(Duration.fromInputUnsafe(ttl(exit))) : constant(Duration.toMillis(Duration.fromInputUnsafe(ttl))))));
|
|
1922
|
+
const infiniteTTL = /*#__PURE__*/constant(Infinity);
|
|
1923
|
+
const makeCachedUnsafe = (self, ttlMillis) => {
|
|
1936
1924
|
let expiresAt = 0;
|
|
1937
|
-
let running = false;
|
|
1938
1925
|
let exit;
|
|
1939
|
-
|
|
1926
|
+
let current;
|
|
1927
|
+
const join = (fiber, run) => {
|
|
1928
|
+
run.awaiters++;
|
|
1929
|
+
onExitUnsafe(fiber, () => {
|
|
1930
|
+
// Abandon the run once every caller has left, unless it already finished.
|
|
1931
|
+
if (--run.awaiters > 0 || current !== run) return;
|
|
1932
|
+
// Detach it first so new callers start a fresh run instead of joining
|
|
1933
|
+
// one that is being interrupted.
|
|
1934
|
+
current = undefined;
|
|
1935
|
+
return fiberInterrupt(run.fiber);
|
|
1936
|
+
});
|
|
1937
|
+
return fiberJoin(run.fiber);
|
|
1938
|
+
};
|
|
1940
1939
|
return [withFiber(fiber => {
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
latch.closeUnsafe();
|
|
1940
|
+
if (current !== undefined) return join(fiber, current);
|
|
1941
|
+
if (exit !== undefined && (expiresAt === Infinity || fiber.getRef(ClockRef).currentTimeMillisUnsafe() < expiresAt)) {
|
|
1942
|
+
return exit;
|
|
1943
|
+
}
|
|
1946
1944
|
exit = undefined;
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1945
|
+
const clock = fiber.getRef(ClockRef);
|
|
1946
|
+
const run = {
|
|
1947
|
+
fiber: undefined,
|
|
1948
|
+
awaiters: 0
|
|
1949
|
+
};
|
|
1950
|
+
current = run;
|
|
1951
|
+
run.fiber = forkUnsafe(fiber, onExitPrimitive(self, exit_ => {
|
|
1952
|
+
// An abandoned run must not overwrite or clear a replacement run.
|
|
1953
|
+
if (current !== run) return;
|
|
1954
|
+
current = undefined;
|
|
1955
|
+
// Interruption is abandonment, so it is never cached.
|
|
1956
|
+
if (exitHasInterrupts(exit_)) return;
|
|
1957
|
+
const duration = ttlMillis(exit_);
|
|
1958
|
+
expiresAt = duration === Infinity ? Infinity : clock.currentTimeMillisUnsafe() + duration;
|
|
1959
|
+
exit = exit_;
|
|
1960
|
+
}), true, true);
|
|
1961
|
+
return run.fiber._exit ?? join(fiber, run);
|
|
1963
1962
|
}), sync(() => {
|
|
1964
|
-
expiresAt = 0;
|
|
1965
|
-
latch.closeUnsafe();
|
|
1966
1963
|
exit = undefined;
|
|
1967
1964
|
})];
|
|
1968
|
-
}
|
|
1965
|
+
};
|
|
1969
1966
|
/** @internal */
|
|
1970
1967
|
export const cachedWithTTL = /*#__PURE__*/dual(2, (self, timeToLive) => map(cachedInvalidateWithTTL(self, timeToLive), tuple => tuple[0]));
|
|
1971
1968
|
/** @internal */
|
|
1972
|
-
export const cached = self => sync(() =>
|
|
1973
|
-
const latch = makeLatchUnsafe(false);
|
|
1974
|
-
let started = false;
|
|
1975
|
-
let exit;
|
|
1976
|
-
const wait = flatMap(latch.await, () => exit);
|
|
1977
|
-
return withFiber(fiber => {
|
|
1978
|
-
if (exit !== undefined) return exit;
|
|
1979
|
-
if (started) return wait;
|
|
1980
|
-
started = true;
|
|
1981
|
-
onExitUnsafe(fiber, result => sync(() => {
|
|
1982
|
-
exit = result;
|
|
1983
|
-
latch.openUnsafe();
|
|
1984
|
-
}));
|
|
1985
|
-
return self;
|
|
1986
|
-
});
|
|
1987
|
-
});
|
|
1969
|
+
export const cached = self => sync(() => makeCachedUnsafe(self, infiniteTTL)[0]);
|
|
1988
1970
|
// ----------------------------------------------------------------------------
|
|
1989
1971
|
// interruption
|
|
1990
1972
|
// ----------------------------------------------------------------------------
|
|
@@ -2100,11 +2082,11 @@ export const reduce = /*#__PURE__*/dual(3, (elements, zero, f) => {
|
|
|
2100
2082
|
/** @internal */
|
|
2101
2083
|
export const validate = /*#__PURE__*/dual(args => isIterable(args[0]) && !isEffect(args[0]), (elements, f, options) => flatMap(partition(elements, f, {
|
|
2102
2084
|
concurrency: options?.concurrency
|
|
2103
|
-
}), ([
|
|
2104
|
-
if (Arr.isArrayNonEmpty(
|
|
2105
|
-
return fail(
|
|
2085
|
+
}), ([passes, fails]) => {
|
|
2086
|
+
if (Arr.isArrayNonEmpty(fails)) {
|
|
2087
|
+
return fail(fails);
|
|
2106
2088
|
}
|
|
2107
|
-
return options?.discard ? void_ : succeed(
|
|
2089
|
+
return options?.discard ? void_ : succeed(passes);
|
|
2108
2090
|
}));
|
|
2109
2091
|
/** @internal */
|
|
2110
2092
|
export const findFirst = /*#__PURE__*/dual(args => isIterable(args[0]) && !isEffect(args[0]), (elements, predicate) => suspend(() => {
|
|
@@ -2233,26 +2215,22 @@ const iterateConcurrentImpl = options => {
|
|
|
2233
2215
|
let parentFiber;
|
|
2234
2216
|
let fibers;
|
|
2235
2217
|
let resume;
|
|
2236
|
-
let interrupted = false;
|
|
2237
2218
|
let terminal;
|
|
2238
2219
|
let effect;
|
|
2239
2220
|
const failDefect = error => {
|
|
2240
2221
|
const defect = exitDie(error);
|
|
2241
2222
|
terminal = defect;
|
|
2242
2223
|
done = true;
|
|
2243
|
-
|
|
2244
|
-
return fibers && fibers.size > 0 ? flatMap(uninterruptible(fiberInterruptAll(Array.from(fibers))), () => defect) : defect;
|
|
2224
|
+
return fibers && fibers.size > 0 ? flatMap(uninterruptible(fiberInterruptAll(Array.from(fibers))), () => terminal ?? defect) : defect;
|
|
2245
2225
|
};
|
|
2246
2226
|
const go = () => {
|
|
2247
2227
|
let paused = false;
|
|
2248
2228
|
for (; !terminal && index < end; index++) {
|
|
2249
2229
|
const item = items[index];
|
|
2250
2230
|
const eff = effect ?? onItem(state, item, index);
|
|
2251
|
-
// fast case (already an exit)
|
|
2252
2231
|
if (effectIsExit(eff)) {
|
|
2253
2232
|
terminal = step(state, item, eff, index);
|
|
2254
2233
|
if (terminal) break;
|
|
2255
|
-
// We have an effect, so enter "async" mode
|
|
2256
2234
|
} else if (!parentFiber) {
|
|
2257
2235
|
return callback(cb => {
|
|
2258
2236
|
parentFiber = getCurrentFiber();
|
|
@@ -2267,14 +2245,12 @@ const iterateConcurrentImpl = options => {
|
|
|
2267
2245
|
}
|
|
2268
2246
|
if (result) return cb(result);
|
|
2269
2247
|
return suspend(() => {
|
|
2270
|
-
terminal
|
|
2271
|
-
|
|
2272
|
-
return fibers ? fiberInterruptAll(fibers) : void_;
|
|
2248
|
+
terminal ??= exitVoid;
|
|
2249
|
+
return flatMap(fibers ? fiberInterruptAll(fibers) : void_, () => terminal?._tag === "Failure" ? terminal : void_);
|
|
2273
2250
|
});
|
|
2274
2251
|
});
|
|
2275
|
-
// Fork the effect with concurrency > 1
|
|
2276
2252
|
} else {
|
|
2277
|
-
// Clear the
|
|
2253
|
+
// Clear the effect cached before the parent fiber was available.
|
|
2278
2254
|
effect = undefined;
|
|
2279
2255
|
const fiber = forkUnsafe(parentFiber, eff, true, true, "inherit");
|
|
2280
2256
|
if (fiber._exit) {
|
|
@@ -2282,27 +2258,23 @@ const iterateConcurrentImpl = options => {
|
|
|
2282
2258
|
if (terminal) break;
|
|
2283
2259
|
continue;
|
|
2284
2260
|
}
|
|
2285
|
-
// Add the fiber to the Set
|
|
2286
2261
|
fibers.add(fiber);
|
|
2287
2262
|
const currentIndex = index;
|
|
2288
2263
|
fiber.addObserver(exit => {
|
|
2289
2264
|
fibers.delete(fiber);
|
|
2290
2265
|
try {
|
|
2291
2266
|
if (terminal) {
|
|
2292
|
-
if (
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
} else {
|
|
2298
|
-
terminal = exitFailCause(causeFromReasons([reason]));
|
|
2299
|
-
}
|
|
2267
|
+
if (exit._tag === "Failure") {
|
|
2268
|
+
const reasons = exit.cause.reasons.filter(reason => reason._tag !== "Interrupt");
|
|
2269
|
+
if (reasons.length > 0) {
|
|
2270
|
+
const cause = causeFromReasons(reasons);
|
|
2271
|
+
terminal = exitFailCause(terminal._tag === "Failure" ? causeCombine(terminal.cause, cause) : cause);
|
|
2300
2272
|
}
|
|
2301
2273
|
}
|
|
2302
2274
|
} else {
|
|
2303
2275
|
const result = step(state, item, exit, currentIndex);
|
|
2304
2276
|
if (result) {
|
|
2305
|
-
terminal = result
|
|
2277
|
+
terminal = result;
|
|
2306
2278
|
go();
|
|
2307
2279
|
}
|
|
2308
2280
|
}
|
|
@@ -2316,7 +2288,6 @@ const iterateConcurrentImpl = options => {
|
|
|
2316
2288
|
resume(failDefect(error));
|
|
2317
2289
|
}
|
|
2318
2290
|
});
|
|
2319
|
-
// Check if we have reached the concurrency limit
|
|
2320
2291
|
if (fibers.size < concurrency) continue;
|
|
2321
2292
|
paused = true;
|
|
2322
2293
|
index++;
|
|
@@ -2436,6 +2407,8 @@ export const forkUnsafe = (parent, effect, immediate = false, daemon = false, un
|
|
|
2436
2407
|
if (immediate) {
|
|
2437
2408
|
child.evaluate(effect);
|
|
2438
2409
|
} else {
|
|
2410
|
+
// Preserve the fork context rather than the dispatcher's context.
|
|
2411
|
+
child._asyncContext = captureAsyncContext();
|
|
2439
2412
|
parentRuntime.currentDispatcher.scheduleTask(() => child.evaluate(effect), 0);
|
|
2440
2413
|
}
|
|
2441
2414
|
if (!daemon && !child._exit) {
|