@carbonenginejs/runtime-resource 0.18.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.
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +16 -4
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js.map +1 -1
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js +11 -1
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +36 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js +45 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +120 -60
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -1
- package/dist/format/index.js +1 -1
- package/dist/formats/dds/core/helpers.js +35 -6
- package/dist/formats/dds/core/helpers.js.map +1 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +53 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +10 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
- package/dist/formats/index.js +3 -0
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/schemabound/CjsSchemaBoundFormat.js +236 -0
- package/dist/formats/schemabound/CjsSchemaBoundFormat.js.map +1 -0
- package/dist/formats/schemabound/core/schemaBoundErrors.js +9 -0
- package/dist/formats/schemabound/core/schemaBoundErrors.js.map +1 -0
- package/dist/formats/schemabound/core/schemaBoundValues.js +307 -0
- package/dist/formats/schemabound/core/schemaBoundValues.js.map +1 -0
- package/dist/formats/schemabound/index.js +2 -0
- package/dist/formats/schemabound/index.js.map +1 -0
- package/dist/formats/sqlite/CjsSqliteFormat.js +244 -0
- package/dist/formats/sqlite/CjsSqliteFormat.js.map +1 -0
- package/dist/formats/sqlite/core/sqlitePages.js +159 -0
- package/dist/formats/sqlite/core/sqlitePages.js.map +1 -0
- package/dist/formats/sqlite/core/sqliteRecords.js +174 -0
- package/dist/formats/sqlite/core/sqliteRecords.js.map +1 -0
- package/dist/formats/sqlite/core/sqliteSchema.js +100 -0
- package/dist/formats/sqlite/core/sqliteSchema.js.map +1 -0
- package/dist/formats/sqlite/index.js +2 -0
- package/dist/formats/sqlite/index.js.map +1 -0
- package/dist/formats/static/CjsStaticFormat.js +220 -0
- package/dist/formats/static/CjsStaticFormat.js.map +1 -0
- package/dist/formats/static/index.js +2 -0
- package/dist/formats/static/index.js.map +1 -0
- package/dist/formats/webgl/core/buildGlslEffectContainer.js +3 -1
- package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -1
- package/dist/formats/webgl/core/effectPackage.js +11 -2
- package/dist/formats/webgl/core/effectPackage.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +10 -2
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +3 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js +179 -131
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -1
- package/dist/formats/webgpu/core/effectBackendBodySet.js +20 -20
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffect.js +14 -1
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +9 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +14 -0
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/docs/concepts/shader-resource-model.md +34 -1
- package/docs/formats/README.md +21 -0
- package/docs/formats/carbon-effect-container.md +54 -27
- package/docs/formats/schemabound.md +112 -0
- package/docs/formats/static.md +119 -0
- package/docs/formats/webgl/README.md +5 -3
- package/docs/formats/webgpu/README.md +2 -2
- package/docs/formats/webgpu/architecture.md +2 -2
- package/docs/formats/webgpu/formats/carbon-webgpu.md +13 -2
- package/docs/formats/webgpu/guides/effect-packaging.md +1 -2
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +2 -2
- package/docs/reference/classes/formats.md +33 -0
- package/package.json +4 -1
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { CjsYamlFormat } from '../yaml/CjsYamlFormat.js';
|
|
2
|
+
import { ReadValue } from './core/schemaBoundValues.js';
|
|
3
|
+
import { SchemaBoundError } from './core/schemaBoundErrors.js';
|
|
4
|
+
|
|
5
|
+
const OUTPUT_JSON = "json";
|
|
6
|
+
const OUTPUT_PAYLOAD = "payload";
|
|
7
|
+
const ROOT_TYPES = new Set(["dict", "list", "object"]);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reads a container whose layout lives in a separate schema.
|
|
11
|
+
*
|
|
12
|
+
* This is the third of the three families that share the `.static` extension,
|
|
13
|
+
* and the one an extension check is least able to help with: the bytes carry no
|
|
14
|
+
* signature, no version and no self-description. What they carry is a payload
|
|
15
|
+
* whose every field position, width and meaning is stated in a sibling `.schema`
|
|
16
|
+
* document — so the schema is not a hint here, it is the reader.
|
|
17
|
+
*
|
|
18
|
+
* That makes this the opposite of the hash-identified containers, where the
|
|
19
|
+
* header names a layout it does not describe and the layout has to be derived
|
|
20
|
+
* and pinned per dataset. Nothing needs deriving for this family. Supply the
|
|
21
|
+
* schema and the bytes decode.
|
|
22
|
+
*
|
|
23
|
+
* **The schema is required and there is no default.** Given the wrong schema
|
|
24
|
+
* these bytes decode into plausible nonsense rather than failing, because there
|
|
25
|
+
* is nothing in them to disagree with. Pair each payload with the `.schema`
|
|
26
|
+
* that shipped beside it.
|
|
27
|
+
*
|
|
28
|
+
* Read {@link CjsSchemaBoundFormat.read} before writing anything that walks the
|
|
29
|
+
* result: a record's variable section changes length from record to record, and
|
|
30
|
+
* a decoder written around a constant stride will read the first record
|
|
31
|
+
* correctly and everything after it wrongly.
|
|
32
|
+
*/
|
|
33
|
+
class CjsSchemaBoundFormat {
|
|
34
|
+
/**
|
|
35
|
+
* Reports whether a schema can drive this reader.
|
|
36
|
+
*
|
|
37
|
+
* The question is about the schema, never the payload. These containers have
|
|
38
|
+
* no signature to test, so claiming to recognize the bytes would be a claim
|
|
39
|
+
* this format cannot support - and `CjsStaticFormat` already answers which
|
|
40
|
+
* family a `.static` file belongs to.
|
|
41
|
+
*
|
|
42
|
+
* @param {object|Uint8Array|ArrayBuffer|string} schema Schema document or its bytes.
|
|
43
|
+
* @returns {boolean} True when the schema has a root this reader understands.
|
|
44
|
+
*/
|
|
45
|
+
static is(schema) {
|
|
46
|
+
try {
|
|
47
|
+
return ROOT_TYPES.has(this.schema(schema).type);
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Reports whether this format can read a payload described by a schema.
|
|
55
|
+
*
|
|
56
|
+
* @param {object|Uint8Array|ArrayBuffer|string} schema Schema document or its bytes.
|
|
57
|
+
* @param {object} [options] Probe options.
|
|
58
|
+
* @returns {object} Resource probe.
|
|
59
|
+
*/
|
|
60
|
+
static isSupported(schema, options = null) {
|
|
61
|
+
return Probe(this.is(schema), options);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// INTERIM, 2026-08-16. No `inspect` alias, matching CjsSqliteFormat and
|
|
65
|
+
// diverging from the older formats. Both are held by the same undecided
|
|
66
|
+
// question; see maintenance/INTERIM-sqlite-and-static-2026-08-16.md.
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Reads a container against its schema.
|
|
70
|
+
*
|
|
71
|
+
* The whole payload decodes in one pass. Three properties are worth knowing
|
|
72
|
+
* before relying on the result:
|
|
73
|
+
*
|
|
74
|
+
* - **A keyed container's index is at the end.** Nothing at the front points
|
|
75
|
+
* at it; it is found by reading the last four bytes as the index's own size.
|
|
76
|
+
* - **Record offsets are relative to the four-byte header**, not to the file.
|
|
77
|
+
* Decoding from the file start reads one field early, which looks like a
|
|
78
|
+
* wrong layout rather than a wrong base.
|
|
79
|
+
* - **The per-record offset table varies in length.** An optional attribute
|
|
80
|
+
* that is absent occupies no slot, so consecutive records hold their
|
|
81
|
+
* variable data at different distances from their own start.
|
|
82
|
+
*
|
|
83
|
+
* An absent optional takes the default its schema declares. Where none is
|
|
84
|
+
* declared the attribute is left off the record entirely, which is what the
|
|
85
|
+
* published static data exports show for those same rows.
|
|
86
|
+
*
|
|
87
|
+
* @param {Uint8Array|ArrayBuffer} input Container bytes.
|
|
88
|
+
* @param {object} options Read options.
|
|
89
|
+
* @param {object|Uint8Array|ArrayBuffer|string} options.schema The sibling schema.
|
|
90
|
+
* @param {string} [options.output] `json` or `payload`.
|
|
91
|
+
* @returns {object|Array} The decoded container.
|
|
92
|
+
*/
|
|
93
|
+
static read(input, options = {}) {
|
|
94
|
+
const bytes = Normalize(input);
|
|
95
|
+
const schema = this.schema(options.schema);
|
|
96
|
+
if (!ROOT_TYPES.has(schema.type)) {
|
|
97
|
+
throw SchemaBoundError(`A container's root must be a dict, list or object, not ${schema.type}.`);
|
|
98
|
+
}
|
|
99
|
+
const context = {
|
|
100
|
+
bytes,
|
|
101
|
+
view: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
102
|
+
};
|
|
103
|
+
const decoded = ReadValue(context, 0, schema).value;
|
|
104
|
+
return options.output === OUTPUT_PAYLOAD ? decoded : ToJSON(decoded);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Reads to plain JSON-compatible values. */
|
|
108
|
+
static readJSON(input, options = {}) {
|
|
109
|
+
return this.read(input, {
|
|
110
|
+
...options,
|
|
111
|
+
output: OUTPUT_JSON
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Reads with wide integers left as `BigInt`. */
|
|
116
|
+
static readPayload(input, options = {}) {
|
|
117
|
+
return this.read(input, {
|
|
118
|
+
...options,
|
|
119
|
+
output: OUTPUT_PAYLOAD
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Parses a schema document, accepting YAML bytes, YAML text or a parsed object.
|
|
125
|
+
*
|
|
126
|
+
* @param {object|Uint8Array|ArrayBuffer|string} schema Schema in any accepted form.
|
|
127
|
+
* @returns {object} The parsed schema.
|
|
128
|
+
*/
|
|
129
|
+
static schema(schema) {
|
|
130
|
+
if (!schema) {
|
|
131
|
+
throw SchemaBoundError("This format cannot read a container without its schema.");
|
|
132
|
+
}
|
|
133
|
+
if (typeof schema === "object" && !ArrayBuffer.isView(schema) && !(schema instanceof ArrayBuffer)) {
|
|
134
|
+
return schema;
|
|
135
|
+
}
|
|
136
|
+
const parsed = CjsYamlFormat.read(typeof schema === "string" ? schema : Normalize(schema));
|
|
137
|
+
if (!parsed || typeof parsed !== "object") {
|
|
138
|
+
throw SchemaBoundError("A schema must parse to a mapping.");
|
|
139
|
+
}
|
|
140
|
+
return Resolve(parsed);
|
|
141
|
+
}
|
|
142
|
+
static Output = Object.freeze({
|
|
143
|
+
JSON: OUTPUT_JSON,
|
|
144
|
+
PAYLOAD: OUTPUT_PAYLOAD
|
|
145
|
+
});
|
|
146
|
+
static id = "schemabound";
|
|
147
|
+
static extensions = Object.freeze([".static"]);
|
|
148
|
+
static type = Object.freeze(["data"]);
|
|
149
|
+
static mediaTypes = Object.freeze(["data"]);
|
|
150
|
+
static inputTypes = Object.freeze(["schemabound"]);
|
|
151
|
+
static outputTypes = Object.freeze([OUTPUT_JSON, OUTPUT_PAYLOAD]);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Rejoins YAML anchors and aliases into the graph they describe.
|
|
156
|
+
*
|
|
157
|
+
* These schemas share repeated declarations by anchor - a container with two
|
|
158
|
+
* coordinates writes the vector's component aliases once - and the YAML reader
|
|
159
|
+
* reports that sharing as `$yamlId` and `$yamlRef` markers rather than
|
|
160
|
+
* duplicating the node. Left alone, `$yamlId` reads as one more component and
|
|
161
|
+
* `$yamlRef` as a declaration with no fields at all.
|
|
162
|
+
*
|
|
163
|
+
* @param {*} value Parsed schema, or any part of one.
|
|
164
|
+
* @returns {*} The same schema with anchors resolved and markers removed.
|
|
165
|
+
*/
|
|
166
|
+
function Resolve(value) {
|
|
167
|
+
const anchors = new Map();
|
|
168
|
+
const walk = node => {
|
|
169
|
+
if (Array.isArray(node)) return node.map(walk);
|
|
170
|
+
if (!node || typeof node !== "object") return node;
|
|
171
|
+
if (Object.hasOwn(node, "$yamlRef")) {
|
|
172
|
+
const target = anchors.get(node.$yamlRef);
|
|
173
|
+
if (!target) {
|
|
174
|
+
throw SchemaBoundError(`The schema refers to an anchor it never declares: ${node.$yamlRef}.`);
|
|
175
|
+
}
|
|
176
|
+
return target;
|
|
177
|
+
}
|
|
178
|
+
const result = {};
|
|
179
|
+
const id = node.$yamlId;
|
|
180
|
+
if (id !== undefined) anchors.set(id, result);
|
|
181
|
+
for (const [key, member] of Object.entries(node)) {
|
|
182
|
+
if (key !== "$yamlId") result[key] = walk(member);
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
};
|
|
186
|
+
return walk(value);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Builds the probe shape the resource manager routes on. */
|
|
190
|
+
function Probe(usable, options) {
|
|
191
|
+
return {
|
|
192
|
+
format: "schemabound",
|
|
193
|
+
source: "buffer",
|
|
194
|
+
supported: usable ? "full" : "none",
|
|
195
|
+
confidence: usable ? 1 : 0,
|
|
196
|
+
preferred: "schemabound",
|
|
197
|
+
// The schema is read to answer this, so it is measured rather than declared.
|
|
198
|
+
// It says nothing about any payload: these containers carry no signature.
|
|
199
|
+
verified: true,
|
|
200
|
+
reason: usable ? "The schema declares a root this reader can decode." : "The schema is missing, unparsable, or declares an unreadable root.",
|
|
201
|
+
variants: [{
|
|
202
|
+
kind: "container",
|
|
203
|
+
codec: "schemabound",
|
|
204
|
+
supported: usable
|
|
205
|
+
}],
|
|
206
|
+
metadata: {
|
|
207
|
+
family: "schemabound",
|
|
208
|
+
requiresSchema: true,
|
|
209
|
+
decodable: usable
|
|
210
|
+
},
|
|
211
|
+
...(options || {})
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Converts decoded values to something `JSON.stringify` keeps losslessly. */
|
|
216
|
+
function ToJSON(value) {
|
|
217
|
+
if (typeof value === "bigint") return value.toString(10);
|
|
218
|
+
if (Array.isArray(value)) return value.map(ToJSON);
|
|
219
|
+
if (value && typeof value === "object") {
|
|
220
|
+
const result = {};
|
|
221
|
+
for (const [key, member] of Object.entries(value)) result[key] = ToJSON(member);
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
return value;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Accepts the byte forms every other format here accepts. */
|
|
228
|
+
function Normalize(input) {
|
|
229
|
+
if (input instanceof Uint8Array) return input;
|
|
230
|
+
if (input instanceof ArrayBuffer) return new Uint8Array(input);
|
|
231
|
+
if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
232
|
+
throw SchemaBoundError("A schema-bound container must be supplied as bytes.");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export { CjsSchemaBoundFormat };
|
|
236
|
+
//# sourceMappingURL=CjsSchemaBoundFormat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CjsSchemaBoundFormat.js","sources":["../../../../src/formats/schemabound/CjsSchemaBoundFormat.js"],"sourcesContent":["import { CjsYamlFormat } from \"../yaml/index.js\";\nimport { ReadValue } from \"./core/schemaBoundValues.js\";\nimport { SchemaBoundError } from \"./core/schemaBoundErrors.js\";\n\nconst OUTPUT_JSON = \"json\";\nconst OUTPUT_PAYLOAD = \"payload\";\nconst ROOT_TYPES = new Set([ \"dict\", \"list\", \"object\" ]);\n\n/**\n * Reads a container whose layout lives in a separate schema.\n *\n * This is the third of the three families that share the `.static` extension,\n * and the one an extension check is least able to help with: the bytes carry no\n * signature, no version and no self-description. What they carry is a payload\n * whose every field position, width and meaning is stated in a sibling `.schema`\n * document — so the schema is not a hint here, it is the reader.\n *\n * That makes this the opposite of the hash-identified containers, where the\n * header names a layout it does not describe and the layout has to be derived\n * and pinned per dataset. Nothing needs deriving for this family. Supply the\n * schema and the bytes decode.\n *\n * **The schema is required and there is no default.** Given the wrong schema\n * these bytes decode into plausible nonsense rather than failing, because there\n * is nothing in them to disagree with. Pair each payload with the `.schema`\n * that shipped beside it.\n *\n * Read {@link CjsSchemaBoundFormat.read} before writing anything that walks the\n * result: a record's variable section changes length from record to record, and\n * a decoder written around a constant stride will read the first record\n * correctly and everything after it wrongly.\n */\nexport class CjsSchemaBoundFormat {\n\n /**\n * Reports whether a schema can drive this reader.\n *\n * The question is about the schema, never the payload. These containers have\n * no signature to test, so claiming to recognize the bytes would be a claim\n * this format cannot support - and `CjsStaticFormat` already answers which\n * family a `.static` file belongs to.\n *\n * @param {object|Uint8Array|ArrayBuffer|string} schema Schema document or its bytes.\n * @returns {boolean} True when the schema has a root this reader understands.\n */\n static is(schema) {\n try {\n return ROOT_TYPES.has(this.schema(schema).type);\n } catch {\n return false;\n }\n }\n\n /**\n * Reports whether this format can read a payload described by a schema.\n *\n * @param {object|Uint8Array|ArrayBuffer|string} schema Schema document or its bytes.\n * @param {object} [options] Probe options.\n * @returns {object} Resource probe.\n */\n static isSupported(schema, options = null) {\n return Probe(this.is(schema), options);\n }\n\n // INTERIM, 2026-08-16. No `inspect` alias, matching CjsSqliteFormat and\n // diverging from the older formats. Both are held by the same undecided\n // question; see maintenance/INTERIM-sqlite-and-static-2026-08-16.md.\n\n /**\n * Reads a container against its schema.\n *\n * The whole payload decodes in one pass. Three properties are worth knowing\n * before relying on the result:\n *\n * - **A keyed container's index is at the end.** Nothing at the front points\n * at it; it is found by reading the last four bytes as the index's own size.\n * - **Record offsets are relative to the four-byte header**, not to the file.\n * Decoding from the file start reads one field early, which looks like a\n * wrong layout rather than a wrong base.\n * - **The per-record offset table varies in length.** An optional attribute\n * that is absent occupies no slot, so consecutive records hold their\n * variable data at different distances from their own start.\n *\n * An absent optional takes the default its schema declares. Where none is\n * declared the attribute is left off the record entirely, which is what the\n * published static data exports show for those same rows.\n *\n * @param {Uint8Array|ArrayBuffer} input Container bytes.\n * @param {object} options Read options.\n * @param {object|Uint8Array|ArrayBuffer|string} options.schema The sibling schema.\n * @param {string} [options.output] `json` or `payload`.\n * @returns {object|Array} The decoded container.\n */\n static read(input, options = {}) {\n const bytes = Normalize(input);\n const schema = this.schema(options.schema);\n\n if (!ROOT_TYPES.has(schema.type)) {\n throw SchemaBoundError(`A container's root must be a dict, list or object, not ${schema.type}.`);\n }\n\n const context = {\n bytes,\n view: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n };\n const decoded = ReadValue(context, 0, schema).value;\n\n return options.output === OUTPUT_PAYLOAD ? decoded : ToJSON(decoded);\n }\n\n /** Reads to plain JSON-compatible values. */\n static readJSON(input, options = {}) {\n return this.read(input, { ...options, output: OUTPUT_JSON });\n }\n\n /** Reads with wide integers left as `BigInt`. */\n static readPayload(input, options = {}) {\n return this.read(input, { ...options, output: OUTPUT_PAYLOAD });\n }\n\n /**\n * Parses a schema document, accepting YAML bytes, YAML text or a parsed object.\n *\n * @param {object|Uint8Array|ArrayBuffer|string} schema Schema in any accepted form.\n * @returns {object} The parsed schema.\n */\n static schema(schema) {\n if (!schema) {\n throw SchemaBoundError(\"This format cannot read a container without its schema.\");\n }\n\n if (typeof schema === \"object\" && !ArrayBuffer.isView(schema) && !(schema instanceof ArrayBuffer)) {\n return schema;\n }\n\n const parsed = CjsYamlFormat.read(typeof schema === \"string\" ? schema : Normalize(schema));\n\n if (!parsed || typeof parsed !== \"object\") {\n throw SchemaBoundError(\"A schema must parse to a mapping.\");\n }\n\n return Resolve(parsed);\n }\n\n static Output = Object.freeze({ JSON: OUTPUT_JSON, PAYLOAD: OUTPUT_PAYLOAD });\n\n static id = \"schemabound\";\n static extensions = Object.freeze([ \".static\" ]);\n static type = Object.freeze([ \"data\" ]);\n static mediaTypes = Object.freeze([ \"data\" ]);\n static inputTypes = Object.freeze([ \"schemabound\" ]);\n static outputTypes = Object.freeze([ OUTPUT_JSON, OUTPUT_PAYLOAD ]);\n}\n\n/**\n * Rejoins YAML anchors and aliases into the graph they describe.\n *\n * These schemas share repeated declarations by anchor - a container with two\n * coordinates writes the vector's component aliases once - and the YAML reader\n * reports that sharing as `$yamlId` and `$yamlRef` markers rather than\n * duplicating the node. Left alone, `$yamlId` reads as one more component and\n * `$yamlRef` as a declaration with no fields at all.\n *\n * @param {*} value Parsed schema, or any part of one.\n * @returns {*} The same schema with anchors resolved and markers removed.\n */\nfunction Resolve(value) {\n const anchors = new Map();\n\n const walk = node => {\n if (Array.isArray(node)) return node.map(walk);\n\n if (!node || typeof node !== \"object\") return node;\n\n if (Object.hasOwn(node, \"$yamlRef\")) {\n const target = anchors.get(node.$yamlRef);\n\n if (!target) {\n throw SchemaBoundError(`The schema refers to an anchor it never declares: ${node.$yamlRef}.`);\n }\n\n return target;\n }\n\n const result = {};\n const id = node.$yamlId;\n\n if (id !== undefined) anchors.set(id, result);\n\n for (const [ key, member ] of Object.entries(node)) {\n if (key !== \"$yamlId\") result[key] = walk(member);\n }\n\n return result;\n };\n\n return walk(value);\n}\n\n/** Builds the probe shape the resource manager routes on. */\nfunction Probe(usable, options) {\n return {\n format: \"schemabound\",\n source: \"buffer\",\n supported: usable ? \"full\" : \"none\",\n confidence: usable ? 1 : 0,\n preferred: \"schemabound\",\n // The schema is read to answer this, so it is measured rather than declared.\n // It says nothing about any payload: these containers carry no signature.\n verified: true,\n reason: usable\n ? \"The schema declares a root this reader can decode.\"\n : \"The schema is missing, unparsable, or declares an unreadable root.\",\n variants: [ { kind: \"container\", codec: \"schemabound\", supported: usable } ],\n metadata: { family: \"schemabound\", requiresSchema: true, decodable: usable },\n ...(options || {})\n };\n}\n\n/** Converts decoded values to something `JSON.stringify` keeps losslessly. */\nfunction ToJSON(value) {\n if (typeof value === \"bigint\") return value.toString(10);\n\n if (Array.isArray(value)) return value.map(ToJSON);\n\n if (value && typeof value === \"object\") {\n const result = {};\n\n for (const [ key, member ] of Object.entries(value)) result[key] = ToJSON(member);\n\n return result;\n }\n\n return value;\n}\n\n/** Accepts the byte forms every other format here accepts. */\nfunction Normalize(input) {\n if (input instanceof Uint8Array) return input;\n\n if (input instanceof ArrayBuffer) return new Uint8Array(input);\n\n if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\n\n throw SchemaBoundError(\"A schema-bound container must be supplied as bytes.\");\n}\n\nexport default CjsSchemaBoundFormat;\n"],"names":["OUTPUT_JSON","OUTPUT_PAYLOAD","ROOT_TYPES","Set","CjsSchemaBoundFormat","is","schema","has","type","isSupported","options","Probe","read","input","bytes","Normalize","SchemaBoundError","context","view","DataView","buffer","byteOffset","byteLength","decoded","ReadValue","value","output","ToJSON","readJSON","readPayload","ArrayBuffer","isView","parsed","CjsYamlFormat","Resolve","Output","Object","freeze","JSON","PAYLOAD","id","extensions","mediaTypes","inputTypes","outputTypes","anchors","Map","walk","node","Array","isArray","map","hasOwn","target","get","$yamlRef","result","$yamlId","undefined","set","key","member","entries","usable","format","source","supported","confidence","preferred","verified","reason","variants","kind","codec","metadata","family","requiresSchema","decodable","toString","Uint8Array"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Builds the error every part of this format throws, with one code. */
|
|
2
|
+
function SchemaBoundError(message, extra = null) {
|
|
3
|
+
const error = new TypeError(message);
|
|
4
|
+
error.code = "CJS_SCHEMA_BOUND_INVALID";
|
|
5
|
+
return Object.assign(error, extra || {});
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { SchemaBoundError };
|
|
9
|
+
//# sourceMappingURL=schemaBoundErrors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaBoundErrors.js","sources":["../../../../../src/formats/schemabound/core/schemaBoundErrors.js"],"sourcesContent":["/** Builds the error every part of this format throws, with one code. */\nexport function SchemaBoundError(message, extra = null) {\n const error = new TypeError(message);\n\n error.code = \"CJS_SCHEMA_BOUND_INVALID\";\n\n return Object.assign(error, extra || {});\n}\n\nexport default SchemaBoundError;\n"],"names":["SchemaBoundError","message","extra","error","TypeError","code","Object","assign"],"mappings":"AAAA;AACO,SAASA,gBAAgBA,CAACC,OAAO,EAAEC,KAAK,GAAG,IAAI,EAAE;AACtD,EAAA,MAAMC,KAAK,GAAG,IAAIC,SAAS,CAACH,OAAO,CAAC;EAEpCE,KAAK,CAACE,IAAI,GAAG,0BAA0B;EAEvC,OAAOC,MAAM,CAACC,MAAM,CAACJ,KAAK,EAAED,KAAK,IAAI,EAAE,CAAC;AAC1C;;;;"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { SchemaBoundError } from './schemaBoundErrors.js';
|
|
2
|
+
|
|
3
|
+
const TEXT = new TextDecoder("utf-8");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decodes one value of any schema type, and reports how many bytes it spanned.
|
|
7
|
+
*
|
|
8
|
+
* Every type answers both questions through this one function because the
|
|
9
|
+
* container mixes them: a list's items may be fixed, in which case the schema
|
|
10
|
+
* states the stride, or variable, in which case the only way to find item `n+1`
|
|
11
|
+
* is to have finished reading item `n`.
|
|
12
|
+
*
|
|
13
|
+
* @param {object} context Reader context: `view`, `bytes` and `options`.
|
|
14
|
+
* @param {number} offset Absolute byte offset of the value.
|
|
15
|
+
* @param {object} node The schema node describing the value.
|
|
16
|
+
* @returns {{value: *, size: number}} Decoded value and the bytes it occupied.
|
|
17
|
+
*/
|
|
18
|
+
function ReadValue(context, offset, node) {
|
|
19
|
+
switch (node.type) {
|
|
20
|
+
case "int":
|
|
21
|
+
return ReadInt(context, offset, node);
|
|
22
|
+
case "float":
|
|
23
|
+
return ReadFloat(context, offset, node);
|
|
24
|
+
case "bool":
|
|
25
|
+
return {
|
|
26
|
+
value: context.view.getUint8(offset) !== 0,
|
|
27
|
+
size: node.size ?? 1
|
|
28
|
+
};
|
|
29
|
+
case "enum":
|
|
30
|
+
return ReadEnum(context, offset, node);
|
|
31
|
+
case "vector3":
|
|
32
|
+
return ReadVector3(context, offset, node);
|
|
33
|
+
case "string":
|
|
34
|
+
case "resPath":
|
|
35
|
+
return ReadString(context, offset);
|
|
36
|
+
case "list":
|
|
37
|
+
return ReadList(context, offset, node);
|
|
38
|
+
case "dict":
|
|
39
|
+
return ReadDict(context, offset, node);
|
|
40
|
+
case "object":
|
|
41
|
+
return ReadObject(context, offset, node);
|
|
42
|
+
default:
|
|
43
|
+
throw SchemaBoundError(`The schema declares a type this reader does not know: ${node.type}.`, {
|
|
44
|
+
schemaType: node.type
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Reads a 1, 2, 4 or 8 byte integer, signed only when the schema allows it. */
|
|
50
|
+
function ReadInt(context, offset, node) {
|
|
51
|
+
const size = node.size ?? 4;
|
|
52
|
+
// `min: 0` is the schema's own statement that the field cannot go negative,
|
|
53
|
+
// and it is the only signedness information there is.
|
|
54
|
+
const unsigned = typeof node.min === "number" && node.min >= 0;
|
|
55
|
+
const view = context.view;
|
|
56
|
+
switch (size) {
|
|
57
|
+
case 1:
|
|
58
|
+
return {
|
|
59
|
+
value: unsigned ? view.getUint8(offset) : view.getInt8(offset),
|
|
60
|
+
size
|
|
61
|
+
};
|
|
62
|
+
case 2:
|
|
63
|
+
return {
|
|
64
|
+
value: unsigned ? view.getUint16(offset, true) : view.getInt16(offset, true),
|
|
65
|
+
size
|
|
66
|
+
};
|
|
67
|
+
case 4:
|
|
68
|
+
return {
|
|
69
|
+
value: unsigned ? view.getUint32(offset, true) : view.getInt32(offset, true),
|
|
70
|
+
size
|
|
71
|
+
};
|
|
72
|
+
case 8:
|
|
73
|
+
return {
|
|
74
|
+
value: Narrow(unsigned ? view.getBigUint64(offset, true) : view.getBigInt64(offset, true)),
|
|
75
|
+
size
|
|
76
|
+
};
|
|
77
|
+
default:
|
|
78
|
+
throw SchemaBoundError(`An integer of ${size} bytes is not a width this container uses.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Returns a wide integer as a Number when that is lossless, else a BigInt. */
|
|
83
|
+
function Narrow(value) {
|
|
84
|
+
return value >= -9007199254740991n && value <= 9007199254740991n ? Number(value) : value;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Reads a single or double precision float. */
|
|
88
|
+
function ReadFloat(context, offset, node) {
|
|
89
|
+
const size = node.size ?? 4;
|
|
90
|
+
if (size === 8) return {
|
|
91
|
+
value: context.view.getFloat64(offset, true),
|
|
92
|
+
size
|
|
93
|
+
};
|
|
94
|
+
if (size === 4) return {
|
|
95
|
+
value: context.view.getFloat32(offset, true),
|
|
96
|
+
size
|
|
97
|
+
};
|
|
98
|
+
throw SchemaBoundError(`A float of ${size} bytes is not a width this container uses.`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Reads an enumeration, as its number or its name.
|
|
103
|
+
*
|
|
104
|
+
* `readEnumValue` is the schema saying the stored number is the meaning; without
|
|
105
|
+
* it the name is. A number with no name is returned as the number rather than
|
|
106
|
+
* dropped, because an unnamed member is data the client still stored.
|
|
107
|
+
*/
|
|
108
|
+
function ReadEnum(context, offset, node) {
|
|
109
|
+
const {
|
|
110
|
+
value,
|
|
111
|
+
size
|
|
112
|
+
} = ReadInt(context, offset, {
|
|
113
|
+
size: node.size ?? 1,
|
|
114
|
+
min: 0
|
|
115
|
+
});
|
|
116
|
+
if (node.readEnumValue === true || !node.values) return {
|
|
117
|
+
value,
|
|
118
|
+
size
|
|
119
|
+
};
|
|
120
|
+
for (const [name, member] of Object.entries(node.values)) {
|
|
121
|
+
if (member === value) return {
|
|
122
|
+
value: name,
|
|
123
|
+
size
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
value,
|
|
128
|
+
size
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Reads three doubles into the component names the schema aliases them to. */
|
|
133
|
+
function ReadVector3(context, offset, node) {
|
|
134
|
+
const wide = (node.precision ?? "double") === "double";
|
|
135
|
+
const width = wide ? 8 : 4;
|
|
136
|
+
const read = index => wide ? context.view.getFloat64(offset + index * width, true) : context.view.getFloat32(offset + index * width, true);
|
|
137
|
+
const aliases = node.aliases ?? {
|
|
138
|
+
x: 0,
|
|
139
|
+
y: 1,
|
|
140
|
+
z: 2
|
|
141
|
+
};
|
|
142
|
+
const value = {};
|
|
143
|
+
for (const [name, index] of Object.entries(aliases)) value[name] = read(index);
|
|
144
|
+
return {
|
|
145
|
+
value,
|
|
146
|
+
size: node.size ?? width * 3
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Reads a length-prefixed UTF-8 string; `resPath` is the same shape. */
|
|
151
|
+
function ReadString(context, offset) {
|
|
152
|
+
const length = context.view.getUint32(offset, true);
|
|
153
|
+
const start = offset + 4;
|
|
154
|
+
return {
|
|
155
|
+
value: TEXT.decode(context.bytes.subarray(start, start + length)),
|
|
156
|
+
size: 4 + length
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Reads a count-prefixed list.
|
|
162
|
+
*
|
|
163
|
+
* A list has two framings and the schema says which: `fixedItemSize` means the
|
|
164
|
+
* items are packed one after another at that stride, and its absence means they
|
|
165
|
+
* are variable, so the count is followed by one `uint32` per item. Those offsets
|
|
166
|
+
* are relative to the start of the list.
|
|
167
|
+
*/
|
|
168
|
+
function ReadList(context, offset, node) {
|
|
169
|
+
const view = context.view;
|
|
170
|
+
const count = view.getUint32(offset, true);
|
|
171
|
+
const items = [];
|
|
172
|
+
if (node.fixedItemSize === undefined) {
|
|
173
|
+
let end = offset + 4 + count * 4;
|
|
174
|
+
for (let index = 0; index < count; index += 1) {
|
|
175
|
+
const at = offset + view.getUint32(offset + 4 + index * 4, true);
|
|
176
|
+
const item = ReadValue(context, at, node.itemTypes);
|
|
177
|
+
items.push(item.value);
|
|
178
|
+
end = Math.max(end, at + item.size);
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
value: items,
|
|
182
|
+
size: end - offset
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
let cursor = offset + 4;
|
|
186
|
+
for (let index = 0; index < count; index += 1) {
|
|
187
|
+
items.push(ReadValue(context, cursor, node.itemTypes).value);
|
|
188
|
+
cursor += node.fixedItemSize;
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
value: items,
|
|
192
|
+
size: cursor - offset
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Reads a keyed map.
|
|
198
|
+
*
|
|
199
|
+
* The framing is the same at the root of a container and nested inside one
|
|
200
|
+
* record: a `uint32` of everything that follows, the values, then the key
|
|
201
|
+
* footer, then a `uint32` of the footer's own size. **The footer is found from
|
|
202
|
+
* the end, never from the front** — nothing at the front points at it.
|
|
203
|
+
*
|
|
204
|
+
* Each footer entry carries a key and an offset, and that offset is relative to
|
|
205
|
+
* the end of the leading `uint32`, not to the file and not to the value region.
|
|
206
|
+
*/
|
|
207
|
+
function ReadDict(context, offset, node) {
|
|
208
|
+
const view = context.view;
|
|
209
|
+
const total = view.getUint32(offset, true);
|
|
210
|
+
const base = offset + 4;
|
|
211
|
+
const end = base + total;
|
|
212
|
+
const footerSize = view.getUint32(end - 4, true);
|
|
213
|
+
const footerStart = end - 4 - footerSize;
|
|
214
|
+
if (footerStart < base) {
|
|
215
|
+
throw SchemaBoundError("The key footer does not fit inside the container.", {
|
|
216
|
+
footerStart,
|
|
217
|
+
base
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
const value = {};
|
|
221
|
+
|
|
222
|
+
// The footer is an ordinary list, and it uses both of the list framings: a
|
|
223
|
+
// list of integer keys is fixed-stride, a list of string keys is not.
|
|
224
|
+
for (const entry of ReadList(context, footerStart, node.keyFooter).value) {
|
|
225
|
+
value[entry.key] = ReadValue(context, base + entry.offset, node.valueTypes).value;
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
value,
|
|
229
|
+
size: 4 + total
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Reads a record.
|
|
235
|
+
*
|
|
236
|
+
* Fixed attributes sit at the offsets the schema names. Everything in
|
|
237
|
+
* `attributesWithVariableOffsets` is reached through a table that follows the
|
|
238
|
+
* fixed part, and **that table's length changes from record to record**: an
|
|
239
|
+
* optional attribute whose presence bit is clear takes no slot in it. A reader
|
|
240
|
+
* that assumes a constant stride decodes the first record correctly and then
|
|
241
|
+
* drifts, which is the single most misleading property of this format.
|
|
242
|
+
*/
|
|
243
|
+
function ReadObject(context, offset, node) {
|
|
244
|
+
const attributes = node.attributes ?? {};
|
|
245
|
+
const variable = node.attributesWithVariableOffsets ?? [];
|
|
246
|
+
const decoded = new Map();
|
|
247
|
+
let size = node.size ?? node.endOfFixedSizeData ?? 0;
|
|
248
|
+
for (const [name, at] of Object.entries(node.constantAttributeOffsets ?? {})) {
|
|
249
|
+
decoded.set(name, ReadValue(context, offset + at, Attribute(attributes, name)).value);
|
|
250
|
+
}
|
|
251
|
+
if (variable.length) {
|
|
252
|
+
const lookups = node.optionalValueLookups ?? {};
|
|
253
|
+
const view = context.view;
|
|
254
|
+
// The presence bitfield is written whenever a record has a variable section
|
|
255
|
+
// at all, including where nothing in it is optional and the field is
|
|
256
|
+
// therefore always zero. It is the offset table that shrinks, never this.
|
|
257
|
+
const bits = view.getBigUint64(offset + node.endOfFixedSizeData, true);
|
|
258
|
+
const table = offset + node.endOfFixedSizeData + 8;
|
|
259
|
+
const present = variable.filter(name => {
|
|
260
|
+
const attribute = Attribute(attributes, name);
|
|
261
|
+
return !attribute.isOptional || (bits & BigInt(lookups[name] ?? 0)) !== 0n;
|
|
262
|
+
});
|
|
263
|
+
const data = table + present.length * 4;
|
|
264
|
+
let end = data;
|
|
265
|
+
present.forEach((name, index) => {
|
|
266
|
+
const at = data + view.getUint32(table + index * 4, true);
|
|
267
|
+
const read = ReadValue(context, at, Attribute(attributes, name));
|
|
268
|
+
decoded.set(name, read.value);
|
|
269
|
+
end = Math.max(end, at + read.size);
|
|
270
|
+
});
|
|
271
|
+
for (const name of variable) {
|
|
272
|
+
const attribute = Attribute(attributes, name);
|
|
273
|
+
|
|
274
|
+
// An absent optional takes the value the schema declares for it. Where no
|
|
275
|
+
// default is declared the attribute is simply not part of this record -
|
|
276
|
+
// which is what the published exports show for these same rows.
|
|
277
|
+
if (!decoded.has(name) && Object.hasOwn(attribute, "default")) {
|
|
278
|
+
decoded.set(name, attribute.default);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
size = end - offset;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Declaration order, not the order the two passes above happened to fill.
|
|
285
|
+
const value = {};
|
|
286
|
+
for (const name of Object.keys(attributes)) {
|
|
287
|
+
if (decoded.has(name)) value[name] = decoded.get(name);
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
value,
|
|
291
|
+
size
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Looks up an attribute, naming the schema rather than failing on undefined. */
|
|
296
|
+
function Attribute(attributes, name) {
|
|
297
|
+
const attribute = attributes[name];
|
|
298
|
+
if (!attribute) {
|
|
299
|
+
throw SchemaBoundError(`The schema offsets an attribute it never declares: ${name}.`, {
|
|
300
|
+
attribute: name
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return attribute;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export { ReadValue };
|
|
307
|
+
//# sourceMappingURL=schemaBoundValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaBoundValues.js","sources":["../../../../../src/formats/schemabound/core/schemaBoundValues.js"],"sourcesContent":["import { SchemaBoundError } from \"./schemaBoundErrors.js\";\n\nconst TEXT = new TextDecoder(\"utf-8\");\n\n/**\n * Decodes one value of any schema type, and reports how many bytes it spanned.\n *\n * Every type answers both questions through this one function because the\n * container mixes them: a list's items may be fixed, in which case the schema\n * states the stride, or variable, in which case the only way to find item `n+1`\n * is to have finished reading item `n`.\n *\n * @param {object} context Reader context: `view`, `bytes` and `options`.\n * @param {number} offset Absolute byte offset of the value.\n * @param {object} node The schema node describing the value.\n * @returns {{value: *, size: number}} Decoded value and the bytes it occupied.\n */\nexport function ReadValue(context, offset, node) {\n switch (node.type) {\n case \"int\": return ReadInt(context, offset, node);\n case \"float\": return ReadFloat(context, offset, node);\n case \"bool\": return { value: context.view.getUint8(offset) !== 0, size: node.size ?? 1 };\n case \"enum\": return ReadEnum(context, offset, node);\n case \"vector3\": return ReadVector3(context, offset, node);\n case \"string\": case \"resPath\": return ReadString(context, offset);\n case \"list\": return ReadList(context, offset, node);\n case \"dict\": return ReadDict(context, offset, node);\n case \"object\": return ReadObject(context, offset, node);\n default:\n throw SchemaBoundError(`The schema declares a type this reader does not know: ${node.type}.`, {\n schemaType: node.type\n });\n }\n}\n\n/** Reads a 1, 2, 4 or 8 byte integer, signed only when the schema allows it. */\nfunction ReadInt(context, offset, node) {\n const size = node.size ?? 4;\n // `min: 0` is the schema's own statement that the field cannot go negative,\n // and it is the only signedness information there is.\n const unsigned = typeof node.min === \"number\" && node.min >= 0;\n const view = context.view;\n\n switch (size) {\n case 1: return { value: unsigned ? view.getUint8(offset) : view.getInt8(offset), size };\n case 2: return { value: unsigned ? view.getUint16(offset, true) : view.getInt16(offset, true), size };\n case 4: return { value: unsigned ? view.getUint32(offset, true) : view.getInt32(offset, true), size };\n case 8: return { value: Narrow(unsigned ? view.getBigUint64(offset, true) : view.getBigInt64(offset, true)), size };\n default:\n throw SchemaBoundError(`An integer of ${size} bytes is not a width this container uses.`);\n }\n}\n\n/** Returns a wide integer as a Number when that is lossless, else a BigInt. */\nfunction Narrow(value) {\n return value >= -9007199254740991n && value <= 9007199254740991n ? Number(value) : value;\n}\n\n/** Reads a single or double precision float. */\nfunction ReadFloat(context, offset, node) {\n const size = node.size ?? 4;\n\n if (size === 8) return { value: context.view.getFloat64(offset, true), size };\n if (size === 4) return { value: context.view.getFloat32(offset, true), size };\n\n throw SchemaBoundError(`A float of ${size} bytes is not a width this container uses.`);\n}\n\n/**\n * Reads an enumeration, as its number or its name.\n *\n * `readEnumValue` is the schema saying the stored number is the meaning; without\n * it the name is. A number with no name is returned as the number rather than\n * dropped, because an unnamed member is data the client still stored.\n */\nfunction ReadEnum(context, offset, node) {\n const { value, size } = ReadInt(context, offset, { size: node.size ?? 1, min: 0 });\n\n if (node.readEnumValue === true || !node.values) return { value, size };\n\n for (const [ name, member ] of Object.entries(node.values)) {\n if (member === value) return { value: name, size };\n }\n\n return { value, size };\n}\n\n/** Reads three doubles into the component names the schema aliases them to. */\nfunction ReadVector3(context, offset, node) {\n const wide = (node.precision ?? \"double\") === \"double\";\n const width = wide ? 8 : 4;\n const read = index => wide\n ? context.view.getFloat64(offset + index * width, true)\n : context.view.getFloat32(offset + index * width, true);\n const aliases = node.aliases ?? { x: 0, y: 1, z: 2 };\n const value = {};\n\n for (const [ name, index ] of Object.entries(aliases)) value[name] = read(index);\n\n return { value, size: node.size ?? width * 3 };\n}\n\n/** Reads a length-prefixed UTF-8 string; `resPath` is the same shape. */\nfunction ReadString(context, offset) {\n const length = context.view.getUint32(offset, true);\n const start = offset + 4;\n\n return {\n value: TEXT.decode(context.bytes.subarray(start, start + length)),\n size: 4 + length\n };\n}\n\n/**\n * Reads a count-prefixed list.\n *\n * A list has two framings and the schema says which: `fixedItemSize` means the\n * items are packed one after another at that stride, and its absence means they\n * are variable, so the count is followed by one `uint32` per item. Those offsets\n * are relative to the start of the list.\n */\nfunction ReadList(context, offset, node) {\n const view = context.view;\n const count = view.getUint32(offset, true);\n const items = [];\n\n if (node.fixedItemSize === undefined) {\n let end = offset + 4 + count * 4;\n\n for (let index = 0; index < count; index += 1) {\n const at = offset + view.getUint32(offset + 4 + index * 4, true);\n const item = ReadValue(context, at, node.itemTypes);\n\n items.push(item.value);\n end = Math.max(end, at + item.size);\n }\n\n return { value: items, size: end - offset };\n }\n\n let cursor = offset + 4;\n\n for (let index = 0; index < count; index += 1) {\n items.push(ReadValue(context, cursor, node.itemTypes).value);\n cursor += node.fixedItemSize;\n }\n\n return { value: items, size: cursor - offset };\n}\n\n/**\n * Reads a keyed map.\n *\n * The framing is the same at the root of a container and nested inside one\n * record: a `uint32` of everything that follows, the values, then the key\n * footer, then a `uint32` of the footer's own size. **The footer is found from\n * the end, never from the front** — nothing at the front points at it.\n *\n * Each footer entry carries a key and an offset, and that offset is relative to\n * the end of the leading `uint32`, not to the file and not to the value region.\n */\nfunction ReadDict(context, offset, node) {\n const view = context.view;\n const total = view.getUint32(offset, true);\n const base = offset + 4;\n const end = base + total;\n const footerSize = view.getUint32(end - 4, true);\n const footerStart = end - 4 - footerSize;\n\n if (footerStart < base) {\n throw SchemaBoundError(\"The key footer does not fit inside the container.\", { footerStart, base });\n }\n\n const value = {};\n\n // The footer is an ordinary list, and it uses both of the list framings: a\n // list of integer keys is fixed-stride, a list of string keys is not.\n for (const entry of ReadList(context, footerStart, node.keyFooter).value) {\n value[entry.key] = ReadValue(context, base + entry.offset, node.valueTypes).value;\n }\n\n return { value, size: 4 + total };\n}\n\n/**\n * Reads a record.\n *\n * Fixed attributes sit at the offsets the schema names. Everything in\n * `attributesWithVariableOffsets` is reached through a table that follows the\n * fixed part, and **that table's length changes from record to record**: an\n * optional attribute whose presence bit is clear takes no slot in it. A reader\n * that assumes a constant stride decodes the first record correctly and then\n * drifts, which is the single most misleading property of this format.\n */\nfunction ReadObject(context, offset, node) {\n const attributes = node.attributes ?? {};\n const variable = node.attributesWithVariableOffsets ?? [];\n const decoded = new Map();\n let size = node.size ?? node.endOfFixedSizeData ?? 0;\n\n for (const [ name, at ] of Object.entries(node.constantAttributeOffsets ?? {})) {\n decoded.set(name, ReadValue(context, offset + at, Attribute(attributes, name)).value);\n }\n\n if (variable.length) {\n const lookups = node.optionalValueLookups ?? {};\n const view = context.view;\n // The presence bitfield is written whenever a record has a variable section\n // at all, including where nothing in it is optional and the field is\n // therefore always zero. It is the offset table that shrinks, never this.\n const bits = view.getBigUint64(offset + node.endOfFixedSizeData, true);\n const table = offset + node.endOfFixedSizeData + 8;\n const present = variable.filter(name => {\n const attribute = Attribute(attributes, name);\n\n return !attribute.isOptional || (bits & BigInt(lookups[name] ?? 0)) !== 0n;\n });\n const data = table + present.length * 4;\n let end = data;\n\n present.forEach((name, index) => {\n const at = data + view.getUint32(table + index * 4, true);\n const read = ReadValue(context, at, Attribute(attributes, name));\n\n decoded.set(name, read.value);\n end = Math.max(end, at + read.size);\n });\n\n for (const name of variable) {\n const attribute = Attribute(attributes, name);\n\n // An absent optional takes the value the schema declares for it. Where no\n // default is declared the attribute is simply not part of this record -\n // which is what the published exports show for these same rows.\n if (!decoded.has(name) && Object.hasOwn(attribute, \"default\")) {\n decoded.set(name, attribute.default);\n }\n }\n\n size = end - offset;\n }\n\n // Declaration order, not the order the two passes above happened to fill.\n const value = {};\n\n for (const name of Object.keys(attributes)) {\n if (decoded.has(name)) value[name] = decoded.get(name);\n }\n\n return { value, size };\n}\n\n/** Looks up an attribute, naming the schema rather than failing on undefined. */\nfunction Attribute(attributes, name) {\n const attribute = attributes[name];\n\n if (!attribute) {\n throw SchemaBoundError(`The schema offsets an attribute it never declares: ${name}.`, {\n attribute: name\n });\n }\n\n return attribute;\n}\n\nexport default ReadValue;\n"],"names":["TEXT","TextDecoder","ReadValue","context","offset","node","type","ReadInt","ReadFloat","value","view","getUint8","size","ReadEnum","ReadVector3","ReadString","ReadList","ReadDict","ReadObject","SchemaBoundError","schemaType","unsigned","min","getInt8","getUint16","getInt16","getUint32","getInt32","Narrow","getBigUint64","getBigInt64","Number","getFloat64","getFloat32","readEnumValue","values","name","member","Object","entries","wide","precision","width","read","index","aliases","x","y","z","length","start","decode","bytes","subarray","count","items","fixedItemSize","undefined","end","at","item","itemTypes","push","Math","max","cursor","total","base","footerSize","footerStart","entry","keyFooter","key","valueTypes","attributes","variable","attributesWithVariableOffsets","decoded","Map","endOfFixedSizeData","constantAttributeOffsets","set","Attribute","lookups","optionalValueLookups","bits","table","present","filter","attribute","isOptional","BigInt","data","forEach","has","hasOwn","default","keys","get"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|