@thi.ng/rstream 7.2.45 → 8.0.0

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/raf.d.ts CHANGED
@@ -1,15 +1,26 @@
1
1
  import type { CommonOpts } from "./api.js";
2
+ export interface FromRAFOpts extends CommonOpts {
3
+ /**
4
+ * Browser only. If true (default: false), passes the timestamps received
5
+ * via `requestAnimationFrame()` as stream values. If false, a simple
6
+ * counter [0..∞) will be emitted.
7
+ *
8
+ * @defaultValue false
9
+ */
10
+ timestamp: boolean;
11
+ }
2
12
  /**
3
- * Yields {@link Stream} of a monotonically increasing counter,
4
- * triggered by a `requestAnimationFrame()` loop (only available in
5
- * browser environments).
13
+ * Yields {@link Stream} of a monotonically increasing counter (or timestamps),
14
+ * triggered by a `requestAnimationFrame()` loop (only available in browser
15
+ * environments).
6
16
  *
7
17
  * @remarks
8
- * In NodeJS, this function falls back to {@link fromInterval}, yielding
9
- * a similar (approx. 60Hz) stream.
18
+ * In NodeJS, this function falls back to {@link fromInterval}, yielding a
19
+ * similar (approx. 60Hz) stream (the {@link FromRAFOpts.timestamp} option will
20
+ * be ignored).
10
21
  *
11
- * All subscribers to this stream will be processed during that same
12
- * loop iteration.
22
+ * All subscribers to this stream will be processed during that same RAF loop
23
+ * iteration.
13
24
  */
14
- export declare const fromRAF: (opts?: Partial<CommonOpts>) => import("./stream.js").Stream<number>;
25
+ export declare const fromRAF: (opts?: Partial<FromRAFOpts>) => import("./stream.js").Stream<number>;
15
26
  //# sourceMappingURL=raf.d.ts.map
package/raf.js CHANGED
@@ -3,24 +3,25 @@ import { __optsWithID } from "./idgen.js";
3
3
  import { fromInterval } from "./interval.js";
4
4
  import { stream } from "./stream.js";
5
5
  /**
6
- * Yields {@link Stream} of a monotonically increasing counter,
7
- * triggered by a `requestAnimationFrame()` loop (only available in
8
- * browser environments).
6
+ * Yields {@link Stream} of a monotonically increasing counter (or timestamps),
7
+ * triggered by a `requestAnimationFrame()` loop (only available in browser
8
+ * environments).
9
9
  *
10
10
  * @remarks
11
- * In NodeJS, this function falls back to {@link fromInterval}, yielding
12
- * a similar (approx. 60Hz) stream.
11
+ * In NodeJS, this function falls back to {@link fromInterval}, yielding a
12
+ * similar (approx. 60Hz) stream (the {@link FromRAFOpts.timestamp} option will
13
+ * be ignored).
13
14
  *
14
- * All subscribers to this stream will be processed during that same
15
- * loop iteration.
15
+ * All subscribers to this stream will be processed during that same RAF loop
16
+ * iteration.
16
17
  */
17
- export const fromRAF = (opts) => isNode()
18
+ export const fromRAF = (opts = {}) => isNode()
18
19
  ? fromInterval(16, opts)
