@neocompose/cli 0.42.1 → 0.43.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
@@ -288,6 +288,11 @@ function readWorkspaceState(root, options = {}) {
288
288
  if (typeof state.records !== "object" || state.records === null) {
289
289
  throw new Error(`"${statePath}" is missing the "records" object.`);
290
290
  }
291
+ if (state.derivedEdgeVersion !== void 0 && state.derivedEdgeVersion !== null && (!Number.isSafeInteger(state.derivedEdgeVersion) || state.derivedEdgeVersion < 0)) {
292
+ throw new Error(
293
+ `"${statePath}" field "derivedEdgeVersion" must be a non-negative safe integer or null.`
294
+ );
295
+ }
291
296
  for (const [key, value] of Object.entries(state.records)) {
292
297
  if (typeof value !== "object" || value === null) {
293
298
  throw new Error(
@@ -367,10 +372,6 @@ var init_auth_api_base_url = __esm({
367
372
  // src/token-store.ts
368
373
  var token_store_exports = {};
369
374
  __export(token_store_exports, {
370
- NEO_CONFIG_HOME_ENV_VAR: () => NEO_CONFIG_HOME_ENV_VAR,
371
- NEO_CREDENTIAL_NAMESPACE_ENV_VAR: () => NEO_CREDENTIAL_NAMESPACE_ENV_VAR,
372
- NEO_TOKEN_ENV_VAR: () => NEO_TOKEN_ENV_VAR,
373
- credentialsDir: () => credentialsDir,
374
375
  deleteCredential: () => deleteCredential,
375
376
  keychainAccount: () => keychainAccount,
376
377
  loadCredential: () => loadCredential,
@@ -22457,7 +22458,7 @@ function reportVariantTypePositions(uri, type, diagnostics, root = "nested") {
22457
22458
  severity: "error",
22458
22459
  source: "neo-project",
22459
22460
  code: "variant-type-position",
22460
- message: variantTypePositionMessage(type.name, root)
22461
+ message: variantTypePositionMessage(type.name)
22461
22462
  });
22462
22463
  return;
22463
22464
  }
@@ -22465,7 +22466,7 @@ function reportVariantTypePositions(uri, type, diagnostics, root = "nested") {
22465
22466
  reportVariantTypePositions(uri, argument2, diagnostics);
22466
22467
  }
22467
22468
  }
22468
- function variantTypePositionMessage(typeName, root) {
22469
+ function variantTypePositionMessage(typeName) {
22469
22470
  if (isNeoVariantFolderTypeName(typeName)) {
22470
22471
  return `'${typeName}' is reference-only: it declares variant folders as top-level globals and is never a member, entry, parameter, or generic binding type.`;
22471
22472
  }
@@ -37224,7 +37225,6 @@ function memberFromDocument(record3, members, owners, classNames, context) {
37224
37225
  "returnTypeInfo"
37225
37226
  ),
37226
37227
  script: isAbstract || getterSource === null ? null : propertyScript(
37227
- record3,
37228
37228
  common.owner,
37229
37229
  classNames,
37230
37230
  getterSource,
@@ -37275,7 +37275,7 @@ function memberFromDocument(record3, members, owners, classNames, context) {
37275
37275
  ...signature,
37276
37276
  ...bodyModeValue === "ui" ? { bodyMode: "ui" } : {},
37277
37277
  ...uiActionValue === null ? {} : { uiAction: jsonValue(uiActionValue, record3, "uiAction") },
37278
- script: isAbstract || code === null ? null : functionScript(record3, common.owner, classNames, code)
37278
+ script: isAbstract || code === null ? null : functionScript(common.owner, classNames, code)
37279
37279
  };
37280
37280
  }
37281
37281
  if (kind === MEMBER_KIND.FunctionRef) {
@@ -37882,8 +37882,8 @@ function memberModifier(overrideOf, modifier) {
37882
37882
  if (modifier === "static") return "static";
37883
37883
  return "virtual";
37884
37884
  }
37885
- function propertyScript(record3, owner, classNames, getterSource, setterSource) {
37886
- const path = scriptPath(record3, owner, classNames);
37885
+ function propertyScript(owner, classNames, getterSource, setterSource) {
37886
+ const path = scriptPath(owner, classNames);
37887
37887
  const sourceText = [
37888
37888
  "get {",
37889
37889
  getterSource,
@@ -37900,8 +37900,8 @@ function propertyScript(record3, owner, classNames, getterSource, setterSource)
37900
37900
  source: zeroSpan(path)
37901
37901
  };
37902
37902
  }
37903
- function functionScript(record3, owner, classNames, sourceText) {
37904
- const path = scriptPath(record3, owner, classNames);
37903
+ function functionScript(owner, classNames, sourceText) {
37904
+ const path = scriptPath(owner, classNames);
37905
37905
  return {
37906
37906
  kind: "function",
37907
37907
  path,
@@ -37909,7 +37909,7 @@ function functionScript(record3, owner, classNames, sourceText) {
37909
37909
  source: zeroSpan(path)
37910
37910
  };
37911
37911
  }
37912
- function scriptPath(record3, ownerValue, classNames) {
37912
+ function scriptPath(ownerValue, classNames) {
37913
37913
  const owner = isRecord2(ownerValue) ? ownerValue : {};
37914
37914
  const sharedMember = owner.kind === "sharedClassMember" && Array.isArray(owner.members) ? owner.members.find(isRecord2) : void 0;
37915
37915
  let ownerClassId;
@@ -42720,36 +42720,36 @@ var MemberKind;
42720
42720
  var init_member_kind_enum = __esm({
42721
42721
  "../src/models/members/member-kind-enum.ts"() {
42722
42722
  "use strict";
42723
- MemberKind = /* @__PURE__ */ ((MemberKind16) => {
42724
- MemberKind16[MemberKind16["Null"] = 0] = "Null";
42725
- MemberKind16[MemberKind16["Bool"] = 1] = "Bool";
42726
- MemberKind16[MemberKind16["Int"] = 2] = "Int";
42727
- MemberKind16[MemberKind16["String"] = 3] = "String";
42728
- MemberKind16[MemberKind16["Float"] = 4] = "Float";
42729
- MemberKind16[MemberKind16["Dictionary"] = 5] = "Dictionary";
42730
- MemberKind16[MemberKind16["List"] = 6] = "List";
42731
- MemberKind16[MemberKind16["Class"] = 7] = "Class";
42732
- MemberKind16[MemberKind16["Enum"] = 8] = "Enum";
42733
- MemberKind16[MemberKind16["Lookup"] = 9] = "Lookup";
42734
- MemberKind16[MemberKind16["NSProperty"] = 10] = "NSProperty";
42735
- MemberKind16[MemberKind16["Sprite"] = 11] = "Sprite";
42736
- MemberKind16[MemberKind16["Audio"] = 12] = "Audio";
42737
- MemberKind16[MemberKind16["Function"] = 13] = "Function";
42738
- MemberKind16[MemberKind16["Vector2"] = 14] = "Vector2";
42739
- MemberKind16[MemberKind16["Vector2Int"] = 15] = "Vector2Int";
42740
- MemberKind16[MemberKind16["Vector3"] = 16] = "Vector3";
42741
- MemberKind16[MemberKind16["Vector3Int"] = 17] = "Vector3Int";
42742
- MemberKind16[MemberKind16["DialogueLookup"] = 18] = "DialogueLookup";
42743
- MemberKind16[MemberKind16["Color"] = 19] = "Color";
42744
- MemberKind16[MemberKind16["Decimal"] = 20] = "Decimal";
42745
- MemberKind16[MemberKind16["Generic"] = 21] = "Generic";
42746
- MemberKind16[MemberKind16["Interface"] = 22] = "Interface";
42747
- MemberKind16[MemberKind16["NSFunction"] = 23] = "NSFunction";
42748
- MemberKind16[MemberKind16["FunctionRef"] = 24] = "FunctionRef";
42749
- MemberKind16[MemberKind16["NSDelegate"] = 25] = "NSDelegate";
42750
- MemberKind16[MemberKind16["NSAction"] = 26] = "NSAction";
42751
- MemberKind16[MemberKind16["Variant"] = 27] = "Variant";
42752
- return MemberKind16;
42723
+ MemberKind = /* @__PURE__ */ ((MemberKind13) => {
42724
+ MemberKind13[MemberKind13["Null"] = 0] = "Null";
42725
+ MemberKind13[MemberKind13["Bool"] = 1] = "Bool";
42726
+ MemberKind13[MemberKind13["Int"] = 2] = "Int";
42727
+ MemberKind13[MemberKind13["String"] = 3] = "String";
42728
+ MemberKind13[MemberKind13["Float"] = 4] = "Float";
42729
+ MemberKind13[MemberKind13["Dictionary"] = 5] = "Dictionary";
42730
+ MemberKind13[MemberKind13["List"] = 6] = "List";
42731
+ MemberKind13[MemberKind13["Class"] = 7] = "Class";
42732
+ MemberKind13[MemberKind13["Enum"] = 8] = "Enum";
42733
+ MemberKind13[MemberKind13["Lookup"] = 9] = "Lookup";
42734
+ MemberKind13[MemberKind13["NSProperty"] = 10] = "NSProperty";
42735
+ MemberKind13[MemberKind13["Sprite"] = 11] = "Sprite";
42736
+ MemberKind13[MemberKind13["Audio"] = 12] = "Audio";
42737
+ MemberKind13[MemberKind13["Function"] = 13] = "Function";
42738
+ MemberKind13[MemberKind13["Vector2"] = 14] = "Vector2";
42739
+ MemberKind13[MemberKind13["Vector2Int"] = 15] = "Vector2Int";
42740
+ MemberKind13[MemberKind13["Vector3"] = 16] = "Vector3";
42741
+ MemberKind13[MemberKind13["Vector3Int"] = 17] = "Vector3Int";
42742
+ MemberKind13[MemberKind13["DialogueLookup"] = 18] = "DialogueLookup";
42743
+ MemberKind13[MemberKind13["Color"] = 19] = "Color";
42744
+ MemberKind13[MemberKind13["Decimal"] = 20] = "Decimal";
42745
+ MemberKind13[MemberKind13["Generic"] = 21] = "Generic";
42746
+ MemberKind13[MemberKind13["Interface"] = 22] = "Interface";
42747
+ MemberKind13[MemberKind13["NSFunction"] = 23] = "NSFunction";
42748
+ MemberKind13[MemberKind13["FunctionRef"] = 24] = "FunctionRef";
42749
+ MemberKind13[MemberKind13["NSDelegate"] = 25] = "NSDelegate";
42750
+ MemberKind13[MemberKind13["NSAction"] = 26] = "NSAction";
42751
+ MemberKind13[MemberKind13["Variant"] = 27] = "Variant";
42752
+ return MemberKind13;
42753
42753
  })(MemberKind || {});
42754
42754
  }
42755
42755
  });
@@ -48107,6 +48107,31 @@ function worldAnimationChildOverrideBindingMember(projectId, classId) {
48107
48107
  updatedAt: 0
48108
48108
  };
48109
48109
  }
48110
+ function animationFamilyClassKinds(classes) {
48111
+ const classesById2 = new Map(classes.map((entry) => [entry.id, entry]));
48112
+ const resolved = /* @__PURE__ */ new Map();
48113
+ const resolve5 = (classId, visiting) => {
48114
+ const cached = resolved.get(classId);
48115
+ if (cached !== void 0) return cached;
48116
+ if (visiting.has(classId)) return null;
48117
+ const schemaClass2 = classesById2.get(classId);
48118
+ if (schemaClass2 === void 0) return null;
48119
+ const worldKind = schemaClass2.system?.worldKind;
48120
+ if (typeof worldKind === "string" && WORLD_SYSTEM_ANIMATION_KINDS.has(worldKind)) {
48121
+ resolved.set(classId, worldKind);
48122
+ return worldKind;
48123
+ }
48124
+ const result = typeof schemaClass2.extendsClassId === "string" ? resolve5(schemaClass2.extendsClassId, new Set(visiting).add(classId)) : null;
48125
+ resolved.set(classId, result);
48126
+ return result;
48127
+ };
48128
+ const family = /* @__PURE__ */ new Map();
48129
+ for (const classId of classesById2.keys()) {
48130
+ const worldKind = resolve5(classId, /* @__PURE__ */ new Set());
48131
+ if (worldKind !== null) family.set(classId, worldKind);
48132
+ }
48133
+ return family;
48134
+ }
48110
48135
  var WORLD_ANIMATION_CHILD_OVERRIDE_BINDING_MEMBER_NAME, WORLD_ANIMATION_CHILD_OVERRIDE_BINDING_MEMBER_NAMESPACE, WORLD_SYSTEM_CLASS_DEFINITION_BY_KIND, WORLD_SYSTEM_ANIMATION_KIND_MARKER, WORLD_SYSTEM_ANIMATION_KINDS, GENERIC_WORLD_SYSTEM_CLASS_KINDS, WORLD_SYSTEM_ALL_KINDS, WORLD_SYSTEM_SCHEMA_FIELD_SITES_BY_MEMBER_ID;
48111
48136
  var init_world_system_classes = __esm({
48112
48137
  "../src/models/classes/world-system-classes.ts"() {
@@ -49665,6 +49690,51 @@ function decodePackedValueRow(row) {
49665
49690
  packedChildIdsByParentId: state.edges
49666
49691
  };
49667
49692
  }
49693
+ function packedValuePositions(row) {
49694
+ if (!rowCarriesPackedValueContent(row)) return NO_POSITIONS;
49695
+ const positions = [];
49696
+ collectPackedPositions(row, {
49697
+ ownerLabel: `value "${row.id}"`,
49698
+ constructionRootId: isCollapseStampedInstanceRoot(row) ? row.id : null,
49699
+ path: [],
49700
+ positions
49701
+ });
49702
+ return positions;
49703
+ }
49704
+ function collectPackedPositions(content, scope) {
49705
+ collectPackedContainerPositions(content.value, "value", scope);
49706
+ collectPackedContainerPositions(
49707
+ content.constructorArgs,
49708
+ "constructorArgs",
49709
+ scope
49710
+ );
49711
+ }
49712
+ function collectPackedContainerPositions(container, field, scope) {
49713
+ if (!containerHoldsPackedEntry(container)) return;
49714
+ const entries = Array.isArray(
49715
+ container
49716
+ ) ? container.map((entry, index) => [String(index), entry]) : Object.entries(container);
49717
+ for (const [key, candidate] of entries) {
49718
+ if (!isPackedValueEnvelope(candidate)) continue;
49719
+ const label = `Packed value entry at ${scope.ownerLabel}.${field}[${JSON.stringify(key)}]`;
49720
+ const entry = candidate[PACKED_VALUE_ENTRY_KEY];
49721
+ assertDecodableEntry(entry, label);
49722
+ const valueId = packedEntryLogicalId(
49723
+ entry,
49724
+ label,
49725
+ scope.constructionRootId
49726
+ );
49727
+ const path = [...scope.path, field, key];
49728
+ scope.positions.push({ valueId, path, entry });
49729
+ if (isInitValueContent(entry)) continue;
49730
+ collectPackedPositions(entry, {
49731
+ ownerLabel: `packed value "${valueId}"`,
49732
+ constructionRootId: isCollapseStampedInstanceRoot(entry) ? valueId : scope.constructionRootId,
49733
+ path,
49734
+ positions: scope.positions
49735
+ });
49736
+ }
49737
+ }
49668
49738
  function encodePackedValueRow(args) {
49669
49739
  const scope = {
49670
49740
  parent: args.parent,
@@ -49984,7 +50054,7 @@ function registerEdge(edges, ownerId, childId) {
49984
50054
  if (existing === void 0) edges.set(ownerId, [childId]);
49985
50055
  else existing.push(childId);
49986
50056
  }
49987
- var PACKED_VALUE_ENTRY_KEY, PackedValueEncodingError, NO_CHILDREN, NO_EDGES, PACKED_ENTRY_FORBIDDEN_FIELDS;
50057
+ var PACKED_VALUE_ENTRY_KEY, PackedValueEncodingError, NO_CHILDREN, NO_EDGES, NO_POSITIONS, PACKED_ENTRY_FORBIDDEN_FIELDS;
49988
50058
  var init_packed_value_encoding = __esm({
49989
50059
  "../src/models/members/packed-value-encoding.ts"() {
49990
50060
  "use strict";
@@ -50000,6 +50070,7 @@ var init_packed_value_encoding = __esm({
50000
50070
  };
50001
50071
  NO_CHILDREN = [];
50002
50072
  NO_EDGES = /* @__PURE__ */ new Map();
50073
+ NO_POSITIONS = [];
50003
50074
  PACKED_ENTRY_FORBIDDEN_FIELDS = [
50004
50075
  "projectId",
50005
50076
  "containerId",
@@ -51157,135 +51228,11 @@ var init_enum_types = __esm({
51157
51228
  }
51158
51229
  });
51159
51230
 
51160
- // ../src/models/interfaces/interface-types.ts
51161
- function isInterfaceFunctionMember(member) {
51162
- return member.kind === 1 /* Function */;
51163
- }
51164
- function interfacePropertyIsSettable(member) {
51165
- return member.accessors === 1 /* GetSet */;
51166
- }
51167
- function containsForbiddenMemberTypeInfo(typeInfo) {
51168
- if (typeInfo.type === NS_TYPE_UNKNOWN) return true;
51169
- if (typeInfo.type === 21 /* Generic */) return true;
51170
- if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
51171
- return containsForbiddenMemberTypeInfo(typeInfo.entryTypeInfo);
51172
- }
51173
- if (typeInfo.type === 7 /* Class */ && typeInfo.typeArguments) {
51174
- return Object.values(typeInfo.typeArguments).some(
51175
- containsForbiddenMemberTypeInfo
51176
- );
51177
- }
51178
- return false;
51179
- }
51180
- function isNeoInterfaceMember(value) {
51181
- if (typeof value !== "object") return false;
51182
- if (value === null) return false;
51183
- const member = value;
51184
- if (typeof member.id !== "string" || member.id.length === 0) return false;
51185
- if (!isValidDocsText(member.docsText)) return false;
51186
- if (member.access !== void 0 && !isMemberAccessKind(member.access))
51187
- return false;
51188
- if (member.kind === void 0 || member.kind === 0 /* Property */) {
51189
- const property2 = value;
51190
- if (!isNSTypeInfo(property2.typeInfo)) return false;
51191
- if (containsForbiddenMemberTypeInfo(property2.typeInfo)) return false;
51192
- return property2.accessors === void 0 || property2.accessors === 0 /* Get */ || property2.accessors === 1 /* GetSet */;
51193
- }
51194
- if (member.kind !== 1 /* Function */) return false;
51195
- const fn = value;
51196
- if (!isNSFunctionReturnTypeInfo(fn.returnTypeInfo)) return false;
51197
- if (containsForbiddenMemberTypeInfo(fn.returnTypeInfo)) return false;
51198
- if (!Array.isArray(fn.argumentTypes)) return false;
51199
- for (const argumentType of fn.argumentTypes) {
51200
- if (!isNSFunctionArgumentTypeInfo(argumentType)) return false;
51201
- if (containsForbiddenMemberTypeInfo(argumentType)) return false;
51202
- }
51203
- if (fn.dispatch !== void 0 && fn.dispatch !== 0 /* Synchronous */ && fn.dispatch !== 1 /* Asynchronous */)
51204
- return false;
51205
- if (fn.dispatch === 1 /* Asynchronous */ && hasAnyParameterDefault(fn.argumentTypes)) {
51206
- return false;
51207
- }
51208
- return validateParameterDefaults(fn.argumentTypes).length === 0;
51209
- }
51210
- function isInterfaceMembersRecord(value) {
51211
- if (typeof value !== "object") return false;
51212
- if (value === null) return false;
51213
- if (Array.isArray(value)) return false;
51214
- for (const [key, member] of Object.entries(value)) {
51215
- if (key.length === 0) return false;
51216
- if (!isNeoInterfaceMember(member)) return false;
51217
- }
51218
- return true;
51219
- }
51220
- function isOptionalStringArray(value) {
51221
- if (value === void 0) return true;
51222
- if (!Array.isArray(value)) return false;
51223
- return value.every((entry) => typeof entry === "string" && entry.length > 0);
51224
- }
51225
- function isNeoInterfaceBase(value) {
51226
- if (typeof value !== "object") return false;
51227
- if (value === null) return false;
51228
- const neoInterface = value;
51229
- if (typeof neoInterface.name !== "string") return false;
51230
- if (!isValidDocsText(neoInterface.docsText)) return false;
51231
- if (!isInterfaceMembersRecord(neoInterface.members)) return false;
51232
- if (!isOptionalStringArray(neoInterface.memberKeyOrder)) return false;
51233
- if (!isOptionalStringArray(neoInterface.extendsInterfaceIds)) return false;
51234
- if (neoInterface.system !== void 0 && !isSystemMetadata(neoInterface.system)) {
51235
- return false;
51236
- }
51237
- return true;
51238
- }
51239
- function isNeoInterfaceProps(value) {
51240
- if (!isNeoInterfaceBase(value)) return false;
51241
- if (!isWithId(value)) return false;
51242
- const neoInterface = value;
51243
- if (typeof neoInterface.projectId !== "string") return false;
51244
- if (!isEpochMillis(neoInterface.createdAt)) return false;
51245
- return isEpochMillis(neoInterface.updatedAt);
51246
- }
51247
- function isNeoInterface(value) {
51248
- return isNeoInterfaceProps(value);
51249
- }
51250
- function getInterfaceMemberKeyOrder(neoInterface) {
51251
- const memberKeys = Object.keys(neoInterface.members);
51252
- const seen = /* @__PURE__ */ new Set();
51253
- const result = [];
51254
- for (const memberKey of neoInterface.memberKeyOrder ?? []) {
51255
- if (!Object.prototype.hasOwnProperty.call(neoInterface.members, memberKey)) {
51256
- continue;
51257
- }
51258
- if (seen.has(memberKey)) continue;
51259
- seen.add(memberKey);
51260
- result.push(memberKey);
51261
- }
51262
- for (const memberKey of memberKeys) {
51263
- if (seen.has(memberKey)) continue;
51264
- seen.add(memberKey);
51265
- result.push(memberKey);
51266
- }
51267
- return result;
51268
- }
51269
- var init_interface_types = __esm({
51270
- "../src/models/interfaces/interface-types.ts"() {
51271
- "use strict";
51272
- init_core();
51273
- init_neoscript_types();
51274
- init_docs_text2();
51275
- init_neoscript_guards();
51276
- init_parameter_defaults();
51277
- init_member_kinds();
51278
- }
51279
- });
51280
-
51281
51231
  // ../src/models/enum/enum-responses.ts
51282
51232
  var init_enum_responses = __esm({
51283
51233
  "../src/models/enum/enum-responses.ts"() {
51284
51234
  "use strict";
51285
- init_members();
51286
- init_classes();
51287
51235
  init_enum_types();
51288
- init_interface_types();
51289
51236
  }
51290
51237
  });
51291
51238
 
@@ -53251,7 +53198,6 @@ var init_add_class_member = __esm({
53251
53198
  init_enum2();
53252
53199
  init_classes();
53253
53200
  init_initial_class_internal_record_relation();
53254
- init_project_version_types();
53255
53201
  }
53256
53202
  });
53257
53203
 
@@ -53271,8 +53217,6 @@ var init_edit_member_props = __esm({
53271
53217
  var init_delete_member_response = __esm({
53272
53218
  "../src/models/members/delete-member-response.ts"() {
53273
53219
  "use strict";
53274
- init_member_kinds();
53275
- init_classes();
53276
53220
  }
53277
53221
  });
53278
53222
 
@@ -57419,12 +57363,131 @@ var init_dialogue_lookup_candidates = __esm({
57419
57363
  }
57420
57364
  });
57421
57365
 
57366
+ // ../src/models/interfaces/interface-types.ts
57367
+ function isInterfaceFunctionMember(member) {
57368
+ return member.kind === 1 /* Function */;
57369
+ }
57370
+ function interfacePropertyIsSettable(member) {
57371
+ return member.accessors === 1 /* GetSet */;
57372
+ }
57373
+ function containsForbiddenMemberTypeInfo(typeInfo) {
57374
+ if (typeInfo.type === NS_TYPE_UNKNOWN) return true;
57375
+ if (typeInfo.type === 21 /* Generic */) return true;
57376
+ if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
57377
+ return containsForbiddenMemberTypeInfo(typeInfo.entryTypeInfo);
57378
+ }
57379
+ if (typeInfo.type === 7 /* Class */ && typeInfo.typeArguments) {
57380
+ return Object.values(typeInfo.typeArguments).some(
57381
+ containsForbiddenMemberTypeInfo
57382
+ );
57383
+ }
57384
+ return false;
57385
+ }
57386
+ function isNeoInterfaceMember(value) {
57387
+ if (typeof value !== "object") return false;
57388
+ if (value === null) return false;
57389
+ const member = value;
57390
+ if (typeof member.id !== "string" || member.id.length === 0) return false;
57391
+ if (!isValidDocsText(member.docsText)) return false;
57392
+ if (member.access !== void 0 && !isMemberAccessKind(member.access))
57393
+ return false;
57394
+ if (member.kind === void 0 || member.kind === 0 /* Property */) {
57395
+ const property2 = value;
57396
+ if (!isNSTypeInfo(property2.typeInfo)) return false;
57397
+ if (containsForbiddenMemberTypeInfo(property2.typeInfo)) return false;
57398
+ return property2.accessors === void 0 || property2.accessors === 0 /* Get */ || property2.accessors === 1 /* GetSet */;
57399
+ }
57400
+ if (member.kind !== 1 /* Function */) return false;
57401
+ const fn = value;
57402
+ if (!isNSFunctionReturnTypeInfo(fn.returnTypeInfo)) return false;
57403
+ if (containsForbiddenMemberTypeInfo(fn.returnTypeInfo)) return false;
57404
+ if (!Array.isArray(fn.argumentTypes)) return false;
57405
+ for (const argumentType of fn.argumentTypes) {
57406
+ if (!isNSFunctionArgumentTypeInfo(argumentType)) return false;
57407
+ if (containsForbiddenMemberTypeInfo(argumentType)) return false;
57408
+ }
57409
+ if (fn.dispatch !== void 0 && fn.dispatch !== 0 /* Synchronous */ && fn.dispatch !== 1 /* Asynchronous */)
57410
+ return false;
57411
+ if (fn.dispatch === 1 /* Asynchronous */ && hasAnyParameterDefault(fn.argumentTypes)) {
57412
+ return false;
57413
+ }
57414
+ return validateParameterDefaults(fn.argumentTypes).length === 0;
57415
+ }
57416
+ function isInterfaceMembersRecord(value) {
57417
+ if (typeof value !== "object") return false;
57418
+ if (value === null) return false;
57419
+ if (Array.isArray(value)) return false;
57420
+ for (const [key, member] of Object.entries(value)) {
57421
+ if (key.length === 0) return false;
57422
+ if (!isNeoInterfaceMember(member)) return false;
57423
+ }
57424
+ return true;
57425
+ }
57426
+ function isOptionalStringArray(value) {
57427
+ if (value === void 0) return true;
57428
+ if (!Array.isArray(value)) return false;
57429
+ return value.every((entry) => typeof entry === "string" && entry.length > 0);
57430
+ }
57431
+ function isNeoInterfaceBase(value) {
57432
+ if (typeof value !== "object") return false;
57433
+ if (value === null) return false;
57434
+ const neoInterface = value;
57435
+ if (typeof neoInterface.name !== "string") return false;
57436
+ if (!isValidDocsText(neoInterface.docsText)) return false;
57437
+ if (!isInterfaceMembersRecord(neoInterface.members)) return false;
57438
+ if (!isOptionalStringArray(neoInterface.memberKeyOrder)) return false;
57439
+ if (!isOptionalStringArray(neoInterface.extendsInterfaceIds)) return false;
57440
+ if (neoInterface.system !== void 0 && !isSystemMetadata(neoInterface.system)) {
57441
+ return false;
57442
+ }
57443
+ return true;
57444
+ }
57445
+ function isNeoInterfaceProps(value) {
57446
+ if (!isNeoInterfaceBase(value)) return false;
57447
+ if (!isWithId(value)) return false;
57448
+ const neoInterface = value;
57449
+ if (typeof neoInterface.projectId !== "string") return false;
57450
+ if (!isEpochMillis(neoInterface.createdAt)) return false;
57451
+ return isEpochMillis(neoInterface.updatedAt);
57452
+ }
57453
+ function isNeoInterface(value) {
57454
+ return isNeoInterfaceProps(value);
57455
+ }
57456
+ function getInterfaceMemberKeyOrder(neoInterface) {
57457
+ const memberKeys = Object.keys(neoInterface.members);
57458
+ const seen = /* @__PURE__ */ new Set();
57459
+ const result = [];
57460
+ for (const memberKey of neoInterface.memberKeyOrder ?? []) {
57461
+ if (!Object.prototype.hasOwnProperty.call(neoInterface.members, memberKey)) {
57462
+ continue;
57463
+ }
57464
+ if (seen.has(memberKey)) continue;
57465
+ seen.add(memberKey);
57466
+ result.push(memberKey);
57467
+ }
57468
+ for (const memberKey of memberKeys) {
57469
+ if (seen.has(memberKey)) continue;
57470
+ seen.add(memberKey);
57471
+ result.push(memberKey);
57472
+ }
57473
+ return result;
57474
+ }
57475
+ var init_interface_types = __esm({
57476
+ "../src/models/interfaces/interface-types.ts"() {
57477
+ "use strict";
57478
+ init_core();
57479
+ init_neoscript_types();
57480
+ init_docs_text2();
57481
+ init_neoscript_guards();
57482
+ init_parameter_defaults();
57483
+ init_member_kinds();
57484
+ }
57485
+ });
57486
+
57422
57487
  // ../src/models/interfaces/interface-responses.ts
57423
57488
  var init_interface_responses = __esm({
57424
57489
  "../src/models/interfaces/interface-responses.ts"() {
57425
57490
  "use strict";
57426
- init_member_kinds();
57427
- init_classes();
57428
57491
  init_interface_types();
57429
57492
  }
57430
57493
  });
@@ -57929,7 +57992,6 @@ var init_dialogue_db_response_types = __esm({
57929
57992
  init_dialogue_types();
57930
57993
  init_dialogue_group_types();
57931
57994
  init_priority_types();
57932
- init_localization_types();
57933
57995
  }
57934
57996
  });
57935
57997
 
@@ -66025,6 +66087,17 @@ function initializerReferencesAnyIdentifier(source, names) {
66025
66087
  }
66026
66088
  return false;
66027
66089
  }
66090
+ function compilationProjectContext(args, members = args.members) {
66091
+ return {
66092
+ project: args.project,
66093
+ projectFiles: args.projectFiles ?? [],
66094
+ members: [...members],
66095
+ classes: [...args.classes],
66096
+ enums: [...args.enums],
66097
+ interfaces: [...args.interfaces ?? []],
66098
+ ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject }
66099
+ };
66100
+ }
66028
66101
  function compileNSPropertyBodies(args) {
66029
66102
  if (args.member.kind !== 10 /* NSProperty */) return;
66030
66103
  if (isMemberNSPropertyContractBase(args.member)) return;
@@ -66044,16 +66117,10 @@ function compileNSPropertyBodies(args) {
66044
66117
  const getter = compileUnit2(
66045
66118
  "getter",
66046
66119
  () => compileNSGetter(code, {
66047
- project: args.project,
66048
- projectFiles: args.projectFiles ?? [],
66049
- members: [...members],
66050
- classes: [...args.classes],
66051
- enums: [...args.enums],
66052
- interfaces: [...args.interfaces ?? []],
66120
+ ...compilationProjectContext(args, members),
66053
66121
  constructors: args.constructors ?? [],
66054
66122
  variants: args.variants ?? [],
66055
66123
  variantFolders: args.variantFolders ?? [],
66056
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66057
66124
  thisClass: args.thisClass,
66058
66125
  returnTypeInfo,
66059
66126
  implicitMemberAccess: true,
@@ -66083,16 +66150,10 @@ function compileNSPropertyBodies(args) {
66083
66150
  const setter = compileUnit2(
66084
66151
  "setter",
66085
66152
  () => compileNSSetter(setterCode, {
66086
- project: args.project,
66087
- projectFiles: args.projectFiles ?? [],
66088
- members: [...members],
66089
- classes: [...args.classes],
66090
- enums: [...args.enums],
66091
- interfaces: [...args.interfaces ?? []],
66153
+ ...compilationProjectContext(args, members),
66092
66154
  constructors: args.constructors ?? [],
66093
66155
  variants: args.variants ?? [],
66094
66156
  variantFolders: args.variantFolders ?? [],
66095
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66096
66157
  thisClass: args.thisClass,
66097
66158
  valueTypeInfo: returnTypeInfo,
66098
66159
  implicitMemberAccess: true,
@@ -66136,16 +66197,10 @@ function compileNSFunctionBody(args) {
66136
66197
  const action2 = compileUnit2(
66137
66198
  "function",
66138
66199
  () => compileNSFunction("", {
66139
- project: args.project,
66140
- projectFiles: args.projectFiles ?? [],
66141
- members: [...members],
66142
- classes: [...args.classes],
66143
- enums: [...args.enums],
66144
- interfaces: [...args.interfaces ?? []],
66200
+ ...compilationProjectContext(args, members),
66145
66201
  constructors: args.constructors ?? [],
66146
66202
  variants: args.variants ?? [],
66147
66203
  variantFolders: args.variantFolders ?? [],
66148
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66149
66204
  thisClass: args.thisClass,
66150
66205
  functionName: args.member.name,
66151
66206
  implicitMemberAccess: true,
@@ -66185,16 +66240,10 @@ function compileNSFunctionBody(args) {
66185
66240
  const action = compileUnit2(
66186
66241
  "function",
66187
66242
  () => compileNSFunction(code, {
66188
- project: args.project,
66189
- projectFiles: args.projectFiles ?? [],
66190
- members: [...members],
66191
- classes: [...args.classes],
66192
- enums: [...args.enums],
66193
- interfaces: [...args.interfaces ?? []],
66243
+ ...compilationProjectContext(args, members),
66194
66244
  constructors: args.constructors ?? [],
66195
66245
  variants: args.variants ?? [],
66196
66246
  variantFolders: args.variantFolders ?? [],
66197
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66198
66247
  thisClass: args.thisClass,
66199
66248
  functionName: args.member.name,
66200
66249
  implicitMemberAccess: true,
@@ -66224,16 +66273,10 @@ function compileMemberInitializerBody(args) {
66224
66273
  compiled = compileUnit2(
66225
66274
  "getter",
66226
66275
  () => compileNSInitializer(defaultValue.init.code, {
66227
- project: args.project,
66228
- projectFiles: args.projectFiles ?? [],
66229
- members: [...members],
66230
- classes: [...args.classes],
66231
- enums: [...args.enums],
66232
- interfaces: [...args.interfaces ?? []],
66276
+ ...compilationProjectContext(args, members),
66233
66277
  constructors: args.constructors ?? [],
66234
66278
  variants: args.variants ?? [],
66235
66279
  variantFolders: args.variantFolders ?? [],
66236
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66237
66280
  returnTypeInfo,
66238
66281
  initializerName: args.member.name,
66239
66282
  argumentTypes: initializerArgumentTypes(
@@ -66287,12 +66330,7 @@ function compileValueRowInitializerBody(args) {
66287
66330
  compiled = compileUnit2(
66288
66331
  "getter",
66289
66332
  () => compileNSInitializer(container.init.code, {
66290
- project: args.project,
66291
- projectFiles: args.projectFiles ?? [],
66292
- members: [...args.members],
66293
- classes: [...args.classes],
66294
- enums: [...args.enums],
66295
- interfaces: [...args.interfaces ?? []],
66333
+ ...compilationProjectContext(args),
66296
66334
  constructors: args.constructors ?? [],
66297
66335
  variants: args.variants ?? [],
66298
66336
  variantFolders: args.variantFolders ?? [],
@@ -66303,7 +66341,6 @@ function compileValueRowInitializerBody(args) {
66303
66341
  args.initializerOwnerClass,
66304
66342
  args.constructors ?? []
66305
66343
  ),
66306
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66307
66344
  ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
66308
66345
  })
66309
66346
  );
@@ -66370,14 +66407,8 @@ function compileConstructorRecord(args) {
66370
66407
  const action = compileUnit2(
66371
66408
  "function",
66372
66409
  () => compileNSConstructor(code, {
66373
- project: args.project,
66374
- projectFiles: args.projectFiles ?? [],
66375
- members: [...args.members],
66376
- classes: [...args.classes],
66377
- enums: [...args.enums],
66378
- interfaces: [...args.interfaces ?? []],
66410
+ ...compilationProjectContext(args),
66379
66411
  constructors: args.constructors,
66380
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66381
66412
  thisClass: owner,
66382
66413
  argumentTypes,
66383
66414
  constructorName: owner.name
@@ -66414,14 +66445,8 @@ function compileConstructorBaseArguments(args, owner) {
66414
66445
  return compileUnit2(
66415
66446
  "getter",
66416
66447
  () => compileNSInitializer(baseArgument.code, {
66417
- project: args.project,
66418
- projectFiles: args.projectFiles ?? [],
66419
- members: [...args.members],
66420
- classes: [...args.classes],
66421
- enums: [...args.enums],
66422
- interfaces: [...args.interfaces ?? []],
66448
+ ...compilationProjectContext(args),
66423
66449
  constructors: args.constructors,
66424
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66425
66450
  returnTypeInfo,
66426
66451
  argumentTypes,
66427
66452
  initializerName: `${owner.name} base argument ${baseArgument.name}`
@@ -66541,14 +66566,8 @@ function compileConstructorBaseInitializerFields(args, owner) {
66541
66566
  return compileUnit2(
66542
66567
  "getter",
66543
66568
  () => compileNSInitializer(field.code, {
66544
- project: args.project,
66545
- projectFiles: args.projectFiles ?? [],
66546
- members: [...args.members],
66547
- classes: [...args.classes],
66548
- enums: [...args.enums],
66549
- interfaces: [...args.interfaces ?? []],
66569
+ ...compilationProjectContext(args),
66550
66570
  constructors: args.constructors,
66551
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
66552
66571
  returnTypeInfo,
66553
66572
  argumentTypes: args.constructor.argumentTypes,
66554
66573
  initializerName: `${owner.name} base initializer ${field.name}`
@@ -67817,7 +67836,6 @@ var init_constructor_argument_ownership = __esm({
67817
67836
  childrenByContainerId;
67818
67837
  edgesByOwnerValueId;
67819
67838
  referenceCountByTargetValueId;
67820
- classesById;
67821
67839
  membersById;
67822
67840
  constructorsById;
67823
67841
  contextualRootMembersByValueId;
@@ -67832,9 +67850,6 @@ var init_constructor_argument_ownership = __esm({
67832
67850
  this.valuesById = rows;
67833
67851
  this.document = { ...document, values: [...rows.values()] };
67834
67852
  this.contextualRootMembersByValueId = contextualRootMembersByValueId;
67835
- this.classesById = new Map(
67836
- document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
67837
- );
67838
67853
  this.membersById = new Map(
67839
67854
  document.members.map((member) => [member.id, member])
67840
67855
  );
@@ -69851,7 +69866,21 @@ function invalidateEvaluatorIndexes(ctx) {
69851
69866
  function trackedRowForValueReference(value, ctx) {
69852
69867
  if (typeof value !== "object" || value === null) return null;
69853
69868
  const indexes = evaluatorIndexes(ctx);
69854
- return indexes.rowByValueReference.get(value) ?? indexes.baseRowByValueReference?.get(value) ?? ctx.vm.databaseVM?.rowForValueReference?.(value) ?? null;
69869
+ const indexed = indexes.rowByValueReference.get(value) ?? indexes.baseRowByValueReference?.get(value) ?? ctx.vm.databaseVM?.rowForValueReference?.(value) ?? null;
69870
+ if (indexed !== null) return indexed;
69871
+ if (value !== ctx.thisValue || typeof ctx.thisValueRowId !== "string") {
69872
+ return null;
69873
+ }
69874
+ return evalValueById(
69875
+ ctx,
69876
+ ctx.thisValueRowId,
69877
+ ctx.__runtimeSessionValues,
69878
+ ctx.__valueOverlay
69879
+ );
69880
+ }
69881
+ function bindThisValue(ctx, thisValue) {
69882
+ const rowId = thisValue === ctx.thisValue ? ctx.thisValueRowId : trackedRowForValueReference(thisValue, ctx)?.id;
69883
+ return { ...ctx, thisValue, thisValueRowId: rowId };
69855
69884
  }
69856
69885
  function assertStoredReplayMutableValue(value, ctx, label) {
69857
69886
  if (ctx.storedConstructionReplay !== true) return;
@@ -71575,8 +71604,7 @@ function dispatchNSSetter(target, value, scope, ctx, writes) {
71575
71604
  evaluateNSSetter(
71576
71605
  setter,
71577
71606
  {
71578
- ...ctx,
71579
- thisValue: receiver,
71607
+ ...bindThisValue(ctx, receiver),
71580
71608
  __setterCallStack: innerStack
71581
71609
  },
71582
71610
  value,
@@ -72157,7 +72185,7 @@ function evalPointer(pointer, scope, ctx) {
72157
72185
  try {
72158
72186
  return executeCompiledFunction(
72159
72187
  action,
72160
- { ...ctx, thisValue: innerThis },
72188
+ bindThisValue(ctx, innerThis),
72161
72189
  args,
72162
72190
  runtimeSignature.returnTypeInfo.type === NS_TYPE_VOID,
72163
72191
  runtimeSignature
@@ -72400,7 +72428,7 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver) {
72400
72428
  const runtimeSignature = receiver === null ? signature : substituteCallableSignatureForReceiver(signature, receiver, ctx);
72401
72429
  return executeCompiledFunction(
72402
72430
  action,
72403
- { ...ctx, thisValue: receiver },
72431
+ bindThisValue(ctx, receiver),
72404
72432
  args,
72405
72433
  runtimeSignature.returnTypeInfo.type === NS_TYPE_VOID,
72406
72434
  runtimeSignature
@@ -73070,8 +73098,7 @@ function dispatchNSGetterById(memberId, receiver, ctx) {
73070
73098
  const innerStack = new Set(stack);
73071
73099
  innerStack.add(memberId);
73072
73100
  return evaluateNSGetter(getter, {
73073
- ...ctx,
73074
- thisValue: receiver,
73101
+ ...bindThisValue(ctx, receiver),
73075
73102
  __getterCallStack: innerStack
73076
73103
  });
73077
73104
  }
@@ -75607,7 +75634,7 @@ function runDeclaredConstructorChain(args) {
75607
75634
  args.applyBaseInitializerBlock(record3, args.argumentValues, args.thisValue);
75608
75635
  executeCompiledFunction(
75609
75636
  record3.action,
75610
- { ...ctx, thisValue: args.thisValue },
75637
+ bindThisValue(ctx, args.thisValue),
75611
75638
  args.argumentValues,
75612
75639
  true
75613
75640
  );
@@ -75682,7 +75709,7 @@ function evaluateBaseInitializerFields(args) {
75682
75709
  });
75683
75710
  const value = executeCompiledFunction(
75684
75711
  getter,
75685
- { ...ctx, thisValue: args.thisValue },
75712
+ bindThisValue(ctx, args.thisValue),
75686
75713
  args.argumentValues,
75687
75714
  false
75688
75715
  );
@@ -75923,9 +75950,7 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
75923
75950
  const closeFrame = pushConstructionFrame(ctx, `${member.name} initializer`);
75924
75951
  let result;
75925
75952
  try {
75926
- const initializerCtx = ctx.thisValue === null ? ctx : Object.assign({}, ctx, {
75927
- thisValue: null
75928
- });
75953
+ const initializerCtx = ctx.thisValue === null ? ctx : bindThisValue(ctx, null);
75929
75954
  result = evaluateNSGetterWithEffects(
75930
75955
  compiled,
75931
75956
  initializerCtx,
@@ -77995,13 +78020,13 @@ function ownedObjectChildMember(row, sourceMember, key, ctx) {
77995
78020
  return memberForCustomSchemaValue(classId, key, ctx);
77996
78021
  }
77997
78022
  function freshCloneValueId() {
77998
- const randomUUID6 = globalThis.crypto?.randomUUID;
77999
- if (randomUUID6 === void 0) {
78023
+ const randomUUID7 = globalThis.crypto?.randomUUID;
78024
+ if (randomUUID7 === void 0) {
78000
78025
  throw new NSGetterRuntimeError(
78001
78026
  "Class.Clone cannot mint a value id because crypto.randomUUID is unavailable."
78002
78027
  );
78003
78028
  }
78004
- return randomUUID6.call(globalThis.crypto);
78029
+ return randomUUID7.call(globalThis.crypto);
78005
78030
  }
78006
78031
  function parseDialogueMemoryPointer(pointer) {
78007
78032
  if (typeof pointer !== "string") return null;
@@ -81060,6 +81085,7 @@ var init_evaluateInitializer = __esm({
81060
81085
  "../src/view-models/neoscript-evaluator/evaluateInitializer.ts"() {
81061
81086
  "use strict";
81062
81087
  init_deep_clone_plain_data();
81088
+ init_collections();
81063
81089
  init_instance_provenance();
81064
81090
  init_members();
81065
81091
  init_project2();
@@ -81322,6 +81348,8 @@ var init_init_backed_value_materialization = __esm({
81322
81348
  function materializeDialogues(dialogueRecords, dialogueNodes) {
81323
81349
  return dialogueRecords.map((dialogue) => {
81324
81350
  if (!isRecordWithStringId(dialogue)) return dialogue;
81351
+ const { triggerNodeId: _triggerNodeId, ...dialoguePayload } = dialogue;
81352
+ void _triggerNodeId;
81325
81353
  const nodes = dialogueNodes.filter(
81326
81354
  (node) => getDialogueNodeDialogueId(node) === dialogue.id
81327
81355
  );
@@ -81334,7 +81362,7 @@ function materializeDialogues(dialogueRecords, dialogueNodes) {
81334
81362
  })
81335
81363
  );
81336
81364
  const materializedDialogue = {
81337
- ...dialogue,
81365
+ ...dialoguePayload,
81338
81366
  nodes: bodyNodes,
81339
81367
  triggerNode: triggerNode === null || triggerNode === void 0 ? null : toDialogueNodePayload(triggerNode)
81340
81368
  };
@@ -81547,23 +81575,18 @@ var init_project_record_migrations = __esm({
81547
81575
  var project_document_read_exports = {};
81548
81576
  __export(project_document_read_exports, {
81549
81577
  DOCUMENT_MANIFEST_PAGE_SIZE: () => DOCUMENT_MANIFEST_PAGE_SIZE,
81550
- DOCUMENT_SNAPSHOT_FETCH_CHUNK_SIZE: () => DOCUMENT_SNAPSHOT_FETCH_CHUNK_SIZE,
81551
- DOCUMENT_SNAPSHOT_FETCH_CONCURRENCY: () => DOCUMENT_SNAPSHOT_FETCH_CONCURRENCY,
81552
- appendProjectRecordToBuckets: () => appendProjectRecordToBuckets,
81553
81578
  assembleProjectDocumentRaw: () => assembleProjectDocumentRaw,
81554
- emptyProjectRecordBuckets: () => emptyProjectRecordBuckets,
81555
81579
  fetchProjectDocumentPartitionRecords: () => fetchProjectDocumentPartitionRecords,
81556
81580
  fetchProjectDocumentRawChunked: () => fetchProjectDocumentRawChunked,
81557
81581
  fetchProjectDocumentSnapshots: () => fetchProjectDocumentSnapshots,
81558
81582
  readArrayField: () => readArrayField,
81559
- readField: () => readField,
81560
- readOptionalArrayField: () => readOptionalArrayField,
81561
81583
  readProjectDocument: () => readProjectDocument,
81562
81584
  readProjectDocumentContentHashHeads: () => readProjectDocumentContentHashHeads,
81585
+ readProjectDocumentManifestPage: () => readProjectDocumentManifestPage,
81563
81586
  readProjectDocumentManifestPageRecords: () => readProjectDocumentManifestPageRecords,
81564
81587
  readProjectDocumentManifestRecords: () => readProjectDocumentManifestRecords,
81565
81588
  readProjectDocumentRevisionMarker: () => readProjectDocumentRevisionMarker,
81566
- readStoredMembersField: () => readStoredMembersField
81589
+ withStoredValueBase: () => withStoredValueBase
81567
81590
  });
81568
81591
  async function fetchProjectDocumentRawChunked(runner, options = {}) {
81569
81592
  const mapKeys = options.mapKeys ?? [
@@ -82015,6 +82038,9 @@ function projectDocumentValueBuckets(rows) {
82015
82038
  if (expanded === rows) return { values: rows };
82016
82039
  return { values: [...expanded], physicalValues: rows };
82017
82040
  }
82041
+ function withStoredValueBase(document) {
82042
+ return document.physicalValues === void 0 ? { ...document, physicalValues: document.values } : document;
82043
+ }
82018
82044
  function readProjectDocument(value, options = {}) {
82019
82045
  if (!isObject4(value)) {
82020
82046
  throw new Error("Convex project document query returned a non-object.");
@@ -86377,7 +86403,6 @@ var init_root_source = __esm({
86377
86403
  init_projection();
86378
86404
  init_instance_provenance();
86379
86405
  init_value_sources();
86380
- init_root_value_paths();
86381
86406
  init_source_format();
86382
86407
  init_stored_value_placements();
86383
86408
  ROOT_PROJECT_FIELDS2 = [
@@ -86414,11 +86439,12 @@ function isWorldAnimationStructuralMember(memberId, members) {
86414
86439
  }
86415
86440
  return false;
86416
86441
  }
86417
- function assertAnimationClipDocumentValid(document) {
86442
+ function assertAnimationClipDocumentValid(document, scope) {
86418
86443
  const context = new AnimationValidationContext(document);
86419
- context.validateSegments();
86444
+ context.validateSegments(scope);
86420
86445
  for (const member of document.members) {
86421
86446
  if (!isMemberClass(member)) continue;
86447
+ if (scope !== void 0 && !scope.memberIds.has(member.id)) continue;
86422
86448
  if (!context.classHasWorldKind(member.classId, "animationClip")) continue;
86423
86449
  if (isAbstractMember(member) === true) continue;
86424
86450
  context.validateClipMember(member);
@@ -87011,16 +87037,6 @@ var init_animation_clips = __esm({
87011
87037
  const member = this.envBindingMember(env, paramId);
87012
87038
  return isMemberClass(member) ? member.classId : null;
87013
87039
  }
87014
- classDescendsFrom(classId, baseClassId) {
87015
- const visited = /* @__PURE__ */ new Set();
87016
- let current = this.classById.get(classId);
87017
- while (current !== void 0 && !visited.has(current.id)) {
87018
- if (current.id === baseClassId) return true;
87019
- visited.add(current.id);
87020
- current = current.extendsClassId ? this.classById.get(current.extendsClassId) : void 0;
87021
- }
87022
- return false;
87023
- }
87024
87040
  /**
87025
87041
  * P48 §1 and §7's segment rules, for every segment the document holds.
87026
87042
  *
@@ -87034,10 +87050,11 @@ var init_animation_clips = __esm({
87034
87050
  * files, and Session all hold segments, and a Session-stored `Duration` a
87035
87051
  * game writes at runtime is a feature, not drift.
87036
87052
  */
87037
- validateSegments() {
87053
+ validateSegments(scope) {
87038
87054
  const visited = /* @__PURE__ */ new Set();
87039
87055
  for (const member of this.document.members) {
87040
87056
  if (!isMemberClass(member)) continue;
87057
+ if (scope !== void 0 && !scope.memberIds.has(member.id)) continue;
87041
87058
  if (!this.classHasWorldKind(member.classId, "animationSegment")) continue;
87042
87059
  const node = this.optionalMemberRootNode(member);
87043
87060
  if (node === null) continue;
@@ -87495,13 +87512,6 @@ var init_animation_clips = __esm({
87495
87512
  };
87496
87513
  return isMemberClass(resolvedEntryMember) ? resolvedEntryMember.classId : void 0;
87497
87514
  }
87498
- requireSingleLookupField(parent, classId, memberId, label) {
87499
- const value = this.scalarField(parent, classId, memberId);
87500
- if (!Array.isArray(value) || value.length !== 1 || typeof value[0] !== "string") {
87501
- throw new Error(`${label} must reference exactly one child.`);
87502
- }
87503
- return value[0];
87504
- }
87505
87515
  requirePositiveIntegerField(parent, classId, memberId, label) {
87506
87516
  const value = this.requireIntegerField(parent, classId, memberId, label);
87507
87517
  if (value < 1) throw new Error(`${label} must be at least 1.`);
@@ -87570,10 +87580,6 @@ var init_animation_clips = __esm({
87570
87580
  const bindingMember = binding?.kind === "member" ? this.memberById.get(binding.memberId) : void 0;
87571
87581
  return isMemberClass(bindingMember) ? bindingMember.classId : null;
87572
87582
  }
87573
- requireClassMember(value) {
87574
- if (!isMemberClass(value)) throw new Error("Expected Class member.");
87575
- return value;
87576
- }
87577
87583
  field(classId, requiredMemberId) {
87578
87584
  const entry = mergeStoredInstanceSchema(
87579
87585
  classId,
@@ -88632,7 +88638,7 @@ function storedConstructionEmitters(state, manifest) {
88632
88638
  if (!isObjectRecord2(record3.data)) continue;
88633
88639
  if (!isObjectRecord2(record3.data.value)) continue;
88634
88640
  const constructorArgs = record3.data.constructorArgs;
88635
- const hasInstanceProvenance = carriesStoredInstanceProvenance(record3.data);
88641
+ const hasInstanceProvenance = isVirtualInstanceRootShape(record3.data);
88636
88642
  if (constructorArgs !== void 0 && constructorArgs !== null && !hasInstanceProvenance) {
88637
88643
  continue;
88638
88644
  }
@@ -88731,9 +88737,6 @@ function nearestOwnedAncestor(valueId, parents, owners) {
88731
88737
  }
88732
88738
  return null;
88733
88739
  }
88734
- function carriesStoredInstanceProvenance(value) {
88735
- return isVirtualInstanceRootShape(value);
88736
- }
88737
88740
  function readMaterializedConstructionBuildCacheV2(root, state) {
88738
88741
  try {
88739
88742
  const parsed = JSON.parse(
@@ -88847,44 +88850,61 @@ function transactionImpactsAnyOwnerMember(scope, impactedIds) {
88847
88850
  }
88848
88851
  return false;
88849
88852
  }
88850
- function collectNeoScriptRecompileTargets(args) {
88851
- if (args.forceRecompile === true) return completeTargets(args.postDocument);
88852
- const explicit = explicitTargetIds(args.changes);
88853
- const {
88854
- impactedIds,
88855
- changedValueIds,
88856
- impactedTypeNames,
88857
- constructedClassIds
88858
- } = collectChangedContractIds(args);
88859
- for (const id2 of args.additionalImpactedIds ?? []) impactedIds.add(id2);
88853
+ function collectNeoScriptRecompileImpact(args) {
88854
+ const impact = collectChangedContractIds(args);
88855
+ for (const id2 of args.additionalImpactedIds ?? []) impact.impactedIds.add(id2);
88860
88856
  for (const id2 of args.additionalChangedValueIds ?? []) {
88861
- changedValueIds.add(id2);
88862
- explicit.valueIds.add(id2);
88857
+ impact.changedValueIds.add(id2);
88863
88858
  }
88864
88859
  includeDerivedConstructionContracts(
88865
- constructedClassIds,
88860
+ impact.constructedClassIds,
88866
88861
  args.postDocument.classes
88867
88862
  );
88868
- const schemaRecords = [
88863
+ const dependentsById = /* @__PURE__ */ new Map();
88864
+ for (const record3 of [
88869
88865
  ...collectSchemaDependencyRecords(args.postDocument),
88870
88866
  ...collectStructuralDependencyRecords(args.postDocument)
88871
- ];
88872
- const dependentsById = /* @__PURE__ */ new Map();
88873
- for (const record3 of schemaRecords) {
88867
+ ]) {
88874
88868
  for (const dependencyId of collectCompilerReferenceIds(record3.value)) {
88875
88869
  const dependents = dependentsById.get(dependencyId) ?? [];
88876
88870
  dependents.push(record3);
88877
88871
  dependentsById.set(dependencyId, dependents);
88878
88872
  }
88879
88873
  }
88880
- const queue = [...impactedIds, ...changedValueIds];
88874
+ const queue = [...impact.impactedIds, ...impact.changedValueIds];
88881
88875
  for (let index = 0; index < queue.length; index += 1) {
88882
88876
  const dependencyId = queue[index];
88883
88877
  if (dependencyId === void 0) continue;
88884
88878
  for (const dependent of dependentsById.get(dependencyId) ?? []) {
88885
- addImpactedId(impactedIds, queue, dependent.id);
88879
+ addImpactedId(impact.impactedIds, queue, dependent.id);
88886
88880
  }
88887
88881
  }
88882
+ return impact;
88883
+ }
88884
+ function collectNeoScriptRecompileReferenceTargets(args) {
88885
+ const impact = collectNeoScriptRecompileImpact(args);
88886
+ return {
88887
+ ids: /* @__PURE__ */ new Set([
88888
+ ...impact.impactedIds,
88889
+ ...impact.changedValueIds,
88890
+ ...impact.constructedClassIds
88891
+ ]),
88892
+ names: impact.impactedTypeNames
88893
+ };
88894
+ }
88895
+ function collectNeoScriptRecompileTargets(args) {
88896
+ if (args.forceRecompile === true) return completeTargets(args.postDocument);
88897
+ const explicit = explicitTargetIds(args.changes);
88898
+ const {
88899
+ impactedIds,
88900
+ changedValueIds,
88901
+ impactedTypeNames,
88902
+ constructedClassIds
88903
+ } = collectNeoScriptRecompileImpact(args);
88904
+ for (const id2 of args.additionalChangedValueIds ?? []) {
88905
+ changedValueIds.add(id2);
88906
+ explicit.valueIds.add(id2);
88907
+ }
88888
88908
  const constructorOwnerById = constructorOwners(args.postDocument);
88889
88909
  const gradesSourceOnlyBodies = impactedIds.size > 0 || impactedTypeNames.size > 0;
88890
88910
  const impactScope = {
@@ -89026,7 +89046,9 @@ function collectCompilerReferenceNamesInto(value, field, names) {
89026
89046
  }
89027
89047
  }
89028
89048
  function isCompilerReferenceField(field) {
89029
- return /(?:member|class|enum|interface|constructor)(?:Type)?Ids?$/i.test(field) || field === "baseTypeIds" || field === "collectionValueId" || field === "fileId" || field === "primaryLinkedValueId" || field === "recordIds" || field === "valueId";
89049
+ return /(?:member|class|enum|interface|constructor|variant)(?:Type)?Ids?$/i.test(
89050
+ field
89051
+ ) || field === "baseTypeIds" || field === "collectionValueId" || field === "fileId" || field === "primaryLinkedValueId" || field === "recordIds" || field === "valueId";
89030
89052
  }
89031
89053
  function collectChangedContractIds(args) {
89032
89054
  const impactedIds = /* @__PURE__ */ new Set();
@@ -91029,7 +91051,7 @@ function consumeWorldPlacementSidecarKeys(args) {
91029
91051
  }
91030
91052
  return present;
91031
91053
  }
91032
- var WORLD_PLACEMENT_SIDECAR_KEYS, WORLD_PLACEMENT_SIDECAR_KEY_SET, WORLD_PLACEMENT_ASSET_KIND;
91054
+ var WORLD_PLACEMENT_SIDECAR_KEYS, WORLD_PLACEMENT_ASSET_KIND;
91033
91055
  var init_world_content_sidecar_validation = __esm({
91034
91056
  "../src/models/project/world-content-sidecar-validation.ts"() {
91035
91057
  "use strict";
@@ -91045,9 +91067,6 @@ var init_world_content_sidecar_validation = __esm({
91045
91067
  "assetValueId",
91046
91068
  "variantId"
91047
91069
  ];
91048
- WORLD_PLACEMENT_SIDECAR_KEY_SET = new Set(
91049
- WORLD_PLACEMENT_SIDECAR_KEYS
91050
- );
91051
91070
  WORLD_PLACEMENT_ASSET_KIND = /* @__PURE__ */ new Map([
91052
91071
  [NeoWorldSystemClassKind.TileInstance, NeoWorldSystemClassKind.Tile],
91053
91072
  [NeoWorldSystemClassKind.ObjectPlacementTile, NeoWorldSystemClassKind.Object],
@@ -97524,7 +97543,7 @@ function reconcileDirectOverrideChains(args) {
97524
97543
  }
97525
97544
  }
97526
97545
  }
97527
- function prepareServerOwnedSchemaCommit(args) {
97546
+ function* prepareServerOwnedSchemaCommitPasses(args) {
97528
97547
  if (args.forceRecompile === true) clearNeoScriptBodyCompileCache();
97529
97548
  assertUniqueChanges(args.changes);
97530
97549
  let authoredChanges = completeLocalizedTextCreateEnvelopes({
@@ -97542,7 +97561,8 @@ function prepareServerOwnedSchemaCommit(args) {
97542
97561
  args.document,
97543
97562
  authoredChanges
97544
97563
  ),
97545
- changes: authoredChanges
97564
+ changes: authoredChanges,
97565
+ createTextId: args.createLocalizedTextId
97546
97566
  });
97547
97567
  const explicitlyChangedMemberIds = /* @__PURE__ */ new Set();
97548
97568
  for (const change of authoredChanges) {
@@ -97572,6 +97592,7 @@ function prepareServerOwnedSchemaCommit(args) {
97572
97592
  if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange && !hasAdditionalContractImpact) {
97573
97593
  return authoredChanges;
97574
97594
  }
97595
+ args.passLifecycle?.("start", "neo-script-recompile-targets");
97575
97596
  const authoredPostDocument = applyProjectVersionWriteChanges(
97576
97597
  args.document,
97577
97598
  authoredChanges
@@ -97792,26 +97813,46 @@ function prepareServerOwnedSchemaCommit(args) {
97792
97813
  recompileTargets,
97793
97814
  contentHashHeads: args.contentHashHeads
97794
97815
  });
97816
+ args.passLifecycle?.("complete", "neo-script-recompile-targets");
97817
+ yield {
97818
+ pass: "neo-script-recompile-targets",
97819
+ preparedChanges: prepared
97820
+ };
97795
97821
  const serverMintedBindingMemberIds = /* @__PURE__ */ new Set();
97822
+ args.passLifecycle?.("start", "authored-value-seeds");
97823
+ const seedPostDocument = applyProjectVersionWriteChanges(
97824
+ args.document,
97825
+ prepared
97826
+ );
97796
97827
  const pendingConstructedGraphValidations = materializeAuthoredValueSeeds({
97797
- document: applyProjectVersionWriteChanges(postDocument, prepared),
97828
+ document: seedPostDocument,
97798
97829
  prepared,
97799
97830
  authoredValueSeeds: args.authoredValueSeeds ?? [],
97800
97831
  contentHashHeads: args.contentHashHeads,
97801
- serverMintedBindingMemberIds
97832
+ serverMintedBindingMemberIds,
97833
+ createLocalizedTextId: args.createLocalizedTextId
97802
97834
  });
97803
97835
  prepareServerOwnedValueInitializerBodies({
97804
97836
  document: args.document,
97805
- postDocument,
97837
+ postDocument: seedPostDocument,
97806
97838
  prepared,
97807
97839
  targetIds: recompileTargets.valueIds,
97808
97840
  contentHashHeads: args.contentHashHeads
97809
97841
  });
97842
+ args.passLifecycle?.("complete", "authored-value-seeds");
97843
+ yield { pass: "authored-value-seeds", preparedChanges: prepared };
97844
+ args.passLifecycle?.("start", "variant-child-override-binding-members");
97810
97845
  materializeVariantChildOverrideBindingMembers({
97811
97846
  document: args.document,
97812
97847
  prepared,
97813
97848
  serverMintedBindingMemberIds
97814
97849
  });
97850
+ args.passLifecycle?.("complete", "variant-child-override-binding-members");
97851
+ yield {
97852
+ pass: "variant-child-override-binding-members",
97853
+ preparedChanges: prepared
97854
+ };
97855
+ args.passLifecycle?.("start", "prepared-instance-initializers");
97815
97856
  materializePreparedInstanceInitializers({
97816
97857
  document: args.document,
97817
97858
  prepared,
@@ -97829,13 +97870,22 @@ function prepareServerOwnedSchemaCommit(args) {
97829
97870
  prepared,
97830
97871
  pending: pendingConstructedGraphValidations
97831
97872
  });
97873
+ args.passLifecycle?.("complete", "prepared-instance-initializers");
97874
+ yield {
97875
+ pass: "prepared-instance-initializers",
97876
+ preparedChanges: prepared
97877
+ };
97878
+ args.passLifecycle?.("start", "delegate-value-bodies");
97832
97879
  prepareServerOwnedDelegateValueBodies({
97833
97880
  document: args.document,
97834
- postDocument,
97881
+ postDocument: applyProjectVersionWriteChanges(args.document, prepared),
97835
97882
  prepared,
97836
97883
  targetIds: recompileTargets.valueIds,
97837
97884
  contentHashHeads: args.contentHashHeads
97838
97885
  });
97886
+ args.passLifecycle?.("complete", "delegate-value-bodies");
97887
+ yield { pass: "delegate-value-bodies", preparedChanges: prepared };
97888
+ args.passLifecycle?.("start", "variant-constructor-args");
97839
97889
  reconcileVariantConstructorArgs({
97840
97890
  document: args.document,
97841
97891
  prepared,
@@ -97846,6 +97896,7 @@ function prepareServerOwnedSchemaCommit(args) {
97846
97896
  prepared,
97847
97897
  contentHashHeads: args.contentHashHeads
97848
97898
  });
97899
+ normalizePreparedServerTimestamps(prepared, args.serverTimestamp);
97849
97900
  const committedDocument = applyProjectVersionWriteChanges(
97850
97901
  args.document,
97851
97902
  prepared
@@ -97862,11 +97913,37 @@ function prepareServerOwnedSchemaCommit(args) {
97862
97913
  });
97863
97914
  attachPreparedValuePlacements(physical, committedDocument);
97864
97915
  attachPreparedConstructorAggregateEdges(physical, committedDocument);
97865
- return orderLocalizedTextWritesBesideLinks(
97916
+ const ordered = orderLocalizedTextWritesBesideLinks(
97866
97917
  orderVariantRootValuesWithVariants(
97867
- orderDeclaredMemberCreatesFirst(physical, postDocument)
97918
+ orderDeclaredMemberCreatesFirst(
97919
+ physical,
97920
+ applyProjectVersionWriteChanges(args.document, prepared)
97921
+ )
97868
97922
  )
97869
97923
  );
97924
+ args.passLifecycle?.("complete", "variant-constructor-args");
97925
+ yield { pass: "variant-constructor-args", preparedChanges: ordered };
97926
+ return ordered;
97927
+ }
97928
+ function normalizePreparedServerTimestamps(prepared, serverTimestamp) {
97929
+ if (serverTimestamp === void 0) return;
97930
+ for (const change of prepared) {
97931
+ if (change.operation === "delete" || change.nextData === null || typeof change.nextData !== "object") {
97932
+ continue;
97933
+ }
97934
+ const nextData = change.nextData;
97935
+ if (change.operation === "create" && "createdAt" in nextData) {
97936
+ nextData.createdAt = serverTimestamp;
97937
+ }
97938
+ if ("updatedAt" in nextData) nextData.updatedAt = serverTimestamp;
97939
+ }
97940
+ }
97941
+ function prepareServerOwnedSchemaCommit(args) {
97942
+ const passes = prepareServerOwnedSchemaCommitPasses(args);
97943
+ for (; ; ) {
97944
+ const step = passes.next();
97945
+ if (step.done) return step.value;
97946
+ }
97870
97947
  }
97871
97948
  function orderLocalizedTextWritesBesideLinks(prepared) {
97872
97949
  const indexByLinkKey = /* @__PURE__ */ new Map();
@@ -98791,8 +98868,12 @@ function prepareServerOwnedDialogueBodies(args) {
98791
98868
  explicitNodeIds.add(change.recordId);
98792
98869
  const next = asRecord2(change.nextData);
98793
98870
  const current = currentNodes.get(change.recordId);
98794
- const dialogueId = typeof next?.dialogueId === "string" ? next.dialogueId : typeof current?.dialogueId === "string" ? current.dialogueId : null;
98795
- if (dialogueId !== null) changedDialogueIds.add(dialogueId);
98871
+ if (typeof current?.dialogueId === "string") {
98872
+ changedDialogueIds.add(current.dialogueId);
98873
+ }
98874
+ if (typeof next?.dialogueId === "string") {
98875
+ changedDialogueIds.add(next.dialogueId);
98876
+ }
98796
98877
  continue;
98797
98878
  }
98798
98879
  if (change.recordKind === "dialogue-group") {
@@ -99042,7 +99123,8 @@ function materializeAuthoredValueSeeds(args) {
99042
99123
  pendingGraphValidations,
99043
99124
  memberChange: { index, change },
99044
99125
  member,
99045
- seed
99126
+ seed,
99127
+ createLocalizedTextId: args.createLocalizedTextId
99046
99128
  });
99047
99129
  continue;
99048
99130
  }
@@ -99103,7 +99185,8 @@ function materializeAuthoredValueSeeds(args) {
99103
99185
  // default builder evaluates it immediately, which bypasses both
99104
99186
  // the server-initializer-materialization grouping and the CLI's
99105
99187
  // parity/identity transport for evaluator-created interior rows.
99106
- seed: { ...seed, values: seed.values ?? [] }
99188
+ seed: { ...seed, values: seed.values ?? [] },
99189
+ createLocalizedTextId: args.createLocalizedTextId
99107
99190
  });
99108
99191
  const { createdValues, localizedTexts, storageKeyDeclarations, rootValue } = materialized;
99109
99192
  const ownedValueId = documentIndex.membersById.get(member.id)?.valueId ?? derivedMemberValueId(member.id);
@@ -99513,7 +99596,8 @@ function materializeInstanceDefaultSeed(args) {
99513
99596
  documentIndex: args.documentIndex,
99514
99597
  member: materializationMember,
99515
99598
  seed: { ...args.seed, values: args.seed.values },
99516
- allowExistingRows: args.memberChange === null || args.memberChange.change.operation === "update"
99599
+ allowExistingRows: args.memberChange === null || args.memberChange.change.operation === "update",
99600
+ createLocalizedTextId: args.createLocalizedTextId
99517
99601
  });
99518
99602
  stampCreatedValuesMapKey(createdValues, null);
99519
99603
  applyDeclaredStorageKeyOverrides({
@@ -99717,7 +99801,8 @@ function materializeAuthoredStaticSeed(args) {
99717
99801
  document: args.document,
99718
99802
  member: args.member,
99719
99803
  createdValues,
99720
- seededLocalizedTexts
99804
+ seededLocalizedTexts,
99805
+ createLocalizedTextId: args.createLocalizedTextId
99721
99806
  });
99722
99807
  return {
99723
99808
  rootValue,
@@ -99747,7 +99832,8 @@ function materializeSeedLocalizableStringWrites(args) {
99747
99832
  memberId: args.member.id
99748
99833
  }),
99749
99834
  expectedBaseContentHash: null
99750
- }))
99835
+ })),
99836
+ createTextId: args.createLocalizedTextId
99751
99837
  });
99752
99838
  const createdValuesById = new Map(
99753
99839
  args.createdValues.map((value) => [value.id, value])
@@ -102228,7 +102314,8 @@ function assertProjectVersionWholeGraphWritesValid(args) {
102228
102314
  assertStagedInternalRecordRelationsValid(args.document, projected, changes);
102229
102315
  assertStagedWorldContentLayerBindingsValid(args.document, projected, changes);
102230
102316
  assertAnimationClipDocumentValid(
102231
- materializeDeclarationInitializersForAnimationValidation(projected)
102317
+ materializeDeclarationInitializersForAnimationValidation(projected),
102318
+ args.animationValidationMemberIds === void 0 ? void 0 : { memberIds: args.animationValidationMemberIds }
102232
102319
  );
102233
102320
  if (args.operation === void 0 || !isSystemOwnedProjectVersionOperation(args.operation)) {
102234
102321
  assertProjectVersionSystemProtectedWritesValid({
@@ -102346,7 +102433,7 @@ function valueDematerializationRefusal(args) {
102346
102433
  return null;
102347
102434
  }
102348
102435
  function materializeDeclarationInitializersForAnimationValidation(document) {
102349
- const animationFamilyClassIds = animationFamilyClasses(document);
102436
+ const animationFamilyClassIds = animationFamilyClassKinds(document.classes);
102350
102437
  const initializers = document.values.filter(
102351
102438
  (value) => isInitValueContent(value)
102352
102439
  );
@@ -102520,31 +102607,6 @@ function materializeDeclarationInitializersForAnimationValidation(document) {
102520
102607
  }
102521
102608
  return { ...document, members, values: [...valuesById.values()] };
102522
102609
  }
102523
- function animationFamilyClasses(document) {
102524
- const classes = new Map(document.classes.map((entry) => [entry.id, entry]));
102525
- const animationKinds = new Set(WORLD_SYSTEM_ANIMATION_KINDS);
102526
- const result = /* @__PURE__ */ new Map();
102527
- const resolve5 = (classId, visiting) => {
102528
- const cached = result.get(classId);
102529
- if (cached !== void 0) return cached;
102530
- if (visiting.has(classId)) return false;
102531
- const schemaClass2 = classes.get(classId);
102532
- if (schemaClass2 === void 0) return false;
102533
- const worldKind = schemaClass2.system?.worldKind;
102534
- if (typeof worldKind === "string" && animationKinds.has(worldKind)) {
102535
- result.set(classId, true);
102536
- return true;
102537
- }
102538
- const nextVisiting = new Set(visiting).add(classId);
102539
- const belongs = typeof schemaClass2.extendsClassId === "string" && resolve5(schemaClass2.extendsClassId, nextVisiting);
102540
- result.set(classId, belongs);
102541
- return belongs;
102542
- };
102543
- for (const classId of classes.keys()) resolve5(classId, /* @__PURE__ */ new Set());
102544
- return new Set(
102545
- [...result].flatMap(([classId, belongs]) => belongs ? [classId] : [])
102546
- );
102547
- }
102548
102610
  function containsDirectValueId(value, ids) {
102549
102611
  if (Array.isArray(value)) {
102550
102612
  return value.some((entry) => typeof entry === "string" && ids.has(entry));
@@ -105699,6 +105761,1467 @@ var init_trusted_commit_verification = __esm({
105699
105761
  }
105700
105762
  });
105701
105763
 
105764
+ // ../src/database/project-snapshot-derived-edges.ts
105765
+ function extractProjectSnapshotDerivedEdges(source) {
105766
+ const edges = /* @__PURE__ */ new Map();
105767
+ const add = (edge) => {
105768
+ edges.set(edgeIdentity(edge), edge);
105769
+ };
105770
+ for (const targetKey of collectCompilerReferenceIds(source.data)) {
105771
+ add({
105772
+ edgeKind: "compiled-reference",
105773
+ targetKey,
105774
+ targetAddressing: "record",
105775
+ payloadJson: canonicalJsonStringify({ referenceKind: "record-id" })
105776
+ });
105777
+ }
105778
+ for (const targetKey of collectCompilerReferenceNames(source.data)) {
105779
+ add({
105780
+ edgeKind: "compiled-reference",
105781
+ targetKey,
105782
+ targetAddressing: "record",
105783
+ // neo-terminology-audit: allow-next-line legacy-stable-id -- REJECTS: treating compiler reference metadata as a stable ID.
105784
+ payloadJson: canonicalJsonStringify({ referenceKind: "type-name" })
105785
+ });
105786
+ }
105787
+ for (const targetKey of collectConstructedClassIds(source.data)) {
105788
+ add({
105789
+ edgeKind: "compiled-reference",
105790
+ targetKey,
105791
+ targetAddressing: "record",
105792
+ payloadJson: canonicalJsonStringify({
105793
+ referenceKind: "constructed-class-id"
105794
+ })
105795
+ });
105796
+ }
105797
+ const record3 = asRecord3(source.data);
105798
+ if (source.recordKind === "dialogue-node" && record3 !== null && typeof record3.dialogueId === "string") {
105799
+ add({
105800
+ edgeKind: "dialogue-membership",
105801
+ targetKey: record3.dialogueId,
105802
+ targetAddressing: "record",
105803
+ payloadJson: canonicalJsonStringify({ relation: "dialogue-node" })
105804
+ });
105805
+ }
105806
+ if (source.recordKind === "value" && record3 !== null) {
105807
+ const body = record3.value;
105808
+ if (Array.isArray(body) || asRecord3(body) !== null) {
105809
+ for (const targetKey of collectDirectBodyChildIds(body)) {
105810
+ add({
105811
+ edgeKind: "containment-child",
105812
+ targetKey,
105813
+ targetAddressing: "record",
105814
+ payloadJson: canonicalJsonStringify({
105815
+ relation: "body-child",
105816
+ depth: 1
105817
+ })
105818
+ });
105819
+ }
105820
+ }
105821
+ if (typeof record3.containerId === "string") {
105822
+ add({
105823
+ edgeKind: "containment-child",
105824
+ targetKey: record3.containerId,
105825
+ targetAddressing: "record",
105826
+ payloadJson: canonicalJsonStringify({
105827
+ relation: "container-join",
105828
+ childId: source.recordId
105829
+ })
105830
+ });
105831
+ }
105832
+ addStampBindingEdges(record3.genericBindings, add);
105833
+ addPackedChildEdges(source, record3, add);
105834
+ }
105835
+ for (const edge of source.constructorAggregateEdges ?? []) {
105836
+ if (edge.ownerValueId !== source.recordId) {
105837
+ throw new Error(
105838
+ `Constructor aggregate edge owner "${edge.ownerValueId}" does not match snapshot record "${source.recordId}".`
105839
+ );
105840
+ }
105841
+ add({
105842
+ edgeKind: "constructor-aggregate",
105843
+ targetKey: edge.targetValueId,
105844
+ targetAddressing: "record",
105845
+ payloadJson: canonicalJsonStringify({
105846
+ parameterId: edge.parameterId,
105847
+ typeInfo: edge.typeInfo
105848
+ })
105849
+ });
105850
+ }
105851
+ const constructorArgs = record3 === null ? null : asRecord3(record3.constructorArgs);
105852
+ return {
105853
+ edges: [...edges.values()].sort(compareEdges),
105854
+ complete: constructorArgs === null || Object.keys(constructorArgs).length === 0 || source.constructorAggregateEdges !== void 0
105855
+ };
105856
+ }
105857
+ function addStampBindingEdges(genericBindings, add) {
105858
+ const bindings = asRecord3(genericBindings);
105859
+ if (bindings === null) return;
105860
+ for (const [parameterId, stampedMemberId] of Object.entries(bindings)) {
105861
+ if (typeof stampedMemberId !== "string") continue;
105862
+ add({
105863
+ edgeKind: "stamp-binding",
105864
+ targetKey: stampedMemberId,
105865
+ targetAddressing: "record",
105866
+ payloadJson: canonicalJsonStringify({ parameterId, stampedMemberId })
105867
+ });
105868
+ }
105869
+ }
105870
+ function addPackedChildEdges(source, record3, add) {
105871
+ if (!rowCarriesPackedValueContent(record3)) return;
105872
+ if (!isMemberValue(source.data)) {
105873
+ throw new Error(
105874
+ `Value snapshot "${source.recordId}" stores packed children but is not a complete value row, so their positions cannot be addressed.`
105875
+ );
105876
+ }
105877
+ for (const position of packedValuePositions(source.data)) {
105878
+ add({
105879
+ edgeKind: "containment-child",
105880
+ targetKey: projectSnapshotDerivedPathTargetKey({
105881
+ recordId: source.recordId,
105882
+ path: position.path
105883
+ }),
105884
+ targetAddressing: "path",
105885
+ payloadJson: canonicalJsonStringify({
105886
+ relation: "packed-child",
105887
+ childId: position.valueId
105888
+ })
105889
+ });
105890
+ addStampBindingEdges(position.entry.genericBindings, add);
105891
+ }
105892
+ }
105893
+ function projectSnapshotDerivedPathTargetKey(args) {
105894
+ return canonicalJsonStringify({ recordId: args.recordId, path: args.path });
105895
+ }
105896
+ function projectSnapshotDerivedEdgeIdentity(edge) {
105897
+ return edgeIdentity(edge);
105898
+ }
105899
+ function edgeIdentity(edge) {
105900
+ return canonicalJsonStringify([
105901
+ edge.edgeKind,
105902
+ edge.targetAddressing,
105903
+ edge.targetKey,
105904
+ edge.payloadJson
105905
+ ]);
105906
+ }
105907
+ function compareEdges(left, right) {
105908
+ return edgeIdentity(left).localeCompare(edgeIdentity(right));
105909
+ }
105910
+ function collectDirectBodyChildIds(value) {
105911
+ const candidates = Array.isArray(value) ? value : Object.values(asRecord3(value) ?? {});
105912
+ return [
105913
+ ...new Set(
105914
+ candidates.filter(
105915
+ (candidate) => typeof candidate === "string" && STORED_PROJECT_RECORD_ID_PATTERN.test(candidate)
105916
+ )
105917
+ )
105918
+ ];
105919
+ }
105920
+ function asRecord3(value) {
105921
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
105922
+ }
105923
+ var PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION, STORED_PROJECT_RECORD_ID_PATTERN;
105924
+ var init_project_snapshot_derived_edges = __esm({
105925
+ "../src/database/project-snapshot-derived-edges.ts"() {
105926
+ "use strict";
105927
+ init_canonical_json();
105928
+ init_neo_script_recompile_scope();
105929
+ init_member_kinds();
105930
+ init_packed_value_encoding();
105931
+ PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION = 4;
105932
+ STORED_PROJECT_RECORD_ID_PATTERN = /^(?:system_)?[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
105933
+ }
105934
+ });
105935
+
105936
+ // ../src/database/commit-preparation-scope-planner.ts
105937
+ function nextCommitPreparationPass(completed) {
105938
+ const index = COMMIT_PREPARATION_PASS_ORDER.indexOf(completed);
105939
+ return COMMIT_PREPARATION_PASS_ORDER[index + 1] ?? null;
105940
+ }
105941
+ var COMMIT_PREPARATION_PROJECTED_BUCKETS, COMMIT_PREPARATION_PASS_ORDER, COMMIT_PREPARATION_CLOSURE_SPECS;
105942
+ var init_commit_preparation_scope_planner = __esm({
105943
+ "../src/database/commit-preparation-scope-planner.ts"() {
105944
+ "use strict";
105945
+ COMMIT_PREPARATION_PROJECTED_BUCKETS = [
105946
+ "project",
105947
+ "members",
105948
+ "classes",
105949
+ "constructors",
105950
+ "variants",
105951
+ "variantFolders",
105952
+ "enums",
105953
+ "interfaces",
105954
+ "internalRecordRelations",
105955
+ "projectFiles",
105956
+ "textureTemplates",
105957
+ "audioClipTemplates",
105958
+ "dialogues",
105959
+ "dialogueRecords",
105960
+ "dialogueGroups",
105961
+ "values",
105962
+ "dialogueNodes",
105963
+ "migrations"
105964
+ ];
105965
+ COMMIT_PREPARATION_PASS_ORDER = [
105966
+ "neo-script-recompile-targets",
105967
+ "authored-value-seeds",
105968
+ "variant-child-override-binding-members",
105969
+ "prepared-instance-initializers",
105970
+ "delegate-value-bodies",
105971
+ "variant-constructor-args"
105972
+ ];
105973
+ COMMIT_PREPARATION_CLOSURE_SPECS = {
105974
+ "neo-script-recompile-targets": {
105975
+ order: 1,
105976
+ entryPoint: "collectNeoScriptRecompileTargets",
105977
+ synthesizes: "recompile updates",
105978
+ // The one pass that does not rebuild a post-document — its caller hands it
105979
+ // both sides — so it is not held to the projection's bucket set.
105980
+ reads: [
105981
+ "project",
105982
+ "members",
105983
+ "classes",
105984
+ "constructors",
105985
+ "variants",
105986
+ "variantFolders",
105987
+ "enums",
105988
+ "interfaces",
105989
+ "values",
105990
+ "dialogues",
105991
+ "dialogueRecords",
105992
+ "dialogueGroups",
105993
+ "dialogueNodes",
105994
+ "migrations"
105995
+ ],
105996
+ closureRules: [
105997
+ "change-targets",
105998
+ "ancestor-paths",
105999
+ "animation-graph-closure",
106000
+ "member-default-value-closure",
106001
+ "compiled-reference-reverse-index",
106002
+ "dialogue-membership-peers",
106003
+ "every-variant-root",
106004
+ "localizable-reference-candidates",
106005
+ "source-only-rows",
106006
+ "whole-graph-validation-members",
106007
+ "world-value-ranges"
106008
+ ],
106009
+ mutatesDocument: []
106010
+ },
106011
+ "authored-value-seeds": {
106012
+ order: 2,
106013
+ entryPoint: "materializeAuthoredValueSeeds",
106014
+ synthesizes: "seed value rows, localized texts",
106015
+ // The one pass that reads the localization buckets: a static seed mints
106016
+ // localized texts, and the mint reads the project's localization config.
106017
+ reads: [
106018
+ ...COMMIT_PREPARATION_PROJECTED_BUCKETS,
106019
+ "localizationConfig",
106020
+ "localizedTexts"
106021
+ ],
106022
+ closureRules: [
106023
+ "change-targets",
106024
+ "ancestor-paths",
106025
+ "animation-graph-closure",
106026
+ "authored-seed-requested-ids",
106027
+ "member-default-value-closure",
106028
+ "every-variant-root",
106029
+ "localizable-reference-candidates",
106030
+ "world-value-ranges"
106031
+ ],
106032
+ // `materializeStaticSeedBindingMembers` pushes the binding member it mints
106033
+ // into the document the rest of this pass reads, not only into `prepared`.
106034
+ mutatesDocument: ["members"]
106035
+ },
106036
+ "variant-child-override-binding-members": {
106037
+ order: 3,
106038
+ entryPoint: "materializeVariantChildOverrideBindingMembers",
106039
+ synthesizes: "binding members",
106040
+ reads: [...COMMIT_PREPARATION_PROJECTED_BUCKETS],
106041
+ closureRules: [
106042
+ "change-targets",
106043
+ "ancestor-paths",
106044
+ "animation-graph-closure",
106045
+ "descendants",
106046
+ "member-default-value-closure",
106047
+ "every-variant-root",
106048
+ "stamp-edge-candidates",
106049
+ "world-value-ranges"
106050
+ ],
106051
+ // The minted binding member is pushed straight into the document the
106052
+ // later passes read, not only into `prepared`.
106053
+ mutatesDocument: ["members"]
106054
+ },
106055
+ "prepared-instance-initializers": {
106056
+ order: 4,
106057
+ entryPoint: "materializePreparedInstanceInitializers",
106058
+ synthesizes: "created value rows from evaluation",
106059
+ reads: [...COMMIT_PREPARATION_PROJECTED_BUCKETS],
106060
+ closureRules: [
106061
+ "change-targets",
106062
+ "every-variant-root",
106063
+ "full-content-dimension",
106064
+ "member-default-value-closure",
106065
+ "world-value-ranges"
106066
+ ],
106067
+ mutatesDocument: []
106068
+ },
106069
+ "delegate-value-bodies": {
106070
+ order: 5,
106071
+ entryPoint: "prepareServerOwnedDelegateValueBodies",
106072
+ synthesizes: "delegate-body rewrites",
106073
+ reads: [...COMMIT_PREPARATION_PROJECTED_BUCKETS],
106074
+ closureRules: [
106075
+ "change-targets",
106076
+ "ancestor-paths",
106077
+ "animation-graph-closure",
106078
+ "descendants",
106079
+ "member-default-value-closure",
106080
+ "every-variant-root",
106081
+ "source-only-rows",
106082
+ "world-value-ranges"
106083
+ ],
106084
+ mutatesDocument: []
106085
+ },
106086
+ "variant-constructor-args": {
106087
+ order: 6,
106088
+ entryPoint: "reconcileVariantConstructorArgs",
106089
+ synthesizes: "constructor-arg updates",
106090
+ reads: [...COMMIT_PREPARATION_PROJECTED_BUCKETS],
106091
+ closureRules: [
106092
+ "change-targets",
106093
+ "every-variant-root",
106094
+ "touched-variant-schema-key-children",
106095
+ "member-default-value-closure",
106096
+ "world-value-ranges"
106097
+ ],
106098
+ mutatesDocument: []
106099
+ }
106100
+ };
106101
+ }
106102
+ });
106103
+
106104
+ // ../src/database/commit-preparation-animation-scope.ts
106105
+ function commitPreparationAnimationSchema(document) {
106106
+ const classesById2 = new Map(
106107
+ document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
106108
+ );
106109
+ const rootKindByClassId = /* @__PURE__ */ new Map();
106110
+ for (const classId of animationFamilyClassKinds(document.classes).keys()) {
106111
+ const visited = /* @__PURE__ */ new Set();
106112
+ let current = classesById2.get(classId);
106113
+ while (current !== void 0 && !visited.has(current.id)) {
106114
+ visited.add(current.id);
106115
+ const worldKind = current.system?.worldKind;
106116
+ if (worldKind !== void 0 && ANIMATION_ROOT_KINDS.has(worldKind)) {
106117
+ rootKindByClassId.set(classId, worldKind);
106118
+ break;
106119
+ }
106120
+ current = typeof current.extendsClassId === "string" ? classesById2.get(current.extendsClassId) : void 0;
106121
+ }
106122
+ }
106123
+ const rootMemberIds2 = /* @__PURE__ */ new Set();
106124
+ for (const member of document.members) {
106125
+ if (isMemberClass(member) && rootKindByClassId.has(member.classId)) {
106126
+ rootMemberIds2.add(member.id);
106127
+ }
106128
+ }
106129
+ const segmentClassIds = /* @__PURE__ */ new Set();
106130
+ for (const [classId, worldKind] of rootKindByClassId) {
106131
+ if (worldKind === NeoWorldSystemClassKind.AnimationSegment) {
106132
+ segmentClassIds.add(classId);
106133
+ }
106134
+ }
106135
+ return { rootMemberIds: rootMemberIds2, segmentClassIds };
106136
+ }
106137
+ function isAnimationSegmentValueRow(data, schema) {
106138
+ if (data === null || typeof data !== "object") return false;
106139
+ const classId = Reflect.get(data, "classId");
106140
+ return typeof classId === "string" && schema.segmentClassIds.has(classId);
106141
+ }
106142
+ function animationClipMemberIdsTargetingClasses(document, classIds, schema) {
106143
+ if (classIds.size === 0) return [];
106144
+ const classesById2 = new Map(
106145
+ document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
106146
+ );
106147
+ const membersById2 = new Map(
106148
+ document.members.map((member) => [member.id, member])
106149
+ );
106150
+ const descendsFromChanged = (classId) => {
106151
+ const visited = /* @__PURE__ */ new Set();
106152
+ let current = classesById2.get(classId);
106153
+ while (current !== void 0 && !visited.has(current.id)) {
106154
+ if (classIds.has(current.id)) return true;
106155
+ visited.add(current.id);
106156
+ current = typeof current.extendsClassId === "string" ? classesById2.get(current.extendsClassId) : void 0;
106157
+ }
106158
+ return false;
106159
+ };
106160
+ const result = [];
106161
+ for (const member of document.members) {
106162
+ if (!isMemberClass(member)) continue;
106163
+ if (!schema.rootMemberIds.has(member.id)) continue;
106164
+ const binding = resolveInstanceEnv(
106165
+ member.classId,
106166
+ member.classArguments,
106167
+ document.classes
106168
+ ).get(WORLD_ANIMATION_CLIP_TARGET_PARAM_ID);
106169
+ const bindingMember = binding?.kind === "member" ? membersById2.get(binding.memberId) : void 0;
106170
+ if (!isMemberClass(bindingMember)) continue;
106171
+ if (descendsFromChanged(bindingMember.classId)) result.push(member.id);
106172
+ }
106173
+ return result;
106174
+ }
106175
+ var ANIMATION_ROOT_KINDS;
106176
+ var init_commit_preparation_animation_scope = __esm({
106177
+ "../src/database/commit-preparation-animation-scope.ts"() {
106178
+ "use strict";
106179
+ init_core();
106180
+ init_member_kinds();
106181
+ init_generics();
106182
+ init_world_system_classes();
106183
+ ANIMATION_ROOT_KINDS = /* @__PURE__ */ new Set([
106184
+ NeoWorldSystemClassKind.AnimationClip,
106185
+ NeoWorldSystemClassKind.AnimationSegment
106186
+ ]);
106187
+ }
106188
+ });
106189
+
106190
+ // ../src/database/project-commit-preparation-scoped-loader.ts
106191
+ function overlayPlanningRows(rows, recordKind, changes) {
106192
+ const result = new Map((rows ?? []).map((row) => [row.id, row]));
106193
+ for (const change of changes) {
106194
+ if (change.recordKind !== recordKind) continue;
106195
+ if (change.operation === "delete" || change.nextData === null) {
106196
+ result.delete(change.recordId);
106197
+ } else {
106198
+ result.set(change.recordId, change.nextData);
106199
+ }
106200
+ }
106201
+ return [...result.values()];
106202
+ }
106203
+ function overlayPlanningDocument(document, changes) {
106204
+ const projectChange = changes.findLast(
106205
+ (change) => change.recordKind === "project" && change.operation !== "delete" && change.nextData !== null
106206
+ );
106207
+ return {
106208
+ ...document,
106209
+ project: projectChange?.nextData ?? document.project,
106210
+ members: overlayPlanningRows(document.members, "member", changes),
106211
+ classes: overlayPlanningRows(document.classes, "class", changes),
106212
+ constructors: overlayPlanningRows(
106213
+ document.constructors,
106214
+ "constructor",
106215
+ changes
106216
+ ),
106217
+ variants: overlayPlanningRows(document.variants, "variant", changes),
106218
+ variantFolders: overlayPlanningRows(
106219
+ document.variantFolders,
106220
+ "variant-folder",
106221
+ changes
106222
+ ),
106223
+ enums: overlayPlanningRows(document.enums, "enum", changes),
106224
+ interfaces: overlayPlanningRows(document.interfaces, "interface", changes),
106225
+ values: overlayPlanningRows(document.values, "value", changes),
106226
+ dialogues: overlayPlanningRows(document.dialogues, "dialogue", changes),
106227
+ dialogueGroups: overlayPlanningRows(
106228
+ document.dialogueGroups,
106229
+ "dialogue-group",
106230
+ changes
106231
+ ),
106232
+ dialogueNodes: overlayPlanningRows(
106233
+ document.dialogueNodes,
106234
+ "dialogue-node",
106235
+ changes
106236
+ ),
106237
+ migrations: overlayPlanningRows(document.migrations, "migration", changes),
106238
+ localizedTexts: overlayPlanningRows(
106239
+ document.localizedTexts,
106240
+ "localized-text",
106241
+ changes
106242
+ )
106243
+ };
106244
+ }
106245
+ function worldKindByClassId(document) {
106246
+ const classes = new Map(
106247
+ document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
106248
+ );
106249
+ const result = /* @__PURE__ */ new Map();
106250
+ const resolve5 = (classId, visiting) => {
106251
+ if (result.has(classId)) return result.get(classId);
106252
+ if (visiting.has(classId)) return void 0;
106253
+ const schemaClass2 = classes.get(classId);
106254
+ if (schemaClass2 === void 0) return void 0;
106255
+ const own = schemaClass2.system?.worldKind;
106256
+ const resolved = typeof own === "string" ? own : schemaClass2.extendsClassId === void 0 ? void 0 : resolve5(schemaClass2.extendsClassId, new Set(visiting).add(classId));
106257
+ result.set(classId, resolved);
106258
+ return resolved;
106259
+ };
106260
+ for (const classId of classes.keys()) resolve5(classId, /* @__PURE__ */ new Set());
106261
+ return result;
106262
+ }
106263
+ function valueWorldKind(kinds, value) {
106264
+ if (value === null || typeof value !== "object") return void 0;
106265
+ const classId = Reflect.get(value, "classId");
106266
+ return typeof classId === "string" ? kinds.get(classId) : void 0;
106267
+ }
106268
+ function hasWorldLayerOverride(value) {
106269
+ if (value === null || typeof value !== "object") return false;
106270
+ const body = Reflect.get(value, "value");
106271
+ return body !== null && typeof body === "object" && typeof Reflect.get(body, "layerOverrideValueId") === "string";
106272
+ }
106273
+ function commitPreparationWorldScopeKinds(args) {
106274
+ const allKinds = new Set(
106275
+ args.postDocument.classes.flatMap(
106276
+ (schemaClass2) => typeof schemaClass2.system?.worldKind === "string" ? [schemaClass2.system.worldKind] : []
106277
+ )
106278
+ );
106279
+ if (args.changes.some((change) => change.recordKind === "class")) {
106280
+ return allKinds;
106281
+ }
106282
+ const kindsByClass = worldKindByClassId(args.postDocument);
106283
+ const current = projectDocumentRecordsByKey(args.currentDocument);
106284
+ const requiresWholeWorld = args.changes.some((change) => {
106285
+ if (change.recordKind !== "value") return false;
106286
+ const prior = current.get(commitPreparationRecordKey(change));
106287
+ return [prior, change.nextData].some((candidate) => {
106288
+ const worldKind = valueWorldKind(kindsByClass, candidate);
106289
+ return hasWorldLayerOverride(candidate) || worldKind === NeoWorldSystemClassKind.TileLayerLink || worldKind === NeoWorldSystemClassKind.ObjectLayerLink;
106290
+ });
106291
+ });
106292
+ return requiresWholeWorld ? allKinds : /* @__PURE__ */ new Set();
106293
+ }
106294
+ function commitPreparationMemberDefaultValueScope(args) {
106295
+ const exactValueIds = /* @__PURE__ */ new Set();
106296
+ const descendantValueIds = /* @__PURE__ */ new Set();
106297
+ const membersById2 = new Map(
106298
+ args.postDocument.members.map((member) => [member.id, member])
106299
+ );
106300
+ const classesById2 = new Map(
106301
+ args.postDocument.classes.map((schemaClass2) => [
106302
+ schemaClass2.id,
106303
+ schemaClass2
106304
+ ])
106305
+ );
106306
+ const visitedMemberIds = /* @__PURE__ */ new Set();
106307
+ const visitedClassIds = /* @__PURE__ */ new Set();
106308
+ const rememberDefaultIds = (value, descendants) => {
106309
+ for (const valueId of collectStoredRecordIds(value)) {
106310
+ exactValueIds.add(valueId);
106311
+ if (descendants) descendantValueIds.add(valueId);
106312
+ }
106313
+ };
106314
+ function visitMember(memberId) {
106315
+ if (visitedMemberIds.has(memberId)) return;
106316
+ visitedMemberIds.add(memberId);
106317
+ const rawMember = membersById2.get(memberId);
106318
+ if (rawMember === void 0) return;
106319
+ const member = resolveMember2(rawMember, args.postDocument.members);
106320
+ rememberDefaultIds(member.defaultValue, true);
106321
+ if (!isMemberClassBase(member)) return;
106322
+ const defaultClassId = Reflect.get(member.defaultValue ?? {}, "classId");
106323
+ visitClass(
106324
+ typeof defaultClassId === "string" ? defaultClassId : member.classId
106325
+ );
106326
+ }
106327
+ function visitClass(classId) {
106328
+ if (visitedClassIds.has(classId)) return;
106329
+ visitedClassIds.add(classId);
106330
+ if (!classesById2.has(classId)) return;
106331
+ for (const entry of mergeStoredInstanceSchema(
106332
+ classId,
106333
+ args.postDocument.classes,
106334
+ args.postDocument.members
106335
+ )) {
106336
+ visitMember(entry.memberId);
106337
+ }
106338
+ }
106339
+ for (const member of [
106340
+ ...args.currentDocument.members,
106341
+ ...args.postDocument.members
106342
+ ]) {
106343
+ rememberDefaultIds(member.defaultValue, false);
106344
+ }
106345
+ for (const seed of args.authoredValueSeeds) {
106346
+ visitMember(seed.memberId);
106347
+ if ("classId" in seed && typeof seed.classId === "string") {
106348
+ visitClass(seed.classId);
106349
+ }
106350
+ for (const row of seed.values ?? []) {
106351
+ visitMember(row.memberId);
106352
+ if ("classId" in row && typeof row.classId === "string") {
106353
+ visitClass(row.classId);
106354
+ }
106355
+ }
106356
+ }
106357
+ for (const change of args.changes) {
106358
+ if (change.recordKind === "member") {
106359
+ visitMember(change.recordId);
106360
+ const currentMember = args.currentDocument.members.find(
106361
+ (member) => member.id === change.recordId
106362
+ );
106363
+ if (currentMember !== void 0) {
106364
+ rememberDefaultIds(currentMember.defaultValue, true);
106365
+ }
106366
+ }
106367
+ if (change.recordKind === "value" && change.nextData !== null && typeof change.nextData === "object") {
106368
+ const classId = Reflect.get(change.nextData, "classId");
106369
+ if (typeof classId === "string") visitClass(classId);
106370
+ }
106371
+ }
106372
+ return { exactValueIds, descendantValueIds };
106373
+ }
106374
+ function planCommitPreparationInitialScope(args) {
106375
+ const rules = new Set(
106376
+ COMMIT_PREPARATION_CLOSURE_SPECS[args.pass].closureRules
106377
+ );
106378
+ const currentDocument = overlayPlanningDocument(args.document, []);
106379
+ const postDocument = overlayPlanningDocument(currentDocument, args.changes);
106380
+ const exactRecords = /* @__PURE__ */ new Map();
106381
+ const descendantRecords = /* @__PURE__ */ new Map();
106382
+ const rememberExact = (recordKind, recordId, includeDescendants = false) => {
106383
+ const record3 = { recordKind, recordId };
106384
+ const key = commitPreparationRecordKey(record3);
106385
+ exactRecords.set(key, record3);
106386
+ if (includeDescendants) descendantRecords.set(key, record3);
106387
+ };
106388
+ for (const change of args.changes) {
106389
+ rememberExact(change.recordKind, change.recordId, true);
106390
+ if (change.recordKind === "member") {
106391
+ rememberExact("value", derivedMemberValueId(change.recordId), true);
106392
+ const current = args.document.members.find(
106393
+ (member) => member.id === change.recordId
106394
+ );
106395
+ for (const candidate of [current, change.nextData]) {
106396
+ if (candidate === null || typeof candidate !== "object") continue;
106397
+ const valueId = Reflect.get(candidate, "valueId");
106398
+ if (typeof valueId === "string") rememberExact("value", valueId, true);
106399
+ }
106400
+ }
106401
+ for (const valueId of collectStoredRecordIds(change.nextData)) {
106402
+ rememberExact("value", valueId, true);
106403
+ }
106404
+ if (change.nextData !== null && typeof change.nextData === "object") {
106405
+ const candidate = change.recordKind === "member" && isMemberStringBase(change.nextData) && isLocalizedStringMember(change.nextData) ? Reflect.get(change.nextData, "defaultValue") : change.recordKind === "value" ? Reflect.get(change.nextData, "value") : void 0;
106406
+ const localizedTextId = candidate !== null && typeof candidate === "object" && typeof Reflect.get(candidate, "value") === "string" ? Reflect.get(candidate, "value") : candidate;
106407
+ if (typeof localizedTextId === "string") {
106408
+ rememberExact("localized-text", localizedTextId);
106409
+ }
106410
+ }
106411
+ }
106412
+ const memberById2 = new Map(
106413
+ postDocument.members.flatMap((member) => {
106414
+ const id2 = Reflect.get(member, "id");
106415
+ return typeof id2 === "string" ? [[id2, member]] : [];
106416
+ })
106417
+ );
106418
+ const rememberSeedLocalizedTextCandidate = (memberId, body) => {
106419
+ const member = memberById2.get(memberId);
106420
+ if (member === void 0 || !isMemberStringBase(member) || !isLocalizedStringMember(member) || typeof body !== "string") {
106421
+ return;
106422
+ }
106423
+ rememberExact("localized-text", body);
106424
+ };
106425
+ if (rules.has("authored-seed-requested-ids")) {
106426
+ for (const seed of args.authoredValueSeeds) {
106427
+ if (seed.valueId !== void 0) {
106428
+ rememberExact("value", seed.valueId);
106429
+ }
106430
+ rememberSeedLocalizedTextCandidate(
106431
+ seed.memberId,
106432
+ Reflect.get(seed, "value")
106433
+ );
106434
+ for (const row of seed.values ?? []) {
106435
+ rememberExact("value", row.id);
106436
+ rememberSeedLocalizedTextCandidate(
106437
+ row.memberId,
106438
+ Reflect.get(row, "value")
106439
+ );
106440
+ }
106441
+ for (const localizedText of seed.localizedTexts ?? []) {
106442
+ rememberExact("localized-text", localizedText.id);
106443
+ }
106444
+ for (const valueId of collectStoredRecordIds(seed)) {
106445
+ rememberExact("value", valueId);
106446
+ }
106447
+ }
106448
+ }
106449
+ if (rules.has("member-default-value-closure")) {
106450
+ const defaultScope = commitPreparationMemberDefaultValueScope({
106451
+ currentDocument,
106452
+ postDocument,
106453
+ changes: args.changes,
106454
+ authoredValueSeeds: args.authoredValueSeeds
106455
+ });
106456
+ for (const valueId of defaultScope.exactValueIds) {
106457
+ rememberExact(
106458
+ "value",
106459
+ valueId,
106460
+ defaultScope.descendantValueIds.has(valueId)
106461
+ );
106462
+ }
106463
+ }
106464
+ if (rules.has("every-variant-root")) {
106465
+ for (const variant of postDocument.variants ?? []) {
106466
+ rememberExact("value", variant.valueId);
106467
+ }
106468
+ for (const folder of postDocument.variantFolders ?? []) {
106469
+ const collectionValueId = Reflect.get(
106470
+ folder,
106471
+ "collectionValueId"
106472
+ );
106473
+ if (typeof collectionValueId === "string") {
106474
+ rememberExact("value", collectionValueId);
106475
+ }
106476
+ }
106477
+ }
106478
+ if (rules.has("touched-variant-schema-key-children")) {
106479
+ const valuesById = new Map(
106480
+ postDocument.values.map((value) => [value.id, value])
106481
+ );
106482
+ for (const variant of postDocument.variants ?? []) {
106483
+ const root = valuesById.get(variant.valueId);
106484
+ const body = root?.value;
106485
+ if (body === null || typeof body !== "object") continue;
106486
+ for (const schemaKey of [
106487
+ NEO_VARIANT_INITIALIZE_SCHEMA_KEY,
106488
+ NEO_VARIANT_APPLY_SCHEMA_KEY,
106489
+ NEO_VARIANT_OVERRIDES_SCHEMA_KEY,
106490
+ NEO_VARIANT_CHILD_OVERRIDES_SCHEMA_KEY
106491
+ ]) {
106492
+ const childId = Reflect.get(body, schemaKey);
106493
+ if (typeof childId === "string") rememberExact("value", childId);
106494
+ }
106495
+ }
106496
+ }
106497
+ const ranges = [];
106498
+ if (rules.has("source-only-rows")) {
106499
+ ranges.push({
106500
+ rangeKind: "source-only",
106501
+ targetKey: "true",
106502
+ limit: Math.min(
106503
+ args.rangeLimit,
106504
+ COMMIT_PREPARATION_SCOPE_SOURCE_ONLY_ROW_LIMIT
106505
+ )
106506
+ });
106507
+ }
106508
+ const valueOwnerMemberIds = /* @__PURE__ */ new Set();
106509
+ const animationValidationMemberIds = /* @__PURE__ */ new Set();
106510
+ if (rules.has("whole-graph-validation-members")) {
106511
+ for (const memberId of commitPreparationValidationCandidateMemberIds(
106512
+ postDocument
106513
+ )) {
106514
+ valueOwnerMemberIds.add(memberId);
106515
+ }
106516
+ for (const change of args.changes) {
106517
+ if (change.recordKind === "member") {
106518
+ valueOwnerMemberIds.add(change.recordId);
106519
+ }
106520
+ }
106521
+ const animationSchema = commitPreparationAnimationSchema(postDocument);
106522
+ const declaringClassIdsByMemberId = /* @__PURE__ */ new Map();
106523
+ for (const schemaClass2 of postDocument.classes) {
106524
+ for (const memberId of Object.values(schemaClass2.schema)) {
106525
+ const declaring = declaringClassIdsByMemberId.get(memberId) ?? [];
106526
+ declaring.push(schemaClass2.id);
106527
+ declaringClassIdsByMemberId.set(memberId, declaring);
106528
+ }
106529
+ }
106530
+ const changedClassIds = /* @__PURE__ */ new Set();
106531
+ for (const change of args.changes) {
106532
+ if (change.recordKind === "class") changedClassIds.add(change.recordId);
106533
+ if (change.recordKind !== "member") continue;
106534
+ if (animationSchema.rootMemberIds.has(change.recordId)) {
106535
+ animationValidationMemberIds.add(change.recordId);
106536
+ }
106537
+ for (const classId of declaringClassIdsByMemberId.get(change.recordId) ?? []) {
106538
+ changedClassIds.add(classId);
106539
+ }
106540
+ }
106541
+ for (const seed of args.authoredValueSeeds) {
106542
+ if (animationSchema.rootMemberIds.has(seed.memberId)) {
106543
+ animationValidationMemberIds.add(seed.memberId);
106544
+ }
106545
+ }
106546
+ for (const memberId of animationClipMemberIdsTargetingClasses(
106547
+ postDocument,
106548
+ changedClassIds,
106549
+ animationSchema
106550
+ )) {
106551
+ rememberExact("member", memberId, true);
106552
+ animationValidationMemberIds.add(memberId);
106553
+ }
106554
+ }
106555
+ for (const memberId of valueOwnerMemberIds) {
106556
+ ranges.push({
106557
+ rangeKind: "value-member",
106558
+ targetKey: memberId,
106559
+ limit: args.rangeLimit
106560
+ });
106561
+ }
106562
+ if (rules.has("world-value-ranges")) {
106563
+ for (const worldKind of commitPreparationWorldScopeKinds({
106564
+ currentDocument,
106565
+ postDocument,
106566
+ changes: args.changes
106567
+ })) {
106568
+ ranges.push({
106569
+ rangeKind: "world-kind",
106570
+ targetKey: worldKind,
106571
+ limit: args.rangeLimit
106572
+ });
106573
+ }
106574
+ }
106575
+ const postingKeys = /* @__PURE__ */ new Map();
106576
+ const rememberPosting = (edgeKind, targetKey) => {
106577
+ const request = { edgeKind, targetKey, limit: args.postingLimit };
106578
+ postingKeys.set(commitPreparationPostingRequestKey(request), request);
106579
+ };
106580
+ const currentByKey = projectDocumentRecordsByKey(currentDocument);
106581
+ if (rules.has("dialogue-membership-peers")) {
106582
+ for (const change of args.changes) {
106583
+ if (change.recordKind === "dialogue") {
106584
+ rememberPosting("dialogue-membership", change.recordId);
106585
+ continue;
106586
+ }
106587
+ if (change.recordKind !== "dialogue-node") continue;
106588
+ for (const candidate of [
106589
+ currentByKey.get(commitPreparationRecordKey(change)),
106590
+ change.nextData
106591
+ ]) {
106592
+ if (candidate === null || typeof candidate !== "object") continue;
106593
+ const dialogueId = Reflect.get(candidate, "dialogueId");
106594
+ if (typeof dialogueId === "string") {
106595
+ rememberPosting("dialogue-membership", dialogueId);
106596
+ }
106597
+ }
106598
+ }
106599
+ }
106600
+ if (rules.has("compiled-reference-reverse-index")) {
106601
+ const targets = collectNeoScriptRecompileReferenceTargets({
106602
+ currentDocument,
106603
+ postDocument,
106604
+ changes: args.changes,
106605
+ additionalImpactedIds: args.additionalImpactedIds,
106606
+ additionalChangedValueIds: args.additionalChangedValueIds
106607
+ });
106608
+ for (const id2 of targets.ids) rememberPosting("compiled-reference", id2);
106609
+ for (const name of targets.names) {
106610
+ rememberPosting("compiled-reference", name);
106611
+ }
106612
+ }
106613
+ for (const change of args.changes) {
106614
+ if (rules.has("compiled-reference-reverse-index")) {
106615
+ if (change.operation !== "create") {
106616
+ rememberPosting("compiled-reference", change.recordId);
106617
+ }
106618
+ for (const candidate of [
106619
+ currentByKey.get(commitPreparationRecordKey(change)),
106620
+ change.nextData
106621
+ ]) {
106622
+ if (candidate === null || typeof candidate !== "object") continue;
106623
+ const name = Reflect.get(candidate, "name");
106624
+ if (typeof name === "string" && change.operation !== "create") {
106625
+ rememberPosting("compiled-reference", name);
106626
+ }
106627
+ }
106628
+ }
106629
+ if (rules.has("stamp-edge-candidates") && change.recordKind === "member" && change.operation === "delete") {
106630
+ rememberPosting("stamp-binding", change.recordId);
106631
+ }
106632
+ if (rules.has("localizable-reference-candidates") && change.recordKind === "value" && change.operation === "create" && change.nextData !== null && typeof change.nextData === "object" && typeof Reflect.get(change.nextData, "value") === "string") {
106633
+ rememberPosting("containment-child", change.recordId);
106634
+ rememberPosting("compiled-reference", change.recordId);
106635
+ }
106636
+ }
106637
+ if (rules.has("localizable-reference-candidates")) {
106638
+ for (const seed of args.authoredValueSeeds) {
106639
+ const rootId = seed.valueId ?? derivedMemberValueId(seed.memberId);
106640
+ if (typeof Reflect.get(seed, "value") === "string") {
106641
+ rememberPosting("containment-child", rootId);
106642
+ rememberPosting("compiled-reference", rootId);
106643
+ }
106644
+ for (const row of seed.values ?? []) {
106645
+ if (typeof Reflect.get(row, "value") !== "string") continue;
106646
+ rememberPosting("containment-child", row.id);
106647
+ rememberPosting("compiled-reference", row.id);
106648
+ }
106649
+ }
106650
+ }
106651
+ return {
106652
+ exactRecords: [...exactRecords.values()].sort(compareRecordKeys),
106653
+ descendantRecords: [...descendantRecords.values()].sort(compareRecordKeys),
106654
+ ranges: ranges.sort(
106655
+ (left, right) => commitPreparationRangeRequestKey(left).localeCompare(
106656
+ commitPreparationRangeRequestKey(right)
106657
+ )
106658
+ ),
106659
+ postings: [...postingKeys.values()].sort(
106660
+ (left, right) => commitPreparationPostingRequestKey(left).localeCompare(
106661
+ commitPreparationPostingRequestKey(right)
106662
+ )
106663
+ ),
106664
+ fullContentDimension: rules.has("full-content-dimension") && (containsInitializerSource(args.changes) || containsInitializerSource(args.authoredValueSeeds)),
106665
+ ...animationValidationScope(animationValidationMemberIds)
106666
+ };
106667
+ }
106668
+ function planCommitPreparationLoadedClosureScope(args) {
106669
+ const rules = new Set(
106670
+ COMMIT_PREPARATION_CLOSURE_SPECS[args.pass].closureRules
106671
+ );
106672
+ const exactRecords = /* @__PURE__ */ new Map();
106673
+ const descendantRecords = /* @__PURE__ */ new Map();
106674
+ const ranges = /* @__PURE__ */ new Map();
106675
+ const postings = /* @__PURE__ */ new Map();
106676
+ const animationValidationMemberIds = /* @__PURE__ */ new Set();
106677
+ const rememberExact = (recordKind, recordId) => {
106678
+ const record3 = { recordKind, recordId };
106679
+ exactRecords.set(commitPreparationRecordKey(record3), record3);
106680
+ };
106681
+ const rememberDescendant = (recordKind, recordId) => {
106682
+ const record3 = { recordKind, recordId };
106683
+ const key = commitPreparationRecordKey(record3);
106684
+ exactRecords.set(key, record3);
106685
+ descendantRecords.set(key, record3);
106686
+ };
106687
+ const rememberRange = (range2) => {
106688
+ ranges.set(commitPreparationRangeRequestKey(range2), range2);
106689
+ };
106690
+ const rememberPosting = (posting) => {
106691
+ postings.set(commitPreparationPostingRequestKey(posting), posting);
106692
+ };
106693
+ for (const record3 of args.records) {
106694
+ if (rules.has("animation-graph-closure") && args.animationSchema !== void 0) {
106695
+ if (record3.recordKind === "value" && record3.includeDescendants === false && isAnimationSegmentValueRow(record3.data, args.animationSchema)) {
106696
+ rememberDescendant(record3.recordKind, record3.recordId);
106697
+ }
106698
+ if (record3.parentRecordKind === "member" && typeof record3.parentRecordId === "string" && args.animationSchema.rootMemberIds.has(record3.parentRecordId)) {
106699
+ rememberDescendant("member", record3.parentRecordId);
106700
+ animationValidationMemberIds.add(record3.parentRecordId);
106701
+ }
106702
+ }
106703
+ if (rules.has("ancestor-paths") && record3.parentRecordKind !== null && record3.parentRecordKind !== void 0 && record3.parentRecordId !== null && record3.parentRecordId !== void 0) {
106704
+ rememberExact(record3.parentRecordKind, record3.parentRecordId);
106705
+ }
106706
+ const canOwnStoredDescendants = record3.recordKind !== "value" || record3.data !== null && typeof record3.data === "object" && Reflect.get(record3.data, "value") !== null && typeof Reflect.get(record3.data, "value") === "object";
106707
+ if (rules.has("descendants") && record3.includeDescendants !== false && canOwnStoredDescendants && (record3.recordKind === "member" || record3.recordKind === "value" || record3.recordKind === "class" || record3.recordKind === "variant")) {
106708
+ rememberRange({
106709
+ rangeKind: "children",
106710
+ targetKey: commitPreparationRecordKey(record3),
106711
+ limit: args.rangeLimit
106712
+ });
106713
+ }
106714
+ if (rules.has("descendants") && record3.includeDescendants !== false && canOwnStoredDescendants && record3.recordKind === "value") {
106715
+ rememberRange({
106716
+ rangeKind: "container-members",
106717
+ targetKey: record3.recordId,
106718
+ limit: args.rangeLimit
106719
+ });
106720
+ }
106721
+ if (rules.has("dialogue-membership-peers") && record3.includeDescendants !== false && record3.recordKind === "dialogue-node" && record3.data !== null && typeof record3.data === "object") {
106722
+ const dialogueId = Reflect.get(record3.data, "dialogueId");
106723
+ if (typeof dialogueId === "string") {
106724
+ rememberPosting({
106725
+ edgeKind: "dialogue-membership",
106726
+ targetKey: dialogueId,
106727
+ limit: args.postingLimit
106728
+ });
106729
+ }
106730
+ }
106731
+ if (record3.includeDescendants !== false) {
106732
+ for (const valueId of collectStoredRecordIds(record3.data)) {
106733
+ rememberDescendant("value", valueId);
106734
+ }
106735
+ }
106736
+ }
106737
+ return {
106738
+ exactRecords: [...exactRecords.values()].sort(compareRecordKeys),
106739
+ descendantRecords: [...descendantRecords.values()].sort(compareRecordKeys),
106740
+ ranges: [...ranges.values()].sort(
106741
+ (left, right) => commitPreparationRangeRequestKey(left).localeCompare(
106742
+ commitPreparationRangeRequestKey(right)
106743
+ )
106744
+ ),
106745
+ postings: [...postings.values()].sort(
106746
+ (left, right) => commitPreparationPostingRequestKey(left).localeCompare(
106747
+ commitPreparationPostingRequestKey(right)
106748
+ )
106749
+ ),
106750
+ fullContentDimension: false,
106751
+ ...animationValidationScope(animationValidationMemberIds)
106752
+ };
106753
+ }
106754
+ function animationValidationScope(memberIds) {
106755
+ return memberIds.size === 0 ? {} : { animationValidationMemberIds: [...memberIds].sort() };
106756
+ }
106757
+ function withCommitPreparationInMemoryPlacement(records2) {
106758
+ const recordKeys = new Set(records2.map(commitPreparationRecordKey));
106759
+ const parentByChild = /* @__PURE__ */ new Map();
106760
+ const ambiguousParentsByChild = /* @__PURE__ */ new Map();
106761
+ const authorityRank = {
106762
+ "reverse-container": 1,
106763
+ forward: 2,
106764
+ persisted: 3
106765
+ };
106766
+ const rememberParent = (childKey, parent, authority) => {
106767
+ if (!recordKeys.has(childKey)) return;
106768
+ const prior = parentByChild.get(childKey);
106769
+ if (prior !== void 0) {
106770
+ const comparison = authorityRank[authority] - authorityRank[prior.authority];
106771
+ if (comparison < 0) return;
106772
+ if (comparison > 0) {
106773
+ ambiguousParentsByChild.delete(childKey);
106774
+ }
106775
+ if (comparison === 0) {
106776
+ if (prior.recordKind === parent.recordKind && prior.recordId === parent.recordId) {
106777
+ return;
106778
+ }
106779
+ const ambiguity = ambiguousParentsByChild.get(childKey) ?? {
106780
+ authority,
106781
+ parents: /* @__PURE__ */ new Set()
106782
+ };
106783
+ ambiguity.parents.add(`${prior.recordKind}:${prior.recordId}`);
106784
+ ambiguity.parents.add(`${parent.recordKind}:${parent.recordId}`);
106785
+ ambiguousParentsByChild.set(childKey, ambiguity);
106786
+ if (`${prior.recordKind}:${prior.recordId}`.localeCompare(
106787
+ `${parent.recordKind}:${parent.recordId}`
106788
+ ) <= 0) {
106789
+ return;
106790
+ }
106791
+ }
106792
+ }
106793
+ parentByChild.set(childKey, { ...parent, authority });
106794
+ };
106795
+ for (const record3 of records2) {
106796
+ const sourceKey = commitPreparationRecordKey(record3);
106797
+ if (record3.parentRecordKind !== void 0 && record3.parentRecordKind !== null && record3.parentRecordId !== void 0 && record3.parentRecordId !== null) {
106798
+ rememberParent(
106799
+ sourceKey,
106800
+ {
106801
+ recordKind: record3.parentRecordKind,
106802
+ recordId: record3.parentRecordId
106803
+ },
106804
+ "persisted"
106805
+ );
106806
+ }
106807
+ if (record3.recordKind === "dialogue-node") {
106808
+ const dialogueId = record3.data !== null && typeof record3.data === "object" ? Reflect.get(record3.data, "dialogueId") : void 0;
106809
+ if (typeof dialogueId === "string") {
106810
+ rememberParent(
106811
+ sourceKey,
106812
+ {
106813
+ recordKind: "dialogue",
106814
+ recordId: dialogueId
106815
+ },
106816
+ "forward"
106817
+ );
106818
+ }
106819
+ }
106820
+ for (const edge of extractProjectSnapshotDerivedEdges(record3).edges) {
106821
+ if (edge.edgeKind !== "containment-child" || edge.targetAddressing !== "record") {
106822
+ continue;
106823
+ }
106824
+ const payload = JSON.parse(edge.payloadJson);
106825
+ if (payload !== null && typeof payload === "object" && Reflect.get(payload, "relation") === "container-join") {
106826
+ rememberParent(
106827
+ sourceKey,
106828
+ {
106829
+ recordKind: "value",
106830
+ recordId: edge.targetKey
106831
+ },
106832
+ "reverse-container"
106833
+ );
106834
+ } else {
106835
+ rememberParent(
106836
+ `value:${edge.targetKey}`,
106837
+ {
106838
+ recordKind: record3.recordKind,
106839
+ recordId: record3.recordId
106840
+ },
106841
+ "forward"
106842
+ );
106843
+ }
106844
+ }
106845
+ }
106846
+ for (const [childKey, ambiguity] of ambiguousParentsByChild) {
106847
+ if (parentByChild.get(childKey)?.authority !== ambiguity.authority)
106848
+ continue;
106849
+ throw new Error(
106850
+ `Commit preparation placement for "${childKey}" has ambiguous ${ambiguity.authority} parents ${[
106851
+ ...ambiguity.parents
106852
+ ].sort().map((parent) => `"${parent}"`).join(" and ")}.`
106853
+ );
106854
+ }
106855
+ return records2.map((record3) => {
106856
+ const parent = parentByChild.get(commitPreparationRecordKey(record3));
106857
+ return parent === void 0 ? record3 : {
106858
+ ...record3,
106859
+ parentRecordKind: parent.recordKind,
106860
+ parentRecordId: parent.recordId
106861
+ };
106862
+ });
106863
+ }
106864
+ function commitPreparationPackedRootIds(records2) {
106865
+ const rootIdByChildId = /* @__PURE__ */ new Map();
106866
+ for (const record3 of records2) {
106867
+ if (record3.recordKind !== "value") continue;
106868
+ if (!isMemberValue(record3.data)) continue;
106869
+ if (!rowCarriesPackedValueContent(record3.data)) continue;
106870
+ for (const position of packedValuePositions(record3.data)) {
106871
+ rootIdByChildId.set(position.valueId, record3.recordId);
106872
+ }
106873
+ }
106874
+ return rootIdByChildId;
106875
+ }
106876
+ function readCommitPreparationScopeInMemory(args) {
106877
+ const records2 = withCommitPreparationInMemoryPlacement(args.records);
106878
+ const recordsByKey = new Map(
106879
+ records2.map((record3) => [commitPreparationRecordKey(record3), record3])
106880
+ );
106881
+ const packedRootIdByChildId = commitPreparationPackedRootIds(records2);
106882
+ const exactStates = /* @__PURE__ */ new Map();
106883
+ const packedRootKeyByExactKey = /* @__PURE__ */ new Map();
106884
+ for (const record3 of args.request.exactRecords) {
106885
+ const key = commitPreparationRecordKey(record3);
106886
+ if (recordsByKey.has(key)) {
106887
+ exactStates.set(key, "live");
106888
+ continue;
106889
+ }
106890
+ const rootId = record3.recordKind === "value" ? packedRootIdByChildId.get(record3.recordId) : void 0;
106891
+ if (rootId === void 0) {
106892
+ exactStates.set(key, "absent");
106893
+ continue;
106894
+ }
106895
+ const rootKey = commitPreparationRecordKey({
106896
+ recordKind: "value",
106897
+ recordId: rootId
106898
+ });
106899
+ exactStates.set(key, "live");
106900
+ exactStates.set(rootKey, "live");
106901
+ packedRootKeyByExactKey.set(key, rootKey);
106902
+ }
106903
+ const keysByKind = /* @__PURE__ */ new Map();
106904
+ const sourceOnlyKeys = [];
106905
+ const valueKeysByMemberId = /* @__PURE__ */ new Map();
106906
+ const valueKeysByClassId = /* @__PURE__ */ new Map();
106907
+ const valueKeysByContainerId = /* @__PURE__ */ new Map();
106908
+ const valueKeysByWorldKind = /* @__PURE__ */ new Map();
106909
+ const childKeysByParentKey = /* @__PURE__ */ new Map();
106910
+ const worldKindsByClass = args.document === void 0 ? /* @__PURE__ */ new Map() : worldKindByClassId(args.document);
106911
+ const semanticOwners = args.document === void 0 ? /* @__PURE__ */ new Map() : resolveSemanticOwnerMembersForValues(
106912
+ args.document,
106913
+ new Set(args.document.values.map((value) => value.id))
106914
+ );
106915
+ const rememberIndexed = (index, target, key) => {
106916
+ if (typeof target !== "string") return;
106917
+ const values = index.get(target) ?? [];
106918
+ values.push(key);
106919
+ index.set(target, values);
106920
+ };
106921
+ for (const record3 of records2) {
106922
+ const key = commitPreparationRecordKey(record3);
106923
+ const kindKeys = keysByKind.get(record3.recordKind) ?? [];
106924
+ kindKeys.push(key);
106925
+ keysByKind.set(record3.recordKind, kindKeys);
106926
+ if (containsAuthoredNeoScriptSource(record3.data) && !containsCompiledNeoScriptBody(record3.data)) {
106927
+ sourceOnlyKeys.push(key);
106928
+ }
106929
+ if (record3.recordKind !== "value") continue;
106930
+ const data = record3.data !== null && typeof record3.data === "object" ? record3.data : {};
106931
+ const explicitMemberId = Reflect.get(data, "valueMemberId") ?? Reflect.get(data, "memberId");
106932
+ rememberIndexed(
106933
+ valueKeysByMemberId,
106934
+ explicitMemberId ?? Reflect.get(semanticOwners.get(record3.recordId) ?? {}, "id"),
106935
+ key
106936
+ );
106937
+ rememberIndexed(valueKeysByClassId, Reflect.get(data, "classId"), key);
106938
+ const classId = Reflect.get(data, "classId");
106939
+ if (typeof classId === "string") {
106940
+ rememberIndexed(
106941
+ valueKeysByWorldKind,
106942
+ worldKindsByClass.get(classId),
106943
+ key
106944
+ );
106945
+ }
106946
+ rememberIndexed(
106947
+ valueKeysByContainerId,
106948
+ Reflect.get(data, "containerId"),
106949
+ key
106950
+ );
106951
+ }
106952
+ const rememberChild = (parentKey, childKey) => {
106953
+ const children = childKeysByParentKey.get(parentKey) ?? [];
106954
+ if (!children.includes(childKey)) children.push(childKey);
106955
+ childKeysByParentKey.set(parentKey, children);
106956
+ };
106957
+ for (const record3 of records2) {
106958
+ const sourceKey = commitPreparationRecordKey(record3);
106959
+ const parentRecordKind = record3.parentRecordKind;
106960
+ const parentRecordId = record3.parentRecordId;
106961
+ if (typeof parentRecordKind === "string" && typeof parentRecordId === "string") {
106962
+ const parentKey = `${parentRecordKind}:${parentRecordId}`;
106963
+ rememberChild(parentKey, sourceKey);
106964
+ }
106965
+ }
106966
+ const rangeRecordKeys = /* @__PURE__ */ new Map();
106967
+ for (const request of args.request.ranges) {
106968
+ const matching = request.rangeKind === "record-kind" ? keysByKind.get(request.targetKey) ?? [] : request.rangeKind === "source-only" ? sourceOnlyKeys : request.rangeKind === "value-member" ? valueKeysByMemberId.get(request.targetKey) ?? [] : request.rangeKind === "value-class" ? valueKeysByClassId.get(request.targetKey) ?? [] : request.rangeKind === "container-members" ? valueKeysByContainerId.get(request.targetKey) ?? [] : request.rangeKind === "children" ? childKeysByParentKey.get(request.targetKey) ?? [] : request.rangeKind === "world-kind" ? valueKeysByWorldKind.get(request.targetKey) ?? [] : keysByKind.get("value") ?? [];
106969
+ if (matching.length > request.limit) {
106970
+ return {
106971
+ kind: "fallback",
106972
+ reason: {
106973
+ code: "range-row-cap-exceeded",
106974
+ requestKey: commitPreparationRangeRequestKey(request),
106975
+ observed: matching.length,
106976
+ limit: request.limit
106977
+ }
106978
+ };
106979
+ }
106980
+ rangeRecordKeys.set(
106981
+ commitPreparationRangeRequestKey(request),
106982
+ [...matching].sort()
106983
+ );
106984
+ }
106985
+ const persisted = [];
106986
+ for (const record3 of records2) {
106987
+ const extraction = extractProjectSnapshotDerivedEdges(record3);
106988
+ if (!extraction.complete && args.request.postings.some(
106989
+ (request) => request.edgeKind === "constructor-aggregate"
106990
+ )) {
106991
+ return {
106992
+ kind: "fallback",
106993
+ reason: {
106994
+ code: "derived-edge-extraction-incomplete",
106995
+ recordKey: commitPreparationRecordKey(record3)
106996
+ }
106997
+ };
106998
+ }
106999
+ for (const edge of extraction.edges) {
107000
+ persisted.push({ ...record3, ...edge });
107001
+ }
107002
+ }
107003
+ const overlaid = overlayCommitPreparationDerivedEdgePostings({
107004
+ requests: args.request.postings,
107005
+ persisted,
107006
+ prepared: args.prepared
107007
+ });
107008
+ if (overlaid.kind === "fallback") return overlaid;
107009
+ return {
107010
+ kind: "complete",
107011
+ value: {
107012
+ exactStates,
107013
+ packedRootKeyByExactKey,
107014
+ rangeRecordKeys,
107015
+ postingSourceKeys: new Map(
107016
+ [...overlaid.value].map(([key, edges]) => [
107017
+ key,
107018
+ edges.map(commitPreparationRecordKey)
107019
+ ])
107020
+ )
107021
+ }
107022
+ };
107023
+ }
107024
+ function commitPreparationRecordKey(record3) {
107025
+ return `${record3.recordKind}:${record3.recordId}`;
107026
+ }
107027
+ function commitPreparationRangeRequestKey(request) {
107028
+ return `${request.rangeKind}:${request.targetKey}`;
107029
+ }
107030
+ function commitPreparationPostingRequestKey(request) {
107031
+ return `${request.edgeKind}:${request.targetKey}`;
107032
+ }
107033
+ function overlayCommitPreparationDerivedEdgePostings(args) {
107034
+ const requestsByKey = /* @__PURE__ */ new Map();
107035
+ const answersByKey = /* @__PURE__ */ new Map();
107036
+ for (const request of args.requests) {
107037
+ const key = commitPreparationPostingRequestKey(request);
107038
+ const prior = requestsByKey.get(key);
107039
+ if (prior === void 0 || prior.limit < request.limit) {
107040
+ requestsByKey.set(key, request);
107041
+ }
107042
+ if (!answersByKey.has(key)) answersByKey.set(key, /* @__PURE__ */ new Map());
107043
+ }
107044
+ const preparedBySource = /* @__PURE__ */ new Map();
107045
+ for (const change of args.prepared) {
107046
+ preparedBySource.set(commitPreparationRecordKey(change), change);
107047
+ }
107048
+ for (const edge of args.persisted) {
107049
+ const requestKey = commitPreparationPostingRequestKey(edge);
107050
+ const answer = answersByKey.get(requestKey);
107051
+ if (answer === void 0) continue;
107052
+ if (preparedBySource.has(commitPreparationRecordKey(edge))) continue;
107053
+ rememberOverlayEdge(answer, { ...edge, origin: "persisted" });
107054
+ }
107055
+ const constructorAggregateRequested = [...requestsByKey.values()].some(
107056
+ (request) => request.edgeKind === "constructor-aggregate"
107057
+ );
107058
+ for (const change of preparedBySource.values()) {
107059
+ if (change.operation === "delete" || change.deleted === true) continue;
107060
+ if (change.nextData === void 0) {
107061
+ return {
107062
+ kind: "fallback",
107063
+ reason: {
107064
+ code: "prepared-edge-source-missing-data",
107065
+ recordKey: commitPreparationRecordKey(change)
107066
+ }
107067
+ };
107068
+ }
107069
+ const extraction = extractProjectSnapshotDerivedEdges({
107070
+ recordKind: change.recordKind,
107071
+ recordId: change.recordId,
107072
+ data: change.nextData,
107073
+ constructorAggregateEdges: change.constructorAggregateEdges
107074
+ });
107075
+ if (!extraction.complete && constructorAggregateRequested) {
107076
+ return {
107077
+ kind: "fallback",
107078
+ reason: {
107079
+ code: "derived-edge-extraction-incomplete",
107080
+ recordKey: commitPreparationRecordKey(change)
107081
+ }
107082
+ };
107083
+ }
107084
+ for (const edge of extraction.edges) {
107085
+ const requestKey = commitPreparationPostingRequestKey(edge);
107086
+ const answer = answersByKey.get(requestKey);
107087
+ if (answer === void 0) continue;
107088
+ rememberOverlayEdge(answer, {
107089
+ ...edge,
107090
+ recordKind: change.recordKind,
107091
+ recordId: change.recordId,
107092
+ origin: "prepared"
107093
+ });
107094
+ }
107095
+ }
107096
+ const result = /* @__PURE__ */ new Map();
107097
+ for (const [requestKey, answer] of answersByKey) {
107098
+ const request = requestsByKey.get(requestKey);
107099
+ if (request === void 0) continue;
107100
+ if (answer.size > request.limit) {
107101
+ return {
107102
+ kind: "fallback",
107103
+ reason: {
107104
+ code: "posting-budget-exceeded",
107105
+ requestKey,
107106
+ observed: answer.size,
107107
+ limit: request.limit
107108
+ }
107109
+ };
107110
+ }
107111
+ result.set(
107112
+ requestKey,
107113
+ [...answer.values()].sort(
107114
+ (left, right) => overlayEdgeKey(left).localeCompare(overlayEdgeKey(right))
107115
+ )
107116
+ );
107117
+ }
107118
+ return { kind: "complete", value: result };
107119
+ }
107120
+ function rememberOverlayEdge(answer, edge) {
107121
+ answer.set(overlayEdgeKey(edge), edge);
107122
+ }
107123
+ function overlayEdgeKey(edge) {
107124
+ return `${commitPreparationRecordKey(edge)}:${projectSnapshotDerivedEdgeIdentity(edge)}`;
107125
+ }
107126
+ function commitPreparationValidationCandidateMemberIds(document) {
107127
+ const result = /* @__PURE__ */ new Set();
107128
+ for (const member of document.members) {
107129
+ if (member.kind === 26 /* NSAction */ || member.kind === 27 /* Variant */ || isReadOnlyMember(member)) {
107130
+ result.add(member.id);
107131
+ }
107132
+ }
107133
+ return result;
107134
+ }
107135
+ function projectDocumentRecordsByKey(document) {
107136
+ const result = /* @__PURE__ */ new Map();
107137
+ const add = (recordKind, records2) => {
107138
+ for (const record3 of records2) {
107139
+ if (record3 === null || typeof record3 !== "object") continue;
107140
+ const recordId = Reflect.get(record3, "id");
107141
+ if (typeof recordId !== "string") continue;
107142
+ result.set(commitPreparationRecordKey({ recordKind, recordId }), record3);
107143
+ }
107144
+ };
107145
+ add("project", [document.project]);
107146
+ add("member", document.members ?? []);
107147
+ add("class", document.classes ?? []);
107148
+ add("constructor", document.constructors ?? []);
107149
+ add("variant", document.variants ?? []);
107150
+ add("variant-folder", document.variantFolders ?? []);
107151
+ add("enum", document.enums ?? []);
107152
+ add("interface", document.interfaces ?? []);
107153
+ add("internal-record-relation", document.internalRecordRelations ?? []);
107154
+ add("project-file", document.projectFiles ?? []);
107155
+ add("dialogue", document.dialogueRecords ?? document.dialogues ?? []);
107156
+ add("dialogue-node", document.dialogueNodes ?? []);
107157
+ add("dialogue-group", document.dialogueGroups ?? []);
107158
+ add("priority-group", document.priorityGroups ?? []);
107159
+ add("unity-texture-template", document.textureTemplates ?? []);
107160
+ add("unity-audio-clip-template", document.audioClipTemplates ?? []);
107161
+ if (document.localizationConfig !== null) {
107162
+ add("localization-config", [document.localizationConfig]);
107163
+ }
107164
+ add("localization-status", document.localizationStatuses ?? []);
107165
+ add("localized-text", document.localizedTexts ?? []);
107166
+ add("migration", document.migrations ?? []);
107167
+ add("value", document.values ?? []);
107168
+ return result;
107169
+ }
107170
+ function collectStoredRecordIds(value) {
107171
+ const result = /* @__PURE__ */ new Set();
107172
+ const visit = (candidate) => {
107173
+ if (typeof candidate === "string") {
107174
+ if (STORED_RECORD_ID_PATTERN.test(candidate)) result.add(candidate);
107175
+ return;
107176
+ }
107177
+ if (Array.isArray(candidate)) {
107178
+ for (const entry of candidate) visit(entry);
107179
+ return;
107180
+ }
107181
+ if (candidate === null || typeof candidate !== "object") return;
107182
+ for (const entry of Object.values(candidate)) visit(entry);
107183
+ };
107184
+ visit(value);
107185
+ return result;
107186
+ }
107187
+ function containsInitializerSource(value) {
107188
+ if (Array.isArray(value)) return value.some(containsInitializerSource);
107189
+ if (value === null || typeof value !== "object") return false;
107190
+ const record3 = value;
107191
+ if (record3.init !== null && typeof record3.init === "object" && typeof Reflect.get(record3.init, "code") === "string") {
107192
+ return true;
107193
+ }
107194
+ return Object.values(record3).some(containsInitializerSource);
107195
+ }
107196
+ function compareRecordKeys(left, right) {
107197
+ return commitPreparationRecordKey(left).localeCompare(
107198
+ commitPreparationRecordKey(right)
107199
+ );
107200
+ }
107201
+ var COMMIT_PREPARATION_SCOPE_RANGE_ROW_LIMIT, COMMIT_PREPARATION_SCOPE_POSTING_ROW_LIMIT, COMMIT_PREPARATION_SCOPE_SOURCE_ONLY_ROW_LIMIT, STORED_RECORD_ID_PATTERN;
107202
+ var init_project_commit_preparation_scoped_loader = __esm({
107203
+ "../src/database/project-commit-preparation-scoped-loader.ts"() {
107204
+ "use strict";
107205
+ init_member_kind_enum();
107206
+ init_members();
107207
+ init_inheritance();
107208
+ init_core();
107209
+ init_member_value_id();
107210
+ init_member_kinds();
107211
+ init_packed_value_encoding();
107212
+ init_variants2();
107213
+ init_project_snapshot_derived_edges();
107214
+ init_neo_script_recompile_scope();
107215
+ init_constructor_argument_ownership();
107216
+ init_commit_preparation_scope_planner();
107217
+ init_commit_preparation_animation_scope();
107218
+ COMMIT_PREPARATION_SCOPE_RANGE_ROW_LIMIT = 4096;
107219
+ COMMIT_PREPARATION_SCOPE_POSTING_ROW_LIMIT = 64;
107220
+ COMMIT_PREPARATION_SCOPE_SOURCE_ONLY_ROW_LIMIT = 64;
107221
+ STORED_RECORD_ID_PATTERN = /^(?:system_)?[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
107222
+ }
107223
+ });
107224
+
105702
107225
  // src/project-source/server-preparation-preflight.ts
105703
107226
  function assertServerPreparationSucceeds(args) {
105704
107227
  for (const change of args.changes) {
@@ -105712,6 +107235,7 @@ function assertServerPreparationSucceeds(args) {
105712
107235
  });
105713
107236
  if (refusal !== null) throw new ServerPreparationPreflightError(refusal);
105714
107237
  }
107238
+ assertDerivedEdgeCompatibility(args.workspace);
105715
107239
  try {
105716
107240
  const prepared = prepareServerPreparationChanges(args);
105717
107241
  if (args.localInitializerMaterialization !== void 0) {
@@ -105725,6 +107249,42 @@ function assertServerPreparationSucceeds(args) {
105725
107249
  throw locateBodyCompileFailure(error, args.sourceByRecord);
105726
107250
  }
105727
107251
  }
107252
+ function assertDerivedEdgeCompatibility(workspace) {
107253
+ const localVersion = PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION;
107254
+ const serverVersion = workspace.state.derivedEdgeVersion;
107255
+ if (serverVersion === void 0) {
107256
+ throw new DerivedEdgeCompatibilityError(
107257
+ "workspace-metadata-missing",
107258
+ localVersion,
107259
+ serverVersion,
107260
+ "Dry-run server rehearsal requires derived-edge compatibility metadata. Run `neo pull` with this CLI, then retry."
107261
+ );
107262
+ }
107263
+ if (serverVersion === null) {
107264
+ throw new DerivedEdgeCompatibilityError(
107265
+ "watermark-missing",
107266
+ localVersion,
107267
+ serverVersion,
107268
+ `Project "${workspace.config.projectId}" has no derived-edge watermark. Run \`neo pull\` and retry. If this persists, repair the project's derived edge index.`
107269
+ );
107270
+ }
107271
+ if (serverVersion > localVersion) {
107272
+ throw new DerivedEdgeCompatibilityError(
107273
+ "cli-stale",
107274
+ localVersion,
107275
+ serverVersion,
107276
+ `This CLI uses derived-edge extractor v${localVersion}, but project "${workspace.config.projectId}" requires v${serverVersion}. Upgrade @neocompose/cli, run \`neo pull\`, then retry.`
107277
+ );
107278
+ }
107279
+ if (serverVersion < localVersion) {
107280
+ throw new DerivedEdgeCompatibilityError(
107281
+ "server-stale",
107282
+ localVersion,
107283
+ serverVersion,
107284
+ `This CLI uses derived-edge extractor v${localVersion}, but project "${workspace.config.projectId}" reports v${serverVersion}. Run \`neo pull\` and retry. If this persists, update the server and repair the project's derived edge index.`
107285
+ );
107286
+ }
107287
+ }
105728
107288
  function assertInitializerMaterializationParity(local, prepared) {
105729
107289
  const rowsById = /* @__PURE__ */ new Map();
105730
107290
  const createdByRoot = /* @__PURE__ */ new Map();
@@ -105796,9 +107356,27 @@ function locateBodyCompileFailure(error, sourceByRecord) {
105796
107356
  if (source === void 0) return error;
105797
107357
  return new Error(`${source.file}:${source.line} \u2014 ${error.message}`);
105798
107358
  }
107359
+ function prepareWithScopedSafetyValve(args) {
107360
+ try {
107361
+ const scoped = args.prepareScoped();
107362
+ if (scoped !== null) {
107363
+ args.validate(scoped);
107364
+ return scoped;
107365
+ }
107366
+ } catch {
107367
+ }
107368
+ const full = args.prepareFull();
107369
+ args.validate(full);
107370
+ return full;
107371
+ }
105799
107372
  function prepareServerPreparationChanges(args) {
107373
+ const serverTimestamp = args.serverTimestamp ?? Date.now();
105800
107374
  const rawDocument = pulledProjectDocumentRaw(args.workspace);
105801
- const document = readProjectDocument(rawDocument);
107375
+ const document = withReplayValueIdFactory(
107376
+ withStoredValueBase(readProjectDocument(rawDocument)),
107377
+ args.createValueId,
107378
+ serverTimestamp
107379
+ );
105802
107380
  const contentHashHeads = readProjectDocumentContentHashHeads(rawDocument);
105803
107381
  const changes = args.changes.map((change) => ({
105804
107382
  ...change,
@@ -105809,9 +107387,44 @@ function prepareServerPreparationChanges(args) {
105809
107387
  }));
105810
107388
  const trustedChanges = stampServerOwnedSourceCommitMetadata({
105811
107389
  rawDocument,
105812
- changes
107390
+ changes,
107391
+ timestamp: serverTimestamp
105813
107392
  });
105814
- const prepared = prepareServerOwnedSchemaCommit({
107393
+ const placedRecords = () => {
107394
+ const canonicalPlacementByValueId = projectValueHeadPlacementGraph({
107395
+ rootMembers: [
107396
+ { id: document.project.rootAssetsMemberId, label: "Assets" },
107397
+ { id: document.project.rootSaveFileMemberId, label: "Save" },
107398
+ { id: document.project.rootSessionMemberId, label: "Session" }
107399
+ ],
107400
+ variantRoots: (document.variants ?? []).map((variant) => ({
107401
+ variantId: variant.id,
107402
+ valueId: variant.valueId
107403
+ })),
107404
+ members: document.members,
107405
+ classes: document.classes,
107406
+ values: document.values
107407
+ });
107408
+ return withCommitPreparationInMemoryPlacement(
107409
+ Object.values(args.workspace.state.records).map((record3) => {
107410
+ const recordKind = narrowRecordKind(
107411
+ record3.recordKind,
107412
+ `${record3.recordKind}:${record3.recordId}`
107413
+ );
107414
+ const placement = recordKind === "value" ? canonicalPlacementByValueId.get(record3.recordId) : void 0;
107415
+ return {
107416
+ recordKind,
107417
+ recordId: record3.recordId,
107418
+ data: record3.data,
107419
+ ...placement?.parentRecordKind === null || placement?.parentRecordKind === void 0 || placement.parentRecordId === null ? {} : {
107420
+ parentRecordKind: placement.parentRecordKind,
107421
+ parentRecordId: placement.parentRecordId
107422
+ }
107423
+ };
107424
+ })
107425
+ );
107426
+ };
107427
+ const preparationArgs = {
105815
107428
  document,
105816
107429
  contentHashHeads,
105817
107430
  changes: trustedChanges,
@@ -105820,10 +107433,258 @@ function prepareServerPreparationChanges(args) {
105820
107433
  // A CLI push is always a trusted-source commit, so the server always
105821
107434
  // expands read-only source conversions for it.
105822
107435
  expandReadOnlySourceConversions: true,
105823
- forceRecompile: args.forceRecompile
107436
+ forceRecompile: args.forceRecompile,
107437
+ serverTimestamp,
107438
+ createLocalizedTextId: args.createLocalizedTextId
107439
+ };
107440
+ const prepareFull = (discardedScopedAttempt) => {
107441
+ if (discardedScopedAttempt) args.resetReplayIds?.();
107442
+ return prepareServerOwnedSchemaCommit(preparationArgs);
107443
+ };
107444
+ const validate2 = (prepared) => assertProjectVersionWholeGraphWritesValid({ document, changes: prepared });
107445
+ if (args.forceRecompile === true) {
107446
+ const prepared = prepareFull(false);
107447
+ validate2(prepared);
107448
+ return prepared;
107449
+ }
107450
+ return prepareWithScopedSafetyValve({
107451
+ prepareScoped: () => {
107452
+ const records2 = placedRecords();
107453
+ const initialScope = planCommitPreparationInitialScope({
107454
+ pass: COMMIT_PREPARATION_PASS_ORDER[0],
107455
+ document,
107456
+ changes,
107457
+ authoredValueSeeds: args.authoredValueSeeds,
107458
+ rangeLimit: COMMIT_PREPARATION_SCOPE_RANGE_ROW_LIMIT,
107459
+ postingLimit: COMMIT_PREPARATION_SCOPE_POSTING_ROW_LIMIT
107460
+ });
107461
+ if (initialScope.fullContentDimension) return null;
107462
+ const scopeAnswer = readCommitPreparationScopeInMemory({
107463
+ request: initialScope,
107464
+ records: records2,
107465
+ prepared: changes,
107466
+ document
107467
+ });
107468
+ if (scopeAnswer.kind === "fallback") return null;
107469
+ const selectedContentKeys = /* @__PURE__ */ new Set();
107470
+ const descendantRootKeys = /* @__PURE__ */ new Set();
107471
+ const absentExactKeys = /* @__PURE__ */ new Set();
107472
+ absorbInMemoryScopeAnswer(
107473
+ selectedContentKeys,
107474
+ scopeAnswer.value,
107475
+ descendantRootKeys,
107476
+ scopeDescendantKeys(initialScope),
107477
+ scopeDescendantRangeKeys(initialScope),
107478
+ absentExactKeys
107479
+ );
107480
+ const initialClosed = closeInMemoryLoadedScope({
107481
+ records: records2,
107482
+ selected: selectedContentKeys,
107483
+ descendantRoots: descendantRootKeys,
107484
+ absentExactKeys,
107485
+ prepared: changes,
107486
+ document,
107487
+ pass: COMMIT_PREPARATION_PASS_ORDER[0]
107488
+ });
107489
+ if (!initialClosed) return null;
107490
+ const scopedDocument = selectPreparationContentRows(
107491
+ document,
107492
+ selectedContentKeys
107493
+ );
107494
+ const scopedHeads = contentHashHeads.filter(
107495
+ (head) => !COMMIT_PREPARATION_CLI_CONTENT_KINDS.has(head.recordKind) || selectedContentKeys.has(`${head.recordKind}:${head.recordId}`)
107496
+ );
107497
+ const passes = prepareServerOwnedSchemaCommitPasses({
107498
+ ...preparationArgs,
107499
+ document: scopedDocument,
107500
+ contentHashHeads: scopedHeads
107501
+ });
107502
+ for (; ; ) {
107503
+ const step = passes.next();
107504
+ if (step.done) return step.value;
107505
+ const topUpRequest = planCommitPreparationInitialScope({
107506
+ pass: nextCommitPreparationPass(step.value.pass) ?? step.value.pass,
107507
+ document: scopedDocument,
107508
+ changes: step.value.preparedChanges,
107509
+ authoredValueSeeds: args.authoredValueSeeds,
107510
+ rangeLimit: COMMIT_PREPARATION_SCOPE_RANGE_ROW_LIMIT,
107511
+ postingLimit: COMMIT_PREPARATION_SCOPE_POSTING_ROW_LIMIT
107512
+ });
107513
+ if (topUpRequest.fullContentDimension) return null;
107514
+ const topUpAnswer = readCommitPreparationScopeInMemory({
107515
+ request: topUpRequest,
107516
+ records: records2,
107517
+ prepared: step.value.preparedChanges,
107518
+ document
107519
+ });
107520
+ if (topUpAnswer.kind === "fallback") return null;
107521
+ absorbInMemoryScopeAnswer(
107522
+ selectedContentKeys,
107523
+ topUpAnswer.value,
107524
+ descendantRootKeys,
107525
+ scopeDescendantKeys(topUpRequest),
107526
+ scopeDescendantRangeKeys(topUpRequest),
107527
+ absentExactKeys
107528
+ );
107529
+ for (const change of step.value.preparedChanges) {
107530
+ if (change.operation === "delete" || change.deleted === true)
107531
+ continue;
107532
+ descendantRootKeys.add(`${change.recordKind}:${change.recordId}`);
107533
+ }
107534
+ if (!closeInMemoryLoadedScope({
107535
+ records: records2,
107536
+ selected: selectedContentKeys,
107537
+ descendantRoots: descendantRootKeys,
107538
+ absentExactKeys,
107539
+ prepared: step.value.preparedChanges,
107540
+ document,
107541
+ pass: nextCommitPreparationPass(step.value.pass) ?? step.value.pass
107542
+ })) {
107543
+ return null;
107544
+ }
107545
+ Object.assign(
107546
+ scopedDocument,
107547
+ selectPreparationContentRows(document, selectedContentKeys)
107548
+ );
107549
+ scopedHeads.splice(
107550
+ 0,
107551
+ scopedHeads.length,
107552
+ ...contentHashHeads.filter(
107553
+ (head) => !COMMIT_PREPARATION_CLI_CONTENT_KINDS.has(head.recordKind) || selectedContentKeys.has(`${head.recordKind}:${head.recordId}`)
107554
+ )
107555
+ );
107556
+ }
107557
+ },
107558
+ prepareFull: () => prepareFull(true),
107559
+ validate: validate2
105824
107560
  });
105825
- assertProjectVersionWholeGraphWritesValid({ document, changes: prepared });
105826
- return prepared;
107561
+ }
107562
+ function withReplayValueIdFactory(document, createValueId, timestamp) {
107563
+ if (createValueId === void 0) return document;
107564
+ return Object.assign(document, {
107565
+ createValueRow: (projectId, body) => {
107566
+ const value = buildNewValue(projectId, body, timestamp);
107567
+ value.id = createValueId();
107568
+ return value;
107569
+ }
107570
+ });
107571
+ }
107572
+ function absorbInMemoryScopeAnswer(selected, answer, descendantRoots, descendantExactKeys = /* @__PURE__ */ new Set(), descendantRangeKeys = /* @__PURE__ */ new Set(), absentExactKeys) {
107573
+ for (const [key, state] of answer.exactStates) {
107574
+ if (state !== "live") {
107575
+ absentExactKeys?.add(key);
107576
+ continue;
107577
+ }
107578
+ const selectedKey = answer.packedRootKeyByExactKey.get(key) ?? key;
107579
+ selected.add(selectedKey);
107580
+ if (descendantExactKeys.has(key)) descendantRoots?.add(selectedKey);
107581
+ }
107582
+ for (const [requestKey, keys] of answer.rangeRecordKeys) {
107583
+ for (const key of keys) {
107584
+ selected.add(key);
107585
+ if (descendantRangeKeys.has(requestKey)) descendantRoots?.add(key);
107586
+ }
107587
+ }
107588
+ for (const keys of answer.postingSourceKeys.values()) {
107589
+ for (const key of keys) {
107590
+ selected.add(key);
107591
+ }
107592
+ }
107593
+ }
107594
+ function closeInMemoryLoadedScope(args) {
107595
+ const animationSchema = commitPreparationAnimationSchema(args.document);
107596
+ for (; ; ) {
107597
+ const closureRecords = args.records.filter(
107598
+ (record3) => args.selected.has(`${record3.recordKind}:${record3.recordId}`)
107599
+ ).map((record3) => ({
107600
+ ...record3,
107601
+ includeDescendants: args.descendantRoots.has(
107602
+ `${record3.recordKind}:${record3.recordId}`
107603
+ )
107604
+ }));
107605
+ const request = planCommitPreparationLoadedClosureScope({
107606
+ pass: args.pass,
107607
+ records: closureRecords,
107608
+ rangeLimit: COMMIT_PREPARATION_SCOPE_RANGE_ROW_LIMIT,
107609
+ postingLimit: COMMIT_PREPARATION_SCOPE_POSTING_ROW_LIMIT,
107610
+ animationSchema
107611
+ });
107612
+ const answer = readCommitPreparationScopeInMemory({
107613
+ request,
107614
+ records: args.records,
107615
+ prepared: args.prepared,
107616
+ document: args.document
107617
+ });
107618
+ if (answer.kind === "fallback") return false;
107619
+ const priorSelectedSize = args.selected.size;
107620
+ const priorDescendantSize = args.descendantRoots.size;
107621
+ absorbInMemoryScopeAnswer(
107622
+ args.selected,
107623
+ answer.value,
107624
+ args.descendantRoots,
107625
+ scopeDescendantKeys(request),
107626
+ scopeDescendantRangeKeys(request),
107627
+ args.absentExactKeys
107628
+ );
107629
+ if (args.selected.size === priorSelectedSize && args.descendantRoots.size === priorDescendantSize) {
107630
+ return selectedAncestorPathsIntact(
107631
+ args.records,
107632
+ args.selected,
107633
+ args.absentExactKeys
107634
+ );
107635
+ }
107636
+ }
107637
+ }
107638
+ function selectedAncestorPathsIntact(records2, selected, absentExactKeys) {
107639
+ if (absentExactKeys.size === 0) return true;
107640
+ const selectedRecords = records2.filter(
107641
+ (record3) => selected.has(`${record3.recordKind}:${record3.recordId}`)
107642
+ );
107643
+ const packedRootIdByChildId = commitPreparationPackedRootIds(selectedRecords);
107644
+ for (const record3 of selectedRecords) {
107645
+ if (record3.recordKind !== "value") continue;
107646
+ if (record3.parentRecordKind !== "value") continue;
107647
+ const parentId = record3.parentRecordId;
107648
+ if (typeof parentId !== "string") continue;
107649
+ if (selected.has(`value:${parentId}`)) continue;
107650
+ if (packedRootIdByChildId.has(parentId)) continue;
107651
+ if (absentExactKeys.has(`value:${parentId}`)) return false;
107652
+ }
107653
+ return true;
107654
+ }
107655
+ function scopeDescendantRangeKeys(scope) {
107656
+ return new Set(
107657
+ scope.ranges.filter(
107658
+ (range2) => range2.rangeKind === "children" || range2.rangeKind === "container-members"
107659
+ ).map((range2) => `${range2.rangeKind}:${range2.targetKey}`)
107660
+ );
107661
+ }
107662
+ function scopeDescendantKeys(scope) {
107663
+ return new Set(
107664
+ (scope.descendantRecords ?? []).map(
107665
+ (record3) => `${record3.recordKind}:${record3.recordId}`
107666
+ )
107667
+ );
107668
+ }
107669
+ function selectPreparationContentRows(document, selected) {
107670
+ const physicalValues = (document.physicalValues ?? document.values).filter(
107671
+ (row) => selected.has(`value:${row.id}`)
107672
+ );
107673
+ const values = expandPackedValueRows(physicalValues);
107674
+ return {
107675
+ ...document,
107676
+ values: values === physicalValues ? physicalValues : [...values],
107677
+ physicalValues,
107678
+ dialogueNodes: (document.dialogueNodes ?? []).filter(
107679
+ (row) => selected.has(`dialogue-node:${row.id}`)
107680
+ ),
107681
+ migrations: (document.migrations ?? []).filter(
107682
+ (row) => selected.has(`migration:${row.id}`)
107683
+ ),
107684
+ localizedTexts: (document.localizedTexts ?? []).filter(
107685
+ (row) => selected.has(`localized-text:${row.id}`)
107686
+ )
107687
+ };
105827
107688
  }
105828
107689
  function pulledProjectDocumentRaw(workspace) {
105829
107690
  const records2 = [];
@@ -105900,7 +107761,7 @@ function syntheticVersionMetadata(workspace) {
105900
107761
  releaseChannels: []
105901
107762
  };
105902
107763
  }
105903
- var ServerPreparationPreflightError;
107764
+ var ServerPreparationPreflightError, DerivedEdgeCompatibilityError, COMMIT_PREPARATION_CLI_CONTENT_KINDS;
105904
107765
  var init_server_preparation_preflight = __esm({
105905
107766
  "src/project-source/server-preparation-preflight.ts"() {
105906
107767
  "use strict";
@@ -105910,13 +107771,33 @@ var init_server_preparation_preflight = __esm({
105910
107771
  init_project_version_whole_graph_validation();
105911
107772
  init_projectRecordBuckets();
105912
107773
  init_compile_ns_property();
107774
+ init_valueHeadPlacementGraph();
105913
107775
  init_projection();
107776
+ init_project_snapshot_derived_edges();
107777
+ init_project_commit_preparation_scoped_loader();
107778
+ init_packed_value_encoding();
107779
+ init_commit_preparation_animation_scope();
107780
+ init_commit_preparation_scope_planner();
107781
+ init_build_default_member_value();
105914
107782
  ServerPreparationPreflightError = class extends Error {
105915
107783
  constructor(message) {
105916
107784
  super(message);
105917
107785
  this.name = "ServerPreparationPreflightError";
105918
107786
  }
105919
107787
  };
107788
+ DerivedEdgeCompatibilityError = class extends ServerPreparationPreflightError {
107789
+ constructor(reason, localVersion, serverVersion, message) {
107790
+ super(message);
107791
+ this.reason = reason;
107792
+ this.localVersion = localVersion;
107793
+ this.serverVersion = serverVersion;
107794
+ this.name = "DerivedEdgeCompatibilityError";
107795
+ }
107796
+ reason;
107797
+ localVersion;
107798
+ serverVersion;
107799
+ };
107800
+ COMMIT_PREPARATION_CLI_CONTENT_KINDS = /* @__PURE__ */ new Set(["value", "dialogue-node", "localized-text", "migration"]);
105920
107801
  }
105921
107802
  });
105922
107803
 
@@ -108800,7 +110681,6 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
108800
110681
  context,
108801
110682
  effectiveClass,
108802
110683
  environment,
108803
- source,
108804
110684
  path
108805
110685
  );
108806
110686
  const body = {};
@@ -109130,7 +111010,6 @@ function lowerStructuralConstructionRow(context, member, expression, source, val
109130
111010
  context,
109131
111011
  effectiveClass,
109132
111012
  environment,
109133
- source,
109134
111013
  path
109135
111014
  );
109136
111015
  const parameters = structuralConstructorParameters(
@@ -110260,7 +112139,7 @@ function selectorReferenceReturnClassId(context, expression) {
110260
112139
  const className = astTypeNameV4(returned.typeArguments[0]);
110261
112140
  return className === null ? null : context.classesByName.get(className)?.id ?? null;
110262
112141
  }
110263
- function animationChildOverrideSeedBindings(context, schemaClass2, environment, source, path) {
112142
+ function animationChildOverrideSeedBindings(context, schemaClass2, environment, path) {
110264
112143
  if (schemaClass2.system?.worldKind !== "animationChildOverride") {
110265
112144
  return void 0;
110266
112145
  }
@@ -114364,7 +116243,7 @@ function discoverProjectBinariesV4(root, explicit, ignoredPaths = []) {
114364
116243
  });
114365
116244
  }
114366
116245
  const reserved = explicit.map((entry) => entry.symbol);
114367
- const symbols = assignDeterministicFileSymbols2(candidates, reserved);
116246
+ const symbols = assignDeterministicFileSymbols(candidates, reserved);
114368
116247
  return candidates.map((candidate) => {
114369
116248
  const inspected = inspectBinaryFile(candidate.absolute, candidate.path);
114370
116249
  return { ...inspected, symbol: symbols.get(candidate.stableId) };
@@ -114615,15 +116494,14 @@ function safePathSegment2(value) {
114615
116494
  function normalizeSlash2(value) {
114616
116495
  return value.split(sep2).join("/").replaceAll("\\", "/");
114617
116496
  }
114618
- var SUPPORTED_BINARY_TYPES, REGISTRY_ENTRY2, assignDeterministicFileSymbols2;
116497
+ var SUPPORTED_BINARY_TYPES, REGISTRY_ENTRY2;
114619
116498
  var init_project_files = __esm({
114620
116499
  "src/project-source/project-files.ts"() {
114621
116500
  "use strict";
114622
116501
  init_src();
114623
116502
  init_projection();
114624
116503
  init_source_format();
114625
- init_members();
114626
- init_project_file_registry();
116504
+ init_project_file_source();
114627
116505
  init_project_file_source();
114628
116506
  SUPPORTED_BINARY_TYPES = /* @__PURE__ */ new Map([
114629
116507
  [".png", { kind: "image", mimeType: "image/png" }],
@@ -114635,7 +116513,6 @@ var init_project_files = __esm({
114635
116513
  [".ogg", { kind: "audio", mimeType: "audio/ogg" }]
114636
116514
  ]);
114637
116515
  REGISTRY_ENTRY2 = /(?:@id\(\s*("(?:[^"\\]|\\.)*")\s*\)\s*)?(?:@settings\(([\s\S]*?)\)\s*)?(NeoImage|NeoAudioClip)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\(\s*("(?:[^"\\]|\\.)*")\s*\)\s*;/gy;
114638
- assignDeterministicFileSymbols2 = assignDeterministicProjectFileSymbols;
114639
116516
  }
114640
116517
  });
114641
116518
 
@@ -115325,7 +117202,8 @@ async function queryProjectDocumentSyncMarker(workspace, convex) {
115325
117202
  return {
115326
117203
  revision: revisionValue,
115327
117204
  headTransactionId: signal?.transactionId ?? null,
115328
- headTransactionHash: signal?.transactionHash ?? null
117205
+ headTransactionHash: signal?.transactionHash ?? null,
117206
+ derivedEdgeVersion: signal?.derivedEdgeVersion ?? null
115329
117207
  };
115330
117208
  }
115331
117209
  async function fetchProjectDocumentDelta(workspace, cursor) {
@@ -115334,7 +117212,8 @@ async function fetchProjectDocumentDelta(workspace, cursor) {
115334
117212
  if (marker.revision.versionsStamp !== cursor.versionsStamp) {
115335
117213
  return {
115336
117214
  fullResync: true,
115337
- headTransactionHash: marker.headTransactionHash
117215
+ headTransactionHash: marker.headTransactionHash,
117216
+ derivedEdgeVersion: marker.derivedEdgeVersion
115338
117217
  };
115339
117218
  }
115340
117219
  if (marker.headTransactionId === marker.revision.latestTransactionId && marker.headTransactionHash === workspace.state.headTransactionHash) {
@@ -115343,7 +117222,8 @@ async function fetchProjectDocumentDelta(workspace, cursor) {
115343
117222
  document: projectDocumentFromWorkspaceState(workspace.state, cursor),
115344
117223
  changedKeys: /* @__PURE__ */ new Set(),
115345
117224
  cursor,
115346
- headTransactionHash: marker.headTransactionHash
117225
+ headTransactionHash: marker.headTransactionHash,
117226
+ derivedEdgeVersion: marker.derivedEdgeVersion
115347
117227
  };
115348
117228
  }
115349
117229
  const result = await convex.query(api2.projectDocuments.getRecordsSince, {
@@ -115355,7 +117235,8 @@ async function fetchProjectDocumentDelta(workspace, cursor) {
115355
117235
  if (result.fullResync) {
115356
117236
  return {
115357
117237
  fullResync: true,
115358
- headTransactionHash: marker.headTransactionHash
117238
+ headTransactionHash: marker.headTransactionHash,
117239
+ derivedEdgeVersion: marker.derivedEdgeVersion
115359
117240
  };
115360
117241
  }
115361
117242
  const document = projectDocumentFromWorkspaceState(workspace.state, cursor);
@@ -115404,7 +117285,8 @@ async function fetchProjectDocumentDelta(workspace, cursor) {
115404
117285
  document: projectDocumentWithRevision(document, nextCursor),
115405
117286
  changedKeys,
115406
117287
  cursor: nextCursor,
115407
- headTransactionHash: marker.headTransactionHash
117288
+ headTransactionHash: marker.headTransactionHash,
117289
+ derivedEdgeVersion: marker.derivedEdgeVersion
115408
117290
  };
115409
117291
  }
115410
117292
  function projectDocumentFromWorkspaceState(state, cursor) {
@@ -116324,7 +118206,6 @@ var init_static_value_seed_records = __esm({
116324
118206
  // src/commands/pull.ts
116325
118207
  var pull_exports = {};
116326
118208
  __export(pull_exports, {
116327
- deltaRequiresSourceProjectionV4: () => deltaRequiresSourceProjectionV4,
116328
118209
  projectSourcePathsRequiringRewriteV4: () => projectSourcePathsRequiringRewriteV4,
116329
118210
  runPull: () => runPull
116330
118211
  });
@@ -116385,6 +118266,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
116385
118266
  let changedRecordKeys = null;
116386
118267
  let nextCursor = null;
116387
118268
  let observedHeadTransactionHash;
118269
+ let observedDerivedEdgeVersion;
116388
118270
  let document = null;
116389
118271
  if (!destructive && hasBaseline) {
116390
118272
  progress.update("Checking remote changes\u2026");
@@ -116392,6 +118274,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
116392
118274
  if (cursor !== void 0) {
116393
118275
  const delta = await fetchProjectDocumentDelta(workspace, cursor);
116394
118276
  observedHeadTransactionHash = delta.headTransactionHash;
118277
+ observedDerivedEdgeVersion = delta.derivedEdgeVersion;
116395
118278
  if (!delta.fullResync) {
116396
118279
  document = delta.document;
116397
118280
  changedRecordKeys = delta.changedKeys;
@@ -116402,11 +118285,13 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
116402
118285
  delta.cursor
116403
118286
  );
116404
118287
  const headChanged = workspace.state.headTransactionHash !== delta.headTransactionHash;
116405
- if (cursorChanged || headChanged) {
118288
+ const derivedEdgeVersionChanged = workspace.state.derivedEdgeVersion !== delta.derivedEdgeVersion;
118289
+ if (cursorChanged || headChanged || derivedEdgeVersionChanged) {
116406
118290
  workspace.state.documentRevisionCursor = mutableCursor(
116407
118291
  delta.cursor
116408
118292
  );
116409
118293
  workspace.state.headTransactionHash = delta.headTransactionHash;
118294
+ workspace.state.derivedEdgeVersion = delta.derivedEdgeVersion;
116410
118295
  writeWorkspaceState(workspace.root, workspace.state);
116411
118296
  }
116412
118297
  progress.succeed("Already up to date.");
@@ -116416,9 +118301,11 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
116416
118301
  } else if (!options.regenerateSourceNames && workspace.state.headTransactionHash !== void 0) {
116417
118302
  const marker = await fetchProjectDocumentSyncMarker(workspace);
116418
118303
  observedHeadTransactionHash = marker.headTransactionHash;
118304
+ observedDerivedEdgeVersion = marker.derivedEdgeVersion;
116419
118305
  if (marker.headTransactionId === marker.revision.latestTransactionId && marker.headTransactionHash === workspace.state.headTransactionHash) {
116420
118306
  const seededCursor = cursorFromRevision(marker.revision);
116421
118307
  workspace.state.documentRevisionCursor = mutableCursor(seededCursor);
118308
+ workspace.state.derivedEdgeVersion = marker.derivedEdgeVersion;
116422
118309
  writeWorkspaceState(workspace.root, workspace.state);
116423
118310
  progress.succeed("Already up to date.");
116424
118311
  return;
@@ -116557,6 +118444,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
116557
118444
  changedRecordKeys,
116558
118445
  nextCursor,
116559
118446
  observedHeadTransactionHash,
118447
+ observedDerivedEdgeVersion,
116560
118448
  progress
116561
118449
  });
116562
118450
  }
@@ -116591,8 +118479,10 @@ async function runResetPull(workspace) {
116591
118479
  versionId: workspace.config.versionId
116592
118480
  });
116593
118481
  workspace.state.headTransactionHash = document.revision !== void 0 && signal?.transactionId === document.revision.latestTransactionId ? signal.transactionHash : null;
118482
+ workspace.state.derivedEdgeVersion = signal?.derivedEdgeVersion ?? null;
116594
118483
  } catch {
116595
118484
  workspace.state.headTransactionHash = null;
118485
+ delete workspace.state.derivedEdgeVersion;
116596
118486
  }
116597
118487
  if (document.revision !== void 0) {
116598
118488
  workspace.state.documentRevisionCursor = mutableCursor(
@@ -116624,6 +118514,7 @@ async function finishFormat4Pull(args) {
116624
118514
  changedRecordKeys,
116625
118515
  nextCursor,
116626
118516
  observedHeadTransactionHash,
118517
+ observedDerivedEdgeVersion,
116627
118518
  progress
116628
118519
  } = args;
116629
118520
  if (changedRecordKeys !== null && !regenerateSourceNames && conflictCount === 0 && localStatus !== null && !deltaRequiresSourceProjectionV4({
@@ -116639,6 +118530,7 @@ async function finishFormat4Pull(args) {
116639
118530
  changedRecordKeys,
116640
118531
  nextCursor,
116641
118532
  observedHeadTransactionHash,
118533
+ observedDerivedEdgeVersion,
116642
118534
  progress
116643
118535
  });
116644
118536
  return;
@@ -116823,10 +118715,15 @@ async function finishFormat4Pull(args) {
116823
118715
  versionId: workspace.config.versionId
116824
118716
  });
116825
118717
  workspace.state.headTransactionHash = document.revision !== void 0 && signal?.transactionId === document.revision.latestTransactionId ? signal.transactionHash : null;
118718
+ workspace.state.derivedEdgeVersion = signal?.derivedEdgeVersion ?? null;
116826
118719
  } catch {
116827
118720
  workspace.state.headTransactionHash = null;
118721
+ delete workspace.state.derivedEdgeVersion;
116828
118722
  }
116829
118723
  }
118724
+ if (observedDerivedEdgeVersion !== void 0) {
118725
+ workspace.state.derivedEdgeVersion = observedDerivedEdgeVersion;
118726
+ }
116830
118727
  writeWorkspaceState(workspace.root, workspace.state);
116831
118728
  if (conflictCount === 0) {
116832
118729
  writeProjectSourceAnalysisCacheV4(workspace.root, localResult.analysis);
@@ -116986,6 +118883,9 @@ function finishRecordOnlyDeltaPull(args) {
116986
118883
  if (args.observedHeadTransactionHash !== void 0) {
116987
118884
  args.workspace.state.headTransactionHash = args.observedHeadTransactionHash;
116988
118885
  }
118886
+ if (args.observedDerivedEdgeVersion !== void 0) {
118887
+ args.workspace.state.derivedEdgeVersion = args.observedDerivedEdgeVersion;
118888
+ }
116989
118889
  writeWorkspaceState(args.workspace.root, args.workspace.state);
116990
118890
  args.progress.succeed(
116991
118891
  `Pulled ${args.changedRecordKeys.size} changed record(s) \u2014 0 file(s) updated \u2014 0 removed.`
@@ -120437,7 +122337,7 @@ function normalizeSourceFiles(inputFiles) {
120437
122337
  return files;
120438
122338
  }
120439
122339
  function readSourceFile(value, index) {
120440
- const record3 = asRecord3(value, `Project source identity file ${index}`);
122340
+ const record3 = asRecord4(value, `Project source identity file ${index}`);
120441
122341
  assertExactKeys(record3, ["path", "kind", "content"]);
120442
122342
  if (typeof record3.path !== "string" || !isSafeSourcePath(record3.path)) {
120443
122343
  throw new Error(
@@ -120472,7 +122372,7 @@ function isSafeSourcePath(path) {
120472
122372
  }
120473
122373
  return neoProjectSourceKind(path) !== null;
120474
122374
  }
120475
- function asRecord3(value, label) {
122375
+ function asRecord4(value, label) {
120476
122376
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
120477
122377
  throw new Error(`${label} must be an object.`);
120478
122378
  }
@@ -120674,6 +122574,17 @@ var init_push_hook = __esm({
120674
122574
  // src/project-source/project-file-push.ts
120675
122575
  import { basename as basename2, join as join13 } from "node:path";
120676
122576
  import { readFileSync as readFileSync14 } from "node:fs";
122577
+ import { randomUUID as randomUUID2 } from "node:crypto";
122578
+ async function cleanupRejectedProjectFilePushesV4(args) {
122579
+ if (args.stagedUploadSessionId === null) return;
122580
+ try {
122581
+ await args.client.post(
122582
+ versionPath(args.workspace, "files/cleanup-staged-upload"),
122583
+ { stagedUploadSessionId: args.stagedUploadSessionId }
122584
+ );
122585
+ } catch {
122586
+ }
122587
+ }
120677
122588
  function ensureProjectFileBinaryChangesV4(args) {
120678
122589
  for (const binary of args.binaryChanges) {
120679
122590
  if (binary.action !== "upload") continue;
@@ -120753,7 +122664,7 @@ async function stageProjectFilePushesV4(args) {
120753
122664
  assignedIds: args.assignedIds
120754
122665
  });
120755
122666
  const staged = [];
120756
- const cleanupKeys = [];
122667
+ const stagedUploadSessionId = args.stagedUploadSessionId ?? randomUUID2();
120757
122668
  const put = args.put ?? fetch;
120758
122669
  const interruptController = new AbortController();
120759
122670
  const interrupt = () => interruptController.abort(new ProjectFilePushCancelledError());
@@ -120770,11 +122681,8 @@ async function stageProjectFilePushesV4(args) {
120770
122681
  });
120771
122682
  report();
120772
122683
  try {
120773
- for (let offset = 0; offset < prepared.length; offset += PROJECT_FILE_UPLOAD_BATCH_SIZE) {
120774
- const batch = prepared.slice(
120775
- offset,
120776
- offset + PROJECT_FILE_UPLOAD_BATCH_SIZE
120777
- );
122684
+ for (let offset = 0; offset < prepared.length; offset += PRESIGN_BATCH_SIZE) {
122685
+ const batch = prepared.slice(offset, offset + PRESIGN_BATCH_SIZE);
120778
122686
  const presign = await postWithTimeout(
120779
122687
  args.client,
120780
122688
  versionPath(args.workspace, "upload"),
@@ -120782,6 +122690,7 @@ async function stageProjectFilePushesV4(args) {
120782
122690
  route: "projectFile",
120783
122691
  metadata: {
120784
122692
  deferredSourceCommit: true,
122693
+ stagedUploadSessionId,
120785
122694
  uploads: batch.map((file) => ({
120786
122695
  uploadToken: file.uploadToken,
120787
122696
  projectFileId: file.recordId,
@@ -120799,12 +122708,11 @@ async function stageProjectFilePushesV4(args) {
120799
122708
  signal
120800
122709
  );
120801
122710
  const entries = readPresignEntries(presign, batch);
120802
- for (const entry of entries) cleanupKeys.push(entry.storageKey);
120803
122711
  const batchController = new AbortController();
120804
122712
  try {
120805
122713
  await mapWithConcurrency(entries, UPLOAD_CONCURRENCY, async (entry) => {
120806
122714
  try {
120807
- await putWithRetry(
122715
+ await uploadWithRetry(
120808
122716
  put,
120809
122717
  entry,
120810
122718
  combineSignals(signal, batchController.signal)
@@ -120849,15 +122757,11 @@ async function stageProjectFilePushesV4(args) {
120849
122757
  return result;
120850
122758
  });
120851
122759
  } catch (error) {
120852
- if (cleanupKeys.length > 0) {
120853
- try {
120854
- await args.client.post(
120855
- versionPath(args.workspace, "files/cleanup-staged-upload"),
120856
- { storageKeys: cleanupKeys }
120857
- );
120858
- } catch {
120859
- }
120860
- }
122760
+ await cleanupRejectedProjectFilePushesV4({
122761
+ workspace: args.workspace,
122762
+ client: args.client,
122763
+ stagedUploadSessionId
122764
+ });
120861
122765
  if (interruptController.signal.aborted || args.signal?.aborted === true) {
120862
122766
  throw new ProjectFilePushCancelledError();
120863
122767
  }
@@ -120867,7 +122771,8 @@ async function stageProjectFilePushesV4(args) {
120867
122771
  }
120868
122772
  }
120869
122773
  function readPresignEntries(presign, batch) {
120870
- const entries = Array.isArray(presign.files) ? presign.files.filter(isObjectRecord2) : [];
122774
+ const multipart = isObjectRecord2(presign.multipart) ? presign.multipart : null;
122775
+ const entries = Array.isArray(multipart?.files) ? multipart.files.filter(isObjectRecord2) : Array.isArray(presign.files) ? presign.files.filter(isObjectRecord2) : [];
120871
122776
  return batch.map((file) => {
120872
122777
  const entry = entries.find((candidate) => {
120873
122778
  const info = isObjectRecord2(candidate.file) ? candidate.file : {};
@@ -120875,21 +122780,62 @@ function readPresignEntries(presign, batch) {
120875
122780
  });
120876
122781
  const fileInfo = isObjectRecord2(entry?.file) ? entry.file : {};
120877
122782
  const objectInfo = isObjectRecord2(fileInfo.objectInfo) ? fileInfo.objectInfo : {};
120878
- if (typeof entry?.signedUrl !== "string") {
122783
+ if (typeof objectInfo.key !== "string") {
120879
122784
  throw new Error(
120880
- `Upload presign response is missing signedUrl for ${file.name}.`
122785
+ `Upload presign response is missing a storage key for ${file.name}.`
120881
122786
  );
120882
122787
  }
120883
- if (typeof objectInfo.key !== "string") {
122788
+ if (multipart === null) {
122789
+ if (typeof entry?.signedUrl !== "string") {
122790
+ throw new Error(
122791
+ `Upload presign response is missing signedUrl for ${file.name}.`
122792
+ );
122793
+ }
122794
+ return {
122795
+ protocol: "single-put",
122796
+ file,
122797
+ signedUrl: entry.signedUrl,
122798
+ storageKey: objectInfo.key,
122799
+ headers: uploadHeaders(entry, objectInfo, file.mimeType)
122800
+ };
122801
+ }
122802
+ if (typeof entry?.completeSignedUrl !== "string") {
120884
122803
  throw new Error(
120885
- `Upload presign response is missing a storage key for ${file.name}.`
122804
+ `Multipart presign response is missing completeSignedUrl for ${file.name}.`
122805
+ );
122806
+ }
122807
+ if (!Array.isArray(entry.parts) || entry.parts.length === 0) {
122808
+ throw new Error(
122809
+ `Multipart presign response is missing parts for ${file.name}.`
122810
+ );
122811
+ }
122812
+ let offset = 0;
122813
+ const parts = entry.parts.map((candidate, index) => {
122814
+ if (!isObjectRecord2(candidate) || candidate.partNumber !== index + 1 || typeof candidate.size !== "number" || !Number.isSafeInteger(candidate.size) || candidate.size <= 0 || typeof candidate.signedUrl !== "string") {
122815
+ throw new Error(
122816
+ `Multipart presign response has invalid part ${index + 1} for ${file.name}.`
122817
+ );
122818
+ }
122819
+ const part = {
122820
+ partNumber: candidate.partNumber,
122821
+ offset,
122822
+ size: candidate.size,
122823
+ signedUrl: candidate.signedUrl
122824
+ };
122825
+ offset += candidate.size;
122826
+ return part;
122827
+ });
122828
+ if (offset !== file.byteLength) {
122829
+ throw new Error(
122830
+ `Multipart presign response covers ${offset}/${file.byteLength} bytes for ${file.name}.`
120886
122831
  );
120887
122832
  }
120888
122833
  return {
122834
+ protocol: "multipart",
120889
122835
  file,
120890
- signedUrl: entry.signedUrl,
120891
122836
  storageKey: objectInfo.key,
120892
- headers: uploadHeaders(entry, objectInfo, file.mimeType)
122837
+ completeSignedUrl: entry.completeSignedUrl,
122838
+ parts
120893
122839
  };
120894
122840
  });
120895
122841
  }
@@ -120908,7 +122854,11 @@ async function postWithTimeout(client, path, body, signal) {
120908
122854
  }
120909
122855
  throw new Error("Upload presign failed after all retry attempts.");
120910
122856
  }
120911
- async function putWithRetry(put, entry, signal) {
122857
+ async function uploadWithRetry(put, entry, signal) {
122858
+ if (entry.protocol === "multipart") {
122859
+ await uploadMultipartWithRetry(put, entry, signal);
122860
+ return;
122861
+ }
120912
122862
  let lastError;
120913
122863
  for (let attempt = 1; attempt <= STORAGE_PUT_ATTEMPTS; attempt += 1) {
120914
122864
  let response;
@@ -120940,6 +122890,83 @@ async function putWithRetry(put, entry, signal) {
120940
122890
  }
120941
122891
  throw lastError instanceof Error ? lastError : new Error(`Storage PUT failed for ${entry.file.name}.`);
120942
122892
  }
122893
+ async function uploadMultipartWithRetry(put, entry, signal) {
122894
+ const uploaded = await mapWithConcurrency(
122895
+ entry.parts,
122896
+ MULTIPART_PART_CONCURRENCY,
122897
+ async (part) => {
122898
+ const body2 = Buffer.from(
122899
+ entry.file.bytes.subarray(part.offset, part.offset + part.size)
122900
+ );
122901
+ const response2 = await requestStorageWithRetry(
122902
+ put,
122903
+ part.signedUrl,
122904
+ { method: "PUT", body: body2 },
122905
+ signal,
122906
+ `multipart part ${part.partNumber}`
122907
+ );
122908
+ const eTag = response2.headers.get("etag");
122909
+ if (eTag === null || eTag.length === 0) {
122910
+ throw new Error(
122911
+ `Multipart upload part ${part.partNumber} for ${entry.file.name} returned no ETag.`
122912
+ );
122913
+ }
122914
+ return { partNumber: part.partNumber, eTag };
122915
+ }
122916
+ );
122917
+ const body = `<CompleteMultipartUpload>${uploaded.sort((left, right) => left.partNumber - right.partNumber).map(
122918
+ ({ partNumber, eTag }) => `<Part><ETag>${escapeXml(eTag)}</ETag><PartNumber>${partNumber}</PartNumber></Part>`
122919
+ ).join("")}</CompleteMultipartUpload>`;
122920
+ const response = await put(entry.completeSignedUrl, {
122921
+ method: "POST",
122922
+ headers: { "content-type": "application/xml" },
122923
+ body,
122924
+ signal: combineSignals(signal, AbortSignal.timeout(STORAGE_PUT_TIMEOUT_MS))
122925
+ });
122926
+ const completion2 = await response.text();
122927
+ if (!response.ok) {
122928
+ throw new Error(
122929
+ `Multipart completion failed (${response.status}): ${completion2}`
122930
+ );
122931
+ }
122932
+ if (completion2.includes("<Error>")) {
122933
+ throw new Error(
122934
+ `Multipart completion for ${entry.file.name} reported an error: ${completion2}`
122935
+ );
122936
+ }
122937
+ }
122938
+ async function requestStorageWithRetry(request, url, init, signal, label) {
122939
+ let lastError;
122940
+ for (let attempt = 1; attempt <= STORAGE_PUT_ATTEMPTS; attempt += 1) {
122941
+ let response;
122942
+ try {
122943
+ response = await request(url, {
122944
+ ...init,
122945
+ signal: combineSignals(
122946
+ signal,
122947
+ AbortSignal.timeout(STORAGE_PUT_TIMEOUT_MS)
122948
+ )
122949
+ });
122950
+ } catch (error) {
122951
+ if (signal.aborted || attempt === STORAGE_PUT_ATTEMPTS) throw error;
122952
+ lastError = error;
122953
+ await waitForRetry(attempt, signal);
122954
+ continue;
122955
+ }
122956
+ if (response.ok) return response;
122957
+ if (!isRetryableStatus(response.status) || attempt === STORAGE_PUT_ATTEMPTS) {
122958
+ throw new Error(
122959
+ `Storage ${label} failed (${response.status}): ${await response.text()}`
122960
+ );
122961
+ }
122962
+ lastError = new Error(`Storage ${label} failed (${response.status}).`);
122963
+ await waitForRetry(attempt, signal);
122964
+ }
122965
+ throw lastError instanceof Error ? lastError : new Error(`Storage ${label} failed.`);
122966
+ }
122967
+ function escapeXml(value) {
122968
+ return value.replace(/&/gu, "&amp;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;").replace(/"/gu, "&quot;").replace(/'/gu, "&apos;");
122969
+ }
120943
122970
  function isRetryableStatus(status) {
120944
122971
  return status === 408 || status === 429 || status >= 500;
120945
122972
  }
@@ -120975,13 +123002,14 @@ async function waitForRetry(attempt, signal) {
120975
123002
  async function mapWithConcurrency(values, concurrency, run) {
120976
123003
  let nextIndex = 0;
120977
123004
  let firstError;
123005
+ const results = new Array(values.length);
120978
123006
  const worker = async () => {
120979
123007
  while (firstError === void 0) {
120980
123008
  const index = nextIndex;
120981
123009
  nextIndex += 1;
120982
123010
  if (index >= values.length) return;
120983
123011
  try {
120984
- await run(values[index]);
123012
+ results[index] = await run(values[index]);
120985
123013
  } catch (error) {
120986
123014
  firstError ??= error;
120987
123015
  }
@@ -120991,6 +123019,7 @@ async function mapWithConcurrency(values, concurrency, run) {
120991
123019
  Array.from({ length: Math.min(concurrency, values.length) }, worker)
120992
123020
  );
120993
123021
  if (firstError !== void 0) throw firstError;
123022
+ return results;
120994
123023
  }
120995
123024
  function combineSignals(...signals) {
120996
123025
  const defined = signals.filter(
@@ -121018,7 +123047,7 @@ function uploadHeaders(entry, objectInfo, mimeType) {
121018
123047
  function versionPath(workspace, suffix) {
121019
123048
  return `/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/${suffix}`;
121020
123049
  }
121021
- var UPLOAD_CONCURRENCY, PRESIGN_TIMEOUT_MS, PRESIGN_ATTEMPTS, STORAGE_PUT_TIMEOUT_MS, STORAGE_PUT_ATTEMPTS, ProjectFilePushCancelledError, RETRYABLE_NETWORK_ERROR_CODES;
123050
+ var UPLOAD_CONCURRENCY, PRESIGN_BATCH_SIZE, MULTIPART_PART_CONCURRENCY, PRESIGN_TIMEOUT_MS, PRESIGN_ATTEMPTS, STORAGE_PUT_TIMEOUT_MS, STORAGE_PUT_ATTEMPTS, ProjectFilePushCancelledError, RETRYABLE_NETWORK_ERROR_CODES;
121022
123051
  var init_project_file_push = __esm({
121023
123052
  "src/project-source/project-file-push.ts"() {
121024
123053
  "use strict";
@@ -121026,6 +123055,11 @@ var init_project_file_push = __esm({
121026
123055
  init_projection();
121027
123056
  init_src();
121028
123057
  UPLOAD_CONCURRENCY = 6;
123058
+ PRESIGN_BATCH_SIZE = Math.min(
123059
+ UPLOAD_CONCURRENCY,
123060
+ PROJECT_FILE_UPLOAD_BATCH_SIZE
123061
+ );
123062
+ MULTIPART_PART_CONCURRENCY = 4;
121029
123063
  PRESIGN_TIMEOUT_MS = 3e4;
121030
123064
  PRESIGN_ATTEMPTS = 3;
121031
123065
  STORAGE_PUT_TIMEOUT_MS = 12e4;
@@ -121243,7 +123277,7 @@ __export(push_exports, {
121243
123277
  runPush: () => runPush,
121244
123278
  stripServerDerivedNeoScript: () => stripServerDerivedNeoScript
121245
123279
  });
121246
- import { createHash as createHash10, randomUUID as randomUUID2 } from "node:crypto";
123280
+ import { createHash as createHash10, randomUUID as randomUUID3 } from "node:crypto";
121247
123281
  import {
121248
123282
  mkdirSync as mkdirSync10,
121249
123283
  writeFileSync as writeFileSync10,
@@ -121289,7 +123323,7 @@ function assignPendingIds(changes, authoredValueSeeds, reconstructed3, localInit
121289
123323
  assigned.set(pendingId2, derived);
121290
123324
  return derived;
121291
123325
  }
121292
- const fresh = randomUUID2();
123326
+ const fresh = randomUUID3();
121293
123327
  assigned.set(pendingId2, fresh);
121294
123328
  return fresh;
121295
123329
  };
@@ -121988,6 +124022,7 @@ async function runPush(workspace, options, preparationOverride) {
121988
124022
  json: options.json === true,
121989
124023
  includeDocument: verifiesConfiguredHook,
121990
124024
  identifyArtifactErrors: true,
124025
+ refreshDerivedEdgeVersion: options.dryRun,
121991
124026
  onPhase: (label) => preparation?.update(label)
121992
124027
  });
121993
124028
  } catch (error) {
@@ -122155,6 +124190,7 @@ async function runPush(workspace, options, preparationOverride) {
122155
124190
  }
122156
124191
  const stagePreparedPush = async () => {
122157
124192
  const client2 = NeoApiClient.forBaseUrl(workspace.config.apiBaseUrl);
124193
+ const stagedUploadSessionId2 = preparedLocal.preparedFiles.length > 0 ? randomUUID3() : null;
122158
124194
  const stagedFiles2 = await stageProjectFilePushesV4({
122159
124195
  workspace,
122160
124196
  changes: status.changes,
@@ -122162,13 +124198,19 @@ async function runPush(workspace, options, preparationOverride) {
122162
124198
  assignedIds: preparedLocal.pendingAssignment.assigned,
122163
124199
  client: client2,
122164
124200
  prepared: preparedLocal.preparedFiles,
124201
+ ...stagedUploadSessionId2 === null ? {} : { stagedUploadSessionId: stagedUploadSessionId2 },
122165
124202
  onProgress: (upload) => progress.report({
122166
124203
  type: "push-progress",
122167
124204
  phase: "uploading",
122168
124205
  ...upload
122169
124206
  })
122170
124207
  });
122171
- return { ...preparedLocal, client: client2, stagedFiles: stagedFiles2 };
124208
+ return {
124209
+ ...preparedLocal,
124210
+ client: client2,
124211
+ stagedFiles: stagedFiles2,
124212
+ stagedUploadSessionId: stagedUploadSessionId2
124213
+ };
122172
124214
  };
122173
124215
  let preparedPush;
122174
124216
  try {
@@ -122189,9 +124231,9 @@ async function runPush(workspace, options, preparationOverride) {
122189
124231
  client,
122190
124232
  transportChanges,
122191
124233
  transportSeeds,
122192
- preparedFiles
124234
+ stagedUploadSessionId
122193
124235
  } = preparedPush;
122194
- let { stagedFiles } = preparedPush;
124236
+ const { stagedFiles } = preparedPush;
122195
124237
  const commit = async (force) => await client.post(
122196
124238
  `/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/schema/commit`,
122197
124239
  {
@@ -122200,12 +124242,14 @@ async function runPush(workspace, options, preparationOverride) {
122200
124242
  authoredValueSeeds: transportSeeds,
122201
124243
  initializerMaterialization: pendingAssignment.localInitializerMaterialization ?? { roots: [] },
122202
124244
  stagedFiles,
124245
+ stagedUploadSessionId,
122203
124246
  sourceHash: source.sourceHash,
122204
124247
  pendingIdAssignments: Object.fromEntries(pendingAssignment.assigned),
122205
124248
  summary: options.summary ?? "neo push",
122206
124249
  // P43 §4. The local evaluator computes against the pulled snapshot, so
122207
124250
  // the server rejects a push whose base is not the project head.
122208
124251
  headTransactionHash: workspace.state.headTransactionHash ?? null,
124252
+ derivedEdgeExtractorVersion: PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION,
122209
124253
  forceRecompile: options.forceRecompile === true
122210
124254
  },
122211
124255
  force ? { "x-neo-force-project-version-write": "true" } : void 0
@@ -122369,40 +124413,29 @@ async function runPush(workspace, options, preparationOverride) {
122369
124413
  fallback: false
122370
124414
  })) {
122371
124415
  progress = createPushProgressReporter(options.json === true);
124416
+ progress.report({
124417
+ type: "project-transaction-progress",
124418
+ transactionId: null,
124419
+ phase: "submitting",
124420
+ totalChangeCount: status.changes.length,
124421
+ appliedChangeCount: 0,
124422
+ totalChunkCount: null,
124423
+ appliedChunkCount: 0,
124424
+ errorCode: null,
124425
+ errorMessage: null
124426
+ });
122372
124427
  try {
122373
- stagedFiles = await stageProjectFilePushesV4({
122374
- workspace,
122375
- changes: status.changes,
122376
- binaryChanges: status.binaryChanges ?? [],
122377
- assignedIds: pendingAssignment.assigned,
122378
- client,
122379
- prepared: preparedFiles,
122380
- onProgress: (upload) => progress.report({
122381
- type: "push-progress",
122382
- phase: "uploading",
122383
- ...upload
122384
- })
122385
- });
122386
- progress.report({
122387
- type: "project-transaction-progress",
122388
- transactionId: null,
122389
- phase: "submitting",
122390
- totalChangeCount: status.changes.length,
122391
- appliedChangeCount: 0,
122392
- totalChunkCount: null,
122393
- appliedChunkCount: 0,
122394
- errorCode: null,
122395
- errorMessage: null
122396
- });
122397
124428
  result = await commit(true);
122398
124429
  } catch (retryError) {
122399
124430
  progress.stop();
122400
- if (retryError instanceof ProjectFilePushCancelledError) {
122401
- if (options.json !== true) console.error("Push cancelled.");
122402
- process.exitCode = 130;
122403
- return;
122404
- }
122405
124431
  if (retryError instanceof NeoApiError) {
124432
+ if (isDefinitiveSchemaCommitRejection(retryError)) {
124433
+ await cleanupRejectedProjectFilePushesV4({
124434
+ workspace,
124435
+ client,
124436
+ stagedUploadSessionId
124437
+ });
124438
+ }
122406
124439
  reportPushRejection(retryError.status, retryError.body);
122407
124440
  process.exitCode = 1;
122408
124441
  return;
@@ -122412,16 +124445,31 @@ async function runPush(workspace, options, preparationOverride) {
122412
124445
  await finishCommitResponse(result, progress);
122413
124446
  return;
122414
124447
  }
124448
+ await cleanupRejectedProjectFilePushesV4({
124449
+ workspace,
124450
+ client,
124451
+ stagedUploadSessionId
124452
+ });
122415
124453
  console.log("Push cancelled.");
122416
124454
  process.exitCode = 1;
122417
124455
  return;
122418
124456
  }
124457
+ if (isDefinitiveSchemaCommitRejection(error)) {
124458
+ await cleanupRejectedProjectFilePushesV4({
124459
+ workspace,
124460
+ client,
124461
+ stagedUploadSessionId
124462
+ });
124463
+ }
122419
124464
  reportPushRejection(error.status, rejection);
122420
124465
  process.exitCode = 1;
122421
124466
  return;
122422
124467
  }
122423
124468
  await finishCommitResponse(result, progress);
122424
124469
  }
124470
+ function isDefinitiveSchemaCommitRejection(error) {
124471
+ return error.status === 400 || error.status === 401 || error.status === 403 || error.status === 404 || error.status === 409;
124472
+ }
122425
124473
  async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => void 0, options = {
122426
124474
  fullValidation: true,
122427
124475
  forceRecompile: false
@@ -122533,6 +124581,14 @@ async function prepareLocalCandidateV4(workspace, options = {}) {
122533
124581
  if (status.changes.length > 0 || status.authoredValueSeeds.size > 0) {
122534
124582
  try {
122535
124583
  documentStatus = pushOptions.dryRun ? cloneStatusForDryRun(status) : status;
124584
+ if (options.refreshDerivedEdgeVersion === true) {
124585
+ const convex = await createConvexClient(workspace);
124586
+ const signal = await convex.query(api2.projectExportData.schemaSignal, {
124587
+ projectId: workspace.config.projectId,
124588
+ versionId: workspace.config.versionId
124589
+ });
124590
+ workspace.state.derivedEdgeVersion = signal?.derivedEdgeVersion ?? null;
124591
+ }
122536
124592
  preparedLocal = await prepareLocalPushArtifactsV4(
122537
124593
  workspace,
122538
124594
  documentStatus,
@@ -122968,8 +125024,10 @@ async function recoverHeadTransactionHashFromSchemaSignal(workspace) {
122968
125024
  versionId: workspace.config.versionId
122969
125025
  });
122970
125026
  workspace.state.headTransactionHash = signal?.transactionHash ?? null;
125027
+ workspace.state.derivedEdgeVersion = signal?.derivedEdgeVersion ?? null;
122971
125028
  } catch {
122972
125029
  workspace.state.headTransactionHash = null;
125030
+ delete workspace.state.derivedEdgeVersion;
122973
125031
  }
122974
125032
  }
122975
125033
  function immediateTransactionId(result) {
@@ -124185,6 +126243,7 @@ var init_push = __esm({
124185
126243
  init_merge();
124186
126244
  init_push_change_intent();
124187
126245
  init_push_body_diagnostics();
126246
+ init_project_snapshot_derived_edges();
124188
126247
  ({
124189
126248
  compileNSVoidBody: compileNSVoidBody2,
124190
126249
  compileNSFunction: compileNSFunction2,
@@ -124241,7 +126300,7 @@ var init_registry2 = __esm({
124241
126300
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
124242
126301
  formatVersion: 4,
124243
126302
  contractVersion: "4.1",
124244
- cliVersion: "0.42.1",
126303
+ cliVersion: "0.43.1",
124245
126304
  projectFileUploadBatchSize: 32,
124246
126305
  documentRecords: {
124247
126306
  member: {
@@ -125664,7 +127723,7 @@ __export(test_exports, {
125664
127723
  maintainNeoTestBuildCache: () => maintainNeoTestBuildCache,
125665
127724
  runTest: () => runTest
125666
127725
  });
125667
- import { createHash as createHash11, randomUUID as randomUUID3 } from "node:crypto";
127726
+ import { createHash as createHash11, randomUUID as randomUUID4 } from "node:crypto";
125668
127727
  import {
125669
127728
  existsSync as existsSync13,
125670
127729
  mkdirSync as mkdirSync11,
@@ -126835,7 +128894,7 @@ async function executeRegisteredSpec(registered, document, selected, timeoutMs,
126835
128894
  }
126836
128895
  function atomicWrite(path, content) {
126837
128896
  mkdirSync11(dirname10(path), { recursive: true });
126838
- const temporary = `${path}.tmp-${String(process.pid)}-${randomUUID3()}`;
128897
+ const temporary = `${path}.tmp-${String(process.pid)}-${randomUUID4()}`;
126839
128898
  writeFileSync11(temporary, content, "utf8");
126840
128899
  renameSync5(temporary, path);
126841
128900
  }
@@ -127374,11 +129433,6 @@ var init_test = __esm({
127374
129433
  // src/commands/doctor.ts
127375
129434
  var doctor_exports = {};
127376
129435
  __export(doctor_exports, {
127377
- NEO_COMPILER_CONTRACT: () => NEO_COMPILER_CONTRACT,
127378
- NEO_FILE_CONTRACT_VERSION: () => NEO_FILE_CONTRACT_VERSION,
127379
- NEO_SOURCE_CONTRACT_VERSION: () => NEO_SOURCE_CONTRACT_VERSION,
127380
- NEO_VSCODE_EXTENSION_CONTRACT_VERSION: () => NEO_VSCODE_EXTENSION_CONTRACT_VERSION,
127381
- NEO_VSCODE_EXTENSION_ID: () => NEO_VSCODE_EXTENSION_ID,
127382
129436
  inspectNeoDoctor: () => inspectNeoDoctor,
127383
129437
  runDoctor: () => runDoctor
127384
129438
  });
@@ -127717,12 +129771,10 @@ var init_doctor = __esm({
127717
129771
  var migrate_exports = {};
127718
129772
  __export(migrate_exports, {
127719
129773
  planCollectionMutation: () => planCollectionMutation,
127720
- resolveAssignTarget: () => resolveAssignTarget,
127721
- resolveCollectionTarget: () => resolveCollectionTarget,
127722
129774
  resolveWriteTarget: () => resolveWriteTarget,
127723
129775
  runMigrate: () => runMigrate
127724
129776
  });
127725
- import { randomUUID as randomUUID4 } from "node:crypto";
129777
+ import { randomUUID as randomUUID5 } from "node:crypto";
127726
129778
  import { existsSync as existsSync15, mkdirSync as mkdirSync12, readdirSync as readdirSync6, writeFileSync as writeFileSync12 } from "node:fs";
127727
129779
  import { join as join17 } from "node:path";
127728
129780
  async function runMigrate(workspace, subcommand, positional, targetRef, json, dependencies = {}) {
@@ -127913,8 +129965,8 @@ async function runMigrate(workspace, subcommand, positional, targetRef, json, de
127913
129965
  return;
127914
129966
  }
127915
129967
  if (subcommand === "run") {
127916
- const client = NeoApiClient.forBaseUrl(workspace.config.apiBaseUrl);
127917
129968
  if (process.argv.includes("--server")) {
129969
+ const client = NeoApiClient.forBaseUrl(workspace.config.apiBaseUrl);
127918
129970
  const result = await client.post(
127919
129971
  `/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/migrations/run`,
127920
129972
  {
@@ -127932,11 +129984,9 @@ async function runMigrate(workspace, subcommand, positional, targetRef, json, de
127932
129984
  }
127933
129985
  await runPendingMigrations(
127934
129986
  workspace,
127935
- client,
127936
129987
  raw,
127937
129988
  migrations,
127938
- positional[0] ?? null,
127939
- json
129989
+ positional[0] ?? null
127940
129990
  );
127941
129991
  return;
127942
129992
  }
@@ -128129,36 +130179,12 @@ function resolveCollectionTarget(write, env, migrationName) {
128129
130179
  `Migration "${migrationName}" mutates a collection through an unsupported target.`
128130
130180
  );
128131
130181
  }
128132
- function resolveAssignTarget(write, instanceValue, migrationName) {
128133
- if (write.kind !== "assign") {
128134
- throw new Error(
128135
- `Migration "${migrationName}" produced a "${write.kind}" write; the current runner only applies plain assignments (this.<Field> = ...).`
128136
- );
128137
- }
128138
- const target = isObjectRecord2(write.target) ? write.target : {};
128139
- const pointer = isObjectRecord2(target.pointer) ? target.pointer : {};
128140
- const keyOf = isObjectRecord2(pointer.keyOf) ? pointer.keyOf : {};
128141
- const receiver = keyOf.pointer;
128142
- if (!isObjectRecord2(receiver) || receiver.type !== "variable" || receiver.variableId !== "__this__" && receiver.variableId !== "__target__") {
128143
- throw new Error(
128144
- `Migration "${migrationName}" assigns to a non-this receiver; the current runner only applies direct this.<Field> assignments.`
128145
- );
128146
- }
128147
- const childKey = readLiteralKey(keyOf.key, migrationName);
128148
- if (!isObjectRecord2(instanceValue) || typeof instanceValue[childKey] !== "string") {
128149
- throw new Error(
128150
- `Migration "${migrationName}" writes "${childKey}" but the instance has no stored value id for that key.`
128151
- );
128152
- }
128153
- return { childKey };
128154
- }
128155
130182
  function migrationTargetClassName(thisClass) {
128156
130183
  if (thisClass === null) return null;
128157
130184
  if (typeof thisClass.name !== "string") return null;
128158
130185
  return thisClass.name;
128159
130186
  }
128160
- async function runPendingMigrations(workspace, client, raw, migrations, onlyRef, dryRunFlagUnused) {
128161
- void dryRunFlagUnused;
130187
+ async function runPendingMigrations(workspace, raw, migrations, onlyRef) {
128162
130188
  const dryRun = process.argv.includes("--dry-run");
128163
130189
  const document = readDocumentArrays(raw);
128164
130190
  const heads = /* @__PURE__ */ new Map();
@@ -128707,7 +130733,7 @@ function planCollectionMutation(args) {
128707
130733
  `Migration "${migrationName}" adds a non-scalar collection entry; minting nested entries is not yet supported (build the value beforehand).`
128708
130734
  );
128709
130735
  }
128710
- const id2 = randomUUID4();
130736
+ const id2 = randomUUID5();
128711
130737
  changes.push({
128712
130738
  recordKind: "value",
128713
130739
  recordId: id2,
@@ -129497,7 +131523,7 @@ __export(content_exports, {
129497
131523
  runLoc: () => runLoc
129498
131524
  });
129499
131525
  import { readFileSync as readFileSync18 } from "node:fs";
129500
- import { randomUUID as randomUUID5 } from "node:crypto";
131526
+ import { randomUUID as randomUUID6 } from "node:crypto";
129501
131527
  function versionPath2(workspace, suffix) {
129502
131528
  return `/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/${suffix}`;
129503
131529
  }
@@ -129580,7 +131606,7 @@ async function runLoc(context, subcommand, positional, file) {
129580
131606
  const config = isObjectRecord2(raw.localizationConfig) ? raw.localizationConfig : {};
129581
131607
  const statusId = config.mainLocale === locale && typeof config.mainLocaleDefaultStatusId === "string" ? config.mainLocaleDefaultStatusId : "localization-status-needs-translation";
129582
131608
  const now = Date.now();
129583
- const textId = typeof body.id === "string" ? body.id : randomUUID5();
131609
+ const textId = typeof body.id === "string" ? body.id : randomUUID6();
129584
131610
  const existingHead = heads.get(`localized-text:${textId}`);
129585
131611
  const text = {
129586
131612
  id: textId,
@@ -130752,8 +132778,7 @@ var init_dev = __esm({
130752
132778
  var resolve_exports = {};
130753
132779
  __export(resolve_exports, {
130754
132780
  resolveMarkers: () => resolveMarkers,
130755
- runResolve: () => runResolve,
130756
- workspaceFilePath: () => workspaceFilePath
132781
+ runResolve: () => runResolve
130757
132782
  });
130758
132783
  import { readFileSync as readFileSync19, rmSync as rmSync8, writeFileSync as writeFileSync14 } from "node:fs";
130759
132784
  import { join as join20 } from "node:path";
@@ -130855,9 +132880,6 @@ function resolveMarkers(source, side) {
130855
132880
  }
130856
132881
  return output.join("\n");
130857
132882
  }
130858
- function workspaceFilePath(workspace, file) {
130859
- return join20(workspace.root, file);
130860
- }
130861
132883
  var init_resolve = __esm({
130862
132884
  "src/commands/resolve.ts"() {
130863
132885
  "use strict";
@@ -131061,7 +133083,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
131061
133083
  async function main() {
131062
133084
  const args = parseArgs(process.argv.slice(2));
131063
133085
  if (args.command === "--version") {
131064
- console.log("0.42.1");
133086
+ console.log("0.43.1");
131065
133087
  return;
131066
133088
  }
131067
133089
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {