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
package/dist/shared.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { c as root, m as must, s as start, n as noop } from './jobutils-Dvu-e99o.mjs';
|
|
2
|
+
import { a as isGeneratorFunction, b as decorateMethod, i as isFunction, c as apply, s as setMap } from './utils-cyEhnyp7.mjs';
|
|
3
|
+
|
|
4
|
+
function service(factory) {
|
|
5
|
+
let known = false, value = void 0;
|
|
6
|
+
if (isGeneratorFunction(factory))
|
|
7
|
+
factory = fork(factory);
|
|
8
|
+
return () => {
|
|
9
|
+
if (known)
|
|
10
|
+
return value;
|
|
11
|
+
root.start(() => {
|
|
12
|
+
value = factory();
|
|
13
|
+
known = true;
|
|
14
|
+
must(() => {
|
|
15
|
+
value = void 0;
|
|
16
|
+
known = false;
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function expiring(obj) {
|
|
23
|
+
const p = Proxy.revocable(obj, {});
|
|
24
|
+
must(p.revoke);
|
|
25
|
+
return p.proxy;
|
|
26
|
+
}
|
|
27
|
+
function fork(genOrFunc, ...args) {
|
|
28
|
+
if (args.length)
|
|
29
|
+
return decorateMethod(fork, genOrFunc, ...args);
|
|
30
|
+
if (isFunction(genOrFunc))
|
|
31
|
+
return function(...args2) {
|
|
32
|
+
return fork(apply(genOrFunc, this, args2));
|
|
33
|
+
};
|
|
34
|
+
else {
|
|
35
|
+
if (forks.has(genOrFunc))
|
|
36
|
+
return forks.get(genOrFunc);
|
|
37
|
+
const job = start();
|
|
38
|
+
start(function* run() {
|
|
39
|
+
try {
|
|
40
|
+
job.return(yield* genOrFunc);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
job.throw(e);
|
|
43
|
+
}
|
|
44
|
+
yield noop;
|
|
45
|
+
});
|
|
46
|
+
const it = { [Symbol.iterator]: job[Symbol.iterator].bind(job) };
|
|
47
|
+
return setMap(forks, it, setMap(forks, genOrFunc, it));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const forks = /* @__PURE__ */ new WeakMap();
|
|
51
|
+
|
|
52
|
+
export { expiring, fork, service };
|
package/dist/signals.d.ts
CHANGED
|
@@ -131,6 +131,9 @@ interface RuleFactory {
|
|
|
131
131
|
*/
|
|
132
132
|
factory(scheduleFn: SchedulerFn): RuleFactory;
|
|
133
133
|
/**
|
|
134
|
+
* @deprecated Use {@link RuleFactory.root} instead
|
|
135
|
+
*
|
|
136
|
+
* ---
|
|
134
137
|
* Create a "detached" or standalone rule, that is not attached to any job.
|
|
135
138
|
*
|
|
136
139
|
* `r.detached(fn)` is shorthand for calling `detached.run(r, fn)`. (Where
|
|
@@ -141,6 +144,17 @@ interface RuleFactory {
|
|
|
141
144
|
* by the rule function arranging to stop itself via {@link rule.stop}().
|
|
142
145
|
*/
|
|
143
146
|
detached(fn: () => OptionalCleanup): DisposeFn;
|
|
147
|
+
/**
|
|
148
|
+
* Create a standalone rule, not attached to the current job.
|
|
149
|
+
*
|
|
150
|
+
* `r.root(fn)` is shorthand for calling `root.run(r, fn)`, where `r` is a
|
|
151
|
+
* {@link RuleFactory} such as `rule`.
|
|
152
|
+
*
|
|
153
|
+
* The created rule will run until the {@link root} job stops, unless
|
|
154
|
+
* explicitly stopped. (Either by calling the returned disposal function or
|
|
155
|
+
* by the rule function arranging to stop itself via {@link rule.stop}().)
|
|
156
|
+
*/
|
|
157
|
+
root(fn: () => OptionalCleanup): DisposeFn;
|
|
144
158
|
/**
|
|
145
159
|
* Change the scheduler used for the currently-executing rule. Throws an
|
|
146
160
|
* error if no rule is running.
|
|
@@ -171,7 +185,7 @@ interface RuleFactory {
|
|
|
171
185
|
* {@link rule.stop}() from within the rule function.
|
|
172
186
|
*
|
|
173
187
|
* Note: this function will throw an error if called without an active job. If
|
|
174
|
-
* you need a standalone rule, use {@link RuleFactory.
|
|
188
|
+
* you need a standalone rule, use {@link RuleFactory.root rule.root}().
|
|
175
189
|
*
|
|
176
190
|
* @param fn The function that will be run each time its dependencies change.
|
|
177
191
|
* The function will be run in a restarted job each time, with any resources
|
|
@@ -181,6 +195,7 @@ interface RuleFactory {
|
|
|
181
195
|
* @returns A function that can be called to terminate the rule.
|
|
182
196
|
*
|
|
183
197
|
* @category Reactive Behaviors
|
|
198
|
+
* @function
|
|
184
199
|
*/
|
|
185
200
|
declare const rule: ((fn: () => OptionalCleanup) => DisposeFn) & RuleFactory;
|
|
186
201
|
/**
|
|
@@ -327,9 +342,16 @@ interface Writable<T> extends Signal<T> {
|
|
|
327
342
|
* @category Writing
|
|
328
343
|
*/
|
|
329
344
|
readonly set: (val: T) => void;
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
|
|
345
|
+
value: T;
|
|
346
|
+
/**
|
|
347
|
+
* Update the current value with a patch function
|
|
348
|
+
*
|
|
349
|
+
* Note: this reads the signal's current value, which may produce a write
|
|
350
|
+
* conflict or circular dependency if you call it from inside a rule.
|
|
351
|
+
*
|
|
352
|
+
* @category Writing
|
|
353
|
+
*/
|
|
354
|
+
edit(patch: (before: T) => T): void;
|
|
333
355
|
}
|
|
334
356
|
/**
|
|
335
357
|
* A writable signal that can be set to either a value or an expression.
|
package/dist/signals.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { b as
|
|
1
|
+
import { F as pushCtx, G as popCtx, w as makeJob, c as root, f as isError, e as markHandled, g as getJob, x as detached, k as currentCell, o as reject, b as resolve } from './jobutils-Dvu-e99o.mjs';
|
|
2
|
+
import { b as backpressure, I as IsStream, a as callOrWait } from './call-or-wait-EzXJX5Dq.mjs';
|
|
3
|
+
import { e as batch, f as arrayEq, d as defer, c as apply, s as setMap, C as CallableObject } from './utils-cyEhnyp7.mjs';
|
|
3
4
|
|
|
4
5
|
const ruleQueues = /* @__PURE__ */ new WeakMap();
|
|
5
6
|
function ruleQueue(scheduleFn = defer) {
|
|
@@ -31,6 +32,14 @@ var timestamp = 1;
|
|
|
31
32
|
const fntrackers = /* @__PURE__ */ new WeakMap();
|
|
32
33
|
const obtrackers = /* @__PURE__ */ new WeakMap();
|
|
33
34
|
const monitors = /* @__PURE__ */ new WeakMap();
|
|
35
|
+
const staleStreams = batch((q) => {
|
|
36
|
+
for (const cell of q)
|
|
37
|
+
if (!cell.subscribers) {
|
|
38
|
+
++timestamp;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
q.clear();
|
|
42
|
+
});
|
|
34
43
|
const demandChanges = batch((q) => {
|
|
35
44
|
for (const cell of q)
|
|
36
45
|
cell.updateDemand();
|
|
@@ -128,6 +137,7 @@ function toggleDemand(c) {
|
|
|
128
137
|
demandChanges.has(c) ? demandChanges.delete(c) : demandChanges.add(c);
|
|
129
138
|
}
|
|
130
139
|
}
|
|
140
|
+
let dummySource;
|
|
131
141
|
class Cell {
|
|
132
142
|
constructor() {
|
|
133
143
|
this.value = void 0;
|
|
@@ -139,7 +149,7 @@ class Cell {
|
|
|
139
149
|
this.latestSource = timestamp;
|
|
140
150
|
// max lastChanged of this cell or any ancestor source
|
|
141
151
|
this.flags = 0;
|
|
142
|
-
this.
|
|
152
|
+
this.job = void 0;
|
|
143
153
|
/** The subscription being added during the current calculation - used for uniqueness */
|
|
144
154
|
this.adding = void 0;
|
|
145
155
|
/** Linked list of sources */
|
|
@@ -158,11 +168,11 @@ class Cell {
|
|
|
158
168
|
Cell.mkRule(() => {
|
|
159
169
|
const val = this.getValue();
|
|
160
170
|
if (val !== lastValue) {
|
|
161
|
-
|
|
171
|
+
pushCtx();
|
|
162
172
|
try {
|
|
163
173
|
sink(lastValue = val);
|
|
164
174
|
} finally {
|
|
165
|
-
|
|
175
|
+
popCtx();
|
|
166
176
|
}
|
|
167
177
|
}
|
|
168
178
|
}, inlet ? ruleQueue(backpressure(inlet)) : defaultQ);
|
|
@@ -171,8 +181,8 @@ class Cell {
|
|
|
171
181
|
getValue() {
|
|
172
182
|
if (arguments.length)
|
|
173
183
|
return apply(this.stream, this, arguments);
|
|
174
|
-
const dep =
|
|
175
|
-
if (dep && this.flags & 132 /* Variable */) {
|
|
184
|
+
const dep = currentCell;
|
|
185
|
+
if (dep && this.flags & 132 /* Variable */ && (dep.flags & 8 /* Peeking */) === 0) {
|
|
176
186
|
if (this.flags & 32 /* Running */)
|
|
177
187
|
throw new CircularDependency("Cached function dependency cycle");
|
|
178
188
|
let s = this.adding;
|
|
@@ -203,7 +213,7 @@ class Cell {
|
|
|
203
213
|
return this.value;
|
|
204
214
|
}
|
|
205
215
|
shouldWrite(changed) {
|
|
206
|
-
const cell =
|
|
216
|
+
const cell = currentCell || currentRule;
|
|
207
217
|
if (cell) {
|
|
208
218
|
if (!cell.queue)
|
|
209
219
|
throw new WriteConflict("Side-effects not allowed outside rules");
|
|
@@ -236,7 +246,6 @@ class Cell {
|
|
|
236
246
|
if (this.shouldWrite(compute !== this.compute)) {
|
|
237
247
|
this.flags |= 4 /* Compute */;
|
|
238
248
|
this.compute = compute;
|
|
239
|
-
this.ctx ||= makeCtx(null, this);
|
|
240
249
|
}
|
|
241
250
|
}
|
|
242
251
|
hasBeenRead() {
|
|
@@ -252,8 +261,13 @@ class Cell {
|
|
|
252
261
|
if (validThrough === timestamp)
|
|
253
262
|
return;
|
|
254
263
|
this.validThrough = timestamp;
|
|
255
|
-
if (!(this.flags & 4 /* Compute */))
|
|
264
|
+
if (!(this.flags & 4 /* Compute */)) {
|
|
265
|
+
if (this.flags & 256 /* Stream */ && !this.subscribers) {
|
|
266
|
+
this.lastChanged = timestamp;
|
|
267
|
+
staleStreams.add(this);
|
|
268
|
+
}
|
|
256
269
|
return;
|
|
270
|
+
}
|
|
257
271
|
if (this.sources) {
|
|
258
272
|
for (let sub = this.sources; sub; sub = sub.nS) {
|
|
259
273
|
const s = sub.src;
|
|
@@ -274,9 +288,9 @@ class Cell {
|
|
|
274
288
|
return this.doRecalc();
|
|
275
289
|
}
|
|
276
290
|
doRecalc() {
|
|
277
|
-
|
|
291
|
+
pushCtx(this.job, this);
|
|
278
292
|
if (this.flags & 64 /* Stateful */) {
|
|
279
|
-
|
|
293
|
+
this.job?.restart();
|
|
280
294
|
}
|
|
281
295
|
for (let sub = this.sources; sub; sub = sub.nS) {
|
|
282
296
|
sub.ts = -1;
|
|
@@ -306,12 +320,12 @@ class Cell {
|
|
|
306
320
|
demandChanges.delete(this);
|
|
307
321
|
if (this.flags & (16 /* Error */ | 2 /* Stopped */)) {
|
|
308
322
|
this.flags &= ~2 /* Stopped */;
|
|
309
|
-
|
|
323
|
+
this.job?.restart();
|
|
310
324
|
} else if (this.flags & 1 /* Observed */) ; else {
|
|
311
|
-
|
|
325
|
+
this.job?.restart();
|
|
312
326
|
}
|
|
313
327
|
}
|
|
314
|
-
|
|
328
|
+
popCtx();
|
|
315
329
|
let head;
|
|
316
330
|
for (let sub = this.sources; sub; ) {
|
|
317
331
|
const pS = sub.pS;
|
|
@@ -327,8 +341,12 @@ class Cell {
|
|
|
327
341
|
}
|
|
328
342
|
}
|
|
329
343
|
becomeConstant() {
|
|
330
|
-
if (this.flags &
|
|
344
|
+
if (this.flags & 32 /* Running */)
|
|
331
345
|
return;
|
|
346
|
+
if (this.flags & 64 /* Stateful */) {
|
|
347
|
+
mksub(dummySource ||= Cell.mkValue(null), this);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
332
350
|
this.flags &= ~4 /* Compute */;
|
|
333
351
|
if (this.flags & 132 /* Variable */)
|
|
334
352
|
return;
|
|
@@ -395,11 +413,15 @@ class Cell {
|
|
|
395
413
|
return cell;
|
|
396
414
|
}
|
|
397
415
|
isObserved() {
|
|
416
|
+
if (this.flags & 8 /* Peeking */)
|
|
417
|
+
return false;
|
|
398
418
|
return !!((this.flags |= 64 /* Stateful */) & 1 /* Observed */);
|
|
399
419
|
}
|
|
400
420
|
getJob() {
|
|
421
|
+
if (this.job)
|
|
422
|
+
return this.job;
|
|
401
423
|
this.flags |= 64 /* Stateful */;
|
|
402
|
-
return this.
|
|
424
|
+
return this.job = makeJob();
|
|
403
425
|
}
|
|
404
426
|
updateDemand() {
|
|
405
427
|
demandChanges.delete(this);
|
|
@@ -408,13 +430,12 @@ class Cell {
|
|
|
408
430
|
} else if (this.flags & 1 /* Observed */) {
|
|
409
431
|
this.shouldWrite(true);
|
|
410
432
|
} else {
|
|
411
|
-
this.
|
|
433
|
+
this.job?.restart();
|
|
412
434
|
}
|
|
413
435
|
}
|
|
414
436
|
static mkStream(src, val) {
|
|
415
437
|
const cell = this.mkValue(val);
|
|
416
|
-
cell.flags |= 64 /* Stateful */;
|
|
417
|
-
const ctx = makeCtx();
|
|
438
|
+
cell.flags |= 64 /* Stateful */ | 256 /* Stream */;
|
|
418
439
|
const write = (v) => {
|
|
419
440
|
cell.setValue(v, false);
|
|
420
441
|
};
|
|
@@ -427,27 +448,39 @@ class Cell {
|
|
|
427
448
|
}
|
|
428
449
|
if (job)
|
|
429
450
|
return;
|
|
430
|
-
job =
|
|
451
|
+
job = makeJob(root).do((r) => {
|
|
431
452
|
if (isError(r)) {
|
|
432
453
|
cell.setValue(markHandled(r), true);
|
|
433
454
|
} else {
|
|
434
455
|
cell.setValue(val, false);
|
|
435
456
|
}
|
|
436
|
-
|
|
457
|
+
job = void 0;
|
|
437
458
|
});
|
|
438
|
-
|
|
459
|
+
pushCtx(job);
|
|
439
460
|
try {
|
|
440
461
|
src(write, job);
|
|
441
462
|
} catch (e) {
|
|
442
463
|
job.end();
|
|
443
|
-
|
|
464
|
+
root.asyncThrow(e);
|
|
444
465
|
} finally {
|
|
445
|
-
|
|
466
|
+
popCtx();
|
|
446
467
|
}
|
|
447
468
|
});
|
|
448
469
|
return cell;
|
|
449
470
|
}
|
|
471
|
+
peek(fn, thisArg, args) {
|
|
472
|
+
if (this.flags & 8 /* Peeking */)
|
|
473
|
+
return apply(fn, thisArg, args);
|
|
474
|
+
this.flags |= 8 /* Peeking */;
|
|
475
|
+
try {
|
|
476
|
+
return apply(fn, thisArg, args);
|
|
477
|
+
} finally {
|
|
478
|
+
this.flags &= ~8 /* Peeking */;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
450
481
|
recalcWhen(fnOrKey, fn) {
|
|
482
|
+
if (this.flags & 8 /* Peeking */)
|
|
483
|
+
return;
|
|
451
484
|
let trackers = fn ? obtrackers.get(fn) || setMap(obtrackers, fn, /* @__PURE__ */ new WeakMap()) : fntrackers;
|
|
452
485
|
let signal = trackers.get(fnOrKey);
|
|
453
486
|
if (!signal) {
|
|
@@ -461,7 +494,6 @@ class Cell {
|
|
|
461
494
|
static mkCached(compute) {
|
|
462
495
|
const cell = new Cell();
|
|
463
496
|
cell.compute = compute;
|
|
464
|
-
cell.ctx = makeCtx(null, cell);
|
|
465
497
|
cell.flags = 4 /* Compute */;
|
|
466
498
|
return cell;
|
|
467
499
|
}
|
|
@@ -470,20 +502,20 @@ class Cell {
|
|
|
470
502
|
try {
|
|
471
503
|
const cleanup = fn();
|
|
472
504
|
if (cleanup)
|
|
473
|
-
(cell.
|
|
474
|
-
cell.lastChanged = timestamp;
|
|
505
|
+
(cell.job || cell.getJob()).must(cleanup);
|
|
475
506
|
} catch (e) {
|
|
476
507
|
cell.stop();
|
|
477
508
|
throw e;
|
|
478
509
|
}
|
|
479
510
|
}), stop = cell.stop.bind(cell);
|
|
480
511
|
outer === detached || ruleStops.set(cell, outer.release(stop));
|
|
512
|
+
cell.flags |= 64 /* Stateful */;
|
|
481
513
|
cell.setQ(q);
|
|
482
514
|
return stop;
|
|
483
515
|
}
|
|
484
516
|
}
|
|
485
517
|
function unchangedIf(newVal, equals = arrayEq) {
|
|
486
|
-
const
|
|
518
|
+
const cell = currentCell;
|
|
487
519
|
if (cell) {
|
|
488
520
|
return cell.flags & 16 /* Error */ || !equals(cell.value, newVal) ? newVal : cell.value;
|
|
489
521
|
} else {
|
|
@@ -520,6 +552,9 @@ class RF extends CallableObject {
|
|
|
520
552
|
detached(fn) {
|
|
521
553
|
return detached.run(this, fn);
|
|
522
554
|
}
|
|
555
|
+
root(fn) {
|
|
556
|
+
return root.run(this, fn);
|
|
557
|
+
}
|
|
523
558
|
setScheduler(scheduleFn) {
|
|
524
559
|
if (currentRule)
|
|
525
560
|
currentRule.setQ(scheduleFn ? ruleQueue(scheduleFn) : defaultQ);
|
|
@@ -619,6 +654,9 @@ class WritableImpl extends SignalImpl {
|
|
|
619
654
|
asReadonly() {
|
|
620
655
|
return new SignalImpl(this._c);
|
|
621
656
|
}
|
|
657
|
+
edit(patch) {
|
|
658
|
+
this.set(patch(this()));
|
|
659
|
+
}
|
|
622
660
|
}
|
|
623
661
|
class ConfigurableImpl extends WritableImpl {
|
|
624
662
|
setf(expr) {
|
|
@@ -638,27 +676,13 @@ function cached(compute, initVal) {
|
|
|
638
676
|
);
|
|
639
677
|
}
|
|
640
678
|
function peek(fn, ...args) {
|
|
641
|
-
|
|
642
|
-
return fn(...args);
|
|
643
|
-
const old = swapCtx(makeCtx(current.job));
|
|
644
|
-
try {
|
|
645
|
-
return fn(...args);
|
|
646
|
-
} finally {
|
|
647
|
-
freeCtx(swapCtx(old));
|
|
648
|
-
}
|
|
679
|
+
return currentCell ? currentCell.peek(fn, null, args) : fn(...args);
|
|
649
680
|
}
|
|
650
681
|
function action(fn, _ctx, desc) {
|
|
651
682
|
if (desc)
|
|
652
683
|
return { ...desc, value: action(desc.value) };
|
|
653
|
-
return function() {
|
|
654
|
-
|
|
655
|
-
return apply(fn, this, arguments);
|
|
656
|
-
const old = swapCtx(makeCtx(current.job));
|
|
657
|
-
try {
|
|
658
|
-
return apply(fn, this, arguments);
|
|
659
|
-
} finally {
|
|
660
|
-
freeCtx(swapCtx(old));
|
|
661
|
-
}
|
|
684
|
+
return function(...args) {
|
|
685
|
+
return currentCell ? currentCell.peek(fn, this, args) : apply(fn, this, args);
|
|
662
686
|
};
|
|
663
687
|
}
|
|
664
688
|
function until(source) {
|
|
@@ -672,4 +696,3 @@ function waitTruthy(job, v) {
|
|
|
672
696
|
}
|
|
673
697
|
|
|
674
698
|
export { CircularDependency, ConfigurableImpl, SignalImpl, WritableImpl, WriteConflict, action, cached, peek, rule, runRules, unchangedIf, until, value };
|
|
675
|
-
//# sourceMappingURL=signals.mjs.map
|
|
@@ -53,6 +53,10 @@ class _Batch {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
function decorateMethod(decorate, fn, _ctxOrName, desc) {
|
|
57
|
+
const method = decorate(desc ? desc.value : fn);
|
|
58
|
+
return desc ? { ...desc, value: method } : method;
|
|
59
|
+
}
|
|
56
60
|
const isArray = Array.isArray;
|
|
57
61
|
function arrayEq(a, b) {
|
|
58
62
|
return a === b || isArray(a) && isArray(b) && a.length === b.length && a.every(same, b);
|
|
@@ -67,14 +71,17 @@ function setMap(map, key, val) {
|
|
|
67
71
|
function isFunction(f) {
|
|
68
72
|
return typeof f === "function";
|
|
69
73
|
}
|
|
70
|
-
const CallableObject = /* @__PURE__ */ (() =>
|
|
74
|
+
const CallableObject = /* @__PURE__ */ (() => {
|
|
71
75
|
function CallableObject2(fn) {
|
|
72
76
|
return Object.setPrototypeOf(fn, new.target.prototype);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
77
|
+
}
|
|
78
|
+
CallableObject2.prototype = Function.prototype;
|
|
79
|
+
return CallableObject2;
|
|
80
|
+
})();
|
|
77
81
|
const apply = Reflect.apply;
|
|
82
|
+
function call(fn, thisArg, ...args) {
|
|
83
|
+
return thisArg ? apply(fn, thisArg, args) : args.length ? fn(...args) : fn();
|
|
84
|
+
}
|
|
78
85
|
const GeneratorBase = /* @__PURE__ */ (() => {
|
|
79
86
|
function G() {
|
|
80
87
|
}
|
|
@@ -82,6 +89,8 @@ const GeneratorBase = /* @__PURE__ */ (() => {
|
|
|
82
89
|
}.constructor.prototype.prototype;
|
|
83
90
|
return G;
|
|
84
91
|
})();
|
|
92
|
+
function isGeneratorFunction(fn) {
|
|
93
|
+
return isFunction(fn) && fn.prototype instanceof GeneratorBase;
|
|
94
|
+
}
|
|
85
95
|
|
|
86
|
-
export { CallableObject as C, GeneratorBase as G,
|
|
87
|
-
//# sourceMappingURL=utils-P0JEpWXG.mjs.map
|
|
96
|
+
export { CallableObject as C, GeneratorBase as G, isGeneratorFunction as a, decorateMethod as b, apply as c, defer as d, batch as e, arrayEq as f, isArray as g, call as h, isFunction as i, setMap as s };
|
package/dist/utils.d.ts
CHANGED
|
@@ -66,14 +66,51 @@ declare function batch<T>(process: (items: Set<T>) => void, sched?: (cb: () => u
|
|
|
66
66
|
* @module uneventful/utils
|
|
67
67
|
*/
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Helper for creating hybrid legacy/TC39 decorator/wrapper functions, e.g.:
|
|
71
|
+
*
|
|
72
|
+
* ```ts
|
|
73
|
+
* // As wrapper function
|
|
74
|
+
* export function myDecorator<T>(fn: SomeFnType<T>): SomeFnType<T>;
|
|
75
|
+
*
|
|
76
|
+
* // TC39 decorator
|
|
77
|
+
* export function myDecorator<T>(fn: SomeFnType<T>, ctx: {kind: "method"}): SomeFnType<T>
|
|
78
|
+
*
|
|
79
|
+
* // "Legacy"/"TypeScript Experimental" Decorator
|
|
80
|
+
* export function myDecorator<T,D extends {value?: SomeFnType<T>}>(clsOrProto:any, name: string|symbol, desc: D): D
|
|
81
|
+
*
|
|
82
|
+
* // Implementation
|
|
83
|
+
* export function myDecorator<T>(factory: SomeFnType<T>, ...args: any[]): SomeFnType<T> {
|
|
84
|
+
* // extra args means we're being used as a decorator, so run as decorator:
|
|
85
|
+
* if (args.length) return decorateMethod(myDecorator, factory, ...args as [any, any]);
|
|
86
|
+
* // No extra args, we're b
|
|
87
|
+
* return () => {
|
|
88
|
+
* }
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* Yes, this is fairly ugly, but it's also the **only** way to make this work
|
|
93
|
+
* when the wrapper is a generic function. (TypeScript's type system doesn't
|
|
94
|
+
* allow generic values, declaring functions as implementing interfaces,
|
|
95
|
+
* higher-order kinds, or any other tricks that would let you avoid this giant
|
|
96
|
+
* ball of boilerplate for generic decorators.)
|
|
97
|
+
*
|
|
98
|
+
* @category Functions and Decorators
|
|
99
|
+
*/
|
|
100
|
+
declare function decorateMethod<F extends AnyFunction, D extends {
|
|
101
|
+
value?: F;
|
|
102
|
+
}>(decorate: (fn: F) => F, fn: F, _ctxOrName: string | symbol | {
|
|
103
|
+
kind: "method";
|
|
104
|
+
}, desc?: D): F | D;
|
|
69
105
|
/**
|
|
70
106
|
* Shorthand for Array.isArray()
|
|
71
107
|
*
|
|
72
108
|
* @category Data Structures
|
|
109
|
+
* @function
|
|
73
110
|
*/
|
|
74
111
|
declare const isArray: (arg: any) => arg is any[];
|
|
75
112
|
/**
|
|
76
|
-
* Return true if the supplied parameters are the same object/
|
|
113
|
+
* Return true if the supplied parameters are the same object/value, or are
|
|
77
114
|
* arrays with identical contents.
|
|
78
115
|
*
|
|
79
116
|
* @category Data Structures
|
|
@@ -97,54 +134,68 @@ declare function setMap<K, V>(map: {
|
|
|
97
134
|
/**
|
|
98
135
|
* Is the given value a function? (Shorthand for `typeof f === "function"`)
|
|
99
136
|
*
|
|
100
|
-
* @category
|
|
137
|
+
* @category Functions and Decorators
|
|
101
138
|
*/
|
|
102
139
|
declare function isFunction(f: any): f is Function;
|
|
103
140
|
/**
|
|
104
|
-
*
|
|
105
|
-
* the documentation. (By default, typedoc exposes all the inherited properties
|
|
106
|
-
* and members, which we don't want. By inheriting from it instead of from
|
|
107
|
-
* Function, we keep the documentation free of unimportant details.)
|
|
141
|
+
* A base class for creating callable objects.
|
|
108
142
|
*
|
|
109
143
|
* The way this works is that you subclass CallableObject and define a
|
|
110
|
-
* constructor that calls `super(someClosure)` where `someClosure` is a unique
|
|
144
|
+
* constructor that calls `super(someClosure)` where `someClosure` is a *unique*
|
|
111
145
|
* function object, which will then pick up any properties or methods defined by
|
|
112
146
|
* the subclass.
|
|
113
147
|
*
|
|
148
|
+
* (Note: It needs to be unique because the `super()` call only sets its
|
|
149
|
+
* prototype, and returns the function you passed as `this`. So if you call it
|
|
150
|
+
* with the same function more than once, you're just reinitializing the same
|
|
151
|
+
* object instead of creating a new one.)
|
|
152
|
+
*
|
|
114
153
|
* @template T The call/return signature that instances of the class will
|
|
115
154
|
* implement.
|
|
116
155
|
*
|
|
117
|
-
* @
|
|
156
|
+
* @param fn A unique function or closure, to be passed to super() in a
|
|
157
|
+
* subclass. The function object will gain a prototype from `new.target`,
|
|
158
|
+
* thereby picking up any properties or methods defined by the class, and
|
|
159
|
+
* becoming `this` for the calling constructor.
|
|
160
|
+
*
|
|
161
|
+
* (Note that calling the constructor by any means other than super() from a
|
|
162
|
+
* constructor will result in an error or some other unhelpful result.)
|
|
163
|
+
*
|
|
164
|
+
* @category Functions and Decorators
|
|
118
165
|
*/
|
|
119
|
-
declare
|
|
120
|
-
/**
|
|
121
|
-
* @param fn A unique function or closure, to be passed to super() in a
|
|
122
|
-
* subclass. The function object will gain a prototype from `new.target`,
|
|
123
|
-
* thereby picking up any properties or methods defined by the class,
|
|
124
|
-
* and becoming `this` for the calling constructor.
|
|
125
|
-
*
|
|
126
|
-
* (Note that calling the constructor by any means other than super() from
|
|
127
|
-
* a constructor will result in an error or some other unhelpful result.)
|
|
128
|
-
*/
|
|
129
|
-
constructor(fn: T);
|
|
130
|
-
}
|
|
131
|
-
interface CallableObject<T extends AnyFunction> extends T {
|
|
132
|
-
}
|
|
133
|
-
declare const CallableObject: any;
|
|
166
|
+
declare const CallableObject: new <T extends AnyFunction>(fn: T) => T;
|
|
134
167
|
|
|
135
168
|
/**
|
|
136
169
|
* Calls the `target` function with the given object as the `this` value and the
|
|
137
|
-
* elements of given array as the arguments.
|
|
170
|
+
* elements of given array as the arguments. (Shorthand for Reflect.apply)
|
|
138
171
|
*
|
|
139
|
-
* @category
|
|
172
|
+
* @category Functions and Decorators
|
|
173
|
+
* @function
|
|
140
174
|
*/
|
|
141
175
|
declare const apply: typeof Reflect.apply;
|
|
176
|
+
/**
|
|
177
|
+
* Like `fn.call(thisArg, ...args)`, but monomorphic, and the `thisArg`
|
|
178
|
+
* parameter can be omitted or null.
|
|
179
|
+
*
|
|
180
|
+
* This is mostly useful as syntax sugar for an immediately-evaluated function
|
|
181
|
+
* expression, replacing `(() => {...})()` with `call(() => {...})`.
|
|
182
|
+
*
|
|
183
|
+
* @category Functions and Decorators
|
|
184
|
+
*/
|
|
185
|
+
declare function call<F extends AnyFunction>(fn: F, thisArg?: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F>;
|
|
142
186
|
/**
|
|
143
187
|
* A pseudo-constructor for the abstract ancestor type of all generators,
|
|
144
188
|
* useful for testing whether something is `instanceof Generator`.
|
|
145
189
|
*
|
|
146
190
|
* @category Data Structures
|
|
191
|
+
* @class
|
|
147
192
|
*/
|
|
148
193
|
declare const GeneratorBase: abstract new () => Generator;
|
|
194
|
+
/**
|
|
195
|
+
* Is the given function a native generator function?
|
|
196
|
+
*
|
|
197
|
+
* @category Functions and Decorators
|
|
198
|
+
*/
|
|
199
|
+
declare function isGeneratorFunction<G extends Generator<any, any, any> = Generator>(fn: any): fn is (this: any, ...args: any[]) => G;
|
|
149
200
|
|
|
150
|
-
export { type Batch, CallableObject, GeneratorBase, apply, arrayEq, batch, isArray, isFunction, setMap };
|
|
201
|
+
export { type Batch, CallableObject, GeneratorBase, apply, arrayEq, batch, call, decorateMethod, isArray, isFunction, isGeneratorFunction, setMap };
|
package/dist/utils.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { C as CallableObject, G as GeneratorBase, c as apply,
|
|
2
|
-
//# sourceMappingURL=utils.mjs.map
|
|
1
|
+
export { C as CallableObject, G as GeneratorBase, c as apply, f as arrayEq, e as batch, h as call, b as decorateMethod, g as isArray, i as isFunction, a as isGeneratorFunction, s as setMap } from './utils-cyEhnyp7.mjs';
|