@johnhenry/iteration 0.0.0 → 0.0.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.
Files changed (49) hide show
  1. package/dist/async-channel.d.ts +24 -4
  2. package/dist/async-channel.d.ts.map +1 -1
  3. package/dist/async-channel.js +41 -38
  4. package/dist/async-channel.js.map +1 -1
  5. package/dist/combine.d.ts +146 -0
  6. package/dist/combine.d.ts.map +1 -0
  7. package/dist/combine.js +353 -0
  8. package/dist/combine.js.map +1 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/internal.d.ts +66 -0
  14. package/dist/internal.d.ts.map +1 -0
  15. package/dist/internal.js +134 -0
  16. package/dist/internal.js.map +1 -0
  17. package/dist/iterator-tools.d.ts.map +1 -1
  18. package/dist/iterator-tools.js +38 -18
  19. package/dist/iterator-tools.js.map +1 -1
  20. package/dist/itertools.d.ts.map +1 -1
  21. package/dist/itertools.js +42 -24
  22. package/dist/itertools.js.map +1 -1
  23. package/dist/tee.d.ts +24 -2
  24. package/dist/tee.d.ts.map +1 -1
  25. package/dist/tee.js +175 -2
  26. package/dist/tee.js.map +1 -1
  27. package/dist/time.d.ts +69 -0
  28. package/dist/time.d.ts.map +1 -0
  29. package/dist/time.js +234 -0
  30. package/dist/time.js.map +1 -0
  31. package/dist/transduce.d.ts +49 -0
  32. package/dist/transduce.d.ts.map +1 -1
  33. package/dist/transduce.js +27 -1
  34. package/dist/transduce.js.map +1 -1
  35. package/dist/transducers.d.ts.map +1 -1
  36. package/dist/transducers.js +32 -14
  37. package/dist/transducers.js.map +1 -1
  38. package/package.json +10 -2
  39. package/readme.md +304 -14
  40. package/src/async-channel.ts +63 -47
  41. package/src/combine.ts +441 -0
  42. package/src/index.ts +2 -0
  43. package/src/internal.ts +164 -0
  44. package/src/iterator-tools.ts +35 -20
  45. package/src/itertools.ts +36 -23
  46. package/src/tee.ts +202 -2
  47. package/src/time.ts +262 -0
  48. package/src/transduce.ts +91 -1
  49. package/src/transducers.ts +34 -19
@@ -8,6 +8,21 @@
8
8
 
9
9
  import { HALT, type ReducerStep, type Transducer } from "./iterator-tools.ts";
10
10
 
