@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.
@@ -1,97 +1,44 @@
1
1
  import { peek } from "@thi.ng/arrays/peek";
2
2
  import { map } from "@thi.ng/transducers/map";
3
- import { State, } from "./api.js";
3
+ import {
4
+ State
5
+ } from "./api.js";
4
6
  import { ASidechain } from "./asidechain.js";
5
7
  import { __optsWithID } from "./idgen.js";
6
8
  import { fromRAF } from "./raf.js";
7
- /**
8
- * Returns a subscription which buffers values from `src` until side chain
9
- * delivers its next value, then emits buffer (unless empty) and repeats process
10
- * until either input is done.
11
- *
12
- * @remarks
13
- * By default, the values read from the side chain are ignored (i.e. only their
14
- * timing is used), however the `pred`icate option can be used to only trigger
15
- * for specific values / conditions.
16
- *
17
- * Also see: {@link sidechainToggle}, {@link sidechainTrigger}, {@link syncRAF}.
18
- *
19
- * @example
20
- * ```t
21
- * // merge various event streams
22
- * events = merge([
23
- * fromEvent(document,"mousemove"),
24
- * fromEvent(document,"mousedown"),
25
- * fromEvent(document,"mouseup")
26
- * ]);
27
- *
28
- * // queue event processing to only execute during the
29
- * // requestAnimationFrame cycle (RAF)
30
- * sidechainPartition(events, fromRAF()).subscribe(trace())
31
- * ```
32
- *
33
- * @param src -
34
- * @param side -
35
- * @param opts -
36
- */
37
- export const sidechainPartition = (src, side, opts) => src.subscribe(new SidechainPartition(side, opts));
38
- /**
39
- * **Deprecated** syntax sugar for one of most common {@link sidechainPartition}
40
- * use cases, to synchronize downstream processing w/ `requestAnimationFrame()`.
41
- * Please use {@link syncRAF} instead.
42
- *
43
- * @remarks
44
- * The returned subscription debounces any high frequency intra-frame input
45
- * values and (if any present), passes only most recent one downstream during
46
- * next RAF event processing.
47
- *
48
- * This example uses thi.ng/atom as state container. Also see {@link fromAtom}
49
- * and {@link syncRAF}.
50
- *
51
- * @example
52
- * ```ts
53
- * const atom = defAtom("alice");
54
- *
55
- * // any change to the atom will only be applied during next RAF update
56
- * sideChainPartitionRAF(fromAtom(atom)).subscribe({
57
- * next({ name }) { document.body.innerText = name; }
58
- * });
59
- *
60
- * // trigger update
61
- * atom.reset("bob");
62
- * ```
63
- *
64
- * @param src -
65
- *
66
- * @deprecated
67
- */
68
- export const sidechainPartitionRAF = (src) => sidechainPartition(src, fromRAF()).transform(map(peek));
69
- export class SidechainPartition extends ASidechain {
70
- buf;
71
- constructor(side, opts) {
72
- opts = __optsWithID("sidepart", opts);
73
- super(opts);
74
- const pred = opts.pred || (() => true);
75
- this.buf = [];
76
- this.sideSub = side.subscribe({
77
- next: (x) => {
78
- if (this.buf.length && pred(x)) {
79
- this.dispatch(this.buf);
80
- this.buf = [];
81
- }
82
- },
83
- done: () => {
84
- if (this.buf.length) {
85
- this.dispatch(this.buf);
86
- }
87
- this.done();
88
- delete this.buf;
89
- },
90
- });
91
- }
92
- next(x) {
93
- if (this.state < State.DONE) {
94
- this.buf.push(x);
9
+ const sidechainPartition = (src, side, opts) => src.subscribe(new SidechainPartition(side, opts));
10
+ const sidechainPartitionRAF = (src) => sidechainPartition(src, fromRAF()).transform(map(peek));
11
+ class SidechainPartition extends ASidechain {
12
+ buf;
13
+ constructor(side, opts) {
14
+ opts = __optsWithID("sidepart", opts);
15
+ super(opts);
16
+ const pred = opts.pred || (() => true);
17
+ this.buf = [];
18
+ this.sideSub = side.subscribe({
19
+ next: (x) => {
20
+ if (this.buf.length && pred(x)) {
21
+ this.dispatch(this.buf);
22
+ this.buf = [];
23
+ }
24
+ },
25
+ done: () => {
26
+ if (this.buf.length) {
27
+ this.dispatch(this.buf);
95
28
  }
29
+ this.done();
30
+ delete this.buf;
31
+ }
32
+ });
33
+ }
34
+ next(x) {
35
+ if (this.state < State.DONE) {
36
+ this.buf.push(x);
96
37
  }
38
+ }
97
39
  }
40
+ export {
41
+ SidechainPartition,
42
+ sidechainPartition,
43
+ sidechainPartitionRAF
44
+ };
@@ -1,53 +1,32 @@
1
- import { State, } from "./api.js";
1
+ import {
2
+ State
3
+ } from "./api.js";
2
4
  import { ASidechain } from "./asidechain.js";
3
5
  import { __optsWithID } from "./idgen.js";
4
- /**
5
- * Returns a subscription which filters values from `src` based on control
6
- * values received from `side` chain.
7
- *
8
- * @remarks
9
- * By default, the values read from the side chain are ignored (i.e. only their
10
- * timing is used), however the `pred`icate option can be used to only trigger
11
- * for specific values/conditions. Every time the predicate fn returns true, the
12
- * filter will be toggled on/off. Whilst switched off, no input values will be
13
- * forwarded downstream.
14
- *
15
- * @example
16
- * ```ts
17
- * // use slower interval stream to toggle faster main stream on/off
18
- * sidechainToggle(fromInterval(500), fromInterval(1000)).subscribe(trace());
19
- * // 0
20
- * // 3
21
- * // 4
22
- * // 7
23
- * // 8
24
- * ...
25
- * ```
26
- *
27
- * @param src -
28
- * @param side -
29
- * @param opts -
30
- */
31
- export const sidechainToggle = (src, side, opts) => src.subscribe(new SidechainToggle(side, opts));
32
- export class SidechainToggle extends ASidechain {
33
- isActive;
34
- constructor(side, opts) {
35
- opts = __optsWithID("sidetoggle", opts);
36
- super(opts);
37
- this.isActive = !!opts.initial;
38
- const pred = opts.pred || (() => true);
39
- this.sideSub = side.subscribe({
40
- next: (x) => {
41
- if (pred(x)) {
42
- this.isActive = !this.isActive;
43
- }
44
- },
45
- done: () => this.done(),
46
- });
47
- }
48
- next(x) {
49
- if (this.isActive && this.state < State.DONE) {
50
- super.next(x);
6
+ const sidechainToggle = (src, side, opts) => src.subscribe(new SidechainToggle(side, opts));
7
+ class SidechainToggle extends ASidechain {
8
+ isActive;
9
+ constructor(side, opts) {
10
+ opts = __optsWithID("sidetoggle", opts);
11
+ super(opts);
12
+ this.isActive = !!opts.initial;
13
+ const pred = opts.pred || (() => true);
14
+ this.sideSub = side.subscribe({
15
+ next: (x) => {
16
+ if (pred(x)) {
17
+ this.isActive = !this.isActive;
51
18
  }
19
+ },
20
+ done: () => this.done()
21
+ });
22
+ }
23
+ next(x) {
24
+ if (this.isActive && this.state < State.DONE) {
25
+ super.next(x);
52
26
  }
27
+ }
53
28
  }
29
+ export {
30
+ SidechainToggle,
31
+ sidechainToggle
32
+ };
@@ -1,66 +1,32 @@
1
1
  import { SEMAPHORE } from "@thi.ng/api/api";
2
- import { State, } from "./api.js";
2
+ import {
3
+ State
4
+ } from "./api.js";
3
5
  import { ASidechain } from "./asidechain.js";
4
6
  import { __optsWithID } from "./idgen.js";
5
- /**
6
- * Returns a subscription which buffers the most recent value received from
7
- * `src` and only forwards it downstream whenever a new control value is
8
- * received from the `side` chain.
9
- *
10
- * @remarks
11
- * By default, the values read from the side chain are ignored (i.e. only their
12
- * timing is used), however the `pred`icate option can be used to only trigger
13
- * for specific values/conditions. Every time the predicate fn returns true AND
14
- * if `src` already has delivered at least one value, it will be forwarded
15
- * downstream.
16
- *
17
- * @example
18
- * ```ts
19
- * const src = reactive("payload");
20
- *
21
- * const side = stream();
22
- *
23
- * sidechainTrigger(src, side).subscribe(trace("data:"));
24
- *
25
- * side.next(1);
26
- * // data: payload
27
- *
28
- * side.next(1);
29
- * // data: payload
30
- *
31
- * // only newest value will be buffered
32
- * src.next("update #1");
33
- * src.next("update #2");
34
- *
35
- * // ...until side chain triggers again
36
- * side.next(1);
37
- * // data: update #2
38
- * ...
39
- * ```
40
- *
41
- * @param src
42
- * @param side
43
- * @param opts
44
- */
45
- export const sidechainTrigger = (src, side, opts) => src.subscribe(new SidechainTrigger(side, opts));
46
- export class SidechainTrigger extends ASidechain {
47
- buf = SEMAPHORE;
48
- constructor(side, opts) {
49
- opts = __optsWithID("sidetrigger", opts);
50
- super(opts);
51
- const pred = opts.pred || (() => true);
52
- this.sideSub = side.subscribe({
53
- next: (x) => {
54
- if (this.buf !== SEMAPHORE && pred(x)) {
55
- this.dispatch(this.buf);
56
- }
57
- },
58
- done: () => this.done(),
59
- });
60
- }
61
- next(x) {
62
- if (this.state < State.DONE) {
63
- this.buf = x;
7
+ const sidechainTrigger = (src, side, opts) => src.subscribe(new SidechainTrigger(side, opts));
8
+ class SidechainTrigger extends ASidechain {
9
+ buf = SEMAPHORE;
10
+ constructor(side, opts) {
11
+ opts = __optsWithID("sidetrigger", opts);
12
+ super(opts);
13
+ const pred = opts.pred || (() => true);
14
+ this.sideSub = side.subscribe({
15
+ next: (x) => {
16
+ if (this.buf !== SEMAPHORE && pred(x)) {
17
+ this.dispatch(this.buf);
64
18
  }
19
+ },
20
+ done: () => this.done()
21
+ });
22
+ }
23
+ next(x) {
24
+ if (this.state < State.DONE) {
25
+ this.buf = x;
65
26
  }
27
+ }
66
28
  }
29
+ export {
30
+ SidechainTrigger,
31
+ sidechainTrigger
32
+ };
package/stream.js CHANGED
@@ -1,85 +1,78 @@
1
1
  import { isFunction } from "@thi.ng/checks/is-function";
2
- import { CloseMode, } from "./api.js";
2
+ import {
3
+ CloseMode
4
+ } from "./api.js";
3
5
  import { __optsWithID } from "./idgen.js";
4
6
  import { LOGGER } from "./logger.js";
5
7
  import { Subscription } from "./subscription.js";
6
- export function stream(src, opts) {
7
- return new Stream(src, opts);
8
+ function stream(src, opts) {
9
+ return new Stream(src, opts);
8
10
  }
9
- /**
10
- * Syntax sugar for {@link stream}. Creates new stream which is
11
- * immediately seeded with initial `val` and configured with optional
12
- * `opts`.
13
- *
14
- * @param val -
15
- * @param opts -
16
- */
17
- export const reactive = (val, opts) => {
18
- const res = new Stream(opts);
19
- res.next(val);
20
- return res;
11
+ const reactive = (val, opts) => {
12
+ const res = new Stream(opts);
13
+ res.next(val);
14
+ return res;
21
15
  };
22
- /**
23
- * @see {@link stream} & {@link reactive} for reference & examples.
24
- */
25
- export class Stream extends Subscription {
26
- src;
27
- _cancel;
28
- _inited;
29
- constructor(src, opts) {
30
- const [_src, _opts] = isFunction(src)
31
- ? [src, opts || {}]
32
- : [undefined, src || {}];
33
- super(_opts.error ? { error: _opts.error } : undefined, __optsWithID("stream", _opts));
34
- this.src = _src;
35
- this._inited = false;
36
- }
37
- subscribe(sub, opts = {}) {
38
- const $sub = super.subscribe(sub, opts);
39
- if (!this._inited) {
40
- if (this.src) {
41
- try {
42
- this._cancel = this.src(this) || (() => void 0);
43
- }
44
- catch (e) {
45
- let s = this.wrapped;
46
- if (!s || !s.error || !s.error(e)) {
47
- this.unhandledError(e);
48
- }
49
- }
50
- }
51
- this._inited = true;
52
- }
53
- return $sub;
54
- }
55
- unsubscribe(sub) {
56
- const res = super.unsubscribe(sub);
57
- if (res &&
58
- (!sub ||
59
- ((!this.subs || !this.subs.length) &&
60
- this.closeOut !== CloseMode.NEVER))) {
61
- this.cancel();
16
+ class Stream extends Subscription {
17
+ src;
18
+ _cancel;
19
+ _inited;
20
+ constructor(src, opts) {
21
+ const [_src, _opts] = isFunction(src) ? [src, opts || {}] : [void 0, src || {}];
22
+ super(
23
+ _opts.error ? { error: _opts.error } : void 0,
24
+ __optsWithID("stream", _opts)
25
+ );
26
+ this.src = _src;
27
+ this._inited = false;
28
+ }
29
+ subscribe(sub, opts = {}) {
30
+ const $sub = super.subscribe(sub, opts);
31
+ if (!this._inited) {
32
+ if (this.src) {
33
+ try {
34
+ this._cancel = this.src(this) || (() => void 0);
35
+ } catch (e) {
36
+ let s = this.wrapped;
37
+ if (!s || !s.error || !s.error(e)) {
38
+ this.unhandledError(e);
39
+ }
62
40
  }
63
- return res;
41
+ }
42
+ this._inited = true;
64
43
  }
65
- done() {
66
- this.cancel();
67
- super.done();
68
- delete this.src;
69
- delete this._cancel;
44
+ return $sub;
45
+ }
46
+ unsubscribe(sub) {
47
+ const res = super.unsubscribe(sub);
48
+ if (res && (!sub || (!this.subs || !this.subs.length) && this.closeOut !== CloseMode.NEVER)) {
49
+ this.cancel();
70
50
  }
71
- error(e) {
72
- if (super.error(e))
73
- return true;
74
- this.cancel();
75
- return false;
76
- }
77
- cancel() {
78
- if (this._cancel) {
79
- LOGGER.debug(this.id, "cancel");
80
- const f = this._cancel;
81
- delete this._cancel;
82
- f();
83
- }
51
+ return res;
52
+ }
53
+ done() {
54
+ this.cancel();
55
+ super.done();
56
+ delete this.src;
57
+ delete this._cancel;
58
+ }
59
+ error(e) {
60
+ if (super.error(e))
61
+ return true;
62
+ this.cancel();
63
+ return false;
64
+ }
65
+ cancel() {
66
+ if (this._cancel) {
67
+ LOGGER.debug(this.id, "cancel");
68
+ const f = this._cancel;
69
+ delete this._cancel;
70
+ f();
84
71
  }
72
+ }
85
73
  }
74
+ export {
75
+ Stream,
76
+ reactive,
77
+ stream
78
+ };