@procedures/client 0.25.0 → 0.26.1

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 (48) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +10 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/browser.d.ts +2 -2
  5. package/dist/browser.d.ts.map +1 -1
  6. package/dist/browser.js +2 -0
  7. package/dist/browser.js.map +1 -1
  8. package/dist/client/client.d.ts +7 -1
  9. package/dist/client/client.d.ts.map +1 -1
  10. package/dist/client/client.js +30 -19
  11. package/dist/client/client.js.map +1 -1
  12. package/dist/procedures/core/index.d.ts +7 -7
  13. package/dist/procedures/core/index.d.ts.map +1 -1
  14. package/dist/procedures/core/index.js +53 -178
  15. package/dist/procedures/core/index.js.map +1 -1
  16. package/dist/procedures/core/operands.d.ts +12 -13
  17. package/dist/procedures/core/operands.d.ts.map +1 -1
  18. package/dist/procedures/core/operands.js +22 -38
  19. package/dist/procedures/core/operands.js.map +1 -1
  20. package/dist/procedures/define-procedure.d.ts.map +1 -1
  21. package/dist/procedures/define-procedure.js +6 -6
  22. package/dist/procedures/define-procedure.js.map +1 -1
  23. package/dist/procedures/envelope.d.ts +20 -11
  24. package/dist/procedures/envelope.d.ts.map +1 -1
  25. package/dist/procedures/envelope.js +51 -20
  26. package/dist/procedures/envelope.js.map +1 -1
  27. package/dist/procedures/index.d.ts +3 -1
  28. package/dist/procedures/index.d.ts.map +1 -1
  29. package/dist/procedures/index.js +3 -1
  30. package/dist/procedures/index.js.map +1 -1
  31. package/dist/procedures/program.d.ts +251 -0
  32. package/dist/procedures/program.d.ts.map +1 -0
  33. package/dist/procedures/program.js +1120 -0
  34. package/dist/procedures/program.js.map +1 -0
  35. package/dist/procedures/ref.d.ts +7 -94
  36. package/dist/procedures/ref.d.ts.map +1 -1
  37. package/dist/procedures/ref.js +16 -279
  38. package/dist/procedures/ref.js.map +1 -1
  39. package/package.json +3 -1
  40. package/src/browser.ts +23 -0
  41. package/src/client/client.ts +35 -23
  42. package/src/procedures/core/index.ts +56 -216
  43. package/src/procedures/core/operands.ts +24 -44
  44. package/src/procedures/define-procedure.ts +5 -7
  45. package/src/procedures/envelope.ts +60 -24
  46. package/src/procedures/index.ts +34 -4
  47. package/src/procedures/program.ts +1371 -0
  48. package/src/procedures/ref.ts +19 -357
@@ -7,25 +7,22 @@ import type { ProcedureContext, ProcedurePath } from "../types.js";
7
7
  import { PROCEDURE_REGISTRY } from "../registry.js";
8
8
  import {
9
9
  isAnyProcedureRef,
10
- getRefWhen,
11
- WHEN_NEVER,
12
- normalizeRef,
13
- hydrateInput,
14
- createRefScope,
15
10
  isOutputRef,
16
11
  lookupOutputRef,
17
12
  rawInputRule,
18
- withScope,
13
+ scopeOf,
19
14
  RUNS_REFS_TAG,
20
15
  type AnyProcedureRef,
21
16
  type RefScope,
22
17
  } from "../ref.js";
18
+ import { hydrateInput, runControl, runOperand } from "../program.js";
23
19
 
24
20
  /**
25
- * The operands of a control-flow procedure arrive raw: the procedure runs them itself, with the
26
- * same rules as `exec()` (one interpreter, `hydrateInput`). The input of a control-flow procedure
27
- * carries the scope of its caller (`withScope`), so an operand can read the names of an outer
28
- * chain, `map` or `reduce` (deep dive CORE-13).
21
+ * The operands of a control-flow procedure arrive raw: the procedure runs them itself. Its logic
22
+ * is a runner of the coeval kernel (`program.ts`): the handler gives its input to the kernel as a
23
+ * document of its kind. The input of a control-flow procedure carries the scope of its caller
24
+ * (`withScope`), so an operand can read the names of an outer chain, `map` or `reduce` (deep dive
25
+ * CORE-13).
29
26
  */
30
27
 
31
28
  /** The raw-input rule of the caller's registry: the procedure at a path decides (deep dive CORE-5). */
@@ -33,6 +30,19 @@ export function rawRule(ctx: ProcedureContext): (path: ProcedurePath) => boolean
33
30
  return rawInputRule(ctx.registry ?? PROCEDURE_REGISTRY);
34
31
  }
35
32
 
33
+ /** The call function of a context, as the executor of a run. */
34
+ function executorOf(ctx: ProcedureContext): <TIn, TOut>(path: ProcedurePath, input: TIn) => Promise<TOut> {
35
+ return <TIn, TOut>(path: ProcedurePath, input: TIn): Promise<TOut> => ctx.client.call<TIn, TOut>(path, input);
36
+ }
37
+
38
+ /**
39
+ * This function runs a control-flow procedure on the kernel: the runner of its kind runs the
40
+ * operands of the input, in the scope of the caller.
41
+ */
42
+ export function runControlFlow(name: string, input: unknown, ctx: ProcedureContext): Promise<unknown> {
43
+ return runControl(name, input, { executor: executorOf(ctx), rawInput: rawRule(ctx), onRef: ctx.onRef, scope: scopeOf(input) });
44
+ }
45
+
36
46
  /**
37
47
  * Without a client, a control-flow procedure cannot run refs. This function gives a value with
38
48
  * its known `$ref` values resolved. A name that the scope does not have stays as it is.
@@ -59,38 +69,23 @@ export function substituteRefs(value: unknown, scope: RefScope): unknown {
59
69
  * in `scope` and runs its nested refs, as `exec()` does for an input.
60
70
  */
61
71
  export async function hydrateOperand(value: unknown, ctx: ProcedureContext, scope?: RefScope): Promise<unknown> {
62
- return hydrateInput(value, (path, input) => ctx.client.call(path, input), { scope, rawInput: rawRule(ctx), onRef: ctx.onRef });
72
+ return hydrateInput(value, executorOf(ctx), { scope, rawInput: rawRule(ctx), onRef: ctx.onRef });
63
73
  }
64
74
 
65
75
  /**
66
- * This function runs an operand ref of a control-flow procedure.
76
+ * This function runs an operand ref of a control-flow procedure (`runOperand()`).
67
77
  *
68
78
  * It resolves the `$ref` values of the ref's input in `scope`, runs the nested refs of the
69
79
  * input and adds `extra` (the parent context, for example `cwd`). Then it calls the procedure.
70
80
  * A procedure that takes its input raw (control flow) gets the input unchanged, with the scope:
71
- * that procedure runs its own operands.
81
+ * that procedure runs its own operands. A `$never` operand is data with its full input.
72
82
  */
73
83
  export async function callOperand(
74
84
  ref: AnyProcedureRef,
75
85
  ctx: ProcedureContext,
76
86
  options: { scope?: RefScope | undefined; extra?: Record<string, unknown> | undefined } = {},
77
87
  ): Promise<unknown> {
78
- // A $never operand is data with its full input, as a $never call anywhere (roadmap R4: before,
79
- // only a chain step obeyed it, and a $never branch, task or fn started)
80
- if (getRefWhen(ref) === WHEN_NEVER) {
81
- return ref;
82
- }
83
- const normalized = normalizeRef(ref);
84
- const raw = rawRule(ctx)(normalized.path);
85
- let input: unknown = raw ? normalized.input : await hydrateOperand(normalized.input, ctx, options.scope);
86
- const extra = options.extra ?? {};
87
- if (Object.keys(extra).length > 0) {
88
- input = { ...(typeof input === "object" && input !== null && !Array.isArray(input) ? input : {}), ...extra };
89
- }
90
- if (raw) {
91
- input = withScope(input, options.scope);
92
- }
93
- return ctx.client.call(normalized.path, input);
88
+ return runOperand(ref, { executor: executorOf(ctx), rawInput: rawRule(ctx), onRef: ctx.onRef, scope: options.scope, extra: options.extra });
94
89
  }
95
90
 
96
91
  /** This function gives the value of any operand: a ref runs, another value is hydrated. */
@@ -105,21 +100,6 @@ export async function evaluateOperand(
105
100
  return hydrateOperand(value, ctx, options.scope);
106
101
  }
107
102
 
