@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/logger.js
CHANGED
package/merge.js
CHANGED
|
@@ -1,127 +1,81 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
State
|
|
3
|
+
} from "./api.js";
|
|
2
4
|
import { isFirstOrLastInput } from "./checks.js";
|
|
3
5
|
import { __optsWithID } from "./idgen.js";
|
|
4
6
|
import { __removeAllIDs } from "./internal/remove.js";
|
|
5
7
|
import { Subscription } from "./subscription.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* // 3
|
|
33
|
-
* // 20
|
|
34
|
-
* // 30
|
|
35
|
-
* ```
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* Use the
|
|
39
|
-
* [`labeled()`](https://docs.thi.ng/umbrella/transducers/functions/labeled.html)
|
|
40
|
-
* transducer for each input to create a stream of labeled values and
|
|
41
|
-
* track their provenance:
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```ts
|
|
45
|
-
* merge({
|
|
46
|
-
* src: [
|
|
47
|
-
* fromIterable([1, 2, 3]).transform(tx.labeled("a")),
|
|
48
|
-
* fromIterable([10, 20, 30]).transform(tx.labeled("b")),
|
|
49
|
-
* ]
|
|
50
|
-
* }).subscribe(trace());
|
|
51
|
-
* // ["a", 1]
|
|
52
|
-
* // ["b", 10]
|
|
53
|
-
* // ["a", 2]
|
|
54
|
-
* // ["b", 20]
|
|
55
|
-
* // ["a", 3]
|
|
56
|
-
* // ["b", 30]
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* @param opts -
|
|
60
|
-
*/
|
|
61
|
-
export const merge = (opts) => new StreamMerge(opts);
|
|
62
|
-
/**
|
|
63
|
-
* @see {@link merge} for reference & examples.
|
|
64
|
-
*/
|
|
65
|
-
export class StreamMerge extends Subscription {
|
|
66
|
-
sources;
|
|
67
|
-
constructor(opts) {
|
|
68
|
-
opts = opts || {};
|
|
69
|
-
super(undefined, __optsWithID("streammerge", opts));
|
|
70
|
-
this.sources = new Map();
|
|
71
|
-
opts.src && this.addAll(opts.src);
|
|
8
|
+
const merge = (opts) => new StreamMerge(opts);
|
|
9
|
+
class StreamMerge extends Subscription {
|
|
10
|
+
sources;
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
opts = opts || {};
|
|
13
|
+
super(void 0, __optsWithID("streammerge", opts));
|
|
14
|
+
this.sources = /* @__PURE__ */ new Map();
|
|
15
|
+
opts.src && this.addAll(opts.src);
|
|
16
|
+
}
|
|
17
|
+
add(src) {
|
|
18
|
+
this.ensureState();
|
|
19
|
+
this.sources.set(
|
|
20
|
+
src,
|
|
21
|
+
src.subscribe(
|
|
22
|
+
{
|
|
23
|
+
next: (x) => x instanceof Subscription ? this.add(x) : this.next(x),
|
|
24
|
+
done: () => this.markDone(src),
|
|
25
|
+
__owner: this
|
|
26
|
+
},
|
|
27
|
+
{ id: `in-${src.id}` }
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
addAll(src) {
|
|
32
|
+
for (let s of src) {
|
|
33
|
+
this.add(s);
|
|
72
34
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
35
|
+
}
|
|
36
|
+
remove(src) {
|
|
37
|
+
const sub = this.sources.get(src);
|
|
38
|
+
if (sub) {
|
|
39
|
+
this.sources.delete(src);
|
|
40
|
+
sub.unsubscribe();
|
|
41
|
+
return true;
|
|
80
42
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
removeID(id) {
|
|
46
|
+
for (let s of this.sources) {
|
|
47
|
+
if (s[0].id === id) {
|
|
48
|
+
return this.remove(s[0]);
|
|
49
|
+
}
|
|
85
50
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
return false;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
removeAll(src) {
|
|
54
|
+
let ok = true;
|
|
55
|
+
for (let s of src) {
|
|
56
|
+
ok = this.remove(s) && ok;
|
|
94
57
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
return ok;
|
|
109
|
-
}
|
|
110
|
-
removeAllIDs(ids) {
|
|
111
|
-
return __removeAllIDs(this, ids);
|
|
112
|
-
}
|
|
113
|
-
unsubscribe(sub) {
|
|
114
|
-
if (!sub) {
|
|
115
|
-
for (let s of this.sources.values()) {
|
|
116
|
-
s.unsubscribe();
|
|
117
|
-
}
|
|
118
|
-
this.state = State.DONE;
|
|
119
|
-
this.sources.clear();
|
|
120
|
-
}
|
|
121
|
-
return super.unsubscribe(sub);
|
|
122
|
-
}
|
|
123
|
-
markDone(src) {
|
|
124
|
-
this.remove(src);
|
|
125
|
-
isFirstOrLastInput(this.closeIn, this.sources.size) && this.done();
|
|
58
|
+
return ok;
|
|
59
|
+
}
|
|
60
|
+
removeAllIDs(ids) {
|
|
61
|
+
return __removeAllIDs(this, ids);
|
|
62
|
+
}
|
|
63
|
+
unsubscribe(sub) {
|
|
64
|
+
if (!sub) {
|
|
65
|
+
for (let s of this.sources.values()) {
|
|
66
|
+
s.unsubscribe();
|
|
67
|
+
}
|
|
68
|
+
this.state = State.DONE;
|
|
69
|
+
this.sources.clear();
|
|
126
70
|
}
|
|
71
|
+
return super.unsubscribe(sub);
|
|
72
|
+
}
|
|
73
|
+
markDone(src) {
|
|
74
|
+
this.remove(src);
|
|
75
|
+
isFirstOrLastInput(this.closeIn, this.sources.size) && this.done();
|
|
76
|
+
}
|
|
127
77
|
}
|
|
78
|
+
export {
|
|
79
|
+
StreamMerge,
|
|
80
|
+
merge
|
|
81
|
+
};
|
package/metastream.js
CHANGED
|
@@ -1,151 +1,75 @@
|
|
|
1
1
|
import { assert } from "@thi.ng/errors/assert";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CloseMode,
|
|
4
|
+
State
|
|
5
|
+
} from "./api.js";
|
|
3
6
|
import { __optsWithID } from "./idgen.js";
|
|
4
7
|
import { Subscription } from "./subscription.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
* ? fromIterable(tx.repeat(x, 3), { delay: 100 })
|
|
37
|
-
* : null
|
|
38
|
-
* );
|
|
39
|
-
*
|
|
40
|
-
* a.subscribe(trace())
|
|
41
|
-
* a.next(23)
|
|
42
|
-
*
|
|
43
|
-
* // 23
|
|
44
|
-
* // 23
|
|
45
|
-
* // 23
|
|
46
|
-
*
|
|
47
|
-
* a.next(42) // ignored by factory fn
|
|
48
|
-
*
|
|
49
|
-
* a.next(43)
|
|
50
|
-
* // 43
|
|
51
|
-
* // 43
|
|
52
|
-
* // 43
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```ts
|
|
57
|
-
* // infinite inputs
|
|
58
|
-
* a = fromIterable(
|
|
59
|
-
* tx.repeat("a"),
|
|
60
|
-
* { delay: 1000, closeOut: CloseMode.NEVER }
|
|
61
|
-
* );
|
|
62
|
-
* b = fromIterable(
|
|
63
|
-
* tx.repeat("b"),
|
|
64
|
-
* { delay: 1000, closeOut: CloseMode.NEVER }
|
|
65
|
-
* );
|
|
66
|
-
*
|
|
67
|
-
* // stream selector / switch
|
|
68
|
-
* m = metaStream((x) => x ? a : b);
|
|
69
|
-
* m.subscribe(trace("meta from: "));
|
|
70
|
-
*
|
|
71
|
-
* m.next(true);
|
|
72
|
-
* // meta from: a
|
|
73
|
-
*
|
|
74
|
-
* m.next(false);
|
|
75
|
-
* // meta from: b
|
|
76
|
-
*
|
|
77
|
-
* m.next(true);
|
|
78
|
-
* // meta from: a
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* @param factory -
|
|
82
|
-
* @param id -
|
|
83
|
-
*/
|
|
84
|
-
export const metaStream = (factory, opts) => new MetaStream(factory, opts);
|
|
85
|
-
/**
|
|
86
|
-
* @see {@link metaStream} for reference & examples.
|
|
87
|
-
*/
|
|
88
|
-
export class MetaStream extends Subscription {
|
|
89
|
-
factory;
|
|
90
|
-
stream;
|
|
91
|
-
sub;
|
|
92
|
-
emitLast;
|
|
93
|
-
doneRequested;
|
|
94
|
-
constructor(factory, opts = {}) {
|
|
95
|
-
super(undefined, __optsWithID("metastram", opts));
|
|
96
|
-
this.factory = factory;
|
|
97
|
-
this.emitLast = opts.emitLast === true;
|
|
98
|
-
this.doneRequested = false;
|
|
99
|
-
}
|
|
100
|
-
next(x) {
|
|
101
|
-
if (this.state < State.DONE) {
|
|
102
|
-
if (this.stream) {
|
|
103
|
-
this.stream.unsubscribe(this.sub);
|
|
104
|
-
}
|
|
105
|
-
let stream = this.factory(x);
|
|
106
|
-
if (stream) {
|
|
107
|
-
this.stream = stream;
|
|
108
|
-
this.sub = this.stream.subscribe({
|
|
109
|
-
next: (x) => {
|
|
110
|
-
stream === this.stream && super.dispatch(x);
|
|
111
|
-
this.doneRequested && this.done();
|
|
112
|
-
},
|
|
113
|
-
done: () => {
|
|
114
|
-
this.stream.unsubscribe(this.sub);
|
|
115
|
-
if (stream === this.stream) {
|
|
116
|
-
this.stream = undefined;
|
|
117
|
-
this.sub = undefined;
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
error: (e) => super.error(e),
|
|
121
|
-
__owner: this,
|
|
122
|
-
});
|
|
8
|
+
const metaStream = (factory, opts) => new MetaStream(factory, opts);
|
|
9
|
+
class MetaStream extends Subscription {
|
|
10
|
+
factory;
|
|
11
|
+
stream;
|
|
12
|
+
sub;
|
|
13
|
+
emitLast;
|
|
14
|
+
doneRequested;
|
|
15
|
+
constructor(factory, opts = {}) {
|
|
16
|
+
super(void 0, __optsWithID("metastram", opts));
|
|
17
|
+
this.factory = factory;
|
|
18
|
+
this.emitLast = opts.emitLast === true;
|
|
19
|
+
this.doneRequested = false;
|
|
20
|
+
}
|
|
21
|
+
next(x) {
|
|
22
|
+
if (this.state < State.DONE) {
|
|
23
|
+
if (this.stream) {
|
|
24
|
+
this.stream.unsubscribe(this.sub);
|
|
25
|
+
}
|
|
26
|
+
let stream = this.factory(x);
|
|
27
|
+
if (stream) {
|
|
28
|
+
this.stream = stream;
|
|
29
|
+
this.sub = this.stream.subscribe({
|
|
30
|
+
next: (x2) => {
|
|
31
|
+
stream === this.stream && super.dispatch(x2);
|
|
32
|
+
this.doneRequested && this.done();
|
|
33
|
+
},
|
|
34
|
+
done: () => {
|
|
35
|
+
this.stream.unsubscribe(this.sub);
|
|
36
|
+
if (stream === this.stream) {
|
|
37
|
+
this.stream = void 0;
|
|
38
|
+
this.sub = void 0;
|
|
123
39
|
}
|
|
124
|
-
|
|
40
|
+
},
|
|
41
|
+
error: (e) => super.error(e),
|
|
42
|
+
__owner: this
|
|
43
|
+
});
|
|
44
|
+
}
|
|
125
45
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
46
|
+
}
|
|
47
|
+
done() {
|
|
48
|
+
if (this.emitLast && !this.doneRequested) {
|
|
49
|
+
this.doneRequested = true;
|
|
50
|
+
} else {
|
|
51
|
+
if (this.stream) {
|
|
52
|
+
this.detach(true);
|
|
53
|
+
}
|
|
54
|
+
this.closeIn !== CloseMode.NEVER && super.done();
|
|
136
55
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return super.unsubscribe(sub);
|
|
56
|
+
}
|
|
57
|
+
unsubscribe(sub) {
|
|
58
|
+
if (this.stream && (!sub || this.subs.length === 1)) {
|
|
59
|
+
this.detach(!sub);
|
|
142
60
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
61
|
+
return super.unsubscribe(sub);
|
|
62
|
+
}
|
|
63
|
+
detach(force) {
|
|
64
|
+
if (force || this.closeOut !== CloseMode.NEVER) {
|
|
65
|
+
assert(!!this.stream, "input stream already removed");
|
|
66
|
+
this.stream.unsubscribe(this.sub);
|
|
67
|
+
delete this.stream;
|
|
68
|
+
delete this.sub;
|
|
150
69
|
}
|
|
70
|
+
}
|
|
151
71
|
}
|
|
72
|
+
export {
|
|
73
|
+
MetaStream,
|
|
74
|
+
metaStream
|
|
75
|
+
};
|
package/nodejs.js
CHANGED
|
@@ -1,54 +1,14 @@
|
|
|
1
1
|
import { rechunk } from "@thi.ng/transducers/rechunk";
|
|
2
2
|
import { stream } from "./stream.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const ingest = stream();
|
|
15
|
-
stdout.on("data", (data) => ingest.next(data));
|
|
16
|
-
stderr && stderr.on("data", (data) => ingest.error(data));
|
|
17
|
-
close && stdout.on("close", () => ingest.done());
|
|
18
|
-
return ingest;
|
|
3
|
+
const fromNodeJS = (stdout, stderr, close = true) => {
|
|
4
|
+
const ingest = stream();
|
|
5
|
+
stdout.on("data", (data) => ingest.next(data));
|
|
6
|
+
stderr && stderr.on("data", (data) => ingest.error(data));
|
|
7
|
+
close && stdout.on("close", () => ingest.done());
|
|
8
|
+
return ingest;
|
|
9
|
+
};
|
|
10
|
+
const linesFromNodeJS = (stdout, stderr, re, close) => fromNodeJS(stdout, stderr, close).transform(rechunk(re));
|
|
11
|
+
export {
|
|
12
|
+
fromNodeJS,
|
|
13
|
+
linesFromNodeJS
|
|
19
14
|
};
|
|
20
|
-
/**
|
|
21
|
-
* Specialized version of {@link fromNodeJS} for string inputs and automatic
|
|
22
|
-
* rechunking/splitting of the input using the optionally provided regexp (line
|
|
23
|
-
* breaks by default).
|
|
24
|
-
*
|
|
25
|
-
* @remarks
|
|
26
|
-
* Internally uses https://docs.thi.ng/umbrella/transducers/functions/rechunk.html
|
|
27
|
-
* to rechunk input.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```ts
|
|
31
|
-
* import { spawn } from "child_process"
|
|
32
|
-
* import { linesFromNodeJS, trace } from "@thi.ng/rstream";
|
|
33
|
-
*
|
|
34
|
-
* const cmd = spawn("ls", ["-la"]);
|
|
35
|
-
*
|
|
36
|
-
* linesFromNodeJS<string>(cmd.stdout, cmd.stderr).subscribe(trace("output"));
|
|
37
|
-
*
|
|
38
|
-
* // output total 12760
|
|
39
|
-
* // output drwxr-xr-x 37 foo staff 1184 Nov 15 15:29 .
|
|
40
|
-
* // output drwxr-xr-x 143 foo staff 4576 Nov 11 21:08 ..
|
|
41
|
-
* // output drwxr-xr-x 17 foo staff 544 Nov 15 17:39 .git
|
|
42
|
-
* // output -rw-r--r-- 1 foo staff 149 Aug 4 15:32 .gitattributes
|
|
43
|
-
* // output drwxr-xr-x 5 foo staff 160 Apr 12 2021 .github
|
|
44
|
-
* // output -rw-r--r-- 1 foo staff 659 Sep 10 22:55 .gitignore
|
|
45
|
-
* // ...
|
|
46
|
-
* // output done
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* @param stdout -
|
|
50
|
-
* @param stderr -
|
|
51
|
-
* @param re -
|
|
52
|
-
* @param close -
|
|
53
|
-
*/
|
|
54
|
-
export const linesFromNodeJS = (stdout, stderr, re, close) => (fromNodeJS(stdout, stderr, close).transform(rechunk(re)));
|
package/object.js
CHANGED
|
@@ -1,103 +1,39 @@
|
|
|
1
1
|
import { dedupe } from "@thi.ng/transducers/dedupe";
|
|
2
2
|
import { __nextID } from "./idgen.js";
|
|
3
3
|
import { subscription } from "./subscription.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* - `done()` - calls {@link ISubscriber.done} on all streams
|
|
33
|
-
*
|
|
34
|
-
* The optional `opts` arg is used to customize overall behavior of
|
|
35
|
-
* `fromObject` and specify shared options for *all* created streams.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* type Foo = { a?: number; b: string; };
|
|
40
|
-
*
|
|
41
|
-
* const obj = fromObject(<Foo>{ a: 1, b: "foo" })
|
|
42
|
-
*
|
|
43
|
-
* obj.streams.a.subscribe(trace("a"))
|
|
44
|
-
* // a 1
|
|
45
|
-
* obj.streams.b.subscribe(trace("b"))
|
|
46
|
-
* // b foo
|
|
47
|
-
*
|
|
48
|
-
* obj.next({ b: "bar" })
|
|
49
|
-
* // a undefined
|
|
50
|
-
* // b bar
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* const obj = fromObject(<Foo>{}, ["a", "b"], { initial: false });
|
|
56
|
-
* obj.streams.a.subscribe(trace("a"));
|
|
57
|
-
* obj.streams.b.subscribe(trace("b"));
|
|
58
|
-
*
|
|
59
|
-
* const src = subscription<Foo, Foo>();
|
|
60
|
-
* // use as subscriber
|
|
61
|
-
* src.subscribe(obj);
|
|
62
|
-
*
|
|
63
|
-
* src.next({ a: 1, b: "foo" });
|
|
64
|
-
* // a 1
|
|
65
|
-
* // b foo
|
|
66
|
-
* ```
|
|
67
|
-
*
|
|
68
|
-
* @param src -
|
|
69
|
-
* @param opts -
|
|
70
|
-
*/
|
|
71
|
-
export const fromObject = (src, opts = {}) => {
|
|
72
|
-
const id = opts.id || `obj${__nextID()}`;
|
|
73
|
-
const keys = opts.keys || Object.keys(src);
|
|
74
|
-
const _opts = opts.dedupe !== false
|
|
75
|
-
? {
|
|
76
|
-
xform: dedupe(opts.equiv || ((a, b) => a === b)),
|
|
77
|
-
...opts,
|
|
78
|
-
}
|
|
79
|
-
: opts;
|
|
80
|
-
const streams = {};
|
|
81
|
-
for (let k of keys) {
|
|
82
|
-
streams[k] = subscription(undefined, {
|
|
83
|
-
..._opts,
|
|
84
|
-
id: `${id}-${String(k)}`,
|
|
85
|
-
});
|
|
4
|
+
const fromObject = (src, opts = {}) => {
|
|
5
|
+
const id = opts.id || `obj${__nextID()}`;
|
|
6
|
+
const keys = opts.keys || Object.keys(src);
|
|
7
|
+
const _opts = opts.dedupe !== false ? {
|
|
8
|
+
xform: dedupe(opts.equiv || ((a, b) => a === b)),
|
|
9
|
+
...opts
|
|
10
|
+
} : opts;
|
|
11
|
+
const streams = {};
|
|
12
|
+
for (let k of keys) {
|
|
13
|
+
streams[k] = subscription(void 0, {
|
|
14
|
+
..._opts,
|
|
15
|
+
id: `${id}-${String(k)}`
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const res = {
|
|
19
|
+
streams,
|
|
20
|
+
next(state) {
|
|
21
|
+
for (let k of keys) {
|
|
22
|
+
const val = state[k];
|
|
23
|
+
streams[k].next(
|
|
24
|
+
opts.defaults && val === void 0 ? opts.defaults[k] : val
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
done() {
|
|
29
|
+
for (let k of keys) {
|
|
30
|
+
streams[k].done();
|
|
31
|
+
}
|
|
86
32
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
done() {
|
|
96
|
-
for (let k of keys) {
|
|
97
|
-
streams[k].done();
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
opts.initial !== false && res.next(src);
|
|
102
|
-
return res;
|
|
33
|
+
};
|
|
34
|
+
opts.initial !== false && res.next(src);
|
|
35
|
+
return res;
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
fromObject
|
|
103
39
|
};
|