@thi.ng/transducers 8.4.7 → 8.5.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**: 2023-06-14T07:58:51Z
3
+ - **Last updated**: 2023-08-04T10:58:19Z
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
+ ## [8.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/transducers@8.5.0) (2023-08-04)
13
+
14
+ #### 🚀 Features
15
+
16
+ - fix [#401](https://github.com/thi-ng/umbrella/issues/401), update multiplex(), step() ([834b076](https://github.com/thi-ng/umbrella/commit/834b076))
17
+ - add optional support to override single-result unwrapping behavior
18
+ - update docstrings/examples
19
+ - add tests
20
+
21
+ #### ♻️ Refactoring
22
+
23
+ - update `identity` usage in various pkgs ([b6db053](https://github.com/thi-ng/umbrella/commit/b6db053))
24
+ - minor internal updates ([5ffdcbb](https://github.com/thi-ng/umbrella/commit/5ffdcbb))
25
+
12
26
  ## [8.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/transducers@8.4.0) (2023-03-19)
13
27
 
14
28
  #### 🚀 Features
package/README.md CHANGED
@@ -173,7 +173,7 @@ For Node.js REPL:
173
173
  const transducers = await import("@thi.ng/transducers");
174
174
  ```
175
175
 
176
- Package sizes (brotli'd, pre-treeshake): ESM: 8.64 KB
176
+ Package sizes (brotli'd, pre-treeshake): ESM: 8.70 KB
177
177
 
178
178
  ## Dependencies
179
179
 
@@ -206,6 +206,7 @@ A selection:
206
206
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/dominant-colors.png" width="240"/> | Color palette generation via dominant color extraction from uploaded images | [Demo](https://demo.thi.ng/umbrella/dominant-colors/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/dominant-colors) |
207
207
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ellipse-proximity.png" width="240"/> | Interactive visualization of closest points on ellipses | [Demo](https://demo.thi.ng/umbrella/ellipse-proximity/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ellipse-proximity) |
208
208
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fft-synth.png" width="240"/> | Interactive inverse FFT toy synth | [Demo](https://demo.thi.ng/umbrella/fft-synth/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/fft-synth) |
209
+ | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fiber-basics.png" width="240"/> | Fiber-based cooperative multitasking basics | [Demo](https://demo.thi.ng/umbrella/fiber-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/fiber-basics) |
209
210
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/grid-iterators.png" width="240"/> | Visualization of different grid iterator strategies | [Demo](https://demo.thi.ng/umbrella/grid-iterators/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/grid-iterators) |
210
211
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hdom-benchmark2.png" width="240"/> | hdom update performance benchmark w/ config options | [Demo](https://demo.thi.ng/umbrella/hdom-benchmark2/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-benchmark2) |
211
212
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hdom-canvas-clock.png" width="240"/> | Realtime analog clock demo | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-clock/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-clock) |
package/api.d.ts CHANGED
@@ -1,11 +1,19 @@
1
- import type { Comparator, Fn, IObjectOf } from "@thi.ng/api";
1
+ import type { Comparator, Fn, Fn0, IObjectOf } from "@thi.ng/api";
2
2
  import type { Reduced } from "./reduced.js";
3
3
  export type Transducer<A, B> = (rfn: Reducer<any, B>) => Reducer<any, A>;
4
+ /**
5
+ * A transducer or a custom type with a {@link IXform} implementation.
6
+ */
4
7
  export type TxLike<A, B> = Transducer<A, B> | IXform<A, B>;
8
+ /**
9
+ * Custom version of {@link TxLike} for use with {@link multiplex} and
10
+ * {@link multiplexObj}.
11
+ */
12
+ export type MultiplexTxLike<T, A> = TxLike<T, A> | [TxLike<T, A>, boolean];
5
13
  export type ReductionFn<A, B> = (acc: A, x: B) => A | Reduced<A>;
6
14
  export interface Reducer<A, B> extends Array<any> {
7
- [0]: () => A;
8
- [1]: (acc: A) => A;
15
+ [0]: Fn0<A>;
16
+ [1]: Fn<A, A>;
9
17
  [2]: ReductionFn<A, B>;
10
18
  }
11
19
  /**
@@ -15,7 +23,7 @@ export interface Reducer<A, B> extends Array<any> {
15
23
  * functions in this package where a `Transducer` arg is expected.
16
24
  *
17
25
  * @example
18
- * ```
26
+ * ```ts
19
27
  * class Mul implements IXform<number, number> {
20
28
  * constructor(public factor = 10) {}
21
29
  *
package/flatten1.js CHANGED
@@ -1,4 +1,5 @@
1
+ import { identity } from "@thi.ng/api/fn";
1
2
  import { mapcat } from "./mapcat.js";
2
3
  export function flatten1(src) {
3
- return mapcat((x) => x, src);
4
+ return mapcat((identity), src);
4
5
  }
package/labeled.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import type { Fn } from "@thi.ng/api";
1
2
  import type { Transducer } from "./api.js";
2
- export type LabelFn<L, T> = L | ((x: T) => L);
3
+ export type LabelFn<L, T> = L | Fn<T, L>;
3
4
  export declare function labeled<L, T>(id: LabelFn<L, T>): Transducer<T, [L, T]>;
4
5
  export declare function labeled<L, T>(id: LabelFn<L, T>, src: Iterable<T>): IterableIterator<[L, T]>;
5
6
  //# sourceMappingURL=labeled.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type { IObjectOf } from "@thi.ng/api";
2
- import type { Reducer, Transducer, TxLike } from "./api.js";
2
+ import type { MultiplexTxLike, Reducer, Transducer } from "./api.js";
3
3
  /**
4
4
  * Transducer. Similar to (and building on) {@link multiplex}, but takes an
5
5
  * object of transducers and produces a result object for each input.
@@ -12,19 +12,18 @@ import type { Reducer, Transducer, TxLike } from "./api.js";
12
12
  * upper: map(x => x.toUpperCase()),
13
13
  * length: map(x => x.length)
14
14
  * },
15
- * ["Alice", "Bob", "Charlie", "Andy"]
15
+ * ["Alice", "Bob", "Charlie"]
16
16
  * )]
17
17
  * // [ { length: 5, upper: 'ALICE', initial: 'A' },
18
18
  * // { length: 3, upper: 'BOB', initial: 'B' },
19
- * // { length: 7, upper: 'CHARLIE', initial: 'C' },
20
- * // { length: 4, upper: 'ANDY', initial: 'A' } ]
19
+ * // { length: 7, upper: 'CHARLIE', initial: 'C' } ]
21
20
  * ```
22
21
  *
23
22
  * @param xforms - object of transducers
24
23
  * @param rfn -
25
24
  * @param src -
26
25
  */
27
- export declare function multiplexObj<A, B>(xforms: IObjectOf<TxLike<A, any>>, rfn?: Reducer<B, [PropertyKey, any]>): Transducer<A, B>;
28
- export declare function multiplexObj<A, B>(xforms: IObjectOf<TxLike<A, any>>, src: Iterable<A>): IterableIterator<B>;
29
- export declare function multiplexObj<A, B>(xforms: IObjectOf<TxLike<A, any>>, rfn: Reducer<B, [PropertyKey, any]>, src: Iterable<A>): IterableIterator<B>;
26
+ export declare function multiplexObj<A, B>(xforms: IObjectOf<MultiplexTxLike<A, any>>, rfn?: Reducer<B, [PropertyKey, any]>): Transducer<A, B>;
27
+ export declare function multiplexObj<A, B>(xforms: IObjectOf<MultiplexTxLike<A, any>>, src: Iterable<A>): IterableIterator<B>;
28
+ export declare function multiplexObj<A, B>(xforms: IObjectOf<MultiplexTxLike<A, any>>, rfn: Reducer<B, [PropertyKey, any]>, src: Iterable<A>): IterableIterator<B>;
30
29
  //# sourceMappingURL=multiplex-obj.d.ts.map
package/multiplex.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Transducer, TxLike } from "./api.js";
1
+ import type { MultiplexTxLike, Transducer } from "./api.js";
2
2
  /**
3
3
  * Yields a new transducer which applies given transducers in parallel (using
4
4
  * [`juxt()`](https://docs.thi.ng/umbrella/compose/functions/juxt.html) &
@@ -8,6 +8,12 @@ import type { Transducer, TxLike } from "./api.js";
8
8
  * Use the {@link noop} transducer for processing lanes which should retain the
9
9
  * original input values.
10
10
  *
11
+ * **Important note for transducers which are producing multiple (possibly
12
+ * varying number of) outputs for each received input:** If only a single output
13
+ * is produced per step, the default behavior of {@link step} is to unwrap it,
14
+ * i.e. `[42]` => `42`. To override this behavior, individual transducers given
15
+ * to `multiplex()` can be given as tuple `[xform, false]` (see 2nd example below).
16
+ *
11
17
  * @example
12
18
  * ```ts
13
19
  * [...iterator(
@@ -16,19 +22,41 @@ import type { Transducer, TxLike } from "./api.js";
16
22
  * map(x => x.toUpperCase()),
17
23
  * map(x => x.length)
18
24
  * ),
19
- * ["Alice", "Bob", "Charlie", "Andy"]
25
+ * ["Alice", "Bob", "Charlie"]
20
26
  * )]
27
+ *
21
28
  * // [ [ "A", "ALICE", 5 ], [ "B", "BOB", 3 ], [ "C", "CHARLIE", 7 ] ]
22
29
  * ```
23
30
  *
31
+ * @example
32
+ * ```ts
33
+ * [...iterator(
34
+ * multiplex(
35
+ * // override default unwrap behavior for this transducer
36
+ * // (i.e. here to ensure results are always arrays)
37
+ * [mapcat((x) => x), false],
38
+ * // use default behavior for this
39
+ * map((x) => x),
40
+ * ),
41
+ * [[1, 2], [3]]
42
+ * )]
43
+ *
44
+ * // [ [ [ 1, 2 ], [ 1, 2 ] ], [ [ 3 ], [ 3 ] ] ]
45
+ *
46
+ * // to compare: using the default behavior would produce this instead
47
+ * // (note the difference in the last result):
48
+ *
49
+ * // [ [ [ 1, 2 ], [ 1, 2 ] ], [ 3, [ 3 ] ] ]
50
+ * ```
51
+ *
24
52
  * @param a -
25
53
  */
26
- export declare function multiplex<T, A>(a: TxLike<T, A>): Transducer<T, [A]>;
27
- export declare function multiplex<T, A, B>(a: TxLike<T, A>, b: TxLike<T, B>): Transducer<T, [A, B]>;
28
- export declare function multiplex<T, A, B, C>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>): Transducer<T, [A, B, C]>;
29
- export declare function multiplex<T, A, B, C, D>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>, d: TxLike<T, D>): Transducer<T, [A, B, C, D]>;
30
- export declare function multiplex<T, A, B, C, D, E>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>, d: TxLike<T, D>, e: TxLike<T, E>): Transducer<T, [A, B, C, D, E]>;
31
- export declare function multiplex<T, A, B, C, D, E, F>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>, d: TxLike<T, D>, e: TxLike<T, E>, f: TxLike<T, F>): Transducer<T, [A, B, C, D, E, F]>;
32
- export declare function multiplex<T, A, B, C, D, E, F, G>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>, d: TxLike<T, D>, e: TxLike<T, E>, f: TxLike<T, F>, g: TxLike<T, G>): Transducer<T, [A, B, C, D, E, F, G]>;
33
- export declare function multiplex<T, A, B, C, D, E, F, G, H>(a: TxLike<T, A>, b: TxLike<T, B>, c: TxLike<T, C>, d: TxLike<T, D>, e: TxLike<T, E>, f: TxLike<T, F>, g: TxLike<T, G>, h: TxLike<T, H>): Transducer<T, [A, B, C, D, E, F, G, H]>;
54
+ export declare function multiplex<T, A>(a: MultiplexTxLike<T, A>): Transducer<T, [A]>;
55
+ export declare function multiplex<T, A, B>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>): Transducer<T, [A, B]>;
56
+ export declare function multiplex<T, A, B, C>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>): Transducer<T, [A, B, C]>;
57
+ export declare function multiplex<T, A, B, C, D>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>, d: MultiplexTxLike<T, D>): Transducer<T, [A, B, C, D]>;
58
+ export declare function multiplex<T, A, B, C, D, E>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>, d: MultiplexTxLike<T, D>, e: MultiplexTxLike<T, E>): Transducer<T, [A, B, C, D, E]>;
59
+ export declare function multiplex<T, A, B, C, D, E, F>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>, d: MultiplexTxLike<T, D>, e: MultiplexTxLike<T, E>, f: MultiplexTxLike<T, F>): Transducer<T, [A, B, C, D, E, F]>;
60
+ export declare function multiplex<T, A, B, C, D, E, F, G>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>, d: MultiplexTxLike<T, D>, e: MultiplexTxLike<T, E>, f: MultiplexTxLike<T, F>, g: MultiplexTxLike<T, G>): Transducer<T, [A, B, C, D, E, F, G]>;
61
+ export declare function multiplex<T, A, B, C, D, E, F, G, H>(a: MultiplexTxLike<T, A>, b: MultiplexTxLike<T, B>, c: MultiplexTxLike<T, C>, d: MultiplexTxLike<T, D>, e: MultiplexTxLike<T, E>, f: MultiplexTxLike<T, F>, g: MultiplexTxLike<T, G>, h: MultiplexTxLike<T, H>): Transducer<T, [A, B, C, D, E, F, G, H]>;
34
62
  //# sourceMappingURL=multiplex.d.ts.map
