@thi.ng/rstream 6.0.21 → 7.0.4

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +49 -620
  2. package/README.md +70 -52
  3. package/api.d.ts +2 -4
  4. package/api.js +0 -3
  5. package/{subs/asidechain.d.ts → asidechain.d.ts} +2 -2
  6. package/{subs/asidechain.js → asidechain.js} +1 -1
  7. package/{from/atom.d.ts → atom.d.ts} +2 -3
  8. package/{from/atom.js → atom.js} +8 -4
  9. package/{subs/bisect.d.ts → bisect.d.ts} +2 -2
  10. package/{subs/bisect.js → bisect.js} +3 -3
  11. package/{utils/checks.d.ts → checks.d.ts} +2 -1
  12. package/{utils/checks.js → checks.js} +3 -1
  13. package/{subs/debounce.d.ts → debounce.d.ts} +2 -2
  14. package/{subs/debounce.js → debounce.js} +7 -4
  15. package/defworker.d.ts +3 -0
  16. package/defworker.js +4 -0
  17. package/{from/event.d.ts → event.d.ts} +2 -2
  18. package/{from/event.js → event.js} +4 -4
  19. package/forkjoin.d.ts +2 -2
  20. package/forkjoin.js +8 -3
  21. package/idgen.d.ts +10 -0
  22. package/idgen.js +9 -0
  23. package/index.d.ts +35 -33
  24. package/index.js +35 -33
  25. package/internal/remove.d.ts +4 -0
  26. package/internal/remove.js +7 -0
  27. package/{from/interval.d.ts → interval.d.ts} +2 -3
  28. package/{from/interval.js → interval.js} +8 -5
  29. package/{from/iterable.d.ts → iterable.d.ts} +3 -4
  30. package/{from/iterable.js → iterable.js} +7 -7
  31. package/logger.d.ts +4 -0
  32. package/logger.js +3 -0
  33. package/{stream-merge.d.ts → merge.d.ts} +3 -3
  34. package/{stream-merge.js → merge.js} +7 -10
  35. package/metastream.d.ts +3 -3
  36. package/metastream.js +5 -5
  37. package/{from/object.d.ts → object.d.ts} +2 -2
  38. package/{from/object.js → object.js} +13 -6
  39. package/package.json +140 -31
  40. package/{subs/post-worker.d.ts → post-worker.d.ts} +1 -1
  41. package/{subs/post-worker.js → post-worker.js} +5 -4
  42. package/{from/promise.d.ts → promise.d.ts} +2 -3
  43. package/{from/promise.js → promise.js} +5 -5
  44. package/{from/promises.d.ts → promises.d.ts} +1 -1
  45. package/{from/promises.js → promises.js} +4 -4
  46. package/pubsub.d.ts +3 -3
  47. package/pubsub.js +12 -8
  48. package/{from/raf.d.ts → raf.d.ts} +2 -3
  49. package/{from/raf.js → raf.js} +6 -6
  50. package/{subs/resolve.d.ts → resolve.d.ts} +1 -1
  51. package/{subs/resolve.js → resolve.js} +5 -4
  52. package/{subs/sidechain-partition.d.ts → sidechain-partition.d.ts} +4 -4
  53. package/{subs/sidechain-partition.js → sidechain-partition.js} +7 -7
  54. package/{subs/sidechain-toggle.d.ts → sidechain-toggle.d.ts} +3 -3
  55. package/{subs/sidechain-toggle.js → sidechain-toggle.js} +4 -4
  56. package/stream.d.ts +2 -2
  57. package/stream.js +6 -5
  58. package/subscription.d.ts +4 -3
  59. package/subscription.js +26 -12
  60. package/{stream-sync.d.ts → sync.d.ts} +4 -4
  61. package/{stream-sync.js → sync.js} +15 -12
  62. package/{subs/timeout.d.ts → timeout.d.ts} +2 -2
  63. package/{subs/timeout.js → timeout.js} +4 -4
  64. package/{subs/trace.d.ts → trace.d.ts} +1 -1
  65. package/{subs/trace.js → trace.js} +0 -0
  66. package/{subs/transduce.d.ts → transduce.d.ts} +1 -1
  67. package/{subs/transduce.js → transduce.js} +1 -1
  68. package/trigger.d.ts +2 -2
  69. package/trigger.js +3 -3
  70. package/{subs/tunnel.d.ts → tunnel.d.ts} +1 -1
  71. package/{subs/tunnel.js → tunnel.js} +7 -6
  72. package/tween.d.ts +5 -5
  73. package/tween.js +8 -6
  74. package/{from/view.d.ts → view.d.ts} +3 -3
  75. package/{from/view.js → view.js} +4 -4
  76. package/{from/worker.d.ts → worker.d.ts} +2 -3
  77. package/{from/worker.js → worker.js} +7 -7
  78. package/lib/index.js +0 -1148
  79. package/lib/index.js.map +0 -1
  80. package/lib/index.umd.js +0 -1
  81. package/lib/index.umd.js.map +0 -1
  82. package/utils/idgen.d.ts +0 -4
  83. package/utils/idgen.js +0 -3
  84. package/utils/worker.d.ts +0 -3
  85. package/utils/worker.js +0 -4
