@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/tunnel.js CHANGED
@@ -3,68 +3,61 @@ import { __nextID } from "./idgen.js";
3
3
  import { LOGGER } from "./logger.js";
4
4
  import { Subscription } from "./subscription.js";
5
5
  import { defWorker } from "./defworker.js";
6
- /**
7
- * Returns a {@link Subscription} which processes received values via
8
- * the configured worker(s) and then passes values received back from
9
- * the worker(s) downstream, thereby allowing workers to be used
10
- * transparently for stream processing.
11
- *
12
- * @remarks
13
- * Multiple worker instances are supported for concurrent processing.
14
- * See the {@link TunnelOpts} for details.
15
- *
16
- * Also see {@link forkJoin} and {@link postWorker}.
17
- *
18
- * @param opts -
19
- */
20
- export const tunnel = (opts) => new Tunnel(opts);
21
- /**
22
- * @see {@link tunnel} for reference & examples.
23
- */
24
- export class Tunnel extends Subscription {
25
- workers;
26
- src;
27
- transferables;
28
- terminate;
29
- interrupt;
30
- index;
31
- constructor(opts) {
32
- super(undefined, { id: opts.id || `tunnel-${__nextID()}` });
33
- this.src = opts.src;
34
- this.workers = new Array(opts.maxWorkers || 1);
35
- this.transferables = opts.transferables;
36
- this.terminate = opts.terminate || 1000;
37
- this.interrupt = opts.interrupt || false;
38
- this.index = 0;
6
+ const tunnel = (opts) => new Tunnel(opts);
7
+ class Tunnel extends Subscription {
8
+ workers;
9
+ src;
10
+ transferables;
11
+ terminate;
12
+ interrupt;
13
+ index;
14
+ constructor(opts) {
15
+ super(void 0, { id: opts.id || `tunnel-${__nextID()}` });
16
+ this.src = opts.src;
17
+ this.workers = new Array(opts.maxWorkers || 1);
18
+ this.transferables = opts.transferables;
19
+ this.terminate = opts.terminate || 1e3;
20
+ this.interrupt = opts.interrupt || false;
21
+ this.index = 0;
22
+ }
23
+ next(x) {
24
+ if (this.state < State.DONE) {
25
+ let tx;
26
+ if (this.transferables) {
27
+ tx = this.transferables(x);
28
+ }
29
+ let worker = this.workers[this.index];
30
+ if (this.interrupt && worker) {
31
+ worker.terminate();
32
+ worker = null;
33
+ }
34
+ if (!worker) {
35
+ this.workers[this.index++] = worker = defWorker(this.src);
36
+ this.index %= this.workers.length;
37
+ worker.addEventListener(
38
+ "message",
39
+ (e) => this.dispatch(e.data)
40
+ );
41
+ worker.addEventListener(
42
+ "error",
43
+ (e) => this.error(e)
44
+ );
45
+ }
46
+ worker.postMessage(x, tx || []);
39
47
  }
40
- next(x) {
41
- if (this.state < State.DONE) {
42
- let tx;
43
- if (this.transferables) {
44
- tx = this.transferables(x);
45
- }
46
- let worker = this.workers[this.index];
47
- if (this.interrupt && worker) {
48
- worker.terminate();
49
- worker = null;
50
- }
51
- if (!worker) {
52
- this.workers[this.index++] = worker = defWorker(this.src);
53
- this.index %= this.workers.length;
54
- worker.addEventListener("message", (e) => this.dispatch(e.data));
55
- worker.addEventListener("error", (e) => this.error(e));
56
- }
57
- worker.postMessage(x, tx || []);
58
- }
59
- }
60
- done() {
61
- super.done();
62
- if (this.terminate > 0) {
63
- setTimeout(() => {
64
- LOGGER.info("terminating workers...");
65
- this.workers.forEach((worker) => worker && worker.terminate());
66
- delete this.workers;
67
- }, this.terminate);
68
- }
48
+ }
49
+ done() {
50
+ super.done();
51
+ if (this.terminate > 0) {
52
+ setTimeout(() => {
53
+ LOGGER.info("terminating workers...");
54
+ this.workers.forEach((worker) => worker && worker.terminate());
55
+ delete this.workers;
56
+ }, this.terminate);
69
57
  }
58
+ }
70
59
  }
60
+ export {
61
+ Tunnel,
62
+ tunnel
63
+ };
package/tween.js CHANGED
@@ -6,79 +6,29 @@ import { CloseMode } from "./api.js";
6
6
  import { fromInterval } from "./interval.js";
7
7
  import { fromRAF } from "./raf.js";
8
8
  import { sync } from "./sync.js";
9
- /**
10
- * Takes an existing stream/subscription `src` and attaches new
11
- * subscription which interpolates between incoming values from `src`
12
- * using the given `mix` function.
13
- *
14
- * @remarks
15
- * The returned construct produces values at a rate controlled by the
16
- * `clock` stream or frequency. If omitted, `clock` defaults to
17
- * {@link fromRAF} (~60Hz). If the `clock` is given as number, creates a
18
- * {@link fromInterval} or else uses the given `clock` stream directly.
19
- * In general, the frequency of the `clock` should always be higher than
20
- * that of `src` or else interpolation will have undefined behavior.
21
- *
22
- * If `stop` is given as well, no values will be passed downstream if
23
- * that function returns true. This can be used to limit traffic once
24
- * the tween target value has been reached.
25
- *
26
- * The returned subscription closes automatically when either `src` or
27
- * `clock` are exhausted.
28
- *
29
- * @example
30
- * ```ts
31
- * val = stream();
32
- *
33
- * tween(
34
- * // consume from `val` stream
35
- * val,
36
- * // initial start value to interpolate from
37
- * 0,
38
- * // interpolation fn (LERP)
39
- * (a, b) => a + (b - a) * 0.5,
40
- * // stop emitting values if difference to previous result < 0.01
41
- * (a, b) => Math.abs(a - b) < 0.01
42
- * ).subscribe(trace("tweened"))
43
- *
44
- * a.next(10)
45
- * // 5
46
- * // 7.5
47
- * // ...
48
- * // 9.98046875
49
- *
50
- * a.next(100)
51
- * // 55
52
- * // 77.5
53
- * // ...
54
- * // 99.989013671875
55
- * ```
56
- *
57
- * @param src -
58
- * @param initial -
59
- * @param mix -
60
- * @param stop -
61
- * @param clock -
62
- */
63
- export const tween = (src, initial, mix, stop, clock) => sync({
64
- src: {
65
- src,
66
- _: clock == null
67
- ? fromRAF()
68
- : isNumber(clock)
69
- ? fromInterval(clock)
70
- : clock,
71
- },
72
- closeIn: CloseMode.FIRST,
73
- }).transform(scan(reducer(() => initial, (acc, { src }) => mix(acc, src))), dedupe(stop || (() => false)));
74
- /**
75
- * Convenience version of {@link tween} for its most common use case, tweening
76
- * of numeric streams.
77
- *
78
- * @param src -
79
- * @param init -
80
- * @param speed -
81
- * @param eps -
82
- * @param clock -
83
- */
84
- export 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);
9
+ const tween = (src, initial, mix, stop, clock) => sync({
10
+ src: {
11
+ src,
12
+ _: clock == null ? fromRAF() : isNumber(clock) ? fromInterval(clock) : clock
13
+ },
14
+ closeIn: CloseMode.FIRST
15
+ }).transform(
16
+ scan(
17
+ reducer(
18
+ () => initial,
19
+ (acc, { src: src2 }) => mix(acc, src2)
20
+ )
21
+ ),
22
+ dedupe(stop || (() => false))
23
+ );
24
+ const tweenNumber = (src, init = 0, speed = 0.05, eps = 1e-3, clock) => tween(
25
+ src,
26
+ init,
27
+ (a, b) => a + (b - a) * speed,
28
+ (a, b) => Math.abs(a - b) < eps,
29
+ clock
30
+ );
31
+ export {
32
+ tween,
33
+ tweenNumber
34
+ };
package/view.js CHANGED
@@ -1,47 +1,26 @@
1
1
  import { View } from "@thi.ng/atom/view";
2
2
  import { __optsWithID } from "./idgen.js";
3
3
  import { Stream } from "./stream.js";
4
- /**
5
- * Unchecked version of {@link fromView}. Paths can be given as string
6
- * or tuple.
7
-
8
- * @example
9
- * ```ts
10
- * const db = defAtom<any>({ a: 1, b: { c: 2 }});
11
- *
12
- * // create stream of `c` value changes
13
- * fromViewUnsafe(
14
- * db,
15
- * {
16
- * path: "b.c",
17
- * tx: (x) => x != null ? String(x) : "n/a"
18
- * }
19
- * ).subscribe(trace("view:"))
20
- * // view: 2
21
- *
22
- * // update `c` in state
23
- * db.swapInUnsafe("b.c", (x: number) => x + 1);
24
- * // view: 3
25
- *
26
- * db.reset({ a: 10 });
27
- * // view: n/a
28
- * ```
29
- *
30
- * @param atom -
31
- * @param opts -
32
- */
33
- export const fromViewUnsafe = (atom, opts) => fromView(atom, opts);
34
- export function fromView(atom, opts) {
35
- opts = __optsWithID("view", opts);
36
- return new Stream((stream) => {
37
- let isActive = true;
38
- const tx = opts.tx;
39
- const view = new View(atom, opts.path, tx
40
- ? (x) => isActive && ((x = tx(x)), stream.next(x), x)
41
- : (x) => isActive && (stream.next(x), x), false, opts.equiv);
42
- return () => {
43
- isActive = false;
44
- view.release();
45
- };
46
- }, opts);
4
+ const fromViewUnsafe = (atom, opts) => fromView(atom, opts);
5
+ function fromView(atom, opts) {
6
+ opts = __optsWithID("view", opts);
7
+ return new Stream((stream) => {
8
+ let isActive = true;
9
+ const tx = opts.tx;
10
+ const view = new View(
11
+ atom,
12
+ opts.path,
13
+ tx ? (x) => isActive && (x = tx(x), stream.next(x), x) : (x) => isActive && (stream.next(x), x),
14
+ false,
15
+ opts.equiv
16
+ );
17
+ return () => {
18
+ isActive = false;
19
+ view.release();
20
+ };
21
+ }, opts);
47
22
  }
23
+ export {
24
+ fromView,
25
+ fromViewUnsafe
26
+ };
package/worker.js CHANGED
@@ -2,48 +2,28 @@ import { defWorker } from "./defworker.js";
2
2
  import { __optsWithID } from "./idgen.js";
3
3
  import { LOGGER } from "./logger.js";
4
4
  import { stream } from "./stream.js";
5
- /**
6
- * Returns a {@link Stream} which adds `message` and `error` event
7
- * listeners to given `worker` and then emits received values.
8
- *
9
- * @remarks
10
- * If `terminate` is true (default), the worker will be terminated when
11
- * the stream is being closed (either directly or indirectly, i.e. if
12
- * the user called {@link ISubscriber.done} on the stream or the last
13
- * child subscription has unsubscribed, depending on
14
- * {@link CommonOpts | config options}).
15
- *
16
- * As with {@link postWorker}, the `worker` can be an existing `Worker`
17
- * instance, a JS source code `Blob` or an URL string. In the latter two
18
- * cases, a worker is created automatically.
19
- *
20
- * @example
21
- * ```ts
22
- *
23
- * ```
24
- *
25
- * @param worker -
26
- * @param opts -
27
- */
28
- export const fromWorker = (worker, opts) => {
29
- const _worker = defWorker(worker);
30
- opts = __optsWithID("worker", opts);
31
- return stream((stream) => {
32
- const msgListener = (e) => {
33
- stream.next(e.data);
34
- };
35
- const errListener = (e) => {
36
- stream.error(e.data);
37
- };
38
- _worker.addEventListener("message", msgListener);
39
- _worker.addEventListener("error", errListener);
40
- return () => {
41
- _worker.removeEventListener("message", msgListener);
42
- _worker.removeEventListener("error", errListener);
43
- if (opts.terminate !== false) {
44
- LOGGER.info("terminating worker", _worker);
45
- _worker.terminate();
46
- }
47
- };
48
- }, opts);
5
+ const fromWorker = (worker, opts) => {
6
+ const _worker = defWorker(worker);
7
+ opts = __optsWithID("worker", opts);
8
+ return stream((stream2) => {
9
+ const msgListener = (e) => {
10
+ stream2.next(e.data);
11
+ };
12
+ const errListener = (e) => {
13
+ stream2.error(e.data);
14
+ };
15
+ _worker.addEventListener("message", msgListener);
16
+ _worker.addEventListener("error", errListener);
17
+ return () => {
18
+ _worker.removeEventListener("message", msgListener);
19
+ _worker.removeEventListener("error", errListener);
20
+ if (opts.terminate !== false) {
21
+ LOGGER.info("terminating worker", _worker);
22
+ _worker.terminate();
23
+ }
24
+ };
25
+ }, opts);
26
+ };
27
+ export {
28
+ fromWorker
49
29
  };