package/multiplex.js CHANGED
@@ -2,5 +2,5 @@ import { juxt } from "@thi.ng/compose/juxt";
2
2
  import { map } from "./map.js";
3
3
  import { step } from "./step.js";
4
4
  export function multiplex(...args) {
5
- return map(juxt.apply(null, args.map(step)));
5
+ return map(juxt.apply(null, (args.map((xf) => Array.isArray(xf) ? step(xf[0], xf[1]) : step(xf)))));
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/transducers",
3
- "version": "8.4.7",
3
+ "version": "8.5.0",
4
4
  "description": "Lightweight transducer implementations for ES6 / TypeScript",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -38,22 +38,22 @@
38
38
  "test": "testament test"
39
39
  },
40
40
  "dependencies": {
41
- "@thi.ng/api": "^8.8.2",
42
- "@thi.ng/arrays": "^2.5.14",
43
- "@thi.ng/checks": "^3.3.14",
44
- "@thi.ng/compare": "^2.1.32",
45
- "@thi.ng/compose": "^2.1.34",
46
- "@thi.ng/errors": "^2.2.17",
47
- "@thi.ng/math": "^5.5.0",
48
- "@thi.ng/random": "^3.5.0"
41
+ "@thi.ng/api": "^8.9.0",
42
+ "@thi.ng/arrays": "^2.5.15",
43
+ "@thi.ng/checks": "^3.4.0",
44
+ "@thi.ng/compare": "^2.1.33",
45
+ "@thi.ng/compose": "^2.1.35",
46
+ "@thi.ng/errors": "^2.3.0",
47
+ "@thi.ng/math": "^5.5.1",
48
+ "@thi.ng/random": "^3.5.1"
49
49
  },
