@barnum/barnum 0.0.0-main-50effdfd → 0.0.0-main-39525152
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/ast.d.ts +8 -6
- package/dist/ast.js +22 -8
- package/dist/bind.d.ts +2 -2
- package/dist/bind.js +5 -5
- package/dist/builtins.d.ts +2 -2
- package/dist/builtins.js +14 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/race.d.ts +1 -1
- package/dist/race.js +1 -1
- package/dist/recursive.js +5 -5
- package/dist/try-catch.d.ts +1 -1
- package/dist/try-catch.js +1 -1
- package/package.json +1 -1
- package/src/ast.ts +37 -12
- package/src/bind.ts +7 -7
- package/src/builtins.ts +14 -14
- package/src/index.ts +2 -2
- package/src/race.ts +1 -1
- package/src/recursive.ts +5 -11
- package/src/try-catch.ts +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/ast.d.ts
CHANGED
|
@@ -68,10 +68,10 @@ export type BuiltinKind = {
|
|
|
68
68
|
} | {
|
|
69
69
|
kind: "Flatten";
|
|
70
70
|
} | {
|
|
71
|
-
kind: "
|
|
71
|
+
kind: "GetField";
|
|
72
72
|
value: string;
|
|
73
73
|
} | {
|
|
74
|
-
kind: "
|
|
74
|
+
kind: "GetIndex";
|
|
75
75
|
value: number;
|
|
76
76
|
} | {
|
|
77
77
|
kind: "Pick";
|
|
@@ -134,8 +134,10 @@ export type TypedAction<In = unknown, Out = unknown, Refs extends string = never
|
|
|
134
134
|
drop(): TypedAction<In, never, Refs>;
|
|
135
135
|
/** Wrap output as a tagged union member. Requires full variant map TDef so __def is carried. */
|
|
136
136
|
tag<TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(kind: TKind): TypedAction<In, TaggedUnion<TDef>, Refs>;
|
|
137
|
-
/** Extract a field from the output object. `a.
|
|
138
|
-
|
|
137
|
+
/** 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], Refs>;
|
|
139
|
+
/** 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, TRefs extends string>(this: TypedAction<TIn, TTuple, TRefs>, index: TIndex): TypedAction<TIn, TTuple[TIndex], TRefs>;
|
|
139
141
|
/** Wrap output in an object under a field name. `a.wrapInField("foo")` ≡ `pipe(a, wrapInField("foo"))`. */
|
|
140
142
|
wrapInField<TField extends string>(field: TField): TypedAction<In, Record<TField, Out>, Refs>;
|
|
141
143
|
/** Merge a tuple of objects into a single object. `a.merge()` ≡ `pipe(a, merge())`. */
|
|
@@ -339,7 +341,7 @@ export declare const IDENTITY: Action;
|
|
|
339
341
|
* If the body completes normally → output is TOut.
|
|
340
342
|
* If restart fires → body re-executes with the restarted value.
|
|
341
343
|
*
|
|
342
|
-
* Compiled form: `RestartHandle(id,
|
|
344
|
+
* Compiled form: `RestartHandle(id, GetIndex(0), body)`
|
|
343
345
|
*/
|
|
344
346
|
export declare function recur<TIn = never, TOut = any>(bodyFn: (restart: TypedAction<TIn, never>) => Pipeable<TIn, TOut>): TypedAction<PipeIn<TIn>, TOut>;
|
|
345
347
|
/**
|
|
@@ -357,7 +359,7 @@ export declare function recur<TIn = never, TOut = any>(bodyFn: (restart: TypedAc
|
|
|
357
359
|
export declare function earlyReturn<TEarlyReturn = never, TIn = any, TOut = any>(bodyFn: (earlyReturn: TypedAction<TEarlyReturn, never>) => Pipeable<TIn, TOut>): TypedAction<TIn, TEarlyReturn | TOut>;
|
|
358
360
|
/**
|
|
359
361
|
* Build the restart+branch compiled form:
|
|
360
|
-
* `Chain(Tag("Continue"), RestartHandle(id,
|
|
362
|
+
* `Chain(Tag("Continue"), RestartHandle(id, GetIndex(0), Branch({ Continue: continueArm, Break: breakArm })))`
|
|
361
363
|
*
|
|
362
364
|
* Input is tagged Continue so the Branch enters the continueArm on first execution.
|
|
363
365
|
* Continue tag → restart → re-enters continueArm. Break tag → restart → runs breakArm, exits `RestartHandle`.
|
package/dist/ast.js
CHANGED
|
@@ -49,7 +49,7 @@ function tagMethod(kind) {
|
|
|
49
49
|
},
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function getFieldMethod(field) {
|
|
53
53
|
return typedAction({
|
|
54
54
|
kind: "Chain",
|
|
55
55
|
first: this,
|
|
@@ -57,7 +57,20 @@ function getMethod(field) {
|
|
|
57
57
|
kind: "Invoke",
|
|
58
58
|
handler: {
|
|
59
59
|
kind: "Builtin",
|
|
60
|
-
builtin: { kind: "
|
|
60
|
+
builtin: { kind: "GetField", value: field },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function getIndexMethod(index) {
|
|
66
|
+
return typedAction({
|
|
67
|
+
kind: "Chain",
|
|
68
|
+
first: this,
|
|
69
|
+
rest: {
|
|
70
|
+
kind: "Invoke",
|
|
71
|
+
handler: {
|
|
72
|
+
kind: "Builtin",
|
|
73
|
+
builtin: { kind: "GetIndex", value: index },
|
|
61
74
|
},
|
|
62
75
|
},
|
|
63
76
|
});
|
|
@@ -202,7 +215,8 @@ export function typedAction(action) {
|
|
|
202
215
|
flatten: { value: flattenMethod, configurable: true },
|
|
203
216
|
drop: { value: dropMethod, configurable: true },
|
|
204
217
|
tag: { value: tagMethod, configurable: true },
|
|
205
|
-
|
|
218
|
+
getField: { value: getFieldMethod, configurable: true },
|
|
219
|
+
getIndex: { value: getIndexMethod, configurable: true },
|
|
206
220
|
wrapInField: { value: wrapInFieldMethod, configurable: true },
|
|
207
221
|
merge: { value: mergeMethod, configurable: true },
|
|
208
222
|
pick: { value: pickMethod, configurable: true },
|
|
@@ -231,7 +245,7 @@ export function forEach(action) {
|
|
|
231
245
|
return typedAction({ kind: "ForEach", action: action });
|
|
232
246
|
}
|
|
233
247
|
/**
|
|
234
|
-
* Insert
|
|
248
|
+
* Insert GetField("value") before each case handler in a branch.
|
|
235
249
|
* This implements auto-unwrapping: the engine dispatches on `kind`, then
|
|
236
250
|
* extracts `value` before passing to the handler. Case handlers receive
|
|
237
251
|
* the payload directly, not the full `{ kind, value }` variant.
|
|
@@ -245,7 +259,7 @@ function unwrapBranchCases(cases) {
|
|
|
245
259
|
kind: "Invoke",
|
|
246
260
|
handler: {
|
|
247
261
|
kind: "Builtin",
|
|
248
|
-
builtin: { kind: "
|
|
262
|
+
builtin: { kind: "GetField", value: "value" },
|
|
249
263
|
},
|
|
250
264
|
},
|
|
251
265
|
rest: cases[key],
|
|
@@ -262,7 +276,7 @@ export function branch(cases) {
|
|
|
262
276
|
// ---------------------------------------------------------------------------
|
|
263
277
|
const EXTRACT_PAYLOAD = {
|
|
264
278
|
kind: "Invoke",
|
|
265
|
-
handler: { kind: "Builtin", builtin: { kind: "
|
|
279
|
+
handler: { kind: "Builtin", builtin: { kind: "GetIndex", value: 0 } },
|
|
266
280
|
};
|
|
267
281
|
const TAG_CONTINUE = {
|
|
268
282
|
kind: "Invoke",
|
|
@@ -286,7 +300,7 @@ export const IDENTITY = {
|
|
|
286
300
|
* If the body completes normally → output is TOut.
|
|
287
301
|
* If restart fires → body re-executes with the restarted value.
|
|
288
302
|
*
|
|
289
|
-
* Compiled form: `RestartHandle(id,
|
|
303
|
+
* Compiled form: `RestartHandle(id, GetIndex(0), body)`
|
|
290
304
|
*/
|
|
291
305
|
export function recur(bodyFn) {
|
|
292
306
|
const restartHandlerId = allocateRestartHandlerId();
|
|
@@ -332,7 +346,7 @@ export function earlyReturn(bodyFn) {
|
|
|
332
346
|
// ---------------------------------------------------------------------------
|
|
333
347
|
/**
|
|
334
348
|
* Build the restart+branch compiled form:
|
|
335
|
-
* `Chain(Tag("Continue"), RestartHandle(id,
|
|
349
|
+
* `Chain(Tag("Continue"), RestartHandle(id, GetIndex(0), Branch({ Continue: continueArm, Break: breakArm })))`
|
|
336
350
|
*
|
|
337
351
|
* Input is tagged Continue so the Branch enters the continueArm on first execution.
|
|
338
352
|
* Continue tag → restart → re-enters continueArm. Break tag → restart → runs breakArm, exits `RestartHandle`.
|
package/dist/bind.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type Action, type ExtractInput, type ExtractOutput, type TypedAction }
|
|
|
3
3
|
* A typed reference to a bound value. Output is `TValue`.
|
|
4
4
|
*
|
|
5
5
|
* Use `.then()` (not `pipe()`) when chaining a VarRef into a generic
|
|
6
|
-
* action like `pick` or `
|
|
6
|
+
* action like `pick` or `getField` — pipe overloads can't infer
|
|
7
7
|
* the generic's type parameter from the VarRef's output.
|
|
8
8
|
*/
|
|
9
9
|
export type VarRef<TValue> = TypedAction<never, TValue>;
|
|
@@ -33,7 +33,7 @@ export type InferVarRefs<TBindings extends Action[]> = {
|
|
|
33
33
|
* All(...bindings, Identity),
|
|
34
34
|
* ResumeHandle(r0, readVar(0),
|
|
35
35
|
* ResumeHandle(r1, readVar(1),
|
|
36
|
-
* Chain(
|
|
36
|
+
* Chain(GetIndex(N), body)
|
|
37
37
|
* )
|
|
38
38
|
* )
|
|
39
39
|
* )
|
package/dist/bind.js
CHANGED
|
@@ -18,7 +18,7 @@ function createVarRef(resumeHandlerId) {
|
|
|
18
18
|
* `state` (index 1) is the full All output tuple. The handler produces
|
|
19
19
|
* `[state[n], state]` — value is state[n], new_state is state (unchanged).
|
|
20
20
|
*
|
|
21
|
-
* Expanded AST: All(Chain(
|
|
21
|
+
* Expanded AST: All(Chain(GetIndex(1), GetIndex(n)), GetIndex(1))
|
|
22
22
|
*/
|
|
23
23
|
function readVar(n) {
|
|
24
24
|
return {
|
|
@@ -30,14 +30,14 @@ function readVar(n) {
|
|
|
30
30
|
kind: "Invoke",
|
|
31
31
|
handler: {
|
|
32
32
|
kind: "Builtin",
|
|
33
|
-
builtin: { kind: "
|
|
33
|
+
builtin: { kind: "GetIndex", value: 1 },
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
rest: {
|
|
37
37
|
kind: "Invoke",
|
|
38
38
|
handler: {
|
|
39
39
|
kind: "Builtin",
|
|
40
|
-
builtin: { kind: "
|
|
40
|
+
builtin: { kind: "GetIndex", value: n },
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
@@ -45,7 +45,7 @@ function readVar(n) {
|
|
|
45
45
|
kind: "Invoke",
|
|
46
46
|
handler: {
|
|
47
47
|
kind: "Builtin",
|
|
48
|
-
builtin: { kind: "
|
|
48
|
+
builtin: { kind: "GetIndex", value: 1 },
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
],
|
|
@@ -67,7 +67,7 @@ export function bind(bindings, body) {
|
|
|
67
67
|
kind: "Invoke",
|
|
68
68
|
handler: {
|
|
69
69
|
kind: "Builtin",
|
|
70
|
-
builtin: { kind: "
|
|
70
|
+
builtin: { kind: "GetIndex", value: pipelineInputIndex },
|
|
71
71
|
},
|
|
72
72
|
},
|
|
73
73
|
rest: bodyAction,
|
package/dist/builtins.d.ts
CHANGED
|
@@ -18,8 +18,8 @@ export declare const drop: TypedAction<any, never>;
|
|
|
18
18
|
export declare function tag<TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(kind: TKind): TypedAction<TDef[TKind], TaggedUnion<TDef>>;
|
|
19
19
|
export declare function merge<TTuple extends Record<string, unknown>[]>(): TypedAction<TTuple, MergeTuple<TTuple>>;
|
|
20
20
|
export declare function flatten<TElement>(): TypedAction<TElement[][], TElement[]>;
|
|
21
|
-
export declare function
|
|
22
|
-
export declare function
|
|
21
|
+
export declare function getField<TObj extends Record<string, unknown>, TField extends keyof TObj & string>(field: TField): TypedAction<TObj, TObj[TField]>;
|
|
22
|
+
export declare function getIndex<TTuple extends unknown[], TIndex extends number>(index: TIndex): TypedAction<TTuple, TTuple[TIndex]>;
|
|
23
23
|
export declare function pick<TObj extends Record<string, unknown>, TKeys extends (keyof TObj & string)[]>(...keys: TKeys): TypedAction<TObj, Pick<TObj, TKeys[number]>>;
|
|
24
24
|
export declare function dropResult<TInput, TOutput>(action: Pipeable<TInput, TOutput>): TypedAction<TInput, never>;
|
|
25
25
|
/**
|
package/dist/builtins.js
CHANGED
|
@@ -64,26 +64,26 @@ export function flatten() {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
// ---------------------------------------------------------------------------
|
|
67
|
-
//
|
|
67
|
+
// GetField — extract a single field from an object
|
|
68
68
|
// ---------------------------------------------------------------------------
|
|
69
|
-
export function
|
|
69
|
+
export function getField(field) {
|
|
70
70
|
return typedAction({
|
|
71
71
|
kind: "Invoke",
|
|
72
72
|
handler: {
|
|
73
73
|
kind: "Builtin",
|
|
74
|
-
builtin: { kind: "
|
|
74
|
+
builtin: { kind: "GetField", value: field },
|
|
75
75
|
},
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
// ---------------------------------------------------------------------------
|
|
79
|
-
//
|
|
79
|
+
// GetIndex — extract a single element from an array by index
|
|
80
80
|
// ---------------------------------------------------------------------------
|
|
81
|
-
export function
|
|
81
|
+
export function getIndex(index) {
|
|
82
82
|
return typedAction({
|
|
83
83
|
kind: "Invoke",
|
|
84
84
|
handler: {
|
|
85
85
|
kind: "Builtin",
|
|
86
|
-
builtin: { kind: "
|
|
86
|
+
builtin: { kind: "GetIndex", value: index },
|
|
87
87
|
},
|
|
88
88
|
});
|
|
89
89
|
}
|
|
@@ -146,16 +146,16 @@ export function withResource({ create, action, dispose, }) {
|
|
|
146
146
|
kind: "All",
|
|
147
147
|
actions: [action, identity],
|
|
148
148
|
});
|
|
149
|
-
// Step 3: all(
|
|
149
|
+
// Step 3: all(getIndex(0), chain(getIndex(1), dispose)) → [TOut, unknown]
|
|
150
150
|
const disposeAndKeepResult = typedAction({
|
|
151
151
|
kind: "All",
|
|
152
152
|
actions: [
|
|
153
|
-
|
|
154
|
-
chain(
|
|
153
|
+
getIndex(0),
|
|
154
|
+
chain(getIndex(1), dispose),
|
|
155
155
|
],
|
|
156
156
|
});
|
|
157
|
-
// Step 4:
|
|
158
|
-
return chain(chain(chain(acquireAndMerge, actionAndKeepMerged), disposeAndKeepResult),
|
|
157
|
+
// Step 4: getIndex(0) → TOut
|
|
158
|
+
return chain(chain(chain(acquireAndMerge, actionAndKeepMerged), disposeAndKeepResult), getIndex(0));
|
|
159
159
|
}
|
|
160
160
|
// ---------------------------------------------------------------------------
|
|
161
161
|
// Tap — run an action for side effects, preserve original input
|
|
@@ -281,7 +281,7 @@ const EXTRACT_VALUE = {
|
|
|
281
281
|
kind: "Invoke",
|
|
282
282
|
handler: {
|
|
283
283
|
kind: "Builtin",
|
|
284
|
-
builtin: { kind: "
|
|
284
|
+
builtin: { kind: "GetField", value: "value" },
|
|
285
285
|
},
|
|
286
286
|
};
|
|
287
287
|
const DROP = {
|
|
@@ -292,7 +292,7 @@ const IDENTITY = {
|
|
|
292
292
|
kind: "Invoke",
|
|
293
293
|
handler: { kind: "Builtin", builtin: { kind: "Identity" } },
|
|
294
294
|
};
|
|
295
|
-
/** Wrap branch cases with
|
|
295
|
+
/** Wrap branch cases with GetField("value") auto-unwrapping. */
|
|
296
296
|
function optionBranch(someCaseBody, noneCaseBody) {
|
|
297
297
|
return {
|
|
298
298
|
kind: "Branch",
|
|
@@ -455,7 +455,7 @@ const TAG_ERR = {
|
|
|
455
455
|
kind: "Invoke",
|
|
456
456
|
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "Err" } },
|
|
457
457
|
};
|
|
458
|
-
/** Wrap branch cases with
|
|
458
|
+
/** Wrap branch cases with GetField("value") auto-unwrapping. */
|
|
459
459
|
function resultBranch(okCaseBody, errCaseBody) {
|
|
460
460
|
return {
|
|
461
461
|
kind: "Branch",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TaggedUnion, OptionDef, ResultDef } from "./ast.js";
|
|
2
2
|
export * from "./ast.js";
|
|
3
|
-
export { constant, identity, drop, tag, merge, flatten,
|
|
3
|
+
export { constant, identity, drop, tag, merge, flatten, getField, getIndex, pick, dropResult, withResource, tap, range, splitFirst, splitLast, wrapInField, Option, Result, } from "./builtins.js";
|
|
4
4
|
export * from "./handler.js";
|
|
5
5
|
export { runPipeline, type RunPipelineOptions, type LogLevel } from "./run.js";
|
|
6
6
|
export { zodToCheckedJsonSchema } from "./schema.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./ast.js";
|
|
2
|
-
export { constant, identity, drop, tag, merge, flatten,
|
|
2
|
+
export { constant, identity, drop, tag, merge, flatten, getField, getIndex, pick, dropResult, withResource, tap, range, splitFirst, splitLast, wrapInField, Option, Result, } from "./builtins.js";
|
|
3
3
|
export * from "./handler.js";
|
|
4
4
|
export { runPipeline } from "./run.js";
|
|
5
5
|
export { zodToCheckedJsonSchema } from "./schema.js";
|
package/dist/race.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { type Pipeable, type Result, type TypedAction } from "./ast.js";
|
|
|
8
8
|
*
|
|
9
9
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
10
10
|
* `Chain(Tag("Continue"),`
|
|
11
|
-
* `RestartHandle(id,
|
|
11
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
12
12
|
* `Branch({`
|
|
13
13
|
* `Continue: All(Chain(a, breakPerform), Chain(b, breakPerform), ...),`
|
|
14
14
|
* `Break: identity,`
|
package/dist/race.js
CHANGED
|
@@ -35,7 +35,7 @@ function breakPerform(restartHandlerId) {
|
|
|
35
35
|
*
|
|
36
36
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
37
37
|
* `Chain(Tag("Continue"),`
|
|
38
|
-
* `RestartHandle(id,
|
|
38
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
39
39
|
* `Branch({`
|
|
40
40
|
* `Continue: All(Chain(a, breakPerform), Chain(b, breakPerform), ...),`
|
|
41
41
|
* `Break: identity,`
|
package/dist/recursive.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { typedAction, branch, } from "./ast.js";
|
|
2
2
|
import { all } from "./all.js";
|
|
3
3
|
import { chain } from "./chain.js";
|
|
4
|
-
import { constant, identity,
|
|
4
|
+
import { constant, identity, getField, getIndex, tag } from "./builtins.js";
|
|
5
5
|
import { allocateResumeHandlerId } from "./effect-id.js";
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
7
|
const UNUSED_STATE = undefined;
|
|
@@ -35,10 +35,10 @@ export function defineRecursiveFunctions(bodiesFn) {
|
|
|
35
35
|
const callTokens = Array.from({ length: fnCount }, (_, i) => typedAction(chain(tag(`Call${i}`), resumePerform)));
|
|
36
36
|
// Get function body ASTs
|
|
37
37
|
const bodyActions = bodiesFn(...callTokens);
|
|
38
|
-
// Branch cases: CallN →
|
|
38
|
+
// Branch cases: CallN → GetField("value") → bodyN
|
|
39
39
|
const cases = {};
|
|
40
40
|
for (let i = 0; i < bodyActions.length; i++) {
|
|
41
|
-
cases[`Call${i}`] = chain(
|
|
41
|
+
cases[`Call${i}`] = chain(getField("value"), bodyActions[i]);
|
|
42
42
|
}
|
|
43
43
|
// Return curried entry-point combinator
|
|
44
44
|
return (entryFn) => {
|
|
@@ -46,8 +46,8 @@ export function defineRecursiveFunctions(bodiesFn) {
|
|
|
46
46
|
return typedAction(chain(all(identity, constant(UNUSED_STATE)), {
|
|
47
47
|
kind: "ResumeHandle",
|
|
48
48
|
resume_handler_id: resumeHandlerId,
|
|
49
|
-
body: chain(
|
|
50
|
-
handler: all(chain(
|
|
49
|
+
body: chain(getIndex(0), userBody),
|
|
50
|
+
handler: all(chain(getIndex(0), branch(cases)), constant(UNUSED_STATE)),
|
|
51
51
|
}));
|
|
52
52
|
};
|
|
53
53
|
}
|
package/dist/try-catch.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { type Pipeable, type TypedAction } from "./ast.js";
|
|
|
12
12
|
*
|
|
13
13
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
14
14
|
* `Chain(Tag("Continue"),`
|
|
15
|
-
* `RestartHandle(id,
|
|
15
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
16
16
|
* `Branch({ Continue: body, Break: recovery })))`
|
|
17
17
|
*
|
|
18
18
|
* throwError = `Chain(Tag("Break"), RestartPerform(id))`
|
package/dist/try-catch.js
CHANGED
|
@@ -16,7 +16,7 @@ import { allocateRestartHandlerId } from "./effect-id.js";
|
|
|
16
16
|
*
|
|
17
17
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
18
18
|
* `Chain(Tag("Continue"),`
|
|
19
|
-
* `RestartHandle(id,
|
|
19
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
20
20
|
* `Branch({ Continue: body, Break: recovery })))`
|
|
21
21
|
*
|
|
22
22
|
* throwError = `Chain(Tag("Break"), RestartPerform(id))`
|
package/package.json
CHANGED
package/src/ast.ts
CHANGED
|
@@ -91,8 +91,8 @@ export type BuiltinKind =
|
|
|
91
91
|
| { kind: "Tag"; value: string }
|
|
92
92
|
| { kind: "Merge" }
|
|
93
93
|
| { kind: "Flatten" }
|
|
94
|
-
| { kind: "
|
|
95
|
-
| { kind: "
|
|
94
|
+
| { kind: "GetField"; value: string }
|
|
95
|
+
| { kind: "GetIndex"; value: number }
|
|
96
96
|
| { kind: "Pick"; value: string[] }
|
|
97
97
|
| { kind: "CollectSome" }
|
|
98
98
|
| { kind: "SplitFirst" }
|
|
@@ -183,10 +183,20 @@ export type TypedAction<
|
|
|
183
183
|
tag<TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(
|
|
184
184
|
kind: TKind,
|
|
185
185
|
): TypedAction<In, TaggedUnion<TDef>, Refs>;
|
|
186
|
-
/** Extract a field from the output object. `a.
|
|
187
|
-
|
|
186
|
+
/** Extract a field from the output object. `a.getField("name")` ≡ `pipe(a, getField("name"))`. */
|
|
187
|
+
getField<TField extends keyof Out & string>(
|
|
188
188
|
field: TField,
|
|
189
189
|
): TypedAction<In, Out[TField], Refs>;
|
|
190
|
+
/** Extract an element from the output tuple by index. `a.getIndex(0)` ≡ `pipe(a, getIndex(0))`. */
|
|
191
|
+
getIndex<
|
|
192
|
+
TIn,
|
|
193
|
+
TTuple extends unknown[],
|
|
194
|
+
TIndex extends number,
|
|
195
|
+
TRefs extends string,
|
|
196
|
+
>(
|
|
197
|
+
this: TypedAction<TIn, TTuple, TRefs>,
|
|
198
|
+
index: TIndex,
|
|
199
|
+
): TypedAction<TIn, TTuple[TIndex], TRefs>;
|
|
190
200
|
/** Wrap output in an object under a field name. `a.wrapInField("foo")` ≡ `pipe(a, wrapInField("foo"))`. */
|
|
191
201
|
wrapInField<TField extends string>(
|
|
192
202
|
field: TField,
|
|
@@ -428,7 +438,21 @@ function tagMethod(this: TypedAction, kind: string): TypedAction {
|
|
|
428
438
|
});
|
|
429
439
|
}
|
|
430
440
|
|
|
431
|
-
function
|
|
441
|
+
function getFieldMethod(this: TypedAction, field: string): TypedAction {
|
|
442
|
+
return typedAction({
|
|
443
|
+
kind: "Chain",
|
|
444
|
+
first: this,
|
|
445
|
+
rest: {
|
|
446
|
+
kind: "Invoke",
|
|
447
|
+
handler: {
|
|
448
|
+
kind: "Builtin",
|
|
449
|
+
builtin: { kind: "GetField", value: field },
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function getIndexMethod(this: TypedAction, index: number): TypedAction {
|
|
432
456
|
return typedAction({
|
|
433
457
|
kind: "Chain",
|
|
434
458
|
first: this,
|
|
@@ -436,7 +460,7 @@ function getMethod(this: TypedAction, field: string): TypedAction {
|
|
|
436
460
|
kind: "Invoke",
|
|
437
461
|
handler: {
|
|
438
462
|
kind: "Builtin",
|
|
439
|
-
builtin: { kind: "
|
|
463
|
+
builtin: { kind: "GetIndex", value: index },
|
|
440
464
|
},
|
|
441
465
|
},
|
|
442
466
|
});
|
|
@@ -594,7 +618,8 @@ export function typedAction<
|
|
|
594
618
|
flatten: { value: flattenMethod, configurable: true },
|
|
595
619
|
drop: { value: dropMethod, configurable: true },
|
|
596
620
|
tag: { value: tagMethod, configurable: true },
|
|
597
|
-
|
|
621
|
+
getField: { value: getFieldMethod, configurable: true },
|
|
622
|
+
getIndex: { value: getIndexMethod, configurable: true },
|
|
598
623
|
wrapInField: { value: wrapInFieldMethod, configurable: true },
|
|
599
624
|
merge: { value: mergeMethod, configurable: true },
|
|
600
625
|
pick: { value: pickMethod, configurable: true },
|
|
@@ -659,7 +684,7 @@ export function forEach<In, Out>(
|
|
|
659
684
|
}
|
|
660
685
|
|
|
661
686
|
/**
|
|
662
|
-
* Insert
|
|
687
|
+
* Insert GetField("value") before each case handler in a branch.
|
|
663
688
|
* This implements auto-unwrapping: the engine dispatches on `kind`, then
|
|
664
689
|
* extracts `value` before passing to the handler. Case handlers receive
|
|
665
690
|
* the payload directly, not the full `{ kind, value }` variant.
|
|
@@ -675,7 +700,7 @@ function unwrapBranchCases(
|
|
|
675
700
|
kind: "Invoke",
|
|
676
701
|
handler: {
|
|
677
702
|
kind: "Builtin",
|
|
678
|
-
builtin: { kind: "
|
|
703
|
+
builtin: { kind: "GetField", value: "value" },
|
|
679
704
|
},
|
|
680
705
|
},
|
|
681
706
|
rest: cases[key],
|
|
@@ -725,7 +750,7 @@ export type LoopResult<TContinue, TBreak> = TaggedUnion<
|
|
|
725
750
|
|
|
726
751
|
const EXTRACT_PAYLOAD: Action = {
|
|
727
752
|
kind: "Invoke",
|
|
728
|
-
handler: { kind: "Builtin", builtin: { kind: "
|
|
753
|
+
handler: { kind: "Builtin", builtin: { kind: "GetIndex", value: 0 } },
|
|
729
754
|
};
|
|
730
755
|
|
|
731
756
|
const TAG_CONTINUE: Action = {
|
|
@@ -754,7 +779,7 @@ export const IDENTITY: Action = {
|
|
|
754
779
|
* If the body completes normally → output is TOut.
|
|
755
780
|
* If restart fires → body re-executes with the restarted value.
|
|
756
781
|
*
|
|
757
|
-
* Compiled form: `RestartHandle(id,
|
|
782
|
+
* Compiled form: `RestartHandle(id, GetIndex(0), body)`
|
|
758
783
|
*/
|
|
759
784
|
export function recur<TIn = never, TOut = any>(
|
|
760
785
|
bodyFn: (restart: TypedAction<TIn, never>) => Pipeable<TIn, TOut>,
|
|
@@ -818,7 +843,7 @@ export function earlyReturn<TEarlyReturn = never, TIn = any, TOut = any>(
|
|
|
818
843
|
|
|
819
844
|
/**
|
|
820
845
|
* Build the restart+branch compiled form:
|
|
821
|
-
* `Chain(Tag("Continue"), RestartHandle(id,
|
|
846
|
+
* `Chain(Tag("Continue"), RestartHandle(id, GetIndex(0), Branch({ Continue: continueArm, Break: breakArm })))`
|
|
822
847
|
*
|
|
823
848
|
* Input is tagged Continue so the Branch enters the continueArm on first execution.
|
|
824
849
|
* Continue tag → restart → re-enters continueArm. Break tag → restart → runs breakArm, exits `RestartHandle`.
|
package/src/bind.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { pipe } from "./pipe.js";
|
|
|
17
17
|
* A typed reference to a bound value. Output is `TValue`.
|
|
18
18
|
*
|
|
19
19
|
* Use `.then()` (not `pipe()`) when chaining a VarRef into a generic
|
|
20
|
-
* action like `pick` or `
|
|
20
|
+
* action like `pick` or `getField` — pipe overloads can't infer
|
|
21
21
|
* the generic's type parameter from the VarRef's output.
|
|
22
22
|
*/
|
|
23
23
|
export type VarRef<TValue> = TypedAction<never, TValue>;
|
|
@@ -61,7 +61,7 @@ export type InferVarRefs<TBindings extends Action[]> = {
|
|
|
61
61
|
* `state` (index 1) is the full All output tuple. The handler produces
|
|
62
62
|
* `[state[n], state]` — value is state[n], new_state is state (unchanged).
|
|
63
63
|
*
|
|
64
|
-
* Expanded AST: All(Chain(
|
|
64
|
+
* Expanded AST: All(Chain(GetIndex(1), GetIndex(n)), GetIndex(1))
|
|
65
65
|
*/
|
|
66
66
|
function readVar(n: number): Action {
|
|
67
67
|
return {
|
|
@@ -73,14 +73,14 @@ function readVar(n: number): Action {
|
|
|
73
73
|
kind: "Invoke",
|
|
74
74
|
handler: {
|
|
75
75
|
kind: "Builtin",
|
|
76
|
-
builtin: { kind: "
|
|
76
|
+
builtin: { kind: "GetIndex", value: 1 },
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
79
|
rest: {
|
|
80
80
|
kind: "Invoke",
|
|
81
81
|
handler: {
|
|
82
82
|
kind: "Builtin",
|
|
83
|
-
builtin: { kind: "
|
|
83
|
+
builtin: { kind: "GetIndex", value: n },
|
|
84
84
|
},
|
|
85
85
|
},
|
|
86
86
|
},
|
|
@@ -88,7 +88,7 @@ function readVar(n: number): Action {
|
|
|
88
88
|
kind: "Invoke",
|
|
89
89
|
handler: {
|
|
90
90
|
kind: "Builtin",
|
|
91
|
-
builtin: { kind: "
|
|
91
|
+
builtin: { kind: "GetIndex", value: 1 },
|
|
92
92
|
},
|
|
93
93
|
},
|
|
94
94
|
],
|
|
@@ -111,7 +111,7 @@ function readVar(n: number): Action {
|
|
|
111
111
|
* All(...bindings, Identity),
|
|
112
112
|
* ResumeHandle(r0, readVar(0),
|
|
113
113
|
* ResumeHandle(r1, readVar(1),
|
|
114
|
-
* Chain(
|
|
114
|
+
* Chain(GetIndex(N), body)
|
|
115
115
|
* )
|
|
116
116
|
* )
|
|
117
117
|
* )
|
|
@@ -148,7 +148,7 @@ export function bind<TBindings extends Action[], TOut>(
|
|
|
148
148
|
kind: "Invoke",
|
|
149
149
|
handler: {
|
|
150
150
|
kind: "Builtin",
|
|
151
|
-
builtin: { kind: "
|
|
151
|
+
builtin: { kind: "GetIndex", value: pipelineInputIndex },
|
|
152
152
|
},
|
|
153
153
|
},
|
|
154
154
|
rest: bodyAction,
|
package/src/builtins.ts
CHANGED
|
@@ -93,10 +93,10 @@ export function flatten<TElement>(): TypedAction<TElement[][], TElement[]> {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// ---------------------------------------------------------------------------
|
|
96
|
-
//
|
|
96
|
+
// GetField — extract a single field from an object
|
|
97
97
|
// ---------------------------------------------------------------------------
|
|
98
98
|
|
|
99
|
-
export function
|
|
99
|
+
export function getField<
|
|
100
100
|
TObj extends Record<string, unknown>,
|
|
101
101
|
TField extends keyof TObj & string,
|
|
102
102
|
>(field: TField): TypedAction<TObj, TObj[TField]> {
|
|
@@ -104,23 +104,23 @@ export function extractField<
|
|
|
104
104
|
kind: "Invoke",
|
|
105
105
|
handler: {
|
|
106
106
|
kind: "Builtin",
|
|
107
|
-
builtin: { kind: "
|
|
107
|
+
builtin: { kind: "GetField", value: field },
|
|
108
108
|
},
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// ---------------------------------------------------------------------------
|
|
113
|
-
//
|
|
113
|
+
// GetIndex — extract a single element from an array by index
|
|
114
114
|
// ---------------------------------------------------------------------------
|
|
115
115
|
|
|
116
|
-
export function
|
|
116
|
+
export function getIndex<TTuple extends unknown[], TIndex extends number>(
|
|
117
117
|
index: TIndex,
|
|
118
118
|
): TypedAction<TTuple, TTuple[TIndex]> {
|
|
119
119
|
return typedAction({
|
|
120
120
|
kind: "Invoke",
|
|
121
121
|
handler: {
|
|
122
122
|
kind: "Builtin",
|
|
123
|
-
builtin: { kind: "
|
|
123
|
+
builtin: { kind: "GetIndex", value: index },
|
|
124
124
|
},
|
|
125
125
|
});
|
|
126
126
|
}
|
|
@@ -216,25 +216,25 @@ export function withResource<
|
|
|
216
216
|
actions: [action as Action, identity as Action],
|
|
217
217
|
});
|
|
218
218
|
|
|
219
|
-
// Step 3: all(
|
|
219
|
+
// Step 3: all(getIndex(0), chain(getIndex(1), dispose)) → [TOut, unknown]
|
|
220
220
|
const disposeAndKeepResult = typedAction<
|
|
221
221
|
[TOut, TResource & TIn],
|
|
222
222
|
[TOut, unknown]
|
|
223
223
|
>({
|
|
224
224
|
kind: "All",
|
|
225
225
|
actions: [
|
|
226
|
-
|
|
226
|
+
getIndex<[TOut, TResource & TIn], 0>(0) as Action,
|
|
227
227
|
chain(
|
|
228
|
-
|
|
228
|
+
getIndex<[TOut, TResource & TIn], 1>(1),
|
|
229
229
|
dispose as Pipeable<TResource & TIn, unknown>,
|
|
230
230
|
) as Action,
|
|
231
231
|
],
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
-
// Step 4:
|
|
234
|
+
// Step 4: getIndex(0) → TOut
|
|
235
235
|
return chain(
|
|
236
236
|
chain(chain(acquireAndMerge, actionAndKeepMerged), disposeAndKeepResult),
|
|
237
|
-
|
|
237
|
+
getIndex<[TOut, unknown], 0>(0),
|
|
238
238
|
) as TypedAction<TIn, TOut>;
|
|
239
239
|
}
|
|
240
240
|
|
|
@@ -383,7 +383,7 @@ const EXTRACT_VALUE: Action = {
|
|
|
383
383
|
kind: "Invoke",
|
|
384
384
|
handler: {
|
|
385
385
|
kind: "Builtin",
|
|
386
|
-
builtin: { kind: "
|
|
386
|
+
builtin: { kind: "GetField", value: "value" },
|
|
387
387
|
},
|
|
388
388
|
};
|
|
389
389
|
const DROP: Action = {
|
|
@@ -395,7 +395,7 @@ const IDENTITY: Action = {
|
|
|
395
395
|
handler: { kind: "Builtin", builtin: { kind: "Identity" } },
|
|
396
396
|
};
|
|
397
397
|
|
|
398
|
-
/** Wrap branch cases with
|
|
398
|
+
/** Wrap branch cases with GetField("value") auto-unwrapping. */
|
|
399
399
|
function optionBranch(someCaseBody: Action, noneCaseBody: Action): Action {
|
|
400
400
|
return {
|
|
401
401
|
kind: "Branch",
|
|
@@ -590,7 +590,7 @@ const TAG_ERR: Action = {
|
|
|
590
590
|
handler: { kind: "Builtin", builtin: { kind: "Tag", value: "Err" } },
|
|
591
591
|
};
|
|
592
592
|
|
|
593
|
-
/** Wrap branch cases with
|
|
593
|
+
/** Wrap branch cases with GetField("value") auto-unwrapping. */
|
|
594
594
|
function resultBranch(okCaseBody: Action, errCaseBody: Action): Action {
|
|
595
595
|
return {
|
|
596
596
|
kind: "Branch",
|
package/src/index.ts
CHANGED
package/src/race.ts
CHANGED
|
@@ -53,7 +53,7 @@ function breakPerform(restartHandlerId: RestartHandlerId): Action {
|
|
|
53
53
|
*
|
|
54
54
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
55
55
|
* `Chain(Tag("Continue"),`
|
|
56
|
-
* `RestartHandle(id,
|
|
56
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
57
57
|
* `Branch({`
|
|
58
58
|
* `Continue: All(Chain(a, breakPerform), Chain(b, breakPerform), ...),`
|
|
59
59
|
* `Break: identity,`
|
package/src/recursive.ts
CHANGED
|
@@ -7,13 +7,7 @@ import {
|
|
|
7
7
|
} from "./ast.js";
|
|
8
8
|
import { all } from "./all.js";
|
|
9
9
|
import { chain } from "./chain.js";
|
|
10
|
-
import {
|
|
11
|
-
constant,
|
|
12
|
-
identity,
|
|
13
|
-
extractField,
|
|
14
|
-
extractIndex,
|
|
15
|
-
tag,
|
|
16
|
-
} from "./builtins.js";
|
|
10
|
+
import { constant, identity, getField, getIndex, tag } from "./builtins.js";
|
|
17
11
|
import { allocateResumeHandlerId } from "./effect-id.js";
|
|
18
12
|
|
|
19
13
|
// ---------------------------------------------------------------------------
|
|
@@ -84,11 +78,11 @@ export function defineRecursiveFunctions<TDefs extends FunctionDef[]>(
|
|
|
84
78
|
...(callTokens as FunctionRefs<TDefs>),
|
|
85
79
|
) as Action[];
|
|
86
80
|
|
|
87
|
-
// Branch cases: CallN →
|
|
81
|
+
// Branch cases: CallN → GetField("value") → bodyN
|
|
88
82
|
const cases: Record<string, Action> = {};
|
|
89
83
|
for (let i = 0; i < bodyActions.length; i++) {
|
|
90
84
|
cases[`Call${i}`] = chain(
|
|
91
|
-
|
|
85
|
+
getField("value"),
|
|
92
86
|
bodyActions[i] as any,
|
|
93
87
|
) as Action;
|
|
94
88
|
}
|
|
@@ -101,9 +95,9 @@ export function defineRecursiveFunctions<TDefs extends FunctionDef[]>(
|
|
|
101
95
|
chain(all(identity, constant(UNUSED_STATE)), {
|
|
102
96
|
kind: "ResumeHandle",
|
|
103
97
|
resume_handler_id: resumeHandlerId,
|
|
104
|
-
body: chain(
|
|
98
|
+
body: chain(getIndex(0), userBody as any) as Action,
|
|
105
99
|
handler: all(
|
|
106
|
-
chain(
|
|
100
|
+
chain(getIndex(0), branch(cases) as any),
|
|
107
101
|
constant(UNUSED_STATE),
|
|
108
102
|
) as Action,
|
|
109
103
|
} as Action) as Action,
|
package/src/try-catch.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { allocateRestartHandlerId } from "./effect-id.js";
|
|
|
25
25
|
*
|
|
26
26
|
* Compiled form (restart+Branch, same substrate as loop/earlyReturn):
|
|
27
27
|
* `Chain(Tag("Continue"),`
|
|
28
|
-
* `RestartHandle(id,
|
|
28
|
+
* `RestartHandle(id, GetIndex(0),`
|
|
29
29
|
* `Branch({ Continue: body, Break: recovery })))`
|
|
30
30
|
*
|
|
31
31
|
* throwError = `Chain(Tag("Break"), RestartPerform(id))`
|