19
20
  : stream((stream) => {
20
21
  let i = 0;
21
22
  let isActive = true;
22
- const loop = () => {
23
- isActive && stream.next(i++);
23
+ const loop = (time) => {
24
+ isActive && stream.next(opts.timestamp ? time : i++);
24
25
  isActive && (id = requestAnimationFrame(loop));
25
26
  };
26
27
  let id = requestAnimationFrame(loop);
@@ -1,19 +1,20 @@
1
1
  import type { Predicate } from "@thi.ng/api";
2
- import { CommonOpts, ISubscribable } from "./api.js";
2
+ import { type CommonOpts, type ISubscribable, type ISubscription } from "./api.js";
3
3
  import { ASidechain } from "./asidechain.js";
4
- import type { Subscription } from "./subscription.js";
5
4
  export interface SidechainPartitionOpts<T> extends CommonOpts {
6
5
  pred: Predicate<T>;
7
6
  }
8
7
  /**
9
- * Returns a {@link Subscription} which buffers values from `src` until
10
- * side chain fires, then emits buffer (unless empty) and repeats
11
- * process until either input is done.
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.
12
11
  *
13
12
  * @remarks
14
- * By default, the values read from the side chain are ignored (i.e.
15
- * only their timing is used), however the `pred`icate option can be
16
- * used to only trigger for specific values / conditions.
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}.
17
18
  *
18
19
  * @example
19
20
  * ```t
@@ -26,23 +27,45 @@ export interface SidechainPartitionOpts<T> extends CommonOpts {
26
27
  *
27
28
  * // queue event processing to only execute during the
28
29
  * // requestAnimationFrame cycle (RAF)
29
- * events.subscribe(sidechainPartition(fromRAF())).subscribe(trace())
30
+ * sidechainPartition(events, fromRAF()).subscribe(trace())
30
31
  * ```
31
32
  *
33
+ * @param src -
32
34
  * @param side -
33
35
  * @param opts -
34
36
  */
35
- export declare const sidechainPartition: <A, B>(side: ISubscribable<B>, opts?: Partial<SidechainPartitionOpts<B>> | undefined) => Subscription<A, A[]>;
37
+ export declare const sidechainPartition: <T, S>(src: ISubscribable<T>, side: ISubscribable<S>, opts?: Partial<SidechainPartitionOpts<S>> | undefined) => ISubscription<T, T[]>;
36
38
  /**
37
- * Syntax sugar for one of most common {@link sidechainPartition} use cases, to
38
- * synchronize downstream processing w/ `requestAnimationFrame()`. The returned
39
- * subscription debounces any high frequency intra-frame input values and (if
40
- * any present), passes only most recent one downstream *during* next RAF event
41
- * processing.
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
+ * ```
42
63
  *
43
64
  * @param src -
65
+ *
66
+ * @deprecated
44
67
  */
45
- export declare const sidechainPartitionRAF: <T>(src: ISubscribable<T>) => import("./api.js").ISubscription<T[], T>;
68
+ export declare const sidechainPartitionRAF: <T>(src: ISubscribable<T>) => ISubscription<T[], T>;
46
69
  export declare class SidechainPartition<T, S> extends ASidechain<T, S, T[]> {
47
70
  buf: T[];
48
71
  constructor(side: ISubscribable<S>, opts?: Partial<SidechainPartitionOpts<S>>);
@@ -1,18 +1,20 @@
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 { State, } from "./api.js";
4
4
  import { ASidechain } from "./asidechain.js";
5
5
  import { __optsWithID } from "./idgen.js";
6
6
  import { fromRAF } from "./raf.js";
7
7
  /**
8
- * Returns a {@link Subscription} which buffers values from `src` until
9
- * side chain fires, then emits buffer (unless empty) and repeats
10
- * process until either input is done.
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
11
  *
12
12
  * @remarks
13
- * By default, the values read from the side chain are ignored (i.e.
14
- * only their timing is used), however the `pred`icate option can be
15
- * used to only trigger for specific values / conditions.
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}.
16
18
  *
17
19
  * @example
18
20
  * ```t
@@ -25,45 +27,64 @@ import { fromRAF } from "./raf.js";
25
27
  *
26
28
  * // queue event processing to only execute during the
27
29
  * // requestAnimationFrame cycle (RAF)
28
- * events.subscribe(sidechainPartition(fromRAF())).subscribe(trace())
30
+ * sidechainPartition(events, fromRAF()).subscribe(trace())
29
31
  * ```
30
32
  *
33
+ * @param src -
31
34
  * @param side -
32
35
  * @param opts -
33
36
  */
34
- export const sidechainPartition = (side, opts) => new SidechainPartition(side, opts);
37
+ export const sidechainPartition = (src, side, opts) => src.subscribe(new SidechainPartition(side, opts));
35
38
  /**
36
- * Syntax sugar for one of most common {@link sidechainPartition} use cases, to
37
- * synchronize downstream processing w/ `requestAnimationFrame()`. The returned
38
- * subscription debounces any high frequency intra-frame input values and (if
39
- * any present), passes only most recent one downstream *during* next RAF event
40
- * processing.
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
+ * ```
41
63
  *
42
64
  * @param src -
65
+ *
66
+ * @deprecated
43
67
  */
44
- export const sidechainPartitionRAF = (src) => src
45
- .subscribe(sidechainPartition(fromRAF()))
46
- .transform(map(peek));
68
+ export const sidechainPartitionRAF = (src) => sidechainPartition(src, fromRAF()).transform(map(peek));
47
69
  export class SidechainPartition extends ASidechain {
48
70
  constructor(side, opts) {
49
71
  opts = __optsWithID("sidepart", opts);
50
72
  super(opts);
51
- this.buf = [];
52
73
  const pred = opts.pred || (() => true);
53
- const $this = this;
74
+ this.buf = [];
54
75
  this.sideSub = side.subscribe({
55
- next(x) {
56
- if ($this.buf.length && pred(x)) {
57
- $this.dispatch($this.buf);
58
- $this.buf = [];
76
+ next: (x) => {
77
+ if (this.buf.length && pred(x)) {
78
+ this.dispatch(this.buf);
79
+ this.buf = [];
59
80
  }
60
81
  },
61
- done() {
62
- if ($this.buf.length) {
63
- $this.dispatch($this.buf);
82
+ done: () => {
83
+ if (this.buf.length) {
84
+ this.dispatch(this.buf);
64
85
  }
65
- $this.done();
66
- delete $this.buf;
86
+ this.done();
87
+ delete this.buf;
67
88
  },
68
89
  });
69
90
  }
@@ -1,28 +1,25 @@
1
1
  import type { Predicate } from "@thi.ng/api";
2
- import { CommonOpts, ISubscribable } from "./api.js";
2
+ import { type CommonOpts, type ISubscribable, type ISubscription } from "./api.js";
3
3
  import { ASidechain } from "./asidechain.js";
4
- import type { Subscription } from "./subscription.js";
5
4
  export interface SidechainToggleOpts<T> extends CommonOpts {
6
5
  pred: Predicate<T>;
7
6
  initial: boolean;
8
7
  }
9
8
  /**
10
- * Returns {@link Subscription} which filters values from input based on
11
- * values received from side chain.
9
+ * Returns a subscription which filters values from `src` based on control
10
+ * values received from `side` chain.
12
11
  *
13
12
  * @remarks
14
- * By default, the value read from the side chain is ignored (i.e. only
15
- * their timing is used), however the `pred`icate option can be used to
16
- * only trigger for specific values/conditions. Every time the predicate
17
- * fn returns true, the filter will be toggled on/off. Whilst switched
18
- * off, no input values will be forwarded.
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. Every time the predicate fn returns true, the
16
+ * filter will be toggled on/off. Whilst switched off, no input values will be
17
+ * forwarded downstream.
19
18
  *
20
19
  * @example
21
20
  * ```ts
22
- * // use slower interval stream to toggle main stream on/off
23
- * fromInterval(500)
24
- * .subscribe(sidechainToggle(fromInterval(1000)))
25
- * .subscribe(trace());
21
+ * // use slower interval stream to toggle faster main stream on/off
22
+ * sidechainToggle(fromInterval(500), fromInterval(1000)).subscribe(trace());
26
23
  * // 0
27
24
  * // 3
28
25
  * // 4
@@ -31,10 +28,11 @@ export interface SidechainToggleOpts<T> extends CommonOpts {
31
28
  * ...
32
29
  * ```
33
30
  *
31
+ * @param src -
34
32
  * @param side -
35
33
  * @param opts -
36
34
  */
37
- export declare const sidechainToggle: <A, B>(side: ISubscribable<B>, opts?: Partial<SidechainToggleOpts<B>> | undefined) => Subscription<A, A>;
35
+ export declare const sidechainToggle: <T, S>(src: ISubscribable<T>, side: ISubscribable<S>, opts?: Partial<SidechainToggleOpts<S>> | undefined) => ISubscription<T, T>;
38
36
  export declare class SidechainToggle<T, S> extends ASidechain<T, S, T> {
39
37
  isActive: boolean;
40
38
  constructor(side: ISubscribable<S>, opts?: Partial<SidechainToggleOpts<S>>);
@@ -1,23 +1,21 @@
1
- import { State } from "./api.js";
1
+ import { State, } from "./api.js";
2
2
  import { ASidechain } from "./asidechain.js";
3
3
  import { __optsWithID } from "./idgen.js";
4
4
  /**
5
- * Returns {@link Subscription} which filters values from input based on
6
- * values received from side chain.
5
+ * Returns a subscription which filters values from `src` based on control
6
+ * values received from `side` chain.
7
7
  *
8
8
  * @remarks
9
- * By default, the value read from the side chain is ignored (i.e. only
10
- * their timing is used), however the `pred`icate option can be used to
11
- * only trigger for specific values/conditions. Every time the predicate
12
- * fn returns true, the filter will be toggled on/off. Whilst switched
13
- * off, no input values will be forwarded.
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
14
  *
15
15
  * @example
16
16
  * ```ts
17
- * // use slower interval stream to toggle main stream on/off
18
- * fromInterval(500)
19
- * .subscribe(sidechainToggle(fromInterval(1000)))
20
- * .subscribe(trace());
17
+ * // use slower interval stream to toggle faster main stream on/off
18
+ * sidechainToggle(fromInterval(500), fromInterval(1000)).subscribe(trace());
21
19
  * // 0
22
20
  * // 3
23
21
  * // 4
@@ -26,26 +24,24 @@ import { __optsWithID } from "./idgen.js";
26
24
  * ...
27
25
  * ```
28
26
  *
27
+ * @param src -
29
28
  * @param side -
30
29
  * @param opts -
31
30
  */
32
- export const sidechainToggle = (side, opts) => new SidechainToggle(side, opts);
31
+ export const sidechainToggle = (src, side, opts) => src.subscribe(new SidechainToggle(side, opts));
33
32
  export class SidechainToggle extends ASidechain {
34
33
  constructor(side, opts) {
35
34
  opts = __optsWithID("sidetoggle", opts);
36
35
  super(opts);
37
36
  this.isActive = !!opts.initial;
38
37
  const pred = opts.pred || (() => true);
39
- const $this = this;
40
38
  this.sideSub = side.subscribe({
41
- next(x) {
39
+ next: (x) => {
42
40
  if (pred(x)) {
43
- $this.isActive = !$this.isActive;
41
+ this.isActive = !this.isActive;
44
42
  }
45
43
  },
46
- done() {
47
- $this.done();
48
- },
44
+ done: () => this.done(),
49
45
  });
50
46
  }
51
47
  next(x) {
@@ -0,0 +1,54 @@
1
+ import type { Predicate } from "@thi.ng/api";
2
+ import { SEMAPHORE } from "@thi.ng/api/api";
3
+ import { type CommonOpts, type ISubscribable, type ISubscription } from "./api.js";
4
+ import { ASidechain } from "./asidechain.js";
5
+ export interface SidechainTriggerOpts<T> extends CommonOpts {
6
+ pred: Predicate<T>;
7
+ }
8
+ /**
9
+ * Returns a subscription which buffers the most recent value received from
10
+ * `src` and only forwards it downstream whenever a new control value is
11
+ * received from the `side` chain.
12
+ *
13
+ * @remarks
14
+ * By default, the values read from the side chain are ignored (i.e. only their
15
+ * timing is used), however the `pred`icate option can be used to only trigger
16
+ * for specific values/conditions. Every time the predicate fn returns true AND
17
+ * if `src` already has delivered at least one value, it will be forwarded
18
+ * downstream.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const src = reactive("payload");
23
+ *
24
+ * const side = stream();
25
+ *
26
+ * sidechainTrigger(src, side).subscribe(trace("data:"));
27
+ *
28
+ * side.next(1);
29
+ * // data: payload
30
+ *
31
+ * side.next(1);
32
+ * // data: payload
33
+ *
34
+ * // only newest value will be buffered
35
+ * src.next("update #1");
36
+ * src.next("update #2");
37
+ *
38
+ * // ...until side chain triggers again
39
+ * side.next(1);
40
+ * // data: update #2
41
+ * ...
42
+ * ```
43
+ *
44
+ * @param src
45
+ * @param side
46
+ * @param opts
47
+ */
48
+ export declare const sidechainTrigger: <T, S>(src: ISubscribable<T>, side: ISubscribable<S>, opts?: Partial<SidechainTriggerOpts<S>> | undefined) => ISubscription<T, T>;
49
+ export declare class SidechainTrigger<T, S> extends ASidechain<T, S, T> {
50
+ buf: T | typeof SEMAPHORE;
51
+ constructor(side: ISubscribable<S>, opts?: Partial<SidechainTriggerOpts<S>>);
52
+ next(x: T): void;
53
+ }
54
+ //# sourceMappingURL=sidechain-trigger.d.ts.map
@@ -0,0 +1,66 @@
1
+ import { SEMAPHORE } from "@thi.ng/api/api";
2
+ import { State, } from "./api.js";
3
+ import { ASidechain } from "./asidechain.js";
4
+ 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
+ constructor(side, opts) {
48
+ opts = __optsWithID("sidetrigger", opts);
49
+ super(opts);
50
+ this.buf = SEMAPHORE;
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;
64
+ }
65
+ }
66
+ }
package/stream.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CommonOpts, IStream, ISubscriber, ISubscription, StreamCancel, StreamSource, TransformableOpts, WithErrorHandlerOpts } from "./api.js";
1
+ import { type CommonOpts, type IStream, type ISubscriber, type ISubscription, type StreamCancel, type StreamSource, type TransformableOpts, type WithErrorHandlerOpts } from "./api.js";
2
2
  import { Subscription } from "./subscription.js";
3
3
  /**
4
4
  * Creates a new {@link Stream} instance, optionally with given `StreamSource`
package/subscription.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { Fn } from "@thi.ng/api";
2
- import type { Reducer, Transducer } from "@thi.ng/transducers";
3
- import { Reduced } from "@thi.ng/transducers/reduced";
4
- import { CloseMode, CommonOpts, ISubscriber, ISubscription, State, SubscriptionOpts, TransformableOpts, WithErrorHandlerOpts, WithTransform } from "./api.js";
2
+ import type { Reduced, Reducer, Transducer } from "@thi.ng/transducers";
3
+ import { CloseMode, State, type CommonOpts, type ISubscriber, type ISubscription, type SubscriptionOpts, type TransformableOpts, type WithErrorHandlerOpts, type WithTransform } from "./api.js";
5
4
  /**
6
5
  * Creates a new {@link Subscription} instance, the fundamental datatype and
7
6
  * building block provided by this package.
package/sync-raf.d.ts ADDED
@@ -0,0 +1,45 @@
1
+ /// <reference types="node" />
2
+ import { type CommonOpts, type ISubscribable } from "./api.js";
3
+ import { Subscription } from "./subscription.js";
4
+ /**
5
+ * Similar to (in in effect the same as the **now deprecated**)
6
+ * {@link sidechainPartitionRAF}, however more performant & lightweight.
7
+ * Synchronizes downstream processing w/ `requestAnimationFrame()`. The returned
8
+ * subscription delays & debounces any high frequency intra-frame input values
9
+ * and passes only most recent one downstream during next RAF event processing.
10
+ *
11
+ * This example uses thi.ng/atom as state container. Also see {@link fromAtom}.
12
+ *
13
+ * See {@link sidechainTrigger} from a similar & more general construct.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const atom = defAtom("alice");
18
+ *
19
+ * // any changes to the atom will only be received by this subscription
20
+ * // during next RAF update cycle
21
+ * syncRAF(fromAtom(atom)).subscribe({
22
+ * next({ name }) { document.body.innerText = name; }
23
+ * });
24
+ *
25
+ * // trigger update
26
+ * atom.reset("bob");
27
+ * ```
28
+ *
29
+ * @param src -
30
+ * @param opts -
31
+ */
32
+ export declare const syncRAF: <T>(src: ISubscribable<T>, opts?: Partial<CommonOpts>) => import("./api.js").ISubscription<T, T>;
33
+ /**
34
+ * See {@link syncRAF} for details.
35
+ */
36
+ export declare class SyncRAF<T> extends Subscription<T, T> {
37
+ queued?: T;
38
+ raf?: number | NodeJS.Timeout;
39
+ constructor(opts?: Partial<CommonOpts>);
40
+ next(x: T): void;
41
+ done(): void;
42
+ error(e: any): boolean;
43
+ protected _clean(): void;
44
+ }
45
+ //# sourceMappingURL=sync-raf.d.ts.map
package/sync-raf.js ADDED
@@ -0,0 +1,72 @@
1
+ import { isNode } from "@thi.ng/checks/is-node";
2
+ import { State } from "./api.js";
3
+ import { __optsWithID } from "./idgen.js";
4
+ import { Subscription } from "./subscription.js";
5
+ /**
6
+ * Similar to (in in effect the same as the **now deprecated**)
7
+ * {@link sidechainPartitionRAF}, however more performant & lightweight.
8
+ * Synchronizes downstream processing w/ `requestAnimationFrame()`. The returned
9
+ * subscription delays & debounces any high frequency intra-frame input values
10
+ * and passes only most recent one downstream during next RAF event processing.
11
+ *
12
+ * This example uses thi.ng/atom as state container. Also see {@link fromAtom}.
13
+ *
14
+ * See {@link sidechainTrigger} from a similar & more general construct.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const atom = defAtom("alice");
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
+ constructor(opts) {
39
+ super(undefined, opts);
40
+ }
41
+ next(x) {
42
+ if (this.state >= State.DONE)
43
+ return;
44
+ this.queued = x;
45
+ if (!this.raf) {
46
+ const update = () => {
47
+ if (this.state < State.DONE)
48
+ super.next(this.queued);
49
+ this._clean();
50
+ };
51
+ this.raf = isNode()
52
+ ? setTimeout(update, 16)
53
+ : requestAnimationFrame(update);
54
+ }
55
+ }
56
+ done() {
57
+ this._clean();
58
+ super.done();
59
+ }
60
+ error(e) {
61
+ this._clean();
62
+ return super.error(e);
63
+ }
64
+ _clean() {
65
+ if (this.raf) {
66
+ isNode()
67
+ ? clearTimeout(this.raf)
68
+ : cancelAnimationFrame(this.raf);
69
+ }
70
+ this.raf = this.queued = undefined;
71
+ }
72
+ }
package/sync.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Always, Derefed, IObjectOf } from "@thi.ng/api";
2
- import { PartitionSync } from "@thi.ng/transducers/partition-sync";
2
+ import { type PartitionSync } from "@thi.ng/transducers/partition-sync";
3
3
  import type { ISubscribable, ISubscription, TransformableOpts } from "./api.js";
4
4
  import { Subscription } from "./subscription.js";
5
5
  export type SyncTuple<T extends IObjectOf<ISubscribable<any>>> = {
package/timeout.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CommonOpts } from "./api.js";
1
+ import { type CommonOpts } from "./api.js";
2
2
  import { Subscription } from "./subscription.js";
3
3
  export interface TimeoutOpts extends CommonOpts {
4
4
  /**