@json-schema-engine/compiler 0.0.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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/emit.d.ts +52 -0
  4. package/dist/emit.d.ts.map +1 -0
  5. package/dist/emit.js +166 -0
  6. package/dist/emit.js.map +1 -0
  7. package/dist/explain.d.ts +28 -0
  8. package/dist/explain.d.ts.map +1 -0
  9. package/dist/explain.js +42 -0
  10. package/dist/explain.js.map +1 -0
  11. package/dist/index.d.ts +132 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +169 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/plan.d.ts +83 -0
  16. package/dist/plan.d.ts.map +1 -0
  17. package/dist/plan.js +385 -0
  18. package/dist/plan.js.map +1 -0
  19. package/dist/runtime-compile.d.ts +30 -0
  20. package/dist/runtime-compile.d.ts.map +1 -0
  21. package/dist/runtime-compile.js +29 -0
  22. package/dist/runtime-compile.js.map +1 -0
  23. package/dist/runtime.d.ts +157 -0
  24. package/dist/runtime.d.ts.map +1 -0
  25. package/dist/runtime.js +336 -0
  26. package/dist/runtime.js.map +1 -0
  27. package/dist/serialize/apply.d.ts +28 -0
  28. package/dist/serialize/apply.d.ts.map +1 -0
  29. package/dist/serialize/apply.js +211 -0
  30. package/dist/serialize/apply.js.map +1 -0
  31. package/dist/serialize/context.d.ts +143 -0
  32. package/dist/serialize/context.d.ts.map +1 -0
  33. package/dist/serialize/context.js +93 -0
  34. package/dist/serialize/context.js.map +1 -0
  35. package/dist/serialize/expressions.d.ts +7 -0
  36. package/dist/serialize/expressions.d.ts.map +1 -0
  37. package/dist/serialize/expressions.js +177 -0
  38. package/dist/serialize/expressions.js.map +1 -0
  39. package/dist/serialize/guards.d.ts +7 -0
  40. package/dist/serialize/guards.d.ts.map +1 -0
  41. package/dist/serialize/guards.js +19 -0
  42. package/dist/serialize/guards.js.map +1 -0
  43. package/dist/serialize/index.d.ts +7 -0
  44. package/dist/serialize/index.d.ts.map +1 -0
  45. package/dist/serialize/index.js +266 -0
  46. package/dist/serialize/index.js.map +1 -0
  47. package/dist/serialize/keywords.d.ts +32 -0
  48. package/dist/serialize/keywords.d.ts.map +1 -0
  49. package/dist/serialize/keywords.js +131 -0
  50. package/dist/serialize/keywords.js.map +1 -0
  51. package/dist/serialize/messages.d.ts +36 -0
  52. package/dist/serialize/messages.d.ts.map +1 -0
  53. package/dist/serialize/messages.js +100 -0
  54. package/dist/serialize/messages.js.map +1 -0
  55. package/dist/serialize/names.d.ts +47 -0
  56. package/dist/serialize/names.d.ts.map +1 -0
  57. package/dist/serialize/names.js +115 -0
  58. package/dist/serialize/names.js.map +1 -0
  59. package/dist/serialize/spans.d.ts +34 -0
  60. package/dist/serialize/spans.d.ts.map +1 -0
  61. package/dist/serialize/spans.js +61 -0
  62. package/dist/serialize/spans.js.map +1 -0
  63. package/dist/serialize/statements.d.ts +16 -0
  64. package/dist/serialize/statements.d.ts.map +1 -0
  65. package/dist/serialize/statements.js +396 -0
  66. package/dist/serialize/statements.js.map +1 -0
  67. package/dist/serialize/unit.d.ts +8 -0
  68. package/dist/serialize/unit.d.ts.map +1 -0
  69. package/dist/serialize/unit.js +107 -0
  70. package/dist/serialize/unit.js.map +1 -0
  71. package/dist/standalone.d.ts +24 -0
  72. package/dist/standalone.d.ts.map +1 -0
  73. package/dist/standalone.js +166 -0
  74. package/dist/standalone.js.map +1 -0
  75. package/package.json +38 -0
  76. package/src/emit.ts +196 -0
  77. package/src/explain.ts +67 -0
  78. package/src/index.ts +366 -0
  79. package/src/plan.ts +496 -0
  80. package/src/runtime-compile.ts +90 -0
  81. package/src/runtime.ts +599 -0
  82. package/src/serialize/apply.ts +251 -0
  83. package/src/serialize/context.ts +161 -0
  84. package/src/serialize/expressions.ts +202 -0
  85. package/src/serialize/guards.ts +20 -0
  86. package/src/serialize/index.ts +432 -0
  87. package/src/serialize/keywords.ts +144 -0
  88. package/src/serialize/messages.ts +120 -0
  89. package/src/serialize/names.ts +136 -0
  90. package/src/serialize/spans.ts +88 -0
  91. package/src/serialize/statements.ts +531 -0
  92. package/src/serialize/unit.ts +118 -0
  93. package/src/standalone.ts +187 -0
