@carbonenginejs/runtime-resource 0.17.0 → 0.18.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 (89) hide show
  1. package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +16 -4
  2. package/dist/format/carbonEffect/CjsCarbonEffectWriter.js.map +1 -1
  3. package/dist/format/carbonEffect/backendEngineId.js +1 -3
  4. package/dist/format/carbonEffect/backendEngineId.js.map +1 -1
  5. package/dist/format/carbonEffect/buildCarbonEffectContainer.js +11 -1
  6. package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -1
  7. package/dist/format/carbonEffect/carbonEffectBackendBlock.js +38 -1
  8. package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
  9. package/dist/format/carbonEffect/carbonEffectRecords.js +45 -1
  10. package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
  11. package/dist/format/carbonEffect/carbonEffectResourceTransform.js +120 -60
  12. package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -1
  13. package/dist/format/effect/effectPermutationGraph.js +46 -29
  14. package/dist/format/effect/effectPermutationGraph.js.map +1 -1
  15. package/dist/format/index.js +1 -1
  16. package/dist/formats/dds/core/helpers.js +35 -6
  17. package/dist/formats/dds/core/helpers.js.map +1 -1
  18. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +53 -1
  19. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
  20. package/dist/formats/hlsl/core/detailMapFamily.js +1 -1
  21. package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -1
  22. package/dist/formats/hlsl/core/localLightFamily.js +1 -1
  23. package/dist/formats/hlsl/core/localLightFamily.js.map +1 -1
  24. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +10 -1
  25. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
  26. package/dist/formats/index.js +3 -0
  27. package/dist/formats/index.js.map +1 -1
  28. package/dist/formats/schemabound/CjsSchemaBoundFormat.js +236 -0
  29. package/dist/formats/schemabound/CjsSchemaBoundFormat.js.map +1 -0
  30. package/dist/formats/schemabound/core/schemaBoundErrors.js +9 -0
  31. package/dist/formats/schemabound/core/schemaBoundErrors.js.map +1 -0
  32. package/dist/formats/schemabound/core/schemaBoundValues.js +307 -0
  33. package/dist/formats/schemabound/core/schemaBoundValues.js.map +1 -0
  34. package/dist/formats/schemabound/index.js +2 -0
  35. package/dist/formats/schemabound/index.js.map +1 -0
  36. package/dist/formats/sqlite/CjsSqliteFormat.js +244 -0
  37. package/dist/formats/sqlite/CjsSqliteFormat.js.map +1 -0
  38. package/dist/formats/sqlite/core/sqlitePages.js +159 -0
  39. package/dist/formats/sqlite/core/sqlitePages.js.map +1 -0
  40. package/dist/formats/sqlite/core/sqliteRecords.js +174 -0
  41. package/dist/formats/sqlite/core/sqliteRecords.js.map +1 -0
  42. package/dist/formats/sqlite/core/sqliteSchema.js +100 -0
  43. package/dist/formats/sqlite/core/sqliteSchema.js.map +1 -0
  44. package/dist/formats/sqlite/index.js +2 -0
  45. package/dist/formats/sqlite/index.js.map +1 -0
  46. package/dist/formats/static/CjsStaticFormat.js +220 -0
  47. package/dist/formats/static/CjsStaticFormat.js.map +1 -0
  48. package/dist/formats/static/index.js +2 -0
  49. package/dist/formats/static/index.js.map +1 -0
  50. package/dist/formats/webgl/core/buildGlslEffectContainer.js +3 -1
  51. package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -1
  52. package/dist/formats/webgl/core/effectPackage.js +13 -5
  53. package/dist/formats/webgl/core/effectPackage.js.map +1 -1
  54. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +10 -2
  55. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  56. package/dist/formats/webgl/core/glslBackendBlock.js +6 -5
  57. package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -1
  58. package/dist/formats/webgl/core/glslBackendBodySet.js +0 -1
  59. package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -1
  60. package/dist/formats/webgpu/CjsWebgpuFormat.js +161 -163
  61. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  62. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +3 -1
  63. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
  64. package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js +179 -131
  65. package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -1
  66. package/dist/formats/webgpu/core/effectBackendBodySet.js +2 -3
  67. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  68. package/dist/formats/webgpu/core/helpers.js +111 -99
  69. package/dist/formats/webgpu/core/helpers.js.map +1 -1
  70. package/dist/formats/webgpu/core/packageEffect.js +44 -33
  71. package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
  72. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +9 -1
  73. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
  74. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +14 -0
  75. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  76. package/docs/concepts/shader-resource-model.md +34 -1
  77. package/docs/formats/README.md +21 -0
  78. package/docs/formats/carbon-effect-container.md +54 -27
  79. package/docs/formats/schemabound.md +112 -0
  80. package/docs/formats/static.md +119 -0
  81. package/docs/formats/webgl/README.md +5 -3
  82. package/docs/formats/webgpu/README.md +2 -2
  83. package/docs/formats/webgpu/architecture.md +2 -2
  84. package/docs/formats/webgpu/formats/carbon-webgpu.md +24 -6
  85. package/docs/formats/webgpu/guides/effect-packaging.md +1 -2
  86. package/docs/formats/webgpu/reference/api.md +7 -6
  87. package/docs/formats/webgpu/reference/wgsl-compatibility.md +2 -2
  88. package/docs/reference/classes/formats.md +33 -0
  89. package/package.json +5 -2