108
- /** The parent context that the control-flow procedures give to their operands. */
109
- export function parentContext(input: { cwd?: string | undefined; node?: unknown }): Record<string, unknown> {
110
- return {
111
- ...(input.cwd ? { cwd: input.cwd } : {}),
112
- ...(input.node ? { node: input.node } : {}),
113
- };
114
- }
115
-
116
- /** A child scope of `parent` with the given `$ref` names, for one call of `fn`. */
117
- export function scopeWith(values: Record<string, unknown>, parent?: RefScope): RefScope {
118
- const scope = createRefScope(parent);
119
- for (const [name, value] of Object.entries(values)) scope.outputs.set(name, value);
120
- return scope;
121
- }
122
-
123
103
  /** The tags of a control-flow procedure: hydration gives it its input raw. */
124
104
  export function controlFlowTags(...tags: string[]): string[] {
125
105
  return ["core", ...tags, RUNS_REFS_TAG];
@@ -41,13 +41,12 @@ import { anySchema, zodAdapter } from "./core/schemas.js";
41
41
  import { keyToPath, pathToKey } from "./types.js";
42
42
  import {
43
43
  createRefScope,
44
- hydrateInput,
45
44
  isAnyProcedureRef,
46
45
  markDataDriven,
47
- prepareRootCall,
48
46
  rawInputRule,
49
47
  RUNS_REFS_TAG,
50
48
  } from "./ref.js";
49
+ import { hydrateInput, runProgram } from "./program.js";
51
50
  import { INFERRED_EFFECTS_METADATA_KEY, PURE_EFFECTS, REGISTRY_READ_EFFECTS, effectsValue, withEffects } from "./effects.js";
52
51
  import { MANIFEST_FORMAT, describeProcedure as describeEntry, describeRegistry, type ProcedureManifest } from "./manifest.js";
53
52
  import type { JsonSchema } from "./schema.js";
@@ -192,9 +191,9 @@ const DeleteOutputSchema = z.looseObject({
192
191
  /**
193
192
  * Create a handler that executes an aggregation definition.
194
193
  *
195
- * The body runs exactly as `exec()` runs the same program: `prepareRootCall()` gives the path
196
- * and the input of the root call (a `$when` on the root call does not apply, a list of calls in
197
- * the root input is an implicit chain), then the body starts the root call. The scope of the
194
+ * The body runs exactly as `exec()` runs the same program: one run of the kernel (`runProgram()`),
195
+ * whose root document is the root call (a `$when` on the root call does not apply, a list of calls
196
+ * in the root input is an implicit chain). The scope of the
198
197
  * body has one name, `input`: the input of the procedure. So `{ $ref: "input.dir" }` reads a
199
198
  * field of the input, and `$last`, the step names, `item`, `acc` and `index` keep their meaning
200
199
  * inside the body. (Deep dive CORE-4: before, a first pass replaced every `$ref` with a field of
@@ -213,8 +212,7 @@ function createAggregationHandler(
213
212
  const executor = <TIn, TOut>(path: ProcedurePath, value: TIn): Promise<TOut> => ctx.client.call<TIn, TOut>(path, value);
214
213
  const options = { scope, rawInput: rawInputRule(ctx.registry ?? PROCEDURE_REGISTRY), onRef: ctx.onRef };
215
214
  if (isAnyProcedureRef(aggregation)) {
216
- const root = await prepareRootCall(aggregation, executor, options);
217
- return ctx.client.call(root.path, root.input);
215
+ return runProgram(aggregation, { ...options, executor });
218
216
  }
219
217
  // A body that is not one call (an older stored program): hydrate it as a root value
220
218
  return hydrateInput(aggregation, executor, options);
@@ -1,20 +1,26 @@
1
1
  /**
2
- * The envelope form of a program (coeval, decisions D6, D9 and D10, roadmap item M7).
2
+ * The envelope form of a program (coeval, decisions D6, D9, D10 and D12, roadmap item M7).
3
3
  *
4
4
  * A document of coeval is an envelope: `{ type, value }`. The header can also have `name` and
5
5
  * `own`. In the envelope form of a program:
6
6
  *
7
7
  * - A call is `{ type: path, value: input }`. The type is the path of a procedure, as an array of
8
8
  * keys. A ref into the world, `{ type: "ref", value: ["world", ...path] }`, is also a type.
9
+ * The arrays `["ref"]` and `["lit"]` are kinds of the kernel, not paths. A procedure with the
10
+ * path `["ref"]` or `["lit"]` has a ref into the world as its type.
9
11
  * - A ref is `{ type: "ref", value: ["names", name, ...fields] }`. The name `last` reads the result
10
12
  * of the step before.
11
- * - A literal is `{ type: "literal", value }`. Nothing in its value runs.
13
+ * - A literal is `{ type: "literal", value }`. Nothing in its value runs. The type `"lit"` (the kind
14
+ * of the kernel, coeval D12) is an alias: `{ type: "lit", value }` is also a literal.
12
15
  *
13
- * The envelope form is a surface. `fromEnvelopeProgram()` changes it into the `$proc` form, and
14
- * `hydrateInput()` starts that form. In the input of a `$proc` program, an envelope is data. Thus
15
- * the root of a program decides its form, and the old programs do not change.
16
+ * The functions of this module read the envelopes with the helpers of `@mark1russell7/coeval`
17
+ * (`isTypeRef`, `typePath`, `ref`). `fromEnvelopeProgram()` changes the envelope form into the
18
+ * `$proc` form, and `client.exec()` then runs the program on the kernel (`program.ts`). In the
19
+ * input of a `$proc` program, an envelope is data. Thus the root of a program decides its form,
20
+ * and the old programs do not change.
16
21
  */
17
22
 
23
+ import { ENVELOPE_KEYS, isTypeRef, ref as refDocument, typePath } from "@mark1russell7/coeval";
18
24
  import {
19
25
  LITERAL_KEY,
20
26
  MAX_DATA_DEPTH,
@@ -50,7 +56,10 @@ export interface EnvelopeRef {
50
56
  readonly value: EnvelopePath;
51
57
  }
52
58
 
53
- /** This document gives its value as data. Nothing in the value runs. */
59
+ /**
60
+ * This document gives its value as data. Nothing in the value runs. The functions of this module
61
+ * write the type `"literal"`, and they also read the alias `"lit"` (coeval D12: the kind `lit`).
62
+ */
54
63
  export interface EnvelopeLiteral {
55
64
  readonly type: "literal";
56
65
  readonly value: unknown;
@@ -64,10 +73,10 @@ export interface EnvelopeProgram {
64
73
  /**
65
74
  * The path of the procedure, or a ref into the world: `{ type: "ref", value: ["world", ...path] }`.
66
75
  *
67
- * Deprecated behavior (D26): the types `["ref"]` and `["lit"]` (arrays of one key) are calls of
68
- * the procedures with these paths. From the next MINOR, they are the kinds `ref` and `lit` of
69
- * the kernel, and a ref into the world stays a call. For a call of these procedures, write a
70
- * ref into the world as the type: `{ type: { type: "ref", value: ["world", "ref"] }, value }`.
76
+ * The types `["ref"]` and `["lit"]` (arrays of one key) are the kinds `ref` and `lit` of the
77
+ * kernel (D26). Before 0.26.0, they were calls of the procedures with these paths. A ref into
78
+ * the world is always a call: it is the type of these procedures, for example
79
+ * `{ type: { type: "ref", value: ["world", "ref"] }, value }`.
71
80
  */
72
81
  readonly type: readonly string[] | EnvelopeRef;
73
82
  /** The input of the call. `null` gives a call without input. */
@@ -83,7 +92,7 @@ export interface EnvelopeProgram {
83
92
  // =============================================================================
84
93
 
85
94
  /** The keys of an envelope (coeval D6). */
86
- const HEADER_KEYS: ReadonlySet<string> = new Set(["type", "value", "name", "own"]);
95
+ const HEADER_KEYS: ReadonlySet<string> = new Set<string>(ENVELOPE_KEYS);
87
96
 
88
97
  /** The keys that make an object a construct of the `$proc` form. */
89
98
  const NATIVE_KEYS: readonly string[] = [PROCEDURE_JSON_KEY, OUTPUT_REF_KEY, LITERAL_KEY];
@@ -95,7 +104,10 @@ const CALL_KEYS: ReadonlySet<string> = new Set([PROCEDURE_JSON_KEY, "input", PRO
95
104
  const RUNTIME_CALL_KEYS: ReadonlySet<string> = new Set(["path", "input", PROCEDURE_NAME_KEY, PROCEDURE_WHEN_KEY]);
96
105
 
97
106
  const REF_TYPE = "ref";
107
+ /** The type of a literal that this module writes (the form of 0.23.0). */
98
108
  const LITERAL_TYPE = "literal";
109
+ /** The alias of the literal type: the kind `lit` of the kernel (coeval D12). */
110
+ const LIT_ALIAS = "lit";
99
111
  const NAMES_ROOT = "names";
100
112
  const WORLD_ROOT = "world";
101
113
  /** The name of the result of the step before, in the envelope form. */
@@ -109,7 +121,10 @@ type EnvelopeShape = Record<string, unknown> & { type: unknown; value: unknown;
109
121
  /** The kind of an envelope. `bad-type` is an envelope whose type is a ref that is not into the world. */
110
122
  type EnvelopeKind = "call" | "ref" | "literal" | "bad-type";
111
123
 
112
- /** This function gives true if a value is a plain object with `type`, `value` and only header keys. */
124
+ /**
125
+ * This function gives true if a value is a plain object with `type`, `value` and only header keys.
126
+ * The test is looser than `isEnvelope()` of coeval: a bad header gives an error, not data.
127
+ */
113
128
  function isEnvelopeShape(value: unknown): value is EnvelopeShape {
114
129
  return (
115
130
  isPlainObject(value) &&
@@ -124,22 +139,39 @@ function isProcedurePath(value: unknown): value is readonly string[] {
124
139
  return Array.isArray(value) && value.length > 0 && value.every((key) => typeof key === "string");
125
140
  }
126
141
 
127
- /** This function gives the procedure path of the type of a call, or undefined for another type. */
142
+ /** The keys of the type of an envelope (coeval `typePath()`), or undefined for a value that is not a type. */
143
+ function keysOfType(type: unknown): readonly (string | number)[] | undefined {
144
+ // A ref into the world as a type has only the keys `type` and `value`
145
+ if (isPlainObject(type) && Object.keys(type).length !== 2) return undefined;
146
+ return isTypeRef(type) ? typePath(type) : undefined;
147
+ }
148
+
149
+ /** This function gives true if a procedure path is also a kind of the kernel as an array: `["ref"]` or `["lit"]`. */
150
+ function isKindPath(keys: readonly unknown[]): boolean {
151
+ return keys.length === 1 && (keys[0] === REF_TYPE || keys[0] === LIT_ALIAS);
152
+ }
153
+
154
+ /**
155
+ * This function gives the procedure path of the type of a call, or undefined for another type. The
156
+ * type of a call is a list of keys, or a ref into the world. A text is a kind of the kernel or data.
157
+ * The arrays `["ref"]` and `["lit"]` are kinds. A ref into the world is always a call, so it is the
158
+ * type of the procedures `["ref"]` and `["lit"]`.
159
+ */
128
160
  function callPath(type: unknown): ProcedurePath | undefined {
129
- if (isProcedurePath(type)) return [...type];
130
- if (!isEnvelopeShape(type) || type.type !== REF_TYPE || Object.keys(type).length !== 2) return undefined;
131
- const path = type.value;
132
- if (!Array.isArray(path) || path[0] !== WORLD_ROOT) return undefined;
133
- const steps: unknown[] = path.slice(1);
134
- return isProcedurePath(steps) ? [...steps] : undefined;
161
+ if (typeof type === "string") return undefined;
162
+ const keys = keysOfType(type);
163
+ if (!isProcedurePath(keys) || (Array.isArray(type) && isKindPath(keys))) return undefined;
164
+ return [...keys];
135
165
  }
136
166
 
137
167
  /** This function gives the kind of an envelope, or undefined for data. */
138
168
  function envelopeKind(value: unknown): EnvelopeKind | undefined {
139
169
  if (!isEnvelopeShape(value)) return undefined;
140
170
  if (callPath(value.type)) return "call";
141
- if (value.type === REF_TYPE) return "ref";
142
- if (value.type === LITERAL_TYPE) return "literal";
171
+ const keys = keysOfType(value.type);
172
+ if (keys?.length === 1 && keys[0] === REF_TYPE) return "ref";
173
+ // The text "literal" (an array ["literal"] is a call, as in 0.23.0), or the alias "lit"
174
+ if (value.type === LITERAL_TYPE || (keys?.length === 1 && keys[0] === LIT_ALIAS)) return "literal";
143
175
  if (isPlainObject(value.type) && value.type["type"] === REF_TYPE) return "bad-type";
144
176
  return undefined;
145
177
  }
@@ -339,7 +371,8 @@ function fromValue(value: unknown, path: Set<object>, depth: number): unknown {
339
371
  *
340
372
  * The conversion:
341
373
  * - A call gives `{ type: path, value: input }`. A call without input gives the value `null`.
342
- * `$name` gives the header `name`.
374
+ * `$name` gives the header `name`. The path `["ref"]` or `["lit"]` gives a ref into the world as
375
+ * the type, because these arrays are kinds of the kernel.
343
376
  * - `{ $ref: "$last" }` gives `["names", "last"]`. `{ $ref: "a.b" }` gives `["names", "a", "b"]`.
344
377
  * - `{ $literal: value }` gives a literal.
345
378
  * - Data that the envelope form reads in a different way gives a literal. This data is an object
@@ -403,7 +436,10 @@ function toCall(call: AnyProcedureRef, path: Set<object>, depth: number): Envelo
403
436
  : input === null
404
437
  ? { type: LITERAL_TYPE, value: null }
405
438
  : toValue(input, path, depth + 1);
406
- return { type: [...procedurePath], value, ...($name !== undefined ? { name: $name } : {}) };
439
+ const type: EnvelopeProgram["type"] = isKindPath(procedurePath)
440
+ ? (refDocument(WORLD_ROOT, ...procedurePath) as unknown as EnvelopeRef)
441
+ : [...procedurePath];
442
+ return { type, value, ...($name !== undefined ? { name: $name } : {}) };
407
443
  }
408
444
 
409
445
  /** This function changes a `$ref` object into a ref envelope. */
@@ -421,7 +457,7 @@ function toRef(ref: OutputRef): EnvelopeRef {
421
457
  `["names", "last"] reads the result of the step before: give the step a different name`
422
458
  );
423
459
  }
424
- return { type: REF_TYPE, value: [NAMES_ROOT, name === NATIVE_LAST ? LAST_NAME : name!, ...fields] };
460
+ return refDocument(NAMES_ROOT, name === NATIVE_LAST ? LAST_NAME : name!, ...fields) as unknown as EnvelopeRef;
425
461
  }
426
462
 
427
463
  /** This function gives true if a value of the `$proc` form is a call, a `$ref` or a `$literal`. */
@@ -247,9 +247,6 @@ export {
247
247
  toJson,
248
248
  normalizeRef,
249
249
  // Hydration
250
- hydrateInput,
251
- prepareRootCall,
252
- observeHydration,
253
250
  isControlFlowPath,
254
251
  isDataDriven,
255
252
  markDataDriven,
@@ -266,7 +263,6 @@ export {
266
263
  resolveOutputRef,
267
264
  withScope,
268
265
  scopeOf,
269
- executeRef,
270
266
  // Templates
271
267
  extractTemplate,
272
268
  parseProcedureJson,
@@ -287,6 +283,40 @@ export type {
287
283
  RefScope,
288
284
  } from "./ref.js";
289
285
 
286
+ // Programs on the coeval kernel (coeval D13, roadmap item M14): the run documents and their machine
287
+ export {
288
+ hydrateInput,
289
+ prepareRootCall,
290
+ observeHydration,
291
+ executeRef,
292
+ runProgram,
293
+ runDocument,
294
+ runControl,
295
+ runOperand,
296
+ programMachine,
297
+ PROGRAM_WORLD,
298
+ desugarProgram,
299
+ desugarInput,
300
+ desugarControlValue,
301
+ originOf,
302
+ namesOfScope,
303
+ scopeOfNames,
304
+ nameKey,
305
+ nameOfKey,
306
+ documentAt,
307
+ } from "./program.js";
308
+ export type {
309
+ ProgramDocument,
310
+ DocumentOrigin,
311
+ DesugarOptions,
312
+ ProgramHost,
313
+ CallEffect,
314
+ CallPosition,
315
+ RunDocumentOptions,
316
+ RunProgramOptions,
317
+ RunOperandOptions,
318
+ } from "./program.js";
319
+
290
320
  // The envelope form of a program (coeval D6, D9 and D10, roadmap item M7)
291
321
  export { isEnvelopeProgram, fromEnvelopeProgram, toEnvelopeProgram } from "./envelope.js";
292
322
  export type { EnvelopeProgram, EnvelopeRef, EnvelopeLiteral, EnvelopePath } from "./envelope.js";