@carbonenginejs/runtime-utils 0.1.1 → 0.1.3

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 (104) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +23 -23
  3. package/README.md +69 -69
  4. package/THIRD-PARTY-NOTICES.md +64 -64
  5. package/docs/README.md +74 -73
  6. package/docs/architecture.md +101 -101
  7. package/docs/concepts/foundation-consolidation.md +85 -85
  8. package/docs/concepts/model-lifecycle.md +111 -0
  9. package/docs/const-kb.md +85 -87
  10. package/docs/core-types/DECORATOR-TODOS.md +25 -25
  11. package/docs/core-types/README.md +229 -168
  12. package/docs/reference/api.md +105 -102
  13. package/docs/reference/classes/README.md +135 -135
  14. package/package.json +139 -139
  15. package/src/arrays.js +5 -5
  16. package/src/audio/audioFormats.js +34 -34
  17. package/src/audio/index.js +1 -1
  18. package/src/box3.js +331 -331
  19. package/src/bytes.js +56 -56
  20. package/src/compression.js +56 -56
  21. package/src/constants/index.js +7 -7
  22. package/src/constants/trinity.js +13 -13
  23. package/src/constants.js +15 -15
  24. package/src/curve.js +79 -79
  25. package/src/d3d/dxgiFormats.js +46 -46
  26. package/src/d3d/index.js +2 -2
  27. package/src/d3d/primitiveTopology.js +11 -11
  28. package/src/document/CjsCarbonDocument.js +212 -212
  29. package/src/document/CjsClassRegistry.js +373 -373
  30. package/src/document/CjsDocumentDehydrator.js +142 -142
  31. package/src/document/CjsDocumentHydrator.js +156 -156
  32. package/src/document/CjsStructRegistry.js +348 -348
  33. package/src/document/hydrationAdapter.js +129 -129
  34. package/src/document/index.js +6 -6
  35. package/src/errors/CjsError.js +286 -286
  36. package/src/errors/index.js +5 -5
  37. package/src/geometry/box.js +22 -22
  38. package/src/geometry/cylinder.js +22 -22
  39. package/src/geometry/helpers/earcut.js +1 -1
  40. package/src/geometry/helpers/misc.js +3 -3
  41. package/src/geometry/index.js +8 -8
  42. package/src/geometry/json.js +67 -67
  43. package/src/geometry/lathe.js +44 -44
  44. package/src/geometry/plane.js +14 -14
  45. package/src/geometry/shape.js +4 -4
  46. package/src/geometry/sphere.js +24 -24
  47. package/src/geometry/torus.js +14 -14
  48. package/src/graphics/colorSpaces.js +22 -22
  49. package/src/graphics/index.js +4 -4
  50. package/src/graphics/pixelFormats.js +158 -158
  51. package/src/graphics/textureDimensions.js +22 -22
  52. package/src/graphics/trinityEnums.js +87 -87
  53. package/src/index.js +62 -62
  54. package/src/is.js +108 -46
  55. package/src/json.js +23 -23
  56. package/src/lifecycle/CjsLifecycleState.js +77 -77
  57. package/src/lifecycle/index.js +1 -1
  58. package/src/lne3.js +70 -70
  59. package/src/lookup.js +48 -48
  60. package/src/mat3.js +51 -51
  61. package/src/mat4.js +699 -699
  62. package/src/math/index.js +25 -25
  63. package/src/math/scalar.js +63 -63
  64. package/src/media/index.js +1 -1
  65. package/src/media/mediaTypes.js +50 -50
  66. package/src/mesh.js +424 -424
  67. package/src/model/CjsEventEmitter.js +333 -333
  68. package/src/model/CjsModel.js +1589 -1544
  69. package/src/model/CjsModelState.js +72 -72
  70. package/src/model/index.js +4 -4
  71. package/src/model/sourceRecordUtils.js +54 -54
  72. package/src/noise.js +310 -310
  73. package/src/num.js +827 -827
  74. package/src/object.js +39 -39
  75. package/src/path.js +53 -53
  76. package/src/pln.js +125 -125
  77. package/src/pool.js +9 -9
  78. package/src/quat.js +144 -144
  79. package/src/ray3.js +188 -188
  80. package/src/renderContext/formats.js +145 -145
  81. package/src/renderContext/index.js +5 -5
  82. package/src/renderContext/presentation.js +125 -125
  83. package/src/renderContext/resources.js +27 -27
  84. package/src/renderContext/upscaling.js +22 -22
  85. package/src/renderContext/window.js +20 -20
  86. package/src/runtime/CjsRuntimeState.js +50 -50
  87. package/src/schema/CjsSchema.js +555 -318
  88. package/src/schema/index.js +4 -4
  89. package/src/shader/index.js +1 -1
  90. package/src/shader/shaderStages.js +37 -37
  91. package/src/sph3.js +181 -181
  92. package/src/tangent.js +288 -288
  93. package/src/text.js +40 -40
  94. package/src/tri3.js +98 -98
  95. package/src/types/carbonTypes.js +635 -635
  96. package/src/types/index.js +2 -2
  97. package/src/utils.js +58 -58
  98. package/src/validation.js +46 -46
  99. package/src/vec2.js +229 -229
  100. package/src/vec3.js +1188 -1172
  101. package/src/vec4.js +347 -347
  102. package/src/vertex.js +108 -108
  103. package/src/webgpu/index.js +1 -1
  104. package/src/webgpu/textureFormats.js +121 -121
