@procedures/compiler 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +254 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/checks.d.ts +24 -0
  6. package/dist/checks.d.ts.map +1 -0
  7. package/dist/checks.js +123 -0
  8. package/dist/checks.js.map +1 -0
  9. package/dist/codegen-closure.d.ts +19 -0
  10. package/dist/codegen-closure.d.ts.map +1 -0
  11. package/dist/codegen-closure.js +200 -0
  12. package/dist/codegen-closure.js.map +1 -0
  13. package/dist/codegen-text.d.ts +44 -0
  14. package/dist/codegen-text.d.ts.map +1 -0
  15. package/dist/codegen-text.js +360 -0
  16. package/dist/codegen-text.js.map +1 -0
  17. package/dist/diagnostics.d.ts +67 -0
  18. package/dist/diagnostics.d.ts.map +1 -0
  19. package/dist/diagnostics.js +38 -0
  20. package/dist/diagnostics.js.map +1 -0
  21. package/dist/effects.d.ts +63 -0
  22. package/dist/effects.d.ts.map +1 -0
  23. package/dist/effects.js +185 -0
  24. package/dist/effects.js.map +1 -0
  25. package/dist/explain.d.ts +58 -0
  26. package/dist/explain.d.ts.map +1 -0
  27. package/dist/explain.js +144 -0
  28. package/dist/explain.js.map +1 -0
  29. package/dist/facts.d.ts +66 -0
  30. package/dist/facts.d.ts.map +1 -0
  31. package/dist/facts.js +102 -0
  32. package/dist/facts.js.map +1 -0
  33. package/dist/fold.d.ts +27 -0
  34. package/dist/fold.d.ts.map +1 -0
  35. package/dist/fold.js +128 -0
  36. package/dist/fold.js.map +1 -0
  37. package/dist/index.d.ts +35 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +22 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/interceptor.d.ts +51 -0
  42. package/dist/interceptor.d.ts.map +1 -0
  43. package/dist/interceptor.js +116 -0
  44. package/dist/interceptor.js.map +1 -0
  45. package/dist/ir.d.ts +240 -0
  46. package/dist/ir.d.ts.map +1 -0
  47. package/dist/ir.js +74 -0
  48. package/dist/ir.js.map +1 -0
  49. package/dist/mermaid.d.ts +53 -0
  50. package/dist/mermaid.d.ts.map +1 -0
  51. package/dist/mermaid.js +423 -0
  52. package/dist/mermaid.js.map +1 -0
  53. package/dist/module.d.ts +20 -0
  54. package/dist/module.d.ts.map +1 -0
  55. package/dist/module.js +124 -0
  56. package/dist/module.js.map +1 -0
  57. package/dist/normalize.d.ts +43 -0
  58. package/dist/normalize.d.ts.map +1 -0
  59. package/dist/normalize.js +529 -0
  60. package/dist/normalize.js.map +1 -0
  61. package/dist/openrpc.d.ts +63 -0
  62. package/dist/openrpc.d.ts.map +1 -0
  63. package/dist/openrpc.js +57 -0
  64. package/dist/openrpc.js.map +1 -0
  65. package/dist/print.d.ts +8 -0
  66. package/dist/print.d.ts.map +1 -0
  67. package/dist/print.js +148 -0
  68. package/dist/print.js.map +1 -0
  69. package/dist/procedures/program/check.d.ts +14 -0
  70. package/dist/procedures/program/check.d.ts.map +1 -0
  71. package/dist/procedures/program/check.js +30 -0
  72. package/dist/procedures/program/check.js.map +1 -0
  73. package/dist/procedures/program/compile.d.ts +14 -0
  74. package/dist/procedures/program/compile.d.ts.map +1 -0
  75. package/dist/procedures/program/compile.js +35 -0
  76. package/dist/procedures/program/compile.js.map +1 -0
  77. package/dist/procedures/program/diagram.d.ts +14 -0
  78. package/dist/procedures/program/diagram.d.ts.map +1 -0
  79. package/dist/procedures/program/diagram.js +23 -0
  80. package/dist/procedures/program/diagram.js.map +1 -0
  81. package/dist/procedures/program/effects-output.d.ts +8 -0
  82. package/dist/procedures/program/effects-output.d.ts.map +1 -0
  83. package/dist/procedures/program/effects-output.js +13 -0
  84. package/dist/procedures/program/effects-output.js.map +1 -0
  85. package/dist/procedures/program/explain.d.ts +14 -0
  86. package/dist/procedures/program/explain.d.ts.map +1 -0
  87. package/dist/procedures/program/explain.js +43 -0
  88. package/dist/procedures/program/explain.js.map +1 -0
  89. package/dist/procedures/program/index.d.ts +5 -0
  90. package/dist/procedures/program/index.d.ts.map +1 -0
  91. package/dist/procedures/program/index.js +5 -0
  92. package/dist/procedures/program/index.js.map +1 -0
  93. package/dist/procedures/sdk/index.d.ts +3 -0
  94. package/dist/procedures/sdk/index.d.ts.map +1 -0
  95. package/dist/procedures/sdk/index.js +3 -0
  96. package/dist/procedures/sdk/index.js.map +1 -0
  97. package/dist/procedures/sdk/manifest.d.ts +11 -0
  98. package/dist/procedures/sdk/manifest.d.ts.map +1 -0
  99. package/dist/procedures/sdk/manifest.js +15 -0
  100. package/dist/procedures/sdk/manifest.js.map +1 -0
  101. package/dist/procedures/sdk/openrpc.d.ts +11 -0
  102. package/dist/procedures/sdk/openrpc.d.ts.map +1 -0
  103. package/dist/procedures/sdk/openrpc.js +13 -0
  104. package/dist/procedures/sdk/openrpc.js.map +1 -0
  105. package/dist/procedures/sdk/typescript.d.ts +11 -0
  106. package/dist/procedures/sdk/typescript.d.ts.map +1 -0
  107. package/dist/procedures/sdk/typescript.js +14 -0
  108. package/dist/procedures/sdk/typescript.js.map +1 -0
  109. package/dist/program.d.ts +84 -0
  110. package/dist/program.d.ts.map +1 -0
  111. package/dist/program.js +108 -0
  112. package/dist/program.js.map +1 -0
  113. package/dist/refs.d.ts +9 -0
  114. package/dist/refs.d.ts.map +1 -0
  115. package/dist/refs.js +9 -0
  116. package/dist/refs.js.map +1 -0
  117. package/dist/register.d.ts +6 -0
  118. package/dist/register.d.ts.map +1 -0
  119. package/dist/register.js +8 -0
  120. package/dist/register.js.map +1 -0
  121. package/dist/runtime.d.ts +68 -0
  122. package/dist/runtime.d.ts.map +1 -0
  123. package/dist/runtime.js +138 -0
  124. package/dist/runtime.js.map +1 -0
  125. package/dist/schema.d.ts +41 -0
  126. package/dist/schema.d.ts.map +1 -0
  127. package/dist/schema.js +325 -0
  128. package/dist/schema.js.map +1 -0
  129. package/dist/scopes.d.ts +25 -0
  130. package/dist/scopes.d.ts.map +1 -0
  131. package/dist/scopes.js +202 -0
  132. package/dist/scopes.js.map +1 -0
  133. package/dist/types.d.ts +129 -0
  134. package/dist/types.d.ts.map +1 -0
  135. package/dist/types.js +157 -0
  136. package/dist/types.js.map +1 -0
  137. package/dist/typescript-sdk.d.ts +34 -0
  138. package/dist/typescript-sdk.d.ts.map +1 -0
  139. package/dist/typescript-sdk.js +231 -0
  140. package/dist/typescript-sdk.js.map +1 -0
  141. package/package.json +83 -3
  142. package/src/checks.ts +128 -0
  143. package/src/codegen-closure.ts +224 -0
  144. package/src/codegen-text.ts +396 -0
  145. package/src/diagnostics.ts +98 -0
  146. package/src/effects.ts +231 -0
  147. package/src/explain.ts +194 -0
  148. package/src/facts.ts +161 -0
  149. package/src/fold.ts +136 -0
  150. package/src/index.ts +35 -0
  151. package/src/interceptor.ts +149 -0
  152. package/src/ir.ts +330 -0
  153. package/src/mermaid.ts +460 -0
  154. package/src/module.ts +171 -0
  155. package/src/normalize.ts +694 -0
  156. package/src/openrpc.ts +104 -0
  157. package/src/print.ts +143 -0
  158. package/src/procedures/program/check.ts +31 -0
  159. package/src/procedures/program/compile.ts +36 -0
  160. package/src/procedures/program/diagram.ts +25 -0
  161. package/src/procedures/program/effects-output.ts +16 -0
  162. package/src/procedures/program/explain.ts +46 -0
  163. package/src/procedures/program/index.ts +4 -0
  164. package/src/procedures/sdk/index.ts +2 -0
  165. package/src/procedures/sdk/manifest.ts +17 -0
  166. package/src/procedures/sdk/openrpc.ts +16 -0
  167. package/src/procedures/sdk/typescript.ts +17 -0
  168. package/src/program.ts +181 -0
  169. package/src/refs.ts +9 -0
  170. package/src/register.ts +10 -0
  171. package/src/runtime.ts +188 -0
  172. package/src/schema.ts +318 -0
  173. package/src/scopes.ts +196 -0
  174. package/src/types.ts +318 -0
  175. package/src/typescript-sdk.ts +282 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The closure code: the IR to a JavaScript function made of closures. A host runs it without