11
+ /**
12
+ * Give a stateless transducer's step the inner step's `.complete`, so the
13
+ * end-of-source flush cascades through it to a stateful transducer further
14
+ * down the pipeline (e.g. the trailing partial group in
15
+ * `transduceSync(map(f), group(2))`). A stateless step has nothing of its
16
+ * own to flush, so it forwards the inner `.complete` unchanged. Without
17
+ * this, `reduceSync`/`reduceAsync`/`transducePush` only ever saw the
18
+ * outermost step, which had no `.complete`, and the flush was lost.
19
+ * @ignore
20
+ */
21
+ const forwardComplete = <In>(next: Pick<ReducerStep<never>, "complete">, step: ReducerStep<In>): ReducerStep<In> => {
22
+ if (next.complete) step.complete = next.complete;
23
+ return step;
24
+ };
25
+
11
26
  /**
12
27
  * Create a transducer that maps values
13
28
  * @kind function
@@ -18,8 +33,7 @@ import { HALT, type ReducerStep, type Transducer } from "./iterator-tools.ts";
18
33
  export const map =
19
34
  <In, Out>(transform: (item: In) => Out): Transducer<In, Out> =>
20
35
  (conjoin) =>
21
- (init, item) =>
22
- conjoin(init, transform(item));
36
+ forwardComplete(conjoin, (init, item) => conjoin(init, transform(item)));
23
37
 
24
38
  /**
25
39
  * Create a transducer that filters values
@@ -31,8 +45,7 @@ export const map =
31
45
  export const filter =
32
46
  <In>(predicate: (item: In) => boolean): Transducer<In, In> =>
33
47
  (conjoin) =>
34
- (init, item) =>
35
- predicate(item) ? conjoin(init, item) : init;
48
+ forwardComplete(conjoin, (init, item) => (predicate(item) ? conjoin(init, item) : init));
36
49
 
37
50
  /**
38
51
  * Create a transducer that halts after a given number of values
@@ -46,7 +59,7 @@ export const take =
46
59
  (conjoin) => {
47
60
  let amount = 0;
48
61
  // biome-ignore lint/complexity/noCommaOperator: deliberate single-expression step function
49
- return (init, item) => (amount < limit ? (amount++, conjoin(init, item)) : HALT);
62
+ return forwardComplete(conjoin, (init, item) => (amount < limit ? (amount++, conjoin(init, item)) : HALT));
50
63
  };
51
64
 
52
65
  /**
@@ -62,8 +75,11 @@ export const drop =
62
75
  <In>(limit: number): Transducer<In, In> =>
63
76
  (conjoin) => {
64
77
  let amount = 0;
65
- // biome-ignore lint/complexity/noCommaOperator: deliberate single-expression step function
66
- return (init, item) => (amount >= limit ? (amount++, conjoin(init, item)) : (amount++, init));
78
+ return forwardComplete(conjoin, (init, item) => {
79
+ const pass = amount >= limit;
80
+ amount++;
81
+ return pass ? conjoin(init, item) : init;
82
+ });
67
83
  };
68
84
 
69
85
  /**
@@ -79,8 +95,7 @@ export const drop =
79
95
  export const reject =
80
96
  <In>(predicate: (item: In) => boolean): Transducer<In, In> =>
81
97
  (conjoin) =>
82
- (init, item) =>
83
- predicate(item) ? init : conjoin(init, item);
98
+ forwardComplete(conjoin, (init, item) => (predicate(item) ? init : conjoin(init, item)));
84
99
 
85
100
  /**
86
101
  * Create a transducer that groups items by quantity before emitting.
@@ -134,10 +149,10 @@ export const accumulate =
134
149
  // directly here would carry accumulated state over into the *next*
135
150
  // transduce run that reuses this same accumulate(...) instance.
136
151
  let accumulated = initial;
137
- return (init, item) => {
152
+ return forwardComplete(conjoin, (init, item) => {
138
153
  accumulated = func(accumulated, item);
139
154
  return conjoin(init, accumulated);
140
- };
155
+ });
141
156
  };
142
157
 
143
158
  /**
@@ -156,7 +171,7 @@ export const dedupe =
156
171
  (conjoin) => {
157
172
  let hasLast = false;
158
173
  let lastKey: unknown;
159
- return (init, item) => {
174
+ return forwardComplete(conjoin, (init, item) => {
160
175
  const key = keyFn(item);
161
176
  if (hasLast && Object.is(key, lastKey)) {
162
177
  return init;
@@ -164,7 +179,7 @@ export const dedupe =
164
179
  hasLast = true;
165
180
  lastKey = key;
166
181
  return conjoin(init, item);
167
- };
182
+ });
168
183
  };
169
184
 
170
185
  /**
@@ -179,7 +194,7 @@ export const interpose =
179
194
  <In, Sep = In>(separator: Sep): Transducer<In, In | Sep> =>
180
195
  (conjoin) => {
181
196
  let started = false;
182
- return (init, item) => {
197
+ return forwardComplete(conjoin, (init, item) => {
183
198
  if (started) {
184
199
  const out = conjoin(init, separator);
185
200
  if (out === HALT) {
@@ -189,7 +204,7 @@ export const interpose =
189
204
  }
190
205
  started = true;
191
206
  return conjoin(init, item);
192
- };
207
+ });
193
208
  };
194
209
 
195
210
  /**
@@ -250,7 +265,7 @@ export const partitionBy =
250
265
  export const tap =
251
266
  <In>(fn: (item: In) => unknown): Transducer<In, In> =>
252
267
  (conjoin) =>
253
- (init, item) => {
254
- fn(item);
255
- return conjoin(init, item);
256
- };
268
+ forwardComplete(conjoin, (init, item) => {
269
+ fn(item);
270
+ return conjoin(init, item);
271
+ });