50
50
  "devDependencies": {
51
- "@microsoft/api-extractor": "^7.35.3",
52
- "@thi.ng/testament": "^0.3.17",
51
+ "@microsoft/api-extractor": "^7.36.3",
52
+ "@thi.ng/testament": "^0.3.18",
53
53
  "rimraf": "^5.0.1",
54
54
  "tools": "^0.0.1",
55
55
  "typedoc": "^0.24.8",
56
- "typescript": "^5.1.3"
56
+ "typescript": "^5.1.6"
57
57
  },
58
58
  "keywords": [
59
59
  "2d",
@@ -574,5 +574,5 @@
574
574
  ],
575
575
  "year": 2016
576
576
  },
577
- "gitHead": "88cfe77770f3b07c788301dccefcb9547cd4aff6\n"
577
+ "gitHead": "9fa3f7f8169efa30e3c71b43c82f77393581c3b5\n"
578
578
  }
package/repeatedly.d.ts CHANGED
@@ -9,6 +9,7 @@ import type { Fn } from "@thi.ng/api";
9
9
  * [...repeatedly(() => Math.floor(Math.random() * 10), 5)]
10
10
  * // [7, 0, 9, 3, 1]
11
11
  *
12
+ * // same result as range(5)
12
13
  * [...repeatedly((i) => i, 5)]
