better-effect 0.8.0 → 0.9.2
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 +47 -0
- package/dist/adapters/iti.d.mts +3 -3
- package/dist/adapters/iti.mjs +2 -1
- package/dist/adapters/iti.mjs.map +1 -1
- package/dist/{internal-identity-Cm4-KIUj.mjs → errors-Dnjhzbt0.mjs} +2 -25
- package/dist/errors-Dnjhzbt0.mjs.map +1 -0
- package/dist/{index-BFgG9zZC.d.mts → index-1NLNdkJy.d.mts} +2 -2
- package/dist/{index-BFgG9zZC.d.mts.map → index-1NLNdkJy.d.mts.map} +1 -1
- package/dist/index-BJFBEsm5.d.mts +406 -0
- package/dist/index-BJFBEsm5.d.mts.map +1 -0
- package/dist/{index-fUyY0eNJ.d.mts → index-CYAgpM_5.d.mts} +28 -14
- package/dist/index-CYAgpM_5.d.mts.map +1 -0
- package/dist/index.d.mts +5 -320
- package/dist/index.mjs +142 -277
- package/dist/index.mjs.map +1 -1
- package/dist/internal-identity-DmUpBeeL.mjs +27 -0
- package/dist/internal-identity-DmUpBeeL.mjs.map +1 -0
- package/dist/{map-layer-backend-CGibcwkc.d.mts → map-layer-backend-DMJauecV.d.mts} +2 -2
- package/dist/{map-layer-backend-CGibcwkc.d.mts.map → map-layer-backend-DMJauecV.d.mts.map} +1 -1
- package/dist/{map-layer-backend-BodcEeNA.mjs → map-layer-backend-gal-mcRv.mjs} +3 -2
- package/dist/{map-layer-backend-BodcEeNA.mjs.map → map-layer-backend-gal-mcRv.mjs.map} +1 -1
- package/dist/runtime/explicit.d.mts +1 -1
- package/dist/runtime/node.d.mts +1 -1
- package/dist/signal-Cl9tqGyX.mjs +270 -0
- package/dist/signal-Cl9tqGyX.mjs.map +1 -0
- package/dist/standard-services.d.mts +116 -0
- package/dist/standard-services.d.mts.map +1 -0
- package/dist/standard-services.mjs +180 -0
- package/dist/standard-services.mjs.map +1 -0
- package/dist/testing.d.mts +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +6 -2
- package/dist/index-fUyY0eNJ.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/internal-identity-Cm4-KIUj.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,226 +1,9 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { a as runRuntimeContext, c as RuntimeContextNotConfiguredError, i as makeRuntimeContext, n as currentRuntimeContext,
|
|
3
|
-
import {
|
|
4
|
-
import { t as MapLayerBackend } from "./map-layer-backend-
|
|
1
|
+
import { a as ServiceTagCollisionError, c as ServiceNotFoundError, i as LayerRegistrationError, l as ServiceRuntimeNotConfiguredError, n as LayerDisposeError, o as CircularDependencyError, r as LayerGeneratorYieldError, s as ServiceAcquisitionError, t as DuplicateServiceError } from "./errors-Dnjhzbt0.mjs";
|
|
2
|
+
import { a as runRuntimeContext, c as RuntimeContextNotConfiguredError, i as makeRuntimeContext, n as currentRuntimeContext, r as getRuntimeContext, t as activeRuntimeContextStorage } from "./context-B4yO5LaH.mjs";
|
|
3
|
+
import { a as ServiceRuntime, i as Service, n as linkAbortSignals, o as defaultRuntimeContextStorage, r as Layer, t as CurrentAbortSignal } from "./signal-Cl9tqGyX.mjs";
|
|
4
|
+
import { t as MapLayerBackend } from "./map-layer-backend-gal-mcRv.mjs";
|
|
5
5
|
import { t as isPromiseLike } from "./runtime-CDcCF5cb.mjs";
|
|
6
6
|
import { Result, TaggedError } from "better-result";
|
|
7
|
-
//#region src/runtime/default.ts
|
|
8
|
-
/** The Node/Bun storage used by the main Runtime entrypoint. */
|
|
9
|
-
const defaultRuntimeContextStorage = nodeRuntimeContextStorage;
|
|
10
|
-
setDefaultRuntimeContextStorage(defaultRuntimeContextStorage);
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/service/runtime.ts
|
|
13
|
-
/** Provides the resolver context used by Service tokens during execution. */
|
|
14
|
-
var ServiceRuntime = class ServiceRuntime {
|
|
15
|
-
/**
|
|
16
|
-
* Run a callback with a resolver available to `yield* Service` expressions.
|
|
17
|
-
*
|
|
18
|
-
* The context is scoped to the callback and is restored afterward.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* const value = ServiceRuntime.run(resolver, () => {
|
|
23
|
-
* return ServiceRuntime.resolve(Database)
|
|
24
|
-
* })
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
static run(resolver, program, storage = defaultRuntimeContextStorage) {
|
|
28
|
-
const current = getRuntimeContext(storage);
|
|
29
|
-
const context = makeRuntimeContext(resolver, current?.scope, current?.resolver === resolver ? current.resolutionPath : [], current?.signal);
|
|
30
|
-
return runRuntimeContext(storage, context, program);
|
|
31
|
-
}
|
|
32
|
-
/** Return the resolver active in the current execution context. */
|
|
33
|
-
static current() {
|
|
34
|
-
let context;
|
|
35
|
-
try {
|
|
36
|
-
context = currentRuntimeContext();
|
|
37
|
-
} catch {
|
|
38
|
-
throw new ServiceRuntimeNotConfiguredError();
|
|
39
|
-
}
|
|
40
|
-
if (!context.resolver) throw new ServiceRuntimeNotConfiguredError();
|
|
41
|
-
return context.resolver;
|
|
42
|
-
}
|
|
43
|
-
/** Resolve a Service token using the active resolver. */
|
|
44
|
-
static async resolve(token) {
|
|
45
|
-
return await ServiceRuntime.current().resolve(token);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/service/service.ts
|
|
50
|
-
/**
|
|
51
|
-
* Declare a class-backed Service with a stable string-literal identity.
|
|
52
|
-
*
|
|
53
|
-
* The returned class is simultaneously the implementation type, the runtime
|
|
54
|
-
* dependency token, and the value yielded by `yield*` in an Effect generator.
|
|
55
|
-
* The explicit self type preserves exact instance inference, while the second
|
|
56
|
-
* call captures the tag as a literal for Layer composition and diagnostics.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* class Database extends Service<Database>()('Database') {
|
|
61
|
-
* query(): string {
|
|
62
|
-
* return 'ok'
|
|
63
|
-
* }
|
|
64
|
-
* }
|
|
65
|
-
*
|
|
66
|
-
* const database = yield* Database
|
|
67
|
-
* database.query()
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* @typeParam Self The instance type implemented by the declared Service.
|
|
71
|
-
*/
|
|
72
|
-
function Service() {
|
|
73
|
-
return function(tag) {
|
|
74
|
-
if (tag.length === 0) throw new TypeError("Service tags must not be empty");
|
|
75
|
-
class BaseService {
|
|
76
|
-
/** The stable logical identity used by Layers and resolver backends. */
|
|
77
|
-
static serviceTag = tag;
|
|
78
|
-
/**
|
|
79
|
-
* Type-check a structural implementation of this Service.
|
|
80
|
-
*
|
|
81
|
-
* This is an identity helper. It returns the supplied value unchanged
|
|
82
|
-
* and does not invoke a constructor or modify its prototype.
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```ts
|
|
86
|
-
* class Database extends Service<Database>()('Database') {
|
|
87
|
-
* query(sql: string): string {
|
|
88
|
-
* return sql
|
|
89
|
-
* }
|
|
90
|
-
* }
|
|
91
|
-
*
|
|
92
|
-
* const database = Database.of({
|
|
93
|
-
* query: (sql) => `Result: ${sql}`
|
|
94
|
-
* })
|
|
95
|
-
*
|
|
96
|
-
* database.query('SELECT 1')
|
|
97
|
-
* // 'Result: SELECT 1'
|
|
98
|
-
* // database is the original object, not an instance of Database
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
static of(implementation) {
|
|
102
|
-
return implementation;
|
|
103
|
-
}
|
|
104
|
-
/** Resolve this Service from the resolver active in the current runtime. */
|
|
105
|
-
static async *[Symbol.asyncIterator]() {
|
|
106
|
-
return await ServiceRuntime.resolve(this);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return BaseService;
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
//#endregion
|
|
113
|
-
//#region src/layer/internal.ts
|
|
114
|
-
const runLayerGenerator = async (service, factory) => {
|
|
115
|
-
const iterator = factory();
|
|
116
|
-
const state = await iterator.next();
|
|
117
|
-
if (!state.done) try {
|
|
118
|
-
await iterator.return(void 0);
|
|
119
|
-
} finally {
|
|
120
|
-
throw new LayerGeneratorYieldError(service);
|
|
121
|
-
}
|
|
122
|
-
return state.value;
|
|
123
|
-
};
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region src/layer/layer.ts
|
|
126
|
-
/**
|
|
127
|
-
* Declarative collection of Service providers.
|
|
128
|
-
*
|
|
129
|
-
* A Layer describes how to acquire implementations; it does not execute
|
|
130
|
-
* providers until a `Runtime` is created. Use `merge` to compose distinct
|
|
131
|
-
* providers and `override` when replacing an existing provider intentionally.
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```ts
|
|
135
|
-
* const AppLive = Layer.merge(
|
|
136
|
-
* Layer.succeed(Database, database),
|
|
137
|
-
* Layer.make(UserRepository)
|
|
138
|
-
* )
|
|
139
|
-
*
|
|
140
|
-
* const runtime = await Runtime.make(AppLive, backend)
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
var Layer = class Layer {
|
|
144
|
-
/** The provider registrations retained by this Layer. */
|
|
145
|
-
providers;
|
|
146
|
-
constructor(providers) {
|
|
147
|
-
this.providers = Object.freeze([...providers]);
|
|
148
|
-
}
|
|
149
|
-
static make(service, acquire) {
|
|
150
|
-
const defaultAcquire = () => {
|
|
151
|
-
return new service();
|
|
152
|
-
};
|
|
153
|
-
const normalizedAcquire = normalizeAcquire(acquire ?? defaultAcquire);
|
|
154
|
-
return new Layer([{
|
|
155
|
-
service,
|
|
156
|
-
acquire: normalizedAcquire
|
|
157
|
-
}]);
|
|
158
|
-
}
|
|
159
|
-
/** Create a Layer from an already-constructed Service instance. */
|
|
160
|
-
static succeed(service, instance) {
|
|
161
|
-
const normalizedAcquire = normalizeAcquire(() => instance);
|
|
162
|
-
return new Layer([{
|
|
163
|
-
service,
|
|
164
|
-
acquire: normalizedAcquire
|
|
165
|
-
}]);
|
|
166
|
-
}
|
|
167
|
-
/** Define a provider with Runtime-root cleanup. */
|
|
168
|
-
static scoped(service, acquire, release) {
|
|
169
|
-
return new Layer([{
|
|
170
|
-
service,
|
|
171
|
-
acquire: normalizeAcquire(acquire),
|
|
172
|
-
release: (instance, outcome) => {
|
|
173
|
-
return release(instance, outcome);
|
|
174
|
-
}
|
|
175
|
-
}]);
|
|
176
|
-
}
|
|
177
|
-
/** Define a provider whose acquisition can yield contextual Services. */
|
|
178
|
-
static scopedGen(service, factory, release) {
|
|
179
|
-
return new Layer([{
|
|
180
|
-
service,
|
|
181
|
-
acquire: () => runLayerGenerator(service, factory),
|
|
182
|
-
release: (instance, outcome) => {
|
|
183
|
-
return release(instance, outcome);
|
|
184
|
-
}
|
|
185
|
-
}]);
|
|
186
|
-
}
|
|
187
|
-
/** Define a provider whose acquisition can yield contextual Services. */
|
|
188
|
-
static gen(service, factory) {
|
|
189
|
-
return new Layer([{
|
|
190
|
-
service,
|
|
191
|
-
acquire: () => runLayerGenerator(service, factory)
|
|
192
|
-
}]);
|
|
193
|
-
}
|
|
194
|
-
/** Compose Layers without replacing providers. */
|
|
195
|
-
static merge(...layers) {
|
|
196
|
-
const providers = /* @__PURE__ */ new Map();
|
|
197
|
-
for (const layer of layers) for (const provider of layer.providers) {
|
|
198
|
-
const service = provider.service;
|
|
199
|
-
const existing = providers.get(service.serviceTag);
|
|
200
|
-
if (existing) {
|
|
201
|
-
if (existing.service !== service) throw new ServiceTagCollisionError(existing.service, service);
|
|
202
|
-
throw new DuplicateServiceError(service);
|
|
203
|
-
}
|
|
204
|
-
providers.set(service.serviceTag, provider);
|
|
205
|
-
}
|
|
206
|
-
return new Layer([...providers.values()]);
|
|
207
|
-
}
|
|
208
|
-
/** Mark a Layer composition root as complete without changing its runtime value. */
|
|
209
|
-
static complete(layer) {
|
|
210
|
-
return layer;
|
|
211
|
-
}
|
|
212
|
-
/** Replace providers in a base Layer, using tag identity and compatible contracts. */
|
|
213
|
-
static override(base, ...overrides) {
|
|
214
|
-
const providers = /* @__PURE__ */ new Map();
|
|
215
|
-
for (const provider of base.providers) providers.set(provider.service.serviceTag, provider);
|
|
216
|
-
for (const layer of overrides) for (const provider of layer.providers) providers.set(provider.service.serviceTag, provider);
|
|
217
|
-
return new Layer([...providers.values()]);
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
const normalizeAcquire = (acquire) => () => {
|
|
221
|
-
return acquire();
|
|
222
|
-
};
|
|
223
|
-
//#endregion
|
|
224
7
|
//#region src/scope/errors.ts
|
|
225
8
|
/** Thrown when Scope context is accessed outside an active Scope execution. */
|
|
226
9
|
var ScopeRuntimeNotConfiguredError = class extends Error {
|
|
@@ -473,6 +256,9 @@ const Scope = {
|
|
|
473
256
|
};
|
|
474
257
|
//#endregion
|
|
475
258
|
//#region src/effect/combinators.ts
|
|
259
|
+
const asResult = (value) => {
|
|
260
|
+
return value;
|
|
261
|
+
};
|
|
476
262
|
const mapResult = (result, fn) => {
|
|
477
263
|
return Result.map(result, fn);
|
|
478
264
|
};
|
|
@@ -537,6 +323,83 @@ function andThenAsync(first, second) {
|
|
|
537
323
|
});
|
|
538
324
|
return andThenAsyncResult(first, next);
|
|
539
325
|
}
|
|
326
|
+
const tapResult = (result, fn) => Result.tap(result, fn);
|
|
327
|
+
const tapErrorResult = (result, fn) => Result.tapError(result, fn);
|
|
328
|
+
const tapBothResult = (result, handlers) => Result.tapBoth(result, handlers);
|
|
329
|
+
const recoverResult = (result, fn) => Result.tryRecover(result, fn);
|
|
330
|
+
const recoverAsyncResult = (result, fn) => Result.tryRecoverAsync(result, (error) => Promise.resolve(fn(error)));
|
|
331
|
+
const flattenResult = (result) => Result.flatten(result);
|
|
332
|
+
const matchResult = (result, handlers) => Result.match(result, handlers);
|
|
333
|
+
const allResult = (results) => Result.all(results);
|
|
334
|
+
function tap(first, second) {
|
|
335
|
+
if (first instanceof Function && second === void 0) {
|
|
336
|
+
const callback = first;
|
|
337
|
+
return (effect) => tap(effect, callback);
|
|
338
|
+
}
|
|
339
|
+
if (second === void 0) throw new TypeError("Effect.tap requires a callback");
|
|
340
|
+
const fn = second;
|
|
341
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => tapResult(asResult(result), fn));
|
|
342
|
+
return tapResult(asResult(first), fn);
|
|
343
|
+
}
|
|
344
|
+
function tapError(first, second) {
|
|
345
|
+
if (first instanceof Function && second === void 0) {
|
|
346
|
+
const callback = first;
|
|
347
|
+
return (effect) => tapError(effect, callback);
|
|
348
|
+
}
|
|
349
|
+
if (second === void 0) throw new TypeError("Effect.tapError requires a callback");
|
|
350
|
+
const fn = second;
|
|
351
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => tapErrorResult(asResult(result), fn));
|
|
352
|
+
return tapErrorResult(asResult(first), fn);
|
|
353
|
+
}
|
|
354
|
+
function tapBoth(first, second) {
|
|
355
|
+
if (second === void 0) return (effect) => tapBoth(effect, first);
|
|
356
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => tapBothResult(result, second));
|
|
357
|
+
return tapBothResult(asResult(first), second);
|
|
358
|
+
}
|
|
359
|
+
function recover(first, second) {
|
|
360
|
+
if (first instanceof Function && second === void 0) {
|
|
361
|
+
const callback = first;
|
|
362
|
+
return (effect) => recover(effect, callback);
|
|
363
|
+
}
|
|
364
|
+
if (second === void 0) throw new TypeError("Effect.recover requires a callback");
|
|
365
|
+
const fn = second;
|
|
366
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => recoverResult(asResult(result), fn));
|
|
367
|
+
return recoverResult(asResult(first), fn);
|
|
368
|
+
}
|
|
369
|
+
function recoverAsync(first, second) {
|
|
370
|
+
if (first instanceof Function && second === void 0) {
|
|
371
|
+
const callback = first;
|
|
372
|
+
return (effect) => recoverAsync(effect, callback);
|
|
373
|
+
}
|
|
374
|
+
if (second === void 0) throw new TypeError("Effect.recoverAsync requires a callback");
|
|
375
|
+
const fn = second;
|
|
376
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => recoverAsyncResult(asResult(result), fn));
|
|
377
|
+
return recoverAsyncResult(asResult(first), fn);
|
|
378
|
+
}
|
|
379
|
+
/** Remove one nested Result/Effect layer. */
|
|
380
|
+
function flatten(effect) {
|
|
381
|
+
return flattenResult(asResult(effect));
|
|
382
|
+
}
|
|
383
|
+
function as(first, second) {
|
|
384
|
+
if (arguments.length < 2) return (effect) => as(effect, first);
|
|
385
|
+
return mapResult(asResult(first), () => second);
|
|
386
|
+
}
|
|
387
|
+
/** Replace a successful value with void. */
|
|
388
|
+
function asVoid(effect) {
|
|
389
|
+
return mapResult(asResult(effect), () => void 0);
|
|
390
|
+
}
|
|
391
|
+
function match(first, second) {
|
|
392
|
+
if (isPromiseLike(first)) return Promise.resolve(first).then((result) => match(asResult(result), second));
|
|
393
|
+
return matchResult(asResult(first), second);
|
|
394
|
+
}
|
|
395
|
+
/** Collect already-created Effects in input order. */
|
|
396
|
+
function all(results) {
|
|
397
|
+
return allResult(results);
|
|
398
|
+
}
|
|
399
|
+
/** Combine two already-created Effects in input order. */
|
|
400
|
+
function zip(left, right) {
|
|
401
|
+
return Result.all([left, right]);
|
|
402
|
+
}
|
|
540
403
|
//#endregion
|
|
541
404
|
//#region src/effect/effect.ts
|
|
542
405
|
const runResultGenerator = Result.gen;
|
|
@@ -547,6 +410,40 @@ function fn(body) {
|
|
|
547
410
|
const program = () => runResultGenerator(body);
|
|
548
411
|
return program;
|
|
549
412
|
}
|
|
413
|
+
const validateProgramConcurrency = (concurrency) => {
|
|
414
|
+
if (concurrency !== void 0 && (!Number.isFinite(concurrency) || !Number.isInteger(concurrency) || concurrency <= 0)) throw new RangeError("Program.all concurrency must be a positive integer");
|
|
415
|
+
};
|
|
416
|
+
/** Build a lazy Program collection with optional bounded concurrency. */
|
|
417
|
+
function programAll(programs, options = {}) {
|
|
418
|
+
validateProgramConcurrency(options.concurrency);
|
|
419
|
+
const concurrency = options.concurrency;
|
|
420
|
+
const program = async () => {
|
|
421
|
+
const results = Array.from({ length: programs.length });
|
|
422
|
+
const failures = Array.from({ length: programs.length }, () => false);
|
|
423
|
+
const causes = Array.from({ length: programs.length });
|
|
424
|
+
let nextIndex = 0;
|
|
425
|
+
const worker = async () => {
|
|
426
|
+
while (true) {
|
|
427
|
+
const index = nextIndex++;
|
|
428
|
+
if (index >= programs.length) return;
|
|
429
|
+
try {
|
|
430
|
+
results[index] = await programs[index]();
|
|
431
|
+
} catch (cause) {
|
|
432
|
+
failures[index] = true;
|
|
433
|
+
causes[index] = cause;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
const workers = Math.min(concurrency ?? programs.length, programs.length);
|
|
438
|
+
await Promise.all(Array.from({ length: workers }, () => worker()));
|
|
439
|
+
const failureIndex = failures.findIndex(Boolean);
|
|
440
|
+
if (failureIndex >= 0) throw causes[failureIndex];
|
|
441
|
+
return Result.all(results);
|
|
442
|
+
};
|
|
443
|
+
return program;
|
|
444
|
+
}
|
|
445
|
+
/** Value-level namespace for lazy Program combinators. */
|
|
446
|
+
const Program = { all: programAll };
|
|
550
447
|
/**
|
|
551
448
|
* Acquire a resource in the current Scope and register its release callback.
|
|
552
449
|
*
|
|
@@ -582,12 +479,6 @@ function add(resource) {
|
|
|
582
479
|
const scope = Scope.current();
|
|
583
480
|
return Result.await(Result.tryPromise(() => scope.add(resource)));
|
|
584
481
|
}
|
|
585
|
-
/**
|
|
586
|
-
* Effect namespace containing generator, resource, and Result combinators.
|
|
587
|
-
*
|
|
588
|
-
* Prefer these helpers when a program needs typed Service requirements or
|
|
589
|
-
* Scope-aware acquisition and cleanup.
|
|
590
|
-
*/
|
|
591
482
|
const Effect = {
|
|
592
483
|
/** Compose a generator-based Effect program. */
|
|
593
484
|
gen,
|
|
@@ -604,7 +495,29 @@ const Effect = {
|
|
|
604
495
|
/** Chain a synchronous Effect result. */
|
|
605
496
|
andThen,
|
|
606
497
|
/** Chain an asynchronous Effect result. */
|
|
607
|
-
andThenAsync
|
|
498
|
+
andThenAsync,
|
|
499
|
+
/** Observe successful values without changing the Result. */
|
|
500
|
+
tap,
|
|
501
|
+
/** Observe error values without changing the Result. */
|
|
502
|
+
tapError,
|
|
503
|
+
/** Observe the active Result branch without changing the Result. */
|
|
504
|
+
tapBoth,
|
|
505
|
+
/** Recover an error with another Effect. */
|
|
506
|
+
recover,
|
|
507
|
+
/** Recover an error asynchronously with another Effect. */
|
|
508
|
+
recoverAsync,
|
|
509
|
+
/** Remove one nested Effect layer. */
|
|
510
|
+
flatten,
|
|
511
|
+
/** Replace a successful value. */
|
|
512
|
+
as,
|
|
513
|
+
/** Replace a successful value with void. */
|
|
514
|
+
asVoid,
|
|
515
|
+
/** Match either Result branch. */
|
|
516
|
+
match,
|
|
517
|
+
/** Collect Effects in input order. */
|
|
518
|
+
all,
|
|
519
|
+
/** Zip two Effects in input order. */
|
|
520
|
+
zip
|
|
608
521
|
};
|
|
609
522
|
//#endregion
|
|
610
523
|
//#region src/function/pipe.ts
|
|
@@ -702,54 +615,6 @@ const classifyRuntimeOutcome = (value) => {
|
|
|
702
615
|
return { status: "success" };
|
|
703
616
|
};
|
|
704
617
|
//#endregion
|
|
705
|
-
//#region src/runtime/signal.ts
|
|
706
|
-
const neverAbortedSignal = new AbortController().signal;
|
|
707
|
-
/** Link caller, Runtime and shutdown signals without owning the caller's controller. */
|
|
708
|
-
const linkAbortSignals = (...signals) => {
|
|
709
|
-
const active = signals.filter((signal) => signal !== void 0);
|
|
710
|
-
if (active.length === 0) return {
|
|
711
|
-
signal: neverAbortedSignal,
|
|
712
|
-
dispose: () => {}
|
|
713
|
-
};
|
|
714
|
-
if (active.length === 1) return {
|
|
715
|
-
signal: active[0],
|
|
716
|
-
dispose: () => {}
|
|
717
|
-
};
|
|
718
|
-
const controller = new AbortController();
|
|
719
|
-
const listeners = [];
|
|
720
|
-
let disposed = false;
|
|
721
|
-
const dispose = () => {
|
|
722
|
-
if (disposed) return;
|
|
723
|
-
disposed = true;
|
|
724
|
-
for (const [source, listener] of listeners) source.removeEventListener("abort", listener);
|
|
725
|
-
listeners.length = 0;
|
|
726
|
-
};
|
|
727
|
-
const abortFrom = (source) => {
|
|
728
|
-
if (controller.signal.aborted) return;
|
|
729
|
-
controller.abort(source.reason);
|
|
730
|
-
dispose();
|
|
731
|
-
};
|
|
732
|
-
for (const source of active) {
|
|
733
|
-
if (source.aborted) {
|
|
734
|
-
abortFrom(source);
|
|
735
|
-
break;
|
|
736
|
-
}
|
|
737
|
-
const listener = () => abortFrom(source);
|
|
738
|
-
listeners.push([source, listener]);
|
|
739
|
-
source.addEventListener("abort", listener, { once: true });
|
|
740
|
-
}
|
|
741
|
-
return {
|
|
742
|
-
signal: controller.signal,
|
|
743
|
-
dispose
|
|
744
|
-
};
|
|
745
|
-
};
|
|
746
|
-
/** Return the current cooperative-cancellation signal. */
|
|
747
|
-
const currentAbortSignal = () => currentRuntimeContext().signal ?? neverAbortedSignal;
|
|
748
|
-
/** Yieldable access to the signal of the current Runtime execution. */
|
|
749
|
-
const CurrentAbortSignal = { *[Symbol.iterator]() {
|
|
750
|
-
return currentAbortSignal();
|
|
751
|
-
} };
|
|
752
|
-
//#endregion
|
|
753
618
|
//#region src/runtime/observer.ts
|
|
754
619
|
const notifyRuntimeObservers = (observers, select, event) => {
|
|
755
620
|
for (const observer of observers) {
|
|
@@ -1272,6 +1137,6 @@ var Runtime = class Runtime {
|
|
|
1272
1137
|
}
|
|
1273
1138
|
};
|
|
1274
1139
|
//#endregion
|
|
1275
|
-
export { CircularDependencyError, CurrentAbortSignal, DuplicateServiceError, Effect, Layer, LayerDisposeError, LayerGeneratorYieldError, LayerRegistrationError, MapLayerBackend, Resource, ResourceNotDisposableError, ResourceReleaseFailure, Runtime, RuntimeContextNotConfiguredError, Scope, ScopeCloseError, ScopeClosedError, ScopeRuntimeNotConfiguredError, Service, ServiceAcquisitionError, ServiceNotFoundError, ServiceRuntime, ServiceRuntimeNotConfiguredError, ServiceTagCollisionError, pipe };
|
|
1140
|
+
export { CircularDependencyError, CurrentAbortSignal, DuplicateServiceError, Effect, Layer, LayerDisposeError, LayerGeneratorYieldError, LayerRegistrationError, MapLayerBackend, Program, Resource, ResourceNotDisposableError, ResourceReleaseFailure, Runtime, RuntimeContextNotConfiguredError, Scope, ScopeCloseError, ScopeClosedError, ScopeRuntimeNotConfiguredError, Service, ServiceAcquisitionError, ServiceNotFoundError, ServiceRuntime, ServiceRuntimeNotConfiguredError, ServiceTagCollisionError, pipe };
|
|
1276
1141
|
|
|
1277
1142
|
//# sourceMappingURL=index.mjs.map
|