@hpcc-js/dataflow 9.5.1 → 9.6.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.
@@ -5,6 +5,11 @@ import { scalar } from "../observers/observer.ts";
5
5
  export type HistogramFn<T> = (row: T) => number;
6
6
  export type HistogramRow<T> = { from: number, to: number, value: T[] };
7
7
  export type OptionA = { buckets: number };
8
+ /**
9
+ * Histogram options specifying the minimum value and bucket range (size).
10
+ * @property min - The minimum value for the first bucket's lower bound
11
+ * @property range - The size/width of each bucket (distance between bucket boundaries)
12
+ */
8
13
  export type OptionB = { min: number, range: number };
9
14
  export type Options = OptionA | OptionB;
10
15
 
@@ -21,8 +26,17 @@ function histogramGen<T = any>(callbackFn: HistogramFn<T>, options: Options): It
21
26
  if (isOptionA(options)) {
22
27
  source = Array.isArray(_source) ? _source : [..._source];
23
28
  const minMax = scalar(extent(callbackFn))(source);
24
- if (minMax === undefined) {
25
- return undefined;
29
+ if (minMax === undefined || minMax[0] === undefined || minMax[1] === undefined) {
30
+ // For empty sources with buckets option, generate empty buckets with NaN bounds
31
+ const buckets = options.buckets;
32
+ for (let i = 0; i < buckets; ++i) {
33
+ yield {
34
+ from: NaN,
35
+ to: NaN,
36
+ value: []
37
+ };
38
+ }
39
+ return;
26
40
  }
27
41
  min = minMax[0];
28
42
  const max = minMax[1];
@@ -37,7 +51,9 @@ function histogramGen<T = any>(callbackFn: HistogramFn<T>, options: Options): It
37
51
  const histogram: { [key: number]: T[] } = {};
38
52
 
39
53
  let maxBucketID = 0;
54
+ let hasData = false;
40
55
  for (const row of source) {
56
+ hasData = true;
41
57
  const value = callbackFn(row);
42
58
  const bucketID = Math.floor((value - min) / bucketSize);
43
59
  if (maxBucketID < bucketID) {
@@ -49,6 +65,11 @@ function histogramGen<T = any>(callbackFn: HistogramFn<T>, options: Options): It
49
65
  histogram[bucketID].push(row);
50
66
  }
51
67
 
68
+ // If no data, return empty for OptionB (min/range)
69
+ if (!hasData) {
70
+ return;
71
+ }
72
+
52
73
  const lastBucket = histogram[maxBucketID];
53
74
  const from = min + maxBucketID * bucketSize;
54
75
 
package/src/utils/pipe.ts CHANGED
@@ -1,74 +1,233 @@
1
- import { IterableActivity, Source, isSource, ScalarActivity } from "../activities/activity.ts";
1
+ import { IterableActivity, ScalarActivity, Source, isSource } from "../activities/activity.ts";
2
+
3
+ // =============================================================================
4
+ // Constants and Base Types
5
+ // =============================================================================
2
6
 
3
7
  const GeneratorFunction = (function* () { }).constructor;
4
8
 
5
- function chainGen<T, U>(...items: (IterableActivity<T, U> | ScalarActivity<unknown, unknown>)[]): IterableActivity<T, U> {
6
- if (items[items.length - 1] instanceof GeneratorFunction) {
7
- return function* (source) {
8
- // @ts-ignore
9
- let tail: IterableIterator<U> = source;
10
- for (const activity of items) {
11
- // @ts-ignore
12
- tail = activity(tail);
13
- }
14
- yield* tail;
15
- };
16
- } else {
17
- return function (source) {
18
- // @ts-ignore
19
- let tail: IterableIterator<U> = source;
20
- for (const activity of items) {
21
- // @ts-ignore
22
- tail = activity(tail);
9
+ type AnyIterableActivity = IterableActivity<any, any>;
10
+ type AnyScalarActivity = ScalarActivity<any, any>;
11
+ type AnyActivity = AnyIterableActivity | AnyScalarActivity;
12
+
13
+ // =============================================================================
14
+ // Type Utilities for Activity Analysis
15
+ // =============================================================================
16
+
17
+ type ActivityIn<A extends AnyActivity> = Parameters<A>[0] extends Source<infer Input> ? Input : never;
18
+ type ActivityOut<A extends AnyActivity> = ReturnType<A> extends IterableIterator<infer Output> ? Output : ReturnType<A>;
19
+ type ActivityIsScalar<A extends AnyActivity> = ReturnType<A> extends IterableIterator<any> ? false : true;
20
+
21
+ type FirstActivity<Activities extends readonly [AnyActivity, ...AnyActivity[]]> = Activities[0];
22
+
23
+ // =============================================================================
24
+ // Type Resolution for Activity Chains (Without Source)
25
+ // =============================================================================
26
+
27
+ /**
28
+ * Recursively resolves the output type of a chain of activities starting from an iterable activity.
29
+ * Validates that each activity's input type matches the previous activity's output type.
30
+ */
31
+
32
+ // Handle a scalar (non-iterable) activity in the chain
33
+ type ResolveScalarActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> =
34
+ CurrentOut extends ActivityIn<Next>
35
+ ? Rest extends []
36
+ ? { kind: "scalar"; in: InitialIn; out: ActivityOut<Next> }
37
+ : { kind: "error" } // Scalar activities must be terminal
38
+ : { kind: "error" }; // Type mismatch
39
+
40
+ // Handle an iterable activity in the chain
41
+ type ResolveIterableActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> =
42
+ CurrentOut extends ActivityIn<Next>
43
+ ? ResolveIterableTail<ActivityOut<Next>, InitialIn, Rest>
44
+ : { kind: "error" }; // Type mismatch
45
+
46
+ // Process the next activity in the chain
47
+ type ResolveNextActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> =
48
+ ActivityIsScalar<Next> extends true
49
+ ? ResolveScalarActivity<CurrentOut, InitialIn, Next, Rest>
50
+ : ResolveIterableActivity<CurrentOut, InitialIn, Next, Rest>;
51
+
52
+ // Check if we've reached the end of the activity chain
53
+ type ResolveIterableTail<CurrentOut, InitialIn, Tail extends readonly AnyActivity[]> =
54
+ Tail extends []
55
+ ? { kind: "iterable"; in: InitialIn; out: CurrentOut }
56
+ : Tail extends readonly [infer Next extends AnyActivity, ...infer Rest extends readonly AnyActivity[]]
57
+ ? ResolveNextActivity<CurrentOut, InitialIn, Next, Rest>
58
+ : { kind: "error" };
59
+
60
+ /**
61
+ * Resolves the complete type signature for a chain of activities without a source.
62
+ * Determines the input, output, and whether the final result is scalar or iterable.
63
+ */
64
+
65
+ // Handle when the first activity is scalar (must be the only activity)
66
+ type ResolveFirstScalarActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> =
67
+ Rest extends []
68
+ ? { kind: "scalar"; in: ActivityIn<First>; out: ActivityOut<First> }
69
+ : { kind: "error" }; // Scalar activities cannot be followed by others
70
+
71
+ // Handle when the first activity is iterable
72
+ type ResolveFirstIterableActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> =
73
+ Rest extends []
74
+ ? { kind: "iterable"; in: ActivityIn<First>; out: ActivityOut<First> }
75
+ : ResolveIterableTail<ActivityOut<First>, ActivityIn<First>, Rest>;
76
+
77
+ // Determine how to handle the first activity based on whether it's scalar or iterable
78
+ type ResolveFirstActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> =
79
+ ActivityIsScalar<First> extends true
80
+ ? ResolveFirstScalarActivity<First, Rest>
81
+ : ResolveFirstIterableActivity<First, Rest>;
82
+
83
+ type ResolveActivities<Activities extends readonly [AnyActivity, ...AnyActivity[]]> =
84
+ Activities extends readonly [infer First extends AnyActivity, ...infer Rest extends readonly AnyActivity[]]
85
+ ? ResolveFirstActivity<First, Rest>
86
+ : { kind: "error" };
87
+
88
+ /**
89
+ * Return type for pipe when called without a source - returns a reusable activity function.
90
+ */
91
+ type PipeWithoutSourceReturn<Activities extends readonly [AnyActivity, ...AnyActivity[]]> =
92
+ ResolveActivities<Activities> extends infer Result
93
+ ? Result extends { kind: "iterable"; in: infer In; out: infer Out }
94
+ ? IterableActivity<In & ActivityIn<FirstActivity<Activities>>, Out>
95
+ : Result extends { kind: "scalar"; in: infer In; out: infer Out }
96
+ ? ScalarActivity<In & ActivityIn<FirstActivity<Activities>>, Out>
97
+ : never
98
+ : never;
99
+
100
+ // =============================================================================
101
+ // Type Resolution for Activity Chains (With Source)
102
+ // =============================================================================
103
+
104
+ /**
105
+ * Resolves the output type when a source is provided as the first argument to pipe.
106
+ * Validates that the source type is compatible with the first activity's input.
107
+ */
108
+
109
+ // Extract the final result kind from ResolveIterableTail
110
+ type ExtractFinalResultKind<Result> =
111
+ Result extends { kind: "iterable"; out: infer Out }
112
+ ? { kind: "iterable"; out: Out }
113
+ : Result extends { kind: "scalar"; out: infer Out }
114
+ ? { kind: "scalar"; out: Out }
115
+ : { kind: "error" };
116
+
117
+ // Handle when the first activity after source is scalar
118
+ type ResolveSourceWithScalarActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> =
119
+ TSource extends ActivityIn<First>
120
+ ? Rest extends []
121
+ ? { kind: "scalar"; out: ActivityOut<First> }
122
+ : { kind: "error" } // Scalar activities must be terminal
123
+ : { kind: "error" }; // Type mismatch
124
+
125
+ // Handle when the first activity after source is iterable
126
+ type ResolveSourceWithIterableActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> =
127
+ TSource extends ActivityIn<First>
128
+ ? Rest extends []
129
+ ? { kind: "iterable"; out: ActivityOut<First> }
130
+ : ExtractFinalResultKind<ResolveIterableTail<ActivityOut<First>, ActivityIn<First>, Rest>>
131
+ : { kind: "error" }; // Type mismatch
132
+
133
+ // Determine how to handle the source with the first activity
134
+ type ResolveSourceWithFirstActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> =
135
+ ActivityIsScalar<First> extends true
136
+ ? ResolveSourceWithScalarActivity<TSource, First, Rest>
137
+ : ResolveSourceWithIterableActivity<TSource, First, Rest>;
138
+
139
+ type ResolveSourceActivities<TSource, Activities extends readonly AnyActivity[]> =
140
+ Activities extends []
141
+ ? { kind: "source"; out: TSource }
142
+ : Activities extends readonly [infer First extends AnyActivity, ...infer Rest extends readonly AnyActivity[]]
143
+ ? ResolveSourceWithFirstActivity<TSource, First, Rest>
144
+ : { kind: "error" };
145
+
146
+ /**
147
+ * Return type for pipe when called with a source - executes immediately and returns the result.
148
+ */
149
+ type PipeWithSourceReturn<TSource, Activities extends readonly AnyActivity[]> =
150
+ ResolveSourceActivities<TSource, Activities> extends infer Result
151
+ ? Result extends { kind: "iterable"; out: infer Out }
152
+ ? IterableIterator<Out>
153
+ : Result extends { kind: "scalar"; out: infer Out }
154
+ ? Out
155
+ : Result extends { kind: "source"; out: infer Out }
156
+ ? Source<Out>
157
+ : never
158
+ : never;
159
+
160
+ // =============================================================================
161
+ // Runtime Implementation
162
+ // =============================================================================
163
+
164
+ /**
165
+ * Internal helper that chains activities together at runtime.
166
+ * Returns a function that accepts a source and applies all activities in sequence.
167
+ * Handles both generator (iterable) and scalar activities appropriately.
168
+ */
169
+ function chainGen(...activities: AnyActivity[]) {
170
+ if (activities.length === 0) {
171
+ return <T>(source: Source<T>) => source;
172
+ }
173
+
174
+ const isGenerator = activities[activities.length - 1] instanceof GeneratorFunction;
175
+ const len = activities.length;
176
+
177
+ if (isGenerator) {
178
+ return function* (source: Source<unknown>) {
179
+ let tail: unknown = source;
180
+ for (let i = 0; i < len; i++) {
181
+ tail = activities[i](tail as Source<unknown>);
23
182
  }
24
- return tail;
183
+ yield* tail as IterableIterator<unknown>;
25
184
  };
26
185
  }
186
+
187
+ return (source: Source<unknown>) => {
188
+ let tail: unknown = source;
189
+ for (let i = 0; i < len; i++) {
190
+ tail = activities[i](tail as Source<unknown>);
191
+ }
192
+ return tail;
193
+ };
27
194
  }
28
195
 
29
- // TODO: Switch to TS Variadic Types in 4.0
30
- export function pipe<T, U>(head: IterableActivity<T, U>): IterableActivity<T, U>;
31
- export function pipe<T, U>(head: ScalarActivity<T, U>): ScalarActivity<T, U>;
32
- export function pipe<T, U>(source: Source<T>): IterableIterator<U>;
33
- export function pipe<T, I1, U>(head: IterableActivity<T, I1>, tail: IterableActivity<I1, U>): IterableActivity<T, U>;
34
- export function pipe<T, I1, U>(head: IterableActivity<T, I1>, tail: ScalarActivity<I1, U>): ScalarActivity<T, U>;
35
- export function pipe<T, U>(source: Source<T>, head: IterableActivity<T, U>): IterableIterator<U>;
36
- export function pipe<T, U>(source: Source<T>, head: ScalarActivity<T, U>): U;
37
- export function pipe<T, I1, I2, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: IterableActivity<I2, U>): IterableActivity<T, U>;
38
- export function pipe<T, I1, I2, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: ScalarActivity<I2, U>): ScalarActivity<T, U>;
39
- export function pipe<T, I1, U>(source: Source<T>, head: IterableActivity<T, I1>, tail: IterableActivity<I1, U>): IterableIterator<U>;
40
- export function pipe<T, I1, U>(source: Source<T>, head: IterableActivity<T, I1>, tail: ScalarActivity<I1, U>): U;
41
- export function pipe<T, I1, I2, I3, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: IterableActivity<I3, U>): IterableActivity<T, U>;
42
- export function pipe<T, I1, I2, I3, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: ScalarActivity<I3, U>): ScalarActivity<T, U>;
43
- export function pipe<T, I1, I2, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: IterableActivity<I1, U>): IterableIterator<U>;
44
- export function pipe<T, I1, I2, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: ScalarActivity<I1, U>): U;
45
- export function pipe<T, I1, I2, I3, I4, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: IterableActivity<I4, U>): IterableActivity<T, U>;
46
- export function pipe<T, I1, I2, I3, I4, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: ScalarActivity<I4, U>): ScalarActivity<T, U>;
47
- export function pipe<T, I1, I2, I3, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: IterableActivity<I3, U>): IterableIterator<U>;
48
- export function pipe<T, I1, I2, I3, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: ScalarActivity<I3, U>): U;
49
- export function pipe<T, I1, I2, I3, I4, I5, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: IterableActivity<I5, U>): IterableActivity<T, U>;
50
- export function pipe<T, I1, I2, I3, I4, I5, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: ScalarActivity<I5, U>): ScalarActivity<T, U>;
51
- export function pipe<T, I1, I2, I3, I4, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: IterableActivity<I4, U>): IterableIterator<U>;
52
- export function pipe<T, I1, I2, I3, I4, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: ScalarActivity<I4, U>): U;
53
- export function pipe<T, I1, I2, I3, I4, I5, I6, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: IterableActivity<I6, U>): IterableActivity<T, U>;
54
- export function pipe<T, I1, I2, I3, I4, I5, I6, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: ScalarActivity<I6, U>): ScalarActivity<T, U>;
55
- export function pipe<T, I1, I2, I3, I4, I5, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: IterableActivity<I5, U>): IterableIterator<U>;
56
- export function pipe<T, I1, I2, I3, I4, I5, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: ScalarActivity<I5, U>): U;
57
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: IterableActivity<I7, U>): IterableActivity<T, U>;
58
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: ScalarActivity<I7, U>): ScalarActivity<T, U>;
59
- export function pipe<T, I1, I2, I3, I4, I5, I6, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: IterableActivity<I6, U>): IterableIterator<U>;
60
- export function pipe<T, I1, I2, I3, I4, I5, I6, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: ScalarActivity<I6, U>): U;
61
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: IterableActivity<I8, U>): IterableActivity<T, U>;
62
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: ScalarActivity<I8, U>): ScalarActivity<T, U>;
63
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: IterableActivity<I7, U>): IterableIterator<U>;
64
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: ScalarActivity<I7, U>): U;
65
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, I9, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, i8: IterableActivity<I8, I9>, tail: IterableActivity<I9, U>): IterableActivity<T, U>;
66
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, I9, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, i8: IterableActivity<I8, I9>, tail: ScalarActivity<I9, U>): ScalarActivity<T, U>;
67
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: IterableActivity<I8, U>): IterableIterator<U>;
68
- export function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: ScalarActivity<I8, U>): U;
69
- export function pipe<T, U = any>(s_or_ia: Source<T> | IterableActivity<T, U>, ...items: (IterableActivity<unknown, unknown> | ScalarActivity<unknown, unknown>)[]): IterableActivity<T, U> | ScalarActivity<T, U> | IterableIterator<U> {
70
- return isSource<T>(s_or_ia) ? chainGen<T, U>(...items)(s_or_ia) : chainGen<T, U>(s_or_ia as IterableActivity<T, U>, ...items);
196
+ // =============================================================================
197
+ // Public API
198
+ // =============================================================================
199
+
200
+ /**
201
+ * Pipes activities together to create a data processing pipeline.
202
+ *
203
+ * Two usage modes:
204
+ * 1. Without source: pipe(activity1, activity2, ...) - returns a reusable activity function
205
+ * 2. With source: pipe(source, activity1, activity2, ...) - executes immediately and returns result
206
+ *
207
+ * Activities are chained left-to-right, with type checking ensuring output of each activity
208
+ * matches the input of the next.
209
+ */
210
+ export function pipe<const Activities extends readonly [AnyActivity, ...AnyActivity[]]>(...activities: Activities): PipeWithoutSourceReturn<Activities>;
211
+ export function pipe<TSource, const Activities extends readonly AnyActivity[]>(source: Source<TSource>, ...activities: Activities): PipeWithSourceReturn<TSource, Activities>;
212
+ export function pipe(...args: any[]): any {
213
+ if (args.length === 0) {
214
+ throw new TypeError("pipe requires at least one argument");
215
+ }
216
+
217
+ // Handle source-based invocation
218
+ if (isSource(args[0])) {
219
+ return args.length === 1 ? args[0] : chainGen(...args.slice(1))(args[0]);
220
+ }
221
+
222
+ // Handle activity-based invocation
223
+ return chainGen(...args);
71
224
  }
72
225
 
73
- // Maintain backward compatibility
226
+ // =============================================================================
227
+ // Backward Compatibility
228
+ // =============================================================================
229
+
230
+ /**
231
+ * @deprecated Use pipe instead. Maintained for backward compatibility.
232
+ */
74
233
  export const chain = pipe;
@@ -8,6 +8,11 @@ export type HistogramRow<T> = {
8
8
  export type OptionA = {
9
9
  buckets: number;
10
10
  };
11
+ /**
12
+ * Histogram options specifying the minimum value and bucket range (size).
13
+ * @property min - The minimum value for the first bucket's lower bound
14
+ * @property range - The size/width of each bucket (distance between bucket boundaries)
15
+ */
11
16
  export type OptionB = {
12
17
  min: number;
13
18
  range: number;
@@ -1,41 +1,134 @@
1
- import { IterableActivity, Source, ScalarActivity } from "../activities/activity.ts";
2
- export declare function pipe<T, U>(head: IterableActivity<T, U>): IterableActivity<T, U>;
3
- export declare function pipe<T, U>(head: ScalarActivity<T, U>): ScalarActivity<T, U>;
4
- export declare function pipe<T, U>(source: Source<T>): IterableIterator<U>;
5
- export declare function pipe<T, I1, U>(head: IterableActivity<T, I1>, tail: IterableActivity<I1, U>): IterableActivity<T, U>;
6
- export declare function pipe<T, I1, U>(head: IterableActivity<T, I1>, tail: ScalarActivity<I1, U>): ScalarActivity<T, U>;
7
- export declare function pipe<T, U>(source: Source<T>, head: IterableActivity<T, U>): IterableIterator<U>;
8
- export declare function pipe<T, U>(source: Source<T>, head: ScalarActivity<T, U>): U;
9
- export declare function pipe<T, I1, I2, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: IterableActivity<I2, U>): IterableActivity<T, U>;
10
- export declare function pipe<T, I1, I2, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: ScalarActivity<I2, U>): ScalarActivity<T, U>;
11
- export declare function pipe<T, I1, U>(source: Source<T>, head: IterableActivity<T, I1>, tail: IterableActivity<I1, U>): IterableIterator<U>;
12
- export declare function pipe<T, I1, U>(source: Source<T>, head: IterableActivity<T, I1>, tail: ScalarActivity<I1, U>): U;
13
- export declare function pipe<T, I1, I2, I3, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: IterableActivity<I3, U>): IterableActivity<T, U>;
14
- export declare function pipe<T, I1, I2, I3, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: ScalarActivity<I3, U>): ScalarActivity<T, U>;
15
- export declare function pipe<T, I1, I2, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: IterableActivity<I1, U>): IterableIterator<U>;
16
- export declare function pipe<T, I1, I2, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, tail: ScalarActivity<I1, U>): U;
17
- export declare function pipe<T, I1, I2, I3, I4, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: IterableActivity<I4, U>): IterableActivity<T, U>;
18
- export declare function pipe<T, I1, I2, I3, I4, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: ScalarActivity<I4, U>): ScalarActivity<T, U>;
19
- export declare function pipe<T, I1, I2, I3, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: IterableActivity<I3, U>): IterableIterator<U>;
20
- export declare function pipe<T, I1, I2, I3, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, tail: ScalarActivity<I3, U>): U;
21
- export declare function pipe<T, I1, I2, I3, I4, I5, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: IterableActivity<I5, U>): IterableActivity<T, U>;
22
- export declare function pipe<T, I1, I2, I3, I4, I5, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: ScalarActivity<I5, U>): ScalarActivity<T, U>;
23
- export declare function pipe<T, I1, I2, I3, I4, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: IterableActivity<I4, U>): IterableIterator<U>;
24
- export declare function pipe<T, I1, I2, I3, I4, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, tail: ScalarActivity<I4, U>): U;
25
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: IterableActivity<I6, U>): IterableActivity<T, U>;
26
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: ScalarActivity<I6, U>): ScalarActivity<T, U>;
27
- export declare function pipe<T, I1, I2, I3, I4, I5, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: IterableActivity<I5, U>): IterableIterator<U>;
28
- export declare function pipe<T, I1, I2, I3, I4, I5, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, tail: ScalarActivity<I5, U>): U;
29
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: IterableActivity<I7, U>): IterableActivity<T, U>;
30
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: ScalarActivity<I7, U>): ScalarActivity<T, U>;
31
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: IterableActivity<I6, U>): IterableIterator<U>;
32
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, tail: ScalarActivity<I6, U>): U;
33
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: IterableActivity<I8, U>): IterableActivity<T, U>;
34
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: ScalarActivity<I8, U>): ScalarActivity<T, U>;
35
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: IterableActivity<I7, U>): IterableIterator<U>;
36
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, tail: ScalarActivity<I7, U>): U;
37
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, I9, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, i8: IterableActivity<I8, I9>, tail: IterableActivity<I9, U>): IterableActivity<T, U>;
38
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, I9, U>(head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, i8: IterableActivity<I8, I9>, tail: ScalarActivity<I9, U>): ScalarActivity<T, U>;
39
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: IterableActivity<I8, U>): IterableIterator<U>;
40
- export declare function pipe<T, I1, I2, I3, I4, I5, I6, I7, I8, U>(source: Source<T>, head: IterableActivity<T, I1>, i1: IterableActivity<I1, I2>, i2: IterableActivity<I2, I3>, i3: IterableActivity<I3, I4>, i4: IterableActivity<I4, I5>, i5: IterableActivity<I5, I6>, i6: IterableActivity<I6, I7>, i7: IterableActivity<I7, I8>, tail: ScalarActivity<I8, U>): U;
1
+ import { IterableActivity, ScalarActivity, Source } from "../activities/activity.ts";
2
+ type AnyIterableActivity = IterableActivity<any, any>;
3
+ type AnyScalarActivity = ScalarActivity<any, any>;
4
+ type AnyActivity = AnyIterableActivity | AnyScalarActivity;
5
+ type ActivityIn<A extends AnyActivity> = Parameters<A>[0] extends Source<infer Input> ? Input : never;
6
+ type ActivityOut<A extends AnyActivity> = ReturnType<A> extends IterableIterator<infer Output> ? Output : ReturnType<A>;
7
+ type ActivityIsScalar<A extends AnyActivity> = ReturnType<A> extends IterableIterator<any> ? false : true;
8
+ type FirstActivity<Activities extends readonly [AnyActivity, ...AnyActivity[]]> = Activities[0];
9
+ /**
10
+ * Recursively resolves the output type of a chain of activities starting from an iterable activity.
11
+ * Validates that each activity's input type matches the previous activity's output type.
12
+ */
13
+ type ResolveScalarActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> = CurrentOut extends ActivityIn<Next> ? Rest extends [] ? {
14
+ kind: "scalar";
15
+ in: InitialIn;
16
+ out: ActivityOut<Next>;
17
+ } : {
18
+ kind: "error";
19
+ } : {
20
+ kind: "error";
21
+ };
22
+ type ResolveIterableActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> = CurrentOut extends ActivityIn<Next> ? ResolveIterableTail<ActivityOut<Next>, InitialIn, Rest> : {
23
+ kind: "error";
24
+ };
25
+ type ResolveNextActivity<CurrentOut, InitialIn, Next extends AnyActivity, Rest extends readonly AnyActivity[]> = ActivityIsScalar<Next> extends true ? ResolveScalarActivity<CurrentOut, InitialIn, Next, Rest> : ResolveIterableActivity<CurrentOut, InitialIn, Next, Rest>;
26
+ type ResolveIterableTail<CurrentOut, InitialIn, Tail extends readonly AnyActivity[]> = Tail extends [] ? {
27
+ kind: "iterable";
28
+ in: InitialIn;
29
+ out: CurrentOut;
30
+ } : Tail extends readonly [infer Next extends AnyActivity, ...infer Rest extends readonly AnyActivity[]] ? ResolveNextActivity<CurrentOut, InitialIn, Next, Rest> : {
31
+ kind: "error";
32
+ };
33
+ /**
34
+ * Resolves the complete type signature for a chain of activities without a source.
35
+ * Determines the input, output, and whether the final result is scalar or iterable.
36
+ */
37
+ type ResolveFirstScalarActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> = Rest extends [] ? {
38
+ kind: "scalar";
39
+ in: ActivityIn<First>;
40
+ out: ActivityOut<First>;
41
+ } : {
42
+ kind: "error";
43
+ };
44
+ type ResolveFirstIterableActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> = Rest extends [] ? {
45
+ kind: "iterable";
46
+ in: ActivityIn<First>;
47
+ out: ActivityOut<First>;
48
+ } : ResolveIterableTail<ActivityOut<First>, ActivityIn<First>, Rest>;
49
+ type ResolveFirstActivity<First extends AnyActivity, Rest extends readonly AnyActivity[]> = ActivityIsScalar<First> extends true ? ResolveFirstScalarActivity<First, Rest> : ResolveFirstIterableActivity<First, Rest>;
50
+ type ResolveActivities<Activities extends readonly [AnyActivity, ...AnyActivity[]]> = Activities extends readonly [infer First extends AnyActivity, ...infer Rest extends readonly AnyActivity[]] ? ResolveFirstActivity<First, Rest> : {
51
+ kind: "error";
52
+ };
53
+ /**
54
+ * Return type for pipe when called without a source - returns a reusable activity function.
55
+ */
56
+ type PipeWithoutSourceReturn<Activities extends readonly [AnyActivity, ...AnyActivity[]]> = ResolveActivities<Activities> extends infer Result ? Result extends {
57
+ kind: "iterable";
58
+ in: infer In;
59
+ out: infer Out;
60
+ } ? IterableActivity<In & ActivityIn<FirstActivity<Activities>>, Out> : Result extends {
61
+ kind: "scalar";
62
+ in: infer In;
63
+ out: infer Out;
64
+ } ? ScalarActivity<In & ActivityIn<FirstActivity<Activities>>, Out> : never : never;
65
+ /**
66
+ * Resolves the output type when a source is provided as the first argument to pipe.
67
+ * Validates that the source type is compatible with the first activity's input.
68
+ */
69
+ type ExtractFinalResultKind<Result> = Result extends {
70
+ kind: "iterable";
71
+ out: infer Out;
72
+ } ? {
73
+ kind: "iterable";
74
+ out: Out;
75
+ } : Result extends {
76
+ kind: "scalar";
77
+ out: infer Out;
78
+ } ? {
79
+ kind: "scalar";
80
+ out: Out;
81
+ } : {
82
+ kind: "error";
83
+ };
84
+ type ResolveSourceWithScalarActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> = TSource extends ActivityIn<First> ? Rest extends [] ? {
85
+ kind: "scalar";
86
+ out: ActivityOut<First>;
87
+ } : {
88
+ kind: "error";
89
+ } : {
90
+ kind: "error";
91
+ };
92
+ type ResolveSourceWithIterableActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> = TSource extends ActivityIn<First> ? Rest extends [] ? {
93
+ kind: "iterable";
94
+ out: ActivityOut<First>;
95
+ } : ExtractFinalResultKind<ResolveIterableTail<ActivityOut<First>, ActivityIn<First>, Rest>> : {
96
+ kind: "error";
97
+ };
98
+ type ResolveSourceWithFirstActivity<TSource, First extends AnyActivity, Rest extends readonly AnyActivity[]> = ActivityIsScalar<First> extends true ? ResolveSourceWithScalarActivity<TSource, First, Rest> : ResolveSourceWithIterableActivity<TSource, First, Rest>;
99
+ type ResolveSourceActivities<TSource, Activities extends readonly AnyActivity[]> = Activities extends [] ? {
100
+ kind: "source";
101
+ out: TSource;
102
+ } : Activities extends readonly [infer First extends AnyActivity, ...infer Rest extends readonly AnyActivity[]] ? ResolveSourceWithFirstActivity<TSource, First, Rest> : {
103
+ kind: "error";
104
+ };
105
+ /**
106
+ * Return type for pipe when called with a source - executes immediately and returns the result.
107
+ */
108
+ type PipeWithSourceReturn<TSource, Activities extends readonly AnyActivity[]> = ResolveSourceActivities<TSource, Activities> extends infer Result ? Result extends {
109
+ kind: "iterable";
110
+ out: infer Out;
111
+ } ? IterableIterator<Out> : Result extends {
112
+ kind: "scalar";
113
+ out: infer Out;
114
+ } ? Out : Result extends {
115
+ kind: "source";
116
+ out: infer Out;
117
+ } ? Source<Out> : never : never;
118
+ /**
119
+ * Pipes activities together to create a data processing pipeline.
120
+ *
121
+ * Two usage modes:
122
+ * 1. Without source: pipe(activity1, activity2, ...) - returns a reusable activity function
123
+ * 2. With source: pipe(source, activity1, activity2, ...) - executes immediately and returns result
124
+ *
125
+ * Activities are chained left-to-right, with type checking ensuring output of each activity
126
+ * matches the input of the next.
127
+ */
128
+ export declare function pipe<const Activities extends readonly [AnyActivity, ...AnyActivity[]]>(...activities: Activities): PipeWithoutSourceReturn<Activities>;
129
+ export declare function pipe<TSource, const Activities extends readonly AnyActivity[]>(source: Source<TSource>, ...activities: Activities): PipeWithSourceReturn<TSource, Activities>;
130
+ /**
131
+ * @deprecated Use pipe instead. Maintained for backward compatibility.
132
+ */
41
133
  export declare const chain: typeof pipe;
134
+ export {};