@@ -1,142 +1,142 @@
1
- import { exportCarbonValue } from "../types/index.js";
2
- import { CjsSchema } from "../schema/index.js";
3
- import { CjsCarbonDocument } from "./CjsCarbonDocument.js";
4
-
5
- /** Converts runtime object graphs into neutral Carbon documents. */
6
- export class CjsDocumentDehydrator
7
- {
8
- Dehydrate(value, options = {})
9
- {
10
- return CjsDocumentDehydrator.dehydrate(value, options);
11
- }
12
-
13
- static dehydrate(value, options = {})
14
- {
15
- const state = {
16
- nextId: options.firstId || 1,
17
- objectIds: new Map(),
18
- nodes: [],
19
- refs: {},
20
- includeClassMetadata: Boolean(options.includeClassMetadata || options.trace || options.debug),
21
- includeRefIndex: Boolean(options.includeRefIndex || options.trace || options.debug)
22
- };
23
-
24
- const rootRef = CjsDocumentDehydrator.dehydrateValue(value, state);
25
- if (!CjsCarbonDocument.isRef(rootRef))
26
- {
27
- throw new TypeError("CarbonDocument roots must be source-shaped objects");
28
- }
29
-
30
- if (state.includeRefIndex)
31
- {
32
- for (const node of state.nodes)
33
- {
34
- state.refs[String(node.id)] = {
35
- kind: node.kind
36
- };
37
- }
38
- }
39
-
40
- return CjsCarbonDocument.create({
41
- format: options.format || { id: "runtime", version: 1 },
42
- roots: [{ name: options.rootName || "default", ref: rootRef }],
43
- nodes: state.nodes.sort((a, b) => a.id - b.id),
44
- refs: state.includeRefIndex ? state.refs : null,
45
- metadata: options.metadata || {},
46
- reports: options.reports || []
47
- });
48
- }
49
-
50
- static dehydrateValue(value, state)
51
- {
52
- if (CjsDocumentDehydrator.isSourceShapedObject(value)) return CjsDocumentDehydrator.dehydrateSourceObject(value, state);
53
- if (Array.isArray(value)) return value.map(item => CjsDocumentDehydrator.dehydrateValue(item, state));
54
- if (value instanceof Map) return Object.fromEntries(Array.from(value.entries()).map(([key, item]) => [key, CjsDocumentDehydrator.dehydrateValue(item, state)]));
55
- if (value instanceof Set) return Array.from(value.values()).map(item => CjsDocumentDehydrator.dehydrateValue(item, state));
56
- if (value && typeof value === "object" && !ArrayBuffer.isView(value))
57
- {
58
- return Object.fromEntries(
59
- Object.entries(value)
60
- .filter(([key]) => !key.startsWith("_"))
61
- .map(([key, item]) => [key, CjsDocumentDehydrator.dehydrateValue(item, state)])
62
- );
63
- }
64
- return exportCarbonValue(value);
65
- }
66
-
67
- static dehydrateSourceObject(value, state)
68
- {
69
- if (state.objectIds.has(value)) return CjsCarbonDocument.createRef(state.objectIds.get(value));
70
-
71
- const id = state.nextId++;
72
- state.objectIds.set(value, id);
73
-
74
- const shape = value._sourceShape || null;
75
- const schemaName = typeof value.GetValues === "function"
76
- ? CjsSchema.getClassName(value.constructor)
77
- : null;
78
- const kind = schemaName || value._sourceClassName;
79
- if (!kind)
80
- {
81
- throw new TypeError("Hydratable objects require an explicit schema className.");
82
- }
83
- const fields = {};
84
- const fieldNames = new Set();
85
-
86
- if (shape?.fields)
87
- {
88
- for (const field of shape.fields)
89
- {
90
- if (schemaName && CjsSchema.isFieldHidden(value.constructor, field.name)) continue;
91
- fieldNames.add(field.name);
92
- fields[field.name] = CjsDocumentDehydrator.dehydrateValue(value[field.name], state);
93
- }
94
- }
95
- else if (typeof value.GetValues === "function")
96
- {
97
- for (const [key, item] of Object.entries(value.GetValues()))
98
- {
99
- fieldNames.add(key);
100
- fields[key] = CjsDocumentDehydrator.dehydrateValue(item, state);
101
- }
102
- }
103
-
104
- const raw = {};
105
- for (const [key, item] of Object.entries(value))
106
- {
107
- if (key.startsWith("_") || fieldNames.has(key)) continue;
108
- if (schemaName && CjsSchema.isFieldHidden(value.constructor, key)) continue;
109
- raw[key] = CjsDocumentDehydrator.dehydrateValue(item, state);
110
- }
111
-
112
- const node = {
113
- id,
114
- kind,
115
- fields
116
- };
117
-
118
- if (state.includeClassMetadata)
119
- {
120
- node.source = shape?.source || {};
121
- node.meta = {
122
- family: shape?.family || null,
123
- hashes: shape?.hashes || null,
124
- blue: shape?.blue || null
125
- };
126
- }
127
-
128
- if (Object.keys(raw).length) node.raw = raw;
129
-
130
- state.nodes.push(node);
131
-
132
- return CjsCarbonDocument.createRef(id);
133
- }
134
-
135
- static isSourceShapedObject(value)
136
- {
137
- return Boolean(value && typeof value === "object" && (
138
- value._sourceClassName
139
- || (typeof value.GetValues === "function" && CjsSchema.getClassName(value.constructor))
140
- ));
141
- }
142
- }
1
+ import { exportCarbonValue } from "../types/index.js";
2
+ import { CjsSchema } from "../schema/index.js";
3
+ import { CjsCarbonDocument } from "./CjsCarbonDocument.js";
4
+
5
+ /** Converts runtime object graphs into neutral Carbon documents. */
6
+ export class CjsDocumentDehydrator
7
+ {
8
+ Dehydrate(value, options = {})
9
+ {
10
+ return CjsDocumentDehydrator.dehydrate(value, options);
11
+ }
12
+
13
+ static dehydrate(value, options = {})
14
+ {
15
+ const state = {
16
+ nextId: options.firstId || 1,
17
+ objectIds: new Map(),
18
+ nodes: [],
19
+ refs: {},
20
+ includeClassMetadata: Boolean(options.includeClassMetadata || options.trace || options.debug),
21
+ includeRefIndex: Boolean(options.includeRefIndex || options.trace || options.debug)
22
+ };
23
+
24
+ const rootRef = CjsDocumentDehydrator.dehydrateValue(value, state);
25
+ if (!CjsCarbonDocument.isRef(rootRef))
26
+ {
27
+ throw new TypeError("CarbonDocument roots must be source-shaped objects");
28
+ }
29
+
30
+ if (state.includeRefIndex)
31
+ {
32
+ for (const node of state.nodes)
33
+ {
34
+ state.refs[String(node.id)] = {
35
+ kind: node.kind
36
+ };
37
+ }
38
+ }
39
+
40
+ return CjsCarbonDocument.create({
41
+ format: options.format || { id: "runtime", version: 1 },
42
+ roots: [{ name: options.rootName || "default", ref: rootRef }],
43
+ nodes: state.nodes.sort((a, b) => a.id - b.id),
44
+ refs: state.includeRefIndex ? state.refs : null,
45
+ metadata: options.metadata || {},
46
+ reports: options.reports || []
47
+ });
48
+ }
49
+
50
+ static dehydrateValue(value, state)
51
+ {
52
+ if (CjsDocumentDehydrator.isSourceShapedObject(value)) return CjsDocumentDehydrator.dehydrateSourceObject(value, state);
53
+ if (Array.isArray(value)) return value.map(item => CjsDocumentDehydrator.dehydrateValue(item, state));
54
+ if (value instanceof Map) return Object.fromEntries(Array.from(value.entries()).map(([key, item]) => [key, CjsDocumentDehydrator.dehydrateValue(item, state)]));
55
+ if (value instanceof Set) return Array.from(value.values()).map(item => CjsDocumentDehydrator.dehydrateValue(item, state));
56
+ if (value && typeof value === "object" && !ArrayBuffer.isView(value))
57
+ {
58
+ return Object.fromEntries(
59
+ Object.entries(value)
60
+ .filter(([key]) => !key.startsWith("_"))
61
+ .map(([key, item]) => [key, CjsDocumentDehydrator.dehydrateValue(item, state)])
62
+ );
63
+ }
64
+ return exportCarbonValue(value);
65
+ }
66
+
67
+ static dehydrateSourceObject(value, state)
68
+ {
69
+ if (state.objectIds.has(value)) return CjsCarbonDocument.createRef(state.objectIds.get(value));
70
+
71
+ const id = state.nextId++;
72
+ state.objectIds.set(value, id);
73
+
74
+ const shape = value._sourceShape || null;
75
+ const schemaName = typeof value.GetValues === "function"
76
+ ? CjsSchema.getClassName(value.constructor)
77
+ : null;
78
+ const kind = schemaName || value._sourceClassName;
79
+ if (!kind)
80
+ {
81
+ throw new TypeError("Hydratable objects require an explicit schema className.");
82
+ }
83
+ const fields = {};
84
+ const fieldNames = new Set();
85
+
86
+ if (shape?.fields)
87
+ {
88
+ for (const field of shape.fields)
89
+ {
90
+ if (schemaName && CjsSchema.isFieldHidden(value.constructor, field.name)) continue;
91
+ fieldNames.add(field.name);
92
+ fields[field.name] = CjsDocumentDehydrator.dehydrateValue(value[field.name], state);
93
+ }
94
+ }
95
+ else if (typeof value.GetValues === "function")
96
+ {
97
+ for (const [key, item] of Object.entries(value.GetValues()))
98
+ {
99
+ fieldNames.add(key);
100
+ fields[key] = CjsDocumentDehydrator.dehydrateValue(item, state);
101
+ }
102
+ }
103
+
104
+ const raw = {};
105
+ for (const [key, item] of Object.entries(value))
106
+ {
107
+ if (key.startsWith("_") || fieldNames.has(key)) continue;
108
+ if (schemaName && CjsSchema.isFieldHidden(value.constructor, key)) continue;
109
+ raw[key] = CjsDocumentDehydrator.dehydrateValue(item, state);
110
+ }
111
+
112
+ const node = {
113
+ id,
114
+ kind,
115
+ fields
116
+ };
117
+
118
+ if (state.includeClassMetadata)
119
+ {
120
+ node.source = shape?.source || {};
121
+ node.meta = {
122
+ family: shape?.family || null,
123
+ hashes: shape?.hashes || null,
124
+ blue: shape?.blue || null
125
+ };
126
+ }
127
+
128
+ if (Object.keys(raw).length) node.raw = raw;
129
+
130
+ state.nodes.push(node);
131
+
132
+ return CjsCarbonDocument.createRef(id);
133
+ }
134
+
135
+ static isSourceShapedObject(value)
136
+ {
137
+ return Boolean(value && typeof value === "object" && (
138
+ value._sourceClassName
139
+ || (typeof value.GetValues === "function" && CjsSchema.getClassName(value.constructor))
140
+ ));
141
+ }
142
+ }
@@ -1,156 +1,156 @@
1
- import { normalizeCarbonValue } from "../types/index.js";
2
- import { CjsSchema } from "../schema/index.js";
3
- import { CjsCarbonDocument } from "./CjsCarbonDocument.js";
4
- import { resolveHydrationAdapter } from "./hydrationAdapter.js";
5
-
6
- /** Constructs runtime object graphs from neutral Carbon documents. */
7
- export class CjsDocumentHydrator
8
- {
9
- Hydrate(document, options = {})
10
- {
11
- return CjsDocumentHydrator.hydrate(document, options);
12
- }
13
-
14
- HydrateRoot(document, options = {})
15
- {
16
- return CjsDocumentHydrator.hydrateRoot(document, options);
17
- }
18
-
19
- static hydrate(document, options = {})
20
- {
21
- const normalized = CjsCarbonDocument.normalize(document);
22
- const nodeById = new Map(normalized.nodes.map(node => [node.id, node]));
23
- const instanceById = new Map();
24
- const reports = [];
25
- const adapter = resolveHydrationAdapter(options);
26
-
27
- for (const node of normalized.nodes)
28
- {
29
- instanceById.set(node.id, CjsDocumentHydrator.createNodeTarget(node, options, reports, adapter));
30
- }
31
-
32
- for (const node of normalized.nodes)
33
- {
34
- CjsDocumentHydrator.applyNodeValues(instanceById.get(node.id), node, instanceById, options, adapter);
35
- }
36
-
37
- // Phase 3: every instance is constructed and valued, so references are
38
- // resolved - now let callers run their own post-graph init.
39
- for (const node of normalized.nodes)
40
- {
41
- adapter.finalize(instanceById.get(node.id), { kind: node.kind, node, options });
42
- }
43
-
44
- const roots = normalized.roots.map(root => ({
45
- name: root.name,
46
- value: CjsDocumentHydrator.resolveDocumentValue(root.ref, instanceById, options)
47
- }));
48
-
49
- return {
50
- root: roots[0]?.value ?? null,
51
- roots,
52
- document: normalized,
53
- reports,
54
- get(id)
55
- {
56
- return instanceById.get(Number(id)) || null;
57
- },
58
- getNode(id)
59
- {
60
- return nodeById.get(Number(id)) || null;
61
- }
62
- };
63
- }
64
-
65
- static hydrateRoot(document, options = {})
66
- {
67
- return CjsDocumentHydrator.hydrate(document, options).root;
68
- }
69
-
70
- static createNodeTarget(node, options, reports, adapter)
71
- {
72
- if (adapter)
73
- {
74
- const built = adapter.construct(node.kind, { kind: node.kind, node, options });
75
- if (built !== undefined) return built;
76
- }
77
-
78
- const ClassConstructor = CjsDocumentHydrator.resolveClass(node.kind, options);
79
- if (ClassConstructor)
80
- {
81
- return new ClassConstructor();
82
- }
83
-
84
- throw new TypeError(`No class is registered for hydratable type ${node.kind}.`);
85
- }
86
-
87
- static applyNodeValues(target, node, instanceById, options, adapter)
88
- {
89
- const registeredSchema = target?.constructor
90
- ? CjsSchema.getSchema(target.constructor)
91
- : null;
92
- const shape = target?._sourceShape || (registeredSchema?.className ? registeredSchema : null);
93
- const fieldByName = new Map((shape?.fields || []).map(field => [field.name, field]));
94
- const values = {};
95
-
96
- for (const [key, item] of Object.entries(node.fields || {}))
97
- {
98
- if (CjsSchema.isFieldHidden(target?.constructor, key)) continue;
99
- const field = fieldByName.get(key) || null;
100
- values[key] = CjsDocumentHydrator.hydrateFieldValue(item, field, instanceById, options);
101
- }
102
-
103
- for (const [key, item] of Object.entries(node.raw || {}))
104
- {
105
- if (CjsSchema.isFieldHidden(target?.constructor, key)) continue;
106
- values[key] = CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options);
107
- }
108
-
109
- const apply = adapter || resolveHydrationAdapter(options);
110
- apply.applyValues(target, values, { kind: node.kind, shape, node, options });
111
- return target;
112
- }
113
-
114
- static hydrateFieldValue(value, field, instanceById, options)
115
- {
116
- const resolved = CjsDocumentHydrator.resolveDocumentValue(value, instanceById, options);
117
- const descriptor = field?.type || field?.jsType || null;
118
- const kind = descriptor?.kind;
119
-
120
- if ((kind === "array" || kind === "list") && Array.isArray(resolved)) return resolved;
121
- if ((kind === "model" || kind === "objectRef" || kind === "struct" || kind === "rawStruct" || kind === "unknown") && resolved && typeof resolved === "object") return resolved;
122
- if (CjsDocumentHydrator.isShapeIncompatibleMathArray(resolved, descriptor)) return resolved;
123
-
124
- return descriptor ? normalizeCarbonValue(resolved, descriptor) : resolved;
125
- }
126
-
127
- static resolveDocumentValue(value, instanceById, options)
128
- {
129
- if (CjsCarbonDocument.isRef(value))
130
- {
131
- const id = Number(value.$ref);
132
- if (instanceById.has(id)) return instanceById.get(id);
133
- if (options.allowMissingRefs) return null;
134
- throw new TypeError(`CarbonDocument ref ${id} does not exist`);
135
- }
136
-
137
- if (Array.isArray(value)) return value.map(item => CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options));
138
- if (value && typeof value === "object")
139
- {
140
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options)]));
141
- }
142
- return value;
143
- }
144
-
145
- static resolveClass(kind, options)
146
- {
147
- const Schema = options.registry || CjsSchema;
148
- return Schema.GetConstructor(kind);
149
- }
150
-
151
- static isShapeIncompatibleMathArray(value, descriptor)
152
- {
153
- const expectedLength = descriptor?.length;
154
- return Array.isArray(value) && Number.isInteger(expectedLength) && value.length !== expectedLength;
155
- }
156
- }
1
+ import { normalizeCarbonValue } from "../types/index.js";
2
+ import { CjsSchema } from "../schema/index.js";
3
+ import { CjsCarbonDocument } from "./CjsCarbonDocument.js";
4
+ import { resolveHydrationAdapter } from "./hydrationAdapter.js";
5
+
6
+ /** Constructs runtime object graphs from neutral Carbon documents. */
7
+ export class CjsDocumentHydrator
8
+ {
9
+ Hydrate(document, options = {})
10
+ {
11
+ return CjsDocumentHydrator.hydrate(document, options);
12
+ }
13
+
14
+ HydrateRoot(document, options = {})
15
+ {
16
+ return CjsDocumentHydrator.hydrateRoot(document, options);
17
+ }
18
+
19
+ static hydrate(document, options = {})
20
+ {
21
+ const normalized = CjsCarbonDocument.normalize(document);
22
+ const nodeById = new Map(normalized.nodes.map(node => [node.id, node]));
23
+ const instanceById = new Map();
24
+ const reports = [];
25
+ const adapter = resolveHydrationAdapter(options);
26
+
27
+ for (const node of normalized.nodes)
28
+ {
29
+ instanceById.set(node.id, CjsDocumentHydrator.createNodeTarget(node, options, reports, adapter));
30
+ }
31
+
32
+ for (const node of normalized.nodes)
33
+ {
34
+ CjsDocumentHydrator.applyNodeValues(instanceById.get(node.id), node, instanceById, options, adapter);
35
+ }
36
+
37
+ // Phase 3: every instance is constructed and valued, so references are
38
+ // resolved - now let callers run their own post-graph init.
39
+ for (const node of normalized.nodes)
40
+ {
41
+ adapter.finalize(instanceById.get(node.id), { kind: node.kind, node, options });
42
+ }
43
+
44
+ const roots = normalized.roots.map(root => ({
45
+ name: root.name,
46
+ value: CjsDocumentHydrator.resolveDocumentValue(root.ref, instanceById, options)
47
+ }));
48
+
49
+ return {
50
+ root: roots[0]?.value ?? null,
51
+ roots,
52
+ document: normalized,
53
+ reports,
54
+ get(id)
55
+ {
56
+ return instanceById.get(Number(id)) || null;
57
+ },
58
+ getNode(id)
59
+ {
60
+ return nodeById.get(Number(id)) || null;
61
+ }
62
+ };
63
+ }
64
+
65
+ static hydrateRoot(document, options = {})
66
+ {
67
+ return CjsDocumentHydrator.hydrate(document, options).root;
68
+ }
69
+
70
+ static createNodeTarget(node, options, reports, adapter)
71
+ {
72
+ if (adapter)
73
+ {
74
+ const built = adapter.construct(node.kind, { kind: node.kind, node, options });
75
+ if (built !== undefined) return built;
76
+ }
77
+
78
+ const ClassConstructor = CjsDocumentHydrator.resolveClass(node.kind, options);
79
+ if (ClassConstructor)
80
+ {
81
+ return new ClassConstructor();
82
+ }
83
+
84
+ throw new TypeError(`No class is registered for hydratable type ${node.kind}.`);
85
+ }
86
+
87
+ static applyNodeValues(target, node, instanceById, options, adapter)
88
+ {
89
+ const registeredSchema = target?.constructor
90
+ ? CjsSchema.getSchema(target.constructor)
91
+ : null;
92
+ const shape = target?._sourceShape || (registeredSchema?.className ? registeredSchema : null);
93
+ const fieldByName = new Map((shape?.fields || []).map(field => [field.name, field]));
94
+ const values = {};
95
+
96
+ for (const [key, item] of Object.entries(node.fields || {}))
97
+ {
98
+ if (CjsSchema.isFieldHidden(target?.constructor, key)) continue;
99
+ const field = fieldByName.get(key) || null;
100
+ values[key] = CjsDocumentHydrator.hydrateFieldValue(item, field, instanceById, options);
101
+ }
102
+
103
+ for (const [key, item] of Object.entries(node.raw || {}))
104
+ {
105
+ if (CjsSchema.isFieldHidden(target?.constructor, key)) continue;
106
+ values[key] = CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options);
107
+ }
108
+
109
+ const apply = adapter || resolveHydrationAdapter(options);
110
+ apply.applyValues(target, values, { kind: node.kind, shape, node, options });
111
+ return target;
112
+ }
113
+
114
+ static hydrateFieldValue(value, field, instanceById, options)
115
+ {
116
+ const resolved = CjsDocumentHydrator.resolveDocumentValue(value, instanceById, options);
117
+ const descriptor = field?.type || field?.jsType || null;
118
+ const kind = descriptor?.kind;
119
+
120
+ if ((kind === "array" || kind === "list") && Array.isArray(resolved)) return resolved;
121
+ if ((kind === "model" || kind === "objectRef" || kind === "struct" || kind === "rawStruct" || kind === "unknown") && resolved && typeof resolved === "object") return resolved;
122
+ if (CjsDocumentHydrator.isShapeIncompatibleMathArray(resolved, descriptor)) return resolved;
123
+
124
+ return descriptor ? normalizeCarbonValue(resolved, descriptor) : resolved;
125
+ }
126
+
127
+ static resolveDocumentValue(value, instanceById, options)
128
+ {
129
+ if (CjsCarbonDocument.isRef(value))
130
+ {
131
+ const id = Number(value.$ref);
132
+ if (instanceById.has(id)) return instanceById.get(id);
133
+ if (options.allowMissingRefs) return null;
134
+ throw new TypeError(`CarbonDocument ref ${id} does not exist`);
135
+ }
136
+
137
+ if (Array.isArray(value)) return value.map(item => CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options));
138
+ if (value && typeof value === "object")
139
+ {
140
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, CjsDocumentHydrator.resolveDocumentValue(item, instanceById, options)]));
141
+ }
142
+ return value;
143
+ }
144
+
145
+ static resolveClass(kind, options)
146
+ {
147
+ const Schema = options.registry || CjsSchema;
148
+ return Schema.GetConstructor(kind);
149
+ }
150
+
151
+ static isShapeIncompatibleMathArray(value, descriptor)
152
+ {
153
+ const expectedLength = descriptor?.length;
154
+ return Array.isArray(value) && Number.isInteger(expectedLength) && value.length !== expectedLength;
155
+ }
156
+ }