@barnum/barnum 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/cli.cjs +33 -0
- package/dist/all.d.ts +12 -0
- package/dist/all.js +8 -0
- package/dist/ast.d.ts +375 -0
- package/dist/ast.js +381 -0
- package/dist/bind.d.ts +62 -0
- package/dist/bind.js +106 -0
- package/dist/builtins.d.ts +257 -0
- package/dist/builtins.js +600 -0
- package/dist/chain.d.ts +2 -0
- package/dist/chain.js +8 -0
- package/dist/effect-id.d.ts +14 -0
- package/dist/effect-id.js +16 -0
- package/dist/handler.d.ts +50 -0
- package/dist/handler.js +146 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +5 -0
- package/dist/pipe.d.ts +11 -0
- package/dist/pipe.js +11 -0
- package/dist/race.d.ts +53 -0
- package/dist/race.js +141 -0
- package/dist/recursive.d.ts +34 -0
- package/dist/recursive.js +53 -0
- package/dist/run.d.ts +7 -0
- package/dist/run.js +143 -0
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +95 -0
- package/dist/try-catch.d.ts +23 -0
- package/dist/try-catch.js +36 -0
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +46 -0
- package/package.json +40 -16
- package/src/all.ts +89 -0
- package/src/ast.ts +878 -0
- package/src/bind.ts +192 -0
- package/src/builtins.ts +804 -0
- package/src/chain.ts +17 -0
- package/src/effect-id.ts +30 -0
- package/src/handler.ts +279 -0
- package/src/index.ts +30 -0
- package/src/pipe.ts +93 -0
- package/src/race.ts +183 -0
- package/src/recursive.ts +112 -0
- package/src/run.ts +181 -0
- package/src/schema.ts +118 -0
- package/src/try-catch.ts +53 -0
- package/src/worker.ts +56 -0
- package/README.md +0 -19
- package/barnum-config-schema.json +0 -408
- package/cli.js +0 -20
- package/index.js +0 -23
package/src/bind.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Action,
|
|
3
|
+
type ExtractInput,
|
|
4
|
+
type ExtractOutput,
|
|
5
|
+
type TypedAction,
|
|
6
|
+
typedAction,
|
|
7
|
+
} from "./ast.js";
|
|
8
|
+
import { identity, drop } from "./builtins.js";
|
|
9
|
+
import { allocateResumeHandlerId, type ResumeHandlerId } from "./effect-id.js";
|
|
10
|
+
import { pipe } from "./pipe.js";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// VarRef — typed reference to a bound value
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A typed reference to a bound value. Output is `TValue`.
|
|
18
|
+
*
|
|
19
|
+
* Use `.then()` (not `pipe()`) when chaining a VarRef into a generic
|
|
20
|
+
* action like `pick` or `extractField` — pipe overloads can't infer
|
|
21
|
+
* the generic's type parameter from the VarRef's output.
|
|
22
|
+
*/
|
|
23
|
+
export type VarRef<TValue> = TypedAction<never, TValue>;
|
|
24
|
+
|
|
25
|
+
function createVarRef<TValue>(
|
|
26
|
+
resumeHandlerId: ResumeHandlerId,
|
|
27
|
+
): VarRef<TValue> {
|
|
28
|
+
return typedAction({
|
|
29
|
+
kind: "ResumePerform",
|
|
30
|
+
resume_handler_id: resumeHandlerId,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// InferVarRefs — map bindings to VarRef types
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Maps each binding's output type to a VarRef. TypeScript resolves
|
|
40
|
+
* ExtractOutput from each binding expression.
|
|
41
|
+
*
|
|
42
|
+
* Constraint is `Action[]` (not `Pipeable<any, any>[]`) because
|
|
43
|
+
* `TypedAction<never, X>` (e.g. from `constant()`) fails the invariant
|
|
44
|
+
* `__in` check against `Pipeable<any, any>` on the 9-variant
|
|
45
|
+
* Action union. Using raw `Action[]` avoids the phantom field
|
|
46
|
+
* assignability issue while `ExtractOutput` still extracts the correct
|
|
47
|
+
* output type from the phantom fields on the concrete types.
|
|
48
|
+
*/
|
|
49
|
+
export type InferVarRefs<TBindings extends Action[]> = {
|
|
50
|
+
[K in keyof TBindings]: VarRef<ExtractOutput<TBindings[K]>>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// readVar — handler DAG for the nth binding
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Returns an action that extracts the nth value from the ResumeHandle's
|
|
59
|
+
* state tuple and passes state through unchanged. When a ResumePerform
|
|
60
|
+
* fires, the engine calls the handler with `[payload, state]`. For bind,
|
|
61
|
+
* `state` (index 1) is the full All output tuple. The handler produces
|
|
62
|
+
* `[state[n], state]` — value is state[n], new_state is state (unchanged).
|
|
63
|
+
*
|
|
64
|
+
* Expanded AST: All(Chain(ExtractIndex(1), ExtractIndex(n)), ExtractIndex(1))
|
|
65
|
+
*/
|
|
66
|
+
function readVar(n: number): Action {
|
|
67
|
+
return {
|
|
68
|
+
kind: "All",
|
|
69
|
+
actions: [
|
|
70
|
+
{
|
|
71
|
+
kind: "Chain",
|
|
72
|
+
first: {
|
|
73
|
+
kind: "Invoke",
|
|
74
|
+
handler: {
|
|
75
|
+
kind: "Builtin",
|
|
76
|
+
builtin: { kind: "ExtractIndex", value: 1 },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
rest: {
|
|
80
|
+
kind: "Invoke",
|
|
81
|
+
handler: {
|
|
82
|
+
kind: "Builtin",
|
|
83
|
+
builtin: { kind: "ExtractIndex", value: n },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
kind: "Invoke",
|
|
89
|
+
handler: {
|
|
90
|
+
kind: "Builtin",
|
|
91
|
+
builtin: { kind: "ExtractIndex", value: 1 },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// bind — the user-facing function
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Bind concurrent values as VarRefs available throughout the body.
|
|
104
|
+
*
|
|
105
|
+
* All bindings are actions (Pipeable) evaluated concurrently with the
|
|
106
|
+
* pipeline input. The body callback receives an array of VarRefs,
|
|
107
|
+
* one per binding.
|
|
108
|
+
*
|
|
109
|
+
* Compiles to:
|
|
110
|
+
* Chain(
|
|
111
|
+
* All(...bindings, Identity),
|
|
112
|
+
* ResumeHandle(r0, readVar(0),
|
|
113
|
+
* ResumeHandle(r1, readVar(1),
|
|
114
|
+
* Chain(ExtractIndex(N), body)
|
|
115
|
+
* )
|
|
116
|
+
* )
|
|
117
|
+
* )
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* Constraint for the body callback return type. Only requires the output
|
|
121
|
+
* phantom fields — omits `__in` and `__in_co` so that body actions with
|
|
122
|
+
* `In = never` (e.g. pipelines starting from a VarRef) are assignable.
|
|
123
|
+
*/
|
|
124
|
+
type BodyResult<TOut> = Action & {
|
|
125
|
+
__out?: () => TOut;
|
|
126
|
+
__out_contra?: (output: TOut) => void;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export function bind<TBindings extends Action[], TOut>(
|
|
130
|
+
bindings: [...TBindings],
|
|
131
|
+
body: (vars: InferVarRefs<TBindings>) => BodyResult<TOut>,
|
|
132
|
+
): TypedAction<ExtractInput<TBindings[number]>, TOut> {
|
|
133
|
+
// 1. Gensym one resumeHandlerId per binding.
|
|
134
|
+
const resumeHandlerIds = bindings.map(() => allocateResumeHandlerId());
|
|
135
|
+
|
|
136
|
+
// 2. Create VarRefs (ResumePerform nodes) for each binding.
|
|
137
|
+
const varRefs = resumeHandlerIds.map((id) => createVarRef(id));
|
|
138
|
+
|
|
139
|
+
// 3. Invoke the body callback with the VarRefs.
|
|
140
|
+
const bodyAction = body(varRefs as InferVarRefs<TBindings>) as Action;
|
|
141
|
+
|
|
142
|
+
// 4. Build nested Handles from inside out.
|
|
143
|
+
// Innermost: extract pipeline_input (last All element) → user body
|
|
144
|
+
const pipelineInputIndex = bindings.length;
|
|
145
|
+
let inner: Action = {
|
|
146
|
+
kind: "Chain",
|
|
147
|
+
first: {
|
|
148
|
+
kind: "Invoke",
|
|
149
|
+
handler: {
|
|
150
|
+
kind: "Builtin",
|
|
151
|
+
builtin: { kind: "ExtractIndex", value: pipelineInputIndex },
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
rest: bodyAction,
|
|
155
|
+
};
|
|
156
|
+
for (let i = resumeHandlerIds.length - 1; i >= 0; i--) {
|
|
157
|
+
inner = {
|
|
158
|
+
kind: "ResumeHandle",
|
|
159
|
+
resume_handler_id: resumeHandlerIds[i],
|
|
160
|
+
handler: readVar(i),
|
|
161
|
+
body: inner,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 5. All(...bindings, identity()) → nested Handles
|
|
166
|
+
const allActions = [...bindings.map((b) => b as Action), identity as Action];
|
|
167
|
+
return typedAction({
|
|
168
|
+
kind: "Chain",
|
|
169
|
+
first: { kind: "All", actions: allActions },
|
|
170
|
+
rest: inner,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// bindInput — bind the pipeline input
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Convenience wrapper for the common pattern of capturing the pipeline
|
|
180
|
+
* input as a VarRef. The body's pipeline input is `never` — the input
|
|
181
|
+
* is dropped, so the body must access it through the VarRef.
|
|
182
|
+
*
|
|
183
|
+
* Sugar for: `bind([identity()], ([input]) => pipe(drop, body(input)))`
|
|
184
|
+
*
|
|
185
|
+
* TOut defaults to `any` so callers can specify just TIn:
|
|
186
|
+
* bindInput<FileEntry>((entry) => ...)
|
|
187
|
+
*/
|
|
188
|
+
export function bindInput<TIn, TOut = any>(
|
|
189
|
+
body: (input: VarRef<TIn>) => BodyResult<TOut>,
|
|
190
|
+
): TypedAction<TIn, TOut> {
|
|
191
|
+
return bind([identity], ([input]) => pipe(drop, body(input)));
|
|
192
|
+
}
|