@thi.ng/rstream 9.0.9 → 9.2.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-11-24T18:15:49Z
3
+ - **Last updated**: 2024-12-05T12:02:40Z
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,20 @@ 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.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream@9.2.0) (2024-12-05)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add fromTuple(), update StreamObj impl ([ef691cc](https://github.com/thi-ng/umbrella/commit/ef691cc))
17
+ - update docs
18
+ - add tests
19
+
20
+ ## [9.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream@9.1.0) (2024-12-04)
21
+
22
+ #### 🚀 Features
23
+
24
+ - update fromObject(), re-implement as full subscription ([6903507](https://github.com/thi-ng/umbrella/commit/6903507))
25
+
12
26
  # [9.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream@9.0.0) (2024-08-20)
13
27
 
14
28
  #### 🛑 Breaking changes
package/README.md CHANGED
@@ -215,7 +215,7 @@ For Node.js REPL:
215
215
  const rs = await import("@thi.ng/rstream");
216
216
  ```
217
217
 
218
- Package sizes (brotli'd, pre-treeshake): ESM: 6.28 KB
218
+ Package sizes (brotli'd, pre-treeshake): ESM: 6.34 KB
219
219
 
220
220
  ## Dependencies
221
221
 
@@ -451,6 +451,7 @@ s.next(42);
451
451
  - [fromPromise()](https://docs.thi.ng/umbrella/rstream/functions/fromPromise.html) - single value stream from promise
452
452
  - [fromPromises()](https://docs.thi.ng/umbrella/rstream/functions/fromPromises.html) - results from multiple promise
453
453
  - [fromRAF()](https://docs.thi.ng/umbrella/rstream/functions/fromRAF.html) - requestAnimationFrame() counter (w/ node fallback)
454
+ - [fromTuple()](https://docs.thi.ng/umbrella/rstream/functions/fromTuple.html) - tuple/vector per-component streams
454
455
  - [fromView()](https://docs.thi.ng/umbrella/rstream/functions/fromView.html) - derived view value changes (see [@thi.ng/atom](https://github.com/thi-ng/umbrella/tree/develop/packages/atom))
455
456
  - [fromWorker()](https://docs.thi.ng/umbrella/rstream/functions/fromWorker.html) - messages received from worker
456
457
  - [toggle()](https://docs.thi.ng/umbrella/rstream/functions/toggle.html) - on/off switch-like stream
package/object.d.ts CHANGED
@@ -1,29 +1,9 @@
1
- import type { Keys, Predicate2 } from "@thi.ng/api";
1
+ import type { IObjectOf, Keys, NumOrString, Predicate2 } from "@thi.ng/api";
2
2
  import type { CommonOpts, ISubscription } from "./api.js";
3
+ import { Subscription } from "./subscription.js";
3
4
  export type KeyStreams<T, K extends Keys<T>> = {
4
5
  [id in K]-?: ISubscription<T[id], T[id]>;
5
6
  };
6
- /**
7
- * Result object type for {@link fromObject}.
8
- */
9
- export interface StreamObj<T, K extends Keys<T>> {
10
- /**
11
- * Object of managed & typed streams for registered keys.
12
- */
13
- streams: KeyStreams<T, K>;
14
- /**
15
- * Feeds new values from `x` to each registered key's stream.
16
- * Satifies {@link ISubscriber.next} interface.
17
- *
18
- * @param x -
19
- */
20
- next(x: T): void;
21
- /**
22
- * Calls {@link ISubscriber.done} for all streams created. Satifies
23
- * {@link ISubscriber.done} interface.
24
- */
25
- done(): void;
26
- }
27
7
  export interface StreamObjOpts<T, K extends Keys<T>> extends CommonOpts {
28
8
  /**
29
9
  * Array of selected `keys` (else selects all by default) for which
@@ -58,36 +38,26 @@ export interface StreamObjOpts<T, K extends Keys<T>> extends CommonOpts {
58
38
  }
59
39
  /**
60
40
  * Takes an arbitrary object `src` and object of options (see
61
- * {@link StreamObjOpts}). Creates a new object and for each selected
62
- * key creates a new stream, optionally seeded with the key's value in
63
- * `src`. Returns new object of streams.
41
+ * {@link StreamObjOpts}). Creates a new object and for each selected key
42
+ * creates a new subscription, optionally seeded with the key's value in `src`.
43
+ * Returns new {@link StreamObj}.
64
44
  *
65
45
  * @remarks
66
- * The structure of the returned object is
67
- * {@link StreamObj | as follows}:
68
- *
69
- * ```text
70
- * {
71
- * streams: { ... },
72
- * next(x): void;
73
- * done(): void;
74
- * }
75
- * ```
76
- *
77
- * All streams will be stored under `streams`. The `next()` and `done()`
78
- * functions/methods allow the object itself to be used as subscriber
79
- * for an upstream subscribable (see 2nd example below):
80
- *
81
- * - `next()` - takes a object of same type as `src` and feeds each
82
- * key's new value into its respective stream. If the `defaults`
83
- * option is given, `undefined` key values are replaced with their
84
- * specified default. If `dedupe` is enabled (default) only changed
85
- * values (as per `equiv` predicate option) will be propagated
86
- * downstream.
87
- * - `done()` - calls {@link ISubscriber.done} on all streams
88
- *
89
- * The optional `opts` arg is used to customize overall behavior of
90
- * `fromObject` and specify shared options for *all* created streams.
46
+ * The optional `opts` arg is used to customize overall behavior of `fromObject`
47
+ * and specify shared options for *all* created streams.
48
+ *
49
+ * A {@link StreamObj} is a full {@link Subscription}, in which additionally all
50
+ * configured key streams are exposed under `streams`. The
51
+ * {@link StreamObj.next} and {@link StreamObj.done} methods allow the
52
+ * {@link StreamObj} itself to be used as subscriber for an upstream
53
+ * subscribable (see 2nd example below):
54
+ *
55
+ * {@link StreamObj.next} receives an object of same type as `src` and feeds
56
+ * each key's new value into its respective {@link StreamObj.streams}. If the
57
+ * {@link StreamObjOpts.defaults} option is given, `undefined` key values are
58
+ * replaced with their specified default. If {@link StreamObjOpts.dedupe} is
59
+ * enabled (default) only changed values (as per {@link StreamObjOpts.equiv}
60
+ * predicate option) will be propagated downstream.
91
61
  *
92
62
  * @example
93
63
  * ```ts tangle:../export/from-object.ts
@@ -119,7 +89,7 @@ export interface StreamObjOpts<T, K extends Keys<T>> extends CommonOpts {
119
89
  * obj.streams.b.subscribe(trace("b"));
120
90
  *
121
91
  * const src = subscription<Foo, Foo>();
122
- * // use as subscriber
92
+ * // use `obj` as subscription itself
123
93
  * src.subscribe(obj);
124
94
  *
125
95
  * src.next({ a: 1, b: "foo" });
@@ -131,4 +101,48 @@ export interface StreamObjOpts<T, K extends Keys<T>> extends CommonOpts {
131
101
  * @param opts -
132
102
  */
133
103
  export declare const fromObject: <T extends object, K extends Keys<T>>(src: T, opts?: Partial<StreamObjOpts<T, K>>) => StreamObj<T, K>;
104
+ /**
105
+ * Syntax sugar for {@link fromObject} for tuple/arrays. Returns a
106
+ * {@link StreamObj} which provides individual subscriptions for each tuple
107
+ * element, i.e. 1:N fanout.
108
+ *
109
+ * ```ts tangle:../export/from-tuple.ts
110
+ * import { fromTuple, subscription, trace } from "@thi.ng/rstream";
111
+ *
112
+ * const tup = fromTuple([1, 2, 3]);
113
+ *
114
+ * tup.streams[0].subscribe(trace("[0]:"));
115
+ * tup.streams[1].subscribe(trace("[1]:"));
116
+ * tup.streams[2].subscribe(trace("[2]:"));
117
+ * ```
118
+ * @param src
119
+ * @param opts
120
+ */
121
+ export declare const fromTuple: <T>(src: T[], opts?: Partial<StreamObjOpts<T[], number>>) => StreamObj<T[], number>;
122
+ /**
123
+ * See {@link fromObject} for details.
124
+ */
125
+ export declare class StreamObj<T extends object, K extends Keys<T>> extends Subscription<T, T> {
126
+ /**
127
+ * Object of managed & typed streams for registered keys.
128
+ */
129
+ keys: NumOrString[];
130
+ streams: IObjectOf<Subscription<any, any>>;
131
+ defaults?: Partial<T>;
132
+ constructor(src: T, opts?: Partial<StreamObjOpts<T, K>>);
133
+ /**
134
+ * Receives an object of configured type and feeds each key's new value into
135
+ * its respective {@link StreamObj.streams}. If the
136
+ * {@link StreamObjOpts.defaults} option is given, `undefined` key values
137
+ * are replaced with their specified default. If
138
+ * {@link StreamObjOpts.dedupe} is enabled (default) only changed values (as
139
+ * per {@link StreamObjOpts.equiv} predicate option) will be propagated
140
+ * downstream.
141
+ *
142
+ * @param x -
143
+ */
144
+ next(x: T): void;
145
+ done(): void;
146
+ unsubscribe(sub?: ISubscription<T, any> | undefined): boolean;
147
+ }
134
148
  //# sourceMappingURL=object.d.ts.map
package/object.js CHANGED
@@ -1,39 +1,70 @@
1
1
  import { dedupe } from "@thi.ng/transducers/dedupe";
2
- import { __nextID } from "./idgen.js";
3
- import { subscription } from "./subscription.js";
4
- const fromObject = (src, opts = {}) => {
5
- const id = opts.id || `obj${__nextID()}`;
6
- const keys = opts.keys || Object.keys(src);
7
- const _opts = opts.dedupe !== false ? {
8
- xform: dedupe(opts.equiv || ((a, b) => a === b)),
9
- ...opts
10
- } : opts;
11
- const streams = {};
12
- for (let k of keys) {
13
- streams[k] = subscription(void 0, {
14
- ..._opts,
15
- id: `${id}-${String(k)}`
16
- });
2
+ import { __optsWithID } from "./idgen.js";
3
+ import { Subscription, subscription } from "./subscription.js";
4
+ import { range } from "@thi.ng/transducers";
5
+ const fromObject = (src, opts = {}) => new StreamObj(src, opts);
6
+ const fromTuple = (src, opts) => new StreamObj(src, { keys: [...range(src.length)], ...opts });
7
+ class StreamObj extends Subscription {
8
+ /**
9
+ * Object of managed & typed streams for registered keys.
10
+ */
11
+ keys;
12
+ streams = {};
13
+ defaults;
14
+ constructor(src, opts = {}) {
15
+ super(void 0, __optsWithID("obj", opts));
16
+ this.keys = opts.keys || Object.keys(src);
17
+ this.defaults = opts.defaults;
18
+ const _opts = opts.dedupe !== false ? {
19
+ xform: dedupe(opts.equiv || ((a, b) => a === b)),
20
+ ...opts
21
+ } : opts;
22
+ for (let k of this.keys) {
23
+ this.streams[k] = subscription(void 0, {
24
+ ..._opts,
25
+ id: `${this.id}-${k}`
26
+ });
27
+ }
28
+ opts.initial !== false && this.next(src);
17
29
  }
18
- const res = {
19
- streams,
20
- next(state) {
21
- for (let k of keys) {
22
- const val = state[k];
23
- streams[k].next(
24
- opts.defaults && val === void 0 ? opts.defaults[k] : val
25
- );
26
- }
27
- },
28
- done() {
29
- for (let k of keys) {
30
- streams[k].done();
30
+ /**
31
+ * Receives an object of configured type and feeds each key's new value into
32
+ * its respective {@link StreamObj.streams}. If the
33
+ * {@link StreamObjOpts.defaults} option is given, `undefined` key values
34
+ * are replaced with their specified default. If
35
+ * {@link StreamObjOpts.dedupe} is enabled (default) only changed values (as
36
+ * per {@link StreamObjOpts.equiv} predicate option) will be propagated
37
+ * downstream.
38
+ *
39
+ * @param x -
40
+ */
41
+ next(x) {
42
+ this.cacheLast && (this.last = x);
43
+ for (let k of this.keys) {
44
+ const val = x[k];
45
+ this.streams[k].next(
46
+ this.defaults && val === void 0 ? this.defaults[k] : val
47
+ );
48
+ }
49
+ super.next(x);
50
+ }
51
+ done() {
52
+ for (let k of this.keys) {
53
+ this.streams[k].done();
54
+ }
55
+ super.done();
56
+ }
57
+ unsubscribe(sub) {
58
+ if (!sub) {
59
+ for (let k of this.keys) {
60
+ this.streams[k].unsubscribe();
31
61
  }
32
62
  }
33
- };
34
- opts.initial !== false && res.next(src);
35
- return res;
36
- };
63
+ return super.unsubscribe(sub);
64
+ }
65
+ }
37
66
  export {
38
- fromObject
67
+ StreamObj,
68
+ fromObject,
69
+ fromTuple
39
70
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/rstream",
3
- "version": "9.0.9",
3
+ "version": "9.2.0",
4
4
  "description": "Reactive streams & subscription primitives for constructing dataflow graphs / pipelines",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -219,5 +219,5 @@
219
219
  ],
220
220
  "year": 2017
221
221
  },
222
- "gitHead": "85e2f0935b58bde5d165fbe754fafec5da0b731e\n"
222
+ "gitHead": "b3cc41cd55dd21cf672c2567b748b0a632b01d76\n"
223
223
  }