13
14
  * // [0, 1, 2, 3, 4]
14
15
  * ```
package/repeatedly.js CHANGED
@@ -8,6 +8,7 @@
8
8
  * [...repeatedly(() => Math.floor(Math.random() * 10), 5)]
9
9
  * // [7, 0, 9, 3, 1]
10
10
  *
11
+ * // same result as range(5)
11
12
  * [...repeatedly((i) => i, 5)]
12
13
  * // [0, 1, 2, 3, 4]
13
14
  * ```
package/step.d.ts CHANGED
@@ -1,25 +1,38 @@
1
+ import type { Fn } from "@thi.ng/api";
1
2
  import type { TxLike } from "./api.js";
2
3
  /**
3
- * Single-step transducer execution wrapper.
4
- * Returns array if transducer produces multiple results
5
- * and undefined if there was no output. Else returns single
6
- * result value.
4
+ * Single-step transducer execution wrapper. Returns array if the given
5
+ * transducer produces multiple results and undefined if there was no output. If
6
+ * the transducer only produces a single result (per step) and if `unwrap`
7
+ * is true (default), the function returns that single result value itself.
7
8
  *
8
9
  * @remarks
9
- * Likewise, once a transducer has produced a final / reduced
10
- * value, all further invocations of the stepper function will
11
- * return undefined.
10
+ * Likewise, once a transducer has produced a final / reduced value, all further
11
+ * invocations of the stepper function will return undefined.
12
12
  *
13
13
  * @example
14
14
  * ```ts
15
- * // single result
15
+ * // single result (unwrapped, default)
16
16
  * step(map(x => x * 10))(1);
17
17
  * // 10
18
18
  *
19
+ * // single result (no unwrapping)
20
+ * step(map(x => x * 10), false)(1);
21
+ * // [10]
22
+ *
19
23
  * // multiple results
20
24
  * step(mapcat(x => [x, x + 1, x + 2]))(1)
21
25
  * // [ 1, 2, 3 ]
22
26
  *
27
+ * // multiple results (default behavior)
28
+ * step(mapcat(x => x))([1, 2])
29
+ * // [1, 2]
30
+ * step(mapcat(x => x))([3])
31
+ * // 3
32
+ * // ...once more without unwrapping
33
+ * step(mapcat(x => x), false)([3])
34
+ * // [3]
35
+ *
23
36
  * // no result
24
37
  * f = step(filter((x) => !(x & 1)))
25
38
  * f(1); // undefined
@@ -34,6 +47,7 @@ import type { TxLike } from "./api.js";
34
47
  * ```
35
48
  *
36
49
  * @param tx -
50
+ * @param unwrap -
37
51
  */
