@thi.ng/rstream 8.2.13 → 8.2.14
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/CHANGELOG.md +1 -1
- package/api.js +18 -26
- package/asidechain.js +18 -19
- package/atom.js +17 -46
- package/bisect.js +8 -49
- package/checks.js +6 -7
- package/debounce.js +9 -17
- package/defworker.js +8 -6
- package/event.js +13 -38
- package/forkjoin.js +38 -104
- package/idgen.js +6 -8
- package/internal/remove.js +9 -6
- package/interval.js +21 -29
- package/iterable.js +21 -43
- package/logger.js +6 -2
- package/merge.js +71 -117
- package/metastream.js +66 -142
- package/nodejs.js +11 -51
- package/object.js +34 -98
- package/package.json +14 -11
- package/post-worker.js +29 -60
- package/promise.js +30 -36
- package/promises.js +7 -41
- package/pubsub.js +91 -105
- package/raf.js +16 -28
- package/resolve.js +37 -58
- package/sidechain-partition.js +36 -89
- package/sidechain-toggle.js +27 -48
- package/sidechain-trigger.js +26 -60
- package/stream.js +67 -74
- package/subscription.js +214 -275
- package/sync-raf.js +35 -66
- package/sync.js +133 -176
- package/timeout.js +38 -49
- package/toggle.js +10 -29
- package/trace.js +14 -18
- package/transduce.js +43 -60
- package/trigger.js +5 -2
- package/tunnel.js +55 -62
- package/tween.js +26 -76
- package/view.js +22 -43
- package/worker.js +24 -44
package/CHANGELOG.md
CHANGED
package/api.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
})(State ||
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* Close when first input/output is done / removed.
|
|
20
|
-
*/
|
|
21
|
-
CloseMode[CloseMode["FIRST"] = 1] = "FIRST";
|
|
22
|
-
/**
|
|
23
|
-
* Close when last input/output is done / removed.
|
|
24
|
-
*/
|
|
25
|
-
CloseMode[CloseMode["LAST"] = 2] = "LAST";
|
|
26
|
-
})(CloseMode || (CloseMode = {}));
|
|
1
|
+
var State = /* @__PURE__ */ ((State2) => {
|
|
2
|
+
State2[State2["IDLE"] = 0] = "IDLE";
|
|
3
|
+
State2[State2["ACTIVE"] = 1] = "ACTIVE";
|
|
4
|
+
State2[State2["DONE"] = 2] = "DONE";
|
|
5
|
+
State2[State2["UNSUBSCRIBED"] = 3] = "UNSUBSCRIBED";
|
|
6
|
+
State2[State2["ERROR"] = 4] = "ERROR";
|
|
7
|
+
return State2;
|
|
8
|
+
})(State || {});
|
|
9
|
+
var CloseMode = /* @__PURE__ */ ((CloseMode2) => {
|
|
10
|
+
CloseMode2[CloseMode2["NEVER"] = 0] = "NEVER";
|
|
11
|
+
CloseMode2[CloseMode2["FIRST"] = 1] = "FIRST";
|
|
12
|
+
CloseMode2[CloseMode2["LAST"] = 2] = "LAST";
|
|
13
|
+
return CloseMode2;
|
|
14
|
+
})(CloseMode || {});
|
|
15
|
+
export {
|
|
16
|
+
CloseMode,
|
|
17
|
+
State
|
|
18
|
+
};
|
package/asidechain.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { Subscription } from "./subscription.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
unsubscribe(sub) {
|
|
12
|
-
const res = super.unsubscribe(sub);
|
|
13
|
-
if (!sub || !this.subs.length) {
|
|
14
|
-
this.sideSub.unsubscribe();
|
|
15
|
-
}
|
|
16
|
-
return res;
|
|
17
|
-
}
|
|
18
|
-
done() {
|
|
19
|
-
this.sideSub.unsubscribe();
|
|
20
|
-
super.done();
|
|
2
|
+
class ASidechain extends Subscription {
|
|
3
|
+
sideSub;
|
|
4
|
+
constructor(opts) {
|
|
5
|
+
super(void 0, opts);
|
|
6
|
+
}
|
|
7
|
+
unsubscribe(sub) {
|
|
8
|
+
const res = super.unsubscribe(sub);
|
|
9
|
+
if (!sub || !this.subs.length) {
|
|
10
|
+
this.sideSub.unsubscribe();
|
|
21
11
|
}
|
|
12
|
+
return res;
|
|
13
|
+
}
|
|
14
|
+
done() {
|
|
15
|
+
this.sideSub.unsubscribe();
|
|
16
|
+
super.done();
|
|
17
|
+
}
|
|
22
18
|
}
|
|
19
|
+
export {
|
|
20
|
+
ASidechain
|
|
21
|
+
};
|
package/atom.js
CHANGED
|
@@ -1,50 +1,21 @@
|
|
|
1
1
|
import { __optsWithID } from "./idgen.js";
|
|
2
2
|
import { stream } from "./stream.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
* Also see {@link fromView}, {@link fromViewUnsafe}
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```ts
|
|
19
|
-
* db = new Atom({ a: 23, b: 88 });
|
|
20
|
-
* cursor = new Cursor(db, "a")
|
|
21
|
-
*
|
|
22
|
-
* rs.fromAtom(cursor).subscribe(rs.trace("cursor val:"))
|
|
23
|
-
* // cursor val: 23
|
|
24
|
-
*
|
|
25
|
-
* cursor.reset(42);
|
|
26
|
-
* // cursor val: 42
|
|
27
|
-
*
|
|
28
|
-
* db.reset({a: 66})
|
|
29
|
-
* // cursor val: 66
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @param atom -
|
|
33
|
-
* @param opts -
|
|
34
|
-
*/
|
|
35
|
-
export const fromAtom = (atom, opts) => {
|
|
36
|
-
opts = __optsWithID("atom", {
|
|
37
|
-
emitFirst: true,
|
|
38
|
-
changed: (a, b) => a !== b,
|
|
39
|
-
...opts,
|
|
3
|
+
const fromAtom = (atom, opts) => {
|
|
4
|
+
opts = __optsWithID("atom", {
|
|
5
|
+
emitFirst: true,
|
|
6
|
+
changed: (a, b) => a !== b,
|
|
7
|
+
...opts
|
|
8
|
+
});
|
|
9
|
+
return stream((stream2) => {
|
|
10
|
+
atom.addWatch(stream2.id, (_, prev, curr) => {
|
|
11
|
+
if (opts.changed(prev, curr)) {
|
|
12
|
+
stream2.next(curr);
|
|
13
|
+
}
|
|
40
14
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
opts.emitFirst && stream.next(atom.deref());
|
|
48
|
-
return () => atom.removeWatch(stream.id);
|
|
49
|
-
}, opts);
|
|
15
|
+
opts.emitFirst && stream2.next(atom.deref());
|
|
16
|
+
return () => atom.removeWatch(stream2.id);
|
|
17
|
+
}, opts);
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
fromAtom
|
|
50
21
|
};
|
package/bisect.js
CHANGED
|
@@ -1,52 +1,11 @@
|
|
|
1
1
|
import { __nextID } from "./idgen.js";
|
|
2
2
|
import { PubSub } from "./pubsub.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* kept prior to calling `bisect()`.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* fromIterable([1, 2, 3, 4]).subscribe(
|
|
16
|
-
* bisect(
|
|
17
|
-
* (x) => !!(x & 1),
|
|
18
|
-
* trace("odd"),
|
|
19
|
-
* trace("even")
|
|
20
|
-
* )
|
|
21
|
-
* );
|
|
22
|
-
* // odd 1
|
|
23
|
-
* // even 2
|
|
24
|
-
* // odd 3
|
|
25
|
-
* // even 4
|
|
26
|
-
* // odd done
|
|
27
|
-
* // even done
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* const odd = subscription();
|
|
33
|
-
* const even = subscription();
|
|
34
|
-
* odd.subscribe(trace("odd"));
|
|
35
|
-
* odd.subscribe(trace("odd x10"), map((x) => x * 10));
|
|
36
|
-
* even.subscribe(trace("even"));
|
|
37
|
-
*
|
|
38
|
-
* fromIterable([1, 2, 3, 4]).subscribe(
|
|
39
|
-
* bisect((x) => !!(x & 1), odd, even)
|
|
40
|
-
* );
|
|
41
|
-
* ```
|
|
42
|
-
*
|
|
43
|
-
* @param pred - predicate function
|
|
44
|
-
* @param truthy - subscription for truthy branch
|
|
45
|
-
* @param falsy - subscription for falsy branch
|
|
46
|
-
*/
|
|
47
|
-
export const bisect = (pred, truthy, falsy) => {
|
|
48
|
-
const sub = new PubSub({ topic: pred, id: `bisect-${__nextID()}` });
|
|
49
|
-
truthy && sub.subscribeTopic(true, truthy);
|
|
50
|
-
falsy && sub.subscribeTopic(false, falsy);
|
|
51
|
-
return sub;
|
|
3
|
+
const bisect = (pred, truthy, falsy) => {
|
|
4
|
+
const sub = new PubSub({ topic: pred, id: `bisect-${__nextID()}` });
|
|
5
|
+
truthy && sub.subscribeTopic(true, truthy);
|
|
6
|
+
falsy && sub.subscribeTopic(false, falsy);
|
|
7
|
+
return sub;
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
bisect
|
|
52
11
|
};
|
package/checks.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { implementsFunction } from "@thi.ng/checks/implements-function";
|
|
2
2
|
import { CloseMode } from "./api.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const isFirstOrLastInput = (mode, num) => mode === CloseMode.FIRST || (mode === CloseMode.LAST && !num);
|
|
3
|
+
const isSubscribable = (x) => implementsFunction(x, "subscribe");
|
|
4
|
+
const isFirstOrLastInput = (mode, num) => mode === CloseMode.FIRST || mode === CloseMode.LAST && !num;
|
|
5
|
+
export {
|
|
6
|
+
isFirstOrLastInput,
|
|
7
|
+
isSubscribable
|
|
8
|
+
};
|
package/debounce.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import { __optsWithID } from "./idgen.js";
|
|
2
2
|
import { fromIterable } from "./iterable.js";
|
|
3
3
|
import { metaStream } from "./metastream.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* milliseconds.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* const src = fromIterable([1, 2, 3], { delay: 10 })
|
|
12
|
-
* src.subscribe(debounce(20)).subscribe({ next: console.log });
|
|
13
|
-
* // 3
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @param delay -
|
|
17
|
-
*/
|
|
18
|
-
export const debounce = (delay, opts) => metaStream((x) => fromIterable([x], { delay }), __optsWithID("debounce", {
|
|
4
|
+
const debounce = (delay, opts) => metaStream(
|
|
5
|
+
(x) => fromIterable([x], { delay }),
|
|
6
|
+
__optsWithID("debounce", {
|
|
19
7
|
emitLast: true,
|
|
20
|
-
...opts
|
|
21
|
-
})
|
|
8
|
+
...opts
|
|
9
|
+
})
|
|
10
|
+
);
|
|
11
|
+
export {
|
|
12
|
+
debounce
|
|
13
|
+
};
|
package/defworker.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { isFunction } from "@thi.ng/checks/is-function";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
const defInlineWorker = (src) => defWorker(new Blob([src], { type: "text/javascript" }));
|
|
3
|
+
const defWorker = (worker) => worker instanceof Worker ? worker : isFunction(worker) ? worker() : new Worker(
|
|
4
|
+
worker instanceof Blob ? URL.createObjectURL(worker) : worker
|
|
5
|
+
);
|
|
6
|
+
export {
|
|
7
|
+
defInlineWorker,
|
|
8
|
+
defWorker
|
|
9
|
+
};
|
package/event.js
CHANGED
|
@@ -1,41 +1,16 @@
|
|
|
1
1
|
import { __optsWithID } from "./idgen.js";
|
|
2
2
|
import { stream, Stream } from "./stream.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
src.addEventListener(name, listener, listenerOpts);
|
|
17
|
-
return () => src.removeEventListener(name, listener, listenerOpts);
|
|
18
|
-
}, __optsWithID(`event-${name}`, streamOpts));
|
|
19
|
-
streamOpts?.init !== undefined && result.next(streamOpts.init);
|
|
20
|
-
return result;
|
|
3
|
+
const fromEvent = (src, name, listenerOpts = false, streamOpts) => {
|
|
4
|
+
const result = stream((stream2) => {
|
|
5
|
+
let listener = (e) => stream2.next(e);
|
|
6
|
+
src.addEventListener(name, listener, listenerOpts);
|
|
7
|
+
return () => src.removeEventListener(name, listener, listenerOpts);
|
|
8
|
+
}, __optsWithID(`event-${name}`, streamOpts));
|
|
9
|
+
streamOpts?.init !== void 0 && result.next(streamOpts.init);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
const fromDOMEvent = (src, name, listenerOpts = false, streamOpts) => fromEvent(src, name, listenerOpts, streamOpts);
|
|
13
|
+
export {
|
|
14
|
+
fromDOMEvent,
|
|
15
|
+
fromEvent
|
|
21
16
|
};
|
|
22
|
-
/**
|
|
23
|
-
* Same as {@link fromEvent}, however only supports well-known DOM event
|
|
24
|
-
* names. Returned stream instance will use corresponding concrete event
|
|
25
|
-
* type in its type signature, whereas {@link fromEvent} will only use the
|
|
26
|
-
* generic `Event`.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* fromDOMEvent(document.body, "mousemove"); // Stream<MouseEvent>
|
|
31
|
-
* fromEvent(document.body, "mousemove"); // Stream<Event>
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* Also see: {@link fromEvent}
|
|
35
|
-
*
|
|
36
|
-
* @param src -
|
|
37
|
-
* @param name -
|
|
38
|
-
* @param listenerOpts -
|
|
39
|
-
* @param streamOpts -
|
|
40
|
-
*/
|
|
41
|
-
export const fromDOMEvent = (src, name, listenerOpts = false, streamOpts) => fromEvent(src, name, listenerOpts, streamOpts);
|
package/forkjoin.js
CHANGED
|
@@ -6,109 +6,43 @@ import { range } from "@thi.ng/transducers/range";
|
|
|
6
6
|
import { transduce } from "@thi.ng/transducers/transduce";
|
|
7
7
|
import { sync } from "./sync.js";
|
|
8
8
|
import { tunnel } from "./tunnel.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
]), assocObj(), workerIDs),
|
|
39
|
-
xform: comp(
|
|
40
|
-
// form result tuple in original order
|
|
41
|
-
map((results) => [...map((id) => results[id], workerIDs)]),
|
|
42
|
-
// apply user join function
|
|
43
|
-
map(opts.join)),
|
|
44
|
-
reset: true,
|
|
45
|
-
backPressure: opts.backPressure,
|
|
46
|
-
});
|
|
9
|
+
const forkJoin = (opts) => {
|
|
10
|
+
const numWorkers = opts.numWorkers || navigator.hardwareConcurrency || 4;
|
|
11
|
+
const workerIDs = range(numWorkers);
|
|
12
|
+
return sync({
|
|
13
|
+
src: transduce(
|
|
14
|
+
map((id) => [
|
|
15
|
+
String(id),
|
|
16
|
+
opts.src.transform(map((x) => opts.fork(id, numWorkers, x))).subscribe(
|
|
17
|
+
tunnel({
|
|
18
|
+
src: opts.worker,
|
|
19
|
+
transferables: opts.transferables,
|
|
20
|
+
interrupt: opts.interrupt === true,
|
|
21
|
+
terminate: opts.terminate,
|
|
22
|
+
id: String(id)
|
|
23
|
+
})
|
|
24
|
+
)
|
|
25
|
+
]),
|
|
26
|
+
assocObj(),
|
|
27
|
+
workerIDs
|
|
28
|
+
),
|
|
29
|
+
xform: comp(
|
|
30
|
+
// form result tuple in original order
|
|
31
|
+
map((results) => [...map((id) => results[id], workerIDs)]),
|
|
32
|
+
// apply user join function
|
|
33
|
+
map(opts.join)
|
|
34
|
+
),
|
|
35
|
+
reset: true,
|
|
36
|
+
backPressure: opts.backPressure
|
|
37
|
+
});
|
|
47
38
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*
|
|
58
|
-
* **Note:** Depending on the configured `minChunkSize` and the size of
|
|
59
|
-
* the input buffer to be partitioned, the returned fork function might
|
|
60
|
-
* produce empty sub-arrays for some workers, iff the configured number
|
|
61
|
-
* of workers exceeds the resulting number of chunks / input values.
|
|
62
|
-
* E.g. If the number of workers = 8, buffer size = 10 and min chunk
|
|
63
|
-
* size = 2, then the last 3 (i.e. 8 - 10 / 2) workers will only receive
|
|
64
|
-
* empty workloads.
|
|
65
|
-
*
|
|
66
|
-
* More generally, if the input buffer size is not equally distributable
|
|
67
|
-
* over the given number of workers, the last worker(s) might receive a
|
|
68
|
-
* larger, smaller or empty chunk.
|
|
69
|
-
*
|
|
70
|
-
* Also see {@link forkJoin} and {@link joinBuffer}.
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* ```ts
|
|
74
|
-
* forkJoin<number[], number[], number[], number[]>({
|
|
75
|
-
* src,
|
|
76
|
-
* // job definition / split buffer into chunks (min size 256 values)
|
|
77
|
-
* fork: forkBuffer(256),
|
|
78
|
-
* // re-join partial results
|
|
79
|
-
* join: joinBuffer(),
|
|
80
|
-
* worker: "./worker.js",
|
|
81
|
-
* })
|
|
82
|
-
* ```
|
|
83
|
-
*
|
|
84
|
-
* @param minChunkSize -
|
|
85
|
-
*/
|
|
86
|
-
export const forkBuffer = (minChunkSize = 1) => (id, numWorkers, buf) => {
|
|
87
|
-
const chunkSize = Math.max(minChunkSize, (buf.length / numWorkers) | 0);
|
|
88
|
-
return id < numWorkers - 1
|
|
89
|
-
? buf.slice(id * chunkSize, (id + 1) * chunkSize)
|
|
90
|
-
: buf.slice(id * chunkSize);
|
|
39
|
+
const forkBuffer = (minChunkSize = 1) => (id, numWorkers, buf) => {
|
|
40
|
+
const chunkSize = Math.max(minChunkSize, buf.length / numWorkers | 0);
|
|
41
|
+
return id < numWorkers - 1 ? buf.slice(id * chunkSize, (id + 1) * chunkSize) : buf.slice(id * chunkSize);
|
|
42
|
+
};
|
|
43
|
+
const joinBuffer = (fn) => fn ? (parts) => [...mapcat(fn, parts)] : (parts) => Array.prototype.concat.apply([], parts);
|
|
44
|
+
export {
|
|
45
|
+
forkBuffer,
|
|
46
|
+
forkJoin,
|
|
47
|
+
joinBuffer
|
|
91
48
|
};
|
|
92
|
-
/**
|
|
93
|
-
* Higher-order join function for scenarios involving the split-parallel
|
|
94
|
-
* processing of a large buffer.
|
|
95
|
-
*
|
|
96
|
-
* @remarks
|
|
97
|
-
* The returned function is meant to be used as `join` function in a
|
|
98
|
-
* {@link ForkJoinOpts} config, receives the processed result chunks
|
|
99
|
-
* from all workers (ordered by worker ID) and concatenates them back
|
|
100
|
-
* into a single result array.
|
|
101
|
-
*
|
|
102
|
-
* The optional `fn` arg can be used to pick the actual result chunk
|
|
103
|
-
* from each worker result. This is useful if the worker result type is
|
|
104
|
-
* not an array and includes other data points (e.g. execution metrics
|
|
105
|
-
* etc.). If `fn` is not given, it defaults to the identity function
|
|
106
|
-
* (i.e. each worker's result is assumed to be an array).
|
|
107
|
-
*
|
|
108
|
-
* Also see {@link forkJoin} and {@link forkBuffer}.
|
|
109
|
-
*
|
|
110
|
-
* @param fn -
|
|
111
|
-
*/
|
|
112
|
-
export const joinBuffer = (fn) => fn
|
|
113
|
-
? (parts) => [...mapcat(fn, parts)]
|
|
114
|
-
: (parts) => Array.prototype.concat.apply([], parts);
|
package/idgen.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
let NEXT_ID = 0;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
export const __optsWithID = (prefix, opts) => ((!opts || !opts.id ? { ...opts, id: prefix + "-" + __nextID() } : opts));
|
|
2
|
+
const __nextID = () => NEXT_ID++;
|
|
3
|
+
const __optsWithID = (prefix, opts) => !opts || !opts.id ? { ...opts, id: prefix + "-" + __nextID() } : opts;
|
|
4
|
+
export {
|
|
5
|
+
__nextID,
|
|
6
|
+
__optsWithID
|
|
7
|
+
};
|
package/internal/remove.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const __removeAllIDs = (impl, ids) => {
|
|
2
|
+
let ok = true;
|
|
3
|
+
for (let id of ids) {
|
|
4
|
+
ok = impl.removeID(id) && ok;
|
|
5
|
+
}
|
|
6
|
+
return ok;
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
__removeAllIDs
|
|
7
10
|
};
|
package/interval.js
CHANGED
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
import { CloseMode } from "./api.js";
|
|
2
2
|
import { __optsWithID } from "./idgen.js";
|
|
3
3
|
import { stream } from "./stream.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
stream.next(i++);
|
|
26
|
-
if (--count <= 0) {
|
|
27
|
-
clearInterval(id);
|
|
28
|
-
stream.closeIn !== CloseMode.NEVER && stream.done();
|
|
29
|
-
}
|
|
30
|
-
}, delay);
|
|
31
|
-
return () => clearInterval(id);
|
|
32
|
-
}, opts);
|
|
4
|
+
const fromInterval = (delay, opts) => {
|
|
5
|
+
opts = __optsWithID("interval", {
|
|
6
|
+
num: Infinity,
|
|
7
|
+
...opts
|
|
8
|
+
});
|
|
9
|
+
return stream((stream2) => {
|
|
10
|
+
let i = 0;
|
|
11
|
+
let count = opts.num;
|
|
12
|
+
stream2.next(i++);
|
|
13
|
+
let id = setInterval(() => {
|
|
14
|
+
stream2.next(i++);
|
|
15
|
+
if (--count <= 0) {
|
|
16
|
+
clearInterval(id);
|
|
17
|
+
stream2.closeIn !== CloseMode.NEVER && stream2.done();
|
|
18
|
+
}
|
|
19
|
+
}, delay);
|
|
20
|
+
return () => clearInterval(id);
|
|
21
|
+
}, opts);
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
fromInterval
|
|
33
25
|
};
|
package/iterable.js
CHANGED
|
@@ -1,48 +1,26 @@
|
|
|
1
1
|
import { CloseMode } from "./api.js";
|
|
2
2
|
import { __optsWithID } from "./idgen.js";
|
|
3
3
|
import { stream } from "./stream.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* {@link ISubscriber.done} to close the stream, but this can be
|
|
14
|
-
* re-configured via provided {@link CommonOpts | options}.
|
|
15
|
-
*
|
|
16
|
-
* @param src -
|
|
17
|
-
* @param opts -
|
|
18
|
-
*/
|
|
19
|
-
export const fromIterable = (src, opts = {}) => stream((stream) => {
|
|
20
|
-
const iter = src[Symbol.iterator]();
|
|
21
|
-
const id = setInterval(() => {
|
|
22
|
-
let val;
|
|
23
|
-
if ((val = iter.next()).done) {
|
|
24
|
-
clearInterval(id);
|
|
25
|
-
stream.closeIn !== CloseMode.NEVER && stream.done();
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
stream.next(val.value);
|
|
29
|
-
}
|
|
30
|
-
}, opts.delay || 0);
|
|
31
|
-
return () => clearInterval(id);
|
|
32
|
-
}, __optsWithID("iterable", opts));
|
|
33
|
-
/**
|
|
34
|
-
* Creates a new {@link Stream} of given iterable which synchronously calls
|
|
35
|
-
* {@link ISubscriber.next} for each item of the iterable when the first (and in
|
|
36
|
-
* this case the only one) subscriber becomes available. Once the iterable is
|
|
37
|
-
* exhausted (MUST be finite!), then calls {@link ISubscriber.done} by default,
|
|
38
|
-
* but can be avoided by passing `false` as last argument.
|
|
39
|
-
*
|
|
40
|
-
* @param src -
|
|
41
|
-
* @param opts -
|
|
42
|
-
*/
|
|
43
|
-
export const fromIterableSync = (src, opts) => stream((stream) => {
|
|
44
|
-
for (let s of src) {
|
|
45
|
-
stream.next(s);
|
|
4
|
+
const fromIterable = (src, opts = {}) => stream((stream2) => {
|
|
5
|
+
const iter = src[Symbol.iterator]();
|
|
6
|
+
const id = setInterval(() => {
|
|
7
|
+
let val;
|
|
8
|
+
if ((val = iter.next()).done) {
|
|
9
|
+
clearInterval(id);
|
|
10
|
+
stream2.closeIn !== CloseMode.NEVER && stream2.done();
|
|
11
|
+
} else {
|
|
12
|
+
stream2.next(val.value);
|
|
46
13
|
}
|
|
47
|
-
|
|
14
|
+
}, opts.delay || 0);
|
|
15
|
+
return () => clearInterval(id);
|
|
16
|
+
}, __optsWithID("iterable", opts));
|
|
17
|
+
const fromIterableSync = (src, opts) => stream((stream2) => {
|
|
18
|
+
for (let s of src) {
|
|
19
|
+
stream2.next(s);
|
|
20
|
+
}
|
|
21
|
+
stream2.closeIn !== CloseMode.NEVER && stream2.done();
|
|
48
22
|
}, __optsWithID("iterable-sync", opts));
|
|
23
|
+
export {
|
|
24
|
+
fromIterable,
|
|
25
|
+
fromIterableSync
|
|
26
|
+
};
|