@lumencast/protocol 0.1.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 (84) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +55 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +162 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/codec.d.ts +15 -0
  9. package/dist/codec.d.ts.map +1 -0
  10. package/dist/codec.js +328 -0
  11. package/dist/codec.js.map +1 -0
  12. package/dist/conformance/bundle-hash.d.ts +4 -0
  13. package/dist/conformance/bundle-hash.d.ts.map +1 -0
  14. package/dist/conformance/bundle-hash.js +49 -0
  15. package/dist/conformance/bundle-hash.js.map +1 -0
  16. package/dist/conformance/control-client.d.ts +42 -0
  17. package/dist/conformance/control-client.d.ts.map +1 -0
  18. package/dist/conformance/control-client.js +63 -0
  19. package/dist/conformance/control-client.js.map +1 -0
  20. package/dist/conformance/harness.d.ts +41 -0
  21. package/dist/conformance/harness.d.ts.map +1 -0
  22. package/dist/conformance/harness.js +441 -0
  23. package/dist/conformance/harness.js.map +1 -0
  24. package/dist/conformance/index.d.ts +8 -0
  25. package/dist/conformance/index.d.ts.map +1 -0
  26. package/dist/conformance/index.js +12 -0
  27. package/dist/conformance/index.js.map +1 -0
  28. package/dist/conformance/loader.d.ts +9 -0
  29. package/dist/conformance/loader.d.ts.map +1 -0
  30. package/dist/conformance/loader.js +27 -0
  31. package/dist/conformance/loader.js.map +1 -0
  32. package/dist/conformance/match.d.ts +7 -0
  33. package/dist/conformance/match.d.ts.map +1 -0
  34. package/dist/conformance/match.js +82 -0
  35. package/dist/conformance/match.js.map +1 -0
  36. package/dist/conformance/placeholders.d.ts +2 -0
  37. package/dist/conformance/placeholders.d.ts.map +1 -0
  38. package/dist/conformance/placeholders.js +40 -0
  39. package/dist/conformance/placeholders.js.map +1 -0
  40. package/dist/conformance/scenario.d.ts +33 -0
  41. package/dist/conformance/scenario.d.ts.map +1 -0
  42. package/dist/conformance/scenario.js +26 -0
  43. package/dist/conformance/scenario.js.map +1 -0
  44. package/dist/envelope.d.ts +66 -0
  45. package/dist/envelope.d.ts.map +1 -0
  46. package/dist/envelope.js +111 -0
  47. package/dist/envelope.js.map +1 -0
  48. package/dist/errors.d.ts +25 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +38 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/index.d.ts +7 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +8 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/leaf-path.d.ts +21 -0
  57. package/dist/leaf-path.d.ts.map +1 -0
  58. package/dist/leaf-path.js +51 -0
  59. package/dist/leaf-path.js.map +1 -0
  60. package/dist/sequence.d.ts +25 -0
  61. package/dist/sequence.d.ts.map +1 -0
  62. package/dist/sequence.js +51 -0
  63. package/dist/sequence.js.map +1 -0
  64. package/dist/types.d.ts +159 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +13 -0
  67. package/dist/types.js.map +1 -0
  68. package/package.json +56 -0
  69. package/src/cli.ts +176 -0
  70. package/src/codec.ts +374 -0
  71. package/src/conformance/bundle-hash.ts +54 -0
  72. package/src/conformance/control-client.ts +93 -0
  73. package/src/conformance/harness.ts +492 -0
  74. package/src/conformance/index.ts +34 -0
  75. package/src/conformance/loader.ts +39 -0
  76. package/src/conformance/match.ts +92 -0
  77. package/src/conformance/placeholders.ts +45 -0
  78. package/src/conformance/scenario.ts +71 -0
  79. package/src/envelope.ts +180 -0
  80. package/src/errors.ts +55 -0
  81. package/src/index.ts +63 -0
  82. package/src/leaf-path.ts +58 -0
  83. package/src/sequence.ts +60 -0
  84. package/src/types.ts +201 -0
