@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.
- package/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/emit.d.ts +52 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +166 -0
- package/dist/emit.js.map +1 -0
- package/dist/explain.d.ts +28 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +42 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.d.ts +132 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +169 -0
- package/dist/index.js.map +1 -0
- package/dist/plan.d.ts +83 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +385 -0
- package/dist/plan.js.map +1 -0
- package/dist/runtime-compile.d.ts +30 -0
- package/dist/runtime-compile.d.ts.map +1 -0
- package/dist/runtime-compile.js +29 -0
- package/dist/runtime-compile.js.map +1 -0
- package/dist/runtime.d.ts +157 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +336 -0
- package/dist/runtime.js.map +1 -0
- package/dist/serialize/apply.d.ts +28 -0
- package/dist/serialize/apply.d.ts.map +1 -0
- package/dist/serialize/apply.js +211 -0
- package/dist/serialize/apply.js.map +1 -0
- package/dist/serialize/context.d.ts +143 -0
- package/dist/serialize/context.d.ts.map +1 -0
- package/dist/serialize/context.js +93 -0
- package/dist/serialize/context.js.map +1 -0
- package/dist/serialize/expressions.d.ts +7 -0
- package/dist/serialize/expressions.d.ts.map +1 -0
- package/dist/serialize/expressions.js +177 -0
- package/dist/serialize/expressions.js.map +1 -0
- package/dist/serialize/guards.d.ts +7 -0
- package/dist/serialize/guards.d.ts.map +1 -0
- package/dist/serialize/guards.js +19 -0
- package/dist/serialize/guards.js.map +1 -0
- package/dist/serialize/index.d.ts +7 -0
- package/dist/serialize/index.d.ts.map +1 -0
- package/dist/serialize/index.js +266 -0
- package/dist/serialize/index.js.map +1 -0
- package/dist/serialize/keywords.d.ts +32 -0
- package/dist/serialize/keywords.d.ts.map +1 -0
- package/dist/serialize/keywords.js +131 -0
- package/dist/serialize/keywords.js.map +1 -0
- package/dist/serialize/messages.d.ts +36 -0
- package/dist/serialize/messages.d.ts.map +1 -0
- package/dist/serialize/messages.js +100 -0
- package/dist/serialize/messages.js.map +1 -0
- package/dist/serialize/names.d.ts +47 -0
- package/dist/serialize/names.d.ts.map +1 -0
- package/dist/serialize/names.js +115 -0
- package/dist/serialize/names.js.map +1 -0
- package/dist/serialize/spans.d.ts +34 -0
- package/dist/serialize/spans.d.ts.map +1 -0
- package/dist/serialize/spans.js +61 -0
- package/dist/serialize/spans.js.map +1 -0
- package/dist/serialize/statements.d.ts +16 -0
- package/dist/serialize/statements.d.ts.map +1 -0
- package/dist/serialize/statements.js +396 -0
- package/dist/serialize/statements.js.map +1 -0
- package/dist/serialize/unit.d.ts +8 -0
- package/dist/serialize/unit.d.ts.map +1 -0
- package/dist/serialize/unit.js +107 -0
- package/dist/serialize/unit.js.map +1 -0
- package/dist/standalone.d.ts +24 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +166 -0
- package/dist/standalone.js.map +1 -0
- package/package.json +38 -0
- package/src/emit.ts +196 -0
- package/src/explain.ts +67 -0
- package/src/index.ts +366 -0
- package/src/plan.ts +496 -0
- package/src/runtime-compile.ts +90 -0
- package/src/runtime.ts +599 -0
- package/src/serialize/apply.ts +251 -0
- package/src/serialize/context.ts +161 -0
- package/src/serialize/expressions.ts +202 -0
- package/src/serialize/guards.ts +20 -0
- package/src/serialize/index.ts +432 -0
- package/src/serialize/keywords.ts +144 -0
- package/src/serialize/messages.ts +120 -0
- package/src/serialize/names.ts +136 -0
- package/src/serialize/spans.ts +88 -0
- package/src/serialize/statements.ts +531 -0
- package/src/serialize/unit.ts +118 -0
- package/src/standalone.ts +187 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// @json-schema-engine/compiler public API (M6.2 vertical slice): compile a registered
|
|
2
|
+
// schema into a specialized flag-mode validator. Static subschemas become
|
|
3
|
+
// emitted JS; dynamic islands and every fallback cause trampoline to the
|
|
4
|
+
// interpreter through core's evaluateFragment, so the compiled artifact is
|
|
5
|
+
// exactly as correct as the interpreter — never less complete.
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
DEFAULT_MAX_DEPTH,
|
|
9
|
+
OutputOptionsError,
|
|
10
|
+
assembleResult,
|
|
11
|
+
renderBasic,
|
|
12
|
+
resolveOutputDemand,
|
|
13
|
+
type AnnotationSelection,
|
|
14
|
+
type AnnotationUnit,
|
|
15
|
+
type BasicOutputDocument,
|
|
16
|
+
type Engine,
|
|
17
|
+
type ErrorUnit,
|
|
18
|
+
type EvaluateOptions,
|
|
19
|
+
type JsonValue,
|
|
20
|
+
type Result,
|
|
21
|
+
type ResultFor,
|
|
22
|
+
} from "@json-schema-engine/core";
|
|
23
|
+
import { buildPlan, type CompilationPlan } from "./plan.js";
|
|
24
|
+
import { serializePlan } from "./serialize/index.js";
|
|
25
|
+
import { finishTrace, makeRuntime } from "./runtime.js";
|
|
26
|
+
import {
|
|
27
|
+
instantiate,
|
|
28
|
+
instantiateList,
|
|
29
|
+
instantiateListAnn,
|
|
30
|
+
instantiateTrace,
|
|
31
|
+
type CompiledValidate,
|
|
32
|
+
} from "./runtime-compile.js";
|
|
33
|
+
|
|
34
|
+
export type { CompilationPlan, PlannedUnit, FallbackCause } from "./plan.js";
|
|
35
|
+
export { buildPlan } from "./plan.js";
|
|
36
|
+
export { explainCompilation } from "./explain.js";
|
|
37
|
+
export type { CompilationExplanation } from "./explain.js";
|
|
38
|
+
export { serializePlan } from "./serialize/index.js";
|
|
39
|
+
export { emitStandalone, StandaloneUnsupportedError } from "./standalone.js";
|
|
40
|
+
export type { StandaloneOptions } from "./standalone.js";
|
|
41
|
+
|
|
42
|
+
/** Options for {@link compileValidator}. */
|
|
43
|
+
export interface CompileOptions {
|
|
44
|
+
/** depth bound shared between compiled nesting and fragments; default core's */
|
|
45
|
+
maxDepth?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Disable the D9 optimizations (inlining, plain-data fast paths). Exists
|
|
48
|
+
* so the differential fuzzer referees both configurations; not a
|
|
49
|
+
* user-facing tuning knob.
|
|
50
|
+
*/
|
|
51
|
+
conservative?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Options for {@link compileList}. */
|
|
55
|
+
export interface ListCompileOptions extends CompileOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Include `keyword`, `vocabulary`, and structured `params` on each error
|
|
58
|
+
* unit, matching the interpreter's `errorParams` option on `list` output
|
|
59
|
+
* (D13).
|
|
60
|
+
*/
|
|
61
|
+
errorParams?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Which annotations to collect, matching the interpreter's `annotations`
|
|
64
|
+
* option: `true` or a selection makes `evaluateList` return an
|
|
65
|
+
* `annotations` array on valid instances and `basic()` render the Basic
|
|
66
|
+
* document's annotation side. A selection's allow/deny lists are
|
|
67
|
+
* specialized into the artifact at compile time; its `keep` predicate runs
|
|
68
|
+
* at evaluation.
|
|
69
|
+
*/
|
|
70
|
+
annotations?: boolean | AnnotationSelection;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** A compiled list-mode result: interpreter-exact flat error units, plus annotations when collected. */
|
|
74
|
+
export interface CompiledListResult {
|
|
75
|
+
valid: boolean;
|
|
76
|
+
errors: ErrorUnit[];
|
|
77
|
+
/**
|
|
78
|
+
* Present on valid instances when compiled with `annotations` (absent on
|
|
79
|
+
* invalid ones, matching `Engine.evaluate`'s valid-only annotation
|
|
80
|
+
* contract); always absent otherwise.
|
|
81
|
+
*/
|
|
82
|
+
annotations?: AnnotationUnit[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A compiled list-mode artifact (see {@link compileList}). */
|
|
86
|
+
export interface CompiledListArtifact {
|
|
87
|
+
/** evaluate with full error collection ({@link CompiledListResult}) */
|
|
88
|
+
evaluateList(instance: JsonValue): CompiledListResult;
|
|
89
|
+
/**
|
|
90
|
+
* The same result as the Basic document (IETF draft-03 §13.4.2), matching
|
|
91
|
+
* `Engine.evaluate(uri, x, { output: "basic" }).outputDocument`: the flat
|
|
92
|
+
* `errors` array on invalid instances; on valid instances compiled with
|
|
93
|
+
* `annotations`, the selected annotations, present only when non-empty.
|
|
94
|
+
*/
|
|
95
|
+
basic(instance: JsonValue): BasicOutputDocument;
|
|
96
|
+
plan: CompilationPlan;
|
|
97
|
+
source: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** A compiled artifact: the validator plus its plan and source (inspection/tests). */
|
|
101
|
+
export interface CompiledArtifact {
|
|
102
|
+
validate: CompiledValidate;
|
|
103
|
+
plan: CompilationPlan;
|
|
104
|
+
source: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Options for {@link compileEvaluator}: the flat surface's controls
|
|
109
|
+
* (`errorParams`, the annotation selection) and the level, fixed when the
|
|
110
|
+
* evaluator is compiled.
|
|
111
|
+
*/
|
|
112
|
+
export interface EvaluatorCompileOptions extends ListCompileOptions {
|
|
113
|
+
/**
|
|
114
|
+
* Retain irrelevant records (draft-03 §12.2) so the artifact can serve
|
|
115
|
+
* the verbose level: `output: "verbose"`, and `list`/`hierarchical` with
|
|
116
|
+
* `verbose: true`. A retaining artifact serves the relevant level too;
|
|
117
|
+
* the retention costs a copy per dropped record and nothing on the
|
|
118
|
+
* emitted source, which is identical at both levels.
|
|
119
|
+
*/
|
|
120
|
+
verbose?: boolean;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The render-time choices of {@link CompiledEvaluator.evaluate}: format,
|
|
125
|
+
* level, and trace. The controls fixed at compile time are rejected here
|
|
126
|
+
* with {@link OutputOptionsError} rather than ignored.
|
|
127
|
+
*/
|
|
128
|
+
export type EvaluatorOptions = Pick<
|
|
129
|
+
EvaluateOptions,
|
|
130
|
+
"output" | "verbose" | "trace"
|
|
131
|
+
>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* A compiled evaluator (see {@link compileEvaluator}): every output format
|
|
135
|
+
* from one recorded application tree, with `Engine.evaluate`'s result for
|
|
136
|
+
* the same instance and options.
|
|
137
|
+
*/
|
|
138
|
+
export interface CompiledEvaluator {
|
|
139
|
+
evaluate<O extends EvaluatorOptions>(
|
|
140
|
+
instance: JsonValue,
|
|
141
|
+
options?: O,
|
|
142
|
+
): ResultFor<O>;
|
|
143
|
+
plan: CompilationPlan;
|
|
144
|
+
source: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Compile a registered schema into a flag-mode validator. The artifact
|
|
149
|
+
* binds to a snapshot of the engine's schema and dialect registries taken at
|
|
150
|
+
* compile time, plus the engine's pattern cache: schemas registered,
|
|
151
|
+
* re-registered, or given a new dialect later are invisible to it, and a
|
|
152
|
+
* reference unresolved at compile time stays unresolved for it (E1).
|
|
153
|
+
*/
|
|
154
|
+
export function compileValidator(
|
|
155
|
+
engine: Engine,
|
|
156
|
+
schemaUri: string,
|
|
157
|
+
options: CompileOptions = {},
|
|
158
|
+
): CompiledArtifact {
|
|
159
|
+
const plan = buildPlan(engine, schemaUri);
|
|
160
|
+
// Compilation is synchronous, so the plan (built from the live registry)
|
|
161
|
+
// and this snapshot see one state; the artifact's islands never see a
|
|
162
|
+
// later registration.
|
|
163
|
+
const registry = engine.registry.snapshot();
|
|
164
|
+
const source = serializePlan(plan, registry, {
|
|
165
|
+
flags: options.conservative
|
|
166
|
+
? { inline: false, plainData: false }
|
|
167
|
+
: { inline: true, plainData: true },
|
|
168
|
+
});
|
|
169
|
+
const runtime = makeRuntime(
|
|
170
|
+
registry,
|
|
171
|
+
engine.patternCache,
|
|
172
|
+
plan.patterns,
|
|
173
|
+
options.maxDepth ?? DEFAULT_MAX_DEPTH,
|
|
174
|
+
false,
|
|
175
|
+
undefined,
|
|
176
|
+
engine.formats,
|
|
177
|
+
plan.formats,
|
|
178
|
+
);
|
|
179
|
+
const validate = instantiate(
|
|
180
|
+
source,
|
|
181
|
+
runtime,
|
|
182
|
+
plan.targets.map((t) => t.ref),
|
|
183
|
+
);
|
|
184
|
+
return {
|
|
185
|
+
validate: (instance: JsonValue) => validate(instance),
|
|
186
|
+
plan,
|
|
187
|
+
source,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Compile a registered schema into a list-output validator (D9e): flat,
|
|
193
|
+
* interpreter-exact error units — the same elements
|
|
194
|
+
* `Engine.evaluate(uri, x, { output: "list" }).errors` yields, in the same
|
|
195
|
+
* order (list artifacts never short-circuit; every branch runs, DESIGN §7).
|
|
196
|
+
* Error-unit objects materialize only on failure paths. Binds to registry
|
|
197
|
+
* snapshots exactly like {@link compileValidator}.
|
|
198
|
+
*/
|
|
199
|
+
export function compileList(
|
|
200
|
+
engine: Engine,
|
|
201
|
+
schemaUri: string,
|
|
202
|
+
options: ListCompileOptions = {},
|
|
203
|
+
): CompiledListArtifact {
|
|
204
|
+
const selection = options.annotations ?? false;
|
|
205
|
+
const collect = selection !== false;
|
|
206
|
+
const errorParams = options.errorParams ?? false;
|
|
207
|
+
const plan = buildPlan(engine, schemaUri, { output: "list" });
|
|
208
|
+
const registry = engine.registry.snapshot();
|
|
209
|
+
const source = serializePlan(plan, registry, {
|
|
210
|
+
flags: options.conservative
|
|
211
|
+
? { inline: false, plainData: false }
|
|
212
|
+
: { inline: true, plainData: true },
|
|
213
|
+
output: "list",
|
|
214
|
+
listParams: errorParams,
|
|
215
|
+
annotate: collect ? { selection } : undefined,
|
|
216
|
+
});
|
|
217
|
+
const runtime = makeRuntime(
|
|
218
|
+
registry,
|
|
219
|
+
engine.patternCache,
|
|
220
|
+
plan.patterns,
|
|
221
|
+
options.maxDepth ?? DEFAULT_MAX_DEPTH,
|
|
222
|
+
errorParams,
|
|
223
|
+
collect ? { selection } : undefined,
|
|
224
|
+
engine.formats,
|
|
225
|
+
plan.formats,
|
|
226
|
+
);
|
|
227
|
+
const targets = plan.targets.map((t) => t.ref);
|
|
228
|
+
const root = registry.rootRef(schemaUri);
|
|
229
|
+
const rootLocation = `${root.baseUri}#${root.pointer}`;
|
|
230
|
+
const keep = typeof selection === "object" ? selection.keep : undefined;
|
|
231
|
+
|
|
232
|
+
if (!collect) {
|
|
233
|
+
const evaluateList = instantiateList<ErrorUnit>(source, runtime, targets);
|
|
234
|
+
return {
|
|
235
|
+
evaluateList,
|
|
236
|
+
basic: (instance) => {
|
|
237
|
+
const { valid, errors } = evaluateList(instance);
|
|
238
|
+
return renderBasic(valid, rootLocation, errors, []);
|
|
239
|
+
},
|
|
240
|
+
plan,
|
|
241
|
+
source,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// The emitted evaluator returns the raw (static-list-filtered) annotation
|
|
246
|
+
// array; the wrapper applies `keep` (over the native unit, as the
|
|
247
|
+
// interpreter does) and the valid-only presence rule, matching
|
|
248
|
+
// `Engine.evaluate`'s Result.annotations; `basic()` renders that same
|
|
249
|
+
// flat surface through core's renderer.
|
|
250
|
+
const rawEval = instantiateListAnn<ErrorUnit>(source, runtime, targets);
|
|
251
|
+
const evaluateList = (instance: JsonValue): CompiledListResult => {
|
|
252
|
+
const r = rawEval(instance);
|
|
253
|
+
if (!r.valid) return { valid: false, errors: r.errors };
|
|
254
|
+
const anns = keep ? r.annotations.filter(keep) : r.annotations;
|
|
255
|
+
return { valid: true, errors: r.errors, annotations: anns };
|
|
256
|
+
};
|
|
257
|
+
return {
|
|
258
|
+
evaluateList,
|
|
259
|
+
basic: (instance) => {
|
|
260
|
+
const r = evaluateList(instance);
|
|
261
|
+
return renderBasic(r.valid, rootLocation, r.errors, r.annotations ?? []);
|
|
262
|
+
},
|
|
263
|
+
plan,
|
|
264
|
+
source,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Compile a registered schema into an evaluator that renders every output
|
|
270
|
+
* format: a list artifact that also records each application's node —
|
|
271
|
+
* locations, keyword verdicts, and the records it raised — into core's
|
|
272
|
+
* located tree, so the documents render through the same code as the
|
|
273
|
+
* interpreter's. Format, level, and `trace` are chosen per evaluation; the
|
|
274
|
+
* annotation selection, `errorParams`, and whether irrelevant records are
|
|
275
|
+
* retained (`verbose`) are fixed here (D5). Without retention the records
|
|
276
|
+
* are discarded at the cut and a verbose-level request throws
|
|
277
|
+
* {@link OutputOptionsError}. Binds to registry snapshots exactly like
|
|
278
|
+
* {@link compileValidator}.
|
|
279
|
+
*/
|
|
280
|
+
export function compileEvaluator(
|
|
281
|
+
engine: Engine,
|
|
282
|
+
schemaUri: string,
|
|
283
|
+
options: EvaluatorCompileOptions = {},
|
|
284
|
+
): CompiledEvaluator {
|
|
285
|
+
const selection = options.annotations ?? false;
|
|
286
|
+
const collect = selection !== false;
|
|
287
|
+
const errorParams = options.errorParams ?? false;
|
|
288
|
+
const retain = options.verbose ?? false;
|
|
289
|
+
const plan = buildPlan(engine, schemaUri, { output: "list" });
|
|
290
|
+
const registry = engine.registry.snapshot();
|
|
291
|
+
const source = serializePlan(plan, registry, {
|
|
292
|
+
flags: options.conservative
|
|
293
|
+
? { inline: false, plainData: false }
|
|
294
|
+
: { inline: true, plainData: true },
|
|
295
|
+
output: "list",
|
|
296
|
+
listParams: errorParams,
|
|
297
|
+
annotate: collect ? { selection } : undefined,
|
|
298
|
+
trace: true,
|
|
299
|
+
});
|
|
300
|
+
const runtime = makeRuntime(
|
|
301
|
+
registry,
|
|
302
|
+
engine.patternCache,
|
|
303
|
+
plan.patterns,
|
|
304
|
+
options.maxDepth ?? DEFAULT_MAX_DEPTH,
|
|
305
|
+
errorParams,
|
|
306
|
+
collect ? { selection } : undefined,
|
|
307
|
+
engine.formats,
|
|
308
|
+
plan.formats,
|
|
309
|
+
true,
|
|
310
|
+
retain,
|
|
311
|
+
);
|
|
312
|
+
const run = instantiateTrace(
|
|
313
|
+
source,
|
|
314
|
+
runtime,
|
|
315
|
+
plan.targets.map((t) => t.ref),
|
|
316
|
+
);
|
|
317
|
+
const root = registry.rootRef(schemaUri);
|
|
318
|
+
const rootLocation = `${root.baseUri}#${root.pointer}`;
|
|
319
|
+
const keep = typeof selection === "object" ? selection.keep : undefined;
|
|
320
|
+
|
|
321
|
+
const evaluate = (
|
|
322
|
+
instance: JsonValue,
|
|
323
|
+
evaluateOptions: EvaluatorOptions = {},
|
|
324
|
+
): Result => {
|
|
325
|
+
// The controls fixed at compile time are rejected, not ignored (ADR
|
|
326
|
+
// 0003: every combination is supported or refused).
|
|
327
|
+
for (const fixed of ["annotations", "errorParams", "positions"]) {
|
|
328
|
+
if (fixed in evaluateOptions) {
|
|
329
|
+
throw new OutputOptionsError(
|
|
330
|
+
`'${fixed}' is fixed when the evaluator is compiled`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// The compiled selection stands in for the option; `flag` is admitted
|
|
335
|
+
// whatever the selection, since it renders no records.
|
|
336
|
+
const demand = {
|
|
337
|
+
...resolveOutputDemand({
|
|
338
|
+
output: evaluateOptions.output,
|
|
339
|
+
verbose: evaluateOptions.verbose,
|
|
340
|
+
trace: evaluateOptions.trace,
|
|
341
|
+
}),
|
|
342
|
+
annotations: selection,
|
|
343
|
+
};
|
|
344
|
+
if (demand.verbose && !retain) {
|
|
345
|
+
throw new OutputOptionsError(
|
|
346
|
+
"the verbose level needs an evaluator compiled with verbose: true",
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
const st = run(instance);
|
|
350
|
+
if (demand.format === "flag") return { valid: st.valid };
|
|
351
|
+
const { units, root: node } = finishTrace(st, keep, demand.verbose);
|
|
352
|
+
return assembleResult(
|
|
353
|
+
demand,
|
|
354
|
+
st.valid,
|
|
355
|
+
units,
|
|
356
|
+
node,
|
|
357
|
+
rootLocation,
|
|
358
|
+
evaluateOptions.trace === true,
|
|
359
|
+
);
|
|
360
|
+
};
|
|
361
|
+
return {
|
|
362
|
+
evaluate: evaluate as CompiledEvaluator["evaluate"],
|
|
363
|
+
plan,
|
|
364
|
+
source,
|
|
365
|
+
};
|
|
366
|
+
}
|