@neocompose/cli 0.23.0 → 0.23.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/neo.mjs CHANGED
@@ -28857,6 +28857,316 @@ var init_contracts = __esm({
28857
28857
  }
28858
28858
  });
28859
28859
 
28860
+ // src/project-sync/merge.ts
28861
+ function threeWayMergeRecord(base, server, local, policy = {}) {
28862
+ const baseRecord = isObjectRecord2(base) ? base : {};
28863
+ const serverRecord = isObjectRecord2(server) ? server : {};
28864
+ const localRecord = isObjectRecord2(local) ? local : {};
28865
+ const comparisonBase = policy.comparison?.base ?? baseRecord;
28866
+ const comparisonServer = policy.comparison?.server ?? serverRecord;
28867
+ const comparisonLocal = policy.comparison?.local ?? localRecord;
28868
+ const merged = {};
28869
+ const conflictFields = [];
28870
+ const keys = /* @__PURE__ */ new Set([
28871
+ ...Object.keys(serverRecord),
28872
+ ...Object.keys(localRecord),
28873
+ ...Object.keys(baseRecord)
28874
+ ]);
28875
+ for (const key of keys) {
28876
+ const rawServerValue = serverRecord[key];
28877
+ const rawLocalValue = localRecord[key];
28878
+ if (policy.serverWinsFields?.has(key) === true) {
28879
+ if (rawServerValue !== void 0) merged[key] = rawServerValue;
28880
+ continue;
28881
+ }
28882
+ const baseValue = comparisonBase[key];
28883
+ const serverValue = comparisonServer[key];
28884
+ const localValue = comparisonLocal[key];
28885
+ const result = mergeValue({
28886
+ rawBase: baseRecord[key],
28887
+ rawServer: rawServerValue,
28888
+ rawLocal: rawLocalValue,
28889
+ base: baseValue,
28890
+ server: serverValue,
28891
+ local: localValue,
28892
+ path: key,
28893
+ recursive: policy.recursive === true
28894
+ });
28895
+ if (result.conflicts.length > 0) {
28896
+ conflictFields.push(...result.conflicts);
28897
+ } else if (result.present) {
28898
+ merged[key] = result.value;
28899
+ }
28900
+ }
28901
+ return { merged, conflictFields };
28902
+ }
28903
+ function mergeValue(args) {
28904
+ if (canonicallyEqual(args.server, args.base)) {
28905
+ return selected(args.rawLocal);
28906
+ }
28907
+ if (canonicallyEqual(args.local, args.base)) {
28908
+ return selected(args.rawServer);
28909
+ }
28910
+ if (canonicallyEqual(args.local, args.server)) {
28911
+ return selected(args.rawLocal);
28912
+ }
28913
+ if (!args.recursive) return conflict(args.path);
28914
+ if (isObjectRecord2(args.rawBase) && isObjectRecord2(args.rawServer) && isObjectRecord2(args.rawLocal)) {
28915
+ const comparisonBase = isObjectRecord2(args.base) ? args.base : args.rawBase;
28916
+ const comparisonServer = isObjectRecord2(args.server) ? args.server : args.rawServer;
28917
+ const comparisonLocal = isObjectRecord2(args.local) ? args.local : args.rawLocal;
28918
+ const value = {};
28919
+ const conflicts = [];
28920
+ const keys = /* @__PURE__ */ new Set([
28921
+ ...Object.keys(args.rawBase),
28922
+ ...Object.keys(args.rawServer),
28923
+ ...Object.keys(args.rawLocal)
28924
+ ]);
28925
+ for (const key of keys) {
28926
+ const nested = mergeValue({
28927
+ rawBase: args.rawBase[key],
28928
+ rawServer: args.rawServer[key],
28929
+ rawLocal: args.rawLocal[key],
28930
+ base: comparisonBase[key],
28931
+ server: comparisonServer[key],
28932
+ local: comparisonLocal[key],
28933
+ path: `${args.path}.${key}`,
28934
+ recursive: true
28935
+ });
28936
+ conflicts.push(...nested.conflicts);
28937
+ if (nested.present) value[key] = nested.value;
28938
+ }
28939
+ return { present: true, value, conflicts };
28940
+ }
28941
+ if (Array.isArray(args.rawBase) && Array.isArray(args.rawServer) && Array.isArray(args.rawLocal)) {
28942
+ return mergeIdentityArray(
28943
+ args.rawBase,
28944
+ args.rawServer,
28945
+ args.rawLocal,
28946
+ args.path
28947
+ );
28948
+ }
28949
+ return conflict(args.path);
28950
+ }
28951
+ function mergeIdentityArray(base, server, local, path) {
28952
+ const baseItems = indexIdentityArray(base);
28953
+ const serverItems = indexIdentityArray(server);
28954
+ const localItems = indexIdentityArray(local);
28955
+ if (baseItems === null || serverItems === null || localItems === null) {
28956
+ return conflict(path);
28957
+ }
28958
+ const retained = /* @__PURE__ */ new Map();
28959
+ const conflicts = [];
28960
+ const ids = /* @__PURE__ */ new Set([
28961
+ ...baseItems.order,
28962
+ ...serverItems.order,
28963
+ ...localItems.order
28964
+ ]);
28965
+ for (const id2 of ids) {
28966
+ const baseHas = baseItems.values.has(id2);
28967
+ const serverHas = serverItems.values.has(id2);
28968
+ const localHas = localItems.values.has(id2);
28969
+ const baseValue = baseItems.values.get(id2);
28970
+ const serverValue = serverItems.values.get(id2);
28971
+ const localValue = localItems.values.get(id2);
28972
+ if (baseHas && !serverHas && !localHas) continue;
28973
+ if (baseHas && !serverHas) {
28974
+ if (canonicallyEqual(localValue, baseValue)) continue;
28975
+ conflicts.push(`${path}[${JSON.stringify(id2)}]`);
28976
+ continue;
28977
+ }
28978
+ if (baseHas && !localHas) {
28979
+ if (canonicallyEqual(serverValue, baseValue)) continue;
28980
+ conflicts.push(`${path}[${JSON.stringify(id2)}]`);
28981
+ continue;
28982
+ }
28983
+ if (!serverHas && localHas) {
28984
+ retained.set(id2, localValue);
28985
+ continue;
28986
+ }
28987
+ if (!localHas && serverHas) {
28988
+ retained.set(id2, serverValue);
28989
+ continue;
28990
+ }
28991
+ const merged = mergeValue({
28992
+ rawBase: baseValue,
28993
+ rawServer: serverValue,
28994
+ rawLocal: localValue,
28995
+ base: baseValue,
28996
+ server: serverValue,
28997
+ local: localValue,
28998
+ path: `${path}[${JSON.stringify(id2)}]`,
28999
+ recursive: true
29000
+ });
29001
+ conflicts.push(...merged.conflicts);
29002
+ if (merged.present) retained.set(id2, merged.value);
29003
+ }
29004
+ if (conflicts.length > 0) return { present: true, value: [], conflicts };
29005
+ const order = mergeIdentityOrder(
29006
+ baseItems.order,
29007
+ serverItems.order,
29008
+ localItems.order,
29009
+ new Set(retained.keys())
29010
+ );
29011
+ if (order === null) return conflict(`${path}.$order`);
29012
+ return {
29013
+ present: true,
29014
+ value: order.map((id2) => retained.get(id2)),
29015
+ conflicts: []
29016
+ };
29017
+ }
29018
+ function indexIdentityArray(values) {
29019
+ const result = /* @__PURE__ */ new Map();
29020
+ const order = [];
29021
+ for (const value of values) {
29022
+ const id2 = identityOf(value);
29023
+ if (id2 === null || result.has(id2)) return null;
29024
+ result.set(id2, value);
29025
+ order.push(id2);
29026
+ }
29027
+ return { order, values: result };
29028
+ }
29029
+ function identityOf(value) {
29030
+ if (typeof value === "string") return value;
29031
+ if (isObjectRecord2(value) && typeof value.id === "string") return value.id;
29032
+ return null;
29033
+ }
29034
+ function mergeIdentityOrder(base, server, local, retained) {
29035
+ const nodes = [...retained];
29036
+ const outgoing = new Map(nodes.map((id2) => [id2, /* @__PURE__ */ new Set()]));
29037
+ const incoming = new Map(nodes.map((id2) => [id2, 0]));
29038
+ for (const order of [server, local]) {
29039
+ const filtered = order.filter((id2) => retained.has(id2));
29040
+ for (let index = 1; index < filtered.length; index += 1) {
29041
+ const before = filtered[index - 1];
29042
+ const after = filtered[index];
29043
+ const edges = outgoing.get(before);
29044
+ if (edges.has(after)) continue;
29045
+ edges.add(after);
29046
+ incoming.set(after, incoming.get(after) + 1);
29047
+ }
29048
+ }
29049
+ const rank = /* @__PURE__ */ new Map();
29050
+ for (const order of [base, server, local]) {
29051
+ for (const id2 of order) {
29052
+ if (!rank.has(id2)) rank.set(id2, rank.size);
29053
+ }
29054
+ }
29055
+ const ready = nodes.filter((id2) => incoming.get(id2) === 0).sort((left, right) => rank.get(left) - rank.get(right));
29056
+ const result = [];
29057
+ while (ready.length > 0) {
29058
+ const id2 = ready.shift();
29059
+ result.push(id2);
29060
+ for (const after of outgoing.get(id2)) {
29061
+ const count = incoming.get(after) - 1;
29062
+ incoming.set(after, count);
29063
+ if (count === 0) {
29064
+ ready.push(after);
29065
+ ready.sort((left, right) => rank.get(left) - rank.get(right));
29066
+ }
29067
+ }
29068
+ }
29069
+ return result.length === nodes.length ? result : null;
29070
+ }
29071
+ function selected(value) {
29072
+ return value === void 0 ? { present: false, conflicts: [] } : { present: true, value, conflicts: [] };
29073
+ }
29074
+ function conflict(path) {
29075
+ return { present: false, conflicts: [path] };
29076
+ }
29077
+ var init_merge = __esm({
29078
+ "src/project-sync/merge.ts"() {
29079
+ "use strict";
29080
+ init_projection();
29081
+ }
29082
+ });
29083
+
29084
+ // src/project-manifest/merge.ts
29085
+ function isSchemaDocumentRecordKind(recordKind) {
29086
+ return Object.hasOwn(SCHEMA_DOCUMENT_FIELD_CONTRACTS, recordKind);
29087
+ }
29088
+ function schemaDocumentSemanticallyEqual(recordKind, left, right) {
29089
+ return canonicallyEqual(
29090
+ normalizeDocumentForComparison(recordKind, left, "left"),
29091
+ normalizeDocumentForComparison(recordKind, right, "right")
29092
+ );
29093
+ }
29094
+ function schemaDocumentAuthoredSemanticallyEqual(recordKind, left, right) {
29095
+ const normalizedLeft = normalizeDocumentForComparison(
29096
+ recordKind,
29097
+ left,
29098
+ "left"
29099
+ );
29100
+ const normalizedRight = normalizeDocumentForComparison(
29101
+ recordKind,
29102
+ right,
29103
+ "right"
29104
+ );
29105
+ return canonicallyEqual(
29106
+ partitionDocumentFields(recordKind, normalizedLeft).authored,
29107
+ partitionDocumentFields(recordKind, normalizedRight).authored
29108
+ );
29109
+ }
29110
+ function mergeSchemaDocumentRecord(recordKind, base, server, local) {
29111
+ const baseRecord = requireDocumentRecord(base, recordKind, "base");
29112
+ const serverRecord = requireDocumentRecord(server, recordKind, "server");
29113
+ const localRecord = requireDocumentRecord(local, recordKind, "local");
29114
+ const contract = SCHEMA_DOCUMENT_FIELD_CONTRACTS[recordKind];
29115
+ return threeWayMergeRecord(baseRecord, serverRecord, localRecord, {
29116
+ comparison: {
29117
+ base: normalizeDocumentForComparison(recordKind, baseRecord, "base"),
29118
+ server: normalizeDocumentForComparison(
29119
+ recordKind,
29120
+ serverRecord,
29121
+ "server"
29122
+ ),
29123
+ local: normalizeDocumentForComparison(recordKind, localRecord, "local")
29124
+ },
29125
+ serverWinsFields: /* @__PURE__ */ new Set([...contract.derived, ...contract.volatile]),
29126
+ recursive: true
29127
+ });
29128
+ }
29129
+ function normalizeDocumentForComparison(recordKind, value, side) {
29130
+ const normalized = normalizeDocumentFields(
29131
+ recordKind,
29132
+ requireDocumentRecord(value, recordKind, side)
29133
+ );
29134
+ if (recordKind === "class") {
29135
+ materializeDeclarationOrder(normalized, "schema", "schemaKeyOrder");
29136
+ } else if (recordKind === "interface") {
29137
+ materializeDeclarationOrder(normalized, "members", "memberKeyOrder");
29138
+ } else if (recordKind === "enum") {
29139
+ materializeDeclarationOrder(normalized, "options", "optionKeyOrder");
29140
+ }
29141
+ return normalized;
29142
+ }
29143
+ function materializeDeclarationOrder(value, recordField, orderField) {
29144
+ const record3 = value[recordField];
29145
+ if (!isObjectRecord2(record3)) return;
29146
+ const explicit = Array.isArray(value[orderField]) ? value[orderField].filter(
29147
+ (entry) => typeof entry === "string" && Object.hasOwn(record3, entry)
29148
+ ) : [];
29149
+ const seen = new Set(explicit);
29150
+ value[orderField] = [
29151
+ ...explicit,
29152
+ ...Object.keys(record3).filter((key) => !seen.has(key))
29153
+ ];
29154
+ }
29155
+ function requireDocumentRecord(value, recordKind, side) {
29156
+ if (isObjectRecord2(value)) return value;
29157
+ throw new Error(
29158
+ `Schema ${recordKind} ${side} document must be an object for semantic merge.`
29159
+ );
29160
+ }
29161
+ var init_merge2 = __esm({
29162
+ "src/project-manifest/merge.ts"() {
29163
+ "use strict";
29164
+ init_merge();
29165
+ init_projection();
29166
+ init_contracts();
29167
+ }
29168
+ });
29169
+
28860
29170
  // src/project-manifest/adapters.ts