@@ -0,0 +1,112 @@
1
+ # Schema-bound containers
2
+
3
+ Status: Experimental
4
+ Scope: `@carbonenginejs/runtime-resource/formats/schemabound`
5
+ Audience: Anyone reading client static data whose layout ships beside it
6
+ Summary: Reads a binary record container against the separate schema document that describes its layout, including the variable-length record section that makes a fixed-stride reader silently wrong.
7
+
8
+ ## Why this exists
9
+
10
+ Some client containers carry no layout at all. They pair a binary payload with a
11
+ sibling schema document — YAML — that states every attribute's offset, width and
12
+ type, which fields are optional, how lists are strided, and how the container
13
+ indexes its own records.
14
+
15
+ That makes them the opposite of a hash-identified container, where the header
16
+ names a layout it does not describe and the layout has to be derived and pinned
17
+ per dataset. **Nothing needs deriving here.** Supply the schema and the payload
18
+ decodes.
19
+
20
+ It also makes them unusually easy to read wrongly. The bytes carry no signature,
21
+ no version and no field names, so given the wrong schema they decode into
22
+ plausible nonsense rather than failing — there is nothing in them to disagree
23
+ with. Pair each payload with the schema that shipped beside it.
24
+
25
+ ## Use
26
+
27
+ ```js
28
+ import { CjsSchemaBoundFormat } from
29
+ "@carbonenginejs/runtime-resource/formats/schemabound";
30
+
31
+ const records = CjsSchemaBoundFormat.read(payloadBytes, { schema: schemaBytes });
32
+ ```
33
+
34
+ `schema` accepts the schema document in any form it arrives in: YAML bytes, YAML
35
+ text, or an already-parsed object. YAML is parsed with `CjsYamlFormat`, and
36
+ anchors and aliases are rejoined — these schemas share repeated declarations that
37
+ way, and left unresolved an anchor reads as one more field.
38
+
39
+ - `read` / `readJSON` — plain JSON-compatible values; a wide integer becomes a
40
+ decimal string.
41
+ - `readPayload` — the same, with wide integers left as `BigInt`.
42
+ - `is` / `isSupported` — **these ask about the schema, not the payload.** These
43
+ containers have no signature, so claiming to recognize the bytes would be a
44
+ claim this format cannot support. Which family a `.static` file belongs to is
45
+ [`CjsStaticFormat`](static.md)'s question.
46
+
47
+ The root is whatever the schema declares: a keyed map decodes to an object, a
48
+ list decodes to an array.
49
+
50
+ ## The format
51
+
52
+ Four properties are worth knowing before writing anything that consumes the
53
+ result. Each of them is a way to get a plausible wrong answer.
54
+
55
+ **A keyed container's index is at the end, and nothing points at it.** The last
56
+ four bytes of the block are the index's own size; the index starts that far back,
57
+ and begins with its entry count. Reading forward from the header will not find
58
+ it.
59
+
60
+ **Record offsets are relative to the four-byte length header, not to the file.**
61
+ Decoding from the file start reads one field early, and produces zeroes that look
62
+ like a wrong layout rather than a wrong base.
63
+
64
+ **The per-record offset table varies in length.** After the fixed attributes come
65
+ a presence bitfield and then one offset per attribute *actually present* — an
66
+ optional attribute whose bit is clear takes no slot. Consecutive records
67
+ therefore hold their variable data at different distances from their own start,
68
+ so a reader written around a constant stride decodes the first record correctly
69
+ and then drifts.
70
+
71
+ **A list has two framings and the schema says which.** `fixedItemSize` means the
72
+ items are packed at that stride. Its absence means they are variable, so the
73
+ count is followed by one offset per item, measured from the start of the list.
74
+
75
+ Two smaller rules:
76
+
77
+ - The presence bitfield is written whenever a record has a variable section at
78
+ all, including where nothing in it is optional and the field is always zero.
79
+ It is the offset table that shrinks, never the bitfield.
80
+ - An absent optional takes the default its schema declares. Where no default is
81
+ declared the attribute is left off the record entirely.
82
+
83
+ ## Types
84
+
85
+ | Schema type | Decoded as |
86
+ |---|---|
87
+ | `int` | number at the declared width; signed unless `min` is zero or more; `BigInt` beyond the safe range |
88
+ | `float` | number, single or double by declared size |
89
+ | `bool` | boolean |
90
+ | `enum` | the member's name, or its number when `readEnumValue` is set |
91
+ | `vector3` | an object keyed by the schema's own component aliases |
92
+ | `string`, `resPath` | length-prefixed UTF-8 |
93
+ | `list` | array, strided or offset-indexed as above |
94
+ | `dict` | object, framed exactly as the file's own root |
95
+ | `object` | record, as above |
96
+
97
+ ## Evidence
98
+
99
+ The reader was verified field for field against the published static data export
100
+ for every container of this family in one build, and cross-checked between
101
+ containers that describe the same relationships from different sides. The
102
+ detailed measurements are recorded in the organization documentation rather than
103
+ here.
104
+
105
+ The tests in this package hold the structure instead, on containers laid out byte
106
+ by byte: the shrinking offset table, both list framings, declared defaults,
107
+ nested maps, anchors in the schema, and the widths ordinary data never reaches.
108
+
109
+ ## Related documentation
110
+
111
+ - [Client `.static` container identification](static.md) — which family a file holds
112
+ - [Formats](README.md)
@@ -0,0 +1,119 @@
1
+ # Client `.static` container identification
2
+
3
+ Status: Experimental
4
+ Scope: `@carbonenginejs/runtime-resource/formats/static`
5
+ Audience: Resource integrators reading client static data
6
+ Summary: Identifies which of three unrelated containers a `.static` file holds, so a caller can route it to the format that decodes it.
7
+
8
+ ## Why this exists
9
+
10
+ `.static` names a role, not a format. Three unrelated containers ship under the
11
+ single extension, and each fails differently when guessed at. Measured across
12
+ the 45 `.static` files in one build:
13
+
14
+ | Family | Count | Signature |
15
+ |---|---:|---|
16
+ | SQLite 3 | 14 | `SQLite format 3\0` |
17
+ | Prefixed pickle | 25 | four-byte little-endian prefix, then `(d` or `(l` |
18
+ | Schema-bound | 6 | no signature; has a `.schema` companion |
19
+
20
+ The six unidentified files are exactly the six with a `.schema` companion —
21
+ `constellations`, `dialogs`, `factionsowningsolarsystems`, `jumps`, `regions`
22
+ and `systems` — so the detector's "unknown" set is not a gap in coverage but the
23
+ family that cannot be read without its companion.
24
+
25
+ ## Boundary
26
+
27
+ `CjsStaticFormat` identifies. It decodes nothing.
28
+
29
+ - **SQLite** containers hold `cache(key, value, time)` and
30
+ `indexes(key, value)`, with a JSON document per record.
31
+ - **Prefixed pickle** containers are decoded through `CjsPickleFormat` after
32
+ the four-byte prefix.
33
+ - **Schema-bound** containers report `unknown` with `requires: "schema"`, and
34
+ are decoded by `CjsSchemaBoundFormat` once the caller has that companion.
35
+
36
+ Detection is signature-based. It never trusts a file name and never executes
37
+ anything.
38
+
39
+ ## This format identifies; it does not decode
40
+
41
+ It reports the family, where the payload starts, and what is still missing. The
42
+ caller takes that to the format that owns the family:
43
+
44
+ ```js
45
+ const probe = await CjsStaticFormat.resolveType(bytes);
46
+
47
+ if (probe.preferred === CJS_STATIC_FAMILIES.SQLITE)
48
+ {
49
+ return CjsSqliteFormat.readJSON(bytes);
50
+ }
51
+
52
+ if (probe.preferred === CJS_STATIC_FAMILIES.PICKLE)
53
+ {
54
+ return CjsPickleFormat.read(CjsStaticFormat.payload(bytes));
55
+ }
56
+ ```
57
+
58
+ **This changed on 2026-08-15.** A `read()` here dispatched to those two formats
59
+ itself, and the SQLite family additionally required a driver injected through
60
+ `options.sqlite`. Both are gone. An identification format should not be the
61
+ routing table for two others, and deciding what to decode belongs to whoever
62
+ asked. Nothing outside this format's own tests ever called `read()`.
63
+
64
+
65
+ ## The pickles name classes, and the schemas describe layouts
66
+
67
+ Two notes that decide how the remaining families get decoded.
68
+
69
+ **The pickle family carries class-construction opcodes.** Protocol 0's `c`
70
+ (`GLOBAL`) names a module and an attribute for the unpickler to import, and
71
+ `R`/`i`/`o`/`b` then call it. That is the pickle remote-execution vector, so
72
+ `CjsPickleFormat` rejects those opcodes by design. Client `.static` pickles use
73
+ them legitimately, to name the classes their records are constructed from, so
74
+ decoding this family fully means mapping each named global to an inert
75
+ descriptor and never invoking it. **Not implemented**; the rejection is
76
+ surfaced rather than worked around, and widening it is a deliberate decision
77
+ rather than a bug fix.
78
+
79
+ **The schema-bound family is self-describing.** Its `.schema` companion is
80
+ YAML and states the whole binary layout — sizes, types, optional flags, list item
81
+ sizes, vector precision and a key-to-offset footer — so **nothing needs
82
+ deriving**, unlike an FSD container. `CjsSchemaBoundFormat` reads it:
83
+ [schema-bound containers](schemabound.md). All six datasets decode, the celestial
84
+ tables among them.
85
+
86
+ ## Use
87
+
88
+ Identification goes through the shared type-resolution seam rather than a
89
+ private entry point — see [format type resolution](../concepts/format-type-resolution.md).
90
+
91
+ ```js
92
+ import { CjsStaticFormat, CJS_STATIC_FAMILIES } from
93
+ "@carbonenginejs/runtime-resource/formats/static";
94
+
95
+ const probe = await CjsStaticFormat.resolveType(bytes);
96
+
97
+ if (probe.preferred === CJS_STATIC_FAMILIES.PICKLE)
98
+ {
99
+ const value = CjsPickleFormat.read(CjsStaticFormat.payload(bytes));
100
+ }
101
+ ```
102
+
103
+ `isSupported()` and its `inspect()` alias report on the declaration seam;
104
+ `resolveType()` is the content-verified one. This format is an unusual case for
105
+ that contract: `.static` carries no in-band declaration at all, so there is
106
+ nothing for the content to disagree with. The signature is both claim and
107
+ evidence, `resolveType()` is therefore always `verified`, and `metadata.declared`
108
+ is `null` with `mismatch` always false.
109
+
110
+ `describe()` returns the underlying
111
+ `{ family, byteLength, payloadOffset, prefix, decodable, requires, reason }` without
112
+ building a probe. `payload()` returns the bytes past any wrapper, which is what a
113
+ caller hands to the format that owns the family.
114
+
115
+ ## Related documentation
116
+
117
+ - [Formats](README.md)
118
+ - [Data-only pickle protocol 0](pickle.md)
119
+ - [Schema-bound containers](schemabound.md)
@@ -39,9 +39,11 @@ compiled effect bytes
39
39
  The emitted artifact is a shared Carbon v15 container, not a tagged-chunk
