@thi.ng/rstream 8.5.12 → 9.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-08-18T14:11:34Z
3
+ - **Last updated**: 2024-08-20T11:41:56Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,18 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ # [9.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream@9.0.0) (2024-08-20)
13
+
14
+ #### 🛑 Breaking changes
15
+
16
+ - replace `CloseMode` enum w/ string union type ([33b1d16](https://github.com/thi-ng/umbrella/commit/33b1d16))
17
+ - BREAKING CHANGE: replace `CloseMode` enum w/ string union type
18
+ - this simplifies all usage sites, now only using (and removing obsolete enum import):
19
+ - `CloseMode.FIRST` => `"first"`
20
+ - `CloseMode.LAST` => `"last"`
21
+ - `CloseMode.NEVER` => `"never"`
22
+ - update docs & all sites
23
+
12
24
  ## [8.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream@8.5.0) (2024-05-08)
13
25
 
14
26
  #### 🚀 Features
package/README.md CHANGED
@@ -17,6 +17,7 @@
17
17
  - [About](#about)
18
18
  - [Conceptual differences to RxJS](#conceptual-differences-to-rxjs)
19
19
  - [Status](#status)
20
+ - [New features & breaking changes in 9.0.0](#new-features--breaking-changes-in-900)
20
21
  - [New features & breaking changes in 6.0.0](#new-features--breaking-changes-in-600)
21
22
  - [Support packages](#support-packages)
22
23
  - [Related packages](#related-packages)
@@ -53,52 +54,46 @@
53
54
 
54
55
  Reactive streams & subscription primitives for constructing dataflow graphs / pipelines.
55
56
 
56
- This library provides & uses three key building blocks for reactive
57
- programming:
58
-
59
- - **Stream sources**: event targets, iterables, timers,
60
- promises,watches, workers, manual-push...
61
- - **Subscriptions**: chained stream processors, each subscribable
62
- (one-tmany) itself
63
- - **Transducers**: stream transformers, either as individual
64
- subscription or to transform incoming values for a single
65
- subscription. See packages/transducers) for 100+ composable operators.
66
- - **Recursive teardown**: Whenever possible, and depending on
67
- configuration, unsubscriptions initiate cleanup and propagate to
68
- parent(s).
69
- - **Workers**: highly configurable, web worker integration for
70
- concurrent / parallel stream processing (fork-join, tunneled stream
71
- processing, etc.)
57
+ This library provides & uses three key building blocks for reactive programming:
58
+
59
+ - **Stream sources**: event targets, iterables, timers, promises,watches,
60
+ workers, manual-push...
61
+ - **Subscriptions**: chained stream processors, each subscribable (one-tmany)
62
+ itself
63
+ - **Transducers**: stream transformers, either as individual subscription or to
64
+ transform incoming values for a single subscription. See packages/transducers)
65
+ for 100+ composable operators.
66
+ - **Recursive teardown**: Whenever possible, and depending on configuration,
67
+ unsubscriptions initiate cleanup and propagate to parent(s).
68
+ - **Workers**: highly configurable, web worker integration for concurrent /
69
+ parallel stream processing (fork-join, tunneled stream processing, etc.)
72
70
 
73
71
  ## Conceptual differences to RxJS
74
72
 
75
73
  (No value judgments implied - there's room for both approaches!)
76
74
 
77
- - Streams are not the same as Observables: I.e. stream sources are NOT
78
- (often just cannot) re-run for each new sub added. Only the first sub
79
- is guaranteed to receive **all** values. Subs added at a later time
80
- MIGHT not receive earlier emitted values, but only the most recent
81
- emitted and any future values
75
+ - Streams are not the same as Observables: I.e. stream sources are NOT (often
76
+ just cannot) re-run for each new sub added. Only the first sub is guaranteed
77
+ to receive **all** values. Subs added at a later time MIGHT not receive
78
+ earlier emitted values, but only the most recent emitted and any future values
82
79
  - Every subscription supports any number of subscribers, which can be
83
80
  added/removed at any time
84
- - Depending on configuration options, every unsubscription recursively
85
- triggers upstream unsubscriptions (provided a parent has no other
86
- active child subscriptions)
87
- - Every subscription can have its own transducer transforming incoming
88
- values (possibly into multiple new ones)
89
- - Transducers can create streams themselves (only for `merge()`
90
- /`sync()`)
91
- - Transducers can cause early stream termination and subsequent
92
- unwinding for its parent and downstream subscriptions.
93
- - Values can be manually injected into the stream pipeline / graph at
94
- any point
95
- - Unhandled errors in a subscription will move the subscription into an
96
- error state and cause unsubscription from parent (if any). Unhandled
97
- errors in stream sources will cancel the stream.
98
- - _Much_ smaller API surface, since most common & custom operations can
99
- be solved via available transducers. Therefore there's less of a need
100
- to provide specialized functions (map / filter etc.) and gain more
101
- flexibility in terms of composing new operations.
81
+ - Depending on configuration options, every unsubscription recursively triggers
82
+ upstream unsubscriptions (provided a parent has no other active child
83
+ subscriptions)
84
+ - Every subscription can have its own transducer transforming incoming values
85
+ (possibly into multiple new ones)
86
+ - Transducers can create streams themselves (only for `merge()` /`sync()`)
87
+ - Transducers can cause early stream termination and subsequent unwinding for
88
+ its parent and downstream subscriptions.
89
+ - Values can be manually injected into the stream pipeline / graph at any point
90
+ - Unhandled errors in a subscription will move the subscription into an error
91
+ state and cause unsubscription from parent (if any). Unhandled errors in
92
+ stream sources will cancel the stream.
93
+ - _Much_ smaller API surface, since most common & custom operations can be
94
+ solved via available transducers. Therefore there's less of a need to provide
95
+ specialized functions (map / filter etc.) and gain more flexibility in terms
96
+ of composing new operations.
102
97
  - IMHO less confusing naming / terminology (only streams (producers) &
103
98
  subscriptions (consumers))
104
99
 
@@ -108,6 +103,12 @@ programming:
108
103
 
109
104
  [Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Brstream%5D+in%3Atitle)
110
105
 
106
+ ### New features & breaking changes in 9.0.0
107
+
108
+ The `CloseMode` enum has been replaced with a more compact & simple string union
109
+ type, see [docs](https://docs.thi.ng/umbrella/rstream/types/CloseMode.html) and
110
+ [usage](#common-configuration-options).
111
+
111
112
  ### New features & breaking changes in 6.0.0
112
113
 
113
114
  Completely revised & improved [error handling](#error-handling), stronger
@@ -167,9 +168,9 @@ src.transformTopic("foo", map((e) => e.value), { error: handleError })
167
168
  **Notes:**
168
169
 
169
170
  - (1): If using multiple transducers, they must be pre-composed with
170
- [`comp()`](https://docs.thi.ng/umbrella/transducers/functions/comp.html). Other
171
- signatures of `.transform()` method support up to 4 transducers and composes
172
- them automatically.
171
+ [`comp()`](https://docs.thi.ng/umbrella/transducers/functions/comp.html).
172
+ Other signatures of `.transform()` method support up to 4 transducers and
173
+ composes them automatically.
173
174
 
174
175
  ## Support packages
175
176
 
@@ -214,7 +215,7 @@ For Node.js REPL:
214
215
  const rs = await import("@thi.ng/rstream");
215
216
  ```
216
217
 
217
- Package sizes (brotli'd, pre-treeshake): ESM: 6.33 KB
218
+ Package sizes (brotli'd, pre-treeshake): ESM: 6.28 KB
218
219
 
219
220
  ## Dependencies
220
221
 
@@ -299,40 +300,40 @@ directory are using this package:
299
300
 
300
301
  ### Common configuration options
301
302
 
302
- Since version 3.0.0 all stream and subscription factory functions take
303
- an optional object of configuration options with **at least** these keys
304
- (each optional):
303
+ Since version 3.0.0 all stream and subscription factory functions take an
304
+ optional object of [common configuration
305
+ options](https://docs.thi.ng/umbrella/rstream/interfaces/CommonOpts.html) with
306
+ **at least** these keys (each optional):
305
307
 
306
308
  ```ts
307
309
  interface CommonOpts {
308
310
  /**
309
- * Internal ID associated with this stream. If omitted, an
310
- * autogenerated ID will be used.
311
+ * Internal ID associated with this stream. If omitted, an autogenerated ID
312
+ * will be used.
311
313
  */
312
314
  id: string;
313
315
  /**
314
- * If false or `CloseMode.NEVER`, the stream stays active even if
315
- * all inputs are done. If true (default) or `CloseMode.LAST`, the
316
- * stream closes when the last input is done. If `CloseMode.FIRST`,
317
- * the instance closes when the first input is done.
316
+ * If false or `"never"`, the stream stays active even if all inputs are
317
+ * done. If true (default) or `"last"`, the stream closes when the last
318
+ * input is done. If `"first"`, the instance closes when the first input is
319
+ * done.
318
320
  *
319
- * @defaultValue CloseMode.LAST
321
+ * @defaultValue "last"
320
322
  */
321
323
  closeIn: CloseMode;
322
324
  /**
323
- * If false or `CloseMode.NEVER`, the stream stays active once there
324
- * are no more subscribers. If true (default) or `CloseMode.LAST`,
325
- * the stream closes when the last subscriber has unsubscribed. If
326
- * `CloseMode.FIRST`, the instance closes when the first subscriber
327
- * disconnects.
325
+ * If false or `"never"`, the stream stays active once there are no more
326
+ * subscribers. If true (default) or `"last"`, the stream closes when the
327
+ * last subscriber has unsubscribed. If `"first"`, the instance closes when
328
+ * the first subscriber disconnects.
328
329
  *
329
- * @defaultValue CloseMode.LAST
330
+ * @defaultValue "last"
330
331
  */
331
332
  closeOut: CloseMode;
332
333
  /**
333
- * If true (default), stream caches last received value and pushes
334
- * it to new subscriberswhen they subscribe. If false, calling
335
- * `.deref()` on this stream will always return `undefined`.
334
+ * If true (default), stream caches last received value and pushes it to new
335
+ * subscriberswhen they subscribe. If false, calling `.deref()` on this
336
+ * stream will always return `undefined`.
336
337
  *
337
338
  * @defaultValue true
338
339
  */
@@ -346,17 +347,16 @@ interface CommonOpts {
346
347
 
347
348
  Docs: [stream()](https://docs.thi.ng/umbrella/rstream/functions/stream-1.html)
348
349
 
349
- Creates a new `Stream` instance, optionally with given `StreamSource`
350
- function and / or ID. If a `src` function is provided, the function
351
- will be only called (with the `Stream` instance as single argument)
352
- once the first subscriber has attached to the stream. If the function
353
- returns another function, it will be used for cleanup purposes if the
354
- stream is cancelled, e.g. if the last subscriber has unsubscribed.
355
- Streams are intended as (primarily async) data sources in a dataflow
356
- graph and are the primary construct for the various `from*()`
357
- functions provided by the package. However, streams can also be
358
- triggered manually (from outside the stream), in which case the user
359
- should call `stream.next()` to cause value propagation.
350
+ Creates a new `Stream` instance, optionally with given `StreamSource` function
351
+ and / or ID. If a `src` function is provided, the function will be only called
352
+ (with the `Stream` instance as single argument) once the first subscriber has
353
+ attached to the stream. If the function returns another function, it will be
354
+ used for cleanup purposes if the stream is cancelled, e.g. if the last
355
+ subscriber has unsubscribed. Streams are intended as (primarily async) data
356
+ sources in a dataflow graph and are the primary construct for the various
357
+ `from*()` functions provided by the package. However, streams can also be
358
+ triggered manually (from outside the stream), in which case the user should call
359
+ `stream.next()` to cause value propagation.
360
360
 
361
361
  ```ts
362
362
  import { stream, trace } from "@thi.ng/rstream";
@@ -387,36 +387,33 @@ b.next(42);
387
387
 
388
388
  ### IDeref support
389
389
 
390
- `Stream` (like all other types of `Subscription`) implements the
391
- [@thi.ng/api
392
- `IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html)
393
- interface which provides read access to a stream's last received value.
394
- This is useful for various purposes, e.g. in combination with
395
- @thi.ng/hdom, which supports direct embedding of streams (i.e. their
396
- values) into UI components (and will be deref'd automatically). If the
397
- stream has not yet emitted a value or if the stream is already done, it
398
- will deref to `undefined`.
390
+ `Stream` (like all other types of `Subscription`) implements the [@thi.ng/api
391
+ `IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html) interface
392
+ which provides read access to a stream's last received value. This is useful for
393
+ various purposes, e.g. in combination with @thi.ng/hdom, which supports direct
394
+ embedding of streams (i.e. their values) into UI components (and will be deref'd
395
+ automatically). If the stream has not yet emitted a value or if the stream is
396
+ already done, it will deref to `undefined`.
399
397
 
400
- Furthermore, all subscription types can be configured (via the `cache`
401
- option) to NOT retain their last emitted value, in which case `.deref()`
402
- will always return `undefined`.
398
+ Furthermore, all subscription types can be configured (via the `cache` option)
399
+ to NOT retain their last emitted value, in which case `.deref()` will always
400
+ return `undefined`.
403
401
 
404
402
  #### Subscription
405
403
 
406
404
  Docs: [subscription()](https://docs.thi.ng/umbrella/rstream/functions/subscription-1.html)
407
405
 
408
- Creates a new `Subscription` instance, the fundamental datatype &
409
- building block provided by this package (`Stream`s are `Subscription`s
410
- too). Subscriptions can be:
406
+ Creates a new `Subscription` instance, the fundamental datatype & building block
407
+ provided by this package (`Stream`s are `Subscription`s too). Subscriptions can
408
+ be:
411
409
 
412
410
  - linked into directed graphs (if async, not necessarily DAGs)
413
411
  - transformed using transducers (incl. early termination)
414
- - can have any number of subscribers (optionally each w/ their own
415
- transducer)
416
- - recursively unsubscribe themselves from parent after their last
417
- subscriber unsubscribed
418
- - will go into a non-recoverable error state if NONE of the subscribers
419
- has an error handler itself
412
+ - can have any number of subscribers (optionally each w/ their own transducer)
413
+ - recursively unsubscribe themselves from parent after their last subscriber
414
+ unsubscribed
415
+ - will go into a non-recoverable error state if NONE of the subscribers has an
416
+ error handler itself
420
417
  - implement the @thi.ng/api `IDeref` interface
421
418
 
422
419
  ```ts
@@ -462,24 +459,22 @@ s.next(42);
462
459
 
463
460
  Docs: [metaStream()](https://docs.thi.ng/umbrella/rstream/functions/metaStream-1.html)
464
461
 
465
- `MetaStream`s are streams of streams. A `MetaStream` is a subscription
466
- type which transforms each incoming value into a new stream, subscribes
467
- to it (via an hidden / internal subscription) and then only passes
468
- values from that stream to its own subscribers. If a new value is
469
- received, the meta stream first unsubscribes from the possibly still
470
- active stream created from the previous input, before creating and
471
- subscribing to the new stream. Hence this stream type is useful for
472
- cases where streams need to be dynamically and invisibly created &
473
- inserted into an existing dataflow topology without changing it, and
474
- with the guarantee that never more than one of these is active at the
475
- same time. Similar behavior (without the restriction in number) can be
476
- achieved using `merge()` (see further below).
477
-
478
- The user supplied `factory` function will be called for each incoming
479
- value and is responsible for creating the new stream instances. If the
480
- function returns `null` / `undefined`, no further action will be taken
481
- (acts like a `filter` transducer, i.e. the incoming value is simply
482
- ignored).
462
+ `MetaStream`s are streams of streams. A `MetaStream` is a subscription type
463
+ which transforms each incoming value into a new stream, subscribes to it (via an
464
+ hidden / internal subscription) and then only passes values from that stream to
465
+ its own subscribers. If a new value is received, the meta stream first
466
+ unsubscribes from the possibly still active stream created from the previous
467
+ input, before creating and subscribing to the new stream. Hence this stream type
468
+ is useful for cases where streams need to be dynamically and invisibly created &
469
+ inserted into an existing dataflow topology without changing it, and with the
470
+ guarantee that never more than one of these is active at the same time. Similar
471
+ behavior (without the restriction in number) can be achieved using `merge()`
472
+ (see further below).
473
+
474
+ The user supplied `factory` function will be called for each incoming value and
475
+ is responsible for creating the new stream instances. If the function returns
476
+ `null` / `undefined`, no further action will be taken (acts like a `filter`
477
+ transducer, i.e. the incoming value is simply ignored).
483
478
 
484
479
  ```ts
485
480
  import { metastream, fromIterable, trace } from "@thi.ng/rstream";
@@ -509,28 +504,27 @@ a.next(43)
509
504
  // odd: 43
510
505
  ```
511
506
 
512
- The factory function does NOT need to create new streams, but too can
513
- merely return other existing streams, and so making the meta stream act
514
- like a switch / stream selector.
507
+ The factory function does NOT need to create new streams, but too can merely
508
+ return other existing streams, and so making the meta stream act like a switch /
509
+ stream selector.
515
510
 
516
- If the meta stream is the only subscriber to these input streams, you'll
517
- need to use the `closeOut: CloseMode.NEVER` option when creating the
518
- inputs. This keeps them alive and allows for dynamic switching between
519
- them.
511
+ If the meta stream is the only subscriber to these input streams, you'll need to
512
+ use the `closeOut: "never"` option when creating the inputs. This keeps them
513
+ alive and allows for dynamic switching between them.
520
514
 
521
515
  ```ts
522
- import { metastream, fromIterable, trace, CloseMode } from "@thi.ng/rstream";
516
+ import { metastream, fromIterable, trace } from "@thi.ng/rstream";
523
517
  import { repeat } from "@thi.ng/transducers";
524
518
 
525
519
  // infinite inputs
526
520
  a = fromIterable(
527
521
  repeat("a"),
528
- { delay: 1000, closeOut: CloseMode.NEVER }
522
+ { delay: 1000, closeOut: "never" }
529
523
  );
530
524
 
531
525
  b = fromIterable(
532
526
  repeat("b"),
533
- { delay: 1000, closeOut: CloseMode.NEVER }
527
+ { delay: 1000, closeOut: "never" }
534
528
  );
535
529
 
536
530
  // stream selector / switch
@@ -555,12 +549,12 @@ Docs: [merge()](https://docs.thi.ng/umbrella/rstream/functions/merge.html)
555
549
 
556
550
  ![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-merge.png)
557
551
 
558
- Returns a new `StreamMerge` instance, a subscription type consuming
559
- inputs from multiple inputs and passing received values on to any
560
- subscribers. Input streams can be added and removed dynamically. By
561
- default, `StreamMerge` calls `done()` when the last active input is
562
- done, but this behavior can be overridden via the `close` option, using
563
- `CloseMode` enums.
552
+ Returns a new `StreamMerge` instance, a subscription type consuming inputs from
553
+ multiple inputs and passing received values on to any subscribers. Input streams
554
+ can be added and removed dynamically. By default, `StreamMerge` calls `done()`
555
+ when the last active input is done, but this behavior can be overridden via the
556
+ [`closeIn`
557
+ option](https://docs.thi.ng/umbrella/rstream/interfaces/StreamMergeOpts.html#closeIn).
564
558
 
565
559
  ```ts
566
560
  import { merge, fromIterable, trace } from "@thi.ng/rstream";
@@ -612,10 +606,9 @@ for further reference of the various behavior options.
612
606
 
613
607
  ##### Adding inputs automatically
614
608
 
615
- If the `StreamMerge` receives a `Subscription`-like value from any of
616
- its inputs, it will not be processed as usual, but instead will be added
617
- as new input to the merge and then automatically remove once that stream
618
- is exhausted.
609
+ If the `StreamMerge` receives a `Subscription`-like value from any of its
610
+ inputs, it will not be processed as usual, but instead will be added as new
611
+ input to the merge and then automatically remove once that stream is exhausted.
619
612
 
620
613
  ```ts
621
614
  import { merge, stream, fromIterable, trace } from "@thi.ng/rstream";
@@ -647,24 +640,24 @@ Docs: [sync()](https://docs.thi.ng/umbrella/rstream/functions/sync.html)
647
640
 
648
641
  ![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sync.png)
649
642
 
650
- Similar to `StreamMerge` above, but with extra synchronization of
651
- inputs. Before emitting any new values, `StreamSync` collects values
652
- until at least one has been received from _all_ inputs. Once that's the
653
- case, the collected values are sent as labeled tuple object to
654
- downstream subscribers. Each value in the emitted tuple objects is
655
- stored under their input stream's ID. Only the last value received from
656
- each input is passed on. After the initial tuple has been emitted, you
657
- can choose from two possible behaviors:
658
-
659
- 1. Any future change in any input will produce a new result tuple. These
660
- tuples will retain the most recently read values from other inputs.
661
- This behavior is the default and illustrated in the above schematic.
662
- 2. If the `reset` option is `true`, every input will have to provide at
663
- least one new value again until another result tuple is produced.
664
-
665
- Any done inputs are automatically removed. By default, `StreamSync`
666
- calls `done()` when the last active input is done, but this behavior can
667
- be overridden via the `close` constructor option, using `CloseMode` enums.
643
+ Similar to `StreamMerge` above, but with extra synchronization of inputs. Before
644
+ emitting any new values, `StreamSync` collects values until at least one has
645
+ been received from _all_ inputs. Once that's the case, the collected values are
646
+ sent as labeled tuple object to downstream subscribers. Each value in the
647
+ emitted tuple objects is stored under their input stream's ID. Only the last
648
+ value received from each input is passed on. After the initial tuple has been
649
+ emitted, you can choose from two possible behaviors:
650
+
651
+ 1. Any future change in any input will produce a new result tuple. These tuples
652
+ will retain the most recently read values from other inputs. This behavior is
653
+ the default and illustrated in the above schematic.
654
+ 2. If the `reset` option is `true`, every input will have to provide at least
655
+ one new value again until another result tuple is produced.
656
+
657
+ Any done inputs are automatically removed. By default, `StreamSync` calls
658
+ `done()` when the last active input is done, but this behavior can be overridden
659
+ via the [`closeIn`
660
+ option](https://docs.thi.ng/umbrella/rstream/interfaces/StreamMergeOpts.html#closeIn).
668
661
 
669
662
  ```ts
670
663
  import { sync, stream, trace } from "@thi.ng/rstream";
@@ -677,13 +670,13 @@ b.next(2);
677
670
  // result: { a: 1, b: 2 }
678
671
  ```
679
672
 
680
- Input streams can be added and removed dynamically and the emitted tuple
681
- size adjusts to the current number of inputs (the next time a value is
682
- received from any input).
673
+ Input streams can be added and removed dynamically and the emitted tuple size
674
+ adjusts to the current number of inputs (the next time a value is received from
675
+ any input).
683
676
 
684
- If the `reset` option is enabled, the last emitted tuple is allowed to
685
- be incomplete, by default. To only allow complete tuples, also set the
686
- `all` option to `false`.
677
+ If the `reset` option is enabled, the last emitted tuple is allowed to be
678
+ incomplete, by default. To only allow complete tuples, also set the `all` option
679
+ to `false`.
687
680
 
688
681
  The synchronization is done via the
689
682
  [`partitionSync()`](https://docs.thi.ng/umbrella/transducers/functions/partitionSync-1.html)
@@ -703,32 +696,30 @@ Docs: [pubsub()](https://docs.thi.ng/umbrella/rstream/functions/pubsub-1.html)
703
696
 
704
697
  ![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-pubsub.png)
705
698
 
706
- Topic based stream splitter. Applies `topic` function to each
707
- received value and only forwards it to child subscriptions for
708
- returned topic. The actual topic (return value from `topic` fn) can
709
- be of any type, apart from `undefined`. Complex topics (e.g objects /
710
- arrays) are allowed and they're matched with registered topics using
711
- @thi.ng/equiv by default (but customizable via `equiv` option).
712
- Each topic can have any number of subscribers.
699
+ Topic based stream splitter. Applies `topic` function to each received value and
700
+ only forwards it to child subscriptions for returned topic. The actual topic
701
+ (return value from `topic` fn) can be of any type, apart from `undefined`.
702
+ Complex topics (e.g objects / arrays) are allowed and they're matched with
703
+ registered topics using @thi.ng/equiv by default (but customizable via `equiv`
704
+ option). Each topic can have any number of subscribers.
713
705
 
714
- If a transducer is specified for the `PubSub`, it is always applied
715
- prior to passing the input to the topic function. I.e. in this case
716
- the topic function will receive the transformed inputs.
706
+ If a transducer is specified for the `PubSub`, it is always applied prior to
707
+ passing the input to the topic function. I.e. in this case the topic function
708
+ will receive the transformed inputs.
717
709
 
718
710
  PubSub supports dynamic topic subscriptions and unsubscriptions via
719
711
  `subscribeTopic()` and `unsubscribeTopic()`. However, **the standard
720
- `subscribe()` / `unsubscribe()` methods are NOT supported** (since
721
- meaningless here) and will throw an error! `unsubscribe()` can only be
722
- called WITHOUT argument to unsubscribe the entire `PubSub` instance
723
- (incl. all topic subscriptions) from the parent stream.
712
+ `subscribe()` / `unsubscribe()` methods are NOT supported** (since meaningless
713
+ here) and will throw an error! `unsubscribe()` can only be called WITHOUT
714
+ argument to unsubscribe the entire `PubSub` instance (incl. all topic
715
+ subscriptions) from the parent stream.
724
716
 
725
717
  #### Splitting via predicate
726
718
 
727
719
  Docs: [bisect()](https://docs.thi.ng/umbrella/rstream/functions/bisect.html)
728
720
 
729
- Returns a new `PubSub` instance using given predicate `pred` as boolean
730
- topic function and `a` & `b` as subscribers for truthy (`a`) and falsy
731
- `b` values.
721
+ Returns a new `PubSub` instance using given predicate `pred` as boolean topic
722
+ function and `a` & `b` as subscribers for truthy (`a`) and falsy `b` values.
732
723
 
733
724
  ```ts
734
725
  import { bisect, fromIterable, trace } from "@thi.ng/rstream";
@@ -744,9 +735,9 @@ fromIterable([1, 2, 3, 4]).subscribe(
744
735
  // even done
745
736
  ```
746
737
 
747
- If `a` or `b` need to be subscribed to directly, then `a` / `b` MUST be
748
- first created as `Subscription` (if not already) and a reference kept
749
- prior to calling `bisect()`.
738
+ If `a` or `b` need to be subscribed to directly, then `a` / `b` MUST be first
739
+ created as `Subscription` (if not already) and a reference kept prior to calling
740
+ `bisect()`.
750
741
 
751
742
  ```ts
752
743
  import { bisect, fromIterable, subscription, trace } from "@thi.ng/rstream";
@@ -777,11 +768,10 @@ Docs: [sidechainPartition()](https://docs.thi.ng/umbrella/rstream/functions/side
777
768
 
778
769
  ![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sidechain-partition.png)
779
770
 
780
- Buffers values from `src` until side chain fires, then emits buffer
781
- (unless empty) and repeats process until either input is done. By
782
- default, the value read from the side chain is ignored, however the
783
- optional predicate can be used to only trigger for specific values /
784
- conditions.
771
+ Buffers values from `src` until side chain fires, then emits buffer (unless
772
+ empty) and repeats process until either input is done. By default, the value
773
+ read from the side chain is ignored, however the optional predicate can be used
774
+ to only trigger for specific values / conditions.
785
775
 
786
776
  ```ts
787
777
  import {
@@ -825,12 +815,11 @@ Docs: [sidechainToggle()](https://docs.thi.ng/umbrella/rstream/functions/sidecha
825
815
 
826
816
  ![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sidechain-toggle.png)
827
817
 
828
- Filters values from input based on values received from side chain. By
829
- default, the value read from the side chain is ignored, however the
830
- optional predicate can be used to only trigger for specific
831
- values/conditions. Every time the predicate fn returns true, the filter
832
- will be toggled on/off. Whilst switched off, no input values will be
833
- forwarded.
818
+ Filters values from input based on values received from side chain. By default,
819
+ the value read from the side chain is ignored, however the optional predicate
820
+ can be used to only trigger for specific values/conditions. Every time the
821
+ predicate fn returns true, the filter will be toggled on/off. Whilst switched
822
+ off, no input values will be forwarded.
834
823
 
835
824
  ```ts
836
825
  import { sidechainToggle, fromInterval, trace } from "@thi.ng/rstream";
@@ -934,9 +923,9 @@ src.next(new Array(16).fill(1));
934
923
 
935
924
  Docs: [tunnel()](https://docs.thi.ng/umbrella/rstream/functions/tunnel-1.html)
936
925
 
937
- Delegate stream value processing to workers and pass on their responses
938
- to downstream subscriptions. Supports multiple worker instances and
939
- worker termination / restart for each new stream value received.
926
+ Delegate stream value processing to workers and pass on their responses to
927
+ downstream subscriptions. Supports multiple worker instances and worker
928
+ termination / restart for each new stream value received.
940
929
 
941
930
  Docs: [postWorker()](https://docs.thi.ng/umbrella/rstream/functions/postWorker.html)
942
931
 
@@ -962,8 +951,8 @@ be found in [this issue](https://github.com/thi-ng/umbrella/issues/281)**
962
951
  The `ISubscriber` interface supports optional error handlers which will be
963
952
  called if code in the `next()` or `done()` handlers throws an error. If no error
964
953
  handler is defined for a subscriber, the wrapping `Subscription`'s own error
965
- handler will be called, which _might_ put this subscription into an error
966
- state and stop it from receiving new values.
954
+ handler will be called, which _might_ put this subscription into an error state
955
+ and stop it from receiving new values.
967
956
 
968
957
  ```ts
969
958
  import { subscription, State } from "@thi.ng/rstream";
package/api.d.ts CHANGED
@@ -9,54 +9,44 @@ export declare enum State {
9
9
  ERROR = 4
10
10
  }
11
11
  /**
12
- * Closing behaviors.
12
+ * Closing behaviors:
13
+ *
14
+ * - Close when first input/output is done / removed
15
+ * - Close when last input/output is done / removed
16
+ * - Never close, even if no more inputs/outputs
13
17
  */
14
- export declare enum CloseMode {
15
- /**
16
- * Never close, even if no more inputs/outputs.
17
- */
18
- NEVER = 0,
19
- /**
20
- * Close when first input/output is done / removed.
21
- */
22
- FIRST = 1,
23
- /**
24
- * Close when last input/output is done / removed.
25
- */
26
- LAST = 2
27
- }
18
+ export type CloseMode = "first" | "last" | "never";
28
19
  /**
29
20
  * Common base options for all stream / subscription types.
30
21
  */
31
22
  export interface CommonOpts {
32
23
  /**
33
- * Internal ID associated with this stream. If omitted, an
34
- * autogenerated ID will be used.
24
+ * Internal ID associated with this stream. If omitted, an autogenerated ID
25
+ * will be used.
35
26
  */
36
27
  id: string;
37
28
  /**
38
- * If false or `CloseMode.NEVER`, the stream stays active even if
39
- * all inputs are done. If true (default) or `CloseMode.LAST`, the
40
- * stream closes when the last input is done. If `CloseMode.FIRST`,
41
- * the instance closes when the first input is done.
29
+ * If false or `"never"`, the stream stays active even if all inputs are
30
+ * done. If true (default) or `"last"`, the stream closes when the last
31
+ * input is done. If `"first"`, the instance closes when the first input is
32
+ * done.
42
33
  *
43
- * @defaultValue CloseMode.LAST
34
+ * @defaultValue "last"
44
35
  */
45
36
  closeIn: CloseMode;
46
37
  /**
47
- * If false or `CloseMode.NEVER`, the stream stays active once there
48
- * are no more subscribers. If true (default) or `CloseMode.LAST`,
49
- * the stream closes when the last subscriber has unsubscribed. If
50
- * `CloseMode.FIRST`, the instance closes when the first subscriber
51
- * disconnects.
38
+ * If false or `"never"`, the stream stays active once there are no more
39
+ * subscribers. If true (default) or `"last"`, the stream closes when the
40
+ * last subscriber has unsubscribed. If `"first"`, the instance closes when
41
+ * the first subscriber disconnects.
52
42
  *
53
- * @defaultValue CloseMode.LAST
43
+ * @defaultValue "last"
54
44
  */
55
45
  closeOut: CloseMode;
56
46
  /**
57
- * If true (default), stream caches last received value and pushes
58
- * it to new subscriberswhen they subscribe. If false, calling
59
- * `.deref()` on this stream will always return `undefined`.
47
+ * If true (default), stream caches last received value and pushes it to new
48
+ * subscriberswhen they subscribe. If false, calling `.deref()` on this
49
+ * stream will always return `undefined`.
60
50
  *
61
51
  * @defaultValue true
62
52
  */
@@ -64,9 +54,8 @@ export interface CommonOpts {
64
54
  }
65
55
  export interface WithTransform<A, B> {
66
56
  /**
67
- * Transducer to transform incoming stream values. If given, all
68
- * child subscriptions will only receive the transformed result
69
- * values.
57
+ * Transducer to transform incoming stream values. If given, all child
58
+ * subscriptions will only receive the transformed result values.
70
59
  */
71
60
  xform: Transducer<A, B>;
72
61
  }
package/api.js CHANGED
@@ -6,13 +6,6 @@ var State = /* @__PURE__ */ ((State2) => {
6
6
  State2[State2["ERROR"] = 4] = "ERROR";
7
7
  return State2;
8
8
  })(State || {});
9
- var CloseMode = /* @__PURE__ */ ((CloseMode2) => {
10
- CloseMode2[CloseMode2["NEVER"] = 0] = "NEVER";
11
- CloseMode2[CloseMode2["FIRST"] = 1] = "FIRST";
12
- CloseMode2[CloseMode2["LAST"] = 2] = "LAST";
13
- return CloseMode2;
14
- })(CloseMode || {});
15
9
  export {
16
- CloseMode,
17
10
  State
18
11
  };
package/checks.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CloseMode, type ISubscribable } from "./api.js";
1
+ import type { CloseMode, ISubscribable } from "./api.js";
2
2
  export declare const isSubscribable: (x: any) => x is ISubscribable<any>;
3
3
  /**
4
4
  * Returns true if mode is FIRST, or if mode is LAST *and* `num = 0`.
package/checks.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { implementsFunction } from "@thi.ng/checks/implements-function";
2
- import { CloseMode } from "./api.js";
3
2
  const isSubscribable = (x) => implementsFunction(x, "subscribe");
4
- const isFirstOrLastInput = (mode, num) => mode === CloseMode.FIRST || mode === CloseMode.LAST && !num;
3
+ const isFirstOrLastInput = (mode, num) => mode === "first" || mode === "last" && !num;
5
4
  export {
6
5
  isFirstOrLastInput,
7
6
  isSubscribable
package/interval.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type CommonOpts } from "./api.js";
1
+ import type { CommonOpts } from "./api.js";
2
2
  export interface FromIntervalOpts extends CommonOpts {
3
3
  /**
4
4
  * If given, only the stated number of values will be emitted (in
package/interval.js CHANGED
@@ -1,4 +1,3 @@
1
- import { CloseMode } from "./api.js";
2
1
  import { __optsWithID } from "./idgen.js";
3
2
  import { stream } from "./stream.js";
4
3
  const fromInterval = (delay, opts) => {
@@ -14,7 +13,7 @@ const fromInterval = (delay, opts) => {
14
13
  stream2.next(i++);
15
14
  if (--count <= 0) {
16
15
  clearInterval(id);
17
- stream2.closeIn !== CloseMode.NEVER && stream2.done();
16
+ stream2.closeIn !== "never" && stream2.done();
18
17
  }
19
18
  }, delay);
20
19
  return () => clearInterval(id);
package/iterable.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type CommonOpts } from "./api.js";
1
+ import type { CommonOpts } from "./api.js";
2
2
  export interface FromIterableOpts extends CommonOpts {
3
3
  /**
4
4
  * Time delay (in ms) between emitted values. The default value of
package/iterable.js CHANGED
@@ -1,4 +1,3 @@
1
- import { CloseMode } from "./api.js";
2
1
  import { __optsWithID } from "./idgen.js";
3
2
  import { stream } from "./stream.js";
4
3
  const fromIterable = (src, opts = {}) => stream((stream2) => {
@@ -7,7 +6,7 @@ const fromIterable = (src, opts = {}) => stream((stream2) => {
7
6
  let val;
8
7
  if ((val = iter.next()).done) {
9
8
  clearInterval(id);
10
- stream2.closeIn !== CloseMode.NEVER && stream2.done();
9
+ stream2.closeIn !== "never" && stream2.done();
11
10
  } else {
12
11
  stream2.next(val.value);
13
12
  }
@@ -18,7 +17,7 @@ const fromIterableSync = (src, opts) => stream((stream2) => {
18
17
  for (let s of src) {
19
18
  stream2.next(s);
20
19
  }
21
- stream2.closeIn !== CloseMode.NEVER && stream2.done();
20
+ stream2.closeIn !== "never" && stream2.done();
22
21
  }, __optsWithID("iterable-sync", opts));
23
22
  export {
24
23
  fromIterable,
package/metastream.d.ts CHANGED
@@ -66,17 +66,17 @@ export interface MetaStreamOpts extends CommonOpts {
66
66
  *
67
67
  * @example
68
68
  * ```ts tangle:../export/metastream-2.ts
69
- * import { CloseMode, fromIterable, metaStream, trace } from "@thi.ng/rstream";
69
+ * import { fromIterable, metaStream, trace } from "@thi.ng/rstream";
70
70
  * import { cycle, repeat } from "@thi.ng/transducers";
71
71
  *
72
- * // infinite inputs (important: closeOut mode = never!)
72
+ * // infinite inputs (important: closeOut mode = "never"!)
73
73
  * const a = fromIterable(
74
74
  * repeat("a"),
75
- * { delay: 100, closeOut: CloseMode.NEVER }
75
+ * { delay: 100, closeOut: "never" }
76
76
  * );
77
77
  * const b = fromIterable(
78
78
  * repeat("b"),
79
- * { delay: 100, closeOut: CloseMode.NEVER }
79
+ * { delay: 100, closeOut: "never" }
80
80
  * );
81
81
  *
82
82
  * // stream selector / switch
package/metastream.js CHANGED
@@ -1,8 +1,5 @@
1
1
  import { assert } from "@thi.ng/errors/assert";
2
- import {
3
- CloseMode,
4
- State
5
- } from "./api.js";
2
+ import { State } from "./api.js";
6
3
  import { __optsWithID } from "./idgen.js";
7
4
  import { Subscription } from "./subscription.js";
8
5
  const metaStream = (factory, opts) => new MetaStream(factory, opts);
@@ -51,7 +48,7 @@ class MetaStream extends Subscription {
51
48
  if (this.stream) {
52
49
  this.detach(true);
53
50
  }
54
- this.closeIn !== CloseMode.NEVER && super.done();
51
+ this.closeIn !== "never" && super.done();
55
52
  }
56
53
  }
57
54
  unsubscribe(sub) {
@@ -61,7 +58,7 @@ class MetaStream extends Subscription {
61
58
  return super.unsubscribe(sub);
62
59
  }
63
60
  detach(force) {
64
- if (force || this.closeOut !== CloseMode.NEVER) {
61
+ if (force || this.closeOut !== "never") {
65
62
  assert(!!this.stream, "input stream already removed");
66
63
  this.stream.unsubscribe(this.sub);
67
64
  delete this.stream;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/rstream",
3
- "version": "8.5.12",
3
+ "version": "9.0.0",
4
4
  "description": "Reactive streams & subscription primitives for constructing dataflow graphs / pipelines",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -42,12 +42,12 @@
42
42
  "dependencies": {
43
43
  "@thi.ng/api": "^8.11.9",
44
44
  "@thi.ng/arrays": "^2.10.0",
45
- "@thi.ng/associative": "^7.0.5",
45
+ "@thi.ng/associative": "^7.0.6",
46
46
  "@thi.ng/atom": "^5.3.9",
47
47
  "@thi.ng/checks": "^3.6.11",
48
48
  "@thi.ng/errors": "^2.5.15",
49
49
  "@thi.ng/logger": "^3.0.19",
50
- "@thi.ng/transducers": "^9.1.1"
50
+ "@thi.ng/transducers": "^9.2.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@microsoft/api-extractor": "^7.47.5",
@@ -219,5 +219,5 @@
219
219
  ],
220
220
  "year": 2017
221
221
  },
222
- "gitHead": "f6e26ea1142525171de5d36b9c3119f2782bb437\n"
222
+ "gitHead": "bb5006182c335294b5c53abf39663d42445c4880\n"
223
223
  }
package/promise.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CloseMode, State } from "./api.js";
1
+ import { State } from "./api.js";
2
2
  import { __optsWithID } from "./idgen.js";
3
3
  import { stream } from "./stream.js";
4
4
  const fromPromise = (src, opts) => {
@@ -18,7 +18,7 @@ const fromPromise = (src, opts) => {
18
18
  err = null;
19
19
  } else {
20
20
  stream2.next(x);
21
- stream2.closeIn !== CloseMode.NEVER && stream2.done();
21
+ stream2.closeIn !== "never" && stream2.done();
22
22
  }
23
23
  }
24
24
  },
package/pubsub.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Fn, Predicate2 } from "@thi.ng/api";
2
2
  import { EquivMap } from "@thi.ng/associative/equiv-map";
3
3
  import type { Transducer } from "@thi.ng/transducers";
4
- import { type ISubscriber, type ISubscription, type TransformableOpts, type WithErrorHandlerOpts } from "./api.js";
4
+ import type { ISubscriber, ISubscription, TransformableOpts, WithErrorHandlerOpts } from "./api.js";
5
5
  import { Subscription } from "./subscription.js";
6
6
  export interface PubSubOpts<A, B, T> {
7
7
  /**
package/pubsub.js CHANGED
@@ -1,8 +1,5 @@
1
1
  import { EquivMap } from "@thi.ng/associative/equiv-map";
2
2
  import { unsupported } from "@thi.ng/errors/unsupported";
3
- import {
4
- CloseMode
5
- } from "./api.js";
6
3
  import { __optsWithID } from "./idgen.js";
7
4
  import { LOGGER } from "./logger.js";
8
5
  import { Subscription, subscription } from "./subscription.js";
@@ -40,9 +37,7 @@ class PubSub extends Subscription {
40
37
  topicID,
41
38
  t = subscription(
42
39
  void 0,
43
- __optsWithID("topic", {
44
- closeOut: CloseMode.NEVER
45
- })
40
+ __optsWithID("topic", { closeOut: "never" })
46
41
  )
47
42
  );
48
43
  return t.subscribe(sub, opts);
package/stream.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Maybe } from "@thi.ng/api";
2
- import { type CommonOpts, type IStream, type ISubscriber, type ISubscription, type StreamCancel, type StreamSource, type TransformableOpts, type WithErrorHandlerOpts } from "./api.js";
2
+ import type { CommonOpts, IStream, ISubscriber, ISubscription, StreamCancel, StreamSource, TransformableOpts, WithErrorHandlerOpts } from "./api.js";
3
3
  import { Subscription } from "./subscription.js";
4
4
  /**
5
5
  * Creates a new {@link Stream} instance, optionally with given `StreamSource`
package/stream.js CHANGED
@@ -1,7 +1,4 @@
1
1
  import { isFunction } from "@thi.ng/checks/is-function";
2
- import {
3
- CloseMode
4
- } from "./api.js";
5
2
  import { __optsWithID } from "./idgen.js";
6
3
  import { LOGGER } from "./logger.js";
7
4
  import { Subscription } from "./subscription.js";
@@ -45,7 +42,7 @@ class Stream extends Subscription {
45
42
  }
46
43
  unsubscribe(sub) {
47
44
  const res = super.unsubscribe(sub);
48
- if (res && (!sub || (!this.subs || !this.subs.length) && this.closeOut !== CloseMode.NEVER)) {
45
+ if (res && (!sub || (!this.subs || !this.subs.length) && this.closeOut !== "never")) {
49
46
  this.cancel();
50
47
  }
51
48
  return res;
package/subscription.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Fn, Maybe } from "@thi.ng/api";
2
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";
3
+ import { State, type CloseMode, type CommonOpts, type ISubscriber, type ISubscription, type SubscriptionOpts, type TransformableOpts, type WithErrorHandlerOpts, type WithTransform } from "./api.js";
4
4
  /**
5
5
  * Creates a new {@link Subscription} instance, the fundamental datatype and
6
6
  * building block provided by this package.
package/subscription.js CHANGED
@@ -9,7 +9,6 @@ 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
11
  import {
12
- CloseMode,
13
12
  State
14
13
  } from "./api.js";
15
14
  import { __optsWithID } from "./idgen.js";
@@ -19,8 +18,8 @@ class Subscription {
19
18
  constructor(wrapped, opts) {
20
19
  this.wrapped = wrapped;
21
20
  opts = __optsWithID(`sub`, {
22
- closeIn: CloseMode.LAST,
23
- closeOut: CloseMode.LAST,
21
+ closeIn: "last",
22
+ closeOut: "last",
24
23
  cache: true,
25
24
  ...opts
26
25
  });
@@ -113,7 +112,7 @@ class Subscription {
113
112
  const idx = this.subs.indexOf(sub);
114
113
  if (idx >= 0) {
115
114
  this.subs.splice(idx, 1);
116
- if (this.closeOut === CloseMode.FIRST || !this.subs.length && this.closeOut !== CloseMode.NEVER) {
115
+ if (this.closeOut === "first" || !this.subs.length && this.closeOut !== "never") {
117
116
  this.unsubscribe();
118
117
  }
119
118
  return true;
@@ -209,7 +208,7 @@ class Subscription {
209
208
  }
210
209
  ensureState() {
211
210
  if (this.state >= State.DONE) {
212
- illegalState(`operation not allowed in state ${this.state}`);
211
+ illegalState(`operation not allowed in state ${State[this.state]}`);
213
212
  }
214
213
  }
215
214
  release() {
package/tween.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Fn2 } from "@thi.ng/api";
2
- import { type ISubscribable } from "./api.js";
2
+ import type { ISubscribable } from "./api.js";
3
3
  /**
4
4
  * Takes an existing stream/subscription `src` and attaches new
5
5
  * subscription which interpolates between incoming values from `src`
package/tween.js CHANGED
@@ -2,7 +2,6 @@ import { isNumber } from "@thi.ng/checks/is-number";
2
2
  import { dedupe } from "@thi.ng/transducers/dedupe";
3
3
  import { reducer } from "@thi.ng/transducers/reduce";
4
4
  import { scan } from "@thi.ng/transducers/scan";
5
- import { CloseMode } from "./api.js";
6
5
  import { fromInterval } from "./interval.js";
7
6
  import { fromRAF } from "./raf.js";
8
7
  import { sync } from "./sync.js";
@@ -11,7 +10,7 @@ const tween = (src, initial, mix, stop, clock) => sync({
11
10
  src,
12
11
  _: clock == null ? fromRAF() : isNumber(clock) ? fromInterval(clock) : clock
13
12
  },
14
- closeIn: CloseMode.FIRST
13
+ closeIn: "first"
15
14
  }).transform(
16
15
  scan(
17
16
  reducer(