28861
29171
  function createSyntheticDocumentSource(recordKind, recordId, symbolKind) {
28862
29172
  const encodedKind = encodeURIComponent(recordKind);
@@ -28897,7 +29207,13 @@ function composeDocumentRecord(recordKind, recordId, authoredFields, baseRecord)
28897
29207
  }
28898
29208
  assertKnownDocumentFields(recordKind, baseRecord.data);
28899
29209
  const base = partitionDocumentFields(recordKind, baseRecord.data);
28900
- Object.assign(data, base.derived, base.volatile);
29210
+ const invalidatesDerivedConstructor = recordKind === "constructor" && !schemaDocumentAuthoredSemanticallyEqual(
29211
+ recordKind,
29212
+ baseRecord.data,
29213
+ normalizedAuthored
29214
+ );
29215
+ if (!invalidatesDerivedConstructor) Object.assign(data, base.derived);
29216
+ Object.assign(data, base.volatile);
28901
29217
  }
28902
29218
  if (recordKind === "member" && data.isReadOnly === false && !Object.prototype.hasOwnProperty.call(baseRecord?.data ?? {}, "isReadOnly")) {
28903
29219
  delete data.isReadOnly;
@@ -28921,6 +29237,7 @@ var init_adapters = __esm({
28921
29237
  "src/project-manifest/adapters.ts"() {
28922
29238
  "use strict";
28923
29239
  init_contracts();
29240
+ init_merge2();
28924
29241
  DEFAULT_DOCUMENT_TO_MANIFEST_CONTEXT = {
28925
29242
  sourceForRecord: createSyntheticDocumentSource
28926
29243
  };
@@ -33797,316 +34114,6 @@ var init_document_adapters = __esm({
33797
34114
  }
33798
34115
  });
33799
34116
 
33800
- // src/project-sync/merge.ts
33801
- function threeWayMergeRecord(base, server, local, policy = {}) {
33802
- const baseRecord = isObjectRecord2(base) ? base : {};
33803
- const serverRecord = isObjectRecord2(server) ? server : {};
33804
- const localRecord = isObjectRecord2(local) ? local : {};
33805
- const comparisonBase = policy.comparison?.base ?? baseRecord;
33806
- const comparisonServer = policy.comparison?.server ?? serverRecord;
33807
- const comparisonLocal = policy.comparison?.local ?? localRecord;
33808
- const merged = {};
33809
- const conflictFields = [];
33810
- const keys = /* @__PURE__ */ new Set([
33811
- ...Object.keys(serverRecord),
33812
- ...Object.keys(localRecord),
33813
- ...Object.keys(baseRecord)
33814
- ]);
33815
- for (const key of keys) {
33816
- const rawServerValue = serverRecord[key];
33817
- const rawLocalValue = localRecord[key];
33818
- if (policy.serverWinsFields?.has(key) === true) {
33819
- if (rawServerValue !== void 0) merged[key] = rawServerValue;
33820
- continue;
33821
- }
33822
- const baseValue = comparisonBase[key];
33823
- const serverValue = comparisonServer[key];
33824
- const localValue = comparisonLocal[key];
33825
- const result = mergeValue({
33826
- rawBase: baseRecord[key],
33827
- rawServer: rawServerValue,
33828
- rawLocal: rawLocalValue,
33829
- base: baseValue,
33830
- server: serverValue,
33831
- local: localValue,
33832
- path: key,
33833
- recursive: policy.recursive === true
33834
- });
33835
- if (result.conflicts.length > 0) {
33836
- conflictFields.push(...result.conflicts);
33837
- } else if (result.present) {
33838
- merged[key] = result.value;
33839
- }
33840
- }
33841
- return { merged, conflictFields };
33842
- }
33843
- function mergeValue(args) {
33844
- if (canonicallyEqual(args.server, args.base)) {
33845
- return selected(args.rawLocal);
33846
- }
33847
- if (canonicallyEqual(args.local, args.base)) {
33848
- return selected(args.rawServer);
33849
- }
33850
- if (canonicallyEqual(args.local, args.server)) {
33851
- return selected(args.rawLocal);
33852
- }
33853
- if (!args.recursive) return conflict(args.path);
33854
- if (isObjectRecord2(args.rawBase) && isObjectRecord2(args.rawServer) && isObjectRecord2(args.rawLocal)) {
33855
- const comparisonBase = isObjectRecord2(args.base) ? args.base : args.rawBase;
33856
- const comparisonServer = isObjectRecord2(args.server) ? args.server : args.rawServer;
33857
- const comparisonLocal = isObjectRecord2(args.local) ? args.local : args.rawLocal;
33858
- const value = {};
33859
- const conflicts = [];
33860
- const keys = /* @__PURE__ */ new Set([
33861
- ...Object.keys(args.rawBase),
33862
- ...Object.keys(args.rawServer),
33863
- ...Object.keys(args.rawLocal)
33864
- ]);
33865
- for (const key of keys) {
33866
- const nested = mergeValue({
33867
- rawBase: args.rawBase[key],
33868
- rawServer: args.rawServer[key],
33869
- rawLocal: args.rawLocal[key],
33870
- base: comparisonBase[key],
33871
- server: comparisonServer[key],
33872
- local: comparisonLocal[key],
33873
- path: `${args.path}.${key}`,
33874
- recursive: true
33875
- });
33876
- conflicts.push(...nested.conflicts);
33877
- if (nested.present) value[key] = nested.value;
33878
- }
33879
- return { present: true, value, conflicts };
33880
- }
33881
- if (Array.isArray(args.rawBase) && Array.isArray(args.rawServer) && Array.isArray(args.rawLocal)) {
33882
- return mergeIdentityArray(
33883
- args.rawBase,
33884
- args.rawServer,
33885
- args.rawLocal,
33886
- args.path
33887
- );
33888
- }
33889
- return conflict(args.path);
33890
- }
33891
- function mergeIdentityArray(base, server, local, path) {
33892
- const baseItems = indexIdentityArray(base);
33893
- const serverItems = indexIdentityArray(server);
33894
- const localItems = indexIdentityArray(local);
33895
- if (baseItems === null || serverItems === null || localItems === null) {
33896
- return conflict(path);
33897
- }
33898
- const retained = /* @__PURE__ */ new Map();
33899
- const conflicts = [];
33900
- const ids = /* @__PURE__ */ new Set([
33901
- ...baseItems.order,
33902
- ...serverItems.order,
33903
- ...localItems.order
33904
- ]);
33905
- for (const id2 of ids) {
33906
- const baseHas = baseItems.values.has(id2);
33907
- const serverHas = serverItems.values.has(id2);
33908
- const localHas = localItems.values.has(id2);
33909
- const baseValue = baseItems.values.get(id2);
33910
- const serverValue = serverItems.values.get(id2);
33911
- const localValue = localItems.values.get(id2);
33912
- if (baseHas && !serverHas && !localHas) continue;
33913
- if (baseHas && !serverHas) {
33914
- if (canonicallyEqual(localValue, baseValue)) continue;
33915
- conflicts.push(`${path}[${JSON.stringify(id2)}]`);
33916
- continue;
33917
- }
33918
- if (baseHas && !localHas) {
33919
- if (canonicallyEqual(serverValue, baseValue)) continue;
33920
- conflicts.push(`${path}[${JSON.stringify(id2)}]`);
33921
- continue;
33922
- }
33923
- if (!serverHas && localHas) {
33924
- retained.set(id2, localValue);
33925
- continue;
33926
- }
33927
- if (!localHas && serverHas) {
33928
- retained.set(id2, serverValue);
33929
- continue;
33930
- }
33931
- const merged = mergeValue({
33932
- rawBase: baseValue,
33933
- rawServer: serverValue,
33934
- rawLocal: localValue,
33935
- base: baseValue,
33936
- server: serverValue,
33937
- local: localValue,
33938
- path: `${path}[${JSON.stringify(id2)}]`,
33939
- recursive: true
33940
- });
33941
- conflicts.push(...merged.conflicts);
33942
- if (merged.present) retained.set(id2, merged.value);
33943
- }
33944
- if (conflicts.length > 0) return { present: true, value: [], conflicts };
33945
- const order = mergeIdentityOrder(
33946
- baseItems.order,
33947
- serverItems.order,
33948
- localItems.order,
33949
- new Set(retained.keys())
33950
- );
33951
- if (order === null) return conflict(`${path}.$order`);
33952
- return {
33953
- present: true,
33954
- value: order.map((id2) => retained.get(id2)),
33955
- conflicts: []
33956
- };
33957
- }
33958
- function indexIdentityArray(values) {
33959
- const result = /* @__PURE__ */ new Map();
33960
- const order = [];
33961
- for (const value of values) {
33962
- const id2 = identityOf(value);
33963
- if (id2 === null || result.has(id2)) return null;
33964
- result.set(id2, value);
33965
- order.push(id2);
33966
- }
33967
- return { order, values: result };
33968
- }
33969
- function identityOf(value) {
33970
- if (typeof value === "string") return value;
33971
- if (isObjectRecord2(value) && typeof value.id === "string") return value.id;
33972
- return null;
33973
- }
33974
- function mergeIdentityOrder(base, server, local, retained) {
33975
- const nodes = [...retained];
33976
- const outgoing = new Map(nodes.map((id2) => [id2, /* @__PURE__ */ new Set()]));
33977
- const incoming = new Map(nodes.map((id2) => [id2, 0]));
33978
- for (const order of [server, local]) {
33979
- const filtered = order.filter((id2) => retained.has(id2));
33980
- for (let index = 1; index < filtered.length; index += 1) {
33981
- const before = filtered[index - 1];
33982
- const after = filtered[index];
33983
- const edges = outgoing.get(before);
33984
- if (edges.has(after)) continue;
33985
- edges.add(after);
33986
- incoming.set(after, incoming.get(after) + 1);
33987
- }
33988
- }
33989
- const rank = /* @__PURE__ */ new Map();
33990
- for (const order of [base, server, local]) {
33991
- for (const id2 of order) {
33992
- if (!rank.has(id2)) rank.set(id2, rank.size);
33993
- }
33994
- }
33995
- const ready = nodes.filter((id2) => incoming.get(id2) === 0).sort((left, right) => rank.get(left) - rank.get(right));
33996
- const result = [];
33997
- while (ready.length > 0) {
33998
- const id2 = ready.shift();
33999
- result.push(id2);
34000
- for (const after of outgoing.get(id2)) {
34001
- const count = incoming.get(after) - 1;
34002
- incoming.set(after, count);
34003
- if (count === 0) {
34004
- ready.push(after);
34005
- ready.sort((left, right) => rank.get(left) - rank.get(right));
34006
- }
34007
- }
34008
- }
34009
- return result.length === nodes.length ? result : null;
34010
- }
34011
- function selected(value) {
34012
- return value === void 0 ? { present: false, conflicts: [] } : { present: true, value, conflicts: [] };
34013
- }
34014
- function conflict(path) {
34015
- return { present: false, conflicts: [path] };
34016
- }
34017
- var init_merge = __esm({
34018
- "src/project-sync/merge.ts"() {
34019
- "use strict";
34020
- init_projection();
34021
- }
34022
- });
34023
-
34024
- // src/project-manifest/merge.ts
34025
- function isSchemaDocumentRecordKind(recordKind) {
34026
- return Object.hasOwn(SCHEMA_DOCUMENT_FIELD_CONTRACTS, recordKind);
34027
- }
34028
- function schemaDocumentSemanticallyEqual(recordKind, left, right) {
34029
- return canonicallyEqual(
34030
- normalizeDocumentForComparison(recordKind, left, "left"),
34031
- normalizeDocumentForComparison(recordKind, right, "right")
34032
- );
34033
- }
34034
- function schemaDocumentAuthoredSemanticallyEqual(recordKind, left, right) {
34035
- const normalizedLeft = normalizeDocumentForComparison(
34036
- recordKind,
34037
- left,
34038
- "left"
34039
- );
34040
- const normalizedRight = normalizeDocumentForComparison(
34041
- recordKind,
34042
- right,
34043
- "right"
34044
- );
34045
- return canonicallyEqual(
34046
- partitionDocumentFields(recordKind, normalizedLeft).authored,
34047
- partitionDocumentFields(recordKind, normalizedRight).authored
34048
- );
34049
- }
34050
- function mergeSchemaDocumentRecord(recordKind, base, server, local) {
34051
- const baseRecord = requireDocumentRecord(base, recordKind, "base");
34052
- const serverRecord = requireDocumentRecord(server, recordKind, "server");
34053
- const localRecord = requireDocumentRecord(local, recordKind, "local");
34054
- const contract = SCHEMA_DOCUMENT_FIELD_CONTRACTS[recordKind];
34055
- return threeWayMergeRecord(baseRecord, serverRecord, localRecord, {
34056
- comparison: {
34057
- base: normalizeDocumentForComparison(recordKind, baseRecord, "base"),
34058
- server: normalizeDocumentForComparison(
34059
- recordKind,
34060
- serverRecord,
34061
- "server"
34062
- ),
34063
- local: normalizeDocumentForComparison(recordKind, localRecord, "local")
34064
- },
34065
- serverWinsFields: /* @__PURE__ */ new Set([...contract.derived, ...contract.volatile]),
34066
- recursive: true
34067
- });
34068
- }
34069
- function normalizeDocumentForComparison(recordKind, value, side) {
34070
- const normalized = normalizeDocumentFields(
34071
- recordKind,
34072
- requireDocumentRecord(value, recordKind, side)
34073
- );
34074
- if (recordKind === "class") {
34075
- materializeDeclarationOrder(normalized, "schema", "schemaKeyOrder");
34076
- } else if (recordKind === "interface") {
34077
- materializeDeclarationOrder(normalized, "members", "memberKeyOrder");
34078
- } else if (recordKind === "enum") {
34079
- materializeDeclarationOrder(normalized, "options", "optionKeyOrder");
34080
- }
34081
- return normalized;
34082
- }
34083
- function materializeDeclarationOrder(value, recordField, orderField) {
34084
- const record3 = value[recordField];
34085
- if (!isObjectRecord2(record3)) return;
34086
- const explicit = Array.isArray(value[orderField]) ? value[orderField].filter(
34087
- (entry) => typeof entry === "string" && Object.hasOwn(record3, entry)
34088
- ) : [];
34089
- const seen = new Set(explicit);
34090
- value[orderField] = [
34091
- ...explicit,
34092
- ...Object.keys(record3).filter((key) => !seen.has(key))
34093
- ];
34094
- }
34095
- function requireDocumentRecord(value, recordKind, side) {
34096
- if (isObjectRecord2(value)) return value;
34097
- throw new Error(
34098
- `Schema ${recordKind} ${side} document must be an object for semantic merge.`
34099
- );
34100
- }
34101
- var init_merge2 = __esm({
34102
- "src/project-manifest/merge.ts"() {
34103
- "use strict";
34104
- init_merge();
34105
- init_projection();
34106
- init_contracts();
34107
- }
34108
- });
34109
-
34110
34117
  // src/project-manifest/index.ts
34111
34118
  var init_project_manifest = __esm({
34112
34119
  "src/project-manifest/index.ts"() {
@@ -55296,6 +55303,16 @@ function liveListIndexRegistry(ctx) {
55296
55303
  liveListIndexesByProject.set(projectKey, created);
55297
55304
  return created;
55298
55305
  }
55306
+ function evaluatorOwnershipCachesForBase(base) {
55307
+ const existing = evaluatorOwnershipCachesByBase.get(base);
55308
+ if (existing !== void 0) return existing;
55309
+ const created = {
55310
+ ownershipRootIdsByRowId: /* @__PURE__ */ new Map(),
55311
+ ownershipDistancesByRowId: /* @__PURE__ */ new Map()
55312
+ };
55313
+ evaluatorOwnershipCachesByBase.set(base, created);
55314
+ return created;
55315
+ }
55299
55316
  function buildEvaluatorBaseIndexes(members, values, valueById = new Map(
55300
55317
  values.map((row) => [row.id, row])
55301
55318
  )) {
@@ -55311,6 +55328,7 @@ function buildEvaluatorBaseIndexes(members, values, valueById = new Map(
55311
55328
  declaredListByArray: /* @__PURE__ */ new WeakMap(),
55312
55329
  rowsBySourceValueId: /* @__PURE__ */ new Map(),
55313
55330
  ownershipRootIdsByRowId: /* @__PURE__ */ new Map(),
55331
+ ownershipDistancesByRowId: /* @__PURE__ */ new Map(),
55314
55332
  ownedValueAttachmentsByValueId: /* @__PURE__ */ new Map(),
55315
55333
  memberByRowId: /* @__PURE__ */ new Map()
55316
55334
  };
@@ -55343,6 +55361,8 @@ function evaluatorIndexes(ctx) {
55343
55361
  }
55344
55362
  const liveListIndexes = liveListIndexRegistry(ctx);
55345
55363
  const base = ctx.vm.databaseVM?.evaluatorIndexes;
55364
+ const hasLocalRows = ctx.__runtimeSessionValues !== void 0 || ctx.__valueOverlay !== void 0;
55365
+ const sharedOwnershipCaches = base !== void 0 && !hasLocalRows ? evaluatorOwnershipCachesForBase(base) : null;
55346
55366
  const indexes = {
55347
55367
  rowByValueReference: /* @__PURE__ */ new WeakMap(),
55348
55368
  baseRowByValueReference: base?.rowByValueReference,
@@ -55359,7 +55379,11 @@ function evaluatorIndexes(ctx) {
55359
55379
  declaredListByArray: liveListIndexes?.declared ?? /* @__PURE__ */ new WeakMap(),
55360
55380
  rowsBySourceValueId: /* @__PURE__ */ new Map(),
55361
55381
  baseRowsBySourceValueId: base?.rowsBySourceValueId,
55362
- ownershipRootIdsByRowId: /* @__PURE__ */ new Map(),
55382
+ // A base index describes one immutable evaluator document. Getter calls
55383
+ // over that document can safely share the expensive ownership walks. A
55384
+ // runtime/overlay context gets private caches because it shadows edges.
55385
+ ownershipRootIdsByRowId: sharedOwnershipCaches?.ownershipRootIdsByRowId ?? /* @__PURE__ */ new Map(),
55386
+ ownershipDistancesByRowId: sharedOwnershipCaches?.ownershipDistancesByRowId ?? /* @__PURE__ */ new Map(),
55363
55387
  ownedValueAttachmentsByValueId: /* @__PURE__ */ new Map(),
55364
55388
  memberByRowId: /* @__PURE__ */ new Map()
55365
55389
  };
@@ -55413,6 +55437,7 @@ function indexEvaluatorRow(indexes, row, allowBaseShadow = false) {
55413
55437
  }
55414
55438
  }
55415
55439
  indexes.ownershipRootIdsByRowId.clear();
55440
+ indexes.ownershipDistancesByRowId.clear();
55416
55441
  indexes.memberByRowId.clear();
55417
55442
  if (indexes.indexedRowIds.has(row.id) || !allowBaseShadow && indexes.baseIndexedRowIds?.has(row.id) === true) {
55418
55443
  return;
@@ -55484,6 +55509,29 @@ function evaluatorOwnershipRootIds(rowId, indexes) {
55484
55509
  indexes.ownershipRootIdsByRowId.set(rowId, roots);
55485
55510
  return roots;
55486
55511
  }
55512
+ function evaluatorOwnershipDistances(rowId, indexes) {
55513
+ const cached = indexes.ownershipDistancesByRowId.get(rowId);
55514
+ if (cached !== void 0) return cached;
55515
+ const distances = /* @__PURE__ */ new Map([[rowId, 0]]);
55516
+ const pending = [rowId];
55517
+ while (pending.length > 0) {
55518
+ const currentId = pending.shift();
55519
+ if (currentId === void 0) break;
55520
+ const currentDistance = distances.get(currentId);
55521
+ if (currentDistance === void 0) continue;
55522
+ for (const parent of evaluatorParentLinks(indexes, currentId)) {
55523
+ const nextDistance = currentDistance + 1;
55524
+ const previousDistance = distances.get(parent.parentId);
55525
+ if (previousDistance !== void 0 && previousDistance <= nextDistance) {
55526
+ continue;
55527
+ }
55528
+ distances.set(parent.parentId, nextDistance);
55529
+ pending.push(parent.parentId);
55530
+ }
55531
+ }
55532
+ indexes.ownershipDistancesByRowId.set(rowId, distances);
55533
+ return distances;
55534
+ }
55487
55535
  function resolveRuntimeReferenceRow(sourceValueId, ctx) {
55488
55536
  const direct = evalValueById(
55489
55537
  ctx.vm,
@@ -55506,6 +55554,28 @@ function resolveRuntimeReferenceRow(sourceValueId, ctx) {
55506
55554
  );
55507
55555
  if (matches.length === 0) return direct;
55508
55556
  if (matches.length === 1) return matches[0] ?? direct;
55557
+ const receiverDistances = evaluatorOwnershipDistances(receiver.id, indexes);
55558
+ let nearestDistance = Number.POSITIVE_INFINITY;
55559
+ let nearestMatches = [];
55560
+ for (const candidate of matches) {
55561
+ const candidateDistances = evaluatorOwnershipDistances(
55562
+ candidate.id,
55563
+ indexes
55564
+ );
55565
+ let distance = Number.POSITIVE_INFINITY;
55566
+ for (const [ownerId, receiverDistance] of receiverDistances) {
55567
+ const candidateDistance = candidateDistances.get(ownerId);
55568
+ if (candidateDistance === void 0) continue;
55569
+ distance = Math.min(distance, receiverDistance + candidateDistance);
55570
+ }
55571
+ if (distance < nearestDistance) {
55572
+ nearestDistance = distance;
55573
+ nearestMatches = [candidate];
55574
+ } else if (distance === nearestDistance) {
55575
+ nearestMatches.push(candidate);
55576
+ }
55577
+ }
55578
+ if (nearestMatches.length === 1) return nearestMatches[0] ?? direct;
55509
55579
  throw new NSGetterRuntimeError(
55510
55580
  `Value reference '${sourceValueId}' is ambiguous within the constructed object graph.`
55511
55581
  );
@@ -61636,7 +61706,7 @@ function pushParams(parent, parameters, positional, isList) {
61636
61706
  }
61637
61707
  return child;
61638
61708
  }
61639
- var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, NonCatchableNSGetterRuntimeError, NativeFunctionDelegateUnavailableError, CorruptNeoScriptIRError, NeoScriptResourceLimitError, DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS, liveListIndexesByProject, MAX_CONSTRUCTION_DEPTH, MAX_LOOP_ITERATIONS, LazyValueOverlay, readonlyBindingErrorsByScope, READONLY_FOREACH_BINDING_ERROR, READONLY_CATCH_BINDING_ERROR;
61709
+ var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, NonCatchableNSGetterRuntimeError, NativeFunctionDelegateUnavailableError, CorruptNeoScriptIRError, NeoScriptResourceLimitError, DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS, liveListIndexesByProject, evaluatorOwnershipCachesByBase, MAX_CONSTRUCTION_DEPTH, MAX_LOOP_ITERATIONS, LazyValueOverlay, readonlyBindingErrorsByScope, READONLY_FOREACH_BINDING_ERROR, READONLY_CATCH_BINDING_ERROR;
61640
61710
  var init_evaluateNSGetter = __esm({
61641
61711
  "../src/view-models/neoscript-evaluator/evaluateNSGetter.ts"() {
61642
61712
  "use strict";
@@ -61675,6 +61745,7 @@ var init_evaluateNSGetter = __esm({
61675
61745
  producedStringCharacters: 1024 * 1024
61676
61746
  });
61677
61747
  liveListIndexesByProject = /* @__PURE__ */ new WeakMap();
61748
+ evaluatorOwnershipCachesByBase = /* @__PURE__ */ new WeakMap();
61678
61749
  MAX_CONSTRUCTION_DEPTH = 64;
61679
61750
  MAX_LOOP_ITERATIONS = 1e4;
61680
61751
  LazyValueOverlay = class extends Map {
@@ -72405,6 +72476,145 @@ var init_trusted_commit_verification = __esm({
72405
72476
  });
72406
72477
 
72407
72478
  // ../src/models/classes/world-layer-link-target.ts
72479
+ function validateWorldLayerLinkClassTargets(args) {
72480
+ for (const schemaClass2 of args.classes) {
72481
+ if (args.classIds !== void 0 && !args.classIds.has(schemaClass2.id)) {
72482
+ continue;
72483
+ }
72484
+ const directWorldKind = schemaClass2.system?.worldKind;
72485
+ const isSystemLinkBase = directWorldKind === NeoWorldSystemClassKind.TileLayerLink || directWorldKind === NeoWorldSystemClassKind.ObjectLayerLink;
72486
+ const descriptor = worldLayerLinkTargetDescriptorForClass(
72487
+ schemaClass2.id,
72488
+ args.classes
72489
+ );
72490
+ if (descriptor === null) continue;
72491
+ if (isSystemLinkBase) {
72492
+ if (!schemaClass2.isAbstract) {
72493
+ throw new Error(
72494
+ `System layer-link base class "${schemaClass2.id}" must remain abstract.`
72495
+ );
72496
+ }
72497
+ if (worldLayerLinkTargetRelations(
72498
+ schemaClass2.id,
72499
+ descriptor,
72500
+ args.relations
72501
+ ).length > 0) {
72502
+ throw new Error(
72503
+ `System layer-link base class "${schemaClass2.id}" cannot declare a layer target relation.`
72504
+ );
72505
+ }
72506
+ continue;
72507
+ }
72508
+ if (schemaClass2.isAbstract) continue;
72509
+ resolveWorldLayerLinkTarget({
72510
+ classes: args.classes,
72511
+ linkLabel: `Concrete layer-link class "${schemaClass2.id}"`,
72512
+ relations: args.relations,
72513
+ sourceClassId: schemaClass2.id
72514
+ });
72515
+ }
72516
+ }
72517
+ function worldLayerLinkTargetDescriptorForClass(classId, classes) {
72518
+ const worldKind = resolveWorldSystemClassKind(classId, classes);
72519
+ if (worldKind === NeoWorldSystemClassKind.TileLayerLink) {
72520
+ return {
72521
+ relationKind: InternalRecordRelationKind.WorldTileLayerLinkTarget,
72522
+ targetWorldKind: NeoWorldSystemClassKind.TileLayer
72523
+ };
72524
+ }
72525
+ if (worldKind === NeoWorldSystemClassKind.ObjectLayerLink) {
72526
+ return {
72527
+ relationKind: InternalRecordRelationKind.WorldObjectLayerLinkTarget,
72528
+ targetWorldKind: NeoWorldSystemClassKind.ObjectLayer
72529
+ };
72530
+ }
72531
+ return null;
72532
+ }
72533
+ function worldLayerLinkTargetRelations(classId, descriptor, relations) {
72534
+ return relations.filter(
72535
+ (relation) => relation.relationKind === descriptor.relationKind && relation.sourceRecordKind === ProjectRecordKind.Class && relation.sourceRecordId === classId && relation.targetRecordKind === ProjectRecordKind.Class
72536
+ );
72537
+ }
72538
+ function resolveWorldLayerLinkTarget(args) {
72539
+ const label = args.linkLabel ?? `Layer-link class "${args.sourceClassId}"`;
72540
+ const sourceClass = args.classes.find(
72541
+ (candidate) => candidate.id === args.sourceClassId
72542
+ );
72543
+ if (sourceClass === void 0) {
72544
+ throw new Error(
72545
+ `${label} references missing class "${args.sourceClassId}".`
72546
+ );
72547
+ }
72548
+ if (sourceClass.isAbstract) {
72549
+ throw new Error(
72550
+ `${label} cannot instantiate abstract class "${args.sourceClassId}".`
72551
+ );
72552
+ }
72553
+ const descriptor = worldLayerLinkTargetDescriptorForClass(
72554
+ args.sourceClassId,
72555
+ args.classes
72556
+ );
72557
+ if (descriptor === null) {
72558
+ throw new Error(
72559
+ `${label} class "${args.sourceClassId}" is not a tile/object layer-link class.`
72560
+ );
72561
+ }
72562
+ const effective = resolveEffectiveClassRelations({
72563
+ relationKind: descriptor.relationKind,
72564
+ sourceClassId: args.sourceClassId,
72565
+ relations: args.relations,
72566
+ classes: args.classes
72567
+ });
72568
+ if (effective.length > 1) {
72569
+ throw new Error(
72570
+ `${label} class "${args.sourceClassId}" resolves more than one effective target for relation kind "${descriptor.relationKind}".`
72571
+ );
72572
+ }
72573
+ const relationTarget = effective[0] ?? null;
72574
+ if (relationTarget !== null) {
72575
+ const declarationClass = args.classes.find(
72576
+ (candidate) => candidate.id === relationTarget.declaredSourceRecordId
72577
+ );
72578
+ if (declarationClass?.system?.worldKind === NeoWorldSystemClassKind.TileLayerLink || declarationClass?.system?.worldKind === NeoWorldSystemClassKind.ObjectLayerLink) {
72579
+ throw new Error(
72580
+ `${label} class "${args.sourceClassId}" cannot inherit a layer target relation from system base class "${declarationClass.id}".`
72581
+ );
72582
+ }
72583
+ }
72584
+ if (relationTarget === null) {
72585
+ throw new Error(
72586
+ `${label} class "${args.sourceClassId}" has no effective layer target relation.`
72587
+ );
72588
+ }
72589
+ const targetClassId = relationTarget.targetRecordId;
72590
+ const targetClass = args.classes.find(
72591
+ (candidate) => candidate.id === targetClassId
72592
+ );
72593
+ if (targetClass === void 0) {
72594
+ throw new Error(`${label} targets missing layer class "${targetClassId}".`);
72595
+ }
72596
+ if (targetClass.isAbstract) {
72597
+ throw new Error(
72598
+ `${label} targets abstract layer class "${targetClassId}".`
72599
+ );
72600
+ }
72601
+ const targetWorldKind = resolveWorldSystemClassKind(
72602
+ targetClass.id,
72603
+ args.classes
72604
+ );
72605
+ if (targetWorldKind !== descriptor.targetWorldKind) {
72606
+ throw new Error(
72607
+ `${label} targets class "${targetClassId}" of world kind "${String(targetWorldKind)}"; expected "${descriptor.targetWorldKind}".`
72608
+ );
72609
+ }
72610
+ return {
72611
+ declaredSourceClassId: relationTarget.declaredSourceRecordId,
72612
+ relationIds: relationTarget.relationIds,
72613
+ relationKind: descriptor.relationKind,
72614
+ sourceClassId: args.sourceClassId,
72615
+ targetClassId
72616
+ };
72617
+ }
72408
72618
  var init_world_layer_link_target = __esm({
72409
72619
  "../src/models/classes/world-layer-link-target.ts"() {
72410
72620
  "use strict";
@@ -72415,6 +72625,292 @@ var init_world_layer_link_target = __esm({
72415
72625
  });
72416
72626
 
72417
72627
  // ../src/models/project/world-content-sidecar-validation.ts
72628
+ function validateWorldContentSidecars(args) {
72629
+ const valuesById = new Map(args.values.map((value) => [value.id, value]));
72630
+ const classesById = new Map(
72631
+ args.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
72632
+ );
72633
+ const containedIds = containedValueIdsByContainer(args.values);
72634
+ const ownedLinkIds = /* @__PURE__ */ new Map();
72635
+ const gridOwnedLinkIds = /* @__PURE__ */ new Set();
72636
+ const validatedPlacementIds = /* @__PURE__ */ new Set();
72637
+ const reachablePlacementIds = /* @__PURE__ */ new Set();
72638
+ for (const gridValue of args.values) {
72639
+ if (worldKindForValue(gridValue, args.classes) !== NeoWorldSystemClassKind.TileGrid) {
72640
+ continue;
72641
+ }
72642
+ const gridClassId = requiredValueClassId(gridValue, "tile-grid");
72643
+ const gridRecord = valueObjectRecord(gridValue);
72644
+ if (gridRecord === null) continue;
72645
+ const childrenList = referencedValue(
72646
+ gridRecord.Children,
72647
+ valuesById,
72648
+ `Grid value "${gridValue.id}" Children`
72649
+ );
72650
+ if (childrenList === null) continue;
72651
+ const registeredTileLayers = effectiveTargetIds({
72652
+ classes: args.classes,
72653
+ relationKind: InternalRecordRelationKind.WorldGridTileLayer,
72654
+ relations: args.relations,
72655
+ sourceClassId: gridClassId
72656
+ });
72657
+ const registeredObjectLayers = effectiveTargetIds({
72658
+ classes: args.classes,
72659
+ relationKind: InternalRecordRelationKind.WorldGridObjectLayer,
72660
+ relations: args.relations,
72661
+ sourceClassId: gridClassId
72662
+ });
72663
+ const importedTiles = effectiveTargetIds({
72664
+ classes: args.classes,
72665
+ relationKind: InternalRecordRelationKind.WorldGridTileImport,
72666
+ relations: args.relations,
72667
+ sourceClassId: gridClassId
72668
+ });
72669
+ const importedObjects = effectiveTargetIds({
72670
+ classes: args.classes,
72671
+ relationKind: InternalRecordRelationKind.WorldGridObjectImport,
72672
+ relations: args.relations,
72673
+ sourceClassId: gridClassId
72674
+ });
72675
+ const overrideOwnerByLayerKey = /* @__PURE__ */ new Map();
72676
+ for (const linkId of containmentEntryIds(childrenList, containedIds)) {
72677
+ const linkValue = valuesById.get(linkId);
72678
+ if (linkValue === void 0) {
72679
+ throw new Error(
72680
+ `Grid value "${gridValue.id}" Children references missing value "${linkId}".`
72681
+ );
72682
+ }
72683
+ const linkKind = worldKindForValue(linkValue, args.classes);
72684
+ if (linkKind !== NeoWorldSystemClassKind.TileLayerLink && linkKind !== NeoWorldSystemClassKind.ObjectLayerLink) {
72685
+ continue;
72686
+ }
72687
+ const linkRecord = valueObjectRecord(linkValue);
72688
+ if (linkRecord === null) continue;
72689
+ gridOwnedLinkIds.add(linkValue.id);
72690
+ const placementListKey = linkKind === NeoWorldSystemClassKind.TileLayerLink ? "Tiles" : "Objects";
72691
+ const placementList = referencedValue(
72692
+ linkRecord[placementListKey],
72693
+ valuesById,
72694
+ `Layer link value "${linkValue.id}" ${placementListKey}`
72695
+ );
72696
+ const placementIds = placementList === null ? [] : containmentEntryIds(placementList, containedIds);
72697
+ for (const placementId of placementIds) {
72698
+ reachablePlacementIds.add(placementId);
72699
+ }
72700
+ const linkClassId = requiredValueClassId(linkValue, "layer-link");
72701
+ const layerClassId = resolveWorldLayerLinkTarget({
72702
+ classes: args.classes,
72703
+ linkLabel: `Layer link value "${linkValue.id}"`,
72704
+ relations: args.relations,
72705
+ sourceClassId: linkClassId
72706
+ }).targetClassId;
72707
+ const existingOwner = ownedLinkIds.get(linkValue.id);
72708
+ if (existingOwner !== void 0 && existingOwner !== gridValue.id) {
72709
+ throw new Error(
72710
+ `Layer link value "${linkValue.id}" is owned by both grid values "${existingOwner}" and "${gridValue.id}".`
72711
+ );
72712
+ }
72713
+ ownedLinkIds.set(linkValue.id, gridValue.id);
72714
+ const isTile = linkKind === NeoWorldSystemClassKind.TileLayerLink;
72715
+ const expectedLayerKind = isTile ? NeoWorldSystemClassKind.TileLayer : NeoWorldSystemClassKind.ObjectLayer;
72716
+ assertConcreteWorldClass({
72717
+ classId: layerClassId,
72718
+ classes: args.classes,
72719
+ classesById,
72720
+ expectedKind: expectedLayerKind,
72721
+ label: `Layer link value "${linkValue.id}" target`
72722
+ });
72723
+ const registeredLayers = isTile ? registeredTileLayers : registeredObjectLayers;
72724
+ if (!registeredLayers.has(layerClassId)) {
72725
+ throw new Error(
72726
+ `Layer link value "${linkValue.id}" binds unregistered ${isTile ? "tile" : "object"} layer class "${layerClassId}" on grid value "${gridValue.id}".`
72727
+ );
72728
+ }
72729
+ const layerOverrideValueId = optionalNonEmptyString(
72730
+ linkRecord.layerOverrideValueId
72731
+ );
72732
+ const layerKey = `${isTile ? "tile" : "object"}:${layerClassId}`;
72733
+ if (layerOverrideValueId !== null) {
72734
+ const existingOverrideOwner = overrideOwnerByLayerKey.get(layerKey);
72735
+ if (existingOverrideOwner !== void 0 && existingOverrideOwner !== linkValue.id) {
72736
+ throw new Error(
72737
+ `Grid value "${gridValue.id}" has more than one override-owning ${isTile ? "tile" : "object"} layer link for class "${layerClassId}" ("${existingOverrideOwner}" and "${linkValue.id}"). Source links may share a layer target, but at most one may define layerOverrideValueId.`
72738
+ );
72739
+ }
72740
+ overrideOwnerByLayerKey.set(layerKey, linkValue.id);
72741
+ }
72742
+ validateOwnedSparseValue({
72743
+ classesById,
72744
+ expectedClassId: layerClassId,
72745
+ ownerId: linkValue.id,
72746
+ referenceId: layerOverrideValueId,
72747
+ referenceLabel: `Layer link value "${linkValue.id}" layerOverrideValueId`,
72748
+ valuesById
72749
+ });
72750
+ for (const placementId of placementIds) {
72751
+ const placement = valuesById.get(placementId);
72752
+ if (placement === void 0) {
72753
+ throw new Error(
72754
+ `Layer link value "${linkValue.id}" ${placementListKey} references missing placement "${placementId}".`
72755
+ );
72756
+ }
72757
+ validateWorldPlacementSidecars({
72758
+ classes: args.classes,
72759
+ classesById,
72760
+ importedClassIds: isTile ? importedTiles : importedObjects,
72761
+ isTile,
72762
+ layerClassId,
72763
+ linkValueId: linkValue.id,
72764
+ placement,
72765
+ relations: args.relations,
72766
+ valuesById
72767
+ });
72768
+ validatedPlacementIds.add(placement.id);
72769
+ }
72770
+ }
72771
+ }
72772
+ for (const linkValue of args.values) {
72773
+ if (gridOwnedLinkIds.has(linkValue.id)) continue;
72774
+ const linkKind = worldKindForValue(linkValue, args.classes);
72775
+ if (linkKind !== NeoWorldSystemClassKind.TileLayerLink && linkKind !== NeoWorldSystemClassKind.ObjectLayerLink) {
72776
+ continue;
72777
+ }
72778
+ const linkRecord = valueObjectRecord(linkValue);
72779
+ if (linkRecord === null) continue;
72780
+ const isTile = linkKind === NeoWorldSystemClassKind.TileLayerLink;
72781
+ const linkClassId = requiredValueClassId(linkValue, "layer-link");
72782
+ const layerClassId = resolveWorldLayerLinkTarget({
72783
+ classes: args.classes,
72784
+ linkLabel: `Object-composition layer link value "${linkValue.id}"`,
72785
+ relations: args.relations,
72786
+ sourceClassId: linkClassId
72787
+ }).targetClassId;
72788
+ assertConcreteWorldClass({
72789
+ classId: layerClassId,
72790
+ classes: args.classes,
72791
+ classesById,
72792
+ expectedKind: isTile ? NeoWorldSystemClassKind.TileLayer : NeoWorldSystemClassKind.ObjectLayer,
72793
+ label: `Object-composition layer link value "${linkValue.id}" target`
72794
+ });
72795
+ validateOwnedSparseValue({
72796
+ classesById,
72797
+ expectedClassId: layerClassId,
72798
+ ownerId: linkValue.id,
72799
+ referenceId: optionalNonEmptyString(linkRecord.layerOverrideValueId),
72800
+ referenceLabel: `Object-composition layer link value "${linkValue.id}" layerOverrideValueId`,
72801
+ valuesById
72802
+ });
72803
+ const placementListKey = isTile ? "Tiles" : "Objects";
72804
+ const placementList = referencedValue(
72805
+ linkRecord[placementListKey],
72806
+ valuesById,
72807
+ `Object-composition layer link value "${linkValue.id}" ${placementListKey}`
72808
+ );
72809
+ if (placementList === null) continue;
72810
+ for (const placementId of containmentEntryIds(
72811
+ placementList,
72812
+ containedIds
72813
+ )) {
72814
+ const placement = valuesById.get(placementId);
72815
+ if (placement === void 0) {
72816
+ throw new Error(
72817
+ `Object-composition layer link value "${linkValue.id}" references missing placement "${placementId}".`
72818
+ );
72819
+ }
72820
+ validateWorldPlacementSidecars({
72821
+ classes: args.classes,
72822
+ classesById,
72823
+ importedClassIds: null,
72824
+ isTile,
72825
+ layerClassId,
72826
+ linkValueId: linkValue.id,
72827
+ placement,
72828
+ relations: args.relations,
72829
+ valuesById
72830
+ });
72831
+ reachablePlacementIds.add(placement.id);
72832
+ validatedPlacementIds.add(placement.id);
72833
+ }
72834
+ }
72835
+ for (const value of args.values) {
72836
+ const record3 = valueObjectRecord(value);
72837
+ if (record3 === null) continue;
72838
+ if (optionalNonEmptyString(record3.assetClassId) !== null && !validatedPlacementIds.has(value.id) && !reachablePlacementIds.has(value.id)) {
72839
+ throw new Error(
72840
+ `Class-backed placement value "${value.id}" is not owned by a class-backed layer link.`
72841
+ );
72842
+ }
72843
+ }
72844
+ }
72845
+ function validateWorldPlacementSidecars(args) {
72846
+ const record3 = valueObjectRecord(args.placement);
72847
+ if (record3 === null) {
72848
+ throw new Error(
72849
+ `Placement value "${args.placement.id}" under layer link "${args.linkValueId}" must store a class record.`
72850
+ );
72851
+ }
72852
+ const assetClassId = optionalNonEmptyString(record3.assetClassId);
72853
+ if (assetClassId === null) {
72854
+ throw new Error(
72855
+ `Class-backed placement value "${args.placement.id}" is missing assetClassId.`
72856
+ );
72857
+ }
72858
+ assertConcreteWorldClass({
72859
+ classId: assetClassId,
72860
+ classes: args.classes,
72861
+ classesById: args.classesById,
72862
+ expectedKind: args.isTile ? NeoWorldSystemClassKind.Tile : NeoWorldSystemClassKind.Object,
72863
+ label: `Placement value "${args.placement.id}" assetClassId`
72864
+ });
72865
+ if (args.importedClassIds !== null && !args.importedClassIds.has(assetClassId)) {
72866
+ throw new Error(
72867
+ `Placement value "${args.placement.id}" uses ${args.isTile ? "tile" : "object"} class "${assetClassId}" that is not imported by its grid.`
72868
+ );
72869
+ }
72870
+ const compatibleLayerIds = effectiveTargetIds({
72871
+ classes: args.classes,
72872
+ relationKind: args.isTile ? InternalRecordRelationKind.WorldTileCompatibleLayer : InternalRecordRelationKind.WorldObjectCompatibleLayer,
72873
+ relations: args.relations,
72874
+ sourceClassId: assetClassId
72875
+ });
72876
+ if (!compatibleLayerIds.has(args.layerClassId)) {
72877
+ throw new Error(
72878
+ `Placement value "${args.placement.id}" asset class "${assetClassId}" is not compatible with layer class "${args.layerClassId}".`
72879
+ );
72880
+ }
72881
+ validateOwnedSparseValue({
72882
+ classesById: args.classesById,
72883
+ expectedClassId: assetClassId,
72884
+ ownerId: args.placement.id,
72885
+ referenceId: optionalNonEmptyString(record3.assetValueId),
72886
+ referenceLabel: `Placement value "${args.placement.id}" assetValueId`,
72887
+ valuesById: args.valuesById
72888
+ });
72889
+ }
72890
+ function validateOwnedSparseValue(args) {
72891
+ if (args.referenceId === null) return;
72892
+ const value = args.valuesById.get(args.referenceId);
72893
+ if (value === void 0) {
72894
+ throw new Error(
72895
+ `${args.referenceLabel} references missing value "${args.referenceId}".`
72896
+ );
72897
+ }
72898
+ if (!args.classesById.has(args.expectedClassId)) {
72899
+ throw new Error(
72900
+ `${args.referenceLabel} expects missing class "${args.expectedClassId}".`
72901
+ );
72902
+ }
72903
+ if (value.classId !== args.expectedClassId) {
72904
+ throw new Error(
72905
+ `${args.referenceLabel} references value "${value.id}" with class "${String(value.classId)}", expected "${args.expectedClassId}".`
72906
+ );
72907
+ }
72908
+ if (value.containerId !== args.ownerId) {
72909
+ throw new Error(
72910
+ `${args.referenceLabel} references value "${value.id}" owned by "${String(value.containerId)}", expected "${args.ownerId}".`
72911
+ );
72912
+ }
72913
+ }
72418
72914
  function assertConcreteWorldClass(args) {
72419
72915
  const schemaClass2 = args.classesById.get(args.classId);
72420
72916
  if (schemaClass2 === void 0) {
@@ -72432,6 +72928,58 @@ function assertConcreteWorldClass(args) {
72432
72928
  throw new Error(`${args.label} must reference a concrete class.`);
72433
72929
  }
72434
72930
  }
72931
+ function effectiveTargetIds(args) {
72932
+ return new Set(
72933
+ resolveEffectiveClassRelations(args).map(
72934
+ (relation) => relation.targetRecordId
72935
+ )
72936
+ );
72937
+ }
72938
+ function worldKindForValue(value, classes) {
72939
+ return typeof value.classId === "string" ? resolveWorldSystemClassKind(value.classId, classes) : null;
72940
+ }
72941
+ function requiredValueClassId(value, label) {
72942
+ if (typeof value.classId === "string" && value.classId.length > 0) {
72943
+ return value.classId;
72944
+ }
72945
+ throw new Error(`${label} value "${value.id}" is missing classId.`);
72946
+ }
72947
+ function valueObjectRecord(value) {
72948
+ if (value.value === null || typeof value.value !== "object") return null;
72949
+ if (Array.isArray(value.value)) return null;
72950
+ return value.value;
72951
+ }
72952
+ function referencedValue(reference2, valuesById, label) {
72953
+ if (reference2 === void 0 || reference2 === null) return null;
72954
+ if (typeof reference2 !== "string" || reference2.length === 0) {
72955
+ throw new Error(`${label} must reference a value id.`);
72956
+ }
72957
+ const value = valuesById.get(reference2);
72958
+ if (value === void 0) {
72959
+ throw new Error(`${label} references missing value "${reference2}".`);
72960
+ }
72961
+ return value;
72962
+ }
72963
+ function containmentEntryIds(listValue2, containedIds) {
72964
+ const ids = /* @__PURE__ */ new Set();
72965
+ if (Array.isArray(listValue2.value)) {
72966
+ for (const valueId of listValue2.value) {
72967
+ if (typeof valueId === "string" && valueId.length > 0) ids.add(valueId);
72968
+ }
72969
+ }
72970
+ for (const valueId of containedIds.get(listValue2.id) ?? []) ids.add(valueId);
72971
+ return [...ids];
72972
+ }
72973
+ function containedValueIdsByContainer(values) {
72974
+ const result = /* @__PURE__ */ new Map();
72975
+ for (const value of values) {
72976
+ if (typeof value.containerId !== "string") continue;
72977
+ const ids = result.get(value.containerId) ?? [];
72978
+ ids.push(value.id);
72979
+ result.set(value.containerId, ids);
72980
+ }
72981
+ return result;
72982
+ }
72435
72983
  function optionalNonEmptyString(value) {
72436
72984
  return typeof value === "string" && value.length > 0 ? value : null;
72437
72985
  }
@@ -81143,6 +81691,16 @@ function assertProjectVersionWholeGraphWritesValid(args) {
81143
81691
  assertStagedUnitySingletonValid(projected, args.changes);
81144
81692
  assertStagedProjectInterfaceValid(projected, args.changes);
81145
81693
  assertStagedTileGridReferencesValid(args.document, projected, args.changes);
81694
+ assertStagedInternalRecordRelationsValid(
81695
+ args.document,
81696
+ projected,
81697
+ args.changes
81698
+ );
81699
+ assertStagedWorldContentLayerBindingsValid(
81700
+ args.document,
81701
+ projected,
81702
+ args.changes
81703
+ );
81146
81704
  assertAnimationClipDocumentValid(
81147
81705
  materializeDeclarationInitializersForAnimationValidation(projected)
81148
81706
  );
@@ -81331,6 +81889,188 @@ function containsDirectValueId(value, ids) {
81331
81889
  (entry) => typeof entry === "string" && ids.has(entry)
81332
81890
  );
81333
81891
  }
81892
+ function assertStagedInternalRecordRelationsValid(current, projected, changes) {
81893
+ if (!stagedChangesAffectClassRelations(current, changes)) return;
81894
+ validateInternalRecordRelations({
81895
+ relations: projected.internalRecordRelations ?? [],
81896
+ endpoints: collectProjectDocumentRelationEndpoints(projected),
81897
+ classes: projected.classes
81898
+ });
81899
+ }
81900
+ function stagedChangesAffectClassRelations(current, changes) {
81901
+ const classesById = new Map(
81902
+ current.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
81903
+ );
81904
+ const valuesById = new Map(current.values.map((value) => [value.id, value]));
81905
+ for (const change of changes) {
81906
+ if (change.recordKind === "internal-record-relation") return true;
81907
+ if (change.recordKind === "class") {
81908
+ if (change.operation !== "update") return true;
81909
+ if (change.deleted === true) return true;
81910
+ const before2 = classesById.get(change.recordId);
81911
+ if (before2 === void 0) return true;
81912
+ const after = change.nextData;
81913
+ if (!isPlainRecord4(after)) return true;
81914
+ if (before2.extendsClassId !== after.extendsClassId) return true;
81915
+ continue;
81916
+ }
81917
+ if (change.recordKind !== "value") continue;
81918
+ const before = valuesById.get(change.recordId);
81919
+ if (relationEndpointClassId(before) !== relationEndpointClassId(change.nextData)) {
81920
+ return true;
81921
+ }
81922
+ }
81923
+ return false;
81924
+ }
81925
+ function assertStagedWorldContentLayerBindingsValid(current, projected, changes) {
81926
+ if (!stagedChangesRequireWorldLayerBindingValidation(current, changes)) {
81927
+ return;
81928
+ }
81929
+ const classes = projected.classes;
81930
+ const relations = projected.internalRecordRelations ?? [];
81931
+ validateWorldContentSidecars({
81932
+ classes,
81933
+ relations,
81934
+ values: projected.values
81935
+ });
81936
+ validateWorldLayerLinkClassTargets({
81937
+ classes,
81938
+ relations,
81939
+ classIds: stagedAffectedWorldLayerLinkClassIds({
81940
+ classes,
81941
+ relations,
81942
+ current,
81943
+ changes
81944
+ })
81945
+ });
81946
+ }
81947
+ function stagedChangesRequireWorldLayerBindingValidation(current, changes) {
81948
+ const classesById = new Map(
81949
+ current.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
81950
+ );
81951
+ const valuesById = new Map(current.values.map((value) => [value.id, value]));
81952
+ const valueChanges = [];
81953
+ for (const change of changes) {
81954
+ if (change.recordKind === "internal-record-relation") return true;
81955
+ if (change.recordKind === "value") {
81956
+ valueChanges.push(change);
81957
+ continue;
81958
+ }
81959
+ if (change.recordKind !== "class") continue;
81960
+ if (change.operation !== "update") return true;
81961
+ if (change.deleted === true) return true;
81962
+ const before = classesById.get(change.recordId);
81963
+ if (before === void 0) return true;
81964
+ const after = change.nextData;
81965
+ if (!isPlainRecord4(after)) return true;
81966
+ if (before.extendsClassId !== after.extendsClassId) return true;
81967
+ if (before.isAbstract !== after.isAbstract) return true;
81968
+ if (!worldClassSystemBlockIsEqual(before.system, after.system)) return true;
81969
+ }
81970
+ if (valueChanges.length === 0) return false;
81971
+ const graph = createWorldReferenceGraph({
81972
+ classes: current.classes,
81973
+ values: []
81974
+ });
81975
+ for (const change of valueChanges) {
81976
+ const before = valuesById.get(change.recordId);
81977
+ if (hasWorldLayerOverrideMetadata(before) || hasWorldLayerOverrideMetadata(change.nextData)) {
81978
+ return true;
81979
+ }
81980
+ const classIds = [
81981
+ relationEndpointClassId(before),
81982
+ relationEndpointClassId(change.nextData)
81983
+ ].filter((classId) => classId !== void 0);
81984
+ for (const classId of classIds) {
81985
+ const worldKind = resolveWorldKindFromClassMap(
81986
+ classId,
81987
+ graph.classesById
81988
+ );
81989
+ if (worldKind === NeoWorldSystemClassKind.TileLayerLink) return true;
81990
+ if (worldKind === NeoWorldSystemClassKind.ObjectLayerLink) return true;
81991
+ }
81992
+ }
81993
+ return false;
81994
+ }
81995
+ function stagedAffectedWorldLayerLinkClassIds(args) {
81996
+ const baseRelationsById = new Map(
81997
+ (args.current.internalRecordRelations ?? []).map((relation) => [
81998
+ relation.id,
81999
+ relation
82000
+ ])
82001
+ );
82002
+ const roots = /* @__PURE__ */ new Set();
82003
+ const changedClassIds = /* @__PURE__ */ new Set();
82004
+ for (const change of args.changes) {
82005
+ if (change.recordKind === "class") {
82006
+ changedClassIds.add(change.recordId);
82007
+ roots.add(change.recordId);
82008
+ continue;
82009
+ }
82010
+ if (change.recordKind !== "internal-record-relation") continue;
82011
+ const candidates = [
82012
+ baseRelationsById.get(change.recordId),
82013
+ change.nextData
82014
+ ];
82015
+ for (const candidate of candidates) {
82016
+ if (!isPlainRecord4(candidate)) continue;
82017
+ const relationKind = candidate.relationKind;
82018
+ if (typeof relationKind !== "string") continue;
82019
+ if (!isStagedWorldLayerLinkTargetRelationKind(relationKind)) continue;
82020
+ const sourceRecordId = candidate.sourceRecordId;
82021
+ if (typeof sourceRecordId !== "string") continue;
82022
+ roots.add(sourceRecordId);
82023
+ }
82024
+ }
82025
+ for (const relation of args.relations) {
82026
+ if (!isStagedWorldLayerLinkTargetRelationKind(relation.relationKind)) {
82027
+ continue;
82028
+ }
82029
+ if (!changedClassIds.has(relation.targetRecordId)) continue;
82030
+ roots.add(relation.sourceRecordId);
82031
+ }
82032
+ const affected = new Set(roots);
82033
+ let added = true;
82034
+ while (added) {
82035
+ added = false;
82036
+ for (const schemaClass2 of args.classes) {
82037
+ if (schemaClass2.extendsClassId === void 0) continue;
82038
+ if (!affected.has(schemaClass2.extendsClassId)) continue;
82039
+ if (affected.has(schemaClass2.id)) continue;
82040
+ affected.add(schemaClass2.id);
82041
+ added = true;
82042
+ }
82043
+ }
82044
+ return affected;
82045
+ }
82046
+ function isStagedWorldLayerLinkTargetRelationKind(relationKind) {
82047
+ if (relationKind === InternalRecordRelationKind.WorldTileLayerLinkTarget) {
82048
+ return true;
82049
+ }
82050
+ return relationKind === InternalRecordRelationKind.WorldObjectLayerLinkTarget;
82051
+ }
82052
+ function worldClassSystemBlockIsEqual(before, after) {
82053
+ return projectRecordDataIsSemanticallyEqual(
82054
+ { system: before },
82055
+ { system: after }
82056
+ );
82057
+ }
82058
+ function hasWorldLayerOverrideMetadata(record3) {
82059
+ if (!isPlainRecord4(record3)) return false;
82060
+ const value = record3.value;
82061
+ if (!isPlainRecord4(value)) return false;
82062
+ return typeof value.layerOverrideValueId === "string";
82063
+ }
82064
+ function relationEndpointClassId(record3) {
82065
+ if (!isPlainRecord4(record3)) return void 0;
82066
+ if (typeof record3.classId === "string") return record3.classId;
82067
+ if (typeof record3.typeId === "string") return record3.typeId;
82068
+ return void 0;
82069
+ }
82070
+ function isPlainRecord4(value) {
82071
+ if (value === null || typeof value !== "object") return false;
82072
+ return !Array.isArray(value);
82073
+ }
81334
82074
  function assertStagedProjectInterfaceValid(projected, changes) {
81335
82075
  const relevant = changes.filter(
81336
82076
  (change) => INTERFACE_VALIDATED_RECORD_KINDS.has(change.recordKind)
@@ -81448,6 +82188,10 @@ var INTERFACE_VALIDATED_RECORD_KINDS;
81448
82188
  var init_project_version_whole_graph_validation = __esm({
81449
82189
  "../src/database/project-version-whole-graph-validation.ts"() {
81450
82190
  "use strict";
82191
+ init_internal_record_relations();
82192
+ init_world_content_sidecar_validation();
82193
+ init_world_layer_link_target();
82194
+ init_core();
81451
82195
  init_animation_clips();
81452
82196
  init_projectInterfaceValidation();
81453
82197
  init_project_schema_identifier_validation();
@@ -81458,6 +82202,7 @@ var init_project_version_whole_graph_validation = __esm({
81458
82202
  init_init_backed_value_materialization();
81459
82203
  init_world_system_classes();
81460
82204
  init_project_world_reference_graph();
82205
+ init_project_record_semantics();
81461
82206
  INTERFACE_VALIDATED_RECORD_KINDS = /* @__PURE__ */ new Set(["member", "class", "constructor", "interface"]);
81462
82207
  }
81463
82208
  });
@@ -81750,6 +82495,7 @@ function replayStoredConstructionV4(args) {
81750
82495
  );
81751
82496
  }
81752
82497
  if (args.evaluate === false) return /* @__PURE__ */ new Map();
82498
+ compilePulledUncompiledConstructorsV4(document, compilationProject);
81753
82499
  assertPulledConstructorsCompiled(document);
81754
82500
  const compiledDependencies = /* @__PURE__ */ new Set();
81755
82501
  let materialized;
@@ -81792,6 +82538,34 @@ function replayStoredConstructionV4(args) {
81792
82538
  ])
81793
82539
  );
81794
82540
  }
82541
+ function compilePulledUncompiledConstructorsV4(document, compilationProject) {
82542
+ const uncompiled = (document.constructors ?? []).filter(
82543
+ (constructor2) => !isNeoClassConstructor(constructor2)
82544
+ );
82545
+ if (uncompiled.length === 0) return;
82546
+ const project = compilationProject ?? createNeoScriptCompilationProject({
82547
+ project: document.project,
82548
+ projectFiles: document.projectFiles,
82549
+ members: document.members,
82550
+ classes: document.classes,
82551
+ enums: document.enums,
82552
+ interfaces: document.interfaces,
82553
+ constructors: document.constructors ?? []
82554
+ });
82555
+ const compileArgs = {
82556
+ project: document.project,
82557
+ projectFiles: document.projectFiles,
82558
+ members: document.members,
82559
+ classes: document.classes,
82560
+ enums: document.enums,
82561
+ interfaces: document.interfaces,
82562
+ constructors: document.constructors ?? [],
82563
+ compilationProject: project
82564
+ };
82565
+ for (const constructor2 of uncompiled) {
82566
+ compileConstructorRecord({ ...compileArgs, constructor: constructor2 });
82567
+ }
82568
+ }
81795
82569
  function valueInitializerCompilationSites(document) {
81796
82570
  const cached = pulledValueInitializerCompilationSites.get(document);
81797
82571
  if (cached !== void 0) return cached;