40
40
  package; the GLSL replaces the DXBC in each stage's program slot. Backend body
41
41
  keys deliberately retain the historical `body_<offset>_<size>` form.
42
- `EFFECT_PERMUTATION_GRAPH_CHUNK` (`PGRF`) still records every Cartesian
43
- permutation, its option indices, its exact source record, and a
44
- content-deduplicated body identity.
42
+ The permutation graph still records every Cartesian permutation, its option
43
+ indices, its exact source record, and a content-deduplicated body identity — but
44
+ it is a **derived view** (`CJS_EFFECT_PERMUTATION_GRAPH`, built by
45
+ `buildEffectPermutationGraph`), not a stored `PGRF` chunk. That chunk and its
46
+ `EFFECT_PERMUTATION_GRAPH_CHUNK` export are retired; nothing emits or reads one.
45
47
 
46
48
  ## Completeness
47
49
 
@@ -16,8 +16,8 @@ Carbon version-15 records.
16
16
  Unsupported requested shader semantics fail explicitly instead of producing a
17
17
  partially translated selected pass. `BuildEffect` preserves every permutation
18
18
  row and representable non-program description/reflection fields in the Carbon
19
- container. Non-dynamic sampler names are unrecoverable and stage order is
20
- canonicalized. Source-stage DXBC is replaced by WGSL or an empty program slot.
19
+ container, including non-dynamic sampler names and the authored stage order.
20
+ Source-stage DXBC is replaced by WGSL or an empty program slot.
21
21
  Selected mode writes WGSL only for the resolved body's requested passes; all