package/lib/index.js DELETED
@@ -1,1148 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var api = require('@thi.ng/api');
6
- var transducers = require('@thi.ng/transducers');
7
- var arrays = require('@thi.ng/arrays');
8
- var checks = require('@thi.ng/checks');
9
- var errors = require('@thi.ng/errors');
10
- var associative = require('@thi.ng/associative');
11
- var atom = require('@thi.ng/atom');
12
-
13
- exports.State = void 0;
14
- (function (State) {
15
- State[State["IDLE"] = 0] = "IDLE";
16
- State[State["ACTIVE"] = 1] = "ACTIVE";
17
- State[State["DONE"] = 2] = "DONE";
18
- State[State["UNSUBSCRIBED"] = 3] = "UNSUBSCRIBED";
19
- State[State["ERROR"] = 4] = "ERROR";
20
- })(exports.State || (exports.State = {}));
21
- exports.CloseMode = void 0;
22
- (function (CloseMode) {
23
- CloseMode[CloseMode["NEVER"] = 0] = "NEVER";
24
- CloseMode[CloseMode["FIRST"] = 1] = "FIRST";
25
- CloseMode[CloseMode["LAST"] = 2] = "LAST";
26
- })(exports.CloseMode || (exports.CloseMode = {}));
27
- exports.LOGGER = api.NULL_LOGGER;
28
- const setLogger = (logger) => (exports.LOGGER = logger);
29
-
30
- let NEXT_ID = 0;
31
- const nextID = () => NEXT_ID++;
32
- const optsWithID = (prefix, opts) => ((!opts || !opts.id ? Object.assign(Object.assign({}, opts), { id: prefix + "-" + nextID() }) : opts));
33
-
34
- const subscription = (sub, opts) => new Subscription(sub, opts);
35
- class Subscription {
36
- constructor(wrapped, opts) {
37
- this.wrapped = wrapped;
38
- this.last = api.SEMAPHORE;
39
- this.state = exports.State.IDLE;
40
- this.subs = [];
41
- opts = optsWithID(`sub`, Object.assign({ closeIn: exports.CloseMode.LAST, closeOut: exports.CloseMode.LAST, cache: true }, opts));
42
- this.parent = opts.parent;
43
- this.id = opts.id;
44
- this.closeIn = opts.closeIn;
45
- this.closeOut = opts.closeOut;
46
- this.cacheLast = opts.cache;
47
- opts.xform && (this.xform = opts.xform(transducers.push()));
48
- }
49
- deref() {
50
- return this.last !== api.SEMAPHORE ? this.last : undefined;
51
- }
52
- getState() {
53
- return this.state;
54
- }
55
- setState(state) {
56
- this.state = state;
57
- }
58
- subscribe(sub, opts = {}) {
59
- this.ensureState();
60
- let $sub;
61
- if (sub instanceof Subscription && !opts.xform) {
62
- sub.ensureState();
63
- api.assert(!sub.parent, `sub '${sub.id}' already has a parent`);
64
- sub.parent = this;
65
- $sub = sub;
66
- }
67
- else {
68
- $sub = new Subscription(sub, Object.assign(Object.assign({}, opts), { parent: this }));
69
- }
70
- this.subs.push($sub);
71
- this.setState(exports.State.ACTIVE);
72
- $sub.setState(exports.State.ACTIVE);
73
- this.last != api.SEMAPHORE && $sub.next(this.last);
74
- return $sub;
75
- }
76
- transform(...args) {
77
- let sub;
78
- let opts;
79
- if (checks.isPlainObject(arrays.peek(args))) {
80
- opts = args.pop();
81
- sub = { error: opts.error };
82
- }
83
- return this.subscribe(sub, optsWithID("xform", args.length > 0
84
- ? Object.assign(Object.assign({}, opts), {
85
- xform: transducers.comp(...args) }) : opts));
86
- }
87
- map(fn, opts) {
88
- return this.transform(transducers.map(fn), opts || {});
89
- }
90
- unsubscribe(sub) {
91
- return sub ? this.unsubscribeChild(sub) : this.unsubscribeSelf();
92
- }
93
- unsubscribeSelf() {
94
- exports.LOGGER.debug(this.id, "unsub self");
95
- this.parent && this.parent.unsubscribe(this);
96
- this.state < exports.State.UNSUBSCRIBED && (this.state = exports.State.UNSUBSCRIBED);
97
- this.release();
98
- return true;
99
- }
100
- unsubscribeChild(sub) {
101
- exports.LOGGER.debug(this.id, "unsub child", sub.id);
102
- const idx = this.subs.indexOf(sub);
103
- if (idx >= 0) {
104
- this.subs.splice(idx, 1);
105
- if (this.closeOut === exports.CloseMode.FIRST ||
106
- (!this.subs.length && this.closeOut !== exports.CloseMode.NEVER)) {
107
- this.unsubscribe();
108
- }
109
- return true;
110
- }
111
- return false;
112
- }
113
- next(x) {
114
- if (this.state >= exports.State.DONE)
115
- return;
116
- this.xform ? this.dispatchXform(x) : this.dispatch(x);
117
- }
118
- done() {
119
- exports.LOGGER.debug(this.id, "entering done()");
120
- if (this.state >= exports.State.DONE)
121
- return;
122
- if (this.xform) {
123
- if (!this.dispatchXformDone())
124
- return;
125
- }
126
- this.state = exports.State.DONE;
127
- if (this.dispatchTo("done")) {
128
- this.state < exports.State.UNSUBSCRIBED && this.unsubscribe();
129
- }
130
- exports.LOGGER.debug(this.id, "exiting done()");
131
- }
132
- error(e) {
133
- const sub = this.wrapped;
134
- const hasErrorHandler = sub && sub.error;
135
- hasErrorHandler &&
136
- exports.LOGGER.debug(this.id, "attempting wrapped error handler");
137
- return (hasErrorHandler && sub.error(e)) || this.unhandledError(e);
138
- }
139
- unhandledError(e) {
140
- (exports.LOGGER !== api.NULL_LOGGER ? exports.LOGGER : console).warn(this.id, "unhandled error:", e);
141
- this.unsubscribe();
142
- this.state = exports.State.ERROR;
143
- return false;
144
- }
145
- dispatchTo(type, x) {
146
- let s = this.wrapped;
147
- if (s) {
148
- try {
149
- s[type] && s[type](x);
150
- }
151
- catch (e) {
152
- if (!this.error(e))
153
- return false;
154
- }
155
- }
156
- const subs = type === "next" ? this.subs : [...this.subs];
157
- for (let i = subs.length; --i >= 0;) {
158
- s = subs[i];
159
- try {
160
- s[type] && s[type](x);
161
- }
162
- catch (e) {
163
- if (type === "error" || !s.error || !s.error(e)) {
164
- return this.unhandledError(e);
165
- }
166
- }
167
- }
168
- return true;
169
- }
170
- dispatch(x) {
171
- exports.LOGGER.debug(this.id, "dispatch", x);
172
- this.cacheLast && (this.last = x);
173
- this.dispatchTo("next", x);
174
- }
175
- dispatchXform(x) {
176
- let acc;
177
- try {
178
- acc = this.xform[2]([], x);
179
- }
180
- catch (e) {
181
- this.error(e);
182
- return;
183
- }
184
- if (this.dispatchXformVals(acc)) {
185
- transducers.isReduced(acc) && this.done();
186
- }
187
- }
188
- dispatchXformDone() {
189
- let acc;
190
- try {
191
- acc = this.xform[1]([]);
192
- }
193
- catch (e) {
194
- return this.error(e);
195
- }
196
- return this.dispatchXformVals(acc);
197
- }
198
- dispatchXformVals(acc) {
199
- const uacc = transducers.unreduced(acc);
200
- for (let i = 0, n = uacc.length; i < n && this.state < exports.State.DONE; i++) {
201
- this.dispatch(uacc[i]);
202
- }
203
- return this.state < exports.State.ERROR;
204
- }
205
- ensureState() {
206
- if (this.state >= exports.State.DONE) {
207
- errors.illegalState(`operation not allowed in state ${this.state}`);
208
- }
209
- }
210
- release() {
211
- this.subs.length = 0;
212
- delete this.parent;
213
- delete this.xform;
214
- delete this.last;
215
- }
216
- }
217
-
218
- const isFirstOrLastInput = (mode, num) => mode === exports.CloseMode.FIRST || (mode === exports.CloseMode.LAST && !num);
219
-
220
- const sync = (opts) => new StreamSync(opts);
221
- class StreamSync extends Subscription {
222
- constructor(opts) {
223
- const psync = transducers.partitionSync(new Set(), {
224
- key: (x) => x[0],
225
- mergeOnly: opts.mergeOnly === true,
226
- reset: opts.reset === true,
227
- all: opts.all !== false,
228
- backPressure: opts.backPressure || 0,
229
- });
230
- const mapv = transducers.mapVals((x) => x[1]);
231
- super(undefined, optsWithID("streamsync", Object.assign(Object.assign({}, opts), { xform: opts.xform
232
- ? transducers.comp(psync, mapv, opts.xform)
233
- : transducers.comp(psync, mapv) })));
234
- this.sources = new Map();
235
- this.realSourceIDs = new Map();
236
- this.invRealSourceIDs = new Map();
237
- this.idSources = new Map();
238
- this.psync = psync;
239
- this.clean = !!opts.clean;
240
- opts.src && this.addAll(opts.src);
241
- }
242
- add(src, id) {
243
- id || (id = src.id);
244
- this.ensureState();
245
- this.psync.add(id);
246
- this.realSourceIDs.set(id, src.id);
247
- this.invRealSourceIDs.set(src.id, id);
248
- this.idSources.set(src.id, src);
249
- this.sources.set(src, src.subscribe({
250
- next: (x) =>
251
- x[1] instanceof Subscription
252
- ? this.add(x[1])
253
- : this.next(x),
254
- done: () => this.markDone(src),
255
- __owner: this,
256
- }, { xform: transducers.labeled(id), id: `in-${id}` }));
257
- }
258
- addAll(src) {
259
- for (let id in src) {
260
- this.psync.add(id);
261
- }
262
- for (let id in src) {
263
- this.add(src[id], id);
264
- }
265
- }
266
- remove(src) {
267
- const sub = this.sources.get(src);
268
- if (sub) {
269
- const id = this.invRealSourceIDs.get(src.id);
270
- exports.LOGGER.info(`removing src: ${src.id} (${id})`);
271
- this.psync.delete(id, this.clean);
272
- this.realSourceIDs.delete(id);
273
- this.invRealSourceIDs.delete(src.id);
274
- this.idSources.delete(src.id);
275
- this.sources.delete(src);
276
- sub.unsubscribe();
277
- return true;
278
- }
279
- return false;
280
- }
281
- removeID(id) {
282
- const src = this.getSourceForID(id);
283
- return src ? this.remove(src) : false;
284
- }
285
- removeAll(src) {
286
- for (let s of src) {
287
- this.psync.delete(this.invRealSourceIDs.get(s.id));
288
- }
289
- let ok = true;
290
- for (let s of src) {
291
- ok = this.remove(s) && ok;
292
- }
293
- return ok;
294
- }
295
- removeAllIDs(ids) {
296
- let ok = true;
297
- for (let id of ids) {
298
- ok = this.removeID(id) && ok;
299
- }
300
- return ok;
301
- }
302
- getSourceForID(id) {
303
- return this.idSources.get(this.realSourceIDs.get(id));
304
- }
305
- getSources() {
306
- const res = {};
307
- for (let [id, src] of this.idSources) {
308
- res[this.invRealSourceIDs.get(id)] = src;
309
- }
310
- return res;
311
- }
312
- unsubscribe(sub) {
313
- if (!sub) {
314
- exports.LOGGER.debug(this.id, "unsub sources");
315
- for (let s of this.sources.values()) {
316
- s.unsubscribe();
317
- }
318
- this.sources.clear();
319
- this.psync.clear();
320
- this.realSourceIDs.clear();
321
- this.invRealSourceIDs.clear();
322
- this.idSources.clear();
323
- }
324
- return super.unsubscribe(sub);
325
- }
326
- markDone(src) {
327
- this.remove(src);
328
- isFirstOrLastInput(this.closeIn, this.sources.size) && this.done();
329
- }
330
- }
331
-
332
- const inlineWorker = (src) => makeWorker(new Blob([src], { type: "text/javascript" }));
333
- const makeWorker = (worker) => worker instanceof Worker
334
- ? worker
335
- : new Worker(worker instanceof Blob ? URL.createObjectURL(worker) : worker);
336
-
337
- const tunnel = (opts) => new Tunnel(opts);
338
- class Tunnel extends Subscription {
339
- constructor(opts) {
340
- super(undefined, { id: opts.id || `tunnel-${nextID()}` });
341
- this.src = opts.src;
342
- this.workers = new Array(opts.maxWorkers || 1);
343
- this.transferables = opts.transferables;
344
- this.terminate = opts.terminate || 1000;
345
- this.interrupt = opts.interrupt || false;
346
- this.index = 0;
347
- }
348
- next(x) {
349
- if (this.state < exports.State.DONE) {
350
- let tx;
351
- if (this.transferables) {
352
- tx = this.transferables(x);
353
- }
354
- let worker = this.workers[this.index];
355
- if (this.interrupt && worker) {
356
- worker.terminate();
357
- worker = null;
358
- }
359
- if (!worker) {
360
- this.workers[this.index++] = worker = makeWorker(this.src);
361
- this.index %= this.workers.length;
362
- worker.addEventListener("message", (e) => this.dispatch(e.data));
363
- worker.addEventListener("error", (e) => this.error(e));
364
- }
365
- worker.postMessage(x, tx || []);
366
- }
367
- }
368
- done() {
369
- super.done();
370
- if (this.terminate > 0) {
371
- setTimeout(() => {
372
- exports.LOGGER.info("terminating workers...");
373
- this.workers.forEach((worker) => worker && worker.terminate());
374
- delete this.workers;
375
- }, this.terminate);
376
- }
377
- }
378
- }
379
-
380
- const forkJoin = (opts) => {
381
- const numWorkers = opts.numWorkers || navigator.hardwareConcurrency || 4;
382
- const workerIDs = transducers.range(numWorkers);
383
- return sync({
384
- src: transducers.transduce(transducers.map((id) => [
385
- String(id),
386
- opts.src
387
- .transform(transducers.map((x) => opts.fork(id, numWorkers, x)))
388
- .subscribe(tunnel({
389
- src: opts.worker,
390
- transferables: opts.transferables,
391
- interrupt: opts.interrupt === true,
392
- terminate: opts.terminate,
393
- id: String(id),
394
- })),
395
- ]), transducers.assocObj(), workerIDs),
396
- xform: transducers.comp(
397
- transducers.map((results) => [...transducers.map((id) => results[id], workerIDs)]),
398
- transducers.map(opts.join)),
399
- reset: true,
400
- backPressure: opts.backPressure,
401
- });
402
- };
403
- const forkBuffer = (minChunkSize = 1) => (id, numWorkers, buf) => {
404
- const chunkSize = Math.max(minChunkSize, (buf.length / numWorkers) | 0);
405
- return id < numWorkers - 1
406
- ? buf.slice(id * chunkSize, (id + 1) * chunkSize)
407
- : buf.slice(id * chunkSize);
408
- };
409
- const joinBuffer = (fn) => fn
410
- ? (parts) => [...transducers.mapcat(fn, parts)]
411
- : (parts) => Array.prototype.concat.apply([], parts);
412
-
413
- const metaStream = (factory, opts) => new MetaStream(factory, opts);
414
- class MetaStream extends Subscription {
415
- constructor(factory, opts = {}) {
416
- super(undefined, optsWithID("metastram", opts));
417
- this.factory = factory;
418
- this.emitLast = opts.emitLast === true;
419
- this.doneRequested = false;
420
- }
421
- next(x) {
422
- if (this.state < exports.State.DONE) {
423
- if (this.stream) {
424
- this.stream.unsubscribe(this.sub);
425
- }
426
- let stream = this.factory(x);
427
- if (stream) {
428
- this.stream = stream;
429
- this.sub = this.stream.subscribe({
430
- next: (x) => {
431
- stream === this.stream && super.dispatch(x);
432
- this.doneRequested && this.done();
433
- },
434
- done: () => {
435
- this.stream.unsubscribe(this.sub);
436
- if (stream === this.stream) {
437
- this.stream = undefined;
438
- this.sub = undefined;
439
- }
440
- },
441
- error: (e) => super.error(e),
442
- __owner: this,
443
- });
444
- }
445
- }
446
- }
447
- done() {
448
- if (this.emitLast && !this.doneRequested) {
449
- this.doneRequested = true;
450
- }
451
- else {
452
- if (this.stream) {
453
- this.detach(true);
454
- }
455
- this.closeIn !== exports.CloseMode.NEVER && super.done();
456
- }
457
- }
458
- unsubscribe(sub) {
459
- if (this.stream && (!sub || this.subs.length === 1)) {
460
- this.detach(!sub);
461
- }
462
- return super.unsubscribe(sub);
463
- }
464
- detach(force) {
465
- if (force || this.closeOut !== exports.CloseMode.NEVER) {
466
- api.assert(!!this.stream, "input stream already removed");
467
- this.stream.unsubscribe(this.sub);
468
- delete this.stream;
469
- delete this.sub;
470
- }
471
- }
472
- }
473
-
474
- const pubsub = (opts) => new PubSub(opts);
475
- class PubSub extends Subscription {
476
- constructor(opts) {
477
- super(undefined, optsWithID("pubsub", {
478
- xform: opts.xform,
479
- }));
480
- this.topicfn = opts.topic;
481
- this.topics = new associative.EquivMap(undefined, {
482
- equiv: opts.equiv,
483
- });
484
- }
485
- subscribe() {
486
- return errors.unsupported(`use subscribeTopic() instead`);
487
- }
488
- transform() {
489
- return errors.unsupported(`use subscribeTopic() instead`);
490
- }
491
- subscribeTopic(topicID, sub, opts) {
492
- let t = this.topics.get(topicID);
493
- !t &&
494
- this.topics.set(topicID, (t = subscription(undefined, optsWithID("topic", {
495
- closeOut: exports.CloseMode.NEVER,
496
- }))));
497
- return t.subscribe(sub, opts);
498
- }
499
- transformTopic(topicID, xform, opts = {}) {
500
- return this.subscribeTopic(topicID, { error: opts.error }, Object.assign(Object.assign({}, opts), { xform }));
501
- }
502
- unsubscribeTopic(topicID, sub) {
503
- const t = this.topics.get(topicID);
504
- return t ? t.unsubscribe(sub) : false;
505
- }
506
- unsubscribe(sub) {
507
- if (!sub) {
508
- for (let t of this.topics.values()) {
509
- t.unsubscribe();
510
- }
511
- this.topics.clear();
512
- return super.unsubscribe();
513
- }
514
- return errors.unsupported();
515
- }
516
- done() {
517
- for (let t of this.topics.values()) {
518
- t.done();
519
- }
520
- super.done();
521
- }
522
- dispatch(x) {
523
- exports.LOGGER.debug(this.id, "dispatch", x);
524
- this.cacheLast && (this.last = x);
525
- const t = this.topicfn(x);
526
- if (t !== undefined) {
527
- const sub = this.topics.get(t);
528
- if (sub) {
529
- try {
530
- sub.next && sub.next(x);
531
- }
532
- catch (e) {
533
- if (!sub.error || !sub.error(e)) {
534
- return this.unhandledError(e);
535
- }
536
- }
537
- }
538
- }
539
- }
540
- }
541
-
542
- function stream(src, opts) {
543
- return new Stream(src, opts);
544
- }
545
- const reactive = (val, opts) => {
546
- const res = new Stream(opts);
547
- res.next(val);
548
- return res;
549
- };
550
- class Stream extends Subscription {
551
- constructor(src, opts) {
552
- const [_src, _opts] = checks.isFunction(src)
553
- ? [src, opts || {}]
554
- : [undefined, src || {}];
555
- super(_opts.error ? { error: _opts.error } : undefined, optsWithID("stream", _opts));
556
- this.src = _src;
557
- this._inited = false;
558
- }
559
- subscribe(sub, opts = {}) {
560
- const $sub = super.subscribe(sub, opts);
561
- if (!this._inited) {
562
- if (this.src) {
563
- try {
564
- this._cancel = this.src(this) || (() => void 0);
565
- }
566
- catch (e) {
567
- let s = this.wrapped;
568
- if (!s || !s.error || !s.error(e)) {
569
- this.unhandledError(e);
570
- }
571
- }
572
- }
573
- this._inited = true;
574
- }
575
- return $sub;
576
- }
577
- unsubscribe(sub) {
578
- const res = super.unsubscribe(sub);
579
- if (res &&
580
- (!sub ||
581
- ((!this.subs || !this.subs.length) &&
582
- this.closeOut !== exports.CloseMode.NEVER))) {
583
- this.cancel();
584
- }
585
- return res;
586
- }
587
- done() {
588
- this.cancel();
589
- super.done();
590
- delete this.src;
591
- delete this._cancel;
592
- }
593
- error(e) {
594
- if (super.error(e))
595
- return true;
596
- this.cancel();
597
- return false;
598
- }
599
- cancel() {
600
- if (this._cancel) {
601
- exports.LOGGER.debug(this.id, "cancel");
602
- const f = this._cancel;
603
- delete this._cancel;
604
- f();
605
- }
606
- }
607
- }
608
-
609
- const merge = (opts) => new StreamMerge(opts);
610
- class StreamMerge extends Subscription {
611
- constructor(opts) {
612
- opts = opts || {};
613
- super(undefined, optsWithID("streammerge", opts));
614
- this.sources = new Map();
615
- opts.src && this.addAll(opts.src);
616
- }
617
- add(src) {
618
- this.ensureState();
619
- this.sources.set(src, src.subscribe({
620
- next: (x) => x instanceof Subscription ? this.add(x) : this.next(x),
621
- done: () => this.markDone(src),
622
- __owner: this,
623
- }, { id: `in-${src.id}` }));
624
- }
625
- addAll(src) {
626
- for (let s of src) {
627
- this.add(s);
628
- }
629
- }
630
- remove(src) {
631
- const sub = this.sources.get(src);
632
- if (sub) {
633
- this.sources.delete(src);
634
- sub.unsubscribe();
635
- return true;
636
- }
637
- return false;
638
- }
639
- removeID(id) {
640
- for (let s of this.sources) {
641
- if (s[0].id === id) {
642
- return this.remove(s[0]);
643
- }
644
- }
645
- return false;
646
- }
647
- removeAll(src) {
648
- let ok = true;
649
- for (let s of src) {
650
- ok = this.remove(s) && ok;
651
- }
652
- return ok;
653
- }
654
- removeAllIDs(ids) {
655
- let ok = true;
656
- for (let id of ids) {
657
- ok = this.removeID(id) && ok;
658
- }
659
- return ok;
660
- }
661
- unsubscribe(sub) {
662
- if (!sub) {
663
- for (let s of this.sources.values()) {
664
- s.unsubscribe();
665
- }
666
- this.state = exports.State.DONE;
667
- this.sources.clear();
668
- }
669
- return super.unsubscribe(sub);
670
- }
671
- markDone(src) {
672
- this.remove(src);
673
- isFirstOrLastInput(this.closeIn, this.sources.size) && this.done();
674
- }
675
- }
676
-
677
- const fromIterable = (src, opts = {}) => new Stream((stream) => {
678
- const iter = src[Symbol.iterator]();
679
- const id = setInterval(() => {
680
- let val;
681
- if ((val = iter.next()).done) {
682
- clearInterval(id);
683
- stream.closeIn !== exports.CloseMode.NEVER && stream.done();
684
- }
685
- else {
686
- stream.next(val.value);
687
- }
688
- }, opts.delay || 0);
689
- return () => clearInterval(id);
690
- }, optsWithID("iterable", opts));
691
- const fromIterableSync = (src, opts) => new Stream((stream) => {
692
- for (let s of src) {
693
- stream.next(s);
694
- }
695
- stream.closeIn !== exports.CloseMode.NEVER && stream.done();
696
- }, optsWithID("iterable-sync", opts));
697
-
698
- function trigger(x = true, opts) {
699
- return fromIterableSync([x], optsWithID("trigger", opts));
700
- }
701
-
702
- const fromInterval = (delay, opts) => {
703
- opts = optsWithID("interval", Object.assign({ num: Infinity }, opts));
704
- return new Stream((stream) => {
705
- let i = 0;
706
- let count = opts.num;
707
- stream.next(i++);
708
- let id = setInterval(() => {
709
- stream.next(i++);
710
- if (--count <= 0) {
711
- clearInterval(id);
712
- stream.closeIn !== exports.CloseMode.NEVER && stream.done();
713
- }
714
- }, delay);
715
- return () => clearInterval(id);
716
- }, opts);
717
- };
718
-
719
- const fromRAF = (opts) => checks.isNode()
720
- ? fromInterval(16, opts)
721
- : new Stream((stream) => {
722
- let i = 0;
723
- let isActive = true;
724
- const loop = () => {
725
- isActive && stream.next(i++);
726
- isActive && (id = requestAnimationFrame(loop));
727
- };
728
- let id = requestAnimationFrame(loop);
729
- return () => {
730
- isActive = false;
731
- cancelAnimationFrame(id);
732
- };
733
- }, optsWithID("raf", opts));
734
-
735
- const tween = (src, initial, mix, stop, clock) => sync({
736
- src: {
737
- src,
738
- _: clock == null
739
- ? fromRAF()
740
- : checks.isNumber(clock)
741
- ? fromInterval(clock)
742
- : clock,
743
- },
744
- closeIn: exports.CloseMode.FIRST,
745
- }).transform(transducers.scan(transducers.reducer(() => initial, (acc, { src }) => mix(acc, src))), transducers.dedupe(stop || (() => false)));
746
- const tweenNumber = (src, init = 0, speed = 0.05, eps = 1e-3, clock) => tween(src, init, (a, b) => a + (b - a) * speed, (a, b) => Math.abs(a - b) < eps, clock);
747
-
748
- const fromAtom = (atom, opts) => {
749
- opts = optsWithID("atom", Object.assign({ emitFirst: true, changed: (a, b) => a !== b }, opts));
750
- return new Stream((stream) => {
751
- atom.addWatch(stream.id, (_, prev, curr) => {
752
- if (opts.changed(prev, curr)) {
753
- stream.next(curr);
754
- }
755
- });
756
- opts.emitFirst && stream.next(atom.deref());
757
- return () => atom.removeWatch(stream.id);
758
- }, opts);
759
- };
760
-
761
- const fromEvent = (src, name, listenerOpts = false, streamOpts) => new Stream((stream) => {
762
- let listener = (e) => stream.next(e);
763
- src.addEventListener(name, listener, listenerOpts);
764
- return () => src.removeEventListener(name, listener, listenerOpts);
765
- }, optsWithID(`event-${name}`, streamOpts));
766
- const fromDOMEvent = (src, name, listenerOpts = false, streamOpts) => fromEvent(src, name, listenerOpts, streamOpts);
767
-
768
- const fromObject = (src, opts = {}) => {
769
- const id = opts.id || `obj${nextID()}`;
770
- const keys = opts.keys || Object.keys(src);
771
- const _opts = opts.dedupe !== false
772
- ? Object.assign({ xform: transducers.dedupe(opts.equiv || ((a, b) => a === b)) }, opts) : opts;
773
- const streams = {};
774
- for (let k of keys) {
775
- streams[k] = subscription(undefined, Object.assign(Object.assign({}, _opts), { id: `${id}-${k}` }));
776
- }
777
- const res = {
778
- streams,
779
- next(state) {
780
- for (let k of keys) {
781
- const val = state[k];
782
- streams[k].next(opts.defaults && val === undefined ? opts.defaults[k] : val);
783
- }
784
- },
785
- done() {
786
- for (let k of keys) {
787
- streams[k].done();
788
- }
789
- },
790
- };
791
- opts.initial !== false && res.next(src);
792
- return res;
793
- };
794
-
795
- const fromPromise = (src, opts) => {
796
- let canceled = false;
797
- let isError = false;
798
- let err = {};
799
- src.catch((e) => {
800
- err = e;
801
- isError = true;
802
- });
803
- return new Stream((stream) => {
804
- src.then((x) => {
805
- if (!canceled && stream.getState() < exports.State.DONE) {
806
- if (isError) {
807
- stream.error(err);
808
- err = null;
809
- }
810
- else {
811
- stream.next(x);
812
- stream.closeIn !== exports.CloseMode.NEVER && stream.done();
813
- }
814
- }
815
- }, (e) => stream.error(e));
816
- return () => {
817
- canceled = true;
818
- };
819
- }, optsWithID("promise", opts));
820
- };
821
-
822
- const fromPromises = (promises, opts) => fromPromise(Promise.all(promises), optsWithID("promises", opts)).transform(transducers.mapcat((x) => x));
823
-
824
- const fromViewUnsafe = (atom, opts) => fromView(atom, opts);
825
- function fromView(atom$1, opts) {
826
- opts = optsWithID("view", opts);
827
- return new Stream((stream) => {
828
- let isActive = true;
829
- const tx = opts.tx;
830
- const view = new atom.View(atom$1, opts.path, tx
831
- ? (x) => isActive && ((x = tx(x)), stream.next(x), x)
832
- : (x) => isActive && (stream.next(x), x), false, opts.equiv);
833
- return () => {
834
- isActive = false;
835
- view.release();
836
- };
837
- });
838
- }
839
-
840
- const fromWorker = (worker, opts) => {
841
- const _worker = makeWorker(worker);
842
- opts = optsWithID("worker", opts);
843
- return new Stream((stream) => {
844
- const msgListener = (e) => {
845
- stream.next(e.data);
846
- };
847
- const errListener = (e) => {
848
- stream.error(e.data);
849
- };
850
- _worker.addEventListener("message", msgListener);
851
- _worker.addEventListener("error", errListener);
852
- return () => {
853
- _worker.removeEventListener("message", msgListener);
854
- _worker.removeEventListener("error", errListener);
855
- if (opts.terminate !== false) {
856
- exports.LOGGER.info("terminating worker", _worker);
857
- _worker.terminate();
858
- }
859
- };
860
- }, opts);
861
- };
862
-
863
- class ASidechain extends Subscription {
864
- constructor(opts) {
865
- super(undefined, opts);
866
- }
867
- unsubscribe(sub) {
868
- const res = super.unsubscribe(sub);
869
- if (!sub || !this.subs.length) {
870
- this.sideSub.unsubscribe();
871
- }
872
- return res;
873
- }
874
- done() {
875
- this.sideSub.unsubscribe();
876
- super.done();
877
- }
878
- }
879
-
880
- const bisect = (pred, truthy, falsy) => {
881
- const sub = new PubSub({ topic: pred, id: `bisect-${nextID()}` });
882
- truthy && sub.subscribeTopic(true, truthy);
883
- falsy && sub.subscribeTopic(false, falsy);
884
- return sub;
885
- };
886
-
887
- const debounce = (delay, opts) => metaStream((x) => fromIterable([x], { delay }), optsWithID("debounce", Object.assign({ emitLast: true }, opts)));
888
-
889
- const postWorker = (worker, transfer = false, terminate = 0) => {
890
- const _worker = makeWorker(worker);
891
- return {
892
- next(x) {
893
- if (x instanceof Promise) {
894
- x.then((y) => this.next(y));
895
- return;
896
- }
897
- let tx;
898
- if (transfer) {
899
- const ta = checks.isTypedArray(x);
900
- if (ta || checks.isTransferable(x)) {
901
- tx = [ta ? x.buffer : x];
902
- }
903
- }
904
- _worker.postMessage(x, tx || []);
905
- },
906
- done() {
907
- if (terminate > 0) {
908
- setTimeout(() => {
909
- exports.LOGGER.info("terminating worker...");
910
- _worker.terminate();
911
- }, terminate);
912
- }
913
- },
914
- };
915
- };
916
-
917
- const resolve = (opts) => new Resolver(opts);
918
- class Resolver extends Subscription {
919
- constructor(opts = {}) {
920
- super(undefined, optsWithID("resolve"));
921
- this.outstanding = 0;
922
- this.fail = opts.fail;
923
- }
924
- next(x) {
925
- this.outstanding++;
926
- x.then((y) => {
927
- if (this.state < exports.State.DONE) {
928
- this.dispatch(y);
929
- if (--this.outstanding === 0) {
930
- this.done();
931
- }
932
- }
933
- else {
934
- exports.LOGGER.warn(`resolved value in state ${this.state} (${x})`);
935
- }
936
- }, (e) => {
937
- if (this.fail) {
938
- this.fail(e);
939
- }
940
- else {
941
- this.error(e);
942
- }
943
- });
944
- }
945
- done() {
946
- if (this.parent &&
947
- this.parent.getState() === exports.State.DONE &&
948
- this.outstanding === 0) {
949
- super.done();
950
- }
951
- }
952
- }
953
-
954
- const sidechainPartition = (side, opts) => new SidechainPartition(side, opts);
955
- const sidechainPartitionRAF = (src) => src
956
- .subscribe(sidechainPartition(fromRAF()))
957
- .transform(transducers.map(arrays.peek));
958
- class SidechainPartition extends ASidechain {
959
- constructor(side, opts) {
960
- opts = optsWithID("sidepart", opts);
961
- super(opts);
962
- this.buf = [];
963
- const pred = opts.pred || (() => true);
964
- const $this = this;
965
- this.sideSub = side.subscribe({
966
- next(x) {
967
- if ($this.buf.length && pred(x)) {
968
- $this.dispatch($this.buf);
969
- $this.buf = [];
970
- }
971
- },
972
- done() {
973
- if ($this.buf.length) {
974
- $this.dispatch($this.buf);
975
- }
976
- $this.done();
977
- delete $this.buf;
978
- },
979
- });
980
- }
981
- next(x) {
982
- if (this.state < exports.State.DONE) {
983
- this.buf.push(x);
984
- }
985
- }
986
- }
987
-
988
- const sidechainToggle = (side, opts) => new SidechainToggle(side, opts);
989
- class SidechainToggle extends ASidechain {
990
- constructor(side, opts) {
991
- opts = optsWithID("sidetoggle", opts);
992
- super(opts);
993
- this.isActive = !!opts.initial;
994
- const pred = opts.pred || (() => true);
995
- const $this = this;
996
- this.sideSub = side.subscribe({
997
- next(x) {
998
- if (pred(x)) {
999
- $this.isActive = !$this.isActive;
1000
- }
1001
- },
1002
- done() {
1003
- $this.done();
1004
- },
1005
- });
1006
- }
1007
- next(x) {
1008
- if (this.isActive && this.state < exports.State.DONE) {
1009
- super.next(x);
1010
- }
1011
- }
1012
- }
1013
-
1014
- const timeout = (timeoutMs, opts) => new Timeout(timeoutMs, opts);
1015
- class Timeout extends Subscription {
1016
- constructor(timeoutMs, opts) {
1017
- opts = optsWithID("timeout", opts);
1018
- super(undefined, opts);
1019
- this.timeoutMs = timeoutMs;
1020
- this.errorObj = opts.error;
1021
- this.resetTimeout = opts.reset === true;
1022
- this.reset();
1023
- }
1024
- next(x) {
1025
- if (this.resetTimeout) {
1026
- clearTimeout(this.timeoutId);
1027
- this.reset();
1028
- }
1029
- super.next(x);
1030
- }
1031
- reset() {
1032
- this.timeoutId = setTimeout(() => {
1033
- if (this.state < exports.State.DONE) {
1034
- this.dispatchTo("error", this.errorObj ||
1035
- new Error(`Timeout '${this.id}' after ${this.timeoutMs} ms`));
1036
- }
1037
- }, this.timeoutMs);
1038
- }
1039
- release() {
1040
- clearTimeout(this.timeoutId);
1041
- super.release();
1042
- }
1043
- }
1044
-
1045
- const trace = (prefix) => ({
1046
- next(x) {
1047
- prefix ? console.log(prefix, x) : console.log(x);
1048
- },
1049
- done() {
1050
- prefix ? console.log(prefix, "done") : console.log("done");
1051
- },
1052
- error(e) {
1053
- prefix ? console.log(prefix, "error", e) : console.log("error", e);
1054
- return false;
1055
- },
1056
- });
1057
-
1058
- const transduce = (src, xform, rfn, init) => {
1059
- let acc = init !== undefined ? init : rfn[0]();
1060
- let sub;
1061
- return new Promise((resolve, reject) => {
1062
- sub = src.subscribe({
1063
- next(x) {
1064
- let _acc;
1065
- try {
1066
- _acc = rfn[2](acc, x);
1067
- }
1068
- catch (e) {
1069
- reject(e);
1070
- return;
1071
- }
1072
- if (transducers.isReduced(_acc)) {
1073
- resolve(_acc.deref());
1074
- }
1075
- else {
1076
- acc = _acc;
1077
- }
1078
- },
1079
- done() {
1080
- resolve(acc);
1081
- },
1082
- error(e) {
1083
- reject(e);
1084
- return false;
1085
- },
1086
- }, { xform });
1087
- }).then((fulfilled) => {
1088
- sub.unsubscribe();
1089
- return fulfilled;
1090
- }, (rejected) => {
1091
- sub.unsubscribe();
1092
- throw rejected;
1093
- });
1094
- };
1095
-
1096
- exports.ASidechain = ASidechain;
1097
- exports.MetaStream = MetaStream;
1098
- exports.PubSub = PubSub;
1099
- exports.Resolver = Resolver;
1100
- exports.SidechainPartition = SidechainPartition;
1101
- exports.SidechainToggle = SidechainToggle;
1102
- exports.Stream = Stream;
1103
- exports.StreamMerge = StreamMerge;
1104
- exports.StreamSync = StreamSync;
1105
- exports.Subscription = Subscription;
1106
- exports.Tunnel = Tunnel;
1107
- exports.bisect = bisect;
1108
- exports.debounce = debounce;
1109
- exports.forkBuffer = forkBuffer;
1110
- exports.forkJoin = forkJoin;
1111
- exports.fromAtom = fromAtom;
1112
- exports.fromDOMEvent = fromDOMEvent;
1113
- exports.fromEvent = fromEvent;
1114
- exports.fromInterval = fromInterval;
1115
- exports.fromIterable = fromIterable;
1116
- exports.fromIterableSync = fromIterableSync;
1117
- exports.fromObject = fromObject;
1118
- exports.fromPromise = fromPromise;
1119
- exports.fromPromises = fromPromises;
1120
- exports.fromRAF = fromRAF;
1121
- exports.fromView = fromView;
1122
- exports.fromViewUnsafe = fromViewUnsafe;
1123
- exports.fromWorker = fromWorker;
1124
- exports.inlineWorker = inlineWorker;
1125
- exports.joinBuffer = joinBuffer;
1126
- exports.makeWorker = makeWorker;
1127
- exports.merge = merge;
1128
- exports.metaStream = metaStream;
1129
- exports.nextID = nextID;
1130
- exports.optsWithID = optsWithID;
1131
- exports.postWorker = postWorker;
1132
- exports.pubsub = pubsub;
1133
- exports.reactive = reactive;
1134
- exports.resolve = resolve;
1135
- exports.setLogger = setLogger;
1136
- exports.sidechainPartition = sidechainPartition;
1137
- exports.sidechainPartitionRAF = sidechainPartitionRAF;
1138
- exports.sidechainToggle = sidechainToggle;
1139
- exports.stream = stream;
1140
- exports.subscription = subscription;
1141
- exports.sync = sync;
1142
- exports.timeout = timeout;
1143
- exports.trace = trace;
1144
- exports.transduce = transduce;
1145
- exports.trigger = trigger;
1146
- exports.tunnel = tunnel;
1147
- exports.tween = tween;
1148
- exports.tweenNumber = tweenNumber;