@effectionx/stream-helpers 0.4.0 → 0.5.1

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/README.md CHANGED
@@ -192,6 +192,53 @@ function* exampleWithCloseValue() {
192
192
  }
193
193
  ```
194
194
 
195
+ ### Subject
196
+
197
+ Subject helper converts any stream into a multicast stream that replays the
198
+ latest value to new subscribers. It's analogous to
199
+ [RxJS BehaviorSubject](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject).
200
+
201
+ ```typescript
202
+ import { createSubject } from "@effectionx/stream-helpers";
203
+ import { createChannel, spawn } from "effection";
204
+
205
+ function* example() {
206
+ const subject = createSubject<number>();
207
+ const channel = createChannel<number, void>();
208
+ const downstream = subject(channel);
209
+
210
+ // First subscriber
211
+ const sub1 = yield* downstream;
212
+
213
+ yield* channel.send(1);
214
+ yield* channel.send(2);
215
+
216
+ console.log(yield* sub1.next()); // { done: false, value: 1 }
217
+ console.log(yield* sub1.next()); // { done: false, value: 2 }
218
+
219
+ // Late subscriber gets the latest value immediately
220
+ const sub2 = yield* downstream;
221
+ console.log(yield* sub2.next()); // { done: false, value: 2 }
222
+ }
223
+ ```
224
+
225
+ Use it with a pipe operator to convert any stream into a behavior subject:
226
+
227
+ ```typescript
228
+ import { createSubject, map } from "@effectionx/stream-helpers";
229
+ import { pipe } from "remeda";
230
+
231
+ const subject = createSubject<string>();
232
+
233
+ const stream = pipe(
234
+ source,
235
+ map(function* (x) {
236
+ return x.toString();
237
+ }),
238
+ subject,
239
+ );
240
+ ```
241
+
195
242
  ### Passthrough Tracker
196
243
 
197
244
  Passthrough Tracker stream helper provides a way to know if all items that
package/esm/mod.d.ts CHANGED
@@ -4,4 +4,5 @@ export * from "./map.js";
4
4
  export * from "./filter.js";
5
5
  export * from "./tracker.js";
6
6
  export * from "./for-each.js";
7
+ export * from "./subject.js";
7
8
  //# sourceMappingURL=mod.d.ts.map
package/esm/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
package/esm/mod.js CHANGED
@@ -4,3 +4,4 @@ export * from "./map.js";
4
4
  export * from "./filter.js";
5
5
  export * from "./tracker.js";
6
6
  export * from "./for-each.js";
7
+ export * from "./subject.js";
@@ -0,0 +1,38 @@
1
+ import type { Stream } from "effection";
2
+ /**
3
+ * Converts any stream into a multicast stream that produces latest value
4
+ * to new subscribers. It's designed to be analagous in function to [RxJS
5
+ * BehaviorSubject](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject).
6
+ *
7
+ * @returns A function that takes a stream and returns a multicast stream
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const subject = createSubject<number>();
12
+ * const downstream = subject(upstream);
13
+ *
14
+ * const sub1 = yield* downstream; // subscribes to upstream
15
+ * yield* upstream.send(1);
16
+ * yield* sub1.next(); // { done: false, value: 1 }
17
+ *
18
+ * const sub2 = yield* downstream; // late subscriber
19
+ * yield* sub2.next(); // { done: false, value: 1 } - gets latest value
20
+ * ```
21
+ *
22
+ * Use it with a pipe operator to convert any stream into a behavior subject.
23
+ *
24
+ * @example
25
+ * ```
26
+ * let source = createChannel<string, void>();
27
+ * let subject = createSubject<string>();
28
+ *
29
+ * let pipeline = pipe([
30
+ * top,
31
+ * transform1,
32
+ * transform2,
33
+ * subject,
34
+ * ]);
35
+ * ```
36
+ */
37
+ export declare function createSubject<T>(): <TClose>(stream: Stream<T, TClose>) => Stream<T, TClose>;
38
+ //# sourceMappingURL=subject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,WAAW,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,aAAa,CAAC,CAAC,KAAK,CAAC,MAAM,EACzC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KACtB,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAyBrB"}
package/esm/subject.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Converts any stream into a multicast stream that produces latest value
3
+ * to new subscribers. It's designed to be analagous in function to [RxJS
4
+ * BehaviorSubject](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject).
5
+ *
6
+ * @returns A function that takes a stream and returns a multicast stream
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const subject = createSubject<number>();
11
+ * const downstream = subject(upstream);
12
+ *
13
+ * const sub1 = yield* downstream; // subscribes to upstream
14
+ * yield* upstream.send(1);
15
+ * yield* sub1.next(); // { done: false, value: 1 }
16
+ *
17
+ * const sub2 = yield* downstream; // late subscriber
18
+ * yield* sub2.next(); // { done: false, value: 1 } - gets latest value
19
+ * ```
20
+ *
21
+ * Use it with a pipe operator to convert any stream into a behavior subject.
22
+ *
23
+ * @example
24
+ * ```
25
+ * let source = createChannel<string, void>();
26
+ * let subject = createSubject<string>();
27
+ *
28
+ * let pipeline = pipe([
29
+ * top,
30
+ * transform1,
31
+ * transform2,
32
+ * subject,
33
+ * ]);
34
+ * ```
35
+ */
36
+ export function createSubject() {
37
+ let current = undefined;
38
+ return (stream) => ({
39
+ *[Symbol.iterator]() {
40
+ let upstream = yield* stream;
41
+ let iterator = current
42
+ ? {
43
+ *next() {
44
+ iterator = upstream;
45
+ return current;
46
+ },
47
+ }
48
+ : {
49
+ *next() {
50
+ return current = yield* upstream.next();
51
+ },
52
+ };
53
+ return {
54
+ next: () => iterator.next(),
55
+ };
56
+ },
57
+ });
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effectionx/stream-helpers",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "author": "engineering@frontside.com",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,8 +28,8 @@
28
28
  },
29
29
  "sideEffects": false,
30
30
  "dependencies": {
31
- "@effectionx/signals": "0.3.0",
32
- "@effectionx/timebox": "0.2.0",
31
+ "@effectionx/signals": "^0.4.0",
32
+ "@effectionx/timebox": "^0.3.0",
33
33
  "effection": "^3 || ^4.0.0-0"
34
34
  },
35
35
  "_generatedBy": "dnt@dev"
package/script/mod.d.ts CHANGED
@@ -4,4 +4,5 @@ export * from "./map.js";
4
4
  export * from "./filter.js";
5
5
  export * from "./tracker.js";
6
6
  export * from "./for-each.js";
7
+ export * from "./subject.js";
7
8
  //# sourceMappingURL=mod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
package/script/mod.js CHANGED
@@ -20,3 +20,4 @@ __exportStar(require("./map.js"), exports);
20
20
  __exportStar(require("./filter.js"), exports);
21
21
  __exportStar(require("./tracker.js"), exports);
22
22
  __exportStar(require("./for-each.js"), exports);
23
+ __exportStar(require("./subject.js"), exports);
@@ -0,0 +1,38 @@
1
+ import type { Stream } from "effection";
2
+ /**
3
+ * Converts any stream into a multicast stream that produces latest value
4
+ * to new subscribers. It's designed to be analagous in function to [RxJS
5
+ * BehaviorSubject](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject).
6
+ *
7
+ * @returns A function that takes a stream and returns a multicast stream
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const subject = createSubject<number>();
12
+ * const downstream = subject(upstream);
13
+ *
14
+ * const sub1 = yield* downstream; // subscribes to upstream
15
+ * yield* upstream.send(1);
16
+ * yield* sub1.next(); // { done: false, value: 1 }
17
+ *
18
+ * const sub2 = yield* downstream; // late subscriber
19
+ * yield* sub2.next(); // { done: false, value: 1 } - gets latest value
20
+ * ```
21
+ *
22
+ * Use it with a pipe operator to convert any stream into a behavior subject.
23
+ *
24
+ * @example
25
+ * ```
26
+ * let source = createChannel<string, void>();
27
+ * let subject = createSubject<string>();
28
+ *
29
+ * let pipeline = pipe([
30
+ * top,
31
+ * transform1,
32
+ * transform2,
33
+ * subject,
34
+ * ]);
35
+ * ```
36
+ */
37
+ export declare function createSubject<T>(): <TClose>(stream: Stream<T, TClose>) => Stream<T, TClose>;
38
+ //# sourceMappingURL=subject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,WAAW,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,aAAa,CAAC,CAAC,KAAK,CAAC,MAAM,EACzC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KACtB,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAyBrB"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSubject = createSubject;
4
+ /**
5
+ * Converts any stream into a multicast stream that produces latest value
6
+ * to new subscribers. It's designed to be analagous in function to [RxJS
7
+ * BehaviorSubject](https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject).
8
+ *
9
+ * @returns A function that takes a stream and returns a multicast stream
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const subject = createSubject<number>();
14
+ * const downstream = subject(upstream);
15
+ *
16
+ * const sub1 = yield* downstream; // subscribes to upstream
17
+ * yield* upstream.send(1);
18
+ * yield* sub1.next(); // { done: false, value: 1 }
19
+ *
20
+ * const sub2 = yield* downstream; // late subscriber
21
+ * yield* sub2.next(); // { done: false, value: 1 } - gets latest value
22
+ * ```
23
+ *
24
+ * Use it with a pipe operator to convert any stream into a behavior subject.
25
+ *
26
+ * @example
27
+ * ```
28
+ * let source = createChannel<string, void>();
29
+ * let subject = createSubject<string>();
30
+ *
31
+ * let pipeline = pipe([
32
+ * top,
33
+ * transform1,
34
+ * transform2,
35
+ * subject,
36
+ * ]);
37
+ * ```
38
+ */
39
+ function createSubject() {
40
+ let current = undefined;
41
+ return (stream) => ({
42
+ *[Symbol.iterator]() {
43
+ let upstream = yield* stream;
44
+ let iterator = current
45
+ ? {
46
+ *next() {
47
+ iterator = upstream;
48
+ return current;
49
+ },
50
+ }
51
+ : {
52
+ *next() {
53
+ return current = yield* upstream.next();
54
+ },
55
+ };
56
+ return {
57
+ next: () => iterator.next(),
58
+ };
59
+ },
60
+ });
61
+ }