22
22
  mode attempts every distinct body after the resolved body passes the initial
23
23
  translation gate. Backend and runtime completeness remain broader gates.
@@ -38,8 +38,8 @@ then package data to the engine.
38
38
  - Reading, inspecting, and building Carbon-record Carbon WebGPU containers.
39
39
  - Resolving one compiled-effect permutation and complete pass.
40
40
  - Preserving every source permutation row and representable non-program
41
- description field; non-dynamic sampler names are unrecoverable and stage
42
- order is canonicalized.
41
+ description field, including non-dynamic sampler names and the authored stage
42
+ order both are preserved, whatever Carbon's runtime does with them.
43
43
  Stored-body identity is exact emitted-description-byte identity; it does not
44
44
  promise to retain the source alias partition after programs are replaced.
45
45
  - Writing WGSL to program slots and bind-group/transform data to the optional
@@ -9,12 +9,23 @@ Summary: Defines the Carbon v15 record container used for WebGPU effects, its ba
9
9
 
10
10
  A `.carbonwebgpu` file is a stock Carbon version-15 compiled-effect container whose
11
11
  program slots carry WGSL instead of DXBC. It preserves every permutation row
12
- and representable non-program description/reflection fields. Non-dynamic
13
- sampler names are unrecoverable and stage order is canonicalized. Source-stage
12
+ and representable non-program description/reflection fields, including
13
+ non-dynamic sampler names and the authored stage order. Source-stage
14
14
  programs are not stored: a translated slot contains WGSL and an untranslated slot is empty.
