@barnum/barnum 0.3.0 → 0.4.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/dist/all.d.ts +41 -10
- package/dist/all.d.ts.map +1 -0
- package/dist/all.js +1 -1
- package/dist/ast.d.ts +199 -98
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +271 -233
- package/dist/bind.d.ts +9 -12
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +14 -51
- package/dist/builtins/array.d.ts +36 -0
- package/dist/builtins/array.d.ts.map +1 -0
- package/dist/builtins/array.js +93 -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 +5 -21
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -2
- package/dist/iterator.d.ts +32 -0
- package/dist/iterator.d.ts.map +1 -0
- package/dist/iterator.js +123 -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 +11 -10
- package/dist/pipe.d.ts.map +1 -0
- package/dist/pipe.js +5 -4
- package/dist/race.d.ts +5 -4
- package/dist/race.d.ts.map +1 -0
- package/dist/race.js +17 -42
- package/dist/recursive.d.ts +9 -3
- package/dist/recursive.d.ts.map +1 -0
- package/dist/recursive.js +18 -13
- 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 +9 -2
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +37 -20
- 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 +2 -1
- package/dist/try-catch.d.ts.map +1 -0
- package/dist/try-catch.js +10 -9
- 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 +5 -1
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +15 -3
- package/package.json +8 -6
- package/src/all.ts +118 -74
- package/src/ast.ts +773 -350
- package/src/bind.ts +32 -62
- package/src/builtins/array.ts +121 -0
- package/src/builtins/index.ts +17 -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 +12 -28
- package/src/index.ts +24 -17
- package/src/iterator.ts +243 -0
- package/src/option.ts +199 -0
- package/src/pipe.ts +123 -78
- package/src/race.ts +41 -51
- package/src/recursive.ts +44 -27
- package/src/result.ts +168 -0
- package/src/run.ts +53 -25
- package/src/runtime.ts +16 -0
- package/src/schemas.ts +21 -0
- package/src/try-catch.ts +14 -10
- package/src/values.ts +21 -0
- package/src/worker.ts +17 -2
- package/dist/builtins.d.ts +0 -257
- package/dist/builtins.js +0 -600
- package/src/builtins.ts +0 -804
package/dist/bind.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { typedAction, } from "./ast.js";
|
|
2
|
-
import {
|
|
1
|
+
import { toAction, typedAction, } from "./ast.js";
|
|
2
|
+
import { chain } from "./chain.js";
|
|
3
|
+
import { all } from "./all.js";
|
|
4
|
+
import { identity, drop, getIndex } from "./builtins/index.js";
|
|
3
5
|
import { allocateResumeHandlerId } from "./effect-id.js";
|
|
4
6
|
import { pipe } from "./pipe.js";
|
|
5
7
|
function createVarRef(resumeHandlerId) {
|
|
@@ -18,38 +20,10 @@ function createVarRef(resumeHandlerId) {
|
|
|
18
20
|
* `state` (index 1) is the full All output tuple. The handler produces
|
|
19
21
|
* `[state[n], state]` — value is state[n], new_state is state (unchanged).
|
|
20
22
|
*
|
|
21
|
-
* Expanded AST: All(Chain(
|
|
23
|
+
* Expanded AST: All(Chain(GetIndex(1).unwrap(), GetIndex(n).unwrap()), GetIndex(1).unwrap())
|
|
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: "ExtractIndex", value: 1 },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
rest: {
|
|
37
|
-
kind: "Invoke",
|
|
38
|
-
handler: {
|
|
39
|
-
kind: "Builtin",
|
|
40
|
-
builtin: { kind: "ExtractIndex", value: n },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
kind: "Invoke",
|
|
46
|
-
handler: {
|
|
47
|
-
kind: "Builtin",
|
|
48
|
-
builtin: { kind: "ExtractIndex", value: 1 },
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
};
|
|
26
|
+
return toAction(all(chain(toAction(getIndex(1).unwrap()), toAction(getIndex(n).unwrap())), toAction(getIndex(1).unwrap())));
|
|
53
27
|
}
|
|
54
28
|
export function bind(bindings, body) {
|
|
55
29
|
// 1. Gensym one resumeHandlerId per binding.
|
|
@@ -57,21 +31,11 @@ export function bind(bindings, body) {
|
|
|
57
31
|
// 2. Create VarRefs (ResumePerform nodes) for each binding.
|
|
58
32
|
const varRefs = resumeHandlerIds.map((id) => createVarRef(id));
|
|
59
33
|
// 3. Invoke the body callback with the VarRefs.
|
|
60
|
-
const bodyAction = body(varRefs);
|
|
34
|
+
const bodyAction = toAction(body(varRefs));
|
|
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: "ExtractIndex", value: pipelineInputIndex },
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
rest: bodyAction,
|
|
74
|
-
};
|
|
38
|
+
let inner = toAction(chain(toAction(getIndex(pipelineInputIndex).unwrap()), toAction(bodyAction)));
|
|
75
39
|
for (let i = resumeHandlerIds.length - 1; i >= 0; i--) {
|
|
76
40
|
inner = {
|
|
77
41
|
kind: "ResumeHandle",
|
|
@@ -81,12 +45,11 @@ export function bind(bindings, body) {
|
|
|
81
45
|
};
|
|
82
46
|
}
|
|
83
47
|
// 5. All(...bindings, identity()) → nested Handles
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
48
|
+
const allAction = {
|
|
49
|
+
kind: "All",
|
|
50
|
+
actions: [...bindings.map((b) => toAction(b)), toAction(identity())],
|
|
51
|
+
};
|
|
52
|
+
return typedAction(toAction(chain(toAction(allAction), toAction(inner))));
|
|
90
53
|
}
|
|
91
54
|
// ---------------------------------------------------------------------------
|
|
92
55
|
// bindInput — bind the pipeline input
|
|
@@ -102,5 +65,5 @@ export function bind(bindings, body) {
|
|
|
102
65
|
* bindInput<FileEntry>((entry) => ...)
|
|
103
66
|
*/
|
|
104
67
|
export function bindInput(body) {
|
|
105
|
-
return bind([identity], ([input]) => pipe(drop, body(input)));
|
|
68
|
+
return bind([identity()], ([input]) => pipe(drop, body(input)));
|
|
106
69
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
/**
|
|
28
|
+
* Slice an array from `start` (inclusive) to `end` (exclusive).
|
|
29
|
+
* `T[] → T[]`
|
|
30
|
+
*
|
|
31
|
+
* Both indices are clamped to array length. If `end` is omitted, slices
|
|
32
|
+
* to the end of the array. Returns empty array if `start >= end`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function slice<TElement>(start: number, end?: number): TypedAction<TElement[], TElement[]>;
|
|
35
|
+
export declare function range(start: number, end: number): TypedAction<any, number[]>;
|
|
36
|
+
//# 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;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAC5B,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,GACX,WAAW,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CASrC;AAMD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAS5E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
// Slice — extract a sub-array from start to end
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* Slice an array from `start` (inclusive) to `end` (exclusive).
|
|
67
|
+
* `T[] → T[]`
|
|
68
|
+
*
|
|
69
|
+
* Both indices are clamped to array length. If `end` is omitted, slices
|
|
70
|
+
* to the end of the array. Returns empty array if `start >= end`.
|
|
71
|
+
*/
|
|
72
|
+
export function slice(start, end) {
|
|
73
|
+
const builtin = end === undefined
|
|
74
|
+
? { kind: "Slice", start }
|
|
75
|
+
: { kind: "Slice", start, end };
|
|
76
|
+
return typedAction({
|
|
77
|
+
kind: "Invoke",
|
|
78
|
+
handler: { kind: "Builtin", builtin },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Range — produce an integer array [start, start+1, ..., end-1]
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
export function range(start, end) {
|
|
85
|
+
const result = [];
|
|
86
|
+
for (let i = start; i < end; i++) {
|
|
87
|
+
result.push(i);
|
|
88
|
+
}
|
|
89
|
+
return typedAction({
|
|
90
|
+
kind: "Invoke",
|
|
91
|
+
handler: { kind: "Builtin", builtin: { kind: "Constant", value: result } },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
@@ -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, slice, 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,EACL,QAAQ,EACR,OAAO,EACP,UAAU,EACV,SAAS,EACT,KAAK,EACL,KAAK,GACN,MAAM,YAAY,CAAC;AACpB,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, slice, 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
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ExtractOutput, type MergeTuple, type Pipeable, type TypedAction } from "../ast.js";
|
|
2
|
+
export declare function getField<TObj extends Record<string, unknown>, TField extends keyof TObj & string>(field: TField): TypedAction<TObj, TObj[TField]>;
|
|
3
|
+
export declare function wrapInField<TField extends string, TValue>(field: TField): TypedAction<TValue, Record<TField, TValue>>;
|
|
4
|
+
export declare function merge<TTuple extends Record<string, unknown>[]>(): TypedAction<TTuple, MergeTuple<TTuple>>;
|
|
5
|
+
export declare function pick<TObj extends Record<string, unknown>, TKeys extends (keyof TObj & string)[]>(...keys: TKeys): TypedAction<TObj, Pick<TObj, TKeys[number]>>;
|
|
6
|
+
/**
|
|
7
|
+
* Run named actions concurrently on the same input, collecting results
|
|
8
|
+
* into an object with matching keys.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* allObject({
|
|
12
|
+
* files: listFiles,
|
|
13
|
+
* config: loadConfig,
|
|
14
|
+
* })
|
|
15
|
+
* // TIn → { files: string[], config: Config }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Each action receives the pipeline input. Results are wrapped in
|
|
19
|
+
* `{ key: value }` via `wrapInField`, run concurrently via `All`,
|
|
20
|
+
* then merged into a single object.
|
|
21
|
+
*/
|
|
22
|
+
export declare function allObject<TActions extends Record<string, Pipeable<any, any>>>(actions: TActions): TypedAction<any, {
|
|
23
|
+
[K in keyof TActions & string]: ExtractOutput<TActions[K]>;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=struct.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"struct.d.ts","sourceRoot":"","sources":["../../src/builtins/struct.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAGjB,MAAM,WAAW,CAAC;AAOnB,wBAAgB,QAAQ,CACtB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,MAAM,SAAS,MAAM,IAAI,GAAG,MAAM,EAClC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAQhD;AAMD,wBAAgB,WAAW,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EACvD,KAAK,EAAE,MAAM,GACZ,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQ7C;AAMD,wBAAgB,KAAK,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,WAAW,CAC5E,MAAM,EACN,UAAU,CAAC,MAAM,CAAC,CACnB,CAKA;AAMD,wBAAgB,IAAI,CAClB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,KAAK,SAAS,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,EACrC,GAAG,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAS9D;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAC3E,OAAO,EAAE,QAAQ,GAChB,WAAW,CACZ,GAAG,EACH;KAAG,CAAC,IAAI,MAAM,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CAAE,CAC/D,CASA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { toAction, typedAction, } from "../ast.js";
|
|
2
|
+
import { chain } from "../chain.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// GetField — extract a single field from an object
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export function getField(field) {
|
|
7
|
+
return typedAction({
|
|
8
|
+
kind: "Invoke",
|
|
9
|
+
handler: {
|
|
10
|
+
kind: "Builtin",
|
|
11
|
+
builtin: { kind: "GetField", field },
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// WrapInField — wrap input as { <field>: <input> }
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export function wrapInField(field) {
|
|
19
|
+
return typedAction({
|
|
20
|
+
kind: "Invoke",
|
|
21
|
+
handler: {
|
|
22
|
+
kind: "Builtin",
|
|
23
|
+
builtin: { kind: "WrapInField", field },
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Merge — merge a tuple of objects into a single object
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
export function merge() {
|
|
31
|
+
return typedAction({
|
|
32
|
+
kind: "Invoke",
|
|
33
|
+
handler: { kind: "Builtin", builtin: { kind: "Merge" } },
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Pick — select named fields from an object
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
export function pick(...keys) {
|
|
40
|
+
const actions = keys.map((key) => toAction(chain(toAction(getField(key)), toAction(wrapInField(key)))));
|
|
41
|
+
const allAction = { kind: "All", actions };
|
|
42
|
+
return chain(toAction(allAction), toAction(merge()));
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// AllObject — run named actions concurrently, collect into an object
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Run named actions concurrently on the same input, collecting results
|
|
49
|
+
* into an object with matching keys.
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* allObject({
|
|
53
|
+
* files: listFiles,
|
|
54
|
+
* config: loadConfig,
|
|
55
|
+
* })
|
|
56
|
+
* // TIn → { files: string[], config: Config }
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* Each action receives the pipeline input. Results are wrapped in
|
|
60
|
+
* `{ key: value }` via `wrapInField`, run concurrently via `All`,
|
|
61
|
+
* then merged into a single object.
|
|
62
|
+
*/
|
|
63
|
+
export function allObject(actions) {
|
|
64
|
+
const wrapped = Object.entries(actions).map(([key, action]) => toAction(chain(action, wrapInField(key))));
|
|
65
|
+
const allAction = { kind: "All", actions: wrapped };
|
|
66
|
+
return chain(toAction(allAction), toAction(merge()));
|
|
67
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Option, type TaggedUnion, type TypedAction } from "../ast.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* Wrap input as a tagged union member. Requires the full variant map TDef
|
|
5
|
+
* so the output type carries __def for branch decomposition.
|
|
6
|
+
*
|
|
7
|
+
* Usage: tag<{ Ok: string; Err: number }, "Ok">("Ok")
|
|
8
|
+
* input: string → output: TaggedUnion<{ Ok: string; Err: number }>
|
|
9
|
+
*/
|
|
10
|
+
export declare function tag<TEnumName extends string, TDef extends Record<string, unknown>, TKind extends keyof TDef & string>(kind: TKind, enumName: TEnumName): TypedAction<TDef[TKind], TaggedUnion<TEnumName, TDef>>;
|
|
11
|
+
/**
|
|
12
|
+
* Extract the enum prefix from a tagged value's `kind` field.
|
|
13
|
+
*
|
|
14
|
+
* Input: `{ kind: "Result.Ok", value: 42 }`
|
|
15
|
+
* Output: `{ kind: "Result", value: { kind: "Result.Ok", value: 42 } }`
|
|
16
|
+
*
|
|
17
|
+
* If `kind` contains no `'.'`, the entire kind string becomes the prefix.
|
|
18
|
+
* Used internally by `branchFamily` for two-level dispatch.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractPrefix(): TypedAction;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a boolean to `Option<void>`.
|
|
23
|
+
*
|
|
24
|
+
* `true` → `{ kind: "Option.Some", value: null }`
|
|
25
|
+
* `false` → `{ kind: "Option.None", value: null }`
|
|
26
|
+
*/
|
|
27
|
+
export declare function asOption(): TypedAction<boolean, Option<void>>;
|
|
28
|
+
/**
|
|
29
|
+
* Reverse of VoidToNull: maps `null` back to `void` in the def so that
|
|
30
|
+
* `taggedUnionSchema({ Clean: z.null() })` produces the same phantom __def
|
|
31
|
+
* as `TaggedUnion<{ Clean: void }>`.
|
|
32
|
+
*/
|
|
33
|
+
type NullToVoid<TDef> = {
|
|
34
|
+
[K in keyof TDef]: TDef[K] extends null ? void : TDef[K];
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Build a Zod schema for a `TaggedUnion<TEnumName, TDef>` — a discriminated
|
|
38
|
+
* union of `{ kind: "EnumName.Variant"; value: V }` objects.
|
|
39
|
+
*
|
|
40
|
+
* Each key in `cases` becomes a variant with a namespaced kind string.
|
|
41
|
+
* Use `z.null()` for void variants.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* const schema = taggedUnionSchema("ClassifyResult", {
|
|
45
|
+
* HasErrors: z.array(TypeErrorValidator),
|
|
46
|
+
* Clean: z.null(),
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function taggedUnionSchema<TEnumName extends string, TDef extends Record<string, z.ZodTypeAny>>(enumName: TEnumName, cases: TDef): z.ZodType<TaggedUnion<TEnumName, NullToVoid<{
|
|
51
|
+
[K in keyof TDef & string]: z.infer<TDef[K]>;
|
|
52
|
+
}>>>;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=tagged-union.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tagged-union.d.ts","sourceRoot":"","sources":["../../src/builtins/tagged-union.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,EAGjB,MAAM,WAAW,CAAC;AAKnB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;;GAMG;AACH,wBAAgB,GAAG,CACjB,SAAS,SAAS,MAAM,EACxB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,KAAK,SAAS,MAAM,IAAI,GAAG,MAAM,EAEjC,IAAI,EAAE,KAAK,EACX,QAAQ,EAAE,SAAS,GAClB,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAcxD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,WAAW,CAK3C;AAMD;;;;;GAKG;AACH,wBAAgB,QAAQ,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAK7D;AAMD;;;;GAIG;AACH,KAAK,UAAU,CAAC,IAAI,IAAI;KACrB,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,SAAS,MAAM,EACxB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,EAEzC,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,IAAI,GACV,CAAC,CAAC,OAAO,CACV,WAAW,CACT,SAAS,EACT,UAAU,CAAC;KAAG,CAAC,IAAI,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,CAC7D,CACF,CAmBA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { toAction, typedAction, } from "../ast.js";
|
|
2
|
+
import { chain } from "../chain.js";
|
|
3
|
+
import { all } from "../all.js";
|
|
4
|
+
import { constant } from "./scalar.js";
|
|
5
|
+
import { wrapInField, merge } from "./struct.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Tag — wrap input as a tagged union variant
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Wrap input as a tagged union member. Requires the full variant map TDef
|
|
12
|
+
* so the output type carries __def for branch decomposition.
|
|
13
|
+
*
|
|
14
|
+
* Usage: tag<{ Ok: string; Err: number }, "Ok">("Ok")
|
|
15
|
+
* input: string → output: TaggedUnion<{ Ok: string; Err: number }>
|
|
16
|
+
*/
|
|
17
|
+
export function tag(kind, enumName) {
|
|
18
|
+
const namespacedKind = `${enumName}.${kind}`;
|
|
19
|
+
return chain(toAction(all(chain(toAction(constant(namespacedKind)), toAction(wrapInField("kind"))), wrapInField("value"))), toAction(merge()));
|
|
20
|
+
}
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// ExtractPrefix — extract enum prefix from tagged value kind
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Extract the enum prefix from a tagged value's `kind` field.
|
|
26
|
+
*
|
|
27
|
+
* Input: `{ kind: "Result.Ok", value: 42 }`
|
|
28
|
+
* Output: `{ kind: "Result", value: { kind: "Result.Ok", value: 42 } }`
|
|
29
|
+
*
|
|
30
|
+
* If `kind` contains no `'.'`, the entire kind string becomes the prefix.
|
|
31
|
+
* Used internally by `branchFamily` for two-level dispatch.
|
|
32
|
+
*/
|
|
33
|
+
export function extractPrefix() {
|
|
34
|
+
return typedAction({
|
|
35
|
+
kind: "Invoke",
|
|
36
|
+
handler: { kind: "Builtin", builtin: { kind: "ExtractPrefix" } },
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// AsOption — convert boolean to Option<void>
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Convert a boolean to `Option<void>`.
|
|
44
|
+
*
|
|
45
|
+
* `true` → `{ kind: "Option.Some", value: null }`
|
|
46
|
+
* `false` → `{ kind: "Option.None", value: null }`
|
|
47
|
+
*/
|
|
48
|
+
export function asOption() {
|
|
49
|
+
return typedAction({
|
|
50
|
+
kind: "Invoke",
|
|
51
|
+
handler: { kind: "Builtin", builtin: { kind: "AsOption" } },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a Zod schema for a `TaggedUnion<TEnumName, TDef>` — a discriminated
|
|
56
|
+
* union of `{ kind: "EnumName.Variant"; value: V }` objects.
|
|
57
|
+
*
|
|
58
|
+
* Each key in `cases` becomes a variant with a namespaced kind string.
|
|
59
|
+
* Use `z.null()` for void variants.
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* const schema = taggedUnionSchema("ClassifyResult", {
|
|
63
|
+
* HasErrors: z.array(TypeErrorValidator),
|
|
64
|
+
* Clean: z.null(),
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function taggedUnionSchema(enumName, cases) {
|
|
69
|
+
const variants = Object.entries(cases).map(([kind, valueSchema]) => z.object({ kind: z.literal(`${enumName}.${kind}`), value: valueSchema }));
|
|
70
|
+
if (variants.length === 0) {
|
|
71
|
+
return z.never();
|
|
72
|
+
}
|
|
73
|
+
if (variants.length === 1) {
|
|
74
|
+
return variants[0];
|
|
75
|
+
}
|
|
76
|
+
return z.discriminatedUnion("kind", [
|
|
77
|
+
variants[0],
|
|
78
|
+
variants[1],
|
|
79
|
+
...variants.slice(2),
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Pipeable, type TypedAction } from "../ast.js";
|
|
2
|
+
/**
|
|
3
|
+
* RAII-style resource management combinator.
|
|
4
|
+
*
|
|
5
|
+
* Runs `create` to acquire a resource, then merges the resource with the
|
|
6
|
+
* original input into a flat object (`TResource & TIn`) for the action.
|
|
7
|
+
* After the action completes, `dispose` receives the resource for cleanup.
|
|
8
|
+
* The overall combinator returns the action's output.
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* TIn → create → TResource
|
|
12
|
+
* → merge(TResource, TIn) → TResource & TIn
|
|
13
|
+
* → action(TResource & TIn) → TOut
|
|
14
|
+
* → dispose(TResource) → (discarded)
|
|
15
|
+
* → TOut
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function withResource<TIn extends Record<string, unknown>, TResource extends Record<string, unknown>, TOut, TDisposeOut = unknown>({ create, action, dispose, }: {
|
|
19
|
+
create: Pipeable<TIn, TResource>;
|
|
20
|
+
action: Pipeable<TResource & TIn, TOut>;
|
|
21
|
+
dispose: Pipeable<TResource, TDisposeOut>;
|
|
22
|
+
}): TypedAction<TIn, TOut>;
|
|
23
|
+
//# sourceMappingURL=with-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-resource.d.ts","sourceRoot":"","sources":["../../src/builtins/with-resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAY,MAAM,WAAW,CAAC;AAWtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzC,IAAI,EACJ,WAAW,GAAG,OAAO,EACrB,EACA,MAAM,EACN,MAAM,EACN,OAAO,GACR,EAAE;IACD,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjC,MAAM,EAAE,QAAQ,CAAC,SAAS,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;IACxC,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;CAC3C,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CA4BzB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { toAction } from "../ast.js";
|
|
2
|
+
import { chain } from "../chain.js";
|
|
3
|
+
import { all } from "../all.js";
|
|
4
|
+
import { identity } from "./scalar.js";
|
|
5
|
+
import { merge } from "./struct.js";
|
|
6
|
+
import { getIndex } from "./array.js";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// WithResource — RAII-style create/action/dispose
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* RAII-style resource management combinator.
|
|
12
|
+
*
|
|
13
|
+
* Runs `create` to acquire a resource, then merges the resource with the
|
|
14
|
+
* original input into a flat object (`TResource & TIn`) for the action.
|
|
15
|
+
* After the action completes, `dispose` receives the resource for cleanup.
|
|
16
|
+
* The overall combinator returns the action's output.
|
|
17
|
+
*
|
|
18
|
+
* ```
|
|
19
|
+
* TIn → create → TResource
|
|
20
|
+
* → merge(TResource, TIn) → TResource & TIn
|
|
21
|
+
* → action(TResource & TIn) → TOut
|
|
22
|
+
* → dispose(TResource) → (discarded)
|
|
23
|
+
* → TOut
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function withResource({ create, action, dispose, }) {
|
|
27
|
+
// Step 1: all(create, identity) → [TResource, TIn] → merge → TResource & TIn
|
|
28
|
+
const acquireAndMerge = chain(toAction(all(create, identity())), toAction(merge()));
|
|
29
|
+
// Step 2: all(action, identity) → [TOut, TResource & TIn]
|
|
30
|
+
const actionAndKeepMerged = all(toAction(action), toAction(identity()));
|
|
31
|
+
// Step 3: all(getIndex(0).unwrap(), chain(getIndex(1).unwrap(), dispose)) → [TOut, unknown]
|
|
32
|
+
const disposeAndKeepResult = all(toAction(getIndex(0).unwrap()), chain(toAction(getIndex(1).unwrap()), toAction(dispose)));
|
|
33
|
+
// Step 4: getIndex(0).unwrap() → TOut
|
|
34
|
+
return chain(toAction(chain(toAction(chain(toAction(acquireAndMerge), toAction(actionAndKeepMerged))), toAction(disposeAndKeepResult))), toAction(getIndex(0).unwrap()));
|
|
35
|
+
}
|
package/dist/chain.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,WAAW,EAGjB,MAAM,UAAU,CAAC;AAElB,wBAAgB,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,EACvB,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,GACrB,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAMrB"}
|
package/dist/chain.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { typedAction, } from "./ast.js";
|
|
1
|
+
import { toAction, typedAction, } from "./ast.js";
|
|
2
2
|
export function chain(first, rest) {
|
|
3
3
|
return typedAction({
|
|
4
4
|
kind: "Chain",
|
|
5
|
-
first: first,
|
|
6
|
-
rest: rest,
|
|
5
|
+
first: toAction(first),
|
|
6
|
+
rest: toAction(rest),
|
|
7
7
|
});
|
|
8
8
|
}
|
package/dist/effect-id.d.ts
CHANGED
|
@@ -12,3 +12,4 @@ export declare function allocateResumeHandlerId(): ResumeHandlerId;
|
|
|
12
12
|
export declare function allocateRestartHandlerId(): RestartHandlerId;
|
|
13
13
|
/** Reset the ID counter. For test isolation only. */
|
|
14
14
|
export declare function resetEffectIdCounter(): void;
|
|
15
|
+
//# sourceMappingURL=effect-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-id.d.ts","sourceRoot":"","sources":["../src/effect-id.ts"],"names":[],"mappings":"AAIA,mDAAmD;AACnD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IACrC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,MAAM,CAAC;CAC9C,CAAC;AAEF,oDAAoD;AACpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IACtC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,MAAM,CAAC;CAC/C,CAAC;AAIF,kDAAkD;AAClD,wBAAgB,uBAAuB,IAAI,eAAe,CAEzD;AAED,mDAAmD;AACnD,wBAAgB,wBAAwB,IAAI,gBAAgB,CAE3D;AAED,qDAAqD;AACrD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|