@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
|
-
|
|
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
|
-
|
|
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;
|