@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,348 +1,348 @@
1
- /** Maps serialized Carbon struct names to explicit constructors and layouts. */
2
- export class CjsStructRegistry
3
- {
4
- constructor(options = {})
5
- {
6
- const {
7
- name = "structs",
8
- family = "",
9
- constructors = null,
10
- layouts = null,
11
- entries = [],
12
- aliases = null,
13
- metadata = {}
14
- } = options;
15
-
16
- this.name = String(name || "structs");
17
- this.family = String(family || "");
18
- this.metadata = { ...metadata };
19
- this.entries = new Map();
20
- this.aliases = new Map();
21
- this.reports = [];
22
-
23
- if (constructors || layouts)
24
- {
25
- this.RegisterMaps({ constructors, layouts, aliases });
26
- }
27
-
28
- this.RegisterMany(entries);
29
- this.RegisterAliases(aliases);
30
- }
31
-
32
- get size()
33
- {
34
- return this.entries.size;
35
- }
36
-
37
- RegisterMaps(options = {})
38
- {
39
- const {
40
- constructors = {},
41
- layouts = {},
42
- aliases = {}
43
- } = options;
44
-
45
- const names = new Set([
46
- ...Object.keys(constructors || {}).filter(name => typeof constructors[name] === "function"),
47
- ...Object.keys(layouts || {})
48
- ]);
49
-
50
- for (const structName of names)
51
- {
52
- this.Register({
53
- structName,
54
- constructor: typeof constructors?.[structName] === "function" ? constructors[structName] : null,
55
- layout: layouts?.[structName] || null,
56
- aliases: aliasesForStructName(structName, aliases),
57
- family: layouts?.[structName]?.family || this.family
58
- });
59
- }
60
-
61
- return this;
62
- }
63
-
64
- RegisterMany(entries = [])
65
- {
66
- const list = Array.isArray(entries) ? entries : Object.values(entries || {});
67
- for (const entry of list)
68
- {
69
- this.Register(entry);
70
- }
71
- return this;
72
- }
73
-
74
- Register(entry)
75
- {
76
- const normalized = normalizeStructEntry(entry, this.family);
77
- const existing = this.entries.get(normalized.structName);
78
-
79
- if (existing)
80
- {
81
- this.entries.set(normalized.structName, mergeStructEntries(existing, normalized));
82
- this.ReportEntryClashes(existing, normalized);
83
- }
84
- else
85
- {
86
- this.entries.set(normalized.structName, normalized);
87
- }
88
-
89
- for (const alias of normalized.aliases)
90
- {
91
- this.RegisterAlias(alias, normalized.structName);
92
- }
93
-
94
- return this;
95
- }
96
-
97
- RegisterAliases(aliases = null)
98
- {
99
- if (!aliases) return this;
100
-
101
- if (Array.isArray(aliases))
102
- {
103
- for (const item of aliases)
104
- {
105
- if (Array.isArray(item)) this.RegisterAlias(item[0], item[1]);
106
- else this.RegisterAlias(item.alias, item.structName || item.name || item.target);
107
- }
108
- return this;
109
- }
110
-
111
- for (const [key, value] of Object.entries(aliases))
112
- {
113
- if (Array.isArray(value))
114
- {
115
- for (const alias of value)
116
- {
117
- this.RegisterAlias(alias, key);
118
- }
119
- }
120
- else
121
- {
122
- this.RegisterAlias(key, value);
123
- }
124
- }
125
-
126
- return this;
127
- }
128
-
129
- RegisterAlias(alias, structName)
130
- {
131
- if (!alias || !structName) return this;
132
-
133
- const normalizedAlias = String(alias);
134
- const normalizedStructName = String(structName);
135
- const existing = this.aliases.get(normalizedAlias);
136
-
137
- if (existing && existing !== normalizedStructName)
138
- {
139
- this.reports.push({
140
- level: "warning",
141
- code: "alias-clash",
142
- alias: normalizedAlias,
143
- existingStructName: existing,
144
- structName: normalizedStructName,
145
- message: `Struct alias ${normalizedAlias} already points to ${existing}`
146
- });
147
- return this;
148
- }
149
-
150
- if (this.entries.has(normalizedAlias) && normalizedAlias !== normalizedStructName)
151
- {
152
- this.reports.push({
153
- level: "warning",
154
- code: "alias-struct-clash",
155
- alias: normalizedAlias,
156
- structName: normalizedStructName,
157
- message: `Struct alias ${normalizedAlias} also names a registered struct`
158
- });
159
- }
160
-
161
- this.aliases.set(normalizedAlias, normalizedStructName);
162
- return this;
163
- }
164
-
165
- ResolveName(name)
166
- {
167
- let current = String(name || "");
168
- const seen = new Set();
169
-
170
- while (this.aliases.has(current) && !seen.has(current))
171
- {
172
- seen.add(current);
173
- current = this.aliases.get(current);
174
- }
175
-
176
- return current;
177
- }
178
-
179
- GetEntry(name)
180
- {
181
- return this.entries.get(this.ResolveName(name)) || null;
182
- }
183
-
184
- Has(name)
185
- {
186
- return Boolean(this.GetEntry(name));
187
- }
188
-
189
- GetConstructor(name)
190
- {
191
- return this.GetEntry(name)?.constructor || null;
192
- }
193
-
194
- GetLayout(name)
195
- {
196
- return this.GetEntry(name)?.layout || null;
197
- }
198
-
199
- Create(name, values = {})
200
- {
201
- const StructConstructor = this.GetConstructor(name);
202
- return StructConstructor ? new StructConstructor(values) : { ...values };
203
- }
204
-
205
- GetReports()
206
- {
207
- return this.reports.map(report => ({ ...report }));
208
- }
209
-
210
- ToJSON()
211
- {
212
- return {
213
- name: this.name,
214
- family: this.family,
215
- metadata: { ...this.metadata },
216
- entries: Array.from(this.entries.values()).map(entry => ({
217
- structName: entry.structName,
218
- family: entry.family,
219
- aliases: [...entry.aliases],
220
- hasConstructor: Boolean(entry.constructor),
221
- hasLayout: Boolean(entry.layout),
222
- layout: summarizeLayout(entry.layout)
223
- })),
224
- aliases: Object.fromEntries(this.aliases),
225
- reports: this.GetReports()
226
- };
227
- }
228
-
229
- [Symbol.iterator]()
230
- {
231
- return this.entries.values();
232
- }
233
-
234
- ReportEntryClashes(existing, incoming)
235
- {
236
- if (existing.constructor && incoming.constructor && existing.constructor !== incoming.constructor)
237
- {
238
- this.reports.push(createStructClash("constructor-clash", existing, incoming));
239
- }
240
-
241
- if (existing.layout && incoming.layout && existing.layout !== incoming.layout)
242
- {
243
- this.reports.push(createStructClash("layout-clash", existing, incoming));
244
- }
245
- }
246
-
247
- static from(options = {})
248
- {
249
- return options instanceof CjsStructRegistry ? options : new CjsStructRegistry(options);
250
- }
251
-
252
- static fromMaps(options = {})
253
- {
254
- return new CjsStructRegistry(options);
255
- }
256
- }
257
-
258
- function normalizeStructEntry(entry, defaultFamily)
259
- {
260
- if (!entry || typeof entry !== "object")
261
- {
262
- throw new TypeError("Struct registry entry must be an object");
263
- }
264
-
265
- const entryConstructor = Object.hasOwn(entry, "constructor") ? entry.constructor : null;
266
- const constructor = typeof entryConstructor === "function" ? entryConstructor : null;
267
- const layout = entry.layout || null;
268
- const structName = String(entry.structName || entry.name || layout?.structName || constructor?.sourceStruct || "");
269
-
270
- if (!structName)
271
- {
272
- throw new TypeError("Struct registry entry is missing a structName");
273
- }
274
-
275
- return {
276
- structName,
277
- constructor,
278
- layout,
279
- aliases: normalizeAliases(entry.aliases),
280
- family: String(entry.family || layout?.family || defaultFamily || ""),
281
- metadata: { ...(entry.metadata || {}) }
282
- };
283
- }
284
-
285
- function mergeStructEntries(existing, incoming)
286
- {
287
- return {
288
- structName: existing.structName,
289
- constructor: existing.constructor || incoming.constructor,
290
- layout: existing.layout || incoming.layout,
291
- aliases: Array.from(new Set([...existing.aliases, ...incoming.aliases])),
292
- family: existing.family || incoming.family,
293
- metadata: { ...existing.metadata, ...incoming.metadata }
294
- };
295
- }
296
-
297
- function normalizeAliases(aliases)
298
- {
299
- if (!aliases) return [];
300
- if (Array.isArray(aliases)) return aliases.map(String).filter(Boolean);
301
- return [String(aliases)].filter(Boolean);
302
- }
303
-
304
- function aliasesForStructName(structName, aliases)
305
- {
306
- if (!aliases || Array.isArray(aliases)) return [];
307
-
308
- const direct = aliases[structName];
309
- if (Array.isArray(direct)) return direct;
310
-
311
- const matched = [];
312
- for (const [alias, target] of Object.entries(aliases))
313
- {
314
- if (target === structName) matched.push(alias);
315
- }
316
- return matched;
317
- }
318
-
319
- function createStructClash(code, existing, incoming)
320
- {
321
- return {
322
- level: "warning",
323
- code,
324
- structName: existing.structName,
325
- message: `${existing.structName} has conflicting struct registry metadata`,
326
- existing: summarizeEntry(existing),
327
- incoming: summarizeEntry(incoming)
328
- };
329
- }
330
-
331
- function summarizeEntry(entry)
332
- {
333
- return {
334
- structName: entry.structName,
335
- hasConstructor: Boolean(entry.constructor),
336
- hasLayout: Boolean(entry.layout)
337
- };
338
- }
339
-
340
- function summarizeLayout(layout)
341
- {
342
- if (!layout || typeof layout !== "object") return null;
343
- return {
344
- structName: layout.structName || layout.name || null,
345
- byteSize: layout.byteSize ?? layout.structureSize ?? null,
346
- fieldCount: Array.isArray(layout.fields) ? layout.fields.length : null
347
- };
348
- }
1
+ /** Maps serialized Carbon struct names to explicit constructors and layouts. */
2
+ export class CjsStructRegistry
3
+ {
4
+ constructor(options = {})
5
+ {
6
+ const {
7
+ name = "structs",
8
+ family = "",
9
+ constructors = null,
10
+ layouts = null,
11
+ entries = [],
12
+ aliases = null,
13
+ metadata = {}
14
+ } = options;
15
+
16
+ this.name = String(name || "structs");
17
+ this.family = String(family || "");
18
+ this.metadata = { ...metadata };
19
+ this.entries = new Map();
20
+ this.aliases = new Map();
21
+ this.reports = [];
22
+
23
+ if (constructors || layouts)
24
+ {
25
+ this.RegisterMaps({ constructors, layouts, aliases });
26
+ }
27
+
28
+ this.RegisterMany(entries);
29
+ this.RegisterAliases(aliases);
30
+ }
31
+
32
+ get size()
33
+ {
34
+ return this.entries.size;
35
+ }
36
+
37
+ RegisterMaps(options = {})
38
+ {
39
+ const {
40
+ constructors = {},
41
+ layouts = {},
42
+ aliases = {}
43
+ } = options;
44
+
45
+ const names = new Set([
46
+ ...Object.keys(constructors || {}).filter(name => typeof constructors[name] === "function"),
47
+ ...Object.keys(layouts || {})
48
+ ]);
49
+
50
+ for (const structName of names)
51
+ {
52
+ this.Register({
53
+ structName,
54
+ constructor: typeof constructors?.[structName] === "function" ? constructors[structName] : null,
55
+ layout: layouts?.[structName] || null,
56
+ aliases: aliasesForStructName(structName, aliases),
57
+ family: layouts?.[structName]?.family || this.family
58
+ });
59
+ }
60
+
61
+ return this;
62
+ }
63
+
64
+ RegisterMany(entries = [])
65
+ {
66
+ const list = Array.isArray(entries) ? entries : Object.values(entries || {});
67
+ for (const entry of list)
68
+ {
69
+ this.Register(entry);
70
+ }
71
+ return this;
72
+ }
73
+
74
+ Register(entry)
75
+ {
76
+ const normalized = normalizeStructEntry(entry, this.family);
77
+ const existing = this.entries.get(normalized.structName);
78
+
79
+ if (existing)
80
+ {
81
+ this.entries.set(normalized.structName, mergeStructEntries(existing, normalized));
82
+ this.ReportEntryClashes(existing, normalized);
83
+ }
84
+ else
85
+ {
86
+ this.entries.set(normalized.structName, normalized);
87
+ }
88
+
89
+ for (const alias of normalized.aliases)
90
+ {
91
+ this.RegisterAlias(alias, normalized.structName);
92
+ }
93
+
94
+ return this;
95
+ }
96
+
97
+ RegisterAliases(aliases = null)
98
+ {
99
+ if (!aliases) return this;
100
+
101
+ if (Array.isArray(aliases))
102
+ {
103
+ for (const item of aliases)
104
+ {
105
+ if (Array.isArray(item)) this.RegisterAlias(item[0], item[1]);
106
+ else this.RegisterAlias(item.alias, item.structName || item.name || item.target);
107
+ }
108
+ return this;
109
+ }
110
+
111
+ for (const [key, value] of Object.entries(aliases))
112
+ {
113
+ if (Array.isArray(value))
114
+ {
115
+ for (const alias of value)
116
+ {
117
+ this.RegisterAlias(alias, key);
118
+ }
119
+ }
120
+ else
121
+ {
122
+ this.RegisterAlias(key, value);
123
+ }
124
+ }
125
+
126
+ return this;
127
+ }
128
+
129
+ RegisterAlias(alias, structName)
130
+ {
131
+ if (!alias || !structName) return this;
132
+
133
+ const normalizedAlias = String(alias);
134
+ const normalizedStructName = String(structName);
135
+ const existing = this.aliases.get(normalizedAlias);
136
+
137
+ if (existing && existing !== normalizedStructName)
138
+ {
139
+ this.reports.push({
140
+ level: "warning",
141
+ code: "alias-clash",
142
+ alias: normalizedAlias,
143
+ existingStructName: existing,
144
+ structName: normalizedStructName,
145
+ message: `Struct alias ${normalizedAlias} already points to ${existing}`
146
+ });
147
+ return this;
148
+ }
149
+
150
+ if (this.entries.has(normalizedAlias) && normalizedAlias !== normalizedStructName)
151
+ {
152
+ this.reports.push({
153
+ level: "warning",
154
+ code: "alias-struct-clash",
155
+ alias: normalizedAlias,
156
+ structName: normalizedStructName,
157
+ message: `Struct alias ${normalizedAlias} also names a registered struct`
158
+ });
159
+ }
160
+
161
+ this.aliases.set(normalizedAlias, normalizedStructName);
162
+ return this;
163
+ }
164
+
165
+ ResolveName(name)
166
+ {
167
+ let current = String(name || "");
168
+ const seen = new Set();
169
+
170
+ while (this.aliases.has(current) && !seen.has(current))
171
+ {
172
+ seen.add(current);
173
+ current = this.aliases.get(current);
174
+ }
175
+
176
+ return current;
177
+ }
178
+
179
+ GetEntry(name)
180
+ {
181
+ return this.entries.get(this.ResolveName(name)) || null;
182
+ }
183
+
184
+ Has(name)
185
+ {
186
+ return Boolean(this.GetEntry(name));
187
+ }
188
+
189
+ GetConstructor(name)
190
+ {
191
+ return this.GetEntry(name)?.constructor || null;
192
+ }
193
+
194
+ GetLayout(name)
195
+ {
196
+ return this.GetEntry(name)?.layout || null;
197
+ }
198
+
199
+ Create(name, values = {})
200
+ {
201
+ const StructConstructor = this.GetConstructor(name);
202
+ return StructConstructor ? new StructConstructor(values) : { ...values };
203
+ }
204
+
205
+ GetReports()
206
+ {
207
+ return this.reports.map(report => ({ ...report }));
208
+ }
209
+
210
+ ToJSON()
211
+ {
212
+ return {
213
+ name: this.name,
214
+ family: this.family,
215
+ metadata: { ...this.metadata },
216
+ entries: Array.from(this.entries.values()).map(entry => ({
217
+ structName: entry.structName,
218
+ family: entry.family,
219
+ aliases: [...entry.aliases],
220
+ hasConstructor: Boolean(entry.constructor),
221
+ hasLayout: Boolean(entry.layout),
222
+ layout: summarizeLayout(entry.layout)
223
+ })),
224
+ aliases: Object.fromEntries(this.aliases),
225
+ reports: this.GetReports()
226
+ };
227
+ }
228
+
229
+ [Symbol.iterator]()
230
+ {
231
+ return this.entries.values();
232
+ }
233
+
234
+ ReportEntryClashes(existing, incoming)
235
+ {
236
+ if (existing.constructor && incoming.constructor && existing.constructor !== incoming.constructor)
237
+ {
238
+ this.reports.push(createStructClash("constructor-clash", existing, incoming));
239
+ }
240
+
241
+ if (existing.layout && incoming.layout && existing.layout !== incoming.layout)
242
+ {
243
+ this.reports.push(createStructClash("layout-clash", existing, incoming));
244
+ }
245
+ }
246
+
247
+ static from(options = {})
248
+ {
249
+ return options instanceof CjsStructRegistry ? options : new CjsStructRegistry(options);
250
+ }
251
+
252
+ static fromMaps(options = {})
253
+ {
254
+ return new CjsStructRegistry(options);
255
+ }
256
+ }
257
+
258
+ function normalizeStructEntry(entry, defaultFamily)
259
+ {
260
+ if (!entry || typeof entry !== "object")
261
+ {
262
+ throw new TypeError("Struct registry entry must be an object");
263
+ }
264
+
265
+ const entryConstructor = Object.hasOwn(entry, "constructor") ? entry.constructor : null;
266
+ const constructor = typeof entryConstructor === "function" ? entryConstructor : null;
267
+ const layout = entry.layout || null;
268
+ const structName = String(entry.structName || entry.name || layout?.structName || constructor?.sourceStruct || "");
269
+
270
+ if (!structName)
271
+ {
272
+ throw new TypeError("Struct registry entry is missing a structName");
273
+ }
274
+
275
+ return {
276
+ structName,
277
+ constructor,
278
+ layout,
279
+ aliases: normalizeAliases(entry.aliases),
280
+ family: String(entry.family || layout?.family || defaultFamily || ""),
281
+ metadata: { ...(entry.metadata || {}) }
282
+ };
283
+ }
284
+
285
+ function mergeStructEntries(existing, incoming)
286
+ {
287
+ return {
288
+ structName: existing.structName,
289
+ constructor: existing.constructor || incoming.constructor,
290
+ layout: existing.layout || incoming.layout,
291
+ aliases: Array.from(new Set([...existing.aliases, ...incoming.aliases])),
292
+ family: existing.family || incoming.family,
293
+ metadata: { ...existing.metadata, ...incoming.metadata }
294
+ };
295
+ }
296
+
297
+ function normalizeAliases(aliases)
298
+ {
299
+ if (!aliases) return [];
300
+ if (Array.isArray(aliases)) return aliases.map(String).filter(Boolean);
301
+ return [String(aliases)].filter(Boolean);
302
+ }
303
+
304
+ function aliasesForStructName(structName, aliases)
305
+ {
306
+ if (!aliases || Array.isArray(aliases)) return [];
307
+
308
+ const direct = aliases[structName];
309
+ if (Array.isArray(direct)) return direct;
310
+
311
+ const matched = [];
312
+ for (const [alias, target] of Object.entries(aliases))
313
+ {
314
+ if (target === structName) matched.push(alias);
315
+ }
316
+ return matched;
317
+ }
318
+
319
+ function createStructClash(code, existing, incoming)
320
+ {
321
+ return {
322
+ level: "warning",
323
+ code,
324
+ structName: existing.structName,
325
+ message: `${existing.structName} has conflicting struct registry metadata`,
326
+ existing: summarizeEntry(existing),
327
+ incoming: summarizeEntry(incoming)
328
+ };
329
+ }
330
+
331
+ function summarizeEntry(entry)
332
+ {
333
+ return {
334
+ structName: entry.structName,
335
+ hasConstructor: Boolean(entry.constructor),
336
+ hasLayout: Boolean(entry.layout)
337
+ };
338
+ }
339
+
340
+ function summarizeLayout(layout)
341
+ {
342
+ if (!layout || typeof layout !== "object") return null;
343
+ return {
344
+ structName: layout.structName || layout.name || null,
345
+ byteSize: layout.byteSize ?? layout.structureSize ?? null,
346
+ fieldCount: Array.isArray(layout.fields) ? layout.fields.length : null
347
+ };
348
+ }