15
15
  Each translated pass may also carry one WebGPU backend block containing
16
16
  bind-group layouts and resource transforms.
17
17
 
18
+ That preservation is **inherited from the shared codec, and now pinned on this
19
+ path.** It holds because the emit round-trips the description through the same
20
+ Carbon classes the plain container uses and mutates only `stage.sourceProgram`
21
+ and `pass.backendBlock`.
22
+
23
+ `carbon-webgpu-emit-fidelity.test.mjs` compares both fields source-to-emitted
24
+ across the corpus rather than trusting that restraint: 2,960 emitted files,
25
+ 39,252 sampler names and 84,912 stage orders, of which 102 are non-canonical —
26
+ the case that distinguishes a preserved order from a re-derived one. Widening
27
+ what the emit touches now fails there instead of surfacing in a consumer later.
28
+
18
29
  There is no Carbon WebGPU-specific magic, envelope, payload tag, or container version.
19
30
  Backend identity comes from the resource path, such as `effect.webgpu/`, just
20
31
  as Carbon selects `effect.dx11/`, `effect.dx12/`, or `effect.metal/`.
@@ -63,10 +74,17 @@ Equivalent read surfaces are derived from the one Carbon record tree:
63
74
  | `WGSL` | Program text and layouts read from stage records and backend blocks |