@@ -0,0 +1,396 @@
1
+ // LowerStmt rendering: the per-keyword statement list with its grouped
2
+ // anyOf/oneOf runs, every statement kind, and the apply folds.
3
+ import { id, join, js, num, json } from "../emit.js";
4
+ import { EV, bindingVar, counterVar, foldVar } from "./names.js";
5
+ import { SerializeError } from "./context.js";
6
+ import { renderMessage, paramsChunk, pushError, errMark, errsLength, errsCut, } from "./messages.js";
7
+ import { channelSpans, spanDecls, spanResets, branchSpan, annsLength, annsCut, annsPush, } from "./spans.js";
8
+ import { annUnit, annRecordSegment, produceChannel } from "./keywords.js";
9
+ import { expr } from "./expressions.js";
10
+ import { applyCall, tryInline } from "./apply.js";
11
+ /**
12
+ * Serialize one keyword's statement list. Runs of anyMayPass applies
13
+ * (the anyOf shape) group into a single OR check; short-circuit emission
14
+ * is licensed here because the planner interpreted every node whose
15
+ * channel a consumer could observe (slice licensing, DESIGN §7). Runs of
16
+ * exactlyOne applies (the oneOf shape) group into a counter block that
17
+ * runs EVERY branch — never stop-at-first-success, since the count past 1
18
+ * must still be exact.
19
+ */
20
+ export function keywordStatements(ctx, stmts) {
21
+ const out = [];
22
+ let anyRun = [];
23
+ let oneRun = [];
24
+ const flushAny = (message, params) => {
25
+ if (anyRun.length === 0)
26
+ return;
27
+ if (ctx.output === "list") {
28
+ // Every branch runs (§7: list artifacts never short-circuit), each
29
+ // marking/truncating its channel spans (branchSpan). An accepting
30
+ // run drops every branch's errors (errMark).
31
+ const a = counterVar(ctx.counters.tally++);
32
+ const em = errMark(ctx);
33
+ const runs = anyRun.map((call) => branchSpan(ctx, call, js `${a} = true;`));
34
+ const onFail = pushError(ctx, renderMessage(ctx, message ?? ["no branch matched"]), true, paramsChunk(ctx, params));
35
+ out.push(js `let ${a} = false; const ${em} = ${errsLength(ctx)}; ${join(" ", runs)} if (${a}) { ${errsCut(ctx, em)} } else { ${onFail} }`);
36
+ }
37
+ else if (ctx.regionMode) {
38
+ // Every branch runs (no short-circuit — a later branch's success
39
+ // contributes coverage the interpreter would merge), each marking and
40
+ // truncating its own channel span (rule 2). Flag failure on no match.
41
+ const a = counterVar(ctx.counters.tally++);
42
+ const runs = anyRun.map((call) => branchSpan(ctx, call, js `${a} = true;`));
43
+ out.push(js `let ${a} = false; ${join(" ", runs)} if (!${a}) return false;`);
44
+ }
45
+ else {
46
+ out.push(js `if (!(${join(" || ", anyRun)})) return false;`);
47
+ }
48
+ anyRun = [];
49
+ };
50
+ const flushOne = (message, params) => {
51
+ if (oneRun.length === 0)
52
+ return;
53
+ const c = counterVar(ctx.counters.tally++);
54
+ if (ctx.output === "list") {
55
+ // Params referencing the passing-branch indexes (tallyList) need an
56
+ // index accumulator next to the count; branch order IS run order.
57
+ // Both-pass discards at the caller (the unit fails, its span
58
+ // truncates); each branch marks/truncates its own spans here.
59
+ const wantsList = ctx.listParams &&
60
+ params !== undefined &&
61
+ Object.values(params).some((p) => p.kind === "tallyList");
62
+ const p = wantsList ? counterVar(ctx.counters.tally++) : undefined;
63
+ const incs = oneRun.map((call, k) => branchSpan(ctx, call, p ? js `${c}++; ${p}.push(${num(k)});` : js `${c}++;`));
64
+ const decl = p ? js `let ${c} = 0; const ${p} = [];` : js `let ${c} = 0;`;
65
+ const onFail = pushError(ctx, renderMessage(ctx, message ?? [{ kind: "tally" }, " branches matched"], c), true, paramsChunk(ctx, params, c, p));
66
+ const em = errMark(ctx);
67
+ out.push(js `${decl} const ${em} = ${errsLength(ctx)}; ${join(" ", incs)} if (${c} === 1) { ${errsCut(ctx, em)} } else { ${onFail} }`);
68
+ }
69
+ else if (ctx.regionMode) {
70
+ // Run every branch with a per-branch mark/truncate (rule 2): a passing
71
+ // branch's coverage merges, a failing branch's truncates. On a non-unit
72
+ // count the unit fails and the caller truncates the whole span.
73
+ const incs = oneRun.map((call) => branchSpan(ctx, call, js `${c}++;`));
74
+ out.push(js `let ${c} = 0; ${join(" ", incs)} if (${c} !== 1) return false;`);
75
+ }
76
+ else {
77
+ const incs = oneRun.map((call) => js `if (${call}) ${c}++;`);
78
+ out.push(js `let ${c} = 0; ${join(" ", incs)} if (${c} !== 1) return false;`);
79
+ }
80
+ oneRun = [];
81
+ };
82
+ for (const stmt of stmts) {
83
+ if (stmt.kind === "apply" && stmt.apply.fold === "anyMayPass") {
84
+ flushOne();
85
+ anyRun.push(applyCall(ctx, stmt.apply));
86
+ continue;
87
+ }
88
+ if (stmt.kind === "apply" && stmt.apply.fold === "exactlyOne") {
89
+ flushAny();
90
+ oneRun.push(applyCall(ctx, stmt.apply));
91
+ continue;
92
+ }
93
+ if (stmt.kind === "combineCheck") {
94
+ // Closes the pending run with the keyword's own failure message.
95
+ flushAny(stmt.message, stmt.params);
96
+ flushOne(stmt.message, stmt.params);
97
+ continue;
98
+ }
99
+ flushAny();
100
+ flushOne();
101
+ out.push(statement(ctx, stmt));
102
+ }
103
+ flushAny();
104
+ flushOne();
105
+ return out;
106
+ }
107
+ /** An `if` statement; an applyExpr condition is hoisted so its channel spans and error mark bracket the call. */
108
+ function emitIf(ctx, stmt) {
109
+ // `if`'s condition IS a bare applyExpr (the only such shape besides
110
+ // contains' probe): hoist the call so its span marks/truncates before
111
+ // the branch reads the verdict. Any other applyExpr position throws in
112
+ // annotation mode (expr()), so no silent annotation loss.
113
+ if ((ctx.annMode || ctx.regionMode || ctx.output === "list") &&
114
+ stmt.cond.kind === "applyExpr") {
115
+ // `if`'s condition is in-place: hoist the call so its channel spans
116
+ // mark/truncate on the condition verdict (a passing condition's
117
+ // coverage merges, a failing one's — with the else taken — truncates;
118
+ // rule 4). ann marks `anns`, region marks `ev`, composed both. The
119
+ // condition's errors are always irrelevant (`if` accepts regardless
120
+ // of its subschema), so list mode truncates them unconditionally.
121
+ const spans = channelSpans(ctx);
122
+ const t = id("m" + String(ctx.counters.temp++));
123
+ const em = errMark(ctx);
124
+ const call = applyCall(ctx, stmt.cond.apply);
125
+ const errDecl = em ? js `const ${em} = ${errsLength(ctx)}; ` : js ``;
126
+ const errReset = em ? js ` ${errsCut(ctx, em)}` : js ``;
127
+ const resets = spans.length > 0 ? js ` if (!${t}) { ${spanResets(ctx, spans)} }` : js ``;
128
+ const head = js `${spanDecls(ctx, spans)} ${errDecl}const ${t} = ${call};${errReset}${resets}`;
129
+ const thenBody = join("\n", stmt.then.map((s) => statement(ctx, s)));
130
+ if (!stmt.else)
131
+ return js `${head} if (${t}) { ${thenBody} }`;
132
+ const elseBody = join("\n", stmt.else.map((s) => statement(ctx, s)));
133
+ return js `${head} if (${t}) { ${thenBody} } else { ${elseBody} }`;
134
+ }
135
+ const thenBody = join("\n", stmt.then.map((s) => statement(ctx, s)));
136
+ const cond = js `if (${expr(ctx, stmt.cond)}) { ${thenBody} }`;
137
+ if (!stmt.else)
138
+ return cond;
139
+ const elseBody = join("\n", stmt.else.map((s) => statement(ctx, s)));
140
+ return js `${cond} else { ${elseBody} }`;
141
+ }
142
+ /** A sweep over an object's own keys (plain for-in under the plain-data contract). */
143
+ function emitForEachKey(ctx, stmt) {
144
+ const b = bindingVar(stmt.binding);
145
+ const body = join("\n", stmt.body.map((s) => statement(ctx, s)));
146
+ // Plain for-in: under the plain-data instance contract (DESIGN §7)
147
+ // instances carry no inherited enumerables, so for-in ≡ Object.keys
148
+ // without the per-validation array allocation.
149
+ const t = expr(ctx, stmt.target);
150
+ if (ctx.flags.plainData) {
151
+ return js `for (const ${b} in ${t}) { ${body} }`;
152
+ }
153
+ return js `for (const ${b} of Object.keys(${t})) { ${body} }`;
154
+ }
155
+ /** A sweep over an array's indexes. */
156
+ function emitForEachIndex(ctx, stmt) {
157
+ const b = bindingVar(stmt.binding);
158
+ const body = join("\n", stmt.body.map((s) => statement(ctx, s)));
159
+ return js `for (let ${b} = ${num(stmt.start ?? 0)}; ${b} < ${expr(ctx, stmt.target)}.length; ${b}++) { ${body} }`;
160
+ }
161
+ /** A keyword failure: an error unit in list mode, fail-fast in flag mode. */
162
+ function emitFail(ctx, stmt) {
163
+ if (ctx.output === "list") {
164
+ return pushError(ctx, renderMessage(ctx, stmt.message), true, paramsChunk(ctx, stmt.params));
165
+ }
166
+ // Flag mode: verdict-only, fail fast.
167
+ return js `return false;`;
168
+ }
169
+ /** The keyword's own value as an annotation unit (annotation mode only). */
170
+ function emitAnnotate(ctx, _stmt) {
171
+ // Annotation mode records the keyword's own value as a unit; every
172
+ // other mode elides. The value is a schema constant (draft-03 §12.9).
173
+ if (!ctx.annMode || !ctx.annKwKept)
174
+ return js ``;
175
+ const value = ctx.unit.ref.node[ctx.currentKeyword];
176
+ return annsPush(ctx, annUnit(ctx, json(value)));
177
+ }
178
+ /** A consumed producer's dependency data onto the coverage channel (region mode only). */
179
+ function emitProduce(ctx, stmt) {
180
+ // Region mode pushes a consumed producer's dependency data onto the
181
+ // channel (rule 5); dependency data is never an annotation unit. In
182
+ // list mode the push waits on the keyword's own verdict (kwOk).
183
+ if (!ctx.covKwKept)
184
+ return js ``;
185
+ const push = produceChannel(ctx, stmt.value);
186
+ return ctx.kwOk ? js `if (${ctx.kwOk}) { ${push} }` : push;
187
+ }
188
+ /** Bind the channel fold a following coverageCovers reads (region mode only). */
189
+ function emitCoverageFold(ctx, stmt) {
190
+ // Bind the channel fold a following coverageCovers reads (rule 6). Only
191
+ // a tracked unit's consumer emits this, and only in region mode.
192
+ if (!ctx.regionMode) {
193
+ throw new SerializeError("coverageFold requires region emission (phase B)");
194
+ }
195
+ const f = foldVar(ctx.counters.temp++);
196
+ ctx.coverageFolds.set(stmt.binding, { var: f, half: stmt.half });
197
+ if (stmt.half === "names") {
198
+ return js `const ${f} = ${id("h_covN")}(${EV});`;
199
+ }
200
+ // indexes: fold over the current instance array's length (the enclosing
201
+ // lower() guards this with an array-type test).
202
+ return js `const ${f} = ${id("h_covI")}(${EV}, ${ctx.valueVar}.length);`;
203
+ }
204
+ /** The contains shape: count matching items, then check the range; the probe's spans and the loop's error mark follow the mode. */
205
+ function emitCountRange(ctx, stmt) {
206
+ const b = bindingVar(stmt.binding);
207
+ const c = counterVar(ctx.counters.tally++);
208
+ const max = Number.isFinite(stmt.max) ? num(stmt.max) : null;
209
+ const outOfRange = max === null
210
+ ? js `${c} < ${num(stmt.min)}`
211
+ : js `${c} < ${num(stmt.min)} || ${c} > ${max}`;
212
+ const onFail = ctx.output === "list"
213
+ ? pushError(ctx, renderMessage(ctx, stmt.outOfRangeMessage, c), true, paramsChunk(ctx, stmt.outOfRangeParams, c))
214
+ : js `return false;`;
215
+ // List mode: an accepting contains drops every probe's errors, a
216
+ // rejecting one keeps them (§12.2) — one mark around the whole loop,
217
+ // never per probe.
218
+ const em = errMark(ctx);
219
+ const errDecl = em ? js `const ${em} = ${errsLength(ctx)}; ` : js ``;
220
+ const check = em
221
+ ? js `if (${outOfRange}) { ${onFail} } else { ${errsCut(ctx, em)} }`
222
+ : js `if (${outOfRange}) { ${onFail} }`;
223
+ // contains' probe IS a bare applyExpr (the only shape besides `if`'s
224
+ // condition): mark/truncate each probe so a matching item's
225
+ // annotations merge and a failing item's discard. collectIndexes feeds
226
+ // the matched-index accumulator the following produce renders.
227
+ if (ctx.annMode && stmt.countWhen.kind === "applyExpr") {
228
+ const probe = applyCall(ctx, stmt.countWhen.apply);
229
+ const m = id("m" + String(ctx.counters.temp++));
230
+ const pushIdx = ctx.annKw?.matched && stmt.collectIndexes
231
+ ? js ` ${ctx.annKw.matched}.push(${b});`
232
+ : js ``;
233
+ const loop = js `${errDecl}let ${c} = 0; for (let ${b} = 0; ${b} < ${expr(ctx, stmt.target)}.length; ${b}++) { const ${m} = ${annsLength(ctx)}; if (${probe}) { ${c}++;${pushIdx} } else ${annsCut(ctx, m)} }`;
234
+ return js `${loop} ${check}`;
235
+ }
236
+ if (ctx.regionMode && stmt.countWhen.kind === "applyExpr") {
237
+ // The probe is a CHILD-cursor apply (a plain call that never receives
238
+ // `ev`), so there is no channel span to mark here — `contains`'
239
+ // coverage reaches the channel only through its matched-index produce
240
+ // (rule 5). Accumulate the matched indexes for that produce.
241
+ const probe = applyCall(ctx, stmt.countWhen.apply);
242
+ const pushIdx = ctx.annKw?.matched && stmt.collectIndexes
243
+ ? js ` ${ctx.annKw.matched}.push(${b});`
244
+ : js ``;
245
+ const loop = js `${errDecl}let ${c} = 0; for (let ${b} = 0; ${b} < ${expr(ctx, stmt.target)}.length; ${b}++) { if (${probe}) { ${c}++;${pushIdx} } }`;
246
+ return js `${loop} ${check}`;
247
+ }
248
+ const loop = js `${errDecl}let ${c} = 0; for (let ${b} = 0; ${b} < ${expr(ctx, stmt.target)}.length; ${b}++) { if (${expr(ctx, stmt.countWhen)}) ${c}++; }`;
249
+ return js `${loop} ${check}`;
250
+ }
251
+ export function statement(ctx, stmt) {
252
+ switch (stmt.kind) {
253
+ case "if":
254
+ return emitIf(ctx, stmt);
255
+ case "forEachKey":
256
+ return emitForEachKey(ctx, stmt);
257
+ case "forEachIndex":
258
+ return emitForEachIndex(ctx, stmt);
259
+ case "fail":
260
+ return emitFail(ctx, stmt);
261
+ case "annotate":
262
+ return emitAnnotate(ctx, stmt);
263
+ case "produce":
264
+ return emitProduce(ctx, stmt);
265
+ case "coverageFold":
266
+ return emitCoverageFold(ctx, stmt);
267
+ case "apply":
268
+ return applyStatement(ctx, stmt.apply);
269
+ case "combineCheck":
270
+ throw new SerializeError("combineCheck must directly follow its anyMayPass/exactlyOne run");
271
+ case "countRange":
272
+ return emitCountRange(ctx, stmt);
273
+ }
274
+ }
275
+ /** List-mode conjunct and negation folds (null for the grouped folds). */
276
+ function emitListApply(ctx, apply, call, evSpan) {
277
+ switch (apply.fold) {
278
+ case "allMustPass": {
279
+ // Record the attempted segment (before the verdict) for the
280
+ // keyword's produce accumulator, then mark the channel spans so a
281
+ // failing application's annotations (annMode) and coverage (region
282
+ // emission) truncate — its errors stay (the keyword rejects), and
283
+ // list mode CONTINUES on failure (ok = false, no return): the
284
+ // unit's remaining keywords, including a consumer sweep that now
285
+ // covers less, still run.
286
+ const rec = annRecordSegment(ctx, apply.cursor);
287
+ const pre = rec ? js `${rec} ` : js ``;
288
+ // A driven sibling's application (`then`/`else` under `if`) fails that
289
+ // sibling's own verdict, as the interpreter reports it.
290
+ const slot = ctx.trace && apply.sibling !== undefined
291
+ ? (ctx.kwVerdicts.get(apply.sibling) ?? null)
292
+ : ctx.kwOk;
293
+ const fail = slot ? js `ok = false; ${slot} = false;` : js `ok = false;`;
294
+ const spans = channelSpans(ctx, evSpan);
295
+ if (spans.length === 0)
296
+ return js `${pre}if (!${call}) { ${fail} }`;
297
+ return js `${pre}${spanDecls(ctx, spans)} if (!${call}) { ${fail} ${spanResets(ctx, spans)} }`;
298
+ }
299
+ case "negate": {
300
+ // A failing negated subschema's spans truncate, and so do its
301
+ // errors (`not` accepts, §12.2); a PASSING one's annotations and
302
+ // coverage STAY (the interpreter merges any passing application
303
+ // into the unit frame, and same-unit consumers see it) while the
304
+ // unit records the not-error.
305
+ const spans = channelSpans(ctx, evSpan);
306
+ const em = errMark(ctx);
307
+ const err = pushError(ctx, renderMessage(ctx, apply.message ?? ["must not match the subschema"]), true, paramsChunk(ctx, apply.params));
308
+ return js `${spanDecls(ctx, spans)} const ${em} = ${errsLength(ctx)}; if (${call}) { ${err} } else { ${errsCut(ctx, em)} ${spanResets(ctx, spans)} }`;
309
+ }
310
+ default:
311
+ return null; // grouped folds handled by keywordStatements; discard by applyExpr
312
+ }
313
+ }
314
+ /** Region-mode conjunct and negation folds (null for the grouped folds). */
315
+ function emitRegionApply(ctx, apply, call, evSpan) {
316
+ switch (apply.fold) {
317
+ case "allMustPass": {
318
+ // Record the attempted child segment (before the verdict) for a
319
+ // consumed producer's channel push (rule 5).
320
+ const rec = annRecordSegment(ctx, apply.cursor);
321
+ const pre = rec ? js `${rec} ` : js ``;
322
+ if (call.text === "true")
323
+ return rec ?? js ``;
324
+ if (call.text === "false")
325
+ return js `${pre}return false;`;
326
+ if (evSpan) {
327
+ // In-place conjunct: a failed span truncates and fails the unit;
328
+ // the caller's own span then truncates this whole call (rule 2).
329
+ const m = id("m" + String(ctx.counters.temp++));
330
+ return js `const ${m} = ${EV}.length; if (!${call}) { ${EV}.length = ${m}; return false; }`;
331
+ }
332
+ // Child-cursor conjunct (a swept property/item): no channel span.
333
+ return js `${pre}if (!${call}) return false;`;
334
+ }
335
+ case "negate": {
336
+ if (call.text === "true")
337
+ return js `return false;`;
338
+ if (call.text === "false")
339
+ return js ``;
340
+ // A passing negated subschema dies with the unit (return false → the
341
+ // caller truncates); a failing one truncates its own span (rule 3).
342
+ const m = id("m" + String(ctx.counters.temp++));
343
+ return js `const ${m} = ${EV}.length; if (${call}) return false; ${EV}.length = ${m};`;
344
+ }
345
+ default:
346
+ return null; // grouped folds handled by keywordStatements; discard by applyExpr
347
+ }
348
+ }
349
+ export function applyStatement(ctx, apply) {
350
+ if (apply.fold === "allMustPass") {
351
+ const inlined = tryInline(ctx, apply);
352
+ if (inlined)
353
+ return inlined;
354
+ }
355
+ const call = applyCall(ctx, apply);
356
+ // A call RECEIVES the coverage channel exactly when it is an in-place
357
+ // apply to a non-boolean target (a region variant, or a coverage-
358
+ // harvesting trampoline); a child-cursor apply is a plain call, and a
359
+ // boolean folds to a literal or reports without producing — neither
360
+ // touches the channel, so neither needs an ev mark/truncate span (rule 1).
361
+ const evSpan = ctx.regionMode &&
362
+ apply.cursor.kind === "here" &&
363
+ call.text !== "true" &&
364
+ call.text !== "false";
365
+ if (ctx.output === "list") {
366
+ const folded = emitListApply(ctx, apply, call, evSpan);
367
+ if (folded)
368
+ return folded;
369
+ }
370
+ else if (ctx.regionMode) {
371
+ const folded = emitRegionApply(ctx, apply, call, evSpan);
372
+ if (folded)
373
+ return folded;
374
+ }
375
+ if (apply.fold === "allMustPass" && call.text === "true")
376
+ return js ``;
377
+ if (apply.fold === "allMustPass" && call.text === "false")
378
+ return js `return false;`;
379
+ switch (apply.fold) {
380
+ case "allMustPass":
381
+ return js `if (!${call}) return false;`;
382
+ case "negate":
383
+ return js `if (${call}) return false;`;
384
+ case "anyMayPass":
385
+ case "exactlyOne":
386
+ // keywordStatements groups consecutive runs of these before they
387
+ // reach here (a lone run of one is still a "run").
388
+ throw new SerializeError("fold '" + apply.fold + "' must be grouped by keywordStatements");
389
+ case "discard":
390
+ // A bare discard apply statement has no verdict-folding meaning —
391
+ // it's only legal as an applyExpr operand (the if/contains probe
392
+ // shape), never a standalone statement.
393
+ throw new SerializeError("fold 'discard' is only legal inside applyExpr");
394
+ }
395
+ }
396
+ //# sourceMappingURL=statements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statements.js","sourceRoot":"","sources":["../../src/serialize/statements.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+DAA+D;AAS/D,OAAO,EAAkB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAe,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,aAAa,EACb,WAAW,EACX,SAAS,EACT,OAAO,EACP,UAAU,EACV,OAAO,GACR,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,OAAO,EACP,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAgB,EAChB,KAA2B;IAE3B,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAgB,EAAE,CAAC;IAC7B,IAAI,MAAM,GAAgB,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,CAAC,OAAsB,EAAE,MAAoB,EAAE,EAAE;QAChE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,mEAAmE;YACnE,kEAAkE;YAClE,6CAA6C;YAC7C,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAA,GAAG,CAAC,UAAU,CAAC,CACxC,CAAC;YACF,MAAM,MAAM,GAAG,SAAS,CACtB,GAAG,EACH,aAAa,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,CAAC,EACpD,IAAI,EACJ,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CACzB,CAAC;YACF,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,OAAO,CAAC,mBAAmB,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,MAAM,IAAI,CAChI,CAAC;QACJ,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAC1B,iEAAiE;YACjE,sEAAsE;YACtE,sEAAsE;YACtE,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAA,GAAG,CAAC,UAAU,CAAC,CACxC,CAAC;YACF,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,OAAO,CAAC,aAAa,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAClE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,GAAG,EAAE,CAAC;IACd,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,OAAsB,EAAE,MAAoB,EAAE,EAAE;QAChE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,oEAAoE;YACpE,kEAAkE;YAClE,6DAA6D;YAC7D,8DAA8D;YAC9D,MAAM,SAAS,GACb,GAAG,CAAC,UAAU;gBACd,MAAM,KAAK,SAAS;gBACpB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;YAC5D,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAClC,UAAU,CACR,GAAG,EACH,IAAI,EACJ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA,GAAG,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,GAAG,CAAC,KAAK,CACpD,CACF,CAAC;YACF,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA,OAAO,CAAC,OAAO,CAAC;YACxE,MAAM,MAAM,GAAG,SAAS,CACtB,GAAG,EACH,aAAa,CACX,GAAG,EACH,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,mBAAmB,CAAC,EACnD,CAAC,CACF,EACD,IAAI,EACJ,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAC/B,CAAC;YACF,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,GAAG,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,MAAM,IAAI,CAC5H,CAAC;QACJ,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAC1B,uEAAuE;YACvE,wEAAwE;YACxE,gEAAgE;YAChE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAA,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,OAAO,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CACnE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAA,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5D,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,OAAO,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CACnE,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,EAAE,CAAC;IACd,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9D,QAAQ,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9D,QAAQ,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACjC,iEAAiE;YACjE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QACD,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iHAAiH;AACjH,SAAS,MAAM,CACb,GAAgB,EAChB,IAAwC;IAExC,oEAAoE;IACpE,sEAAsE;IACtE,uEAAuE;IACvE,0DAA0D;IAC1D,IACE,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,EAC9B,CAAC;QACD,oEAAoE;QACpE,gEAAgE;QAChE,sEAAsE;QACtE,mEAAmE;QACnE,oEAAoE;QACpE,kEAAkE;QAClE,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA,SAAS,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;QACtD,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA,SAAS,CAAC,OAAO,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;QAC1E,MAAM,IAAI,GAAG,EAAE,CAAA,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,SAAS,CAAC,MAAM,IAAI,IAAI,QAAQ,GAAG,MAAM,EAAE,CAAC;QAC9F,MAAM,QAAQ,GAAG,IAAI,CACnB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA,GAAG,IAAI,QAAQ,CAAC,OAAO,QAAQ,IAAI,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CACnB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;QACF,OAAO,EAAE,CAAA,GAAG,IAAI,QAAQ,CAAC,OAAO,QAAQ,aAAa,QAAQ,IAAI,CAAC;IACpE,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CACnB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;IACF,MAAM,IAAI,GAAG,EAAE,CAAA,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,QAAQ,IAAI,CAAC;IAC9D,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAI,CACnB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;IACF,OAAO,EAAE,CAAA,GAAG,IAAI,WAAW,QAAQ,IAAI,CAAC;AAC1C,CAAC;AAED,sFAAsF;AACtF,SAAS,cAAc,CACrB,GAAgB,EAChB,IAAgD;IAEhD,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CACf,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;IACF,mEAAmE;IACnE,oEAAoE;IACpE,+CAA+C;IAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAA,cAAc,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IAClD,CAAC;IACD,OAAO,EAAE,CAAA,cAAc,CAAC,mBAAmB,CAAC,QAAQ,IAAI,IAAI,CAAC;AAC/D,CAAC;AAED,uCAAuC;AACvC,SAAS,gBAAgB,CACvB,GAAgB,EAChB,IAAkD;IAElD,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CACf,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACxC,CAAC;IACF,OAAO,EAAE,CAAA,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,IAAI,IAAI,CAAC;AACnH,CAAC;AAED,6EAA6E;AAC7E,SAAS,QAAQ,CACf,GAAgB,EAChB,IAA0C;IAE1C,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,SAAS,CACd,GAAG,EACH,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,EAChC,IAAI,EACJ,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAC9B,CAAC;IACJ,CAAC;IACD,sCAAsC;IACtC,OAAO,EAAE,CAAA,eAAe,CAAC;AAC3B,CAAC;AAED,4EAA4E;AAC5E,SAAS,YAAY,CACnB,GAAgB,EAChB,KAA+C;IAE/C,mEAAmE;IACnE,sEAAsE;IACtE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,EAAE,CAAA,EAAE,CAAC;IAChD,MAAM,KAAK,GAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAkC,CAC5D,GAAG,CAAC,cAAc,CAClB,CAAC;IACH,OAAO,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,0FAA0F;AAC1F,SAAS,WAAW,CAClB,GAAgB,EAChB,IAA6C;IAE7C,oEAAoE;IACpE,oEAAoE;IACpE,gEAAgE;IAChE,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,EAAE,CAAA,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,OAAO,GAAG,CAAC,IAAI,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC;AAED,iFAAiF;AACjF,SAAS,gBAAgB,CACvB,GAAgB,EAChB,IAAkD;IAElD,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,IAAI,cAAc,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAA,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAClD,CAAC;IACD,wEAAwE;IACxE,gDAAgD;IAChD,OAAO,EAAE,CAAA,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,QAAQ,WAAW,CAAC;AAC1E,CAAC;AAED,mIAAmI;AACnI,SAAS,cAAc,CACrB,GAAgB,EAChB,IAAgD;IAEhD,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,MAAM,UAAU,GACd,GAAG,KAAK,IAAI;QACV,CAAC,CAAC,EAAE,CAAA,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC7B,CAAC,CAAC,EAAE,CAAA,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;IACnD,MAAM,MAAM,GACV,GAAG,CAAC,MAAM,KAAK,MAAM;QACnB,CAAC,CAAC,SAAS,CACP,GAAG,EACH,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAC7C,IAAI,EACJ,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAC3C;QACH,CAAC,CAAC,EAAE,CAAA,eAAe,CAAC;IACxB,iEAAiE;IACjE,qEAAqE;IACrE,mBAAmB;IACnB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA,SAAS,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;IACnE,MAAM,KAAK,GAAG,EAAE;QACd,CAAC,CAAC,EAAE,CAAA,OAAO,UAAU,OAAO,MAAM,aAAa,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI;QACnE,CAAC,CAAC,EAAE,CAAA,OAAO,UAAU,OAAO,MAAM,IAAI,CAAC;IACzC,qEAAqE;IACrE,4DAA4D;IAC5D,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GACX,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,cAAc;YACvC,CAAC,CAAC,EAAE,CAAA,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,IAAI;YACvC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,EAAE,CAAA,GAAG,OAAO,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,OAAO,WAAW,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC;QAC9M,OAAO,EAAE,CAAA,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;IAC9B,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC1D,sEAAsE;QACtE,gEAAgE;QAChE,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,OAAO,GACX,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,cAAc;YACvC,CAAC,CAAC,EAAE,CAAA,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,IAAI;YACvC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,EAAE,CAAA,GAAG,OAAO,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,KAAK,OAAO,CAAC,MAAM,OAAO,MAAM,CAAC;QACrJ,OAAO,EAAE,CAAA,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,CAAA,GAAG,OAAO,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;IAC3J,OAAO,EAAE,CAAA,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAgB,EAAE,IAAe;IACzD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,IAAI;YACP,OAAO,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,KAAK,YAAY;YACf,OAAO,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnC,KAAK,cAAc;YACjB,OAAO,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,KAAK,UAAU;YACb,OAAO,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,KAAK,cAAc;YACjB,OAAO,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,cAAc;YACjB,MAAM,IAAI,cAAc,CACtB,iEAAiE,CAClE,CAAC;QACJ,KAAK,YAAY;YACf,OAAO,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,SAAS,aAAa,CACpB,GAAgB,EAChB,KAAiB,EACjB,IAAe,EACf,MAAe;IAEf,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,4DAA4D;YAC5D,kEAAkE;YAClE,mEAAmE;YACnE,kEAAkE;YAClE,8DAA8D;YAC9D,iEAAiE;YACjE,0BAA0B;YAC1B,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;YACrC,uEAAuE;YACvE,wDAAwD;YACxD,MAAM,IAAI,GACR,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;gBACtC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;gBAC7C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YACf,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,eAAe,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA,aAAa,CAAC;YACvE,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAA,GAAG,GAAG,QAAQ,IAAI,OAAO,IAAI,IAAI,CAAC;YACnE,OAAO,EAAE,CAAA,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC;QAChG,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,8DAA8D;YAC9D,iEAAiE;YACjE,gEAAgE;YAChE,iEAAiE;YACjE,8BAA8B;YAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACxC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAE,CAAC;YACzB,MAAM,GAAG,GAAG,SAAS,CACnB,GAAG,EACH,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC,8BAA8B,CAAC,CAAC,EACrE,IAAI,EACJ,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAC/B,CAAC;YACF,OAAO,EAAE,CAAA,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,GAAG,aAAa,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC;QACvJ,CAAC;QACD;YACE,OAAO,IAAI,CAAC,CAAC,mEAAmE;IACpF,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,eAAe,CACtB,GAAgB,EAChB,KAAiB,EACjB,IAAe,EACf,MAAe;IAEf,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,gEAAgE;YAChE,6CAA6C;YAC7C,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,GAAG,IAAI,EAAE,CAAA,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,EAAE,CAAA,GAAG,GAAG,eAAe,CAAC;YAC1D,IAAI,MAAM,EAAE,CAAC;gBACX,iEAAiE;gBACjE,iEAAiE;gBACjE,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChD,OAAO,EAAE,CAAA,SAAS,CAAC,MAAM,EAAE,iBAAiB,IAAI,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC;YAC7F,CAAC;YACD,kEAAkE;YAClE,OAAO,EAAE,CAAA,GAAG,GAAG,QAAQ,IAAI,iBAAiB,CAAC;QAC/C,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,EAAE,CAAA,eAAe,CAAC;YACnD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,EAAE,CAAA,EAAE,CAAC;YACvC,qEAAqE;YACrE,oEAAoE;YACpE,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAChD,OAAO,EAAE,CAAA,SAAS,CAAC,MAAM,EAAE,gBAAgB,IAAI,mBAAmB,EAAE,aAAa,CAAC,GAAG,CAAC;QACxF,CAAC;QACD;YACE,OAAO,IAAI,CAAC,CAAC,mEAAmE;IACpF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAgB,EAAE,KAAiB;IAChE,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,sEAAsE;IACtE,kEAAkE;IAClE,sEAAsE;IACtE,oEAAoE;IACpE,2EAA2E;IAC3E,MAAM,MAAM,GACV,GAAG,CAAC,UAAU;QACd,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;QAC5B,IAAI,CAAC,IAAI,KAAK,MAAM;QACpB,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;IACxB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;SAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,CAAA,EAAE,CAAC;IACtE,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QACvD,OAAO,EAAE,CAAA,eAAe,CAAC;IAC3B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,EAAE,CAAA,QAAQ,IAAI,iBAAiB,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,EAAE,CAAA,OAAO,IAAI,iBAAiB,CAAC;QACxC,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY;YACf,iEAAiE;YACjE,mDAAmD;YACnD,MAAM,IAAI,cAAc,CACtB,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,wCAAwC,CACjE,CAAC;QACJ,KAAK,SAAS;YACZ,kEAAkE;YAClE,iEAAiE;YACjE,wCAAwC;YACxC,MAAM,IAAI,cAAc,CAAC,+CAA+C,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type LowerStmt, type LoweringContext } from "@json-schema-engine/core";
2
+ import { type CodeChunk } from "../emit.js";
3
+ import { UnitContext } from "./context.js";
4
+ /** Serialize every present keyword of this unit, in dialect order. */
5
+ export declare function unitBody(ctx: UnitContext): CodeChunk[];
6
+ /** Run one keyword's lower() against a fresh LoweringContext, return its stmts. */
7
+ export declare function collect(ctx: UnitContext, keyword: string, run: (lctx: LoweringContext) => void): LowerStmt[];
8
+ //# sourceMappingURL=unit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit.d.ts","sourceRoot":"","sources":["../../src/serialize/unit.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,YAAY,CAAC;AAErE,OAAO,EAAE,WAAW,EAAkB,MAAM,cAAc,CAAC;AAK3D,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CA4EtD;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CACrB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,GACnC,SAAS,EAAE,CAiBb"}
@@ -0,0 +1,107 @@
1
+ // Per-unit orchestration: run each present keyword's lower() in dialect
2
+ // order and hand its statements to the emitters.
3
+ import { escapeSegment, } from "@json-schema-engine/core";
4
+ import { id, join, js, str, json } from "../emit.js";
5
+ import { TN } from "./names.js";
6
+ import { SerializeError } from "./context.js";
7
+ import { beginKeyword } from "./keywords.js";
8
+ import { keywordStatements } from "./statements.js";
9
+ import { annsPush } from "./spans.js";
10
+ /** Serialize every present keyword of this unit, in dialect order. */
11
+ export function unitBody(ctx) {
12
+ const node = ctx.unit.ref.node;
13
+ const dialect = ctx.registry.dialectFor(ctx.unit.ref.baseUri);
14
+ // Mirrors buildPlan's refOnly (plan.ts, citing engine.ts:397): the plan
15
+ // only resolved edges for $ref when this is true, so siblings must be
16
+ // skipped here too, or this would try to serialize applies the plan
17
+ // never planned.
18
+ const refOnly = dialect.refIgnoresSiblings && Object.hasOwn(node, "$ref");
19
+ const out = [];
20
+ if (ctx.trace) {
21
+ // One verdict slot per present non-structural keyword, declared up front:
22
+ // `if` settles `then`/`else`'s verdicts before those keywords' own (empty)
23
+ // statement lists run. Structural keywords record no entry (engine.ts).
24
+ const slots = [];
25
+ for (const entry of dialect.ordered) {
26
+ if (refOnly && entry.name !== "$ref")
27
+ continue;
28
+ if (!Object.hasOwn(node, entry.name))
29
+ continue;
30
+ if (entry.behavior.structural === true)
31
+ continue;
32
+ const k = id("k" + String(ctx.counters.temp++));
33
+ ctx.kwVerdicts.set(entry.name, k);
34
+ slots.push(js `${k} = true`);
35
+ }
36
+ if (slots.length > 0)
37
+ out.push(js `let ${join(", ", slots)};`);
38
+ }
39
+ for (const entry of dialect.ordered) {
40
+ if (refOnly && entry.name !== "$ref")
41
+ continue;
42
+ if (!Object.hasOwn(node, entry.name))
43
+ continue;
44
+ const behavior = entry.behavior;
45
+ if (typeof behavior.lower !== "function") {
46
+ throw new SerializeError("planner accepted unlowerable keyword '" + entry.name + "' (bug)");
47
+ }
48
+ const stmts = collect(ctx, entry.name, (lctx) => {
49
+ behavior.lower(node[entry.name], lctx);
50
+ });
51
+ ctx.currentVocab = entry.vocabularyUri;
52
+ ctx.currentBehaviorId = behavior.id;
53
+ // Accumulator declarations hoist above the keyword's statements: the
54
+ // application call sites feed them, the produce reads them.
55
+ const decls = beginKeyword(ctx, stmts);
56
+ const chunks = keywordStatements(ctx, stmts);
57
+ out.push(...decls, ...chunks);
58
+ // The verdict entry follows the keyword's applications, as the
59
+ // interpreter's traceKeyword does.
60
+ if (ctx.trace && behavior.structural !== true) {
61
+ const k = ctx.kwVerdicts.get(entry.name);
62
+ out.push(js `${TN}.keywords.push({ name: ${str(entry.name)}, valid: ${k} });`);
63
+ }
64
+ }
65
+ // Unknown keywords collect as annotations (engine.ts:414): unconditional
66
+ // constant annotations, in schema-key order, after every dialect keyword.
67
+ // The refOnly break silences siblings, matching the interpreter. Trace
68
+ // emission records each as an accepting keyword entry whether or not its
69
+ // annotation is selected.
70
+ if ((ctx.annMode || ctx.trace) && !refOnly) {
71
+ for (const name of Object.keys(node)) {
72
+ if (dialect.keywords.has(name))
73
+ continue;
74
+ if (ctx.trace) {
75
+ out.push(js `${TN}.keywords.push({ name: ${str(name)}, valid: true });`);
76
+ }
77
+ if (!ctx.annMode)
78
+ continue;
79
+ if (ctx.annKeep && !ctx.annKeep("", name, null))
80
+ continue;
81
+ const suffix = "/" + escapeSegment(name);
82
+ const sloc = ctx.unit.ref.baseUri + "#" + ctx.unit.ref.pointer + suffix;
83
+ out.push(annsPush(ctx, js `{ keyword: ${str(name)}, evaluationPath: ${id("ep")} + ${str(suffix)}, schemaLocation: ${str(sloc)}, inputLocation: ${id("ip")}, annotation: ${json(node[name])} }`));
84
+ }
85
+ }
86
+ return out;
87
+ }
88
+ /** Run one keyword's lower() against a fresh LoweringContext, return its stmts. */
89
+ export function collect(ctx, keyword, run) {
90
+ ctx.currentKeyword = keyword;
91
+ const stmts = [];
92
+ const unit = ctx.unit;
93
+ const lctx = {
94
+ instance: { kind: "instance" },
95
+ schema: unit.ref.node,
96
+ staticCoverage: () => unit.coverage,
97
+ // A tracked unit's consumers read the runtime channel; a static-coverage
98
+ // consumer (even one that is a region member) keeps its static path and
99
+ // instead PUSHES its produce onto the channel for the enclosing consumer.
100
+ runtimeCoverage: () => unit.tracking === true,
101
+ emit: (...s) => stmts.push(...s),
102
+ binding: () => ctx.counters.binding++,
103
+ };
104
+ run(lctx);
105
+ return stmts;
106
+ }
107
+ //# sourceMappingURL=unit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit.js","sourceRoot":"","sources":["../../src/serialize/unit.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,iDAAiD;AAEjD,OAAO,EACL,aAAa,GAId,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAkB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAChC,OAAO,EAAe,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,GAAgB;IACvC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAiC,CAAC;IAC5D,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9D,wEAAwE;IACxE,sEAAsE;IACtE,oEAAoE;IACpE,iBAAiB;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,kBAAkB,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,KAAK,GAAgB,EAAE,CAAC;QAC9B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC/C,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,KAAK,IAAI;gBAAE,SAAS;YACjD,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAChD,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAA,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,IAAI,OAAO,QAAQ,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACzC,MAAM,IAAI,cAAc,CACtB,wCAAwC,GAAG,KAAK,CAAC,IAAI,GAAG,SAAS,CAClE,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9C,QAAQ,CAAC,KAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAE,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,GAAG,CAAC,iBAAiB,GAAG,QAAQ,CAAC,EAAE,CAAC;QACpC,qEAAqE;QACrE,4DAA4D;QAC5D,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7C,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAC9B,+DAA+D;QAC/D,mCAAmC;QACnC,IAAI,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CACN,EAAE,CAAA,GAAG,EAAE,0BAA0B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,yEAAyE;IACzE,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,0BAA0B;IAC1B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACzC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA,GAAG,EAAE,0BAA0B,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,OAAO;gBAAE,SAAS;YAC3B,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC;gBAAE,SAAS;YAC1D,MAAM,MAAM,GAAG,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;YACxE,GAAG,CAAC,IAAI,CACN,QAAQ,CACN,GAAG,EACH,EAAE,CAAA,cAAc,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,qBAAqB,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,IAAI,CACxK,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,OAAO,CACrB,GAAgB,EAChB,OAAe,EACf,GAAoC;IAEpC,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC;IAC7B,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,MAAM,IAAI,GAAoB;QAC5B,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC9B,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,IAAiC;QAClD,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ;QACnC,yEAAyE;QACzE,wEAAwE;QACxE,0EAA0E;QAC1E,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI;QAC7C,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE;KACtC,CAAC;IACF,GAAG,CAAC,IAAI,CAAC,CAAC;IACV,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type Engine } from "@json-schema-engine/core";
2
+ /** Thrown when a plan needs the interpreter at runtime (islands/fallbacks). */
3
+ export declare class StandaloneUnsupportedError extends Error {
4
+ }
5
+ /**
6
+ * The standalone helper preamble, exported so standalone.test.ts can compare
7
+ * each helper against its core original over a vector corpus (the drift
8
+ * guard the header describes). Not part of the public API surface.
9
+ */
10
+ export declare const STANDALONE_PREAMBLE = "// Generated by @json-schema-engine/compiler (standalone mode). Self-contained; no imports.\nconst h_obj = (v) => typeof v === \"object\" && v !== null && !Array.isArray(v);\nconst h_int = (v) => typeof v === \"number\" && Number.isInteger(v);\nconst h_hop = Object.prototype.hasOwnProperty;\nconst h_s0 = [];\n// Mirrors core's MaxDepthExceededError, which the interpreter and every\n// runtime-compiled artifact throw for this bound. Self-contained emission\n// cannot share core's class object, so `instanceof` against it is false\n// here by construction; `constructor.name` is the discriminator a\n// standalone consumer has. Throwing RangeError instead would be worse than\n// imprecise: core converts a native stack RangeError INTO this class so a\n// depth failure is never uncatchable by type, and reusing RangeError for\n// the bound makes \"schema too deep\" and \"blew the native stack\"\n// indistinguishable.\nclass MaxDepthExceededError extends Error {}\nconst h_rx = (source) => {\n try {\n return new RegExp(source, \"u\");\n } catch {\n return new RegExp(source);\n }\n};\nconst h_eq = (a, b) => {\n if (a === b) return true;\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (!h_eq(a[i], b[i])) return false;\n return true;\n }\n if (h_obj(a)) {\n if (!h_obj(b)) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n for (const k of keys) {\n if (!h_hop.call(b, k) || !h_eq(a[k], b[k])) return false;\n }\n return true;\n }\n return false;\n};\nconst h_ck = (v) => {\n if (v === null || typeof v !== \"object\") return JSON.stringify(v);\n if (Array.isArray(v)) return \"[\" + v.map(h_ck).join(\",\") + \"]\";\n const keys = Object.keys(v).sort();\n return (\n \"{\" +\n keys.map((k) => JSON.stringify(k) + \":\" + h_ck(v[k])).join(\",\") +\n \"}\"\n );\n};\nconst h_dup = (items) => {\n const seen = new Map();\n for (let i = 0; i < items.length; i++) {\n const key = h_ck(items[i]);\n const bucket = seen.get(key);\n if (bucket === undefined) {\n seen.set(key, [i]);\n continue;\n }\n for (const j of bucket) if (h_eq(items[j], items[i])) return true;\n bucket.push(i);\n }\n return false;\n};\nconst h_cpl = (s) => {\n let n = 0;\n for (let i = 0; i < s.length; i++) {\n n++;\n const c = s.charCodeAt(i);\n if (c >= 0xd800 && c <= 0xdbff) i++;\n }\n return n;\n};\nconst h_esc = (s) => s.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\nconst h_digits = (n) => {\n if (!Number.isFinite(n)) return 0;\n const s = Math.abs(n).toString();\n const eIndex = s.indexOf(\"e\");\n if (eIndex !== -1) {\n const mantissa = s.slice(0, eIndex);\n const exponent = Number(s.slice(eIndex + 1));\n const dot = mantissa.indexOf(\".\");\n const mantissaDigits = dot === -1 ? 0 : mantissa.length - dot - 1;\n return Math.max(0, mantissaDigits - exponent);\n }\n const dot = s.indexOf(\".\");\n return dot === -1 ? 0 : s.length - dot - 1;\n};\nconst h_mof = (instance, divisor) => {\n const scale = 10 ** Math.max(h_digits(instance), h_digits(divisor));\n const scaledInstance = instance * scale;\n const scaledDivisor = divisor * scale;\n if (Number.isFinite(scaledInstance) && Number.isFinite(scaledDivisor)) {\n return Math.round(scaledInstance) % Math.round(scaledDivisor) === 0;\n }\n const quotient = instance / divisor;\n return Number.isFinite(quotient) && Number.isInteger(quotient);\n};\n";
11
+ /** Options for {@link emitStandalone}. */
12
+ export interface StandaloneOptions {
13
+ /** depth bound baked into the module; defaults to core's DEFAULT_MAX_DEPTH */
14
+ maxDepth?: number;
15
+ }
16
+ /**
17
+ * Emit a self-contained ES module validating against one registered,
18
+ * fully-static schema. The module's default export is
19
+ * `validate(instance): boolean`.
20
+ * @throws StandaloneUnsupportedError when the plan contains interpreted
21
+ * units — use the interpreter (CSP) or runtime compilation (no CSP).
22
+ */
23
+ export declare function emitStandalone(engine: Engine, schemaUri: string, options?: StandaloneOptions): string;
24
+ //# sourceMappingURL=standalone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAI1E,+EAA+E;AAC/E,qBAAa,0BAA2B,SAAQ,KAAK;CAAG;AAKxD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,u/GAkG/B,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAoCR"}