@manifesto-ai/compiler 1.6.1 → 1.7.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 (185) hide show
  1. package/README.md +64 -16
  2. package/dist/chunk-DJY6BFGK.js +74 -0
  3. package/dist/chunk-DJY6BFGK.js.map +1 -0
  4. package/dist/chunk-QP2LGMBA.js +4522 -0
  5. package/dist/chunk-QP2LGMBA.js.map +1 -0
  6. package/dist/chunk-QXLPDCLA.js +33 -0
  7. package/dist/chunk-QXLPDCLA.js.map +1 -0
  8. package/dist/esbuild.d.ts +8 -0
  9. package/dist/esbuild.js +14 -0
  10. package/dist/esbuild.js.map +1 -0
  11. package/dist/index.d.ts +2710 -11
  12. package/dist/index.js +2189 -43
  13. package/dist/index.js.map +1 -1
  14. package/dist/node-loader.d.ts +18 -0
  15. package/dist/node-loader.js +47 -0
  16. package/dist/node-loader.js.map +1 -0
  17. package/dist/rollup.d.ts +8 -0
  18. package/dist/rollup.js +14 -0
  19. package/dist/rollup.js.map +1 -0
  20. package/dist/rspack.d.ts +7 -0
  21. package/dist/rspack.js +14 -0
  22. package/dist/rspack.js.map +1 -0
  23. package/dist/unplugin-6wnvFiEo.d.ts +17 -0
  24. package/dist/vite.d.ts +8 -17
  25. package/dist/vite.js +13 -33
  26. package/dist/vite.js.map +1 -1
  27. package/dist/webpack.d.ts +8 -0
  28. package/dist/webpack.js +14 -0
  29. package/dist/webpack.js.map +1 -0
  30. package/package.json +42 -24
  31. package/dist/analyzer/index.d.ts +0 -6
  32. package/dist/analyzer/index.d.ts.map +0 -1
  33. package/dist/analyzer/index.js +0 -6
  34. package/dist/analyzer/index.js.map +0 -1
  35. package/dist/analyzer/scope.d.ts +0 -77
  36. package/dist/analyzer/scope.d.ts.map +0 -1
  37. package/dist/analyzer/scope.js +0 -296
  38. package/dist/analyzer/scope.js.map +0 -1
  39. package/dist/analyzer/validator.d.ts +0 -60
  40. package/dist/analyzer/validator.d.ts.map +0 -1
  41. package/dist/analyzer/validator.js +0 -439
  42. package/dist/analyzer/validator.js.map +0 -1
  43. package/dist/api/compile-mel.d.ts +0 -126
  44. package/dist/api/compile-mel.d.ts.map +0 -1
  45. package/dist/api/compile-mel.js +0 -129
  46. package/dist/api/compile-mel.js.map +0 -1
  47. package/dist/api/index.d.ts +0 -10
  48. package/dist/api/index.d.ts.map +0 -1
  49. package/dist/api/index.js +0 -9
  50. package/dist/api/index.js.map +0 -1
  51. package/dist/diagnostics/codes.d.ts +0 -25
  52. package/dist/diagnostics/codes.d.ts.map +0 -1
  53. package/dist/diagnostics/codes.js +0 -154
  54. package/dist/diagnostics/codes.js.map +0 -1
  55. package/dist/diagnostics/index.d.ts +0 -6
  56. package/dist/diagnostics/index.d.ts.map +0 -1
  57. package/dist/diagnostics/index.js +0 -6
  58. package/dist/diagnostics/index.js.map +0 -1
  59. package/dist/diagnostics/types.d.ts +0 -67
  60. package/dist/diagnostics/types.d.ts.map +0 -1
  61. package/dist/diagnostics/types.js +0 -58
  62. package/dist/diagnostics/types.js.map +0 -1
  63. package/dist/evaluation/context.d.ts +0 -91
  64. package/dist/evaluation/context.d.ts.map +0 -1
  65. package/dist/evaluation/context.js +0 -59
  66. package/dist/evaluation/context.js.map +0 -1
  67. package/dist/evaluation/evaluate-expr.d.ts +0 -24
  68. package/dist/evaluation/evaluate-expr.d.ts.map +0 -1
  69. package/dist/evaluation/evaluate-expr.js +0 -576
  70. package/dist/evaluation/evaluate-expr.js.map +0 -1
  71. package/dist/evaluation/evaluate-patch.d.ts +0 -123
  72. package/dist/evaluation/evaluate-patch.d.ts.map +0 -1
  73. package/dist/evaluation/evaluate-patch.js +0 -202
  74. package/dist/evaluation/evaluate-patch.js.map +0 -1
  75. package/dist/evaluation/evaluate-runtime-patch.d.ts +0 -86
  76. package/dist/evaluation/evaluate-runtime-patch.d.ts.map +0 -1
  77. package/dist/evaluation/evaluate-runtime-patch.js +0 -153
  78. package/dist/evaluation/evaluate-runtime-patch.js.map +0 -1
  79. package/dist/evaluation/index.d.ts +0 -15
  80. package/dist/evaluation/index.d.ts.map +0 -1
  81. package/dist/evaluation/index.js +0 -13
  82. package/dist/evaluation/index.js.map +0 -1
  83. package/dist/generator/index.d.ts +0 -7
  84. package/dist/generator/index.d.ts.map +0 -1
  85. package/dist/generator/index.js +0 -7
  86. package/dist/generator/index.js.map +0 -1
  87. package/dist/generator/ir.d.ts +0 -348
  88. package/dist/generator/ir.d.ts.map +0 -1
  89. package/dist/generator/ir.js +0 -709
  90. package/dist/generator/ir.js.map +0 -1
  91. package/dist/generator/lowering.d.ts +0 -11
  92. package/dist/generator/lowering.d.ts.map +0 -1
  93. package/dist/generator/lowering.js +0 -368
  94. package/dist/generator/lowering.js.map +0 -1
  95. package/dist/generator/normalizer.d.ts +0 -16
  96. package/dist/generator/normalizer.d.ts.map +0 -1
  97. package/dist/generator/normalizer.js +0 -181
  98. package/dist/generator/normalizer.js.map +0 -1
  99. package/dist/index.d.ts.map +0 -1
  100. package/dist/lexer/index.d.ts +0 -7
  101. package/dist/lexer/index.d.ts.map +0 -1
  102. package/dist/lexer/index.js +0 -7
  103. package/dist/lexer/index.js.map +0 -1
  104. package/dist/lexer/lexer.d.ts +0 -59
  105. package/dist/lexer/lexer.d.ts.map +0 -1
  106. package/dist/lexer/lexer.js +0 -433
  107. package/dist/lexer/lexer.js.map +0 -1
  108. package/dist/lexer/source-location.d.ts +0 -41
  109. package/dist/lexer/source-location.d.ts.map +0 -1
  110. package/dist/lexer/source-location.js +0 -33
  111. package/dist/lexer/source-location.js.map +0 -1
  112. package/dist/lexer/tokens.d.ts +0 -47
  113. package/dist/lexer/tokens.d.ts.map +0 -1
  114. package/dist/lexer/tokens.js +0 -73
  115. package/dist/lexer/tokens.js.map +0 -1
  116. package/dist/loader.d.ts +0 -23
  117. package/dist/loader.d.ts.map +0 -1
  118. package/dist/loader.js +0 -62
  119. package/dist/loader.js.map +0 -1
  120. package/dist/lowering/context.d.ts +0 -96
  121. package/dist/lowering/context.d.ts.map +0 -1
  122. package/dist/lowering/context.js +0 -42
  123. package/dist/lowering/context.js.map +0 -1
  124. package/dist/lowering/errors.d.ts +0 -84
  125. package/dist/lowering/errors.d.ts.map +0 -1
  126. package/dist/lowering/errors.js +0 -81
  127. package/dist/lowering/errors.js.map +0 -1
  128. package/dist/lowering/index.d.ts +0 -20
  129. package/dist/lowering/index.d.ts.map +0 -1
  130. package/dist/lowering/index.js +0 -13
  131. package/dist/lowering/index.js.map +0 -1
  132. package/dist/lowering/lower-expr.d.ts +0 -76
  133. package/dist/lowering/lower-expr.d.ts.map +0 -1
  134. package/dist/lowering/lower-expr.js +0 -351
  135. package/dist/lowering/lower-expr.js.map +0 -1
  136. package/dist/lowering/lower-patch.d.ts +0 -231
  137. package/dist/lowering/lower-patch.d.ts.map +0 -1
  138. package/dist/lowering/lower-patch.js +0 -146
  139. package/dist/lowering/lower-patch.js.map +0 -1
  140. package/dist/lowering/lower-runtime-patch.d.ts +0 -100
  141. package/dist/lowering/lower-runtime-patch.d.ts.map +0 -1
  142. package/dist/lowering/lower-runtime-patch.js +0 -49
  143. package/dist/lowering/lower-runtime-patch.js.map +0 -1
  144. package/dist/mel-module.d.ts +0 -13
  145. package/dist/mel-module.d.ts.map +0 -1
  146. package/dist/mel-module.js +0 -33
  147. package/dist/mel-module.js.map +0 -1
  148. package/dist/parser/ast.d.ts +0 -344
  149. package/dist/parser/ast.d.ts.map +0 -1
  150. package/dist/parser/ast.js +0 -24
  151. package/dist/parser/ast.js.map +0 -1
  152. package/dist/parser/index.d.ts +0 -7
  153. package/dist/parser/index.d.ts.map +0 -1
  154. package/dist/parser/index.js +0 -7
  155. package/dist/parser/index.js.map +0 -1
  156. package/dist/parser/parser.d.ts +0 -92
  157. package/dist/parser/parser.d.ts.map +0 -1
  158. package/dist/parser/parser.js +0 -892
  159. package/dist/parser/parser.js.map +0 -1
  160. package/dist/parser/precedence.d.ts +0 -44
  161. package/dist/parser/precedence.d.ts.map +0 -1
  162. package/dist/parser/precedence.js +0 -69
  163. package/dist/parser/precedence.js.map +0 -1
  164. package/dist/renderer/expr-node.d.ts +0 -172
  165. package/dist/renderer/expr-node.d.ts.map +0 -1
  166. package/dist/renderer/expr-node.js +0 -218
  167. package/dist/renderer/expr-node.js.map +0 -1
  168. package/dist/renderer/fragment.d.ts +0 -84
  169. package/dist/renderer/fragment.d.ts.map +0 -1
  170. package/dist/renderer/fragment.js +0 -172
  171. package/dist/renderer/fragment.js.map +0 -1
  172. package/dist/renderer/index.d.ts +0 -23
  173. package/dist/renderer/index.d.ts.map +0 -1
  174. package/dist/renderer/index.js +0 -27
  175. package/dist/renderer/index.js.map +0 -1
  176. package/dist/renderer/patch-op.d.ts +0 -82
  177. package/dist/renderer/patch-op.d.ts.map +0 -1
  178. package/dist/renderer/patch-op.js +0 -203
  179. package/dist/renderer/patch-op.js.map +0 -1
  180. package/dist/renderer/type-expr.d.ts +0 -61
  181. package/dist/renderer/type-expr.d.ts.map +0 -1
  182. package/dist/renderer/type-expr.js +0 -131
  183. package/dist/renderer/type-expr.js.map +0 -1
  184. package/dist/vite.d.ts.map +0 -1
  185. package/loader.cjs +0 -22