3
+ * `eval` and without `new Function`.
4
+ *
5
+ * The function does the steps of the interpreter in the same order. Each call goes through
6
+ * `ctx.client.call`, so it keeps its admission, validation, deadline and interceptors. The
7
+ * control-flow procedures do not start: the function does their work in line. A dynamic node
8
+ * calls its procedure with the raw input, and the interpreter of the client runs it.
9
+ */
10
+ import type { ProgramIR } from "./ir.js";
11
+ import { type CompiledProgram } from "./runtime.js";
12
+ /** The options of the closure code. */
13
+ export interface ClosureOptions {
14
+ /** The keys of the procedures that take raw input, for `client.exec(program, input)`. */
15
+ readonly rawKeys: readonly string[];
16
+ }
17
+ /** This function makes the closure code of a program. */
18
+ export declare function compileClosure(ir: ProgramIR, options: ClosureOptions): CompiledProgram;
19
+ //# sourceMappingURL=codegen-closure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen-closure.d.ts","sourceRoot":"","sources":["../src/codegen-closure.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAqB,SAAS,EAAiB,MAAM,SAAS,CAAC;AAC3E,OAAO,EAcL,KAAK,eAAe,EAGrB,MAAM,cAAc,CAAC;AAUtB,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,eAAe,CAUtF"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * The closure code: the IR to a JavaScript function made of closures. A host runs it without
3
+ * `eval` and without `new Function`.
4
+ *
5
+ * The function does the steps of the interpreter in the same order. Each call goes through
6
+ * `ctx.client.call`, so it keeps its admission, validation, deadline and interceptors. The
7
+ * control-flow procedures do not start: the function does their work in line. A dynamic node
8
+ * calls its procedure with the raw input, and the interpreter of the client runs it.
9
+ */
10
+ import { call, callRaw, deferred, execWithInput, fail, get, items as itemsOf, merge, message, object, parallel, truthy, unknownName, } from "./runtime.js";
11
+ /** This function makes the closure code of a program. */
12
+ export function compileClosure(ir, options) {
13
+ const root = compile(ir.root);
14
+ const { mode, program, input: inputBinding, bindingCount } = ir;
15
+ const rawKeys = [...options.rawKeys];
16
+ return async (ctx, input) => {
17
+ if (mode === "exec" && input !== undefined)
18
+ return execWithInput(ctx, program, input, rawKeys);
19
+ const state = { ctx, vars: new Array(bindingCount) };
20
+ if (inputBinding)
21
+ state.vars[inputBinding.id] = input;
22
+ return root(state);
23
+ };
24
+ }
25
+ /** The frames of a scope with the values of a run, for `withScope()`. */
26
+ function framesOf(snapshot, vars) {
27
+ if (!snapshot)
28
+ return undefined;
29
+ return snapshot.map((frame) => ({
30
+ names: frame.names.map(([name, binding]) => [name, vars[binding.id]]),
31
+ ...(frame.last ? { last: [vars[frame.last.id]] } : {}),
32
+ }));
33
+ }
34
+ function compileItems(spec) {
35
+ if (spec.kind === "list") {
36
+ const runs = spec.items.map(compile);
37
+ return async (state) => {
38
+ const values = [];
39
+ for (const run of runs)
40
+ values.push(await run(state));
41
+ return values;
42
+ };
43
+ }
44
+ const run = compile(spec.value);
45
+ return async (state) => itemsOf(await run(state));
46
+ }
47
+ function compile(node) {
48
+ switch (node.kind) {
49
+ case "literal": {
50
+ const value = node.value;
51
+ return async () => value;
52
+ }
53
+ case "object": {
54
+ const parts = node.entries.map((entry) => [entry.key, compile(entry.value)]);
55
+ return async (state) => {
56
+ const entries = [];
57
+ for (const [key, run] of parts)
58
+ entries.push([key, await run(state)]);
59
+ return object(entries);
60
+ };
61
+ }
62
+ case "array": {
63
+ const runs = node.items.map(compile);
64
+ return async (state) => {
65
+ const values = [];
66
+ for (const run of runs)
67
+ values.push(await run(state));
68
+ return values;
69
+ };
70
+ }
71
+ case "reference": {
72
+ const { binding, fields, text, deferred: isDeferred, source } = node;
73
+ if (binding) {
74
+ const id = binding.id;
75
+ return fields.length === 0 ? async (state) => state.vars[id] : async (state) => get(state.vars[id], fields);
76
+ }
77
+ if (isDeferred)
78
+ return async () => source;
79
+ return async () => unknownName(text);
80
+ }
81
+ case "call": {
82
+ const input = compile(node.input);
83
+ const { path, extra } = node;
84
+ return async (state) => call(state.ctx, path, merge(await input(state), extra));
85
+ }
86
+ case "deferred": {
87
+ const input = compile(node.input);
88
+ const source = node.source;
89
+ return async (state) => deferred(source, await input(state));
90
+ }
91
+ case "dynamic": {
92
+ const input = compile(node.input);
93
+ const { path, extra, scope } = node;
94
+ return async (state) => callRaw(state.ctx, path, merge(await input(state), extra), framesOf(scope, state.vars));
95
+ }
96
+ case "fail": {
97
+ const text = node.message;
98
+ return async () => fail(text);
99
+ }
100
+ case "chain": {
101
+ const initial = node.initialInput ? compile(node.initialInput) : undefined;
102
+ const initialId = node.initial?.id;
103
+ const steps = node.steps.map((step) => [step.result.id, compile(step.node)]);
104
+ return async (state) => {
105
+ if (initial && initialId !== undefined)
106
+ state.vars[initialId] = await initial(state);
107
+ const results = [];
108
+ for (const [id, run] of steps) {
109
+ const result = await run(state);
110
+ state.vars[id] = result;
111
+ results.push(result);
112
+ }
113
+ return { results, final: results[results.length - 1] };
114
+ };
115
+ }
116
+ case "parallel": {
117
+ const tasks = node.tasks.map(compile);
118
+ const { concurrency, failFast } = node;
119
+ return async (state) => parallel(tasks.map((task) => () => task(state)), concurrency, failFast);
120
+ }
121
+ case "conditional": {
122
+ const condition = compile(node.condition);
123
+ const thenRun = node.then ? compile(node.then) : undefined;
124
+ const elseRun = node.else ? compile(node.else) : undefined;
125
+ return async (state) => {
126
+ const branch = truthy(await condition(state)) ? thenRun : elseRun;
127
+ return branch ? branch(state) : undefined;
128
+ };
129
+ }
130
+ case "try": {
131
+ const tried = compile(node.try);
132
+ const caught = compile(node.catch);
133
+ const errorId = node.error.id;
134
+ return async (state) => {
135
+ try {
136
+ const value = await tried(state);
137
+ return { success: true, value };
138
+ }
139
+ catch (error) {
140
+ const text = message(error);
141
+ state.vars[errorId] = text;
142
+ const value = await caught(state);
143
+ return { success: false, value, error: text };
144
+ }
145
+ };
146
+ }
147
+ case "and":
148
+ case "or": {
149
+ const values = node.values.map(compile);
150
+ const stop = node.kind === "and" ? (value) => !value : (value) => Boolean(value);
151
+ return async (state) => {
152
+ let last = undefined;
153
+ for (const run of values) {
154
+ last = await run(state);
155
+ if (stop(last))
156
+ return last;
157
+ }
158
+ return last;
159
+ };
160
+ }
161
+ case "map": {
162
+ const list = compileItems(node.items);
163
+ const fn = node.fn ? compile(node.fn) : undefined;
164
+ const itemId = node.item.id;
165
+ const indexId = node.index.id;
166
+ return async (state) => {
167
+ const values = await list(state);
168
+ if (!fn)
169
+ return { results: values };
170
+ const results = [];
171
+ for (const [index, item] of values.entries()) {
172
+ state.vars[itemId] = item;
173
+ state.vars[indexId] = index;
174
+ results.push(await fn(state));
175
+ }
176
+ return { results };
177
+ };
178
+ }
179
+ case "reduce": {
180
+ const initial = compile(node.initial);
181
+ if (!node.fn || !node.items)
182
+ return initial;
183
+ const list = compileItems(node.items);
184
+ const fn = compile(node.fn);
185
+ const { acc: accBinding, item: itemBinding, index: indexBinding } = node;
186
+ return async (state) => {
187
+ const values = await list(state);
188
+ let acc = await initial(state);
189
+ for (const [index, item] of values.entries()) {
190
+ state.vars[accBinding.id] = acc;
191
+ state.vars[itemBinding.id] = item;
192
+ state.vars[indexBinding.id] = index;
193
+ acc = await fn(state);
194
+ }
195
+ return acc;
196
+ };
197
+ }
198
+ }
199
+ }
200
+ //# sourceMappingURL=codegen-closure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen-closure.js","sourceRoot":"","sources":["../src/codegen-closure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The source text: the IR to the text of an ES module (JavaScript or TypeScript).
3
+ *
4
+ * The text does the same steps as the closure code, with the functions of
5
+ * `@procedures/compiler/runtime`. Each literal goes into the text through `JSON.stringify` or
6
+ * through a number or a keyword, so a value of the program cannot change the code. Each key of
7
+ * an object is a computed key, so `__proto__` stays an own property.
8
+ */
9
+ import type { Pointer, ProgramIR } from "./ir.js";
10
+ import type { Diagnostic } from "./diagnostics.js";
11
+ /** The options of the source text. */
12
+ export interface TextOptions {
13
+ /** `js` (the default) or `ts`: TypeScript adds the types that a strict configuration needs. */
14
+ readonly language?: "js" | "ts" | undefined;
15
+ /** The import specifier of the runtime. The default is `@procedures/compiler/runtime`. */
16
+ readonly runtime?: string | undefined;
17
+ /** The hash of the manifest that the code was compiled against. */
18
+ readonly registryHash: string;
19
+ /** The keys of the procedures that take raw input, for `client.exec(program, input)`. */
20
+ readonly rawKeys: readonly string[];
21
+ }
22
+ /** One line of the source map: a line of the module and the pointer of its part of the program. */
23
+ export interface SourceMapLine {
24
+ /** The line number in the module, from 1. */
25
+ readonly line: number;
26
+ readonly pointer: Pointer;
27
+ }
28
+ /** The source text of a program. */
29
+ export interface ProgramText {
30
+ /** The ES module: its default export is `async (ctx, input) => output`. */
31
+ readonly module: string;
32
+ /**
33
+ * The body of an async function with the parameters `rt` (the runtime), `ctx` and `input`, in
34
+ * JavaScript. A host that can evaluate code (a test, a playground) uses it.
35
+ */
36
+ readonly body: string;
37
+ /** The lines of the module that start a part of the program. */
38
+ readonly sourceMap: SourceMapLine[];
39
+ /** The literals that have no source text. Then the text is not complete. */
40
+ readonly diagnostics: Diagnostic[];
41
+ }
42
+ /** This function writes the source text of a program. */
43
+ export declare function emitText(ir: ProgramIR, options: TextOptions): ProgramText;
44
+ //# sourceMappingURL=codegen-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen-text.d.ts","sourceRoot":"","sources":["../src/codegen-text.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAA8B,OAAO,EAAE,SAAS,EAAiB,MAAM,SAAS,CAAC;AAE7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,0FAA0F;IAC1F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;CACpC;AA4RD,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,WAAW,CAgEzE"}
@@ -0,0 +1,360 @@
1
+ /**
2
+ * The source text: the IR to the text of an ES module (JavaScript or TypeScript).
3
+ *
4
+ * The text does the same steps as the closure code, with the functions of
5
+ * `@procedures/compiler/runtime`. Each literal goes into the text through `JSON.stringify` or
6
+ * through a number or a keyword, so a value of the program cannot change the code. Each key of
7
+ * an object is a computed key, so `__proto__` stays an own property.
8
+ */
9
+ import { isPlainObject } from "@procedures/client/browser";
10
+ import { childrenOf, walk } from "./ir.js";
11
+ /** The deepest literal that the text writes: a deeper value is not serializable (no stack overflow). */
12
+ const MAX_LITERAL_DEPTH = 2000;
13
+ const LINE_SEPARATOR = String.fromCharCode(0x2028);
14
+ const PARAGRAPH_SEPARATOR = String.fromCharCode(0x2029);
15
+ const BACKSLASH = String.fromCharCode(0x5c);
16
+ /** A string literal: JSON, and the two line separators that a comment does not permit. */
17
+ function str(value) {
18
+ return JSON.stringify(value).split(LINE_SEPARATOR).join(BACKSLASH + "u2028").split(PARAGRAPH_SEPARATOR).join(BACKSLASH + "u2029");
19
+ }
20
+ /**
21
+ * The key of a property in an object literal: a name, or a computed key. `__proto__` is always a
22
+ * computed key: as a name or a string, it sets the prototype and makes no property.
23
+ */
24
+ function propertyKey(key) {
25
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) && key !== "__proto__" ? key : `[${str(key)}]`;
26
+ }
27
+ /** The comment that names the pointer of a line, for the source map. */
28
+ function pointerComment(pointer) {
29
+ return ` // ${str(pointer)}`;
30
+ }
31
+ class Emitter {
32
+ ts;
33
+ diagnostics = [];
34
+ temps = 0;
35
+ /** The bindings that a reference or a scope reads: only these get a variable. */
36
+ used = new Set();
37
+ usesContext = false;
38
+ usesRuntime = false;
39
+ constructor(ts) {
40
+ this.ts = ts;
41
+ }
42
+ temp() {
43
+ return `t${this.temps++}`;
44
+ }
45
+ rt(name) {
46
+ this.usesRuntime = true;
47
+ return `rt.${name}`;
48
+ }
49
+ ctx() {
50
+ this.usesContext = true;
51
+ return "ctx";
52
+ }
53
+ type(annotation) {
54
+ return this.ts ? `: ${annotation}` : "";
55
+ }
56
+ /** The source of a literal value, or undefined when the value has none. */
57
+ literal(value, pointer, seen = new Set()) {
58
+ switch (typeof value) {
59
+ case "undefined":
60
+ return "undefined";
61
+ case "boolean":
62
+ return value ? "true" : "false";
63
+ case "number":
64
+ if (Number.isNaN(value))
65
+ return "NaN";
66
+ if (value === Infinity)
67
+ return "Infinity";
68
+ if (value === -Infinity)
69
+ return "-Infinity";
70
+ if (Object.is(value, -0))
71
+ return "-0";
72
+ return String(value);
73
+ case "bigint":
74
+ return `${value}n`;
75
+ case "string":
76
+ return str(value);
77
+ case "object": {
78
+ if (value === null)
79
+ return "null";
80
+ if (seen.has(value))
81
+ return this.unserializable(pointer, "the value contains itself");
82
+ if (seen.size > MAX_LITERAL_DEPTH)
83
+ return this.unserializable(pointer, `the value nests deeper than ${MAX_LITERAL_DEPTH} levels`);
84
+ seen.add(value);
85
+ try {
86
+ if (Array.isArray(value))
87
+ return `[${Array.from(value, (item) => this.literal(item, pointer, seen)).join(", ")}]`;
88
+ if (isPlainObject(value) && Object.getOwnPropertySymbols(value).length === 0) {
89
+ const entries = Object.entries(value);
90
+ if (entries.length === 0)
91
+ return "{}";
92
+ return `{ ${entries.map(([key, item]) => `${propertyKey(key)}: ${this.literal(item, pointer, seen)}`).join(", ")} }`;
93
+ }
94
+ return this.unserializable(pointer, "the value is not plain data (a class instance or a runtime ref)");
95
+ }
96
+ finally {
97
+ seen.delete(value);
98
+ }
99
+ }
100
+ default:
101
+ return this.unserializable(pointer, `a ${typeof value} has no source text`);
102
+ }
103
+ }
104
+ unserializable(pointer, why) {
105
+ this.diagnostics.push({
106
+ severity: "warning",
107
+ code: "not-serializable",
108
+ message: `The source text cannot hold this literal: ${why}. The text has undefined in its place. The closure code is complete.`,
109
+ pointer,
110
+ });
111
+ return "undefined";
112
+ }
113
+ path(path) {
114
+ return `[${path.map((segment) => str(segment)).join(", ")}]`;
115
+ }
116
+ frames(snapshot) {
117
+ if (!snapshot)
118
+ return "undefined";
119
+ return `[${snapshot
120
+ .map((frame) => {
121
+ const names = frame.names.map(([name, binding]) => `[${str(name)}, ${this.binding(binding)}]`).join(", ");
122
+ return `{ names: [${names}]${frame.last ? `, last: [${this.binding(frame.last)}]` : ""} }`;
123
+ })
124
+ .join(", ")}]`;
125
+ }
126
+ binding(binding) {
127
+ return `b${binding.id}`;
128
+ }
129
+ /** An async block that gives a value: `(await (async () => { ... })())`. */
130
+ block(lines, indent, pointer, what) {
131
+ const inner = lines.map((line) => `${indent} ${line}`).join("\n");
132
+ return `(await (async () => {${pointerComment(pointer)} ${what}\n${inner}\n${indent}})())`;
133
+ }
134
+ items(spec, indent) {
135
+ if (spec.kind === "list")
136
+ return `[${spec.items.map((item) => this.expr(item, indent)).join(", ")}]`;
137
+ return `${this.rt("items")}(${this.expr(spec.value, indent)})`;
138
+ }
139
+ /** The expression of a node. `indent` is the indent of the line that holds it. */
140
+ expr(node, indent) {
141
+ const deeper = `${indent} `;
142
+ switch (node.kind) {
143
+ case "literal":
144
+ return this.literal(node.value, node.pointer);
145
+ case "object":
146
+ if (node.entries.length === 0)
147
+ return "{}";
148
+ return `${this.rt("object")}([${node.entries.map((entry) => `[${str(entry.key)}, ${this.expr(entry.value, indent)}]`).join(", ")}])`;
149
+ case "array":
150
+ return `[${node.items.map((item) => this.expr(item, indent)).join(", ")}]`;
151
+ case "reference": {
152
+ if (node.binding) {
153
+ const variable = this.binding(node.binding);
154
+ return node.fields.length === 0 ? variable : `${this.rt("get")}(${variable}, [${node.fields.map(str).join(", ")}])`;
155
+ }
156
+ if (node.deferred)
157
+ return this.literal(node.source, node.pointer);
158
+ return `${this.rt("unknownName")}(${str(node.text)})`;
159
+ }
160
+ case "call": {
161
+ const input = this.expr(node.input, indent);
162
+ const merged = Object.keys(node.extra).length > 0 ? `${this.rt("merge")}(${input}, ${this.literal(node.extra, node.pointer)})` : input;
163
+ return `(await ${this.rt("call")}(${this.ctx()}, ${this.path(node.path)}, ${merged}))`;
164
+ }
165
+ case "deferred":
166
+ return `${this.rt("deferred")}(${this.literal(node.source, node.pointer)}, ${this.expr(node.input, indent)})`;
167
+ case "dynamic": {
168
+ const input = this.expr(node.input, indent);
169
+ const merged = Object.keys(node.extra).length > 0 ? `${this.rt("merge")}(${input}, ${this.literal(node.extra, node.pointer)})` : input;
170
+ return `(await ${this.rt("callRaw")}(${this.ctx()}, ${this.path(node.path)}, ${merged}, ${this.frames(node.scope)}))`;
171
+ }
172
+ case "fail":
173
+ return `${this.rt("fail")}(${str(node.message)})`;
174
+ case "chain": {
175
+ const lines = [];
176
+ if (node.initialInput && node.initial) {
177
+ const initial = this.expr(node.initialInput, deeper);
178
+ lines.push(this.used.has(node.initial.id) ? `const ${this.binding(node.initial)} = ${initial};` : `void ${initial};`);
179
+ }
180
+ for (const step of node.steps) {
181
+ lines.push(`const ${this.binding(step.result)} = ${this.expr(step.node, deeper)};${pointerComment(step.pointer)}`);
182
+ }
183
+ const results = this.temp();
184
+ lines.push(`const ${results}${this.type("unknown[]")} = [${node.steps.map((step) => this.binding(step.result)).join(", ")}];`);
185
+ lines.push(`return { results: ${results}, final: ${results}[${results}.length - 1] };`);
186
+ return this.block(lines, indent, node.pointer, node.implicit ? "implicit chain" : "client.chain");
187
+ }
188
+ case "parallel": {
189
+ const tasks = node.tasks.map((task) => `async () => (${this.expr(task, deeper)})`);
190
+ const concurrency = node.concurrency === undefined ? "undefined" : String(node.concurrency);
191
+ return `(await ${this.rt("parallel")}([${tasks.join(", ")}], ${concurrency}, ${node.failFast ? "true" : "false"}))`;
192
+ }
193
+ case "conditional": {
194
+ const lines = [
195
+ `if (${this.rt("truthy")}(${this.expr(node.condition, deeper)})) return ${node.then ? this.expr(node.then, deeper) : "undefined"};`,
196
+ `return ${node.else ? this.expr(node.else, deeper) : "undefined"};`,
197
+ ];
198
+ return this.block(lines, indent, node.pointer, "client.conditional");
199
+ }
200
+ case "try": {
201
+ const error = this.temp();
202
+ const tried = this.temp();
203
+ const lines = [`try {`, ` const ${tried} = ${this.expr(node.try, `${deeper} `)};`];
204
+ lines.push(` return { success: true, value: ${tried} };`);
205
+ lines.push(`} catch (${error}) {`);
206
+ lines.push(` const ${this.binding(node.error)} = ${this.rt("message")}(${error});`);
207
+ const caught = this.temp();
208
+ lines.push(` const ${caught} = ${this.expr(node.catch, `${deeper} `)};`);
209
+ lines.push(` return { success: false, value: ${caught}, error: ${this.binding(node.error)} };`);
210
+ lines.push(`}`);
211
+ return this.block(lines, indent, node.pointer, "client.tryCatch");
212
+ }
213
+ case "and":
214
+ case "or": {
215
+ const last = this.temp();
216
+ const lines = [`let ${last}${this.type("unknown")};`];
217
+ node.values.forEach((value, index) => {
218
+ lines.push(`${last} = ${this.expr(value, deeper)};${pointerComment(value.pointer)}`);
219
+ if (index < node.values.length - 1)
220
+ lines.push(`if (${node.kind === "and" ? "!" : ""}${last}) return ${last};`);
221
+ });
222
+ lines.push(`return ${last};`);
223
+ return this.block(lines, indent, node.pointer, `client.${node.kind}`);
224
+ }
225
+ case "map": {
226
+ const values = this.temp();
227
+ const lines = [`const ${values}${this.type("unknown[]")} = ${this.items(node.items, deeper)};`];
228
+ if (!node.fn) {
229
+ lines.push(`return { results: ${values} };`);
230
+ }
231
+ else {
232
+ const results = this.temp();
233
+ lines.push(`const ${results}${this.type("unknown[]")} = [];`);
234
+ lines.push(`for (const [${this.declare(node.index)}, ${this.declare(node.item)}] of ${values}.entries()) {`);
235
+ lines.push(` ${results}.push(${this.expr(node.fn, `${deeper} `)});${pointerComment(node.fn.pointer)}`);
236
+ lines.push(`}`);
237
+ lines.push(`return { results: ${results} };`);
238
+ }
239
+ return this.block(lines, indent, node.pointer, "client.map");
240
+ }
241
+ case "reduce": {
242
+ if (!node.fn || !node.items)
243
+ return this.expr(node.initial, indent);
244
+ const values = this.temp();
245
+ const acc = this.temp();
246
+ const lines = [
247
+ `const ${values}${this.type("unknown[]")} = ${this.items(node.items, deeper)};`,
248
+ `let ${acc}${this.type("unknown")} = ${this.expr(node.initial, deeper)};`,
249
+ `for (const [${this.declare(node.index)}, ${this.declare(node.item)}] of ${values}.entries()) {`,
250
+ ];
251
+ if (this.used.has(node.acc.id))
252
+ lines.push(` const ${this.binding(node.acc)} = ${acc};`);
253
+ lines.push(` ${acc} = ${this.expr(node.fn, `${deeper} `)};${pointerComment(node.fn.pointer)}`);
254
+ lines.push(`}`);
255
+ lines.push(`return ${acc};`);
256
+ return this.block(lines, indent, node.pointer, "client.reduce");
257
+ }
258
+ }
259
+ }
260
+ /** The name of a binding in a declaration, or nothing when no reference reads it. */
261
+ declare(binding) {
262
+ return this.used.has(binding.id) ? this.binding(binding) : "";
263
+ }
264
+ }
265
+ /** The bindings that the code reads: the resolved references and the scopes of the dynamic nodes. */
266
+ function usedBindings(root) {
267
+ const used = new Set();
268
+ walk(root, (node) => {
269
+ if (node.kind === "reference" && node.binding)
270
+ used.add(node.binding.id);
271
+ if (node.kind === "dynamic" && node.scope) {
272
+ for (const frame of node.scope) {
273
+ for (const [, binding] of frame.names)
274
+ used.add(binding.id);
275
+ if (frame.last)
276
+ used.add(frame.last.id);
277
+ }
278
+ }
279
+ });
280
+ return used;
281
+ }
282
+ /** The nesting above which the source text gets a warning. V8 refuses a text of approximately 1000 levels. */
283
+ const MAX_TEXT_DEPTH = 300;
284
+ /** The deepest nesting of the nodes. */
285
+ function depthOf(root) {
286
+ let deepest = 0;
287
+ const visit = (node, depth) => {
288
+ deepest = Math.max(deepest, depth);
289
+ for (const child of childrenOf(node))
290
+ visit(child, depth + 1);
291
+ };
292
+ visit(root, 1);
293
+ return deepest;
294
+ }
295
+ /** This function writes the source text of a program. */
296
+ export function emitText(ir, options) {
297
+ const ts = options.language === "ts";
298
+ const runtime = options.runtime ?? "@procedures/compiler/runtime";
299
+ const emitter = new Emitter(ts);
300
+ for (const id of usedBindings(ir.root))
301
+ emitter.used.add(id);
302
+ const depth = depthOf(ir.root);
303
+ if (depth > MAX_TEXT_DEPTH) {
304
+ emitter.diagnostics.push({
305
+ severity: "warning",
306
+ code: "text-depth",
307
+ message: `The program nests ${depth} levels deep: a JavaScript parser can refuse a source text this deep. The closure code has no such limit.`,
308
+ pointer: ir.root.pointer,
309
+ });
310
+ }
311
+ const bodyLines = [];
312
+ /** The constants of the exec mode: the module has them one time, the function body has them in the body. */
313
+ const constants = [];
314
+ let inputUsed = false;
315
+ if (ir.mode === "exec") {
316
+ inputUsed = true;
317
+ constants.push(`const PROGRAM${emitter.type("unknown")} = ${emitter.literal(ir.program, "")};`);
318
+ constants.push(`const RAW_KEYS${emitter.type("string[]")} = [${options.rawKeys.map(str).join(", ")}];`);
319
+ bodyLines.push(`if (input !== undefined) return ${emitter.rt("execWithInput")}(${emitter.ctx()}, PROGRAM, input, RAW_KEYS);`);
320
+ }
321
+ else if (ir.input && emitter.used.has(ir.input.id)) {
322
+ inputUsed = true;
323
+ bodyLines.push(`const ${emitter.binding(ir.input)} = input;`);
324
+ }
325
+ bodyLines.push(`return ${emitter.expr(ir.root, " ")};${pointerComment(ir.root.pointer)}`);
326
+ const body = bodyLines.map((line) => ` ${line}`).join("\n");
327
+ const ctxName = emitter.usesContext ? "ctx" : "_ctx";
328
+ const inputName = inputUsed ? "input" : "_input";
329
+ const header = [
330
+ "// Generated by @procedures/compiler from a program. Compile the program again after a change.",
331
+ `// The registry hash: ${options.registryHash}`,
332
+ ...(emitter.usesRuntime ? [`import * as rt from ${str(runtime)};`] : []),
333
+ ...(ts ? [`import type { ProgramContext } from ${str(runtime)};`] : []),
334
+ "",
335
+ `export const registryHash${ts ? ": string" : ""} = ${str(options.registryHash)};`,
336
+ ...(constants.length > 0 ? ["", "// The program, for client.exec(program, input): the input changes the program, so the interpreter runs it", ...constants] : []),
337
+ "",
338
+ ts
339
+ ? `export default async function program(${ctxName}: ProgramContext, ${inputName}?: unknown): Promise<unknown> {`
340
+ : `export default async function program(${ctxName}, ${inputName}) {`,
341
+ ];
342
+ const moduleText = `${[...header, body, "}"].join("\n")}\n`;
343
+ // The function body for `new AsyncFunction("rt", "ctx", "input", body)`: always JavaScript
344
+ const jsEmitter = ts ? emitText(ir, { ...options, language: "js" }) : undefined;
345
+ const functionBody = jsEmitter ? jsEmitter.body : [...constants, ...bodyLines].join("\n");
346
+ const sourceMap = [];
347
+ moduleText.split("\n").forEach((line, index) => {
348
+ const match = /\/\/ ("(?:[^"\\]|\\.)*")(?: [a-zA-Z. ]*)?$/.exec(line);
349
+ if (match?.[1]) {
350
+ try {
351
+ sourceMap.push({ line: index + 1, pointer: JSON.parse(match[1]) });
352
+ }
353
+ catch {
354
+ // Not a pointer comment
355
+ }
356
+ }
357
+ });
358
+ return { module: moduleText, body: functionBody, sourceMap, diagnostics: emitter.diagnostics };
359
+ }
360
+ //# sourceMappingURL=codegen-text.js.map