@ai-matrx/content-ir 0.2.0 → 0.2.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/CHANGELOG.md +22 -0
- package/dist/index.cjs +45 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -5
- package/dist/index.d.ts +16 -5
- package/dist/index.js +45 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 — 2026-08-24
|
|
4
|
+
|
|
5
|
+
- **FIX — `validateStructuralLeg` no longer rejects every current kind
|
|
6
|
+
instance.** The leg validated ONLY the `__kind`-stripped copy of the sample,
|
|
7
|
+
a leftover from the dead "marker is envelope framing" doctrine. Since the
|
|
8
|
+
2026-08-23 ruling every `emitted_json_schema` DECLARES `__kind` (const +
|
|
9
|
+
required), so stripping turned a valid instance into
|
|
10
|
+
`(root) must have required property '__kind'` — 503 of the 842 live kind
|
|
11
|
+
definitions, i.e. every marker-declaring kind, failed the Shape Studio Test
|
|
12
|
+
tab, the gate tab, the example manager, and instance save. The leg now
|
|
13
|
+
validates the caller's value VERBATIM and only retries the marker-free
|
|
14
|
+
reduction if that fails (backward compatibility for a row still pinned to a
|
|
15
|
+
pre-2026-08-23 marker-free schema), and reports the errors from whichever
|
|
16
|
+
attempt matches the schema in hand.
|
|
17
|
+
- `JsonTokenizer` and `KindStreamParser` declare explicit fields instead of
|
|
18
|
+
constructor parameter properties. Consumers compile this SOURCE directly, and
|
|
19
|
+
a strict host (`apps/dashboard`) sets `erasableSyntaxOnly`, under which
|
|
20
|
+
parameter properties are a hard error — the flag had to be turned off in
|
|
21
|
+
Workflow Studio for exactly this reason, and is now back on. Behaviour is
|
|
22
|
+
unchanged; the published 0.2.0 tarball does not carry this edit.
|
|
23
|
+
|
|
24
|
+
|
|
3
25
|
## 0.2.0 — 2026-08-23
|
|
4
26
|
|
|
5
27
|
- Added the `wire/` layer — the server→UI contracts every UI reads the same way:
|
package/dist/index.cjs
CHANGED
|
@@ -404,16 +404,19 @@ var IrTree = class {
|
|
|
404
404
|
|
|
405
405
|
// core/json-tokenizer.ts
|
|
406
406
|
var JsonStreamTokenizer = class {
|
|
407
|
-
constructor(onToken) {
|
|
408
|
-
this.onToken = onToken;
|
|
409
|
-
}
|
|
410
|
-
onToken;
|
|
411
407
|
mode = "normal";
|
|
412
408
|
pos = 0;
|
|
413
409
|
stringBuffer = "";
|
|
414
410
|
primitiveBuffer = "";
|
|
415
411
|
unicodeBuffer = "";
|
|
416
412
|
tokenStart = 0;
|
|
413
|
+
onToken;
|
|
414
|
+
// Explicit field rather than a parameter property: consumers compile this
|
|
415
|
+
// source directly, and a strict host (the dashboard) sets
|
|
416
|
+
// `erasableSyntaxOnly`, under which parameter properties are a hard error.
|
|
417
|
+
constructor(onToken) {
|
|
418
|
+
this.onToken = onToken;
|
|
419
|
+
}
|
|
417
420
|
get position() {
|
|
418
421
|
return this.pos;
|
|
419
422
|
}
|
|
@@ -636,16 +639,6 @@ function safeCopy(value) {
|
|
|
636
639
|
}
|
|
637
640
|
}
|
|
638
641
|
var KindStreamParser = class {
|
|
639
|
-
constructor(options) {
|
|
640
|
-
this.options = options;
|
|
641
|
-
this.resolver = isSchemaResolver(options.schemas) ? options.schemas : {
|
|
642
|
-
get: (kind) => options.schemas[kind]
|
|
643
|
-
};
|
|
644
|
-
this.tokenizer = new JsonStreamTokenizer(
|
|
645
|
-
(token) => this.handleToken(token)
|
|
646
|
-
);
|
|
647
|
-
}
|
|
648
|
-
options;
|
|
649
642
|
resolver;
|
|
650
643
|
stack = [];
|
|
651
644
|
objectKinds = /* @__PURE__ */ new Map();
|
|
@@ -680,6 +673,18 @@ var KindStreamParser = class {
|
|
|
680
673
|
rootKind = "";
|
|
681
674
|
rootDone = false;
|
|
682
675
|
failed = false;
|
|
676
|
+
options;
|
|
677
|
+
// Explicit field, not a parameter property — see the note in
|
|
678
|
+
// `json-tokenizer.ts`: `erasableSyntaxOnly` hosts compile this source.
|
|
679
|
+
constructor(options) {
|
|
680
|
+
this.options = options;
|
|
681
|
+
this.resolver = isSchemaResolver(options.schemas) ? options.schemas : {
|
|
682
|
+
get: (kind) => options.schemas[kind]
|
|
683
|
+
};
|
|
684
|
+
this.tokenizer = new JsonStreamTokenizer(
|
|
685
|
+
(token) => this.handleToken(token)
|
|
686
|
+
);
|
|
687
|
+
}
|
|
683
688
|
push(chunk) {
|
|
684
689
|
if (this.failed || this.rootDone) return;
|
|
685
690
|
try {
|
|
@@ -2773,6 +2778,12 @@ function storageToKindSchema(kind, shape) {
|
|
|
2773
2778
|
}
|
|
2774
2779
|
return { kind, fields };
|
|
2775
2780
|
}
|
|
2781
|
+
var GENERIC_FALLBACK_COMPONENT_KEY = "generic_structured";
|
|
2782
|
+
function satisfies(resolved) {
|
|
2783
|
+
return Boolean(
|
|
2784
|
+
resolved?.isActive && resolved.componentKey !== GENERIC_FALLBACK_COMPONENT_KEY
|
|
2785
|
+
);
|
|
2786
|
+
}
|
|
2776
2787
|
var ajv = new Ajv__default.default({ allErrors: true, strict: false });
|
|
2777
2788
|
function stripKind(value) {
|
|
2778
2789
|
if (Array.isArray(value)) return value.map(stripKind);
|
|
@@ -2786,6 +2797,14 @@ function stripKind(value) {
|
|
|
2786
2797
|
}
|
|
2787
2798
|
return value;
|
|
2788
2799
|
}
|
|
2800
|
+
function describeAjvErrors(errors) {
|
|
2801
|
+
return (errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message ?? ""}`.trim()).slice(0, 8);
|
|
2802
|
+
}
|
|
2803
|
+
function schemaDeclaresKind(emittedJsonSchema) {
|
|
2804
|
+
if (!emittedJsonSchema || typeof emittedJsonSchema !== "object") return false;
|
|
2805
|
+
const properties = emittedJsonSchema.properties;
|
|
2806
|
+
return !!properties && typeof properties === "object" && KIND_KEY in properties;
|
|
2807
|
+
}
|
|
2789
2808
|
function validateStructuralLeg(sample, emittedJsonSchema) {
|
|
2790
2809
|
let validate;
|
|
2791
2810
|
try {
|
|
@@ -2796,9 +2815,11 @@ function validateStructuralLeg(sample, emittedJsonSchema) {
|
|
|
2796
2815
|
detail: `emitted_json_schema failed to compile: ${err instanceof Error ? err.message : String(err)}`
|
|
2797
2816
|
};
|
|
2798
2817
|
}
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2818
|
+
if (validate(sample)) return { ok: true };
|
|
2819
|
+
const markedErrors = describeAjvErrors(validate.errors);
|
|
2820
|
+
if (validate(stripKind(sample))) return { ok: true };
|
|
2821
|
+
const strippedErrors = describeAjvErrors(validate.errors);
|
|
2822
|
+
const errors = schemaDeclaresKind(emittedJsonSchema) ? markedErrors : strippedErrors;
|
|
2802
2823
|
return { ok: false, detail: `sample failed schema: ${errors.join("; ")}` };
|
|
2803
2824
|
}
|
|
2804
2825
|
var SERVER_DATA_ANNOTATION_KEYS = /* @__PURE__ */ new Set(["language"]);
|
|
@@ -2848,16 +2869,18 @@ function validateRender(kind, sample, definition, resolvedComponent, dataOnly) {
|
|
|
2848
2869
|
detail: "data-only contract kind \u2014 render leg is structurally inapplicable (n/a)"
|
|
2849
2870
|
};
|
|
2850
2871
|
}
|
|
2851
|
-
|
|
2872
|
+
const onlyFallback = resolvedComponent?.isActive && resolvedComponent.componentKey === GENERIC_FALLBACK_COMPONENT_KEY;
|
|
2873
|
+
const noComponentDetail = onlyFallback ? `the only active role='output' component for kind "${kind}" is '${GENERIC_FALLBACK_COMPONENT_KEY}' \u2014 that IS the generic viewer, i.e. no component. A reader would get a key/value dump. Author a real source='db' component (or register a compiled one), then retire the generic row.` : null;
|
|
2874
|
+
if (!definition && !satisfies(resolvedComponent)) {
|
|
2852
2875
|
return {
|
|
2853
2876
|
ok: false,
|
|
2854
|
-
detail: `kind "${kind}" has no component (not in the compiled registry, and no active role='output' kind_component row) \u2014 nothing to render`
|
|
2877
|
+
detail: noComponentDetail ?? `kind "${kind}" has no component (not in the compiled registry, and no active role='output' kind_component row) \u2014 nothing to render`
|
|
2855
2878
|
};
|
|
2856
2879
|
}
|
|
2857
|
-
if (definition && !definition.legacyBlockType && !definition.component && !definition.toLegacyServerData && !resolvedComponent
|
|
2880
|
+
if (definition && !definition.legacyBlockType && !definition.component && !definition.toLegacyServerData && !satisfies(resolvedComponent)) {
|
|
2858
2881
|
return {
|
|
2859
2882
|
ok: false,
|
|
2860
|
-
detail: `kind "${kind}" has no component (no compiled legacyBlockType/component facet, and no active role='output' kind_component row) \u2014 nothing to render`
|
|
2883
|
+
detail: noComponentDetail ?? `kind "${kind}" has no component (no compiled legacyBlockType/component facet, and no active role='output' kind_component row) \u2014 nothing to render`
|
|
2861
2884
|
};
|
|
2862
2885
|
}
|
|
2863
2886
|
if (definition?.toLegacyServerData) {
|
|
@@ -2881,7 +2904,7 @@ function validateRender(kind, sample, definition, resolvedComponent, dataOnly) {
|
|
|
2881
2904
|
}
|
|
2882
2905
|
return { ok: true };
|
|
2883
2906
|
}
|
|
2884
|
-
const satisfier = definition?.legacyBlockType ? `compiled component "${definition.legacyBlockType}"` : definition?.component ? "compiled component facet" : resolvedComponent ? `resolved ${resolvedComponent.source} component "${resolvedComponent.componentKey}"` : "component";
|
|
2907
|
+
const satisfier = definition?.legacyBlockType ? `compiled component "${definition.legacyBlockType}"` : definition?.component ? "compiled component facet" : satisfies(resolvedComponent) && resolvedComponent ? `resolved ${resolvedComponent.source} component "${resolvedComponent.componentKey}"` : "component";
|
|
2885
2908
|
return {
|
|
2886
2909
|
ok: true,
|
|
2887
2910
|
detail: `bridgeless kind \u2014 ${satisfier} parses content itself; full DOM render check deferred to an RTL harness`
|