uneventful 0.0.9 → 0.0.11
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 +2 -2
- package/dist/call-or-wait-EzXJX5Dq.mjs +111 -0
- package/dist/ext.d.ts +260 -0
- package/dist/ext.mjs +112 -0
- package/dist/{call-or-wait-DpJBh_pS.mjs → jobutils-Dvu-e99o.mjs} +64 -167
- package/dist/mod.d.ts +65 -5
- package/dist/mod.mjs +11 -9
- package/dist/shared.d.ts +109 -0
- package/dist/shared.mjs +52 -0
- package/dist/signals.d.ts +26 -4
- package/dist/signals.mjs +70 -47
- package/dist/{utils-P0JEpWXG.mjs → utils-cyEhnyp7.mjs} +16 -7
- package/dist/utils.d.ts +77 -26
- package/dist/utils.mjs +1 -2
- package/package.json +27 -11
- package/dist/call-or-wait-DpJBh_pS.mjs.map +0 -1
- package/dist/mod.mjs.map +0 -1
- package/dist/signals.mjs.map +0 -1
- package/dist/utils-P0JEpWXG.mjs.map +0 -1
- package/dist/utils.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { e as batch, d as defer, i as isFunction, G as GeneratorBase, c as apply } from './utils-cyEhnyp7.mjs';
|
|
2
2
|
|
|
3
3
|
function resolve(request, val) {
|
|
4
4
|
request("next", val);
|
|
@@ -44,12 +44,13 @@ function markHandled(res) {
|
|
|
44
44
|
return res.err;
|
|
45
45
|
}
|
|
46
46
|
function getResult(res) {
|
|
47
|
-
if (isValue(res))
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
47
|
+
if (!isValue(res)) {
|
|
48
|
+
res.op;
|
|
49
|
+
fulfillPromise(noop, (e) => {
|
|
50
|
+
throw e;
|
|
51
|
+
}, res);
|
|
52
|
+
}
|
|
53
|
+
return res.val;
|
|
53
54
|
}
|
|
54
55
|
function fulfillPromise(resolve2, reject2, res) {
|
|
55
56
|
if (isError(res))
|
|
@@ -66,31 +67,25 @@ function propagateResult(job, res) {
|
|
|
66
67
|
class CancelError extends Error {
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
var
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return { job, cell };
|
|
84
|
-
}
|
|
85
|
-
function freeCtx(s) {
|
|
86
|
-
s.job = s.cell = null;
|
|
87
|
-
freelist.push(s);
|
|
70
|
+
var currentJob, currentCell;
|
|
71
|
+
const cells = [], jobs = [];
|
|
72
|
+
function pushCtx(job, cell) {
|
|
73
|
+
jobs.push(currentJob);
|
|
74
|
+
cells.push(currentCell);
|
|
75
|
+
currentJob = job;
|
|
76
|
+
currentCell = cell;
|
|
77
|
+
}
|
|
78
|
+
function popCtx() {
|
|
79
|
+
currentJob = jobs.pop();
|
|
80
|
+
currentCell = cells.pop();
|
|
81
|
+
}
|
|
82
|
+
function cellJob() {
|
|
83
|
+
return currentJob ||= currentCell?.getJob();
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
const catchers = /* @__PURE__ */ new WeakMap(), defaultCatch = (e) => {
|
|
91
87
|
Promise.reject(e);
|
|
92
88
|
};
|
|
93
|
-
const nullCtx = makeCtx();
|
|
94
89
|
const owners = /* @__PURE__ */ new WeakMap();
|
|
95
90
|
const pulls = /* @__PURE__ */ batch((pulls2) => {
|
|
96
91
|
for (const conn of pulls2) {
|
|
@@ -127,8 +122,7 @@ function qlen(c) {
|
|
|
127
122
|
return c ? c.v : 0;
|
|
128
123
|
}
|
|
129
124
|
function pop(c) {
|
|
130
|
-
|
|
131
|
-
return unlink(c, c.p);
|
|
125
|
+
return qlen(c) ? unlink(c, c.p) : void 0;
|
|
132
126
|
}
|
|
133
127
|
class Node {
|
|
134
128
|
constructor() {
|
|
@@ -185,22 +179,23 @@ function unlinker(chain2, node) {
|
|
|
185
179
|
}
|
|
186
180
|
|
|
187
181
|
function getJob() {
|
|
188
|
-
const job =
|
|
182
|
+
const job = currentJob || cellJob();
|
|
189
183
|
if (job)
|
|
190
184
|
return job;
|
|
191
185
|
throw new Error("No job is currently active");
|
|
192
186
|
}
|
|
193
187
|
function recalcJob(job) {
|
|
194
188
|
return (cb) => {
|
|
195
|
-
|
|
189
|
+
currentJob.must(job.release(cb));
|
|
196
190
|
};
|
|
197
191
|
}
|
|
198
192
|
function runChain(res, cbs) {
|
|
199
|
-
|
|
193
|
+
let cb;
|
|
194
|
+
while (cb = pop(cbs))
|
|
200
195
|
try {
|
|
201
|
-
|
|
196
|
+
cb(res);
|
|
202
197
|
} catch (e) {
|
|
203
|
-
|
|
198
|
+
_detached.asyncThrow(e);
|
|
204
199
|
}
|
|
205
200
|
cbs && recycle(cbs);
|
|
206
201
|
return void 0;
|
|
@@ -212,14 +207,15 @@ class _Job {
|
|
|
212
207
|
const res = this._done ||= CancelResult, cbs = this._cbs;
|
|
213
208
|
if (!cbs && !isUnhandled(res))
|
|
214
209
|
return;
|
|
215
|
-
const ct = inProcess.size
|
|
210
|
+
const ct = inProcess.size;
|
|
211
|
+
pushCtx();
|
|
216
212
|
if (!ct)
|
|
217
213
|
inProcess.add(null);
|
|
218
214
|
if (cbs && cbs.u)
|
|
219
215
|
cbs.u = runChain(res, cbs.u);
|
|
220
216
|
inProcess.add(this);
|
|
221
217
|
if (ct) {
|
|
222
|
-
|
|
218
|
+
popCtx();
|
|
223
219
|
return;
|
|
224
220
|
}
|
|
225
221
|
inProcess.delete(null);
|
|
@@ -230,7 +226,7 @@ class _Job {
|
|
|
230
226
|
if (isUnhandled(item._done))
|
|
231
227
|
item.throw(markHandled(item._done));
|
|
232
228
|
}
|
|
233
|
-
|
|
229
|
+
popCtx();
|
|
234
230
|
};
|
|
235
231
|
this._done = void 0;
|
|
236
232
|
// Chain whose .u stores a second chain for `release()` callbacks
|
|
@@ -268,7 +264,7 @@ class _Job {
|
|
|
268
264
|
});
|
|
269
265
|
}
|
|
270
266
|
result() {
|
|
271
|
-
return this._done ||
|
|
267
|
+
return this._done || currentCell?.recalcWhen(this, recalcJob) || void 0;
|
|
272
268
|
}
|
|
273
269
|
get [Symbol.toStringTag]() {
|
|
274
270
|
return "Job";
|
|
@@ -289,14 +285,14 @@ class _Job {
|
|
|
289
285
|
_end(res) {
|
|
290
286
|
if (this._done)
|
|
291
287
|
throw new Error("Job already ended");
|
|
292
|
-
if (this !==
|
|
288
|
+
if (this !== _detached)
|
|
293
289
|
this._done = res;
|
|
294
290
|
this.end();
|
|
295
291
|
return this;
|
|
296
292
|
}
|
|
297
293
|
throw(err) {
|
|
298
294
|
if (this._done) {
|
|
299
|
-
(owners.get(this) ||
|
|
295
|
+
(owners.get(this) || _detached).asyncThrow(err);
|
|
300
296
|
return this;
|
|
301
297
|
}
|
|
302
298
|
return this._end(ErrorResult(err));
|
|
@@ -380,21 +376,21 @@ class _Job {
|
|
|
380
376
|
return this.start((job) => void src(sink, job, inlet));
|
|
381
377
|
}
|
|
382
378
|
run(fn, ...args) {
|
|
383
|
-
|
|
379
|
+
pushCtx(this);
|
|
384
380
|
try {
|
|
385
381
|
return fn(...args);
|
|
386
382
|
} finally {
|
|
387
|
-
|
|
383
|
+
popCtx();
|
|
388
384
|
}
|
|
389
385
|
}
|
|
390
386
|
bind(fn) {
|
|
391
387
|
const job = this;
|
|
392
388
|
return function() {
|
|
393
|
-
|
|
389
|
+
pushCtx(job);
|
|
394
390
|
try {
|
|
395
391
|
return apply(fn, this, arguments);
|
|
396
392
|
} finally {
|
|
397
|
-
|
|
393
|
+
popCtx();
|
|
398
394
|
}
|
|
399
395
|
};
|
|
400
396
|
}
|
|
@@ -404,7 +400,7 @@ class _Job {
|
|
|
404
400
|
return this;
|
|
405
401
|
}
|
|
406
402
|
release(cleanup) {
|
|
407
|
-
if (this ===
|
|
403
|
+
if (this === _detached)
|
|
408
404
|
return noop;
|
|
409
405
|
let cbs = this._chain();
|
|
410
406
|
if (!this._done || cbs.u)
|
|
@@ -415,7 +411,7 @@ class _Job {
|
|
|
415
411
|
try {
|
|
416
412
|
(catchers.get(this) || this.throw).call(this, err);
|
|
417
413
|
} catch (e) {
|
|
418
|
-
if (this ===
|
|
414
|
+
if (this === _detached)
|
|
419
415
|
catchers.set(this, defaultCatch);
|
|
420
416
|
else
|
|
421
417
|
catchers.delete(this);
|
|
@@ -433,7 +429,7 @@ class _Job {
|
|
|
433
429
|
return this;
|
|
434
430
|
}
|
|
435
431
|
_chain() {
|
|
436
|
-
if (this ===
|
|
432
|
+
if (this === _detached)
|
|
437
433
|
this.end();
|
|
438
434
|
if (this._done && isEmpty(this._cbs))
|
|
439
435
|
defer(this.end);
|
|
@@ -454,14 +450,23 @@ function nativePromise(job) {
|
|
|
454
450
|
return promises.get(job);
|
|
455
451
|
}
|
|
456
452
|
const makeJob = _Job.create;
|
|
457
|
-
const
|
|
458
|
-
detached
|
|
453
|
+
const _detached = makeJob();
|
|
454
|
+
const detached = _detached;
|
|
455
|
+
_detached.end = () => {
|
|
459
456
|
throw new Error("Can't do that with the detached job");
|
|
460
457
|
};
|
|
461
|
-
|
|
458
|
+
_detached.asyncCatch(defaultCatch);
|
|
459
|
+
let root;
|
|
460
|
+
newRoot();
|
|
461
|
+
function newRoot() {
|
|
462
|
+
root?.end();
|
|
463
|
+
const job = root = makeJob().asyncCatch((e) => _detached.asyncThrow(e));
|
|
464
|
+
job.release(() => root === job && (root = null));
|
|
465
|
+
return root;
|
|
466
|
+
}
|
|
462
467
|
function runGen(g, job) {
|
|
463
|
-
let it = g[Symbol.iterator](), running = true,
|
|
464
|
-
let done =
|
|
468
|
+
let it = g[Symbol.iterator](), running = true, j = job, ct = 0;
|
|
469
|
+
let done = job.release(() => {
|
|
465
470
|
job = void 0;
|
|
466
471
|
++ct;
|
|
467
472
|
step("return", void 0);
|
|
@@ -476,7 +481,7 @@ function runGen(g, job) {
|
|
|
476
481
|
if (running) {
|
|
477
482
|
return defer(step.bind(null, method, arg));
|
|
478
483
|
}
|
|
479
|
-
|
|
484
|
+
pushCtx(j);
|
|
480
485
|
try {
|
|
481
486
|
running = true;
|
|
482
487
|
try {
|
|
@@ -510,107 +515,18 @@ function runGen(g, job) {
|
|
|
510
515
|
}
|
|
511
516
|
} catch (e) {
|
|
512
517
|
it = job = void 0;
|
|
513
|
-
|
|
518
|
+
j.throw(e);
|
|
514
519
|
}
|
|
515
520
|
it = void 0;
|
|
516
521
|
done?.();
|
|
517
522
|
done = void 0;
|
|
518
523
|
} finally {
|
|
519
|
-
|
|
524
|
+
popCtx();
|
|
520
525
|
running = false;
|
|
521
526
|
}
|
|
522
527
|
}
|
|
523
528
|
}
|
|
524
529
|
|
|
525
|
-
function backpressure(inlet = defaultInlet) {
|
|
526
|
-
const job = getJob();
|
|
527
|
-
return (cb) => {
|
|
528
|
-
if (!job.result() && inlet.isOpen()) {
|
|
529
|
-
if (cb)
|
|
530
|
-
inlet.onReady(cb, job);
|
|
531
|
-
return inlet.isReady();
|
|
532
|
-
}
|
|
533
|
-
return false;
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
const IsStream = "uneventful/is-stream";
|
|
537
|
-
function connect(src, sink, inlet) {
|
|
538
|
-
return getJob().connect(src, sink, inlet);
|
|
539
|
-
}
|
|
540
|
-
function throttle(job = current.job) {
|
|
541
|
-
return new _Throttle(job);
|
|
542
|
-
}
|
|
543
|
-
class _Throttle {
|
|
544
|
-
/** @internal */
|
|
545
|
-
constructor(_job) {
|
|
546
|
-
this._job = _job;
|
|
547
|
-
/** @internal */
|
|
548
|
-
this._callbacks = void 0;
|
|
549
|
-
this._isReady = true;
|
|
550
|
-
this._isPulling = false;
|
|
551
|
-
}
|
|
552
|
-
isOpen() {
|
|
553
|
-
return !this._job?.result();
|
|
554
|
-
}
|
|
555
|
-
/** Is the connection ready to receive data? */
|
|
556
|
-
isReady() {
|
|
557
|
-
return this.isOpen() && this._isReady;
|
|
558
|
-
}
|
|
559
|
-
onReady(cb, job) {
|
|
560
|
-
if (!this.isOpen())
|
|
561
|
-
return this;
|
|
562
|
-
const _callbacks = this._callbacks ||= /* @__PURE__ */ new Map();
|
|
563
|
-
const unlink = job.release(() => _callbacks.delete(cb));
|
|
564
|
-
if (this.isReady() && this && !_callbacks.size) {
|
|
565
|
-
pulls.add(this);
|
|
566
|
-
}
|
|
567
|
-
_callbacks.set(cb, unlink);
|
|
568
|
-
return this;
|
|
569
|
-
}
|
|
570
|
-
pause() {
|
|
571
|
-
this._isReady = false;
|
|
572
|
-
return this;
|
|
573
|
-
}
|
|
574
|
-
doPull() {
|
|
575
|
-
if (this._isPulling)
|
|
576
|
-
return;
|
|
577
|
-
const { _callbacks } = this;
|
|
578
|
-
if (!_callbacks?.size)
|
|
579
|
-
return;
|
|
580
|
-
this._isPulling = true;
|
|
581
|
-
try {
|
|
582
|
-
for (let [cb, unlink] of _callbacks) {
|
|
583
|
-
if (!this.isReady())
|
|
584
|
-
break;
|
|
585
|
-
unlink();
|
|
586
|
-
_callbacks.delete(cb);
|
|
587
|
-
cb();
|
|
588
|
-
}
|
|
589
|
-
} finally {
|
|
590
|
-
this._isPulling = false;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
resume() {
|
|
594
|
-
if (this.isOpen()) {
|
|
595
|
-
this._isReady = true;
|
|
596
|
-
this.doPull();
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
const defaultInlet = throttle();
|
|
601
|
-
function pipe() {
|
|
602
|
-
var v = arguments[0];
|
|
603
|
-
for (var i = 1; i < arguments.length; i++)
|
|
604
|
-
v = arguments[i](v);
|
|
605
|
-
return v;
|
|
606
|
-
}
|
|
607
|
-
function compose(...fns) {
|
|
608
|
-
return (val) => pipe(val, ...fns);
|
|
609
|
-
}
|
|
610
|
-
function into(...args) {
|
|
611
|
-
return (src) => src(...args);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
530
|
function must(cleanup) {
|
|
615
531
|
getJob().must(cleanup);
|
|
616
532
|
}
|
|
@@ -618,7 +534,7 @@ function start(init, fn) {
|
|
|
618
534
|
return getJob().start(init, fn);
|
|
619
535
|
}
|
|
620
536
|
function isJobActive() {
|
|
621
|
-
return !!
|
|
537
|
+
return !!currentJob;
|
|
622
538
|
}
|
|
623
539
|
const timers = /* @__PURE__ */ new WeakMap();
|
|
624
540
|
function timeout(ms = 0, job = getJob()) {
|
|
@@ -664,14 +580,14 @@ function restarting(task2) {
|
|
|
664
580
|
inner.asyncCatch((e) => outer.asyncThrow(e));
|
|
665
581
|
return function() {
|
|
666
582
|
inner.restart().must(outer.release(end));
|
|
667
|
-
|
|
583
|
+
pushCtx(inner);
|
|
668
584
|
try {
|
|
669
585
|
return apply(task2, this, arguments);
|
|
670
586
|
} catch (e) {
|
|
671
587
|
inner.restart();
|
|
672
588
|
throw e;
|
|
673
589
|
} finally {
|
|
674
|
-
|
|
590
|
+
popCtx();
|
|
675
591
|
}
|
|
676
592
|
};
|
|
677
593
|
}
|
|
@@ -683,23 +599,4 @@ function task(fn, _ctx, desc) {
|
|
|
683
599
|
};
|
|
684
600
|
}
|
|
685
601
|
|
|
686
|
-
|
|
687
|
-
if (source && isFunction(source[method]))
|
|
688
|
-
return source[method]();
|
|
689
|
-
if (isFunction(source))
|
|
690
|
-
return (source.length === 0 ? noArgs(source) : false) || start((job) => {
|
|
691
|
-
connect(source, (v) => handler(job, v)).do((r) => {
|
|
692
|
-
if (isValue(r))
|
|
693
|
-
job.throw(new Error("Stream ended"));
|
|
694
|
-
else if (isError(r))
|
|
695
|
-
job.throw(markHandled(r));
|
|
696
|
-
});
|
|
697
|
-
});
|
|
698
|
-
mustBeSourceOrSignal();
|
|
699
|
-
}
|
|
700
|
-
function mustBeSourceOrSignal() {
|
|
701
|
-
throw new TypeError("not a source or signal");
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
export { nativePromise as A, makeJob as B, CancelResult as C, pipe as D, ErrorResult as E, compose as F, into as G, isJobActive as H, IsStream as I, timeout as J, abortSignal as K, task as L, swapCtx as M, nullCtx as N, makeCtx as O, freeCtx as P, ValueResult as V, rejecter as a, resolve as b, backpressure as c, detached as d, isUnhandled as e, markHandled as f, getJob as g, isError as h, isCancel as i, connect as j, fulfillPromise as k, callOrWait as l, must as m, noop as n, restarting as o, current as p, mustBeSourceOrSignal as q, resolver as r, start as s, throttle as t, isValue as u, reject as v, isHandled as w, getResult as x, propagateResult as y, CancelError as z };
|
|
705
|
-
//# sourceMappingURL=call-or-wait-DpJBh_pS.mjs.map
|
|
602
|
+
export { timeout as A, abortSignal as B, CancelResult as C, task as D, ErrorResult as E, pushCtx as F, popCtx as G, currentJob as H, pulls as I, ValueResult as V, rejecter as a, resolve as b, root as c, isUnhandled as d, markHandled as e, isError as f, getJob as g, fulfillPromise as h, isCancel as i, restarting as j, currentCell as k, isValue as l, must as m, noop as n, reject as o, isHandled as p, getResult as q, resolver as r, start as s, propagateResult as t, CancelError as u, nativePromise as v, makeJob as w, detached as x, newRoot as y, isJobActive as z };
|
package/dist/mod.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { a as Each, E as EachResult, N as NextMethod, U as UntilMethod, e as eac
|
|
|
6
6
|
* Invoke a no-argument function as a microtask, using queueMicrotask or Promise.resolve().then()
|
|
7
7
|
*
|
|
8
8
|
* @category Scheduling
|
|
9
|
+
* @function
|
|
9
10
|
*/
|
|
10
11
|
declare let defer: (cb: () => any) => void;
|
|
11
12
|
|
|
@@ -37,21 +38,30 @@ declare function nativePromise<T>(job: Job<T>): Promise<T>;
|
|
|
37
38
|
* Return a new {@link Job}. If *either* a parent parameter or stop function
|
|
38
39
|
* are given, the new job is linked to the parent.
|
|
39
40
|
*
|
|
41
|
+
* @remarks You should generally use `start()`, `parent.start()` or
|
|
42
|
+
* `root.start()` instead of this, unless you're creating a special kind of job
|
|
43
|
+
* that needs a custom stop function.
|
|
44
|
+
*
|
|
40
45
|
* @param parent The parent job to which the new job should be attached.
|
|
41
|
-
* Defaults to the currently-active job if none given (assuming a stop
|
|
42
|
-
*
|
|
46
|
+
* Defaults to the currently-active job if none given (assuming a stop parameter
|
|
47
|
+
* is provided).
|
|
43
48
|
*
|
|
44
49
|
* @param stop The function to call to destroy the nested job. Defaults to the
|
|
45
50
|
* {@link Job.end} method of the new job if none is given (assuming a parent
|
|
46
51
|
* parameter is provided).
|
|
47
52
|
*
|
|
48
|
-
* @returns A new job. The job is
|
|
49
|
-
*
|
|
53
|
+
* @returns A new job. The job is a child job if any arguments are given, or
|
|
54
|
+
* a detached (parentless) job otherwise.
|
|
50
55
|
*
|
|
51
56
|
* @category Jobs
|
|
57
|
+
* @function
|
|
52
58
|
*/
|
|
53
59
|
declare const makeJob: <T>(parent?: Job, stop?: CleanupFn) => Job<T>;
|
|
54
60
|
/**
|
|
61
|
+
* @deprecated Use {@link root} instead. (Including uses of
|
|
62
|
+
* `.asyncCatch()` to set the default async error handling policy.)
|
|
63
|
+
*
|
|
64
|
+
* ---
|
|
55
65
|
* A special {@link Job} with no parents, that can be used to create standalone
|
|
56
66
|
* jobs. detached.start() returns a new detached job, detached.run() can be
|
|
57
67
|
* used to run code that expects to create a child job, and detached.bind() can
|
|
@@ -80,6 +90,56 @@ declare const makeJob: <T>(parent?: Job, stop?: CleanupFn) => Job<T>;
|
|
|
80
90
|
* @category Jobs
|
|
81
91
|
*/
|
|
82
92
|
declare const detached: Job<unknown>;
|
|
93
|
+
/**
|
|
94
|
+
* The "main" job of the program or bundle, which all other jobs should be a
|
|
95
|
+
* child of. This provides a single point of configuration and cleanup, as one
|
|
96
|
+
* can e.g.:
|
|
97
|
+
*
|
|
98
|
+
* - Use {@link Job.asyncCatch `root.asyncCatch()`} to define the default async
|
|
99
|
+
* error handling policy
|
|
100
|
+
* - Use {@link Job.end `root.end()`} to clean up all resources for the entire
|
|
101
|
+
* program
|
|
102
|
+
* - Use {@link Job.start `root.start()`} to create top-level, standalone, or
|
|
103
|
+
* "daemon"/service tasks, or to create tasks whose lifetime is managed by an
|
|
104
|
+
* external framework.
|
|
105
|
+
*
|
|
106
|
+
* By default, there is only ever one root job, run once, in a given process or
|
|
107
|
+
* page. But for testing you can use {@link newRoot} to end the existing root
|
|
108
|
+
* and start a new one.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Uneventful does not include any code to end the root job itself, as the
|
|
112
|
+
* decision of when and whether to do that varies heavily by context (e.g.
|
|
113
|
+
* server vs. browser, app vs. plugin, etc.), and often doesn't need to happen
|
|
114
|
+
* at all. (Because exiting the process or leaving the web page is often
|
|
115
|
+
* sufficient.)
|
|
116
|
+
*
|
|
117
|
+
* More commonly, you will only end the root job when running tests (to get a
|
|
118
|
+
* clean environment for the next test), or when your entire bundle is itself an
|
|
119
|
+
* unloadable plugin (e.g. in Obsidian).
|
|
120
|
+
*
|
|
121
|
+
* Note, too, that when the root job ends, root is reset to `null` so that any
|
|
122
|
+
* subsequent attempt to use the root job will throw an exception. (Unless of
|
|
123
|
+
* course a new root job has been created with {@link newRoot}.)
|
|
124
|
+
*
|
|
125
|
+
* @category Jobs
|
|
126
|
+
*/
|
|
127
|
+
declare let root: Job<unknown>;
|
|
128
|
+
/**
|
|
129
|
+
* Create a new root job (usually for testing purposes). If there is an existing
|
|
130
|
+
* root job, it is ended first. The new root is configured to convert async
|
|
131
|
+
* errors into unhandled promise rejections by default, so if you need to change
|
|
132
|
+
* that you can use its {@link Job.asyncCatch `.asyncCatch()`} method.
|
|
133
|
+
*
|
|
134
|
+
* @returns The new root job.
|
|
135
|
+
*
|
|
136
|
+
* @remarks If your project customizes the root job in some way(s), you will
|
|
137
|
+
* probably want a function to do that, so you can use it both in tests and at
|
|
138
|
+
* runtime. (e.g. `myInit(newJob())` in tests, and `myInit(root)` at runtime.)
|
|
139
|
+
*
|
|
140
|
+
* @category Jobs
|
|
141
|
+
*/
|
|
142
|
+
declare function newRoot(): Job<unknown>;
|
|
83
143
|
|
|
84
144
|
/**
|
|
85
145
|
* Convert a (possible) promise to something you can `yield *to()` in a job
|
|
@@ -653,4 +713,4 @@ declare function task<T, A extends any[], C, D extends {
|
|
|
653
713
|
value?: (this: C, ...args: A) => StartObj<T>;
|
|
654
714
|
}>(clsOrProto: any, name: string | symbol, desc: D): D;
|
|
655
715
|
|
|
656
|
-
export { AnyFunction, Backpressure, CleanupFn, DisposeFn, type Emitter, Job, type MockSource, OptionalCleanup, Sink, Source, StartFn, StartObj, Stream, Transformer, Yielding, abortSignal, concat, concatAll, concatMap, defer, detached, emitter, empty, filter, fromAsyncIterable, fromDomEvent, fromIterable, fromPromise, fromSubscribe, fromValue, getJob, interval, isJobActive, lazy, makeJob, map, merge, mergeAll, mergeMap, mockSource, must, nativePromise, never, restarting, share, skip, skipUntil, skipWhile, slack, sleep, start, switchAll, switchMap, take, takeUntil, takeWhile, task, timeout, to };
|
|
716
|
+
export { AnyFunction, Backpressure, CleanupFn, DisposeFn, type Emitter, Job, type MockSource, OptionalCleanup, Sink, Source, StartFn, StartObj, Stream, Transformer, Yielding, abortSignal, concat, concatAll, concatMap, defer, detached, emitter, empty, filter, fromAsyncIterable, fromDomEvent, fromIterable, fromPromise, fromSubscribe, fromValue, getJob, interval, isJobActive, lazy, makeJob, map, merge, mergeAll, mergeMap, mockSource, must, nativePromise, never, newRoot, restarting, root, share, skip, skipUntil, skipWhile, slack, sleep, start, switchAll, switchMap, take, takeUntil, takeWhile, task, timeout, to };
|
package/dist/mod.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { d as defer, i as isFunction } from './utils-
|
|
2
|
-
import { r as resolver, a as rejecter, b as resolve,
|
|
3
|
-
export {
|
|
1
|
+
import { d as defer, i as isFunction } from './utils-cyEhnyp7.mjs';
|
|
2
|
+
import { r as resolver, a as rejecter, b as resolve, m as must, s as start, g as getJob, n as noop, c as root, i as isCancel, d as isUnhandled, e as markHandled, f as isError, h as fulfillPromise, j as restarting, k as currentCell, l as isValue } from './jobutils-Dvu-e99o.mjs';
|
|
3
|
+
export { u as CancelError, C as CancelResult, E as ErrorResult, V as ValueResult, B as abortSignal, x as detached, q as getResult, p as isHandled, z as isJobActive, w as makeJob, v as nativePromise, y as newRoot, t as propagateResult, o as reject, D as task, A as timeout } from './jobutils-Dvu-e99o.mjs';
|
|
4
|
+
import { I as IsStream, b as backpressure, t as throttle, c as connect, a as callOrWait, m as mustBeSourceOrSignal } from './call-or-wait-EzXJX5Dq.mjs';
|
|
5
|
+
export { d as compose, i as into, p as pipe } from './call-or-wait-EzXJX5Dq.mjs';
|
|
4
6
|
|
|
5
7
|
function* to(p) {
|
|
6
8
|
return yield (res) => Promise.resolve(p).then(resolver(res), rejecter(res));
|
|
@@ -189,7 +191,7 @@ function share(source) {
|
|
|
189
191
|
defer(produce);
|
|
190
192
|
});
|
|
191
193
|
if (links.size === 1) {
|
|
192
|
-
uplink =
|
|
194
|
+
uplink = root.connect(source, (v) => {
|
|
193
195
|
for (const [s, c] of links)
|
|
194
196
|
try {
|
|
195
197
|
s(v);
|
|
@@ -274,10 +276,10 @@ function forEach(src, sink, inlet) {
|
|
|
274
276
|
return (src2) => forEach(src2, sink, inlet);
|
|
275
277
|
}
|
|
276
278
|
function recalcWhen(fnOrKey, fn) {
|
|
277
|
-
|
|
279
|
+
currentCell?.recalcWhen(fnOrKey, fn);
|
|
278
280
|
}
|
|
279
281
|
function isObserved() {
|
|
280
|
-
return
|
|
282
|
+
return currentCell?.isObserved();
|
|
281
283
|
}
|
|
282
284
|
|
|
283
285
|
function concat(sources) {
|
|
@@ -369,7 +371,7 @@ function slack(size, dropped = noop) {
|
|
|
369
371
|
conn.connect(src, (v) => {
|
|
370
372
|
buffer.push(v);
|
|
371
373
|
if (!draining && ready())
|
|
372
|
-
return drain();
|
|
374
|
+
return void drain();
|
|
373
375
|
while (buffer.length > max) {
|
|
374
376
|
dropped(size < 0 ? buffer.pop() : buffer.shift());
|
|
375
377
|
}
|
|
@@ -399,6 +401,7 @@ function slack(size, dropped = noop) {
|
|
|
399
401
|
} finally {
|
|
400
402
|
draining = false;
|
|
401
403
|
}
|
|
404
|
+
return false;
|
|
402
405
|
}
|
|
403
406
|
return IsStream;
|
|
404
407
|
};
|
|
@@ -438,5 +441,4 @@ function takeWhile(condition) {
|
|
|
438
441
|
};
|
|
439
442
|
}
|
|
440
443
|
|
|
441
|
-
export { IsStream, backpressure, concat, concatAll, concatMap, connect, defer,
|
|
442
|
-
//# sourceMappingURL=mod.mjs.map
|
|
444
|
+
export { IsStream, backpressure, concat, concatAll, concatMap, connect, defer, each, emitter, empty, filter, forEach, fromAsyncIterable, fromDomEvent, fromIterable, fromPromise, fromSubscribe, fromValue, fulfillPromise, getJob, interval, isCancel, isError, isObserved, isUnhandled, isValue, lazy, map, markHandled, merge, mergeAll, mergeMap, mockSource, must, never, next, noop, recalcWhen, rejecter, resolve, resolver, restarting, root, share, skip, skipUntil, skipWhile, slack, sleep, start, switchAll, switchMap, take, takeUntil, takeWhile, throttle, to };
|
package/dist/shared.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Y as Yielding } from './types-N2ua11te.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tools for sharing tasks, values, services, etc., especially across job
|
|
5
|
+
* boundaries.
|
|
6
|
+
*
|
|
7
|
+
* @module uneventful/shared
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Wrap a factory function to create a singleton service accessor
|
|
12
|
+
*
|
|
13
|
+
* The returned function, when called, will run the factory in a new job and
|
|
14
|
+
* cache the result. The job the factory ran in will end when the {@link root}
|
|
15
|
+
* job does, after which the cached result will be cleared.
|
|
16
|
+
*
|
|
17
|
+
* @param factory A function returning whatever result you want to share: a
|
|
18
|
+
* value, a function, an object, etc. It will be called at most once per root
|
|
19
|
+
* job lifetime, in a job that is an immediate child of the root job.
|
|
20
|
+
*
|
|
21
|
+
* (Note: if your factory is a native generator function, it is automatically
|
|
22
|
+
* wrapped with {@link fork}() so that its job will not end when the generator
|
|
23
|
+
* ends, and the result can be waited on by multiple callers. If your factory
|
|
24
|
+
* is *not* a native generator function but still returns a generator to produce
|
|
25
|
+
* an async result, you should wrap that generator with {@link fork} before
|
|
26
|
+
* returning it.)
|
|
27
|
+
*
|
|
28
|
+
* @remarks Note that if you want your code to be testable with {@link newRoot},
|
|
29
|
+
* you should avoid storing the *result* of calling the service accessor
|
|
30
|
+
* anywhere it can outlive the root job, since you will otherwise end up with a
|
|
31
|
+
* stale reference to the previous service instance *and* fail to initialize the
|
|
32
|
+
* new instance.
|
|
33
|
+
*
|
|
34
|
+
* Your services can detect this scenario, however, by having the factory wrap
|
|
35
|
+
* its return value with {@link expiring}(), which will make any access to a
|
|
36
|
+
* saved service value throw a TypeError after the root job ends. (Note that
|
|
37
|
+
* such a thing should not be necessary in your production builds, however,
|
|
38
|
+
* since at runtime you will normally only ever have one root job.)
|
|
39
|
+
*/
|
|
40
|
+
declare function service<T>(factory: () => T): () => T;
|
|
41
|
+
/**
|
|
42
|
+
* Proxy an object so it "expires" (becomes inaccessible) with the calling job.
|
|
43
|
+
*
|
|
44
|
+
* Any attempts to use the returned object after the job ends or restarts (other
|
|
45
|
+
* than to check its `typeof`) will result in a TypeError.
|
|
46
|
+
*
|
|
47
|
+
* Note: your runtime environment must support `Proxy.revocable()`.
|
|
48
|
+
*/
|
|
49
|
+
declare function expiring<T extends object>(obj: T): T;
|
|
50
|
+
/**
|
|
51
|
+
* Wrap a generator, generator function, or generator method to run in parallel
|
|
52
|
+
* and have a result that can be waited on in parallel as well.
|
|
53
|
+
*
|
|
54
|
+
* Normally, when you `yield *` to a generator in a job function, you're
|
|
55
|
+
* *pausing* the current function until that generator is finished. And
|
|
56
|
+
* normally, this is what you *want*, because you're not trying to do things in
|
|
57
|
+
* parallel. But if you *do* want to do things in parallel, you need `fork`.
|
|
58
|
+
*
|
|
59
|
+
* Generators also can't normally be *waited on* in parallel either: if multiple
|
|
60
|
+
* jobs try to wait on an unfinished generator, the most likely result is an
|
|
61
|
+
* error or data corruption. (Because the extra `yield *` operations will make
|
|
62
|
+
* the generator think it's received data it was waiting for, causing all kinds
|
|
63
|
+
* of havoc.)
|
|
64
|
+
*
|
|
65
|
+
* So if you want a generator to either *run* in parallel or be *waited on* in
|
|
66
|
+
* parallel (or both), you need to `fork` it: either on the consuming side by
|
|
67
|
+
* wrapping a generator with `fork()`, or on the producing side by wrapping a
|
|
68
|
+
* generator function (or decorating a generator method).
|
|
69
|
+
*
|
|
70
|
+
* When called with a generator, `fork` returns a wrapped generator; when called
|
|
71
|
+
* with a function, it returns a wrapped version of the function that will fork
|
|
72
|
+
* its results. And when used as a decorator (`@fork`, compatible with both
|
|
73
|
+
* TC39 and legacy decorator protocols), it wraps a method to fork its result as
|
|
74
|
+
* well.
|
|
75
|
+
*
|
|
76
|
+
* It is safe to call `fork()` more than once on the same generator, or to
|
|
77
|
+
* `fork()` an already-forked generator: the result will always be the same as
|
|
78
|
+
* the original fork.
|
|
79
|
+
*
|
|
80
|
+
* @remarks Note that while you can *also* make a generator run or be waitable
|
|
81
|
+
* in parallel using e.g. `start()`, the critical difference is in when resource
|
|
82
|
+
* cleanup happens. If you `start()` the generator (or wrap the generator
|
|
83
|
+
* function with `task`), its resources will be cleaned up when the generator
|
|
84
|
+
* function exits.
|
|
85
|
+
*
|
|
86
|
+
* With `yield*`, however (with or without `fork`), the resources are cleaned up
|
|
87
|
+
* when the original *calling* job ends. And this is what you want when the
|
|
88
|
+
* generator's return value is some kind of resource using other active
|
|
89
|
+
* resources (such as event listeners rules, etc.) that need to *remain* active
|
|
90
|
+
* for the caller.
|
|
91
|
+
*
|
|
92
|
+
* (If you're familiar with the Effection framework, you may recognize this as
|
|
93
|
+
* the difference between "actions" and "resources": in Uneventful we use
|
|
94
|
+
* `start()` or `task()` for generators that return the result of an action, and
|
|
95
|
+
* `fork` for generators that return a resource that will be owned by the
|
|
96
|
+
* calling job.)
|
|
97
|
+
*/
|
|
98
|
+
declare function fork<T>(gen: Yielding<T>): Yielding<T>;
|
|
99
|
+
declare function fork<T, F extends (...args: any[]) => Yielding<T>>(genFunc: F): F;
|
|
100
|
+
/** @hidden TC39 decorator */
|
|
101
|
+
declare function fork<T, F extends (...args: any[]) => Yielding<T>>(genFunc: F, ctx: {
|
|
102
|
+
kind: "method";
|
|
103
|
+
}): F;
|
|
104
|
+
/** @hidden legacy decorator */
|
|
105
|
+
declare function fork<T, F extends (...args: any[]) => Yielding<T>, D extends {
|
|
106
|
+
value?: F;
|
|
107
|
+
}>(clsOrProto: any, name: string | symbol, desc: D): D;
|
|
108
|
+
|
|
109
|
+
export { expiring, fork, service };
|