38
- export declare const step: <A, B>(tx: TxLike<A, B>) => (x: A) => B | B[];
52
+ export declare const step: <A, B>(tx: TxLike<A, B>, unwrap?: boolean) => Fn<A, B | B[]>;
39
53
  //# sourceMappingURL=step.d.ts.map
package/step.js CHANGED
@@ -2,26 +2,38 @@ import { ensureTransducer } from "./ensure.js";
2
2
  import { push } from "./push.js";
3
3
  import { isReduced } from "./reduced.js";
4
4
  /**
5
- * Single-step transducer execution wrapper.
6
- * Returns array if transducer produces multiple results
7
- * and undefined if there was no output. Else returns single
8
- * result value.
5
+ * Single-step transducer execution wrapper. Returns array if the given
6
+ * transducer produces multiple results and undefined if there was no output. If
7
+ * the transducer only produces a single result (per step) and if `unwrap`
8
+ * is true (default), the function returns that single result value itself.
9
9
  *
10
10
  * @remarks
11
- * Likewise, once a transducer has produced a final / reduced
12
- * value, all further invocations of the stepper function will
13
- * return undefined.
11
+ * Likewise, once a transducer has produced a final / reduced value, all further
12
+ * invocations of the stepper function will return undefined.
14
13
  *
15
14
  * @example
16
15
  * ```ts
17
- * // single result
16
+ * // single result (unwrapped, default)
18
17
  * step(map(x => x * 10))(1);
19
18
  * // 10
20
19
  *
20
+ * // single result (no unwrapping)
21
+ * step(map(x => x * 10), false)(1);
22
+ * // [10]
23
+ *
21
24
  * // multiple results
22
25
  * step(mapcat(x => [x, x + 1, x + 2]))(1)
23
26
  * // [ 1, 2, 3 ]
24
27
  *
28
+ * // multiple results (default behavior)
29
+ * step(mapcat(x => x))([1, 2])
30
+ * // [1, 2]
31
+ * step(mapcat(x => x))([3])
32
+ * // 3
33
+ * // ...once more without unwrapping
34
+ * step(mapcat(x => x), false)([3])
35
+ * // [3]
36
+ *
25
37
  * // no result
26
38
  * f = step(filter((x) => !(x & 1)))
27
39
  * f(1); // undefined
@@ -36,8 +48,9 @@ import { isReduced } from "./reduced.js";
36
48
  * ```
37
49
  *
38
50
  * @param tx -
51
+ * @param unwrap -
39
52
  */
40
- export const step = (tx) => {
53
+ export const step = (tx, unwrap = true) => {
41
54
  const { 1: complete, 2: reduce } = ensureTransducer(tx)(push());
42
55
  let done = false;
43
56
  return (x) => {
@@ -47,7 +60,11 @@ export const step = (tx) => {
47
60
  if (done) {
48
61
  acc = complete(acc.deref());
49
62
  }
50
- return acc.length === 1 ? acc[0] : acc.length > 0 ? acc : undefined;
63
+ return acc.length === 1 && unwrap
64
+ ? acc[0]
65
+ : acc.length > 0
66
+ ? acc
67
+ : undefined;
51
68
  }
52
69
  };
53
70
  };