@@ -1,709 +0,0 @@
1
- /**
2
- * IR Generator - Transforms MEL AST to Core DomainSchema
3
- * Based on MEL SPEC v0.3.3 Section 5
4
- */
5
- import { normalizeExpr, normalizeFunctionCall } from "./normalizer.js";
6
- import { hashSchemaSync, sha256Sync } from "@manifesto-ai/core";
7
- function createContext(domainName) {
8
- return {
9
- domainName,
10
- stateFields: new Set(),
11
- computedFields: new Set(),
12
- actionParams: new Map(),
13
- onceIntentCounters: new Map(),
14
- currentAction: null,
15
- diagnostics: [],
16
- typeDefs: new Map(),
17
- };
18
- }
19
- // ============ Main Generator ============
20
- /**
21
- * Generate Core DomainSchema from MEL AST
22
- */
23
- export function generate(program) {
24
- const ctx = createContext(program.domain.name);
25
- // First pass: collect state and computed field names
26
- collectFieldNames(program.domain, ctx);
27
- // v0.3.3: Generate types first
28
- const types = generateTypes(program.domain, ctx);
29
- // Generate schema parts
30
- const state = generateState(program.domain, ctx);
31
- const computed = generateComputed(program.domain, ctx);
32
- const actions = generateActions(program.domain, ctx);
33
- if (ctx.diagnostics.some(d => d.severity === "error")) {
34
- return {
35
- schema: null,
36
- diagnostics: ctx.diagnostics,
37
- };
38
- }
39
- // Create schema
40
- const schemaWithoutHash = {
41
- id: `mel:${program.domain.name.toLowerCase()}`,
42
- version: "1.0.0",
43
- types,
44
- state,
45
- computed,
46
- actions,
47
- meta: {
48
- name: program.domain.name,
49
- },
50
- };
51
- // Compute hash
52
- const hash = computeHash(schemaWithoutHash);
53
- const schema = {
54
- ...schemaWithoutHash,
55
- hash,
56
- };
57
- return {
58
- schema,
59
- diagnostics: ctx.diagnostics,
60
- };
61
- }
62
- // ============ Field Collection ============
63
- function collectFieldNames(domain, ctx) {
64
- // Collect type declarations first
65
- for (const typeDecl of domain.types) {
66
- ctx.typeDefs.set(typeDecl.name, typeDecl);
67
- }
68
- for (const member of domain.members) {
69
- if (member.kind === "state") {
70
- for (const field of member.fields) {
71
- ctx.stateFields.add(field.name);
72
- }
73
- }
74
- else if (member.kind === "computed") {
75
- ctx.computedFields.add(member.name);
76
- }
77
- }
78
- }
79
- // ============ Type Generation (v0.3.3) ============
80
- function generateTypes(domain, _ctx) {
81
- const types = {};
82
- for (const typeDecl of domain.types) {
83
- types[typeDecl.name] = {
84
- name: typeDecl.name,
85
- definition: typeExprToDefinition(typeDecl.typeExpr),
86
- };
87
- }
88
- return types;
89
- }
90
- function typeExprToDefinition(typeExpr) {
91
- switch (typeExpr.kind) {
92
- case "simpleType":
93
- // Primitive types vs type references
94
- if (["string", "number", "boolean", "null"].includes(typeExpr.name)) {
95
- return { kind: "primitive", type: typeExpr.name };
96
- }
97
- // User-defined type reference
98
- return { kind: "ref", name: typeExpr.name };
99
- case "arrayType":
100
- return {
101
- kind: "array",
102
- element: typeExprToDefinition(typeExpr.elementType),
103
- };
104
- case "recordType":
105
- return {
106
- kind: "record",
107
- key: typeExprToDefinition(typeExpr.keyType),
108
- value: typeExprToDefinition(typeExpr.valueType),
109
- };
110
- case "objectType":
111
- const fields = {};
112
- for (const field of typeExpr.fields) {
113
- fields[field.name] = {
114
- type: typeExprToDefinition(field.typeExpr),
115
- optional: field.optional,
116
- };
117
- }
118
- return { kind: "object", fields };
119
- case "unionType":
120
- return {
121
- kind: "union",
122
- types: typeExpr.types.map(typeExprToDefinition),
123
- };
124
- case "literalType":
125
- return { kind: "literal", value: typeExpr.value };
126
- default:
127
- // Exhaustive check
128
- const _exhaustive = typeExpr;
129
- throw new Error(`Unknown type expression kind: ${typeExpr.kind}`);
130
- }
131
- }
132
- // ============ State Generation ============
133
- function generateState(domain, ctx) {
134
- const fields = {};
135
- for (const member of domain.members) {
136
- if (member.kind === "state") {
137
- for (const field of member.fields) {
138
- fields[field.name] = generateFieldSpec(field, ctx);
139
- }
140
- }
141
- }
142
- return { fields };
143
- }
144
- function generateFieldSpec(field, ctx) {
145
- const spec = typeExprToFieldSpec(field.typeExpr, ctx);
146
- const defaultValue = field.initializer
147
- ? evaluateInitializer(field.initializer, ctx)
148
- : undefined;
149
- return {
150
- ...spec,
151
- required: true,
152
- default: defaultValue,
153
- };
154
- }
155
- /**
156
- * Convert TypeExprNode to complete FieldSpec (including nested fields)
157
- * This is the full conversion that includes `fields` for object types
158
- */
159
- function typeExprToFieldSpec(typeExpr, ctx) {
160
- switch (typeExpr.kind) {
161
- case "simpleType":
162
- switch (typeExpr.name) {
163
- case "string": return { type: "string", required: true };
164
- case "number": return { type: "number", required: true };
165
- case "boolean": return { type: "boolean", required: true };
166
- case "null": return { type: "null", required: true };
167
- default: {
168
- // User-defined type - look up and expand
169
- const typeDef = ctx.typeDefs.get(typeExpr.name);
170
- if (typeDef) {
171
- return typeExprToFieldSpec(typeDef.typeExpr, ctx);
172
- }
173
- // Unknown type - treat as opaque object
174
- return { type: "object", required: true };
175
- }
176
- }
177
- case "unionType": {
178
- // Check if it's a literal union (enum)
179
- const literals = [];
180
- let isLiteralUnion = true;
181
- let hasNull = false;
182
- for (const t of typeExpr.types) {
183
- if (t.kind === "literalType") {
184
- if (t.value === null) {
185
- hasNull = true;
186
- }
187
- literals.push(t.value);
188
- continue;
189
- }
190
- if (t.kind === "simpleType" && t.name === "null") {
191
- hasNull = true;
192
- literals.push(null);
193
- continue;
194
- }
195
- isLiteralUnion = false;
196
- }
197
- if (isLiteralUnion && literals.length > 0) {
198
- return { type: { enum: literals }, required: !hasNull };
199
- }
200
- // Nullable type: T | null -> get spec of T
201
- if (hasNull) {
202
- for (const t of typeExpr.types) {
203
- if (t.kind !== "simpleType" || t.name !== "null") {
204
- const innerSpec = typeExprToFieldSpec(t, ctx);
205
- return { ...innerSpec, required: false };
206
- }
207
- }
208
- }
209
- // Mixed union - default to first non-null type
210
- for (const t of typeExpr.types) {
211
- if (t.kind !== "simpleType" || t.name !== "null") {
212
- return typeExprToFieldSpec(t, ctx);
213
- }
214
- }
215
- return { type: "null", required: true };
216
- }
217
- case "arrayType": {
218
- const itemSpec = typeExprToFieldSpec(typeExpr.elementType, ctx);
219
- return {
220
- type: "array",
221
- required: true,
222
- items: itemSpec,
223
- };
224
- }
225
- case "recordType":
226
- return { type: "object", required: true };
227
- case "literalType":
228
- // Single literal type - use its base type
229
- if (typeof typeExpr.value === "string")
230
- return { type: "string", required: true };
231
- if (typeof typeExpr.value === "number")
232
- return { type: "number", required: true };
233
- if (typeof typeExpr.value === "boolean")
234
- return { type: "boolean", required: true };
235
- return { type: "null", required: true };
236
- case "objectType": {
237
- // v0.3.3: Inline object type - expand to fields
238
- const objectFields = {};
239
- for (const field of typeExpr.fields) {
240
- const fieldSpec = typeExprToFieldSpec(field.typeExpr, ctx);
241
- objectFields[field.name] = {
242
- ...fieldSpec,
243
- required: !field.optional,
244
- };
245
- }
246
- return {
247
- type: "object",
248
- required: true,
249
- fields: objectFields,
250
- };
251
- }
252
- }
253
- }
254
- /**
255
- * Simple type extraction (for backward compat with action input specs)
256
- */
257
- function typeExprToFieldType(typeExpr, ctx) {
258
- const spec = typeExprToFieldSpec(typeExpr, ctx);
259
- return spec.type;
260
- }
261
- function evaluateInitializer(expr, ctx) {
262
- // Only evaluate literals and simple expressions for default values
263
- switch (expr.kind) {
264
- case "literal":
265
- return expr.value;
266
- case "arrayLiteral":
267
- return expr.elements.map(e => evaluateInitializer(e, ctx));
268
- case "objectLiteral": {
269
- const obj = {};
270
- for (const prop of expr.properties) {
271
- obj[prop.key] = evaluateInitializer(prop.value, ctx);
272
- }
273
- return obj;
274
- }
275
- default:
276
- // Complex expressions can't be evaluated statically
277
- return undefined;
278
- }
279
- }
280
- // ============ Computed Generation ============
281
- function generateComputed(domain, ctx) {
282
- const fields = {};
283
- for (const member of domain.members) {
284
- if (member.kind === "computed") {
285
- const expr = generateExpr(member.expression, ctx);
286
- const deps = extractDeps(expr);
287
- fields[`computed.${member.name}`] = {
288
- deps,
289
- expr,
290
- };
291
- }
292
- }
293
- return { fields };
294
- }
295
- function extractDeps(expr) {
296
- const deps = new Set();
297
- function visit(node) {
298
- if (node.kind === "get") {
299
- deps.add(node.path);
300
- }
301
- else {
302
- // Visit all nested expressions
303
- for (const value of Object.values(node)) {
304
- if (typeof value === "object" && value !== null) {
305
- if (Array.isArray(value)) {
306
- for (const item of value) {
307
- if (typeof item === "object" && item !== null && "kind" in item) {
308
- visit(item);
309
- }
310
- }
311
- }
312
- else if ("kind" in value) {
313
- visit(value);
314
- }
315
- }
316
- }
317
- }
318
- }
319
- visit(expr);
320
- return Array.from(deps);
321
- }
322
- // ============ Action Generation ============
323
- function generateActions(domain, ctx) {
324
- const actions = {};
325
- for (const member of domain.members) {
326
- if (member.kind === "action") {
327
- ctx.currentAction = member.name;
328
- ctx.onceIntentCounters.set(member.name, 0);
329
- // Collect params
330
- const params = new Set();
331
- for (const param of member.params) {
332
- params.add(param.name);
333
- }
334
- ctx.actionParams.set(member.name, params);
335
- const flow = generateFlow(member.body, ctx);
336
- // Generate input spec if there are params
337
- let input;
338
- if (member.params.length > 0) {
339
- const inputFields = {};
340
- for (const param of member.params) {
341
- const fieldSpec = typeExprToFieldSpec(param.typeExpr, ctx);
342
- const inputField = {
343
- type: fieldSpec.type,
344
- required: fieldSpec.required ?? true,
345
- };
346
- if (fieldSpec.type === "object" && fieldSpec.fields) {
347
- inputField.fields = fieldSpec.fields;
348
- }
349
- if (fieldSpec.type === "array" && fieldSpec.items) {
350
- inputField.items = fieldSpec.items;
351
- }
352
- inputFields[param.name] = inputField;
353
- }
354
- input = {
355
- type: "object",
356
- required: true,
357
- fields: inputFields,
358
- };
359
- }
360
- // v0.3.2: Generate available condition if present
361
- let available;
362
- if (member.available) {
363
- available = generateExpr(member.available, ctx);
364
- }
365
- actions[member.name] = {
366
- flow,
367
- input,
368
- available,
369
- };
370
- ctx.currentAction = null;
371
- }
372
- }
373
- return actions;
374
- }
375
- function generateFlow(stmts, ctx) {
376
- if (stmts.length === 0) {
377
- return { kind: "seq", steps: [] };
378
- }
379
- if (stmts.length === 1) {
380
- return generateStmt(stmts[0], ctx);
381
- }
382
- return {
383
- kind: "seq",
384
- steps: stmts.map(s => generateStmt(s, ctx)),
385
- };
386
- }
387
- function generateStmt(stmt, ctx) {
388
- switch (stmt.kind) {
389
- case "when":
390
- return generateWhen(stmt, ctx);
391
- case "once":
392
- return generateOnce(stmt, ctx);
393
- case "onceIntent":
394
- return generateOnceIntent(stmt, ctx);
395
- case "patch":
396
- return generatePatch(stmt, ctx);
397
- case "effect":
398
- return generateEffect(stmt, ctx);
399
- case "fail":
400
- return generateFail(stmt, ctx);
401
- case "stop":
402
- return generateStop(stmt, ctx);
403
- }
404
- }
405
- function generateWhen(stmt, ctx) {
406
- const cond = generateExpr(stmt.condition, ctx);
407
- const thenFlow = generateFlow(stmt.body, ctx);
408
- return {
409
- kind: "if",
410
- cond,
411
- then: thenFlow,
412
- };
413
- }
414
- function generateOnce(stmt, ctx) {
415
- // Desugar once(marker) { ... } to:
416
- // when neq(marker, $meta.intentId) { patch marker = $meta.intentId; ... }
417
- // Note: Core accesses $meta intent values via meta.*
418
- const markerPath = generatePath(stmt.marker, ctx);
419
- const intentIdExpr = { kind: "get", path: "meta.intentId" };
420
- // Condition: marker != $meta.intentId
421
- let cond = {
422
- kind: "neq",
423
- left: { kind: "get", path: markerPath },
424
- right: intentIdExpr,
425
- };
426
- // Add extra condition if present
427
- if (stmt.condition) {
428
- const extraCond = generateExpr(stmt.condition, ctx);
429
- cond = {
430
- kind: "and",
431
- args: [cond, extraCond],
432
- };
433
- }
434
- // Body: patch marker = $meta.intentId, then rest
435
- const markerPatch = {
436
- kind: "patch",
437
- op: "set",
438
- path: markerPath,
439
- value: intentIdExpr,
440
- };
441
- const bodySteps = stmt.body.map(s => generateStmt(s, ctx));
442
- return {
443
- kind: "if",
444
- cond,
445
- then: {
446
- kind: "seq",
447
- steps: [markerPatch, ...bodySteps],
448
- },
449
- };
450
- }
451
- function generateOnceIntent(stmt, ctx) {
452
- const actionName = ctx.currentAction ?? "unknown";
453
- const nextIndex = ctx.onceIntentCounters.get(actionName) ?? 0;
454
- ctx.onceIntentCounters.set(actionName, nextIndex + 1);
455
- const guardId = sha256Sync(`${actionName}:${nextIndex}:intent`);
456
- const guardPath = `$mel.guards.intent.${guardId}`;
457
- const intentIdExpr = { kind: "get", path: "meta.intentId" };
458
- let cond = {
459
- kind: "neq",
460
- left: { kind: "get", path: guardPath },
461
- right: intentIdExpr,
462
- };
463
- if (stmt.condition) {
464
- const extraCond = generateExpr(stmt.condition, ctx);
465
- cond = {
466
- kind: "and",
467
- args: [cond, extraCond],
468
- };
469
- }
470
- // Guard write: semantic target is guardPath, lowered as map-level merge.
471
- const markerPatch = {
472
- kind: "patch",
473
- op: "merge",
474
- path: "$mel.guards.intent",
475
- value: {
476
- kind: "object",
477
- fields: { [guardId]: intentIdExpr },
478
- },
479
- };
480
- const bodySteps = stmt.body.map(s => generateStmt(s, ctx));
481
- return {
482
- kind: "if",
483
- cond,
484
- then: {
485
- kind: "seq",
486
- steps: [markerPatch, ...bodySteps],
487
- },
488
- };
489
- }
490
- function generatePatch(stmt, ctx) {
491
- const path = generatePath(stmt.path, ctx);
492
- const result = {
493
- kind: "patch",
494
- op: stmt.op,
495
- path,
496
- };
497
- if (stmt.value) {
498
- result.value = generateExpr(stmt.value, ctx);
499
- }
500
- return result;
501
- }
502
- function generateEffect(stmt, ctx) {
503
- const params = {};
504
- for (const arg of stmt.args) {
505
- if (arg.isPath) {
506
- // Path arguments like into:, pass:, fail:
507
- params[arg.name] = { kind: "lit", value: generatePath(arg.value, ctx) };
508
- }
509
- else {
510
- params[arg.name] = generateExpr(arg.value, ctx);
511
- }
512
- }
513
- return {
514
- kind: "effect",
515
- type: stmt.effectType,
516
- params,
517
- };
518
- }
519
- /**
520
- * v0.3.2: Generate fail statement
521
- * fail "CODE" with expr → { kind: "fail", code, message? }
522
- */
523
- function generateFail(stmt, ctx) {
524
- const result = {
525
- kind: "fail",
526
- code: stmt.code,
527
- };
528
- if (stmt.message) {
529
- result.message = generateExpr(stmt.message, ctx);
530
- }
531
- return result;
532
- }
533
- /**
534
- * v0.3.2: Generate stop statement
535
- * stop "reason" → { kind: "halt", reason }
536
- */
537
- function generateStop(stmt, ctx) {
538
- return {
539
- kind: "halt",
540
- reason: stmt.reason,
541
- };
542
- }
543
- // ============ Path Generation ============
544
- function generatePath(path, ctx) {
545
- const segments = [];
546
- for (const segment of path.segments) {
547
- if (segment.kind === "propertySegment") {
548
- segments.push(segment.name);
549
- }
550
- else {
551
- // Index segment - for now, stringify the index
552
- // In reality, this would need runtime evaluation
553
- const indexExpr = generateExpr(segment.index, ctx);
554
- if (indexExpr.kind === "lit") {
555
- segments.push(String(indexExpr.value));
556
- }
557
- else {
558
- // Dynamic index - use placeholder
559
- segments.push("*");
560
- }
561
- }
562
- }
563
- // Determine prefix based on first segment
564
- const first = segments[0];
565
- if (ctx.stateFields.has(first)) {
566
- // Core expects state paths without prefix (e.g., "count" not "data.count")
567
- return segments.join(".");
568
- }
569
- if (ctx.computedFields.has(first)) {
570
- return `computed.${segments.join(".")}`;
571
- }
572
- if (ctx.currentAction && ctx.actionParams.get(ctx.currentAction)?.has(first)) {
573
- return `input.${segments.join(".")}`;
574
- }
575
- // Default to plain path (state-like)
576
- return segments.join(".");
577
- }
578
- // ============ Expression Generation ============
579
- function generateExpr(expr, ctx) {
580
- switch (expr.kind) {
581
- case "literal":
582
- return { kind: "lit", value: expr.value };
583
- case "identifier":
584
- return generateIdentifier(expr.name, ctx);
585
- case "systemIdent":
586
- return generateSystemIdent(expr.path, ctx);
587
- case "iterationVar":
588
- // v0.3.2: $item only (reduce pattern deprecated, $acc removed)
589
- // $item is used in filter/map expressions
590
- return { kind: "get", path: `$${expr.name}` };
591
- case "propertyAccess":
592
- return generatePropertyAccess(expr, ctx);
593
- case "indexAccess":
594
- return {
595
- kind: "at",
596
- array: generateExpr(expr.object, ctx),
597
- index: generateExpr(expr.index, ctx),
598
- };
599
- case "functionCall":
600
- return normalizeFunctionCall(expr.name, expr.args.map(a => generateExpr(a, ctx)));
601
- case "binary":
602
- return normalizeExpr(expr.operator, generateExpr(expr.left, ctx), generateExpr(expr.right, ctx));
603
- case "unary":
604
- if (expr.operator === "!") {
605
- return { kind: "not", arg: generateExpr(expr.operand, ctx) };
606
- }
607
- else {
608
- return { kind: "neg", arg: generateExpr(expr.operand, ctx) };
609
- }
610
- case "ternary":
611
- return {
612
- kind: "if",
613
- cond: generateExpr(expr.condition, ctx),
614
- then: generateExpr(expr.consequent, ctx),
615
- else: generateExpr(expr.alternate, ctx),
616
- };
617
- case "objectLiteral": {
618
- const fields = {};
619
- for (const prop of expr.properties) {
620
- fields[prop.key] = generateExpr(prop.value, ctx);
621
- }
622
- return { kind: "object", fields };
623
- }
624
- case "arrayLiteral":
625
- // For array literals, we build using append
626
- if (expr.elements.length === 0) {
627
- return { kind: "lit", value: [] };
628
- }
629
- // Check if all elements are literals
630
- const allLiterals = expr.elements.every(e => e.kind === "literal");
631
- if (allLiterals) {
632
- return { kind: "lit", value: expr.elements.map(e => e.value) };
633
- }
634
- // Otherwise use append
635
- return {
636
- kind: "append",
637
- array: { kind: "lit", value: [] },
638
- items: expr.elements.map(e => generateExpr(e, ctx)),
639
- };
640
- }
641
- }
642
- function generateIdentifier(name, ctx) {
643
- // Resolve identifier to path
644
- if (ctx.stateFields.has(name)) {
645
- // Core expects state paths without prefix (e.g., "count" not "data.count")
646
- return { kind: "get", path: name };
647
- }
648
- if (ctx.computedFields.has(name)) {
649
- return { kind: "get", path: `computed.${name}` };
650
- }
651
- if (ctx.currentAction && ctx.actionParams.get(ctx.currentAction)?.has(name)) {
652
- return { kind: "get", path: `input.${name}` };
653
- }
654
- // Unknown identifier - report error and default to plain path
655
- ctx.diagnostics.push({
656
- severity: "error",
657
- code: "E_UNKNOWN_IDENT",
658
- message: `Unknown identifier '${name}'`,
659
- location: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
660
- });
661
- return { kind: "get", path: name };
662
- }
663
- function generateSystemIdent(path, ctx) {
664
- // $system.uuid -> will be lowered later
665
- // $meta.intentId -> meta.intentId
666
- // $input.* -> input.*
667
- const [namespace, ...rest] = path;
668
- switch (namespace) {
669
- case "system":
670
- // $system values are placeholders - will be lowered in the lowering pass
671
- return { kind: "get", path: `$system.${rest.join(".")}` };
672
- case "meta":
673
- return { kind: "get", path: `meta.${rest.join(".")}` };
674
- case "input":
675
- return { kind: "get", path: `input.${rest.join(".")}` };
676
- default:
677
- ctx.diagnostics.push({
678
- severity: "error",
679
- code: "E_INVALID_SYSTEM",
680
- message: `Invalid system identifier namespace '$${namespace}'`,
681
- location: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
682
- });
683
- return { kind: "lit", value: null };
684
- }
685
- }
686
- function generatePropertyAccess(expr, ctx) {
687
- // Handle chained property access
688
- const objectExpr = generateExpr(expr.object, ctx);
689
- // If the object is a get expression, we can extend the path
690
- if (objectExpr.kind === "get") {
691
- return { kind: "get", path: `${objectExpr.path}.${expr.property}` };
692
- }
693
- // Static member access: use field() to access a known property on a computed object.
694
- // This is semantically distinct from at() (array indexing) and get() (snapshot path lookup).
695
- return {
696
- kind: "field",
697
- object: objectExpr,
698
- property: expr.property,
699
- };
700
- }
701
- // ============ Hash Computation ============
702
- /**
703
- * Compute schema hash using browser-compatible SHA-256.
704
- * Uses @manifesto-ai/core's sha256Sync for universal compatibility.
705
- */
706
- function computeHash(schema) {
707
- return hashSchemaSync(schema);
708
- }
709
- //# sourceMappingURL=ir.js.map