@barnum/barnum 0.0.0-main-54c41bbb → 0.0.0-main-57736a4e
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 +1 -0
- package/dist/all.d.ts.map +1 -0
- package/dist/all.js +1 -1
- package/dist/ast.d.ts +148 -61
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +225 -42
- package/dist/bind.d.ts +7 -10
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +8 -8
- package/dist/builtins/array.d.ts +28 -0
- package/dist/builtins/array.d.ts.map +1 -0
- package/dist/builtins/array.js +74 -0
- package/dist/builtins/index.d.ts +6 -0
- package/dist/builtins/index.d.ts.map +1 -0
- package/dist/builtins/index.js +5 -0
- package/dist/builtins/scalar.d.ts +12 -0
- package/dist/builtins/scalar.d.ts.map +1 -0
- package/dist/builtins/scalar.js +41 -0
- package/dist/builtins/struct.d.ts +25 -0
- package/dist/builtins/struct.d.ts.map +1 -0
- package/dist/builtins/struct.js +67 -0
- package/dist/builtins/tagged-union.d.ts +54 -0
- package/dist/builtins/tagged-union.d.ts.map +1 -0
- package/dist/builtins/tagged-union.js +81 -0
- package/dist/builtins/with-resource.d.ts +23 -0
- package/dist/builtins/with-resource.d.ts.map +1 -0
- package/dist/builtins/with-resource.js +35 -0
- package/dist/chain.d.ts +1 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +3 -3
- package/dist/effect-id.d.ts +1 -0
- package/dist/effect-id.d.ts.map +1 -0
- package/dist/handler.d.ts +7 -6
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +3 -3
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -2
- package/dist/iterator.d.ts +18 -0
- package/dist/iterator.d.ts.map +1 -0
- package/dist/iterator.js +71 -0
- package/dist/option.d.ts +74 -0
- package/dist/option.d.ts.map +1 -0
- package/dist/option.js +141 -0
- package/dist/pipe.d.ts +2 -1
- package/dist/pipe.d.ts.map +1 -0
- package/dist/pipe.js +3 -2
- package/dist/race.d.ts +4 -3
- package/dist/race.d.ts.map +1 -0
- package/dist/race.js +10 -9
- package/dist/recursive.d.ts +9 -3
- package/dist/recursive.d.ts.map +1 -0
- package/dist/recursive.js +16 -10
- package/dist/result.d.ts +50 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +117 -0
- package/dist/run.d.ts +2 -1
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +9 -5
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +7 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schemas.d.ts +5 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +13 -0
- package/dist/try-catch.d.ts +1 -0
- package/dist/try-catch.d.ts.map +1 -0
- package/dist/try-catch.js +6 -6
- package/dist/values.d.ts +6 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +12 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.d.ts.map +1 -0
- package/package.json +7 -3
- package/src/all.ts +1 -1
- package/src/ast.ts +608 -132
- package/src/bind.ts +24 -23
- package/src/builtins/array.ts +96 -0
- package/src/builtins/index.ts +10 -0
- package/src/builtins/scalar.ts +49 -0
- package/src/builtins/struct.ts +111 -0
- package/src/builtins/tagged-union.ts +142 -0
- package/src/builtins/with-resource.ts +69 -0
- package/src/chain.ts +4 -4
- package/src/handler.ts +10 -13
- package/src/index.ts +18 -15
- package/src/iterator.ts +125 -0
- package/src/option.ts +199 -0
- package/src/pipe.ts +10 -4
- package/src/race.ts +32 -22
- package/src/recursive.ts +46 -22
- package/src/result.ts +168 -0
- package/src/run.ts +14 -6
- package/src/runtime.ts +16 -0
- package/src/schemas.ts +21 -0
- package/src/try-catch.ts +8 -9
- package/src/values.ts +21 -0
- package/dist/builtins.d.ts +0 -229
- package/dist/builtins.js +0 -486
- package/src/builtins.ts +0 -703
package/dist/ast.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { chain } from "./chain.js";
|
|
2
|
-
import { drop, flatten as flattenBuiltin, getField, getIndex, identity,
|
|
2
|
+
import { constant, drop, extractPrefix, flatten as flattenBuiltin, getField, getIndex, identity, panic, pick, splitFirst, splitLast, tag, wrapInField, asOption as asOptionStandalone, } from "./builtins/index.js";
|
|
3
|
+
import { Option } from "./option.js";
|
|
4
|
+
import { Result } from "./result.js";
|
|
5
|
+
// Lazy import — iterator.ts imports from ast.ts, but these are only called inside
|
|
6
|
+
// methods (after all modules load), so the circular reference is safe at runtime.
|
|
7
|
+
import { Iterator as IteratorNs } from "./iterator.js";
|
|
8
|
+
// Lazy import — bind.ts imports from ast.ts, but these are only called inside
|
|
9
|
+
// methods (after all modules load), so the circular reference is safe at runtime.
|
|
10
|
+
import { bind as bindStandalone, bindInput as bindInputStandalone, } from "./bind.js";
|
|
11
|
+
/**
|
|
12
|
+
* Strip phantom types from a Pipeable, returning a plain Action.
|
|
13
|
+
*
|
|
14
|
+
* Replaces `x as Action` casts throughout the codebase. The constraint
|
|
15
|
+
* ensures the argument is structurally a Pipeable — unlike a bare cast,
|
|
16
|
+
* `toAction(123)` is a type error.
|
|
17
|
+
*/
|
|
18
|
+
export function toAction(pipeable) {
|
|
19
|
+
return pipeable;
|
|
20
|
+
}
|
|
3
21
|
// ---------------------------------------------------------------------------
|
|
4
22
|
// typedAction — attach .then() and .forEach() as non-enumerable methods
|
|
5
23
|
// ---------------------------------------------------------------------------
|
|
@@ -7,50 +25,182 @@ import { drop, flatten as flattenBuiltin, getField, getIndex, identity, merge, O
|
|
|
7
25
|
function thenMethod(next) {
|
|
8
26
|
return chain(this, next);
|
|
9
27
|
}
|
|
10
|
-
function forEachMethod(action) {
|
|
11
|
-
return chain(this, forEach(action));
|
|
12
|
-
}
|
|
13
28
|
function branchMethod(cases) {
|
|
14
|
-
return chain(this, branch(cases));
|
|
29
|
+
return chain(toAction(this), toAction(branch(cases)));
|
|
15
30
|
}
|
|
16
31
|
function flattenMethod() {
|
|
17
|
-
return chain(this, flattenBuiltin());
|
|
32
|
+
return chain(toAction(this), toAction(flattenBuiltin()));
|
|
18
33
|
}
|
|
19
34
|
function dropMethod() {
|
|
20
|
-
return chain(this, drop);
|
|
35
|
+
return chain(toAction(this), toAction(drop));
|
|
21
36
|
}
|
|
22
|
-
function tagMethod(kind) {
|
|
23
|
-
return chain(this, tag(kind));
|
|
37
|
+
function tagMethod(kind, enumName) {
|
|
38
|
+
return chain(toAction(this), toAction(tag(kind, enumName)));
|
|
39
|
+
}
|
|
40
|
+
function someMethod() {
|
|
41
|
+
return chain(toAction(this), toAction(Option.some()));
|
|
42
|
+
}
|
|
43
|
+
function okMethod() {
|
|
44
|
+
return chain(toAction(this), toAction(Result.ok()));
|
|
45
|
+
}
|
|
46
|
+
function errMethod() {
|
|
47
|
+
return chain(toAction(this), toAction(Result.err()));
|
|
24
48
|
}
|
|
25
49
|
function getFieldMethod(field) {
|
|
26
|
-
return chain(this, getField(field));
|
|
50
|
+
return chain(toAction(this), toAction(getField(field)));
|
|
27
51
|
}
|
|
28
52
|
function getIndexMethod(index) {
|
|
29
|
-
return chain(this, getIndex(index));
|
|
53
|
+
return chain(toAction(this), toAction(getIndex(index)));
|
|
30
54
|
}
|
|
31
55
|
function wrapInFieldMethod(field) {
|
|
32
|
-
return chain(this, wrapInField(field));
|
|
33
|
-
}
|
|
34
|
-
function mergeMethod() {
|
|
35
|
-
return chain(this, merge());
|
|
56
|
+
return chain(toAction(this), toAction(wrapInField(field)));
|
|
36
57
|
}
|
|
37
58
|
function pickMethod(...keys) {
|
|
38
|
-
return chain(this, pick(...keys));
|
|
59
|
+
return chain(toAction(this), toAction(pick(...keys)));
|
|
39
60
|
}
|
|
40
61
|
function splitFirstMethod() {
|
|
41
|
-
return chain(this, splitFirst());
|
|
62
|
+
return chain(toAction(this), toAction(splitFirst()));
|
|
42
63
|
}
|
|
43
64
|
function splitLastMethod() {
|
|
44
|
-
return chain(this, splitLast());
|
|
65
|
+
return chain(toAction(this), toAction(splitLast()));
|
|
45
66
|
}
|
|
46
|
-
|
|
47
|
-
|
|
67
|
+
// --- Shared postfix methods (Option + Result) — dispatch via branchFamily ---
|
|
68
|
+
function mapMethod(action) {
|
|
69
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
70
|
+
Result: branch({
|
|
71
|
+
Ok: chain(toAction(action), toAction(Result.ok())),
|
|
72
|
+
Err: Result.err(),
|
|
73
|
+
}),
|
|
74
|
+
Option: branch({
|
|
75
|
+
Some: chain(toAction(action), toAction(Option.some())),
|
|
76
|
+
None: Option.none(),
|
|
77
|
+
}),
|
|
78
|
+
Iterator: IteratorNs.map(action),
|
|
79
|
+
})));
|
|
48
80
|
}
|
|
49
|
-
function
|
|
50
|
-
return chain(this,
|
|
81
|
+
function unwrapMethod() {
|
|
82
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
83
|
+
Result: branch({ Ok: identity(), Err: panic("called unwrap on Err") }),
|
|
84
|
+
Option: branch({
|
|
85
|
+
Some: identity(),
|
|
86
|
+
None: panic("called unwrap on None"),
|
|
87
|
+
}),
|
|
88
|
+
})));
|
|
51
89
|
}
|
|
52
90
|
function unwrapOrMethod(defaultAction) {
|
|
53
|
-
return chain(this,
|
|
91
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
92
|
+
Result: branch({ Ok: identity(), Err: defaultAction }),
|
|
93
|
+
Option: branch({ Some: identity(), None: defaultAction }),
|
|
94
|
+
})));
|
|
95
|
+
}
|
|
96
|
+
function andThenMethod(action) {
|
|
97
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
98
|
+
Result: branch({ Ok: action, Err: Result.err() }),
|
|
99
|
+
Option: branch({ Some: action, None: Option.none() }),
|
|
100
|
+
})));
|
|
101
|
+
}
|
|
102
|
+
function transposeMethod() {
|
|
103
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
104
|
+
Option: branch({
|
|
105
|
+
Some: branch({
|
|
106
|
+
Ok: chain(toAction(Option.some()), toAction(Result.ok())),
|
|
107
|
+
Err: Result.err(),
|
|
108
|
+
}),
|
|
109
|
+
None: chain(toAction(chain(toAction(drop), toAction(Option.none()))), toAction(Result.ok())),
|
|
110
|
+
}),
|
|
111
|
+
Result: branch({
|
|
112
|
+
Ok: branch({
|
|
113
|
+
Some: chain(toAction(Result.ok()), toAction(Option.some())),
|
|
114
|
+
None: chain(toAction(drop), toAction(Option.none())),
|
|
115
|
+
}),
|
|
116
|
+
Err: chain(toAction(Result.err()), toAction(Option.some())),
|
|
117
|
+
}),
|
|
118
|
+
})));
|
|
119
|
+
}
|
|
120
|
+
// --- Result-only postfix methods ---
|
|
121
|
+
function mapErrMethod(action) {
|
|
122
|
+
return chain(toAction(this), toAction(branch({
|
|
123
|
+
Ok: Result.ok(),
|
|
124
|
+
Err: chain(toAction(action), toAction(Result.err())),
|
|
125
|
+
})));
|
|
126
|
+
}
|
|
127
|
+
function orMethod(fallback) {
|
|
128
|
+
return chain(toAction(this), toAction(branch({
|
|
129
|
+
Ok: Result.ok(),
|
|
130
|
+
Err: fallback,
|
|
131
|
+
})));
|
|
132
|
+
}
|
|
133
|
+
function asOkOptionMethod() {
|
|
134
|
+
return chain(toAction(this), toAction(branch({
|
|
135
|
+
Ok: Option.some(),
|
|
136
|
+
Err: chain(toAction(drop), toAction(Option.none())),
|
|
137
|
+
})));
|
|
138
|
+
}
|
|
139
|
+
function asErrOptionMethod() {
|
|
140
|
+
return chain(toAction(this), toAction(branch({
|
|
141
|
+
Ok: chain(toAction(drop), toAction(Option.none())),
|
|
142
|
+
Err: Option.some(),
|
|
143
|
+
})));
|
|
144
|
+
}
|
|
145
|
+
function isOkMethod() {
|
|
146
|
+
return chain(toAction(this), toAction(branch({
|
|
147
|
+
Ok: constant(true),
|
|
148
|
+
Err: constant(false),
|
|
149
|
+
})));
|
|
150
|
+
}
|
|
151
|
+
function isErrMethod() {
|
|
152
|
+
return chain(toAction(this), toAction(branch({
|
|
153
|
+
Ok: constant(false),
|
|
154
|
+
Err: constant(true),
|
|
155
|
+
})));
|
|
156
|
+
}
|
|
157
|
+
// --- Option-only postfix methods ---
|
|
158
|
+
function filterMethod(predicate) {
|
|
159
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
160
|
+
Option: branch({
|
|
161
|
+
Some: predicate,
|
|
162
|
+
None: Option.none(),
|
|
163
|
+
}),
|
|
164
|
+
Iterator: IteratorNs.filter(predicate),
|
|
165
|
+
})));
|
|
166
|
+
}
|
|
167
|
+
function isSomeMethod() {
|
|
168
|
+
return chain(toAction(this), toAction(branch({
|
|
169
|
+
Some: constant(true),
|
|
170
|
+
None: constant(false),
|
|
171
|
+
})));
|
|
172
|
+
}
|
|
173
|
+
function isNoneMethod() {
|
|
174
|
+
return chain(toAction(this), toAction(branch({
|
|
175
|
+
Some: constant(false),
|
|
176
|
+
None: constant(true),
|
|
177
|
+
})));
|
|
178
|
+
}
|
|
179
|
+
function asOptionMethod() {
|
|
180
|
+
return chain(toAction(this), toAction(asOptionStandalone()));
|
|
181
|
+
}
|
|
182
|
+
// --- Iterator postfix methods ---
|
|
183
|
+
function iterateMethod() {
|
|
184
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
185
|
+
Option: IteratorNs.fromOption(),
|
|
186
|
+
Result: IteratorNs.fromResult(),
|
|
187
|
+
Array: IteratorNs.fromArray(),
|
|
188
|
+
})));
|
|
189
|
+
}
|
|
190
|
+
function flatMapMethod(action) {
|
|
191
|
+
return chain(toAction(this), toAction(IteratorNs.flatMap(action)));
|
|
192
|
+
}
|
|
193
|
+
function collectMethod() {
|
|
194
|
+
return chain(toAction(this), toAction(branchFamily({
|
|
195
|
+
Array: Option.collect(),
|
|
196
|
+
Iterator: IteratorNs.collect(),
|
|
197
|
+
})));
|
|
198
|
+
}
|
|
199
|
+
function bindMethod(bindings, body) {
|
|
200
|
+
return chain(toAction(this), toAction(bindStandalone(bindings, body)));
|
|
201
|
+
}
|
|
202
|
+
function bindInputMethod(body) {
|
|
203
|
+
return chain(toAction(this), toAction(bindInputStandalone(body)));
|
|
54
204
|
}
|
|
55
205
|
/**
|
|
56
206
|
* Attach `.then()` and `.forEach()` methods to a plain Action object.
|
|
@@ -60,21 +210,39 @@ export function typedAction(action) {
|
|
|
60
210
|
if (!("then" in action)) {
|
|
61
211
|
Object.defineProperties(action, {
|
|
62
212
|
then: { value: thenMethod, configurable: true },
|
|
63
|
-
forEach: { value: forEachMethod, configurable: true },
|
|
64
213
|
branch: { value: branchMethod, configurable: true },
|
|
65
214
|
flatten: { value: flattenMethod, configurable: true },
|
|
66
215
|
drop: { value: dropMethod, configurable: true },
|
|
67
216
|
tag: { value: tagMethod, configurable: true },
|
|
217
|
+
some: { value: someMethod, configurable: true },
|
|
218
|
+
ok: { value: okMethod, configurable: true },
|
|
219
|
+
err: { value: errMethod, configurable: true },
|
|
68
220
|
getField: { value: getFieldMethod, configurable: true },
|
|
69
221
|
getIndex: { value: getIndexMethod, configurable: true },
|
|
70
222
|
wrapInField: { value: wrapInFieldMethod, configurable: true },
|
|
71
|
-
merge: { value: mergeMethod, configurable: true },
|
|
72
223
|
pick: { value: pickMethod, configurable: true },
|
|
73
224
|
splitFirst: { value: splitFirstMethod, configurable: true },
|
|
74
225
|
splitLast: { value: splitLastMethod, configurable: true },
|
|
75
|
-
|
|
226
|
+
map: { value: mapMethod, configurable: true },
|
|
76
227
|
mapErr: { value: mapErrMethod, configurable: true },
|
|
228
|
+
unwrap: { value: unwrapMethod, configurable: true },
|
|
77
229
|
unwrapOr: { value: unwrapOrMethod, configurable: true },
|
|
230
|
+
andThen: { value: andThenMethod, configurable: true },
|
|
231
|
+
filter: { value: filterMethod, configurable: true },
|
|
232
|
+
isSome: { value: isSomeMethod, configurable: true },
|
|
233
|
+
isNone: { value: isNoneMethod, configurable: true },
|
|
234
|
+
asOption: { value: asOptionMethod, configurable: true },
|
|
235
|
+
collect: { value: collectMethod, configurable: true },
|
|
236
|
+
or: { value: orMethod, configurable: true },
|
|
237
|
+
iterate: { value: iterateMethod, configurable: true },
|
|
238
|
+
flatMap: { value: flatMapMethod, configurable: true },
|
|
239
|
+
asOkOption: { value: asOkOptionMethod, configurable: true },
|
|
240
|
+
asErrOption: { value: asErrOptionMethod, configurable: true },
|
|
241
|
+
isOk: { value: isOkMethod, configurable: true },
|
|
242
|
+
isErr: { value: isErrMethod, configurable: true },
|
|
243
|
+
transpose: { value: transposeMethod, configurable: true },
|
|
244
|
+
bind: { value: bindMethod, configurable: true },
|
|
245
|
+
bindInput: { value: bindInputMethod, configurable: true },
|
|
78
246
|
});
|
|
79
247
|
}
|
|
80
248
|
return action;
|
|
@@ -92,7 +260,7 @@ import { allocateRestartHandlerId, } from "./effect-id.js";
|
|
|
92
260
|
export { tryCatch } from "./try-catch.js";
|
|
93
261
|
export { race, sleep, withTimeout } from "./race.js";
|
|
94
262
|
export function forEach(action) {
|
|
95
|
-
return typedAction({ kind: "ForEach", action: action });
|
|
263
|
+
return typedAction({ kind: "ForEach", action: toAction(action) });
|
|
96
264
|
}
|
|
97
265
|
/**
|
|
98
266
|
* Insert GetField("value") before each case handler in a branch.
|
|
@@ -103,7 +271,7 @@ export function forEach(action) {
|
|
|
103
271
|
function unwrapBranchCases(cases) {
|
|
104
272
|
const unwrapped = {};
|
|
105
273
|
for (const key of Object.keys(cases)) {
|
|
106
|
-
unwrapped[key] = chain(getField("value"), cases[key]);
|
|
274
|
+
unwrapped[key] = toAction(chain(toAction(getField("value")), toAction(cases[key])));
|
|
107
275
|
}
|
|
108
276
|
return unwrapped;
|
|
109
277
|
}
|
|
@@ -111,6 +279,21 @@ function unwrapBranchCases(cases) {
|
|
|
111
279
|
export function branch(cases) {
|
|
112
280
|
return typedAction({ kind: "Branch", cases: unwrapBranchCases(cases) });
|
|
113
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Two-level dispatch: extract the enum prefix from a tagged value's `kind`,
|
|
284
|
+
* then branch on that prefix. Used by postfix methods (`.map()`, `.unwrapOr()`,
|
|
285
|
+
* etc.) to dispatch across union families (Option, Result) without runtime
|
|
286
|
+
* metadata.
|
|
287
|
+
*
|
|
288
|
+
* `branchFamily({ Result: ..., Option: ... })` ≡ `chain(extractPrefix(), branch(cases))`
|
|
289
|
+
*/
|
|
290
|
+
export function branchFamily(cases) {
|
|
291
|
+
return typedAction({
|
|
292
|
+
kind: "Chain",
|
|
293
|
+
first: toAction(extractPrefix()),
|
|
294
|
+
rest: toAction(branch(cases)),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
114
297
|
// ---------------------------------------------------------------------------
|
|
115
298
|
// recur — restart body primitive
|
|
116
299
|
// ---------------------------------------------------------------------------
|
|
@@ -129,12 +312,12 @@ export function recur(bodyFn) {
|
|
|
129
312
|
kind: "RestartPerform",
|
|
130
313
|
restart_handler_id: restartHandlerId,
|
|
131
314
|
});
|
|
132
|
-
const body = bodyFn(restartAction);
|
|
315
|
+
const body = toAction(bodyFn(restartAction));
|
|
133
316
|
return typedAction({
|
|
134
317
|
kind: "RestartHandle",
|
|
135
318
|
restart_handler_id: restartHandlerId,
|
|
136
319
|
body,
|
|
137
|
-
handler: getIndex(0),
|
|
320
|
+
handler: toAction(getIndex(0).unwrap()),
|
|
138
321
|
});
|
|
139
322
|
}
|
|
140
323
|
// ---------------------------------------------------------------------------
|
|
@@ -154,12 +337,12 @@ export function recur(bodyFn) {
|
|
|
154
337
|
*/
|
|
155
338
|
export function earlyReturn(bodyFn) {
|
|
156
339
|
const restartHandlerId = allocateRestartHandlerId();
|
|
157
|
-
const earlyReturnAction = typedAction(chain(tag("Break"), {
|
|
340
|
+
const earlyReturnAction = typedAction(toAction(chain(toAction(tag("Break", "LoopResult")), {
|
|
158
341
|
kind: "RestartPerform",
|
|
159
342
|
restart_handler_id: restartHandlerId,
|
|
160
|
-
}));
|
|
161
|
-
const body = bodyFn(earlyReturnAction);
|
|
162
|
-
return typedAction(buildRestartBranchAction(restartHandlerId, body, identity()));
|
|
343
|
+
})));
|
|
344
|
+
const body = toAction(bodyFn(earlyReturnAction));
|
|
345
|
+
return typedAction(buildRestartBranchAction(restartHandlerId, body, toAction(identity())));
|
|
163
346
|
}
|
|
164
347
|
// ---------------------------------------------------------------------------
|
|
165
348
|
// loop — iterative restart with break
|
|
@@ -174,12 +357,12 @@ export function earlyReturn(bodyFn) {
|
|
|
174
357
|
* Used by earlyReturn, loop, tryCatch, and race.
|
|
175
358
|
*/
|
|
176
359
|
export function buildRestartBranchAction(restartHandlerId, continueArm, breakArm) {
|
|
177
|
-
return chain(tag("Continue"), {
|
|
360
|
+
return toAction(chain(toAction(tag("Continue", "LoopResult")), {
|
|
178
361
|
kind: "RestartHandle",
|
|
179
362
|
restart_handler_id: restartHandlerId,
|
|
180
|
-
body: branch({ Continue: continueArm, Break: breakArm }),
|
|
181
|
-
handler: getIndex(0),
|
|
182
|
-
});
|
|
363
|
+
body: toAction(branch({ Continue: continueArm, Break: breakArm })),
|
|
364
|
+
handler: toAction(getIndex(0).unwrap()),
|
|
365
|
+
}));
|
|
183
366
|
}
|
|
184
367
|
/**
|
|
185
368
|
* Iterative loop. The body callback receives `recur` and `done`:
|
|
@@ -196,10 +379,10 @@ export function loop(bodyFn) {
|
|
|
196
379
|
kind: "RestartPerform",
|
|
197
380
|
restart_handler_id: restartHandlerId,
|
|
198
381
|
};
|
|
199
|
-
const recurAction = typedAction(chain(tag("Continue"), perform));
|
|
200
|
-
const doneAction = typedAction(chain(tag("Break"), perform));
|
|
201
|
-
const body = bodyFn(recurAction, doneAction);
|
|
202
|
-
return typedAction(buildRestartBranchAction(restartHandlerId, body, identity()));
|
|
382
|
+
const recurAction = typedAction(toAction(chain(toAction(tag("Continue", "LoopResult")), toAction(perform))));
|
|
383
|
+
const doneAction = typedAction(toAction(chain(toAction(tag("Break", "LoopResult")), toAction(perform))));
|
|
384
|
+
const body = toAction(bodyFn(recurAction, doneAction));
|
|
385
|
+
return typedAction(buildRestartBranchAction(restartHandlerId, body, toAction(identity())));
|
|
203
386
|
}
|
|
204
387
|
// ---------------------------------------------------------------------------
|
|
205
388
|
// Config builders
|
package/dist/bind.d.ts
CHANGED
|
@@ -6,17 +6,14 @@ import { type Action, type ExtractInput, type ExtractOutput, type TypedAction }
|
|
|
6
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
|
-
export type VarRef<TValue> = TypedAction<
|
|
9
|
+
export type VarRef<TValue> = TypedAction<any, TValue>;
|
|
10
10
|
/**
|
|
11
11
|
* Maps each binding's output type to a VarRef. TypeScript resolves
|
|
12
12
|
* ExtractOutput from each binding expression.
|
|
13
13
|
*
|
|
14
|
-
* Constraint is `Action[]` (not `Pipeable<any, any>[]`)
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* Action union. Using raw `Action[]` avoids the phantom field
|
|
18
|
-
* assignability issue while `ExtractOutput` still extracts the correct
|
|
19
|
-
* output type from the phantom fields on the concrete types.
|
|
14
|
+
* Constraint is `Action[]` (not `Pipeable<any, any>[]`) so that
|
|
15
|
+
* `ExtractOutput` extracts the correct output type from the phantom
|
|
16
|
+
* fields on the concrete types without fighting invariant `__in` checks.
|
|
20
17
|
*/
|
|
21
18
|
export type InferVarRefs<TBindings extends Action[]> = {
|
|
22
19
|
[K in keyof TBindings]: VarRef<ExtractOutput<TBindings[K]>>;
|
|
@@ -40,12 +37,11 @@ export type InferVarRefs<TBindings extends Action[]> = {
|
|
|
40
37
|
*/
|
|
41
38
|
/**
|
|
42
39
|
* Constraint for the body callback return type. Only requires the output
|
|
43
|
-
* phantom
|
|
44
|
-
*
|
|
40
|
+
* phantom field — omits `__in` and `__in_co` so that body actions with
|
|
41
|
+
* any input type (e.g. pipelines starting from a VarRef) are assignable.
|
|
45
42
|
*/
|
|
46
43
|
type BodyResult<TOut> = Action & {
|
|
47
44
|
__out?: () => TOut;
|
|
48
|
-
__out_contra?: (output: TOut) => void;
|
|
49
45
|
};
|
|
50
46
|
export declare function bind<TBindings extends Action[], TOut>(bindings: [...TBindings], body: (vars: InferVarRefs<TBindings>) => BodyResult<TOut>): TypedAction<ExtractInput<TBindings[number]>, TOut>;
|
|
51
47
|
/**
|
|
@@ -60,3 +56,4 @@ export declare function bind<TBindings extends Action[], TOut>(bindings: [...TBi
|
|
|
60
56
|
*/
|
|
61
57
|
export declare function bindInput<TIn, TOut = any>(body: (input: VarRef<TIn>) => BodyResult<TOut>): TypedAction<TIn, TOut>;
|
|
62
58
|
export {};
|
|
59
|
+
//# sourceMappingURL=bind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,WAAW,EAGjB,MAAM,UAAU,CAAC;AAWlB;;;;;;GAMG;AACH,MAAM,MAAM,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAetD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI;KACpD,CAAC,IAAI,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5D,CAAC;AA4BF;;;;;;;;;;;;;;;;GAgBG;AACH;;;;GAIG;AACH,KAAK,UAAU,CAAC,IAAI,IAAI,MAAM,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE,EAAE,IAAI,EACnD,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,EACxB,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,GACxD,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAkCpD;AAMD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,GAAG,GAAG,EACvC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,GAC7C,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAExB"}
|
package/dist/bind.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { typedAction, } from "./ast.js";
|
|
1
|
+
import { toAction, typedAction, } from "./ast.js";
|
|
2
2
|
import { chain } from "./chain.js";
|
|
3
3
|
import { all } from "./all.js";
|
|
4
|
-
import { identity, drop, getIndex } from "./builtins.js";
|
|
4
|
+
import { identity, drop, getIndex } from "./builtins/index.js";
|
|
5
5
|
import { allocateResumeHandlerId } from "./effect-id.js";
|
|
6
6
|
import { pipe } from "./pipe.js";
|
|
7
7
|
function createVarRef(resumeHandlerId) {
|
|
@@ -20,10 +20,10 @@ function createVarRef(resumeHandlerId) {
|
|
|
20
20
|
* `state` (index 1) is the full All output tuple. The handler produces
|
|
21
21
|
* `[state[n], state]` — value is state[n], new_state is state (unchanged).
|
|
22
22
|
*
|
|
23
|
-
* Expanded AST: All(Chain(GetIndex(1), GetIndex(n)), GetIndex(1))
|
|
23
|
+
* Expanded AST: All(Chain(GetIndex(1).unwrap(), GetIndex(n).unwrap()), GetIndex(1).unwrap())
|
|
24
24
|
*/
|
|
25
25
|
function readVar(n) {
|
|
26
|
-
return all(chain(getIndex(1), getIndex(n)), getIndex(1));
|
|
26
|
+
return toAction(all(chain(toAction(getIndex(1).unwrap()), toAction(getIndex(n).unwrap())), toAction(getIndex(1).unwrap())));
|
|
27
27
|
}
|
|
28
28
|
export function bind(bindings, body) {
|
|
29
29
|
// 1. Gensym one resumeHandlerId per binding.
|
|
@@ -31,11 +31,11 @@ export function bind(bindings, body) {
|
|
|
31
31
|
// 2. Create VarRefs (ResumePerform nodes) for each binding.
|
|
32
32
|
const varRefs = resumeHandlerIds.map((id) => createVarRef(id));
|
|
33
33
|
// 3. Invoke the body callback with the VarRefs.
|
|
34
|
-
const bodyAction = body(varRefs);
|
|
34
|
+
const bodyAction = toAction(body(varRefs));
|
|
35
35
|
// 4. Build nested Handles from inside out.
|
|
36
36
|
// Innermost: extract pipeline_input (last All element) → user body
|
|
37
37
|
const pipelineInputIndex = bindings.length;
|
|
38
|
-
let inner = chain(getIndex(pipelineInputIndex), bodyAction);
|
|
38
|
+
let inner = toAction(chain(toAction(getIndex(pipelineInputIndex).unwrap()), toAction(bodyAction)));
|
|
39
39
|
for (let i = resumeHandlerIds.length - 1; i >= 0; i--) {
|
|
40
40
|
inner = {
|
|
41
41
|
kind: "ResumeHandle",
|
|
@@ -47,9 +47,9 @@ export function bind(bindings, body) {
|
|
|
47
47
|
// 5. All(...bindings, identity()) → nested Handles
|
|
48
48
|
const allAction = {
|
|
49
49
|
kind: "All",
|
|
50
|
-
actions: [...bindings.map((b) => b), identity()],
|
|
50
|
+
actions: [...bindings.map((b) => toAction(b)), toAction(identity())],
|
|
51
51
|
};
|
|
52
|
-
return typedAction(chain(allAction, inner));
|
|
52
|
+
return typedAction(toAction(chain(toAction(allAction), toAction(inner))));
|
|
53
53
|
}
|
|
54
54
|
// ---------------------------------------------------------------------------
|
|
55
55
|
// bindInput — bind the pipeline input
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Option as OptionT, type TypedAction } from "../ast.js";
|
|
2
|
+
export declare function getIndex<TTuple extends unknown[], TIndex extends number>(index: TIndex): TypedAction<TTuple, OptionT<TTuple[TIndex]>>;
|
|
3
|
+
export declare function flatten<TElement>(): TypedAction<TElement[][], TElement[]>;
|
|
4
|
+
/**
|
|
5
|
+
* Deconstruct an array into its first element and the remaining elements.
|
|
6
|
+
* `TElement[] → Option<[TElement, TElement[]]>`
|
|
7
|
+
*
|
|
8
|
+
* Returns `Some([first, rest])` for non-empty arrays, `None` for empty arrays.
|
|
9
|
+
* This is the array equivalent of cons/uncons — enables recursive iteration
|
|
10
|
+
* patterns via `loop` + `splitFirst` + `branch`.
|
|
11
|
+
*
|
|
12
|
+
* This is a builtin (SplitFirst) because it requires array-length branching
|
|
13
|
+
* that can't be composed from existing AST nodes.
|
|
14
|
+
*/
|
|
15
|
+
export declare function splitFirst<TElement>(): TypedAction<TElement[], OptionT<[TElement, TElement[]]>>;
|
|
16
|
+
/**
|
|
17
|
+
* Deconstruct an array into the leading elements and the last element.
|
|
18
|
+
* `TElement[] → Option<[TElement[], TElement]>`
|
|
19
|
+
*
|
|
20
|
+
* Returns `Some([init, last])` for non-empty arrays, `None` for empty arrays.
|
|
21
|
+
* Mirror of `splitFirst` — enables processing from the tail end.
|
|
22
|
+
*
|
|
23
|
+
* This is a builtin (SplitLast) because it requires array-length branching
|
|
24
|
+
* that can't be composed from existing AST nodes.
|
|
25
|
+
*/
|
|
26
|
+
export declare function splitLast<TElement>(): TypedAction<TElement[], OptionT<[TElement[], TElement]>>;
|
|
27
|
+
export declare function range(start: number, end: number): TypedAction<any, number[]>;
|
|
28
|
+
//# sourceMappingURL=array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/builtins/array.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,IAAI,OAAO,EACtB,KAAK,WAAW,EAEjB,MAAM,WAAW,CAAC;AAMnB,wBAAgB,QAAQ,CAAC,MAAM,SAAS,OAAO,EAAE,EAAE,MAAM,SAAS,MAAM,EACtE,KAAK,EAAE,MAAM,GACZ,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAQ9C;AAMD,wBAAgB,OAAO,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAKzE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,QAAQ,KAAK,WAAW,CACjD,QAAQ,EAAE,EACV,OAAO,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAChC,CAKA;AAMD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,QAAQ,KAAK,WAAW,CAChD,QAAQ,EAAE,EACV,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC,CAChC,CAKA;AAMD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAS5E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { typedAction, } from "../ast.js";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// GetIndex — extract a single element from an array by index
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
export function getIndex(index) {
|
|
6
|
+
return typedAction({
|
|
7
|
+
kind: "Invoke",
|
|
8
|
+
handler: {
|
|
9
|
+
kind: "Builtin",
|
|
10
|
+
builtin: { kind: "GetIndex", index },
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Flatten — flatten a nested array one level
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export function flatten() {
|
|
18
|
+
return typedAction({
|
|
19
|
+
kind: "Invoke",
|
|
20
|
+
handler: { kind: "Builtin", builtin: { kind: "Flatten" } },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// SplitFirst — head/tail decomposition of an array
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Deconstruct an array into its first element and the remaining elements.
|
|
28
|
+
* `TElement[] → Option<[TElement, TElement[]]>`
|
|
29
|
+
*
|
|
30
|
+
* Returns `Some([first, rest])` for non-empty arrays, `None` for empty arrays.
|
|
31
|
+
* This is the array equivalent of cons/uncons — enables recursive iteration
|
|
32
|
+
* patterns via `loop` + `splitFirst` + `branch`.
|
|
33
|
+
*
|
|
34
|
+
* This is a builtin (SplitFirst) because it requires array-length branching
|
|
35
|
+
* that can't be composed from existing AST nodes.
|
|
36
|
+
*/
|
|
37
|
+
export function splitFirst() {
|
|
38
|
+
return typedAction({
|
|
39
|
+
kind: "Invoke",
|
|
40
|
+
handler: { kind: "Builtin", builtin: { kind: "SplitFirst" } },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// SplitLast — init/last decomposition of an array
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Deconstruct an array into the leading elements and the last element.
|
|
48
|
+
* `TElement[] → Option<[TElement[], TElement]>`
|
|
49
|
+
*
|
|
50
|
+
* Returns `Some([init, last])` for non-empty arrays, `None` for empty arrays.
|
|
51
|
+
* Mirror of `splitFirst` — enables processing from the tail end.
|
|
52
|
+
*
|
|
53
|
+
* This is a builtin (SplitLast) because it requires array-length branching
|
|
54
|
+
* that can't be composed from existing AST nodes.
|
|
55
|
+
*/
|
|
56
|
+
export function splitLast() {
|
|
57
|
+
return typedAction({
|
|
58
|
+
kind: "Invoke",
|
|
59
|
+
handler: { kind: "Builtin", builtin: { kind: "SplitLast" } },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Range — produce an integer array [start, start+1, ..., end-1]
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
export function range(start, end) {
|
|
66
|
+
const result = [];
|
|
67
|
+
for (let i = start; i < end; i++) {
|
|
68
|
+
result.push(i);
|
|
69
|
+
}
|
|
70
|
+
return typedAction({
|
|
71
|
+
kind: "Invoke",
|
|
72
|
+
handler: { kind: "Builtin", builtin: { kind: "Constant", value: result } },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { constant, identity, drop, panic } from "./scalar.js";
|
|
2
|
+
export { getField, wrapInField, merge, pick, allObject } from "./struct.js";
|
|
3
|
+
export { getIndex, flatten, splitFirst, splitLast, range } from "./array.js";
|
|
4
|
+
export { tag, extractPrefix, asOption, taggedUnionSchema, } from "./tagged-union.js";
|
|
5
|
+
export { withResource } from "./with-resource.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builtins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EACL,GAAG,EACH,aAAa,EACb,QAAQ,EACR,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { constant, identity, drop, panic } from "./scalar.js";
|
|
2
|
+
export { getField, wrapInField, merge, pick, allObject } from "./struct.js";
|
|
3
|
+
export { getIndex, flatten, splitFirst, splitLast, range } from "./array.js";
|
|
4
|
+
export { tag, extractPrefix, asOption, taggedUnionSchema, } from "./tagged-union.js";
|
|
5
|
+
export { withResource } from "./with-resource.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type TypedAction } from "../ast.js";
|
|
2
|
+
export declare function constant<TValue>(value: TValue): TypedAction<any, TValue>;
|
|
3
|
+
export declare function identity<TValue = any>(): TypedAction<TValue, TValue>;
|
|
4
|
+
export declare const drop: TypedAction<any, void>;
|
|
5
|
+
/**
|
|
6
|
+
* Halt execution with a fatal error. Not caught by tryCatch.
|
|
7
|
+
* Analogous to Rust's `panic!`.
|
|
8
|
+
*
|
|
9
|
+
* Output type is `never` — a panic never produces a value.
|
|
10
|
+
*/
|
|
11
|
+
export declare function panic(message: string): TypedAction<any, never>;
|
|
12
|
+
//# sourceMappingURL=scalar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalar.d.ts","sourceRoot":"","sources":["../../src/builtins/scalar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,WAAW,CAAC;AAM1D,wBAAgB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAKxE;AAMD,wBAAgB,QAAQ,CAAC,MAAM,GAAG,GAAG,KAAK,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAKpE;AAMD,eAAO,MAAM,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,IAAI,CAGtC,CAAC;AAMH;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAK9D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { typedAction } from "../ast.js";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Constant — produce a fixed value (takes no pipeline input)
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
export function constant(value) {
|
|
6
|
+
return typedAction({
|
|
7
|
+
kind: "Invoke",
|
|
8
|
+
handler: { kind: "Builtin", builtin: { kind: "Constant", value } },
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Identity — pass input through unchanged
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export function identity() {
|
|
15
|
+
return typedAction({
|
|
16
|
+
kind: "Invoke",
|
|
17
|
+
handler: { kind: "Builtin", builtin: { kind: "Identity" } },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Drop — discard pipeline value
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
export const drop = typedAction({
|
|
24
|
+
kind: "Invoke",
|
|
25
|
+
handler: { kind: "Builtin", builtin: { kind: "Drop" } },
|
|
26
|
+
});
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Panic — halt execution with an error message
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Halt execution with a fatal error. Not caught by tryCatch.
|
|
32
|
+
* Analogous to Rust's `panic!`.
|
|
33
|
+
*
|
|
34
|
+
* Output type is `never` — a panic never produces a value.
|
|
35
|
+
*/
|
|
36
|
+
export function panic(message) {
|
|
37
|
+
return typedAction({
|
|
38
|
+
kind: "Invoke",
|
|
39
|
+
handler: { kind: "Builtin", builtin: { kind: "Panic", message } },
|
|
40
|
+
});
|
|
41
|
+
}
|