64
75
  | `WGSB` | A body-set view derived across distinct stored bodies |
65
76
 
66
- `Read(..., { emit: "json" })` returns these compatibility views as plain data.
67
- They are not independent stored documents and carry no cross-document digests.
68
- `Read(..., { emit: "raw" })` returns the internal `CarbonWebgpuContainer` reader.
69
- There is no `chunks` array and no generic `Build(chunks)` API.
77
+ `Read` returns these derived views as plain data. They are not independent stored
78
+ documents and carry no cross-document digests. There is no `chunks` array and no
79
+ generic `Build(chunks)` API.
80
+
81
+ There is exactly one emit, as there is for WebGL, and the document it returns is
82
+ complete: alongside the views above it carries `permutationGraph` and
83
+ `backendBodySet`, the latter being every translated body joined to its shared
84
+ translation units. A second `raw` emit used to hand back the internal
85
+ `CarbonWebgpuContainer` because the former chunk package could not express the
86
+ body set in JSON. It is removed. The container is internal, and consumers read
87
+ the document rather than binding to a reader object.
70
88
 
71
89
  ## Building
72
90
 
@@ -50,8 +50,7 @@ The emitted bytes are a stock Carbon v15 effect container:
50
50
  - each distinct emitted description body is stored once, based on exact emitted
51
51
  bytes rather than the source alias partition;
52
52
  - representable non-program description/reflection fields remain in the Carbon
53
- tree; non-dynamic sampler names are unrecoverable and stage order is
54
- canonicalized;
53
+ tree, non-dynamic sampler names and the authored stage order included;
55
54
  - translated stage program slots contain UTF-8 WGSL;
56
55
  - untranslated or unsupported stage program slots have zero length; and
57
56
  - translated passes may carry a WebGPU backend block with bind-group layouts
@@ -75,7 +75,7 @@ Callers establish identity through the resource path that supplied the bytes.
75
75
 
76
76
  | Option | Meaning |
77
77
  | --- | --- |
78
- | `emit` | `"json"` by default or `"raw"` for the internal container reader. |
78
+ | `emit` | `"json"`, the only accepted value. Any other value is a `TypeError`. |
79
79
  | `source` | Caller-owned diagnostic label; it is never opened. |
80
80
  | `decodeInstructions` | Includes decoded instruction and IR detail during analysis. |
81
81
  | `permutation` | Exact `NAME=VALUE` assertions for `AnalyzeEffect` and `BuildEffect`; ignored by current `Read` and `Inspect`. |
@@ -85,8 +85,9 @@ Callers establish identity through the resource path that supplied the bytes.
85
85
  Class registrations are validated and stored for forward compatibility.
86
86
  Current JSON reads return plain data rather than hydrated package classes.
87
87
 
88
- Raw output is an internal reader over the same bytes. It is not a second wire
89
- format and should not be persisted.
88
+ There is one emit. The document it returns carries every view a consumer needs,
89
+ including `permutationGraph` and the complete `backendBodySet`, so there is no
90
+ second read mode to choose and no reader object to hold.
90
91
 
91
92
  ## Read result
92
93
 
@@ -174,9 +175,9 @@ coalescing uses version 3 and carries an explicit transform recipe.
174
175
 
175
176
  ## Static metadata
176
177
 
177
- The class exposes `OUTPUT_JSON`, `OUTPUT_RAW`, `CLASS_KEYS`, `type`,
178
- `mediaTypes`, `inputTypes`, `outputTypes`, `debugOutputTypes`,
179
- `implementationStatus`, `format`, `analysisFormat`, and `packageVersion`.
178
+ The class exposes `OUTPUT_JSON`, `CLASS_KEYS`, `type`, `mediaTypes`,
179
+ `inputTypes`, `outputTypes`, `implementationStatus`, `format`, `analysisFormat`,
180
+ and `packageVersion`. There is no `OUTPUT_RAW` and no `debugOutputTypes`.
180
181
 
181
182
  ## Errors
182
183
 
@@ -1403,8 +1403,8 @@ program slots and coverage degrades to `partial`. The in-memory build result
1403
1403
  retains its specific reason; the wire does not. A reread can say only that the