@@ -0,0 +1,441 @@
1
+ // Conformance harness — drives a server through a YAML scenario via the
2
+ // LSDP/1 wire protocol + the HTTP test control plane.
3
+ //
4
+ // One harness per run; each scenario is fully isolated:
5
+ // 1. Hash inline bundles
6
+ // 2. POST /test/setup with tokens + bundles + initial_state
7
+ // 3. Open WebSocket to the URL returned by setup (subprotocol lsdp.v1)
8
+ // 4. Walk steps, sending/expecting frames + control-plane introspection
9
+ // 5. POST /test/reset before the next scenario
10
+ import { WebSocket } from "ws";
11
+ import { WS_SUBPROTOCOL } from "../types.js";
12
+ import { hashInlineBundle } from "./bundle-hash.js";
13
+ import { ControlClient } from "./control-client.js";
14
+ import { matchFrame } from "./match.js";
15
+ import { substitute } from "./placeholders.js";
16
+ const DEFAULT_TOKENS = {
17
+ $TOKEN_OPERATOR: "interop-tok-operator-7f3a",
18
+ $TOKEN_VIEWER: "interop-tok-viewer-7f3a",
19
+ $TOKEN_SERVICE: "interop-tok-service-7f3a",
20
+ $TOKEN_TEST: "interop-tok-test-7f3a",
21
+ $TOKEN_INVALID: "interop-tok-invalid-7f3a",
22
+ };
23
+ export class Harness {
24
+ opts;
25
+ control;
26
+ tokens;
27
+ stepTimeoutMs;
28
+ constructor(opts) {
29
+ this.opts = opts;
30
+ this.control = new ControlClient(opts.controlUrl);
31
+ this.tokens = opts.tokens ?? DEFAULT_TOKENS;
32
+ this.stepTimeoutMs = opts.stepTimeoutMs ?? 2000;
33
+ }
34
+ /** Run a single scenario. */
35
+ async runScenario(scenario) {
36
+ const base = { name: scenario.name, tag: scenario.tag, target: scenario.target };
37
+ // Skip runtime-targeted scenarios — this harness drives a server.
38
+ if (scenario.target === "runtime") {
39
+ return {
40
+ ...base,
41
+ outcome: "SKIP",
42
+ reason: "runtime-targeted scenario, harness drives a server",
43
+ };
44
+ }
45
+ let bundleHashes = {};
46
+ if (scenario.bundles && scenario.bundles.length > 0) {
47
+ bundleHashes = await this.computeBundleHashes(scenario.bundles);
48
+ }
49
+ // Build the /test/setup payload. The control plane requires at least one
50
+ // bundle; if the scenario doesn't declare any, infer scene_id +
51
+ // scene_version + initial state from the first server-sends snapshot step.
52
+ const setupBundles = buildSetupBundles(scenario, bundleHashes);
53
+ const initialState = setupBundles.initialState;
54
+ let setupResponse;
55
+ try {
56
+ setupResponse = await this.control.setup({
57
+ scenario: scenario.name,
58
+ tokens: this.tokens,
59
+ bundles: setupBundles.bundles,
60
+ initial_state: initialState,
61
+ });
62
+ }
63
+ catch (err) {
64
+ return { ...base, outcome: "FAIL", reason: `setup: ${err.message}` };
65
+ }
66
+ void setupResponse;
67
+ const wsUrl = this.opts.serverUrl ?? setupResponse.ws_url;
68
+ let ws;
69
+ try {
70
+ ws = await openSocket(wsUrl);
71
+ }
72
+ catch (err) {
73
+ await this.control.reset().catch(() => undefined);
74
+ return { ...base, outcome: "FAIL", reason: `dial: ${err.message}` };
75
+ }
76
+ const exec = new Exec(ws, this.tokens, bundleHashes, this.control, this.stepTimeoutMs);
77
+ let result = { ...base, outcome: "PASS" };
78
+ for (let i = 0; i < scenario.steps.length; i++) {
79
+ const step = scenario.steps[i];
80
+ try {
81
+ await exec.runStep(step);
82
+ }
83
+ catch (err) {
84
+ result = {
85
+ ...base,
86
+ outcome: "FAIL",
87
+ reason: `step ${i + 1} (${step.kind}): ${err.message}`,
88
+ };
89
+ break;
90
+ }
91
+ }
92
+ try {
93
+ ws.close(1000, "scenario done");
94
+ }
95
+ catch {
96
+ // ignore
97
+ }
98
+ await this.control.reset().catch(() => undefined);
99
+ return result;
100
+ }
101
+ /** Run every scenario in `scenarios` matching the tag filter (default required). */
102
+ async runAll(scenarios, tagFilter = "required") {
103
+ const rep = { total: 0, passed: 0, failed: 0, skipped: 0, results: [] };
104
+ for (const sc of scenarios) {
105
+ rep.total++;
106
+ if (sc.tag !== tagFilter) {
107
+ rep.skipped++;
108
+ rep.results.push({
109
+ name: sc.name,
110
+ tag: sc.tag,
111
+ target: sc.target,
112
+ outcome: "SKIP",
113
+ reason: `tag ${sc.tag} != filter ${tagFilter}`,
114
+ });
115
+ continue;
116
+ }
117
+ const r = await this.runScenario(sc);
118
+ rep.results.push(r);
119
+ if (r.outcome === "PASS")
120
+ rep.passed++;
121
+ else if (r.outcome === "FAIL")
122
+ rep.failed++;
123
+ else
124
+ rep.skipped++;
125
+ }
126
+ return rep;
127
+ }
128
+ async computeBundleHashes(bundles) {
129
+ const out = {};
130
+ for (const b of bundles) {
131
+ const h = await hashInlineBundle(b.inline);
132
+ b.hash = h;
133
+ out[b.id] = h;
134
+ }
135
+ return out;
136
+ }
137
+ }
138
+ class Exec {
139
+ ws;
140
+ tokens;
141
+ bundleHashes;
142
+ control;
143
+ stepTimeoutMs;
144
+ shadowState = {};
145
+ inbox = [];
146
+ waiters = [];
147
+ closed = false;
148
+ /** WebSocket close code (RFC 6455). Set on the `close` event ; used
149
+ * by `expect-no-frame-for` to distinguish clean shutdown (1000/1001/
150
+ * 1005) from abnormal closures. */
151
+ closeCode = null;
152
+ constructor(ws, tokens, bundleHashes, control, stepTimeoutMs) {
153
+ this.ws = ws;
154
+ this.tokens = tokens;
155
+ this.bundleHashes = bundleHashes;
156
+ this.control = control;
157
+ this.stepTimeoutMs = stepTimeoutMs;
158
+ // Queue messages so frames that arrive between recv() calls aren't lost.
159
+ this.ws.on("message", (data) => {
160
+ const s = String(data);
161
+ const w = this.waiters.shift();
162
+ if (w)
163
+ w(s);
164
+ else
165
+ this.inbox.push(s);
166
+ });
167
+ this.ws.on("close", (code) => {
168
+ this.closed = true;
169
+ this.closeCode = code;
170
+ // Wake every waiter so they reject promptly.
171
+ while (this.waiters.length > 0)
172
+ this.waiters.shift()(""); // signal close
173
+ });
174
+ }
175
+ async runStep(step) {
176
+ switch (step.kind) {
177
+ case "client-sends":
178
+ return this.send(step.frame ?? {});
179
+ case "server-sends":
180
+ return this.expectServerFrame(step.frame ?? {});
181
+ case "server-emits":
182
+ return this.serverEmits(step.frame ?? {});
183
+ case "expect-runtime-state":
184
+ return this.expectRuntimeState(step.state ?? {});
185
+ case "expect-server-state":
186
+ return this.expectServerState(step.state ?? {});
187
+ case "expect-no-frame-for":
188
+ return this.expectQuiet(step.duration_ms ?? 0);
189
+ case "expect-client-action":
190
+ return this.expectClientAction(step.action, step.reason);
191
+ default:
192
+ throw new Error(`unsupported step kind ${step.kind}`);
193
+ }
194
+ }
195
+ /**
196
+ * `server-emits` (SCENARIO-FORMAT.md) — harness orchestrates a
197
+ * server-driven frame via the test control plane, then validates
198
+ * the wire form. Only `frame.type === "delta"` is currently
199
+ * supported (POST /test/emit).
200
+ */
201
+ async serverEmits(expected) {
202
+ if (expected["type"] !== "delta" || !Array.isArray(expected["patches"])) {
203
+ throw new Error(`server-emits only supports type=delta today, got ${String(expected["type"])}`);
204
+ }
205
+ const patches = expected["patches"];
206
+ const resolved = patches.map((p) => ({
207
+ path: p.path,
208
+ value: substitute(p.value, this.tokens, this.bundleHashes),
209
+ }));
210
+ await this.control.emit(resolved);
211
+ return this.expectServerFrame(expected);
212
+ }
213
+ send(frame) {
214
+ const resolved = substitute(frame, this.tokens, this.bundleHashes);
215
+ return new Promise((resolve, reject) => {
216
+ this.ws.send(JSON.stringify(resolved), (err) => {
217
+ if (err)
218
+ reject(err);
219
+ else
220
+ resolve();
221
+ });
222
+ });
223
+ }
224
+ async expectServerFrame(expected) {
225
+ // Try to read what's already in flight first (snapshots, error frames, and
226
+ // operator-input echoes arrive without prompting). Only fall back to
227
+ // /test/emit when nothing arrives within a short window AND the expected
228
+ // frame is a delta — that's the case where the server needs nudging.
229
+ const want = substitute(expected, this.tokens, this.bundleHashes);
230
+ let actual = null;
231
+ try {
232
+ const raw = await this.recv(150);
233
+ actual = JSON.parse(raw);
234
+ }
235
+ catch {
236
+ // No frame yet — if the expected is a delta, drive it via /test/emit.
237
+ if (expected["type"] === "delta" && Array.isArray(expected["patches"])) {
238
+ const patches = expected["patches"];
239
+ const resolved = patches.map((p) => ({
240
+ path: p.path,
241
+ value: substitute(p.value, this.tokens, this.bundleHashes),
242
+ }));
243
+ try {
244
+ await this.control.emit(resolved);
245
+ }
246
+ catch {
247
+ // Swallow — the matcher will report any actual mismatch.
248
+ }
249
+ }
250
+ const raw = await this.recv(this.stepTimeoutMs);
251
+ actual = JSON.parse(raw);
252
+ }
253
+ const err = matchFrame(want, actual);
254
+ if (err) {
255
+ throw new Error(`frame mismatch at ${err.path}: ${err.reason} (got ${JSON.stringify(actual)})`);
256
+ }
257
+ this.absorb(actual);
258
+ }
259
+ absorb(frame) {
260
+ if (frame["type"] === "snapshot") {
261
+ const state = frame["state"] ?? {};
262
+ this.shadowState = { ...state };
263
+ }
264
+ else if (frame["type"] === "delta") {
265
+ const patches = frame["patches"] ?? [];
266
+ for (const p of patches)
267
+ this.shadowState[p.path] = p.value;
268
+ }
269
+ }
270
+ expectRuntimeState(want) {
271
+ for (const [k, v] of Object.entries(want)) {
272
+ if (!(k in this.shadowState)) {
273
+ throw new Error(`runtime state missing ${k}`);
274
+ }
275
+ const got = this.shadowState[k];
276
+ if (JSON.stringify(got) !== JSON.stringify(v)) {
277
+ throw new Error(`runtime state ${k}: want ${JSON.stringify(v)}, got ${JSON.stringify(got)}`);
278
+ }
279
+ }
280
+ }
281
+ async expectServerState(want) {
282
+ const snap = await this.control.state();
283
+ for (const [k, v] of Object.entries(want)) {
284
+ if (!(k in snap.state)) {
285
+ throw new Error(`server state missing ${k}`);
286
+ }
287
+ const got = snap.state[k];
288
+ if (JSON.stringify(got) !== JSON.stringify(v)) {
289
+ throw new Error(`server state ${k}: want ${JSON.stringify(v)}, got ${JSON.stringify(got)}`);
290
+ }
291
+ }
292
+ }
293
+ async expectQuiet(durationMs) {
294
+ try {
295
+ const raw = await this.recv(durationMs);
296
+ throw new Error(`expected silence for ${durationMs}ms, got frame: ${raw}`);
297
+ }
298
+ catch (err) {
299
+ const msg = err.message;
300
+ if (msg === "recv timeout")
301
+ return;
302
+ // SCENARIO-FORMAT.md `expect-no-frame-for` § Connection-close
303
+ // semantics : clean WS close (1000/1001/1005) within the duration
304
+ // counts as success — no data flowed. Abnormal closures still
305
+ // surface as errors.
306
+ if (msg === "connection closed") {
307
+ const code = this.closeCode;
308
+ if (code === 1000 || code === 1001 || code === 1005)
309
+ return;
310
+ }
311
+ throw err;
312
+ }
313
+ }
314
+ async expectClientAction(action, _reason) {
315
+ if (!action)
316
+ throw new Error("expect-client-action: action required");
317
+ if (action === "close-with-reason" || action === "reconnect") {
318
+ // Read should reject (connection closed or no further frames).
319
+ try {
320
+ await this.recv(this.stepTimeoutMs);
321
+ }
322
+ catch (err) {
323
+ if (err.message === "recv timeout")
324
+ return;
325
+ // close → recv rejects, that's the success path.
326
+ return;
327
+ }
328
+ throw new Error(`expected connection close or no frame, got data`);
329
+ }
330
+ throw new Error(`unknown client action ${action}`);
331
+ }
332
+ recv(timeoutMs) {
333
+ return new Promise((resolve, reject) => {
334
+ const queued = this.inbox.shift();
335
+ if (queued !== undefined) {
336
+ resolve(queued);
337
+ return;
338
+ }
339
+ if (this.closed) {
340
+ reject(new Error("connection closed"));
341
+ return;
342
+ }
343
+ const t = setTimeout(() => {
344
+ const i = this.waiters.indexOf(resolveAndDispatch);
345
+ if (i >= 0)
346
+ this.waiters.splice(i, 1);
347
+ reject(new Error("recv timeout"));
348
+ }, timeoutMs);
349
+ const resolveAndDispatch = (v) => {
350
+ clearTimeout(t);
351
+ if (v === "" && this.closed)
352
+ reject(new Error("connection closed"));
353
+ else
354
+ resolve(v);
355
+ };
356
+ this.waiters.push(resolveAndDispatch);
357
+ });
358
+ }
359
+ }
360
+ function openSocket(url) {
361
+ return new Promise((resolve, reject) => {
362
+ const ws = new WebSocket(url, [WS_SUBPROTOCOL]);
363
+ ws.once("open", () => resolve(ws));
364
+ ws.once("error", reject);
365
+ });
366
+ }
367
+ function extractInitialState(bundles) {
368
+ // The Go reference reads `initial_state` from the scenario top-level when
369
+ // present. Our scenarios encode it inside each bundle's `defaults` field
370
+ // (LSML 1.0 §10). Pull from the first bundle's defaults if any.
371
+ const primary = bundles[0];
372
+ if (primary && typeof primary.inline === "object" && primary.inline !== null) {
373
+ const defaults = primary.inline.defaults;
374
+ if (defaults && typeof defaults === "object")
375
+ return defaults;
376
+ }
377
+ return {};
378
+ }
379
+ /** Build the bundles + initial_state payload for /test/setup.
380
+ * When the scenario declares bundles, use them verbatim. Otherwise, infer
381
+ * scene_id + scene_version + initial state from the first server-sends
382
+ * snapshot step in the scenario — the same shape the harness will later
383
+ * expect on the wire. */
384
+ function buildSetupBundles(scenario, bundleHashes) {
385
+ if (scenario.bundles && scenario.bundles.length > 0) {
386
+ return {
387
+ bundles: scenario.bundles.map((b) => ({
388
+ id: b.id,
389
+ hash: bundleHashes[b.id] ?? "",
390
+ inline: b.inline,
391
+ })),
392
+ initialState: extractInitialState(scenario.bundles),
393
+ };
394
+ }
395
+ // Look for the first `server-sends snapshot` step.
396
+ let sceneId = "t";
397
+ let sceneVersion = "sha256:" + "f".repeat(64);
398
+ let initialState = {};
399
+ for (const step of scenario.steps) {
400
+ if (step.kind !== "server-sends" || !step.frame || step.frame["type"] !== "snapshot") {
401
+ continue;
402
+ }
403
+ const snap = step.frame;
404
+ if (typeof snap["scene_id"] === "string" && snap["scene_id"] !== "$ANY") {
405
+ sceneId = snap["scene_id"];
406
+ }
407
+ if (typeof snap["scene_version"] === "string" && snap["scene_version"] !== "$ANY_HASH") {
408
+ sceneVersion = snap["scene_version"];
409
+ }
410
+ if (snap["state"] && typeof snap["state"] === "object") {
411
+ initialState = snap["state"];
412
+ }
413
+ break;
414
+ }
415
+ // Synthesize an `operator_inputs` schema declaring every __inputs.* path
416
+ // present in the initial state. This makes the server reject UNKNOWN_PATH
417
+ // for inputs on undeclared paths, mirroring real-server semantics.
418
+ const operatorInputs = Object.keys(initialState)
419
+ .filter((p) => p.startsWith("__inputs."))
420
+ .map((p) => ({
421
+ path: p,
422
+ label: p,
423
+ type: typeof initialState[p] === "number" ? "number" : "string",
424
+ writable_by: ["operator"],
425
+ }));
426
+ return {
427
+ bundles: [
428
+ {
429
+ id: sceneId,
430
+ hash: sceneVersion,
431
+ inline: {
432
+ scene_id: sceneId,
433
+ synthetic: true,
434
+ ...(operatorInputs.length > 0 ? { operator_inputs: operatorInputs } : {}),
435
+ },
436
+ },
437
+ ],
438
+ initialState,
439
+ };
440
+ }
441
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/conformance/harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { parseScenario, type Scenario, type Step, type StepKind, type Tag, type Target, type ClientAction, type BundleDecl, } from "./scenario.js";
2
+ export { loadScenarios, type LoadOptions } from "./loader.js";
3
+ export { matchFrame, matchValue, type MatchError } from "./match.js";
4
+ export { substitute } from "./placeholders.js";
5
+ export { canonicalize, hashInlineBundle } from "./bundle-hash.js";
6
+ export { ControlClient, type SetupRequest, type SetupResponse, type StateResponse, type HealthResponse, } from "./control-client.js";
7
+ export { Harness, type HarnessOptions, type Outcome, type ScenarioResult, type Report, } from "./harness.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conformance/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,GAAG,EACR,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,MAAM,GACZ,MAAM,cAAc,CAAC"}
@@ -0,0 +1,12 @@
1
+ // Public surface of @lumencast/protocol/conformance.
2
+ //
3
+ // Loaders + harness for the LSDP/1 conformance scenarios. Used by the
4
+ // `lumencast-js conformance` CLI and by interop matrix runs.
5
+ export { parseScenario, } from "./scenario.js";
6
+ export { loadScenarios } from "./loader.js";
7
+ export { matchFrame, matchValue } from "./match.js";
8
+ export { substitute } from "./placeholders.js";
9
+ export { canonicalize, hashInlineBundle } from "./bundle-hash.js";
10
+ export { ControlClient, } from "./control-client.js";
11
+ export { Harness, } from "./harness.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/conformance/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,6DAA6D;AAE7D,OAAO,EACL,aAAa,GAQd,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,aAAa,GAKd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,OAAO,GAKR,MAAM,cAAc,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type Scenario } from "./scenario.js";
2
+ export interface LoadOptions {
3
+ /** Directory containing the *.yaml scenarios. Required. */
4
+ scenariosDir: string;
5
+ /** When set, only load this single scenario (basename without .yaml). */
6
+ scenarioName?: string;
7
+ }
8
+ export declare function loadScenarios(opts: LoadOptions): Scenario[];
9
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/conformance/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,EAAE,CAwB3D"}
@@ -0,0 +1,27 @@
1
+ // Filesystem loader for scenarios. Reads YAML files from disk by path. The
2
+ // CLI uses this to find scenarios under `lumencast-protocol/conformance/v1/scenarios/`.
3
+ import { readdirSync, readFileSync, statSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
+ import { parseScenario } from "./scenario.js";
6
+ export function loadScenarios(opts) {
7
+ const dir = resolve(opts.scenariosDir);
8
+ const stat = statSync(dir, { throwIfNoEntry: false });
9
+ if (!stat || !stat.isDirectory()) {
10
+ throw new Error(`scenarios directory not found: ${dir}`);
11
+ }
12
+ let files = readdirSync(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
13
+ if (opts.scenarioName) {
14
+ files = files.filter((f) => f === `${opts.scenarioName}.yaml` || f === `${opts.scenarioName}.yml`);
15
+ if (files.length === 0) {
16
+ throw new Error(`scenario not found in ${dir}: ${opts.scenarioName}`);
17
+ }
18
+ }
19
+ files.sort();
20
+ const out = [];
21
+ for (const f of files) {
22
+ const raw = readFileSync(join(dir, f), "utf8");
23
+ out.push(parseScenario(raw));
24
+ }
25
+ return out;
26
+ }
27
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/conformance/loader.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wFAAwF;AAExF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAiB,MAAM,eAAe,CAAC;AAS7D,MAAM,UAAU,aAAa,CAAC,IAAiB;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,KAAK,GAAG,KAAK,CAAC,MAAM,CAClB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,MAAM,CAC7E,CAAC;QACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/C,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface MatchError {
2
+ path: string;
3
+ reason: string;
4
+ }
5
+ export declare function matchFrame(expected: Record<string, unknown>, actual: Record<string, unknown>): MatchError | null;
6
+ export declare function matchValue(expected: unknown, actual: unknown, path: string): MatchError | null;
7
+ //# sourceMappingURL=match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/conformance/match.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,UAAU,GAAG,IAAI,CASnB;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAyC9F"}
@@ -0,0 +1,82 @@
1
+ // Frame matcher with $ANY / $ANY_HASH sentinels. Mirrors
2
+ // lumencast-go/conformance/match.go.
3
+ //
4
+ // matchValue rules :
5
+ // - "$ANY" → matches any present value
6
+ // - "$ANY_HASH" → matches a sha256:<hex64> string
7
+ // - object → recurse on each key in the expected template; extra fields in
8
+ // the actual object are tolerated (forward-compat)
9
+ // - array → length and element-wise match
10
+ // - scalar → strict equality (numeric tower normalized)
11
+ const SHA256_RE = /^sha256:[0-9a-f]{64}$/;
12
+ export function matchFrame(expected, actual) {
13
+ for (const [k, want] of Object.entries(expected)) {
14
+ if (!(k in actual)) {
15
+ return { path: k, reason: `missing field` };
16
+ }
17
+ const err = matchValue(want, actual[k], k);
18
+ if (err)
19
+ return err;
20
+ }
21
+ return null;
22
+ }
23
+ export function matchValue(expected, actual, path) {
24
+ if (typeof expected === "string") {
25
+ if (expected === "$ANY")
26
+ return null;
27
+ if (expected === "$ANY_HASH") {
28
+ if (typeof actual !== "string" || !SHA256_RE.test(actual)) {
29
+ return { path, reason: `not a sha256 hash: ${JSON.stringify(actual)}` };
30
+ }
31
+ return null;
32
+ }
33
+ }
34
+ if (Array.isArray(expected)) {
35
+ if (!Array.isArray(actual)) {
36
+ return { path, reason: `want array, got ${typeOf(actual)}` };
37
+ }
38
+ if (expected.length !== actual.length) {
39
+ return { path, reason: `length ${expected.length} != ${actual.length}` };
40
+ }
41
+ for (let i = 0; i < expected.length; i++) {
42
+ const err = matchValue(expected[i], actual[i], `${path}[${i}]`);
43
+ if (err)
44
+ return err;
45
+ }
46
+ return null;
47
+ }
48
+ if (typeof expected === "object" && expected !== null) {
49
+ if (typeof actual !== "object" || actual === null || Array.isArray(actual)) {
50
+ return { path, reason: `want object, got ${typeOf(actual)}` };
51
+ }
52
+ return matchFrame(expected, actual)
53
+ ? prefix(path, matchFrame(expected, actual))
54
+ : null;
55
+ }
56
+ if (!equalScalar(expected, actual)) {
57
+ return {
58
+ path,
59
+ reason: `want ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`,
60
+ };
61
+ }
62
+ return null;
63
+ }
64
+ function prefix(p, err) {
65
+ return { path: `${p}.${err.path}`, reason: err.reason };
66
+ }
67
+ function equalScalar(a, b) {
68
+ if (a === b)
69
+ return true;
70
+ if (typeof a === "number" && typeof b === "number") {
71
+ return a === b || (Number.isNaN(a) && Number.isNaN(b));
72
+ }
73
+ return false;
74
+ }
75
+ function typeOf(v) {
76
+ if (v === null)
77
+ return "null";
78
+ if (Array.isArray(v))
79
+ return "array";
80
+ return typeof v;
81
+ }
82
+ //# sourceMappingURL=match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.js","sourceRoot":"","sources":["../../src/conformance/match.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function substitute(value: unknown, tokens: Record<string, string>, bundleHashes: Record<string, string>): unknown;
2
+ //# sourceMappingURL=placeholders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placeholders.d.ts","sourceRoot":"","sources":["../../src/conformance/placeholders.ts"],"names":[],"mappings":"AAgBA,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CAwBT"}