@thi.ng/rstream 8.2.13 → 8.2.15
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 +15 -12
- 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/subscription.js
CHANGED
|
@@ -8,283 +8,222 @@ import { comp } from "@thi.ng/transducers/comp";
|
|
|
8
8
|
import { map } from "@thi.ng/transducers/map";
|
|
9
9
|
import { push } from "@thi.ng/transducers/push";
|
|
10
10
|
import { isReduced, unreduced } from "@thi.ng/transducers/reduced";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CloseMode,
|
|
13
|
+
State
|
|
14
|
+
} from "./api.js";
|
|
12
15
|
import { __optsWithID } from "./idgen.js";
|
|
13
16
|
import { LOGGER } from "./logger.js";
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
$sub.setState(State.ACTIVE);
|
|
115
|
-
this.last != SEMAPHORE && $sub.next(this.last);
|
|
116
|
-
return $sub;
|
|
117
|
-
}
|
|
118
|
-
transform(...args) {
|
|
119
|
-
let sub;
|
|
120
|
-
let opts;
|
|
121
|
-
if (isPlainObject(peek(args))) {
|
|
122
|
-
opts = args.pop();
|
|
123
|
-
sub = { error: opts.error };
|
|
124
|
-
}
|
|
125
|
-
return this.subscribe(sub, __optsWithID("xform", args.length > 0
|
|
126
|
-
? {
|
|
127
|
-
...opts,
|
|
128
|
-
// @ts-ignore
|
|
129
|
-
xform: comp(...args),
|
|
130
|
-
}
|
|
131
|
-
: opts));
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Syntax sugar for {@link Subscription.transform} when using a single
|
|
135
|
-
* [`map()`](https://docs.thi.ng/umbrella/transducers/functions/map.html)
|
|
136
|
-
* transducer only. The given function `fn` is used as `map`'s
|
|
137
|
-
* transformation fn.
|
|
138
|
-
*
|
|
139
|
-
* @param fn -
|
|
140
|
-
* @param opts -
|
|
141
|
-
*/
|
|
142
|
-
map(fn, opts) {
|
|
143
|
-
return this.transform(map(fn), opts || {});
|
|
144
|
-
}
|
|
145
|
-
unsubscribe(sub) {
|
|
146
|
-
return sub ? this.unsubscribeChild(sub) : this.unsubscribeSelf();
|
|
147
|
-
}
|
|
148
|
-
unsubscribeSelf() {
|
|
149
|
-
LOGGER.debug(this.id, "unsub self");
|
|
150
|
-
this.parent && this.parent.unsubscribe(this);
|
|
151
|
-
this.state < State.UNSUBSCRIBED && (this.state = State.UNSUBSCRIBED);
|
|
152
|
-
this.release();
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
unsubscribeChild(sub) {
|
|
156
|
-
LOGGER.debug(this.id, "unsub child", sub.id);
|
|
157
|
-
const idx = this.subs.indexOf(sub);
|
|
158
|
-
if (idx >= 0) {
|
|
159
|
-
this.subs.splice(idx, 1);
|
|
160
|
-
if (this.closeOut === CloseMode.FIRST ||
|
|
161
|
-
(!this.subs.length && this.closeOut !== CloseMode.NEVER)) {
|
|
162
|
-
this.unsubscribe();
|
|
163
|
-
}
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
next(x) {
|
|
169
|
-
if (this.state >= State.DONE)
|
|
170
|
-
return;
|
|
171
|
-
this.xform ? this.dispatchXform(x) : this.dispatch(x);
|
|
172
|
-
}
|
|
173
|
-
done() {
|
|
174
|
-
LOGGER.debug(this.id, "entering done()");
|
|
175
|
-
if (this.state >= State.DONE)
|
|
176
|
-
return;
|
|
177
|
-
if (this.xform) {
|
|
178
|
-
if (!this.dispatchXformDone())
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
this.state = State.DONE;
|
|
182
|
-
// attempt to call .done in wrapped sub
|
|
183
|
-
if (this.dispatchTo("done")) {
|
|
184
|
-
// disconnect from parent & internal cleanup
|
|
185
|
-
this.state < State.UNSUBSCRIBED && this.unsubscribe();
|
|
186
|
-
}
|
|
187
|
-
LOGGER.debug(this.id, "exiting done()");
|
|
188
|
-
}
|
|
189
|
-
error(e) {
|
|
190
|
-
// only the wrapped sub's error handler gets a chance
|
|
191
|
-
// to deal with the error
|
|
192
|
-
const sub = this.wrapped;
|
|
193
|
-
const hasErrorHandler = sub && sub.error;
|
|
194
|
-
hasErrorHandler &&
|
|
195
|
-
LOGGER.debug(this.id, "attempting wrapped error handler");
|
|
196
|
-
// flag success if error handler returns true
|
|
197
|
-
// (i.e. it could handle/recover from the error)
|
|
198
|
-
// else detach this entire sub by going into error state...
|
|
199
|
-
return (hasErrorHandler && sub.error(e)) || this.unhandledError(e);
|
|
200
|
-
}
|
|
201
|
-
unhandledError(e) {
|
|
202
|
-
// ensure error is at least logged to console
|
|
203
|
-
// even if default NULL_LOGGER is used...
|
|
204
|
-
(LOGGER !== NULL_LOGGER ? LOGGER : console).warn(this.id, "unhandled error:", e);
|
|
17
|
+
const subscription = (sub, opts) => new Subscription(sub, opts);
|
|
18
|
+
class Subscription {
|
|
19
|
+
constructor(wrapped, opts) {
|
|
20
|
+
this.wrapped = wrapped;
|
|
21
|
+
opts = __optsWithID(`sub`, {
|
|
22
|
+
closeIn: CloseMode.LAST,
|
|
23
|
+
closeOut: CloseMode.LAST,
|
|
24
|
+
cache: true,
|
|
25
|
+
...opts
|
|
26
|
+
});
|
|
27
|
+
this.parent = opts.parent;
|
|
28
|
+
this.id = opts.id;
|
|
29
|
+
this.closeIn = opts.closeIn;
|
|
30
|
+
this.closeOut = opts.closeOut;
|
|
31
|
+
this.cacheLast = opts.cache;
|
|
32
|
+
opts.xform && (this.xform = opts.xform(push()));
|
|
33
|
+
}
|
|
34
|
+
id;
|
|
35
|
+
closeIn;
|
|
36
|
+
closeOut;
|
|
37
|
+
parent;
|
|
38
|
+
__owner;
|
|
39
|
+
xform;
|
|
40
|
+
cacheLast;
|
|
41
|
+
last = SEMAPHORE;
|
|
42
|
+
state = State.IDLE;
|
|
43
|
+
subs = [];
|
|
44
|
+
deref() {
|
|
45
|
+
return this.last !== SEMAPHORE ? this.last : void 0;
|
|
46
|
+
}
|
|
47
|
+
getState() {
|
|
48
|
+
return this.state;
|
|
49
|
+
}
|
|
50
|
+
setState(state) {
|
|
51
|
+
this.state = state;
|
|
52
|
+
}
|
|
53
|
+
subscribe(sub, opts = {}) {
|
|
54
|
+
this.ensureState();
|
|
55
|
+
let $sub;
|
|
56
|
+
if (sub instanceof Subscription && !opts.xform) {
|
|
57
|
+
sub.ensureState();
|
|
58
|
+
assert(!sub.parent, `sub '${sub.id}' already has a parent`);
|
|
59
|
+
sub.parent = this;
|
|
60
|
+
$sub = sub;
|
|
61
|
+
} else {
|
|
62
|
+
$sub = new Subscription(sub, { ...opts, parent: this });
|
|
63
|
+
}
|
|
64
|
+
this.subs.push($sub);
|
|
65
|
+
this.setState(State.ACTIVE);
|
|
66
|
+
$sub.setState(State.ACTIVE);
|
|
67
|
+
this.last != SEMAPHORE && $sub.next(this.last);
|
|
68
|
+
return $sub;
|
|
69
|
+
}
|
|
70
|
+
transform(...args) {
|
|
71
|
+
let sub;
|
|
72
|
+
let opts;
|
|
73
|
+
if (isPlainObject(peek(args))) {
|
|
74
|
+
opts = args.pop();
|
|
75
|
+
sub = { error: opts.error };
|
|
76
|
+
}
|
|
77
|
+
return this.subscribe(
|
|
78
|
+
sub,
|
|
79
|
+
__optsWithID(
|
|
80
|
+
"xform",
|
|
81
|
+
args.length > 0 ? {
|
|
82
|
+
...opts,
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
xform: comp(...args)
|
|
85
|
+
} : opts
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Syntax sugar for {@link Subscription.transform} when using a single
|
|
91
|
+
* [`map()`](https://docs.thi.ng/umbrella/transducers/functions/map.html)
|
|
92
|
+
* transducer only. The given function `fn` is used as `map`'s
|
|
93
|
+
* transformation fn.
|
|
94
|
+
*
|
|
95
|
+
* @param fn -
|
|
96
|
+
* @param opts -
|
|
97
|
+
*/
|
|
98
|
+
map(fn, opts) {
|
|
99
|
+
return this.transform(map(fn), opts || {});
|
|
100
|
+
}
|
|
101
|
+
unsubscribe(sub) {
|
|
102
|
+
return sub ? this.unsubscribeChild(sub) : this.unsubscribeSelf();
|
|
103
|
+
}
|
|
104
|
+
unsubscribeSelf() {
|
|
105
|
+
LOGGER.debug(this.id, "unsub self");
|
|
106
|
+
this.parent && this.parent.unsubscribe(this);
|
|
107
|
+
this.state < State.UNSUBSCRIBED && (this.state = State.UNSUBSCRIBED);
|
|
108
|
+
this.release();
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
unsubscribeChild(sub) {
|
|
112
|
+
LOGGER.debug(this.id, "unsub child", sub.id);
|
|
113
|
+
const idx = this.subs.indexOf(sub);
|
|
114
|
+
if (idx >= 0) {
|
|
115
|
+
this.subs.splice(idx, 1);
|
|
116
|
+
if (this.closeOut === CloseMode.FIRST || !this.subs.length && this.closeOut !== CloseMode.NEVER) {
|
|
205
117
|
this.unsubscribe();
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
next(x) {
|
|
124
|
+
if (this.state >= State.DONE)
|
|
125
|
+
return;
|
|
126
|
+
this.xform ? this.dispatchXform(x) : this.dispatch(x);
|
|
127
|
+
}
|
|
128
|
+
done() {
|
|
129
|
+
LOGGER.debug(this.id, "entering done()");
|
|
130
|
+
if (this.state >= State.DONE)
|
|
131
|
+
return;
|
|
132
|
+
if (this.xform) {
|
|
133
|
+
if (!this.dispatchXformDone())
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
this.state = State.DONE;
|
|
137
|
+
if (this.dispatchTo("done")) {
|
|
138
|
+
this.state < State.UNSUBSCRIBED && this.unsubscribe();
|
|
139
|
+
}
|
|
140
|
+
LOGGER.debug(this.id, "exiting done()");
|
|
141
|
+
}
|
|
142
|
+
error(e) {
|
|
143
|
+
const sub = this.wrapped;
|
|
144
|
+
const hasErrorHandler = sub && sub.error;
|
|
145
|
+
hasErrorHandler && LOGGER.debug(this.id, "attempting wrapped error handler");
|
|
146
|
+
return hasErrorHandler && sub.error(e) || this.unhandledError(e);
|
|
147
|
+
}
|
|
148
|
+
unhandledError(e) {
|
|
149
|
+
(LOGGER !== NULL_LOGGER ? LOGGER : console).warn(
|
|
150
|
+
this.id,
|
|
151
|
+
"unhandled error:",
|
|
152
|
+
e
|
|
153
|
+
);
|
|
154
|
+
this.unsubscribe();
|
|
155
|
+
this.state = State.ERROR;
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
dispatchTo(type, x) {
|
|
159
|
+
let s = this.wrapped;
|
|
160
|
+
if (s) {
|
|
161
|
+
try {
|
|
162
|
+
s[type] && s[type](x);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
if (!this.error(e))
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const subs = type === "next" ? this.subs : [...this.subs];
|
|
169
|
+
for (let i = subs.length; i-- > 0; ) {
|
|
170
|
+
s = subs[i];
|
|
171
|
+
try {
|
|
172
|
+
s[type] && s[type](x);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
if (type === "error" || !s.error || !s.error(e)) {
|
|
175
|
+
return this.unhandledError(e);
|
|
235
176
|
}
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
release() {
|
|
285
|
-
this.subs.length = 0;
|
|
286
|
-
delete this.parent;
|
|
287
|
-
delete this.xform;
|
|
288
|
-
delete this.last;
|
|
289
|
-
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
dispatch(x) {
|
|
182
|
+
LOGGER.debug(this.id, "dispatch", x);
|
|
183
|
+
this.cacheLast && (this.last = x);
|
|
184
|
+
this.dispatchTo("next", x);
|
|
185
|
+
}
|
|
186
|
+
dispatchXform(x) {
|
|
187
|
+
let acc;
|
|
188
|
+
try {
|
|
189
|
+
acc = this.xform[2]([], x);
|
|
190
|
+
} catch (e) {
|
|
191
|
+
this.error(e);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.dispatchXformVals(acc)) {
|
|
195
|
+
isReduced(acc) && this.done();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
dispatchXformDone() {
|
|
199
|
+
let acc;
|
|
200
|
+
try {
|
|
201
|
+
acc = this.xform[1]([]);
|
|
202
|
+
} catch (e) {
|
|
203
|
+
return this.error(e);
|
|
204
|
+
}
|
|
205
|
+
return this.dispatchXformVals(acc);
|
|
206
|
+
}
|
|
207
|
+
dispatchXformVals(acc) {
|
|
208
|
+
const uacc = unreduced(acc);
|
|
209
|
+
for (let i = 0, n = uacc.length; i < n && this.state < State.DONE; i++) {
|
|
210
|
+
this.dispatch(uacc[i]);
|
|
211
|
+
}
|
|
212
|
+
return this.state < State.ERROR;
|
|
213
|
+
}
|
|
214
|
+
ensureState() {
|
|
215
|
+
if (this.state >= State.DONE) {
|
|
216
|
+
illegalState(`operation not allowed in state ${this.state}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
release() {
|
|
220
|
+
this.subs.length = 0;
|
|
221
|
+
delete this.parent;
|
|
222
|
+
delete this.xform;
|
|
223
|
+
delete this.last;
|
|
224
|
+
}
|
|
290
225
|
}
|
|
226
|
+
export {
|
|
227
|
+
Subscription,
|
|
228
|
+
subscription
|
|
229
|
+
};
|
package/sync-raf.js
CHANGED
|
@@ -2,73 +2,42 @@ import { isNode } from "@thi.ng/checks/is-node";
|
|
|
2
2
|
import { State } from "./api.js";
|
|
3
3
|
import { __optsWithID } from "./idgen.js";
|
|
4
4
|
import { Subscription } from "./subscription.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* // any changes to the atom will only be received by this subscription
|
|
21
|
-
* // during next RAF update cycle
|
|
22
|
-
* syncRAF(fromAtom(atom)).subscribe({
|
|
23
|
-
* next({ name }) { document.body.innerText = name; }
|
|
24
|
-
* });
|
|
25
|
-
*
|
|
26
|
-
* // trigger update
|
|
27
|
-
* atom.reset("bob");
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @param src -
|
|
31
|
-
* @param opts -
|
|
32
|
-
*/
|
|
33
|
-
export const syncRAF = (src, opts) => src.subscribe(new SyncRAF(__optsWithID(`syncraf-${src.id}`, opts)));
|
|
34
|
-
/**
|
|
35
|
-
* See {@link syncRAF} for details.
|
|
36
|
-
*/
|
|
37
|
-
export class SyncRAF extends Subscription {
|
|
38
|
-
queued;
|
|
39
|
-
raf;
|
|
40
|
-
constructor(opts) {
|
|
41
|
-
super(undefined, opts);
|
|
42
|
-
}
|
|
43
|
-
next(x) {
|
|
44
|
-
if (this.state >= State.DONE)
|
|
45
|
-
return;
|
|
46
|
-
this.queued = x;
|
|
47
|
-
if (!this.raf) {
|
|
48
|
-
const update = () => {
|
|
49
|
-
if (this.state < State.DONE)
|
|
50
|
-
super.next(this.queued);
|
|
51
|
-
this._clean();
|
|
52
|
-
};
|
|
53
|
-
this.raf = isNode()
|
|
54
|
-
? setTimeout(update, 16)
|
|
55
|
-
: requestAnimationFrame(update);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
done() {
|
|
59
|
-
this._clean();
|
|
60
|
-
super.done();
|
|
61
|
-
}
|
|
62
|
-
error(e) {
|
|
5
|
+
const syncRAF = (src, opts) => src.subscribe(new SyncRAF(__optsWithID(`syncraf-${src.id}`, opts)));
|
|
6
|
+
class SyncRAF extends Subscription {
|
|
7
|
+
queued;
|
|
8
|
+
raf;
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
super(void 0, opts);
|
|
11
|
+
}
|
|
12
|
+
next(x) {
|
|
13
|
+
if (this.state >= State.DONE)
|
|
14
|
+
return;
|
|
15
|
+
this.queued = x;
|
|
16
|
+
if (!this.raf) {
|
|
17
|
+
const update = () => {
|
|
18
|
+
if (this.state < State.DONE)
|
|
19
|
+
super.next(this.queued);
|
|
63
20
|
this._clean();
|
|
64
|
-
|
|
21
|
+
};
|
|
22
|
+
this.raf = isNode() ? setTimeout(update, 16) : requestAnimationFrame(update);
|
|
65
23
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
24
|
+
}
|
|
25
|
+
done() {
|
|
26
|
+
this._clean();
|
|
27
|
+
super.done();
|
|
28
|
+
}
|
|
29
|
+
error(e) {
|
|
30
|
+
this._clean();
|
|
31
|
+
return super.error(e);
|
|
32
|
+
}
|
|
33
|
+
_clean() {
|
|
34
|
+
if (this.raf) {
|
|
35
|
+
isNode() ? clearTimeout(this.raf) : cancelAnimationFrame(this.raf);
|
|
73
36
|
}
|
|
37
|
+
this.raf = this.queued = void 0;
|
|
38
|
+
}
|
|
74
39
|
}
|
|
40
|
+
export {
|
|
41
|
+
SyncRAF,
|
|
42
|
+
syncRAF
|
|
43
|
+
};
|