@barnum/barnum 0.0.0-main-3c07d795 → 0.0.0-main-54c41bbb
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/artifacts/linux-arm64/barnum +0 -0
- package/artifacts/linux-x64/barnum +0 -0
- package/artifacts/macos-arm64/barnum +0 -0
- package/artifacts/macos-x64/barnum +0 -0
- package/artifacts/win-x64/barnum.exe +0 -0
- package/dist/all.d.ts +40 -10
- package/dist/ast.d.ts +28 -38
- package/dist/ast.js +34 -232
- package/dist/bind.js +10 -50
- package/dist/builtins.d.ts +79 -118
- package/dist/builtins.js +193 -333
- package/dist/handler.js +4 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pipe.d.ts +11 -11
- package/dist/pipe.js +2 -2
- package/dist/race.js +15 -41
- package/dist/recursive.js +1 -2
- package/dist/try-catch.js +7 -6
- package/package.json +1 -1
- package/src/all.ts +117 -73
- package/src/ast.ts +110 -295
- package/src/bind.ts +16 -50
- package/src/builtins.ts +267 -395
- package/src/handler.ts +7 -20
- package/src/index.ts +3 -1
- package/src/pipe.ts +120 -81
- package/src/race.ts +26 -46
- package/src/recursive.ts +1 -2
- package/src/run.ts +2 -2
- package/src/try-catch.ts +11 -6
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/all.d.ts
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
1
|
import { type Pipeable, type TypedAction } from "./ast.js";
|
|
2
2
|
export declare function all(): TypedAction<any, []>;
|
|
3
|
-
export declare function all<
|
|
4
|
-
export declare function all<
|
|
5
|
-
export declare function all<
|
|
6
|
-
export declare function all<
|
|
7
|
-
export declare function all<
|
|
8
|
-
export declare function all<
|
|
9
|
-
export declare function all<
|
|
10
|
-
export declare function all<
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
export declare function all<TInput, TOut1>(a1: Pipeable<TInput, TOut1>): TypedAction<TInput, [TOut1]>;
|
|
4
|
+
export declare function all<TInput, TOut1, TOut2>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>): TypedAction<TInput, [TOut1, TOut2]>;
|
|
5
|
+
export declare function all<TInput, TOut1, TOut2, TOut3>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>): TypedAction<TInput, [TOut1, TOut2, TOut3]>;
|
|
6
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>): TypedAction<TInput, [TOut1, TOut2, TOut3, TOut4]>;
|
|
7
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>): TypedAction<TInput, [TOut1, TOut2, TOut3, TOut4, TOut5]>;
|
|
8
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>, a6: Pipeable<TInput, TOut6>): TypedAction<TInput, [TOut1, TOut2, TOut3, TOut4, TOut5, TOut6]>;
|
|
9
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6, TOut7>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>, a6: Pipeable<TInput, TOut6>, a7: Pipeable<TInput, TOut7>): TypedAction<TInput, [TOut1, TOut2, TOut3, TOut4, TOut5, TOut6, TOut7]>;
|
|
10
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6, TOut7, TOut8>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>, a6: Pipeable<TInput, TOut6>, a7: Pipeable<TInput, TOut7>, a8: Pipeable<TInput, TOut8>): TypedAction<TInput, [
|
|
11
|
+
TOut1,
|
|
12
|
+
TOut2,
|
|
13
|
+
TOut3,
|
|
14
|
+
TOut4,
|
|
15
|
+
TOut5,
|
|
16
|
+
TOut6,
|
|
17
|
+
TOut7,
|
|
18
|
+
TOut8
|
|
19
|
+
]>;
|
|
20
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6, TOut7, TOut8, TOut9>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>, a6: Pipeable<TInput, TOut6>, a7: Pipeable<TInput, TOut7>, a8: Pipeable<TInput, TOut8>, a9: Pipeable<TInput, TOut9>): TypedAction<TInput, [
|
|
21
|
+
TOut1,
|
|
22
|
+
TOut2,
|
|
23
|
+
TOut3,
|
|
24
|
+
TOut4,
|
|
25
|
+
TOut5,
|
|
26
|
+
TOut6,
|
|
27
|
+
TOut7,
|
|
28
|
+
TOut8,
|
|
29
|
+
TOut9
|
|
30
|
+
]>;
|
|
31
|
+
export declare function all<TInput, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6, TOut7, TOut8, TOut9, TOut10>(a1: Pipeable<TInput, TOut1>, a2: Pipeable<TInput, TOut2>, a3: Pipeable<TInput, TOut3>, a4: Pipeable<TInput, TOut4>, a5: Pipeable<TInput, TOut5>, a6: Pipeable<TInput, TOut6>, a7: Pipeable<TInput, TOut7>, a8: Pipeable<TInput, TOut8>, a9: Pipeable<TInput, TOut9>, a10: Pipeable<TInput, TOut10>): TypedAction<TInput, [
|
|
32
|
+
TOut1,
|
|
33
|
+
TOut2,
|
|
34
|
+
TOut3,
|
|
35
|
+
TOut4,
|
|
36
|
+
TOut5,
|
|
37
|
+
TOut6,
|
|
38
|
+
TOut7,
|
|
39
|
+
TOut8,
|
|
40
|
+
TOut9,
|
|
41
|
+
TOut10
|
|
42
|
+
]>;
|
package/dist/ast.d.ts
CHANGED
|
@@ -60,22 +60,16 @@ export type BuiltinKind = {
|
|
|
60
60
|
kind: "Identity";
|
|
61
61
|
} | {
|
|
62
62
|
kind: "Drop";
|
|
63
|
-
} | {
|
|
64
|
-
kind: "Tag";
|
|
65
|
-
value: string;
|
|
66
63
|
} | {
|
|
67
64
|
kind: "Merge";
|
|
68
65
|
} | {
|
|
69
66
|
kind: "Flatten";
|
|
70
67
|
} | {
|
|
71
68
|
kind: "GetField";
|
|
72
|
-
|
|
69
|
+
field: string;
|
|
73
70
|
} | {
|
|
74
71
|
kind: "GetIndex";
|
|
75
|
-
|
|
76
|
-
} | {
|
|
77
|
-
kind: "Pick";
|
|
78
|
-
value: string[];
|
|
72
|
+
index: number;
|
|
79
73
|
} | {
|
|
80
74
|
kind: "CollectSome";
|
|
81
75
|
} | {
|
|
@@ -84,10 +78,10 @@ export type BuiltinKind = {
|
|
|
84
78
|
kind: "SplitLast";
|
|
85
79
|
} | {
|
|
86
80
|
kind: "WrapInField";
|
|
87
|
-
|
|
81
|
+
field: string;
|
|
88
82
|
} | {
|
|
89
83
|
kind: "Sleep";
|
|
90
|
-
|
|
84
|
+
ms: number;
|
|
91
85
|
};
|
|
92
86
|
/**
|
|
93
87
|
* When TIn is `never` (handler ignores input), produce `any` so the
|
|
@@ -112,54 +106,51 @@ export type MergeTuple<TTuple> = TTuple extends unknown[] ? UnionToIntersection<
|
|
|
112
106
|
* Data crosses serialization boundaries to handlers in arbitrary languages
|
|
113
107
|
* (Rust, Python, etc.), so extra/missing fields are runtime errors.
|
|
114
108
|
*/
|
|
115
|
-
export type TypedAction<In = unknown, Out = unknown
|
|
109
|
+
export type TypedAction<In = unknown, Out = unknown> = Action & {
|
|
116
110
|
__in?: (input: In) => void;
|
|
117
111
|
__in_co?: In;
|
|
118
112
|
__out?: () => Out;
|
|
119
113
|
__out_contra?: (output: Out) => void;
|
|
120
|
-
__refs?: {
|
|
121
|
-
_brand: Refs;
|
|
122
|
-
};
|
|
123
114
|
/** Chain this action with another. `a.then(b)` ≡ `chain(a, b)`. */
|
|
124
|
-
then<TNext>(next: Pipeable<Out, TNext>): TypedAction<In, TNext
|
|
115
|
+
then<TNext>(next: Pipeable<Out, TNext>): TypedAction<In, TNext>;
|
|
125
116
|
/** Apply an action to each element of an array output. `a.forEach(b)` ≡ `a.then(forEach(b))`. */
|
|
126
|
-
forEach<TIn, TElement, TNext
|
|
117
|
+
forEach<TIn, TElement, TNext>(this: TypedAction<TIn, TElement[]>, action: Pipeable<TElement, TNext>): TypedAction<TIn, TNext[]>;
|
|
127
118
|
/** Dispatch on a tagged union output. Auto-unwraps `value` before each case handler. */
|
|
128
119
|
branch<TCases extends {
|
|
129
120
|
[K in BranchKeys<Out>]: CaseHandler<BranchPayload<Out, K>, unknown>;
|
|
130
|
-
}>(cases: [BranchKeys<Out>] extends [never] ? never : TCases): TypedAction<In, ExtractOutput<TCases[keyof TCases & string]
|
|
121
|
+
}>(cases: [BranchKeys<Out>] extends [never] ? never : TCases): TypedAction<In, ExtractOutput<TCases[keyof TCases & string]>>;
|
|
131
122
|
/** Flatten a nested array output. `a.flatten()` ≡ `pipe(a, flatten())`. */
|
|
132
|
-
flatten(): TypedAction<In, Out extends (infer TElement)[][] ? TElement[] : Out
|
|
123
|
+
flatten(): TypedAction<In, Out extends (infer TElement)[][] ? TElement[] : Out>;
|
|
133
124
|
/** Discard output. `a.drop()` ≡ `pipe(a, drop)`. */
|
|
134
|
-
drop(): TypedAction<In, never
|
|
125
|
+
drop(): TypedAction<In, never>;
|
|
135
126
|
/** Wrap output as a tagged union member. Requires full variant map TDef so __def is carried. */
|
|
136
|
-
tag<TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(kind: TKind): TypedAction<In, TaggedUnion<TDef
|
|
127
|
+
tag<TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(kind: TKind): TypedAction<In, TaggedUnion<TDef>>;
|
|
137
128
|
/** Extract a field from the output object. `a.getField("name")` ≡ `pipe(a, getField("name"))`. */
|
|
138
|
-
getField<TField extends keyof Out & string>(field: TField): TypedAction<In, Out[TField]
|
|
129
|
+
getField<TField extends keyof Out & string>(field: TField): TypedAction<In, Out[TField]>;
|
|
139
130
|
/** Extract an element from the output tuple by index. `a.getIndex(0)` ≡ `pipe(a, getIndex(0))`. */
|
|
140
|
-
getIndex<TIn, TTuple extends unknown[], TIndex extends number
|
|
131
|
+
getIndex<TIn, TTuple extends unknown[], TIndex extends number>(this: TypedAction<TIn, TTuple>, index: TIndex): TypedAction<TIn, TTuple[TIndex]>;
|
|
141
132
|
/** Wrap output in an object under a field name. `a.wrapInField("foo")` ≡ `pipe(a, wrapInField("foo"))`. */
|
|
142
|
-
wrapInField<TField extends string>(field: TField): TypedAction<In, Record<TField, Out
|
|
133
|
+
wrapInField<TField extends string>(field: TField): TypedAction<In, Record<TField, Out>>;
|
|
143
134
|
/** Merge a tuple of objects into a single object. `a.merge()` ≡ `pipe(a, merge())`. */
|
|
144
|
-
merge(): TypedAction<In, MergeTuple<Out
|
|
135
|
+
merge(): TypedAction<In, MergeTuple<Out>>;
|
|
145
136
|
/** Select fields from the output. `a.pick("x", "y")` ≡ `pipe(a, pick("x", "y"))`. */
|
|
146
|
-
pick<TKeys extends (keyof Out & string)[]>(...keys: TKeys): TypedAction<In, Pick<Out, TKeys[number]
|
|
137
|
+
pick<TKeys extends (keyof Out & string)[]>(...keys: TKeys): TypedAction<In, Pick<Out, TKeys[number]>>;
|
|
147
138
|
/** Head/tail decomposition. Only callable when Out is TElement[]. */
|
|
148
|
-
splitFirst<TIn, TElement
|
|
139
|
+
splitFirst<TIn, TElement>(this: TypedAction<TIn, TElement[]>): TypedAction<TIn, Option<[TElement, TElement[]]>>;
|
|
149
140
|
/** Init/last decomposition. Only callable when Out is TElement[]. */
|
|
150
|
-
splitLast<TIn, TElement
|
|
141
|
+
splitLast<TIn, TElement>(this: TypedAction<TIn, TElement[]>): TypedAction<TIn, Option<[TElement[], TElement]>>;
|
|
151
142
|
/**
|
|
152
143
|
* Transform the Some value inside an Option output. Only callable when
|
|
153
144
|
* Out is Option<T>. Uses `this` parameter constraint to gate availability.
|
|
154
145
|
*/
|
|
155
|
-
mapOption<TIn, T, U
|
|
146
|
+
mapOption<TIn, T, U>(this: TypedAction<TIn, Option<T>>, action: Pipeable<T, U>): TypedAction<TIn, Option<U>>;
|
|
156
147
|
/**
|
|
157
148
|
* Transform the Err value of a Result output.
|
|
158
149
|
* `Result<TValue, TError> → Result<TValue, TErrorOut>`
|
|
159
150
|
*
|
|
160
151
|
* Only callable when Out is Result<TValue, TError>.
|
|
161
152
|
*/
|
|
162
|
-
mapErr<TIn, TValue, TError, TErrorOut>(this: TypedAction<TIn, Result<TValue, TError
|
|
153
|
+
mapErr<TIn, TValue, TError, TErrorOut>(this: TypedAction<TIn, Result<TValue, TError>>, action: Pipeable<TError, TErrorOut>): TypedAction<TIn, Result<TValue, TErrorOut>>;
|
|
163
154
|
/**
|
|
164
155
|
* Unwrap a Result output. If Ok, pass through the value. If Err, apply
|
|
165
156
|
* the default action. Only callable when Out is Result<TValue, TError>.
|
|
@@ -170,12 +161,8 @@ export type TypedAction<In = unknown, Out = unknown, Refs extends string = never
|
|
|
170
161
|
*
|
|
171
162
|
* Uses CaseHandler for defaultAction (covariant output only) so that
|
|
172
163
|
* `TypedAction<TError, never>` is assignable to `CaseHandler<TError, TValue>`.
|
|
173
|
-
*
|
|
174
|
-
* Refs position uses `any` in the `this` constraint to avoid TS
|
|
175
|
-
* falling back to the constraint bound `string` when Refs = never.
|
|
176
|
-
* The return type uses the enclosing TypedAction's `Refs` directly.
|
|
177
164
|
*/
|
|
178
|
-
unwrapOr<TIn, TValue, TError>(this: TypedAction<TIn, Result<TValue, TError
|
|
165
|
+
unwrapOr<TIn, TValue, TError>(this: TypedAction<TIn, Result<TValue, TError>>, defaultAction: CaseHandler<TError, TValue>): TypedAction<TIn, TValue>;
|
|
179
166
|
};
|
|
180
167
|
/**
|
|
181
168
|
* Parameter type for pipe and combinators. Contains the same phantom fields
|
|
@@ -231,6 +218,11 @@ type CaseHandler<TIn = unknown, TOut = unknown> = Action & {
|
|
|
231
218
|
* field enables `.branch()` to decompose the union via simple indexing
|
|
232
219
|
* (`keyof ExtractDef<Out>` and `ExtractDef<Out>[K]`) instead of
|
|
233
220
|
* conditional types (`KindOf<Out>` and `Extract<Out, { kind: K }>`).
|
|
221
|
+
*
|
|
222
|
+
* **Void → null mapping:** Variants with `void` payload (e.g. `{ None: void }`)
|
|
223
|
+
* become `{ kind: "None"; value: null }` at runtime. This is handled by
|
|
224
|
+
* `VoidToNull` below — `void` has no runtime representation in JSON, so it
|
|
225
|
+
* serializes as `null`. Use `z.null()` in Zod schemas for void variants.
|
|
234
226
|
*/
|
|
235
227
|
type VoidToNull<T> = 0 extends 1 & T ? T : [T] extends [never] ? never : [T] extends [void] ? null : T;
|
|
236
228
|
export type TaggedUnion<TDef extends Record<string, unknown>> = {
|
|
@@ -279,12 +271,12 @@ type BranchPayload<Out, K extends string> = [ExtractDef<Out>] extends [never] ?
|
|
|
279
271
|
* Attach `.then()` and `.forEach()` methods to a plain Action object.
|
|
280
272
|
* Methods are non-enumerable: invisible to JSON.stringify and toEqual.
|
|
281
273
|
*/
|
|
282
|
-
export declare function typedAction<In = unknown, Out = unknown
|
|
274
|
+
export declare function typedAction<In = unknown, Out = unknown>(action: Action): TypedAction<In, Out>;
|
|
283
275
|
/**
|
|
284
276
|
* Extract the input type from a TypedAction.
|
|
285
277
|
*
|
|
286
278
|
* Uses direct phantom field extraction (not full TypedAction matching) to
|
|
287
|
-
* avoid
|
|
279
|
+
* avoid a full `TypedAction<any, any>` constraint which fails for In=never
|
|
288
280
|
* due to __in contravariance.
|
|
289
281
|
*/
|
|
290
282
|
export type ExtractInput<T> = T extends {
|
|
@@ -332,8 +324,6 @@ type LoopResultDef<TContinue, TBreak> = {
|
|
|
332
324
|
Break: TBreak;
|
|
333
325
|
};
|
|
334
326
|
export type LoopResult<TContinue, TBreak> = TaggedUnion<LoopResultDef<TContinue, TBreak>>;
|
|
335
|
-
export declare const TAG_BREAK: Action;
|
|
336
|
-
export declare const IDENTITY: Action;
|
|
337
327
|
/**
|
|
338
328
|
* Restartable scope. The body callback receives `restart`, a TypedAction that
|
|
339
329
|
* re-executes the body from the beginning with a new input value.
|
package/dist/ast.js
CHANGED
|
@@ -1,206 +1,56 @@
|
|
|
1
|
+
import { chain } from "./chain.js";
|
|
2
|
+
import { drop, flatten as flattenBuiltin, getField, getIndex, identity, merge, Option, pick, Result, splitFirst, splitLast, tag, wrapInField, } from "./builtins.js";
|
|
1
3
|
// ---------------------------------------------------------------------------
|
|
2
4
|
// typedAction — attach .then() and .forEach() as non-enumerable methods
|
|
3
5
|
// ---------------------------------------------------------------------------
|
|
4
6
|
// Shared implementations (one closure, not per-instance)
|
|
5
7
|
function thenMethod(next) {
|
|
6
|
-
return
|
|
8
|
+
return chain(this, next);
|
|
7
9
|
}
|
|
8
10
|
function forEachMethod(action) {
|
|
9
|
-
return
|
|
10
|
-
kind: "Chain",
|
|
11
|
-
first: this,
|
|
12
|
-
rest: { kind: "ForEach", action },
|
|
13
|
-
});
|
|
11
|
+
return chain(this, forEach(action));
|
|
14
12
|
}
|
|
15
13
|
function branchMethod(cases) {
|
|
16
|
-
return
|
|
17
|
-
kind: "Chain",
|
|
18
|
-
first: this,
|
|
19
|
-
rest: { kind: "Branch", cases: unwrapBranchCases(cases) },
|
|
20
|
-
});
|
|
14
|
+
return chain(this, branch(cases));
|
|
21
15
|
}
|
|
22
16
|
function flattenMethod() {
|
|
23
|
-
return
|
|
24
|
-
kind: "Chain",
|
|
25
|
-
first: this,
|
|
26
|
-
rest: {
|
|
27
|
-
kind: "Invoke",
|
|
28
|
-
handler: { kind: "Builtin", builtin: { kind: "Flatten" } },
|
|
29
|
-
},
|
|
30
|
-
});
|
|
17
|
+
return chain(this, flattenBuiltin());
|
|
31
18
|
}
|
|
32
19
|
function dropMethod() {
|
|
33
|
-
return
|
|
34
|
-
kind: "Chain",
|
|
35
|
-
first: this,
|
|
36
|
-
rest: {
|
|
37
|
-
kind: "Invoke",
|
|
38
|
-
handler: { kind: "Builtin", builtin: { kind: "Drop" } },
|
|
39
|
-
},
|
|
40
|
-
});
|
|
20
|
+
return chain(this, drop);
|
|
41
21
|
}
|
|
42
22
|
function tagMethod(kind) {
|
|
43
|
-
return
|
|
44
|
-
kind: "Chain",
|
|
45
|
-
first: this,
|
|
46
|
-
rest: {
|
|
47
|
-
kind: "Invoke",
|
|
48
|
-
handler: { kind: "Builtin", builtin: { kind: "Tag", value: kind } },
|
|
49
|
-
},
|
|
50
|
-
});
|
|
23
|
+
return chain(this, tag(kind));
|
|
51
24
|
}
|
|
52
25
|
function getFieldMethod(field) {
|
|
53
|
-
return
|
|
54
|
-
kind: "Chain",
|
|
55
|
-
first: this,
|
|
56
|
-
rest: {
|
|
57
|
-
kind: "Invoke",
|
|
58
|
-
handler: {
|
|
59
|
-
kind: "Builtin",
|
|
60
|
-
builtin: { kind: "GetField", value: field },
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
});
|
|
26
|
+
return chain(this, getField(field));
|
|
64
27
|
}
|
|
65
28
|
function getIndexMethod(index) {
|
|
66
|
-
return
|
|
67
|
-
kind: "Chain",
|
|
68
|
-
first: this,
|
|
69
|
-
rest: {
|
|
70
|
-
kind: "Invoke",
|
|
71
|
-
handler: {
|
|
72
|
-
kind: "Builtin",
|
|
73
|
-
builtin: { kind: "GetIndex", value: index },
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
});
|
|
29
|
+
return chain(this, getIndex(index));
|
|
77
30
|
}
|
|
78
31
|
function wrapInFieldMethod(field) {
|
|
79
|
-
return
|
|
80
|
-
kind: "Chain",
|
|
81
|
-
first: this,
|
|
82
|
-
rest: {
|
|
83
|
-
kind: "Invoke",
|
|
84
|
-
handler: {
|
|
85
|
-
kind: "Builtin",
|
|
86
|
-
builtin: { kind: "WrapInField", value: field },
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
});
|
|
32
|
+
return chain(this, wrapInField(field));
|
|
90
33
|
}
|
|
91
34
|
function mergeMethod() {
|
|
92
|
-
return
|
|
93
|
-
kind: "Chain",
|
|
94
|
-
first: this,
|
|
95
|
-
rest: {
|
|
96
|
-
kind: "Invoke",
|
|
97
|
-
handler: { kind: "Builtin", builtin: { kind: "Merge" } },
|
|
98
|
-
},
|
|
99
|
-
});
|
|
35
|
+
return chain(this, merge());
|
|
100
36
|
}
|
|
101
37
|
function pickMethod(...keys) {
|
|
102
|
-
return
|
|
103
|
-
kind: "Chain",
|
|
104
|
-
first: this,
|
|
105
|
-
rest: {
|
|
106
|
-
kind: "Invoke",
|
|
107
|
-
handler: { kind: "Builtin", builtin: { kind: "Pick", value: keys } },
|
|
108
|
-
},
|
|
109
|
-
});
|
|
38
|
+
return chain(this, pick(...keys));
|
|
110
39
|
}
|
|
111
40
|
function splitFirstMethod() {
|
|
112
|
-
return
|
|
113
|
-
kind: "Chain",
|
|
114
|
-
first: this,
|
|
115
|
-
rest: {
|
|
116
|
-
kind: "Invoke",
|
|
117
|
-
handler: { kind: "Builtin", builtin: { kind: "SplitFirst" } },
|
|
118
|
-
},
|
|
119
|
-
});
|
|
41
|
+
return chain(this, splitFirst());
|
|
120
42
|
}
|
|
121
43
|
function splitLastMethod() {
|
|
122
|
-
return
|
|
123
|
-
kind: "Chain",
|
|
124
|
-
first: this,
|
|
125
|
-
rest: {
|
|
126
|
-
kind: "Invoke",
|
|
127
|
-
handler: { kind: "Builtin", builtin: { kind: "SplitLast" } },
|
|
128
|
-
},
|
|
129
|
-
});
|
|
44
|
+
return chain(this, splitLast());
|
|
130
45
|
}
|
|
131
46
|
function mapOptionMethod(action) {
|
|
132
|
-
|
|
133
|
-
// But branch auto-unwraps value, so:
|
|
134
|
-
// Some case: receives T, runs action, wraps as Some
|
|
135
|
-
// None case: receives void, wraps as None
|
|
136
|
-
return typedAction({
|
|
137
|
-
kind: "Chain",
|
|
138
|
-
first: this,
|
|
139
|
-
rest: {
|
|
140
|
-
kind: "Branch",
|
|
141
|
-
cases: unwrapBranchCases({
|
|
142
|
-
Some: {
|
|
143
|
-
kind: "Chain",
|
|
144
|
-
first: action,
|
|
145
|
-
rest: {
|
|
146
|
-
kind: "Invoke",
|
|
147
|
-
handler: {
|
|
148
|
-
kind: "Builtin",
|
|
149
|
-
builtin: { kind: "Tag", value: "Some" },
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
None: {
|
|
154
|
-
kind: "Invoke",
|
|
155
|
-
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "None" } },
|
|
156
|
-
},
|
|
157
|
-
}),
|
|
158
|
-
},
|
|
159
|
-
});
|
|
47
|
+
return chain(this, Option.map(action));
|
|
160
48
|
}
|
|
161
49
|
function mapErrMethod(action) {
|
|
162
|
-
|
|
163
|
-
return typedAction({
|
|
164
|
-
kind: "Chain",
|
|
165
|
-
first: this,
|
|
166
|
-
rest: {
|
|
167
|
-
kind: "Branch",
|
|
168
|
-
cases: unwrapBranchCases({
|
|
169
|
-
Ok: {
|
|
170
|
-
kind: "Invoke",
|
|
171
|
-
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "Ok" } },
|
|
172
|
-
},
|
|
173
|
-
Err: {
|
|
174
|
-
kind: "Chain",
|
|
175
|
-
first: action,
|
|
176
|
-
rest: {
|
|
177
|
-
kind: "Invoke",
|
|
178
|
-
handler: {
|
|
179
|
-
kind: "Builtin",
|
|
180
|
-
builtin: { kind: "Tag", value: "Err" },
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
}),
|
|
185
|
-
},
|
|
186
|
-
});
|
|
50
|
+
return chain(this, Result.mapErr(action));
|
|
187
51
|
}
|
|
188
52
|
function unwrapOrMethod(defaultAction) {
|
|
189
|
-
|
|
190
|
-
return typedAction({
|
|
191
|
-
kind: "Chain",
|
|
192
|
-
first: this,
|
|
193
|
-
rest: {
|
|
194
|
-
kind: "Branch",
|
|
195
|
-
cases: unwrapBranchCases({
|
|
196
|
-
Ok: {
|
|
197
|
-
kind: "Invoke",
|
|
198
|
-
handler: { kind: "Builtin", builtin: { kind: "Identity" } },
|
|
199
|
-
},
|
|
200
|
-
Err: defaultAction,
|
|
201
|
-
}),
|
|
202
|
-
},
|
|
203
|
-
});
|
|
53
|
+
return chain(this, Result.unwrapOr(defaultAction));
|
|
204
54
|
}
|
|
205
55
|
/**
|
|
206
56
|
* Attach `.then()` and `.forEach()` methods to a plain Action object.
|
|
@@ -253,17 +103,7 @@ export function forEach(action) {
|
|
|
253
103
|
function unwrapBranchCases(cases) {
|
|
254
104
|
const unwrapped = {};
|
|
255
105
|
for (const key of Object.keys(cases)) {
|
|
256
|
-
unwrapped[key] =
|
|
257
|
-
kind: "Chain",
|
|
258
|
-
first: {
|
|
259
|
-
kind: "Invoke",
|
|
260
|
-
handler: {
|
|
261
|
-
kind: "Builtin",
|
|
262
|
-
builtin: { kind: "GetField", value: "value" },
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
rest: cases[key],
|
|
266
|
-
};
|
|
106
|
+
unwrapped[key] = chain(getField("value"), cases[key]);
|
|
267
107
|
}
|
|
268
108
|
return unwrapped;
|
|
269
109
|
}
|
|
@@ -272,25 +112,6 @@ export function branch(cases) {
|
|
|
272
112
|
return typedAction({ kind: "Branch", cases: unwrapBranchCases(cases) });
|
|
273
113
|
}
|
|
274
114
|
// ---------------------------------------------------------------------------
|
|
275
|
-
// Shared AST constants for control flow compilation
|
|
276
|
-
// ---------------------------------------------------------------------------
|
|
277
|
-
const EXTRACT_PAYLOAD = {
|
|
278
|
-
kind: "Invoke",
|
|
279
|
-
handler: { kind: "Builtin", builtin: { kind: "GetIndex", value: 0 } },
|
|
280
|
-
};
|
|
281
|
-
const TAG_CONTINUE = {
|
|
282
|
-
kind: "Invoke",
|
|
283
|
-
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "Continue" } },
|
|
284
|
-
};
|
|
285
|
-
export const TAG_BREAK = {
|
|
286
|
-
kind: "Invoke",
|
|
287
|
-
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "Break" } },
|
|
288
|
-
};
|
|
289
|
-
export const IDENTITY = {
|
|
290
|
-
kind: "Invoke",
|
|
291
|
-
handler: { kind: "Builtin", builtin: { kind: "Identity" } },
|
|
292
|
-
};
|
|
293
|
-
// ---------------------------------------------------------------------------
|
|
294
115
|
// recur — restart body primitive
|
|
295
116
|
// ---------------------------------------------------------------------------
|
|
296
117
|
/**
|
|
@@ -313,7 +134,7 @@ export function recur(bodyFn) {
|
|
|
313
134
|
kind: "RestartHandle",
|
|
314
135
|
restart_handler_id: restartHandlerId,
|
|
315
136
|
body,
|
|
316
|
-
handler:
|
|
137
|
+
handler: getIndex(0),
|
|
317
138
|
});
|
|
318
139
|
}
|
|
319
140
|
// ---------------------------------------------------------------------------
|
|
@@ -333,13 +154,12 @@ export function recur(bodyFn) {
|
|
|
333
154
|
*/
|
|
334
155
|
export function earlyReturn(bodyFn) {
|
|
335
156
|
const restartHandlerId = allocateRestartHandlerId();
|
|
336
|
-
const earlyReturnAction = typedAction({
|
|
337
|
-
kind: "
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
});
|
|
157
|
+
const earlyReturnAction = typedAction(chain(tag("Break"), {
|
|
158
|
+
kind: "RestartPerform",
|
|
159
|
+
restart_handler_id: restartHandlerId,
|
|
160
|
+
}));
|
|
341
161
|
const body = bodyFn(earlyReturnAction);
|
|
342
|
-
return typedAction(buildRestartBranchAction(restartHandlerId, body,
|
|
162
|
+
return typedAction(buildRestartBranchAction(restartHandlerId, body, identity()));
|
|
343
163
|
}
|
|
344
164
|
// ---------------------------------------------------------------------------
|
|
345
165
|
// loop — iterative restart with break
|
|
@@ -354,22 +174,12 @@ export function earlyReturn(bodyFn) {
|
|
|
354
174
|
* Used by earlyReturn, loop, tryCatch, and race.
|
|
355
175
|
*/
|
|
356
176
|
export function buildRestartBranchAction(restartHandlerId, continueArm, breakArm) {
|
|
357
|
-
return {
|
|
358
|
-
kind: "
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
body: {
|
|
364
|
-
kind: "Branch",
|
|
365
|
-
cases: unwrapBranchCases({
|
|
366
|
-
Continue: continueArm,
|
|
367
|
-
Break: breakArm,
|
|
368
|
-
}),
|
|
369
|
-
},
|
|
370
|
-
handler: EXTRACT_PAYLOAD,
|
|
371
|
-
},
|
|
372
|
-
};
|
|
177
|
+
return chain(tag("Continue"), {
|
|
178
|
+
kind: "RestartHandle",
|
|
179
|
+
restart_handler_id: restartHandlerId,
|
|
180
|
+
body: branch({ Continue: continueArm, Break: breakArm }),
|
|
181
|
+
handler: getIndex(0),
|
|
182
|
+
});
|
|
373
183
|
}
|
|
374
184
|
/**
|
|
375
185
|
* Iterative loop. The body callback receives `recur` and `done`:
|
|
@@ -386,18 +196,10 @@ export function loop(bodyFn) {
|
|
|
386
196
|
kind: "RestartPerform",
|
|
387
197
|
restart_handler_id: restartHandlerId,
|
|
388
198
|
};
|
|
389
|
-
const recurAction = typedAction(
|
|
390
|
-
|
|
391
|
-
first: TAG_CONTINUE,
|
|
392
|
-
rest: perform,
|
|
393
|
-
});
|
|
394
|
-
const doneAction = typedAction({
|
|
395
|
-
kind: "Chain",
|
|
396
|
-
first: TAG_BREAK,
|
|
397
|
-
rest: perform,
|
|
398
|
-
});
|
|
199
|
+
const recurAction = typedAction(chain(tag("Continue"), perform));
|
|
200
|
+
const doneAction = typedAction(chain(tag("Break"), perform));
|
|
399
201
|
const body = bodyFn(recurAction, doneAction);
|
|
400
|
-
return typedAction(buildRestartBranchAction(restartHandlerId, body,
|
|
202
|
+
return typedAction(buildRestartBranchAction(restartHandlerId, body, identity()));
|
|
401
203
|
}
|
|
402
204
|
// ---------------------------------------------------------------------------
|
|
403
205
|
// Config builders
|
package/dist/bind.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { typedAction, } from "./ast.js";
|
|
2
|
-
import {
|
|
2
|
+
import { chain } from "./chain.js";
|
|
3
|
+
import { all } from "./all.js";
|
|
4
|
+
import { identity, drop, getIndex } from "./builtins.js";
|
|
3
5
|
import { allocateResumeHandlerId } from "./effect-id.js";
|
|
4
6
|
import { pipe } from "./pipe.js";
|
|
5
7
|
function createVarRef(resumeHandlerId) {
|
|
@@ -21,35 +23,7 @@ function createVarRef(resumeHandlerId) {
|
|
|
21
23
|
* Expanded AST: All(Chain(GetIndex(1), GetIndex(n)), GetIndex(1))
|
|
22
24
|
*/
|
|
23
25
|
function readVar(n) {
|
|
24
|
-
return
|
|
25
|
-
kind: "All",
|
|
26
|
-
actions: [
|
|
27
|
-
{
|
|
28
|
-
kind: "Chain",
|
|
29
|
-
first: {
|
|
30
|
-
kind: "Invoke",
|
|
31
|
-
handler: {
|
|
32
|
-
kind: "Builtin",
|
|
33
|
-
builtin: { kind: "GetIndex", value: 1 },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
rest: {
|
|
37
|
-
kind: "Invoke",
|
|
38
|
-
handler: {
|
|
39
|
-
kind: "Builtin",
|
|
40
|
-
builtin: { kind: "GetIndex", value: n },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
kind: "Invoke",
|
|
46
|
-
handler: {
|
|
47
|
-
kind: "Builtin",
|
|
48
|
-
builtin: { kind: "GetIndex", value: 1 },
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
};
|
|
26
|
+
return all(chain(getIndex(1), getIndex(n)), getIndex(1));
|
|
53
27
|
}
|
|
54
28
|
export function bind(bindings, body) {
|
|
55
29
|
// 1. Gensym one resumeHandlerId per binding.
|
|
@@ -61,17 +35,7 @@ export function bind(bindings, body) {
|
|
|
61
35
|
// 4. Build nested Handles from inside out.
|
|
62
36
|
// Innermost: extract pipeline_input (last All element) → user body
|
|
63
37
|
const pipelineInputIndex = bindings.length;
|
|
64
|
-
let inner =
|
|
65
|
-
kind: "Chain",
|
|
66
|
-
first: {
|
|
67
|
-
kind: "Invoke",
|
|
68
|
-
handler: {
|
|
69
|
-
kind: "Builtin",
|
|
70
|
-
builtin: { kind: "GetIndex", value: pipelineInputIndex },
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
rest: bodyAction,
|
|
74
|
-
};
|
|
38
|
+
let inner = chain(getIndex(pipelineInputIndex), bodyAction);
|
|
75
39
|
for (let i = resumeHandlerIds.length - 1; i >= 0; i--) {
|
|
76
40
|
inner = {
|
|
77
41
|
kind: "ResumeHandle",
|
|
@@ -81,15 +45,11 @@ export function bind(bindings, body) {
|
|
|
81
45
|
};
|
|
82
46
|
}
|
|
83
47
|
// 5. All(...bindings, identity()) → nested Handles
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
identity(),
|
|
87
|
-
|
|
88
|
-
return typedAction(
|
|
89
|
-
kind: "Chain",
|
|
90
|
-
first: { kind: "All", actions: allActions },
|
|
91
|
-
rest: inner,
|
|
92
|
-
});
|
|
48
|
+
const allAction = {
|
|
49
|
+
kind: "All",
|
|
50
|
+
actions: [...bindings.map((b) => b), identity()],
|
|
51
|
+
};
|
|
52
|
+
return typedAction(chain(allAction, inner));
|
|
93
53
|
}
|
|
94
54
|
// ---------------------------------------------------------------------------
|
|
95
55
|
// bindInput — bind the pipeline input
|