@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.
Files changed (109) hide show
  1. package/artifacts/linux-arm64/barnum +0 -0
  2. package/artifacts/linux-x64/barnum +0 -0
  3. package/artifacts/macos-arm64/barnum +0 -0
  4. package/artifacts/macos-x64/barnum +0 -0
  5. package/artifacts/win-x64/barnum.exe +0 -0
  6. package/dist/all.d.ts +41 -10
  7. package/dist/all.d.ts.map +1 -0
  8. package/dist/all.js +1 -1
  9. package/dist/ast.d.ts +199 -98
  10. package/dist/ast.d.ts.map +1 -0
  11. package/dist/ast.js +271 -233
  12. package/dist/bind.d.ts +9 -12
  13. package/dist/bind.d.ts.map +1 -0
  14. package/dist/bind.js +14 -51
  15. package/dist/builtins/array.d.ts +36 -0
  16. package/dist/builtins/array.d.ts.map +1 -0
  17. package/dist/builtins/array.js +93 -0
  18. package/dist/builtins/index.d.ts +6 -0
  19. package/dist/builtins/index.d.ts.map +1 -0
  20. package/dist/builtins/index.js +5 -0
  21. package/dist/builtins/scalar.d.ts +12 -0
  22. package/dist/builtins/scalar.d.ts.map +1 -0
  23. package/dist/builtins/scalar.js +41 -0
  24. package/dist/builtins/struct.d.ts +25 -0
  25. package/dist/builtins/struct.d.ts.map +1 -0
  26. package/dist/builtins/struct.js +67 -0
  27. package/dist/builtins/tagged-union.d.ts +54 -0
  28. package/dist/builtins/tagged-union.d.ts.map +1 -0
  29. package/dist/builtins/tagged-union.js +81 -0
  30. package/dist/builtins/with-resource.d.ts +23 -0
  31. package/dist/builtins/with-resource.d.ts.map +1 -0
  32. package/dist/builtins/with-resource.js +35 -0
  33. package/dist/chain.d.ts +1 -0
  34. package/dist/chain.d.ts.map +1 -0
  35. package/dist/chain.js +3 -3
  36. package/dist/effect-id.d.ts +1 -0
  37. package/dist/effect-id.d.ts.map +1 -0
  38. package/dist/handler.d.ts +7 -6
  39. package/dist/handler.d.ts.map +1 -0
  40. package/dist/handler.js +5 -21
  41. package/dist/index.d.ts +10 -6
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +4 -2
  44. package/dist/iterator.d.ts +32 -0
  45. package/dist/iterator.d.ts.map +1 -0
  46. package/dist/iterator.js +123 -0
  47. package/dist/option.d.ts +74 -0
  48. package/dist/option.d.ts.map +1 -0
  49. package/dist/option.js +141 -0
  50. package/dist/pipe.d.ts +11 -10
  51. package/dist/pipe.d.ts.map +1 -0
  52. package/dist/pipe.js +5 -4
  53. package/dist/race.d.ts +5 -4
  54. package/dist/race.d.ts.map +1 -0
  55. package/dist/race.js +17 -42
  56. package/dist/recursive.d.ts +9 -3
  57. package/dist/recursive.d.ts.map +1 -0
  58. package/dist/recursive.js +18 -13
  59. package/dist/result.d.ts +50 -0
  60. package/dist/result.d.ts.map +1 -0
  61. package/dist/result.js +117 -0
  62. package/dist/run.d.ts +9 -2
  63. package/dist/run.d.ts.map +1 -0
  64. package/dist/run.js +37 -20
  65. package/dist/runtime.d.ts +6 -0
  66. package/dist/runtime.d.ts.map +1 -0
  67. package/dist/runtime.js +7 -0
  68. package/dist/schema.d.ts +1 -0
  69. package/dist/schema.d.ts.map +1 -0
  70. package/dist/schemas.d.ts +5 -0
  71. package/dist/schemas.d.ts.map +1 -0
  72. package/dist/schemas.js +13 -0
  73. package/dist/try-catch.d.ts +2 -1
  74. package/dist/try-catch.d.ts.map +1 -0
  75. package/dist/try-catch.js +10 -9
  76. package/dist/values.d.ts +6 -0
  77. package/dist/values.d.ts.map +1 -0
  78. package/dist/values.js +12 -0
  79. package/dist/worker.d.ts +5 -1
  80. package/dist/worker.d.ts.map +1 -0
  81. package/dist/worker.js +15 -3
  82. package/package.json +8 -6
  83. package/src/all.ts +118 -74
  84. package/src/ast.ts +773 -350
  85. package/src/bind.ts +32 -62
  86. package/src/builtins/array.ts +121 -0
  87. package/src/builtins/index.ts +17 -0
  88. package/src/builtins/scalar.ts +49 -0
  89. package/src/builtins/struct.ts +111 -0
  90. package/src/builtins/tagged-union.ts +142 -0
  91. package/src/builtins/with-resource.ts +69 -0
  92. package/src/chain.ts +4 -4
  93. package/src/handler.ts +12 -28
  94. package/src/index.ts +24 -17
  95. package/src/iterator.ts +243 -0
  96. package/src/option.ts +199 -0
  97. package/src/pipe.ts +123 -78
  98. package/src/race.ts +41 -51
  99. package/src/recursive.ts +44 -27
  100. package/src/result.ts +168 -0
  101. package/src/run.ts +53 -25
  102. package/src/runtime.ts +16 -0
  103. package/src/schemas.ts +21 -0
  104. package/src/try-catch.ts +14 -10
  105. package/src/values.ts +21 -0
  106. package/src/worker.ts +17 -2
  107. package/dist/builtins.d.ts +0 -257
  108. package/dist/builtins.js +0 -600
  109. package/src/builtins.ts +0 -804
package/dist/bind.js CHANGED
@@ -1,5 +1,7 @@
1
- import { typedAction, } from "./ast.js";
2
- import { identity, drop } from "./builtins.js";
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(ExtractIndex(1), ExtractIndex(n)), ExtractIndex(1))
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 allActions = [...bindings.map((b) => b), identity];
85
- return typedAction({
86
- kind: "Chain",
87
- first: { kind: "All", actions: allActions },
88
- rest: inner,
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
@@ -1,2 +1,3 @@
1
1
  import { type Pipeable, type TypedAction } from "./ast.js";
2
2
  export declare function chain<T1, T2, T3>(first: Pipeable<T1, T2>, rest: Pipeable<T2, T3>): TypedAction<T1, T3>;
3
+ //# sourceMappingURL=chain.d.ts.map
@@ -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
  }
@@ -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"}