1404
1404
  body carries no translated programs. Permutation topology and representable
1405
1405
  non-program description fields remain present, but source-stage programs are
1406
- not stored. Non-dynamic sampler names are unrecoverable and stage order is
1407
- canonicalized.
1406
+ not stored. Non-dynamic sampler names and the authored stage order are both
1407
+ preserved.
1408
1408
 
1409
1409
  Translating every body is deliberately **not** treated as backend completeness.
1410
1410
  `backendComplete` and `runtimeComplete` remain false, matching the sibling
@@ -689,6 +689,39 @@ Data-only Python pickle format facade that currently decodes protocol 0 into JSO
689
689
  - Visibility: Public
690
690
  - Kind: Original CarbonEngineJS class
691
691
 
692
+ <!-- class:CjsSchemaBoundFormat -->
693
+ ## `CjsSchemaBoundFormat`
694
+
695
+ Reads a binary record container against the separate schema document that describes its layout.
696
+
697
+ - Export: `@carbonenginejs/runtime-resource/formats/schemabound`
698
+ - Source: `src/formats/schemabound/CjsSchemaBoundFormat.js`
699
+ - Visibility: Public
700
+ - Kind: Original CarbonEngineJS class
701
+ - Notes: The schema is required and there is no default. These bytes carry no signature, so the wrong schema decodes into plausible nonsense rather than failing.
702
+
703
+ <!-- class:CjsSqliteFormat -->
704
+ ## `CjsSqliteFormat`
705
+
706
+ Reads a SQLite 3 container as data: the tables it holds and every row of them, with no SQL and no query engine.
707
+
708
+ - Export: `@carbonenginejs/runtime-resource/formats/sqlite`
709
+ - Source: `src/formats/sqlite/CjsSqliteFormat.js`
710
+ - Visibility: Public
711
+ - Kind: Original CarbonEngineJS class
712
+ - Notes: Read-only and full-scan. Index b-trees are never walked, and nothing here needs a driver or a filesystem.
713
+
714
+ <!-- class:CjsStaticFormat -->
715
+ ## `CjsStaticFormat`
716
+
717
+ Identifies which of three unrelated containers a client `.static` file holds, so a caller can route it to the format that decodes it.
718
+
719
+ - Export: `@carbonenginejs/runtime-resource/formats/static`
720
+ - Source: `src/formats/static/CjsStaticFormat.js`
721
+ - Visibility: Public
722
+ - Kind: Original CarbonEngineJS class
723
+ - Notes: Signature-based, and it decodes nothing at all since 2026-08-15. It reports the family and the payload offset; `CjsPickleFormat`, `CjsSqliteFormat` and `CjsSchemaBoundFormat` decode.
724
+
692
725
  <!-- class:CjsPickleProtocol0Reader -->
693
726
  ## `CjsPickleProtocol0Reader`
694
727
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbonenginejs/runtime-resource",
3
- "version": "0.17.0",
3
+ "version": "0.18.1",
4
4
  "description": "CarbonEngineJS resource lifecycle, cache, source, and object loading contracts.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -39,6 +39,9 @@
39
39
  "./formats/png": "./dist/formats/png/index.js",
40
40
  "./formats/red": "./dist/formats/red/index.js",
41
41
  "./formats/red/schema": "./dist/formats/red/core/blackDefinitions.js",
42
+ "./formats/schemabound": "./dist/formats/schemabound/index.js",
43
+ "./formats/sqlite": "./dist/formats/sqlite/index.js",
44
+ "./formats/static": "./dist/formats/static/index.js",
42
45
  "./formats/stl": "./dist/formats/stl/index.js",
43
46
  "./formats/tga": "./dist/formats/tga/index.js",
44
47
  "./formats/wav": "./dist/formats/wav/index.js",
@@ -52,7 +55,7 @@
52
55
  "node": ">=18"
53
56
  },
54
57
  "dependencies": {
55
- "@carbonenginejs/runtime-utils": "^0.1.5",
58
+ "@carbonenginejs/runtime-utils": "^0.1.6",
56
59
  "meshoptimizer": "^1.2.0",
57
60
  "yaml": "^2.4.0"
58
61
  },