@neocompose/cli 0.47.0 → 0.47.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
@@ -43513,7 +43513,13 @@ var init_member_kind_taxonomy = __esm({
43513
43513
  [15 /* Vector2Int */]: [1 /* Direct */, BINDABLE, "vector", 2, 7],
43514
43514
  [16 /* Vector3 */]: [1 /* Direct */, BINDABLE, "vector", 3, 8],
43515
43515
  [17 /* Vector3Int */]: [1 /* Direct */, BINDABLE, "vector", 3, 9],
43516
- [18 /* DialogueLookup */]: [1 /* Direct */, STORED, "core", null, 16],
43516
+ [18 /* DialogueLookup */]: [
43517
+ 1 /* Direct */,
43518
+ STORED,
43519
+ "collection",
43520
+ null,
43521
+ 16
43522
+ ],
43517
43523
  [19 /* Color */]: [1 /* Direct */, BINDABLE, "core", null, 10],
43518
43524
  [20 /* Decimal */]: [1 /* Direct */, BINDABLE, "number", null, 5],
43519
43525
  [21 /* Generic */]: [2 /* Contextual */, STORED, "core", null, null],
@@ -44000,6 +44006,56 @@ var init_neoscript_types = __esm({
44000
44006
  }
44001
44007
  });
44002
44008
 
44009
+ // ../src/models/neoscript/neoscript-compiler-revision.ts
44010
+ function isAcceptedNeoScriptCompilerRevision(stamp, rollout = ACTIVE_NEOSCRIPT_COMPILER_REVISION_ROLLOUT) {
44011
+ if (stamp === NEOSCRIPT_COMPILER_REVISION) return true;
44012
+ if (rollout === null) return false;
44013
+ if (stamp === void 0) return true;
44014
+ if (typeof stamp !== "number") return false;
44015
+ if (!Number.isSafeInteger(stamp)) return false;
44016
+ return stamp >= 1 && stamp < rollout.revision;
44017
+ }
44018
+ function describeNeoScriptCompilerRevisionRejection(stamp, rollout = ACTIVE_NEOSCRIPT_COMPILER_REVISION_ROLLOUT) {
44019
+ const carried = stamp === void 0 ? "carries no compiler revision stamp" : `carries compiler revision ${JSON.stringify(stamp)}`;
44020
+ const remedy = rollout === null ? `push the project source again or queue a recompile with \`npm run compiler-revision:mint\`` : `let migration ${rollout.migrationId} finish or push the project source again`;
44021
+ return `${carried}; this build requires exactly revision ${String(NEOSCRIPT_COMPILER_REVISION)} \u2014 ${remedy}`;
44022
+ }
44023
+ function collectNeoScriptCompiledBodyStamps(record4) {
44024
+ const stamps = [];
44025
+ const visit = (node, path) => {
44026
+ if (Array.isArray(node)) {
44027
+ for (let index = 0; index < node.length; index += 1) {
44028
+ visit(node[index], `${path}[${String(index)}]`);
44029
+ }
44030
+ return;
44031
+ }
44032
+ if (typeof node !== "object" || node === null) return;
44033
+ const object2 = node;
44034
+ if (isCompiledBodyShape(object2)) {
44035
+ stamps.push({ path, stamp: object2.compilerRevision });
44036
+ }
44037
+ for (const key of Object.keys(object2)) {
44038
+ visit(object2[key], path === "" ? key : `${path}.${key}`);
44039
+ }
44040
+ };
44041
+ visit(record4, "");
44042
+ return stamps;
44043
+ }
44044
+ function isCompiledBodyShape(object2) {
44045
+ if (!Array.isArray(object2.parameters)) return false;
44046
+ if (!Array.isArray(object2.instructions)) return false;
44047
+ return Object.prototype.hasOwnProperty.call(object2, "typeInfo");
44048
+ }
44049
+ var ACTIVE_NEOSCRIPT_COMPILER_REVISION_ROLLOUT;
44050
+ var init_neoscript_compiler_revision = __esm({
44051
+ "../src/models/neoscript/neoscript-compiler-revision.ts"() {
44052
+ "use strict";
44053
+ init_src();
44054
+ ACTIVE_NEOSCRIPT_COMPILER_REVISION_ROLLOUT = // <neoscript-compiler-revision-rollout>
44055
+ { migrationId: "neoscript-compiler-revision-13", revision: 13 };
44056
+ }
44057
+ });
44058
+
44003
44059
  // ../src/models/neoscript/neoscript-guards.ts
44004
44060
  function isNSTypeInfoBase(value) {
44005
44061
  const v = value;
@@ -44506,15 +44562,10 @@ function isNSConditionalBranch(value) {
44506
44562
  function isNSFunctionWithReturnType(value) {
44507
44563
  const v = value;
44508
44564
  if (typeof v !== "object" || v === null) return false;
44509
- if (v.compilerRevision !== void 0 && (!Number.isSafeInteger(v.compilerRevision) || v.compilerRevision < 1 || v.compilerRevision > NEOSCRIPT_COMPILER_REVISION)) {
44510
- return false;
44511
- }
44565
+ if (!isAcceptedNeoScriptCompilerRevision(v.compilerRevision)) return false;
44512
44566
  if (!Array.isArray(v.parameters)) return false;
44513
44567
  if (!v.parameters.every(isNSVariable)) return false;
44514
44568
  if (!isNSInstructions(v.instructions)) return false;
44515
- if ((v.compilerRevision ?? 1) < NEOSCRIPT_COMPILER_REVISION && (v.compilerRevision ?? 1) < minimumNeoScriptCompilerRevisionForIR(v.instructions)) {
44516
- return false;
44517
- }
44518
44569
  if (!isNSTypeInfo(v.typeInfo)) return false;
44519
44570
  return true;
44520
44571
  }
@@ -44968,38 +45019,6 @@ function isNSInstructionTry(value) {
44968
45019
  function isNSInstruction(value) {
44969
45020
  return isNSInstructionVariable(value) || isNSInstructionIfBranch(value) || isNSInstructionReturn(value) || isNSInstructionThrow(value) || isNSInstructionAssign(value) || isNSInstructionCollectionCall(value) || isNSInstructionFunctionCall(value) || isNSInstructionFor(value) || isNSInstructionForEach(value) || isNSInstructionBreak(value) || isNSInstructionContinue(value) || isNSInstructionSwitch(value) || isNSInstructionTry(value) || isNSInstructionAddActionListener(value) || isNSInstructionRemoveActionListener(value);
44970
45021
  }
44971
- function minimumNeoScriptCompilerRevisionForIR(node, visited = /* @__PURE__ */ new Set()) {
44972
- if (Array.isArray(node)) {
44973
- let minimum2 = 1;
44974
- for (const entry of node) {
44975
- minimum2 = Math.max(
44976
- minimum2,
44977
- minimumNeoScriptCompilerRevisionForIR(entry, visited)
44978
- );
44979
- }
44980
- return minimum2;
44981
- }
44982
- if (typeof node !== "object" || node === null) return 1;
44983
- if (visited.has(node)) return 1;
44984
- visited.add(node);
44985
- const discriminatorRevision = "type" in node && typeof node.type === "string" ? MINIMUM_REVISION_BY_IR_DISCRIMINATOR.get(node.type) ?? 1 : 1;
44986
- const fallbackRevision = "missingMemberFallback" in node && node.missingMemberFallback === "valueEquality" ? 12 : 1;
44987
- const countPredicateRevision = "type" in node && node.type === "count" /* count */ && "info" in node && typeof node.info === "object" && node.info !== null && "function" in node.info && node.info.function !== void 0 && node.info.function !== null ? 13 : 1;
44988
- let minimum = Math.max(
44989
- discriminatorRevision,
44990
- fallbackRevision,
44991
- countPredicateRevision
44992
- );
44993
- const isLiteralValue = "typeInfo" in node && "value" in node && !("type" in node);
44994
- for (const [key, child] of Object.entries(node)) {
44995
- if (isLiteralValue && key === "value") continue;
44996
- minimum = Math.max(
44997
- minimum,
44998
- minimumNeoScriptCompilerRevisionForIR(child, visited)
44999
- );
45000
- }
45001
- return minimum;
45002
- }
45003
45022
  function isNSInstructions(value) {
45004
45023
  return Array.isArray(value) && value.every(isNSInstruction);
45005
45024
  }
@@ -45046,11 +45065,11 @@ function isNSVoidBody(value) {
45046
45065
  if (value.typeInfo.type !== 0 /* Null */) return false;
45047
45066
  return value.typeInfo.required === true;
45048
45067
  }
45049
- var NS_STRING_OPS, NS_DECIMAL_OPS, NS_MATH_OPS, MINIMUM_REVISION_BY_IR_DISCRIMINATOR;
45068
+ var NS_STRING_OPS, NS_DECIMAL_OPS, NS_MATH_OPS;
45050
45069
  var init_neoscript_guards = __esm({
45051
45070
  "../src/models/neoscript/neoscript-guards.ts"() {
45052
45071
  "use strict";
45053
- init_src();
45072
+ init_neoscript_compiler_revision();
45054
45073
  init_member_kinds();
45055
45074
  init_core();
45056
45075
  init_neoscript_types();
@@ -45079,21 +45098,6 @@ var init_neoscript_guards = __esm({
45079
45098
  "sign",
45080
45099
  "sqrt"
45081
45100
  ];
45082
- MINIMUM_REVISION_BY_IR_DISCRIMINATOR = /* @__PURE__ */ new Map([
45083
- ["for" /* for */, 4],
45084
- ["forEach" /* forEach */, 4],
45085
- ["break" /* break */, 4],
45086
- ["continue" /* continue */, 4],
45087
- ["switch" /* switch */, 5],
45088
- ["try" /* try */, 6],
45089
- ["callDelegate" /* callDelegate */, 7],
45090
- ["addActionListener" /* addActionListener */, 8],
45091
- ["removeActionListener" /* removeActionListener */, 8],
45092
- ["callAction" /* callAction */, 8],
45093
- ["conditional" /* conditional */, 12],
45094
- ["delegateClosure" /* delegateClosure */, 12],
45095
- ["indexOf" /* indexOf */, 13]
45096
- ]);
45097
45101
  }
45098
45102
  });
45099
45103
 
@@ -45281,6 +45285,7 @@ var init_neoscript = __esm({
45281
45285
  init_neoscript_guards();
45282
45286
  init_parameter_defaults();
45283
45287
  init_type_info_compatibility();
45288
+ init_neoscript_compiler_revision();
45284
45289
  }
45285
45290
  });
45286
45291
 
@@ -57360,6 +57365,7 @@ function pendingGroupIdentity(global, kind, ordinal, name) {
57360
57365
  }
57361
57366
  function placeholderBoolGetter() {
57362
57367
  return {
57368
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
57363
57369
  parameters: [],
57364
57370
  typeInfo: { type: 1, required: true },
57365
57371
  instructions: [
@@ -67995,6 +68001,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
67995
68001
  resolveMemberDeclaredTypeInfoInternal(collection, members, nextSeen)
67996
68002
  );
67997
68003
  }
68004
+ if (resolved.kind === 9 /* Lookup */) return null;
67998
68005
  if (!memberKindSupportsStorage(resolved.kind)) return null;
67999
68006
  if (resolved.kind === 21 /* Generic */) return null;
68000
68007
  return {
@@ -75491,25 +75498,16 @@ function evalDeclaredListIndex(info, scope, ctx) {
75491
75498
  function prepareCollectionCallback(callback, parentScope, ctx, isList, returnContract, onPredicateMatch) {
75492
75499
  const metrics = ctx.__collectionCallbackPreparationMetrics;
75493
75500
  if (metrics !== void 0) metrics.bodyValidations += 1;
75494
- const compilerRevision = callback.compilerRevision ?? 1;
75495
- if (!Number.isSafeInteger(compilerRevision)) {
75501
+ const compilerRevision = callback.compilerRevision;
75502
+ if (!isAcceptedNeoScriptCompilerRevision(compilerRevision)) {
75496
75503
  throw new NSGetterRuntimeError(
75497
- "Collection callback compiler revision must be a safe integer."
75498
- );
75499
- }
75500
- if (compilerRevision < 1) {
75501
- throw new NSGetterRuntimeError(
75502
- "Collection callback compiler revision must be at least 1."
75503
- );
75504
- }
75505
- if (compilerRevision > NEOSCRIPT_COMPILER_REVISION) {
75506
- throw new NSGetterRuntimeError(
75507
- `Collection callback compiler revision ${String(compilerRevision)} is newer than supported revision ${String(NEOSCRIPT_COMPILER_REVISION)}.`
75504
+ `Collection callback ${describeNeoScriptCompilerRevisionRejection(compilerRevision)}.`
75508
75505
  );
75509
75506
  }
75510
75507
  if (!isNSFunctionWithReturnType(callback)) {
75508
+ const stamp = compilerRevision === void 0 ? "(unstamped)" : String(compilerRevision);
75511
75509
  throw new NSGetterRuntimeError(
75512
- `Collection callback body metadata is invalid for compiler revision ${String(compilerRevision)}.`
75510
+ `Collection callback body metadata is invalid for compiler revision ${stamp}.`
75513
75511
  );
75514
75512
  }
75515
75513
  const parameters = callback.parameters;
@@ -79535,7 +79533,6 @@ var init_evaluateNSGetter = __esm({
79535
79533
  init_neoscript();
79536
79534
  init_NSGetterRuntimeError();
79537
79535
  init_value_row_owner_members();
79538
- init_src();
79539
79536
  init_decimal();
79540
79537
  init_members();
79541
79538
  init_packed_value_encoding();
@@ -80722,10 +80719,29 @@ function resolveVirtualInstanceGraph(args) {
80722
80719
  return comparison;
80723
80720
  };
80724
80721
  const rootLocation = resolvePath(ROOT_PATH, args.instanceRoot.id, null);
80722
+ const canonicalReceiver = (id2) => locationsById.get(id2)?.virtualRow.id ?? id2;
80723
+ for (const location3 of locationsByPath.values()) {
80724
+ if (location3.materializedRow !== null) continue;
80725
+ if (location3.member.kind !== 25 /* NSDelegate */) continue;
80726
+ const effective = rowsById.get(location3.id);
80727
+ effective.value = remapMemberDelegateReceiver(effective.value, (id2) => {
80728
+ const target = expansion.nodesByExpandedId.get(id2);
80729
+ return target === void 0 ? id2 : locationsByPath.get(target.pathKey)?.id ?? target.virtualId;
80730
+ });
80731
+ }
80732
+ const compareLeafContent = (location3) => location3.materializedRow !== null && semanticEqual(
80733
+ normalizeLeafPayload(
80734
+ location3.materializedRow,
80735
+ location3.member,
80736
+ canonicalReceiver
80737
+ ),
80738
+ normalizeLeafPayload(location3.virtualRow, location3.member)
80739
+ );
80725
80740
  return {
80726
80741
  instanceRootId: args.instanceRoot.id,
80727
80742
  pinnedRootSchemaKeys: args.pinnedRootSchemaKeys,
80728
80743
  compareCreationProvenance,
80744
+ compareLeafContent,
80729
80745
  rowsById,
80730
80746
  locationsById,
80731
80747
  locationsByPath,
@@ -80739,7 +80755,9 @@ function mergeExpandedAndMaterializedRow(expanded, materialized) {
80739
80755
  const expandedClone = cloneRow(expanded);
80740
80756
  if (materialized === null) return expandedClone;
80741
80757
  const materializedClone = cloneRow(materialized);
80742
- return isLiteralValueContent(materialized) ? overlayLiteralValueContent(expandedClone, materializedClone) : { ...expandedClone, ...materializedClone };
80758
+ const merged = isLiteralValueContent(materialized) ? overlayLiteralValueContent(expandedClone, materializedClone) : { ...expandedClone, ...materializedClone };
80759
+ if (merged.sourceValueId === materialized.id) delete merged.sourceValueId;
80760
+ return merged;
80743
80761
  }
80744
80762
  function firstUnattributableExpansionMember(expansion) {
80745
80763
  for (const node of expansion.nodesByPath.values()) {
@@ -81047,10 +81065,7 @@ function planCollapseVirtualInstance(args) {
81047
81065
  if (named === void 0) return false;
81048
81066
  if (!isLiteralValueContent(stored)) return false;
81049
81067
  if (!isLiteralValueContent(named)) {
81050
- return semanticEqual(
81051
- normalizeLeafPayload(stored, location3.member),
81052
- normalizeLeafPayload(location3.virtualRow, location3.member)
81053
- );
81068
+ return args.graph.compareLeafContent(location3);
81054
81069
  }
81055
81070
  return semanticEqual(
81056
81071
  normalizeLeafPayload(named, location3.member),
@@ -81182,6 +81197,7 @@ function planCollapseVirtualInstance(args) {
81182
81197
  contentEqual &&= bothArrays;
81183
81198
  contentEqual &&= lengthsAgree;
81184
81199
  for (let index = 0; index < (stored2?.length ?? 0); index += 1) {
81200
+ if (stored2?.[index] === null && virtual?.[index] === null) continue;
81185
81201
  const child = args.graph.locationsByPath.get(
81186
81202
  appendPath(location3.pathKey, { kind: "list", index })
81187
81203
  );
@@ -81220,10 +81236,7 @@ function planCollapseVirtualInstance(args) {
81220
81236
  protectedSubtree ||= facts.protected;
81221
81237
  }
81222
81238
  } else {
81223
- const leafEqual = semanticEqual(
81224
- normalizeLeafPayload(real, location3.member),
81225
- normalizeLeafPayload(location3.virtualRow, location3.member)
81226
- );
81239
+ const leafEqual = args.graph.compareLeafContent(location3);
81227
81240
  defaultEqual &&= leafEqual;
81228
81241
  contentEqual &&= leafEqual;
81229
81242
  }
@@ -81481,12 +81494,25 @@ function sparsifyConstructedInstance(args) {
81481
81494
  Object.entries(value).map(([key, entry]) => [key, remap(entry)])
81482
81495
  );
81483
81496
  };
81497
+ const remapReceiver = (id2) => {
81498
+ const retainedId = nextIdById.get(id2);
81499
+ if (retainedId !== void 0) return retainedId;
81500
+ const receiver = graph.locationsById.get(id2);
81501
+ if (receiver === void 0) return id2;
81502
+ return args.virtualValueIdForSource?.(
81503
+ args.constructed.root.id,
81504
+ receiver.sourceIdentity
81505
+ ) ?? receiver.virtualRow.id;
81506
+ };
81484
81507
  const rewrite = (row) => {
81485
81508
  const literal3 = literalRow(row);
81509
+ const payload = updatedValueById.get(row.id) ?? literal3.value;
81510
+ const member = graph.locationsById.get(row.id)?.member ?? materializedGraph.ownerForValue(row.id);
81511
+ const value = member?.kind === 25 /* NSDelegate */ && isMemberDelegateTarget(payload) ? remapMemberDelegateReceiver(payload, remapReceiver) : remap(payload);
81486
81512
  return {
81487
81513
  ...literal3,
81488
81514
  id: nextIdById.get(row.id) ?? row.id,
81489
- value: remap(updatedValueById.get(row.id) ?? literal3.value),
81515
+ value,
81490
81516
  ...literal3.constructorArgs === void 0 ? {} : {
81491
81517
  constructorArgs: remap(literal3.constructorArgs)
81492
81518
  },
@@ -81844,6 +81870,9 @@ function rewriteExpandedRow(node, expansion) {
81844
81870
  (childId) => typeof childId === "string" ? rewrite(childId) : childId
81845
81871
  );
81846
81872
  }
81873
+ if (node.member.kind === 25 /* NSDelegate */) {
81874
+ row.value = remapMemberDelegateReceiver(row.value, rewrite);
81875
+ }
81847
81876
  if (typeof row.containerId === "string") {
81848
81877
  row.containerId = rewrite(row.containerId);
81849
81878
  }
@@ -81880,7 +81909,12 @@ function sparseParentBody(segment, childId) {
81880
81909
  "A positional List override materializes the List atomically, not as a sparse child spine."
81881
81910
  );
81882
81911
  }
81883
- function normalizeLeafPayload(row, member) {
81912
+ function remapMemberDelegateReceiver(value, remap) {
81913
+ if (!isMemberDelegateTarget(value) || value.valueId === null) return value;
81914
+ const valueId = remap(value.valueId);
81915
+ return valueId === value.valueId ? value : { ...value, valueId };
81916
+ }
81917
+ function normalizeLeafPayload(row, member, remapReceiver = (id2) => id2) {
81884
81918
  const literal3 = literalRow(row);
81885
81919
  if (isMemberListBase(member) || isMemberDictionaryBase(member)) {
81886
81920
  return {
@@ -81889,7 +81923,8 @@ function normalizeLeafPayload(row, member) {
81889
81923
  constructorArgs: literal3.constructorArgs ?? {}
81890
81924
  };
81891
81925
  }
81892
- return { value: literal3.value, classId: literal3.classId ?? null };
81926
+ const value = member.kind === 25 /* NSDelegate */ ? remapMemberDelegateReceiver(literal3.value, remapReceiver) : literal3.value;
81927
+ return { value, classId: literal3.classId ?? null };
81893
81928
  }
81894
81929
  function compareContextualCreationProvenance(left, right, context) {
81895
81930
  const effectiveType = (row) => {
@@ -83670,10 +83705,18 @@ function readArrayField(source, key, isValid) {
83670
83705
  }
83671
83706
  if (value.every(isValid)) return value;
83672
83707
  const invalidIndex = value.findIndex((item) => !isValid(item));
83708
+ const invalidItem = value[invalidIndex];
83673
83709
  throw new Error(
83674
- `Convex project document field "${key}" has an invalid shape at index ${invalidIndex}: ${describeInvalidReadItem(value[invalidIndex])}.`
83710
+ `Convex project document field "${key}" has an invalid shape at index ${invalidIndex}: ${describeInvalidReadItem(invalidItem)}${describeRejectedCompilerRevision(invalidItem)}.`
83675
83711
  );
83676
83712
  }
83713
+ function describeRejectedCompilerRevision(value) {
83714
+ for (const body of collectNeoScriptCompiledBodyStamps(value)) {
83715
+ if (isAcceptedNeoScriptCompilerRevision(body.stamp)) continue;
83716
+ return `; NeoScript compiler revision rejection: ${body.path} ${describeNeoScriptCompilerRevisionRejection(body.stamp)}`;
83717
+ }
83718
+ return "";
83719
+ }
83677
83720
  function readOptionalArrayField(source, key, isValid) {
83678
83721
  if (!Object.prototype.hasOwnProperty.call(source, key)) return [];
83679
83722
  return readArrayField(source, key, isValid);
@@ -83718,6 +83761,7 @@ var init_project_document_read = __esm({
83718
83761
  init_variants2();
83719
83762
  init_dialogue();
83720
83763
  init_enum2();
83764
+ init_neoscript();
83721
83765
  init_interfaces();
83722
83766
  init_files();
83723
83767
  init_localization2();
@@ -84454,6 +84498,202 @@ var init_primary_localized_text_writes = __esm({
84454
84498
  }
84455
84499
  });
84456
84500
 
84501
+ // ../src/database/neo-script-derived-bodies.ts
84502
+ function cloneAndStripClientDerivedBodies(change) {
84503
+ if (change.operation === "delete" || change.nextData === void 0) {
84504
+ return { ...change };
84505
+ }
84506
+ return {
84507
+ ...change,
84508
+ nextData: stripClientDerivedBodies(change.recordKind, change.nextData)
84509
+ };
84510
+ }
84511
+ function stripClientDerivedBodies(recordKind, nextData) {
84512
+ const record4 = asRecord2(nextData);
84513
+ return record4 === null ? nextData : strippedClone(recordKind, record4);
84514
+ }
84515
+ function hasPendingNeoScriptDerivation(recordKind, data) {
84516
+ const record4 = asRecord2(data);
84517
+ if (record4 === null) return false;
84518
+ return collectDerivedBodySites(recordKind, record4).some(
84519
+ (site) => site.authored && !(site.key in site.container)
84520
+ );
84521
+ }
84522
+ function strippedClone(recordKind, record4) {
84523
+ const next = structuredClone(record4);
84524
+ const container = asRecord2(next);
84525
+ if (container === null) return next;
84526
+ for (const site of collectDerivedBodySites(recordKind, container)) {
84527
+ delete site.container[site.key];
84528
+ }
84529
+ return next;
84530
+ }
84531
+ function collectDerivedBodySites(recordKind, record4) {
84532
+ const sites = [];
84533
+ if (recordKind === "migration") {
84534
+ sites.push({
84535
+ container: record4,
84536
+ key: "action",
84537
+ authored: typeof record4.code === "string"
84538
+ });
84539
+ return sites;
84540
+ }
84541
+ if (recordKind === "dialogue-group") {
84542
+ collectConditionSites(record4.conditions, sites);
84543
+ return sites;
84544
+ }
84545
+ if (recordKind === "dialogue-node") {
84546
+ collectDialogueNodeSites(record4, sites);
84547
+ return sites;
84548
+ }
84549
+ if (recordKind === "constructor") {
84550
+ sites.push({ container: record4, key: "action", authored: true });
84551
+ sites.push({
84552
+ container: record4,
84553
+ key: "compiledBaseArguments",
84554
+ authored: false
84555
+ });
84556
+ sites.push({
84557
+ container: record4,
84558
+ key: "compiledBaseInitializerFields",
84559
+ authored: false
84560
+ });
84561
+ return sites;
84562
+ }
84563
+ if (recordKind === "value") {
84564
+ collectInitializerSite(record4, sites);
84565
+ collectDelegateClosureSite(record4, sites, true);
84566
+ collectInlineDelegateArgumentSites(record4, sites);
84567
+ return sites;
84568
+ }
84569
+ if (recordKind !== "member") return sites;
84570
+ if (record4.kind === 10 /* NSProperty */) {
84571
+ sites.push({
84572
+ container: record4,
84573
+ key: "getter",
84574
+ authored: typeof record4.code === "string"
84575
+ });
84576
+ sites.push({
84577
+ container: record4,
84578
+ key: "setter",
84579
+ authored: typeof record4.setterCode === "string"
84580
+ });
84581
+ }
84582
+ if (record4.kind === 23 /* NSFunction */) {
84583
+ sites.push({
84584
+ container: record4,
84585
+ key: "action",
84586
+ authored: typeof record4.code === "string"
84587
+ });
84588
+ }
84589
+ if (record4.kind === 25 /* NSDelegate */) {
84590
+ collectDelegateClosureSite(asRecord2(record4.defaultValue), sites, false);
84591
+ }
84592
+ collectInitializerSite(asRecord2(record4.defaultValue), sites);
84593
+ return sites;
84594
+ }
84595
+ function collectDialogueNodeSites(node, sites) {
84596
+ collectConditionSites(node.conditions, sites);
84597
+ collectTextVariableSites(node.variables, sites);
84598
+ if (Array.isArray(node.actions)) {
84599
+ for (const actionValue2 of node.actions) {
84600
+ const logic = asRecord2(asRecord2(actionValue2)?.logic);
84601
+ if (logic === null) continue;
84602
+ if (logic.type !== 1 /* Code */) continue;
84603
+ if (typeof logic.code !== "string") continue;
84604
+ sites.push({ container: logic, key: "action", authored: true });
84605
+ }
84606
+ }
84607
+ if (Array.isArray(node.outcomes)) {
84608
+ for (const outcomeValue of node.outcomes) {
84609
+ collectConditionSites(asRecord2(outcomeValue)?.conditions, sites);
84610
+ }
84611
+ }
84612
+ const options = asRecord2(node.optionSettings)?.options;
84613
+ if (!Array.isArray(options)) return;
84614
+ for (const optionValue of options) {
84615
+ const option = asRecord2(optionValue);
84616
+ if (option === null) continue;
84617
+ collectTextVariableSites(option.variables, sites);
84618
+ const settings = asRecord2(option.settings);
84619
+ if (settings === null) continue;
84620
+ collectConditionSites(settings.conditions, sites);
84621
+ collectConditionSites(settings.selectableConditions, sites);
84622
+ }
84623
+ }
84624
+ function collectConditionSites(value, sites) {
84625
+ if (!Array.isArray(value)) return;
84626
+ for (const conditionValue of value) {
84627
+ const condition = asRecord2(conditionValue);
84628
+ if (condition === null) continue;
84629
+ if (condition.type !== 1 /* Code */) continue;
84630
+ if (typeof condition.code !== "string") continue;
84631
+ sites.push({ container: condition, key: "getter", authored: true });
84632
+ }
84633
+ }
84634
+ function collectTextVariableSites(value, sites) {
84635
+ const variables = asRecord2(value);
84636
+ if (variables === null) return;
84637
+ for (const variableValue of Object.values(variables)) {
84638
+ const variable2 = asRecord2(variableValue);
84639
+ if (variable2 === null) continue;
84640
+ if (typeof variable2.code !== "string") continue;
84641
+ sites.push({ container: variable2, key: "getter", authored: true });
84642
+ }
84643
+ }
84644
+ function collectDelegateClosureSite(container, sites, authored) {
84645
+ const delegate = asRecord2(container?.value);
84646
+ if (delegate === null) return;
84647
+ if (typeof delegate.code !== "string") return;
84648
+ sites.push({ container: delegate, key: "action", authored });
84649
+ }
84650
+ function collectInlineDelegateArgumentSites(record4, sites) {
84651
+ const constructorArgs = asRecord2(record4.constructorArgs);
84652
+ if (constructorArgs === null) return;
84653
+ for (const argument2 of Object.values(constructorArgs)) {
84654
+ const closure = asRecord2(argument2);
84655
+ if (closure === null) continue;
84656
+ if (typeof closure.code !== "string") continue;
84657
+ sites.push({ container: closure, key: "action", authored: true });
84658
+ }
84659
+ }
84660
+ function collectInitializerSite(container, sites) {
84661
+ const init = asRecord2(container?.init);
84662
+ if (init === null) return;
84663
+ sites.push({ container: init, key: "compiled", authored: true });
84664
+ }
84665
+ function stripDerivedBodies(member) {
84666
+ return strippedClone("member", member);
84667
+ }
84668
+ function stripConstructorDerivedBodies(constructorRecord) {
84669
+ return strippedClone("constructor", constructorRecord);
84670
+ }
84671
+ function stripMigrationAction(migration) {
84672
+ return strippedClone("migration", migration);
84673
+ }
84674
+ function stampUILogicBody(logic, bodyKey) {
84675
+ if (logic?.type !== 0 /* UI */) return false;
84676
+ const body = asRecord2(logic[bodyKey]);
84677
+ if (body === null) return false;
84678
+ if (body.compilerRevision === NEOSCRIPT_COMPILER_REVISION) return false;
84679
+ body.compilerRevision = NEOSCRIPT_COMPILER_REVISION;
84680
+ return true;
84681
+ }
84682
+ function asRecord2(value) {
84683
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
84684
+ return null;
84685
+ }
84686
+ return value;
84687
+ }
84688
+ var init_neo_script_derived_bodies = __esm({
84689
+ "../src/database/neo-script-derived-bodies.ts"() {
84690
+ "use strict";
84691
+ init_members();
84692
+ init_dialogue();
84693
+ init_src();
84694
+ }
84695
+ });
84696
+
84457
84697
  // ../src/database/neo-script-recompile-scope.ts
84458
84698
  function memberNeoScriptContractChanged(current, next) {
84459
84699
  return canonicalJsonStringify(neoScriptMemberContractProjection(current)) !== canonicalJsonStringify(neoScriptMemberContractProjection(next));
@@ -84554,12 +84794,13 @@ function collectNeoScriptRecompileTargets(args) {
84554
84794
  };
84555
84795
  const memberIds = new Set(explicit.memberIds);
84556
84796
  for (const member of args.postDocument.members) {
84557
- if (recordDependsOnChangedContract(member, impactScope)) {
84797
+ if (recordDependsOnChangedContract("member", member, impactScope)) {
84558
84798
  memberIds.add(member.id);
84559
84799
  }
84560
84800
  }
84561
84801
  const postValues = args.postDocument.values ?? [];
84562
84802
  const valueIds = selectedRecordIds(
84803
+ "value",
84563
84804
  postValues,
84564
84805
  explicit.valueIds,
84565
84806
  impactScope
@@ -84587,22 +84828,26 @@ function collectNeoScriptRecompileTargets(args) {
84587
84828
  complete: false,
84588
84829
  memberIds,
84589
84830
  constructorIds: selectedRecordIds(
84831
+ "constructor",
84590
84832
  args.postDocument.constructors ?? [],
84591
84833
  explicit.constructorIds,
84592
84834
  impactScope,
84593
84835
  (record4) => constructorOwnerById.get(record4.id) ?? null
84594
84836
  ),
84595
84837
  migrationIds: selectedRecordIds(
84838
+ "migration",
84596
84839
  args.postDocument.migrations ?? [],
84597
84840
  explicit.migrationIds,
84598
84841
  impactScope
84599
84842
  ),
84600
84843
  dialogueNodeIds: selectedRecordIds(
84844
+ "dialogue-node",
84601
84845
  args.postDocument.dialogueNodes ?? [],
84602
84846
  explicit.dialogueNodeIds,
84603
84847
  impactScope
84604
84848
  ),
84605
84849
  dialogueGroupIds: selectedRecordIds(
84850
+ "dialogue-group",
84606
84851
  args.postDocument.dialogueGroups ?? [],
84607
84852
  explicit.dialogueGroupIds,
84608
84853
  impactScope
@@ -84984,17 +85229,17 @@ function explicitTargetIds(changes) {
84984
85229
  }
84985
85230
  return result;
84986
85231
  }
84987
- function selectedRecordIds(records2, explicitIds, scope, ownerId = () => null) {
85232
+ function selectedRecordIds(recordKind, records2, explicitIds, scope, ownerId = () => null) {
84988
85233
  const selected = new Set(explicitIds);
84989
85234
  for (const record4 of records2) {
84990
85235
  const owner = ownerId(record4);
84991
- if (owner !== null && scope.impactedIds.has(owner) || recordDependsOnChangedContract(record4, scope)) {
85236
+ if (owner !== null && scope.impactedIds.has(owner) || recordDependsOnChangedContract(recordKind, record4, scope)) {
84992
85237
  selected.add(record4.id);
84993
85238
  }
84994
85239
  }
84995
85240
  return selected;
84996
85241
  }
84997
- function recordDependsOnChangedContract(record4, scope) {
85242
+ function recordDependsOnChangedContract(recordKind, record4, scope) {
84998
85243
  const recordId = isObjectRecord4(record4) ? record4.id : void 0;
84999
85244
  if (typeof recordId === "string" && scope.impactedIds.has(recordId)) {
85000
85245
  return true;
@@ -85008,6 +85253,7 @@ function recordDependsOnChangedContract(record4, scope) {
85008
85253
  if (intersects(collectConstructedClassIds(record4), scope.constructedClassIds)) {
85009
85254
  return true;
85010
85255
  }
85256
+ if (hasPendingNeoScriptDerivation(recordKind, record4)) return true;
85011
85257
  if (scope.impactedIds.size === 0 && scope.impactedTypeNames.size === 0) {
85012
85258
  return false;
85013
85259
  }
@@ -85214,6 +85460,7 @@ var init_neo_script_recompile_scope = __esm({
85214
85460
  "../src/database/neo-script-recompile-scope.ts"() {
85215
85461
  "use strict";
85216
85462
  init_variant_value_graph();
85463
+ init_neo_script_derived_bodies();
85217
85464
  init_canonical_json();
85218
85465
  init_src();
85219
85466
  init_member_kind_enum();
@@ -89452,6 +89699,7 @@ function stripTrailingSemicolon(value) {
89452
89699
  }
89453
89700
  function placeholderBoolGetter2() {
89454
89701
  return {
89702
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
89455
89703
  parameters: [],
89456
89704
  typeInfo: { type: 1, required: true },
89457
89705
  instructions: [
@@ -89467,6 +89715,7 @@ function placeholderBoolGetter2() {
89467
89715
  }
89468
89716
  function placeholderVoidAction() {
89469
89717
  return {
89718
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
89470
89719
  parameters: [],
89471
89720
  typeInfo: { type: 0, required: true },
89472
89721
  instructions: []
@@ -89474,6 +89723,7 @@ function placeholderVoidAction() {
89474
89723
  }
89475
89724
  function placeholderStringGetter() {
89476
89725
  return {
89726
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
89477
89727
  parameters: [],
89478
89728
  typeInfo: { type: 3, required: true },
89479
89729
  instructions: [
@@ -97359,7 +97609,7 @@ var init_project_version_transaction_planning = __esm({
97359
97609
  delete: { documentsRead: 6, documentsWritten: 3, databaseQueries: 14 }
97360
97610
  };
97361
97611
  SCHEMA_CHANGE_COUNT_COSTS = {
97362
- create: { documentsRead: 3, documentsWritten: 5, databaseQueries: 12 },
97612
+ create: { documentsRead: 9, documentsWritten: 7, databaseQueries: 9 },
97363
97613
  update: { documentsRead: 6, documentsWritten: 5, databaseQueries: 22 },
97364
97614
  delete: { documentsRead: 6, documentsWritten: 5, databaseQueries: 22 }
97365
97615
  };
@@ -97862,7 +98112,7 @@ function projectValueHeadPlacementGraph(args) {
97862
98112
  } : null;
97863
98113
  const storedMember = item.memberId === null ? void 0 : members.get(item.memberId);
97864
98114
  if (rootlessMember === null && storedMember === void 0) continue;
97865
- const member = rootlessMember ?? contextualMember(
98115
+ const member = rootlessMember ?? item.constructorMember ?? contextualMember(
97866
98116
  resolvedMember(storedMember),
97867
98117
  item.bindings ?? emptyBindings
97868
98118
  );
@@ -97955,7 +98205,25 @@ function projectValueHeadPlacementGraph(args) {
97955
98205
  }
97956
98206
  for (const edge of constructorEdgesByOwner.get(item.valueId) ?? []) {
97957
98207
  const childMember = members.get(edge.memberId);
97958
- const childName = childMember === void 0 ? null : stringOrNull(resolvedMember(childMember).name);
98208
+ let constructorMember;
98209
+ if (edge.member !== void 0) {
98210
+ if (!isRecord7(edge.member)) {
98211
+ throw new Error(
98212
+ `Constructor value edge for "${edge.targetValueId}" has a non-object member "${edge.memberId}".`
98213
+ );
98214
+ }
98215
+ if (edge.member.id !== edge.memberId) {
98216
+ throw new Error(
98217
+ `Constructor value edge for "${edge.targetValueId}" has mismatched member "${edge.memberId}".`
98218
+ );
98219
+ }
98220
+ constructorMember = edge.member;
98221
+ }
98222
+ let childName = null;
98223
+ if (constructorMember !== void 0)
98224
+ childName = stringOrNull(constructorMember.name);
98225
+ else if (childMember !== void 0)
98226
+ childName = stringOrNull(resolvedMember(childMember).name);
97959
98227
  queue.push({
97960
98228
  valueId: edge.targetValueId,
97961
98229
  memberId: edge.memberId,
@@ -97967,6 +98235,7 @@ function projectValueHeadPlacementGraph(args) {
97967
98235
  rootMemberId: item.rootMemberId,
97968
98236
  path: childName === null ? item.path : joinPath(item.path, childName),
97969
98237
  constructorOrigin: true,
98238
+ constructorMember,
97970
98239
  bindings: childBindings,
97971
98240
  constructorParameterId: edge.parameterId,
97972
98241
  constructorSchemaKey: edge.schemaKey
@@ -99047,7 +99316,10 @@ function recompileDialogueNode(args) {
99047
99316
  const action = asObject(actionValue2);
99048
99317
  if (action?.type !== 0 /* EditMember */) continue;
99049
99318
  const logic = asObject(action.logic);
99050
- if (!isCodeLogic(logic)) continue;
99319
+ if (!isCodeLogic(logic)) {
99320
+ changed = stampUILogicBody(logic, "action") || changed;
99321
+ continue;
99322
+ }
99051
99323
  const compiled = compileSourceUnit(
99052
99324
  args.sourceLabel,
99053
99325
  () => compileDialogueLogicWithProjectData(
@@ -99132,7 +99404,10 @@ function recompileConditionList(value, context) {
99132
99404
  let changed = false;
99133
99405
  for (const conditionValue of value) {
99134
99406
  const condition = asObject(conditionValue);
99135
- if (!isCodeLogic(condition)) continue;
99407
+ if (!isCodeLogic(condition)) {
99408
+ changed = stampUILogicBody(condition, "getter") || changed;
99409
+ continue;
99410
+ }
99136
99411
  const compiled = compileSourceUnit(
99137
99412
  context.sourceLabel,
99138
99413
  () => compileDialogueLogicWithProjectData(
@@ -99239,6 +99514,7 @@ function compileSourceUnit(label, compile, onSourceRejection, compileErrorFallba
99239
99514
  }
99240
99515
  function makeThrowBody(message, typeInfo) {
99241
99516
  return {
99517
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
99242
99518
  parameters: [],
99243
99519
  instructions: [
99244
99520
  {
@@ -99291,6 +99567,8 @@ var init_general_function_call_ir_source_recompile = __esm({
99291
99567
  init_compiler_adapter();
99292
99568
  init_neoscript();
99293
99569
  init_dialogue_node_index();
99570
+ init_src();
99571
+ init_neo_script_derived_bodies();
99294
99572
  VOID_ACTION_TYPE_INFO = {
99295
99573
  type: 0 /* Null */,
99296
99574
  required: true
@@ -99306,6 +99584,77 @@ var init_general_function_call_ir_source_recompile = __esm({
99306
99584
  }
99307
99585
  });
99308
99586
 
99587
+ // ../src/database/project-record-semantics.ts
99588
+ function projectRecordSemanticData(value) {
99589
+ if (!isPlainRecord(value)) return value;
99590
+ const semantic = {};
99591
+ for (const [key, child] of Object.entries(value)) {
99592
+ if (SERVER_MANAGED_PROJECT_RECORD_FIELDS.has(key)) continue;
99593
+ semantic[key] = child;
99594
+ }
99595
+ return semantic;
99596
+ }
99597
+ function projectRecordDataIsSemanticallyEqual(left, right) {
99598
+ return canonicalJsonStringify2(projectRecordSemanticData(left)) === canonicalJsonStringify2(projectRecordSemanticData(right));
99599
+ }
99600
+ function canonicalJsonStringify2(value) {
99601
+ return JSON.stringify(toCanonicalJsonValue2(value));
99602
+ }
99603
+ function toCanonicalJsonValue2(value) {
99604
+ if (value === null) return null;
99605
+ if (value === void 0) return void 0;
99606
+ if (value instanceof Date) return value.toISOString();
99607
+ if (typeof value === "string" || typeof value === "boolean") return value;
99608
+ if (typeof value === "number") {
99609
+ if (!Number.isFinite(value)) {
99610
+ throw new Error("Cannot canonicalize a non-finite number.");
99611
+ }
99612
+ return value;
99613
+ }
99614
+ if (typeof value === "bigint") {
99615
+ throw new Error("Cannot canonicalize bigint values.");
99616
+ }
99617
+ if (typeof value === "symbol") {
99618
+ throw new Error("Cannot canonicalize symbol values.");
99619
+ }
99620
+ if (typeof value === "function") {
99621
+ throw new Error("Cannot canonicalize function values.");
99622
+ }
99623
+ if (Array.isArray(value)) {
99624
+ return value.map((item) => toCanonicalJsonValue2(item) ?? null);
99625
+ }
99626
+ if (!isPlainRecord(value)) {
99627
+ throw new Error("Cannot canonicalize a non-plain object.");
99628
+ }
99629
+ const canonical = {};
99630
+ const entries = Object.entries(value).sort(
99631
+ ([left], [right]) => left.localeCompare(right)
99632
+ );
99633
+ for (const [key, child] of entries) {
99634
+ const canonicalChild = toCanonicalJsonValue2(child);
99635
+ if (canonicalChild === void 0) continue;
99636
+ canonical[key] = canonicalChild;
99637
+ }
99638
+ return canonical;
99639
+ }
99640
+ function isPlainRecord(value) {
99641
+ if (value === null || typeof value !== "object") return false;
99642
+ const prototype = Object.getPrototypeOf(value);
99643
+ return prototype === Object.prototype || prototype === null;
99644
+ }
99645
+ var SERVER_MANAGED_PROJECT_RECORD_FIELDS;
99646
+ var init_project_record_semantics = __esm({
99647
+ "../src/database/project-record-semantics.ts"() {
99648
+ "use strict";
99649
+ SERVER_MANAGED_PROJECT_RECORD_FIELDS = /* @__PURE__ */ new Set([
99650
+ "_id",
99651
+ "projectId",
99652
+ "createdAt",
99653
+ "updatedAt"
99654
+ ]);
99655
+ }
99656
+ });
99657
+
99309
99658
  // ../src/database/project-version-relation-sweep-trigger.ts
99310
99659
  function stagedChangesAffectClassRelations(current, changes) {
99311
99660
  const classesById = new Map(
@@ -99322,7 +99671,7 @@ function stagedChangesAffectClassRelations(current, changes) {
99322
99671
  const before2 = classesById.get(change.recordId);
99323
99672
  if (before2 === void 0) return true;
99324
99673
  const after = change.nextData;
99325
- if (!isPlainRecord(after)) return true;
99674
+ if (!isPlainRecord2(after)) return true;
99326
99675
  if (before2.extendsClassId !== after.extendsClassId) return true;
99327
99676
  continue;
99328
99677
  }
@@ -99341,17 +99690,20 @@ function valueCreateCannotAffectClassRelations(change, before) {
99341
99690
  return before === void 0;
99342
99691
  }
99343
99692
  function relationEndpointClassId(record4) {
99344
- if (!isPlainRecord(record4)) return void 0;
99693
+ if (!isPlainRecord2(record4)) return void 0;
99345
99694
  if (typeof record4.classId === "string") return record4.classId;
99346
99695
  return void 0;
99347
99696
  }
99348
- function isPlainRecord(value) {
99697
+ function isPlainRecord2(value) {
99349
99698
  if (value === null || typeof value !== "object") return false;
99350
99699
  return !Array.isArray(value);
99351
99700
  }
99352
99701
  var init_project_version_relation_sweep_trigger = __esm({
99353
99702
  "../src/database/project-version-relation-sweep-trigger.ts"() {
99354
99703
  "use strict";
99704
+ init_internal_record_relations();
99705
+ init_project_version_types();
99706
+ init_project_record_semantics();
99355
99707
  }
99356
99708
  });
99357
99709
 
@@ -100670,7 +101022,513 @@ var init_member_localization_normalization = __esm({
100670
101022
  }
100671
101023
  });
100672
101024
 
101025
+ // ../src/database/owned-value-deletion.ts
101026
+ function collectOwnedValueDeletionIds(args) {
101027
+ if (args.rootIds.length === 0) return [];
101028
+ return createOwnedValueDeletionCollector(
101029
+ args.document,
101030
+ args.placements
101031
+ ).collect(args);
101032
+ }
101033
+ function createOwnedValueDeletionCollector(input, knownPlacements) {
101034
+ const scope = withVariantPlacementRoots(input);
101035
+ const document = scope.document;
101036
+ const stored = new Map(document.values.map((row) => [row.id, row]));
101037
+ const members = new Map(
101038
+ document.members.map((member) => [member.id, member])
101039
+ );
101040
+ const placements = knownPlacements === void 0 ? findSemanticOwnerPlacementsForValues(
101041
+ scope.document,
101042
+ new Set(stored.keys()),
101043
+ scope.roots
101044
+ ) : new Map(knownPlacements);
101045
+ let graph;
101046
+ const childrenByContainer = /* @__PURE__ */ new Map();
101047
+ for (const row of document.values) {
101048
+ if (typeof row.containerId !== "string") continue;
101049
+ const children = childrenByContainer.get(row.containerId) ?? /* @__PURE__ */ new Set();
101050
+ children.add(row.id);
101051
+ childrenByContainer.set(row.containerId, children);
101052
+ }
101053
+ const schemas = /* @__PURE__ */ new Map();
101054
+ const schemaFor = (classId) => {
101055
+ let schema = schemas.get(classId);
101056
+ if (schema === void 0) {
101057
+ schema = mergeStoredInstanceSchema(
101058
+ classId,
101059
+ document.classes,
101060
+ document.members
101061
+ );
101062
+ schemas.set(classId, schema);
101063
+ }
101064
+ return schema;
101065
+ };
101066
+ const expanded = /* @__PURE__ */ new Map();
101067
+ let lookups;
101068
+ const classMember = (classId) => ({
101069
+ name: "Deletion root",
101070
+ kind: 7 /* Class */,
101071
+ classId
101072
+ });
101073
+ const currentDocument = () => ({ ...document, values: [...stored.values()] });
101074
+ let constructorTypes;
101075
+ let independentlyOwnedBeforeAppend;
101076
+ const constructorEdgesFor = (row) => {
101077
+ if (!isLiteralValueContent(row) || !Object.values(row.constructorArgs ?? {}).some(
101078
+ (value) => typeof value === "string"
101079
+ ))
101080
+ return [];
101081
+ constructorTypes ??= new MaterializedValueGraphContext(
101082
+ { ...document, values: [] },
101083
+ /* @__PURE__ */ new Map(),
101084
+ new Map(
101085
+ scope.roots.flatMap(
101086
+ (root) => isMemberClassBase(root.member) ? [[root.valueId, root.member]] : []
101087
+ )
101088
+ )
101089
+ );
101090
+ return constructorTypes.constructorEdges(row);
101091
+ };
101092
+ const appendDisjointRows = (rows) => {
101093
+ if (rows.length === 0) return true;
101094
+ const addedIds = new Set(rows.map((row) => row.id));
101095
+ const referencedIds2 = /* @__PURE__ */ new Set();
101096
+ const referencesStored = (value) => {
101097
+ if (typeof value === "string") {
101098
+ if (addedIds.has(value)) referencedIds2.add(value);
101099
+ return stored.has(value);
101100
+ }
101101
+ if (value === null || typeof value !== "object") return false;
101102
+ return Object.values(value).some(referencesStored);
101103
+ };
101104
+ const deltaRows = new Map(rows.map((row) => [row.id, row]));
101105
+ const roots = [];
101106
+ for (const row of rows) {
101107
+ if (stored.has(row.id) || !isLiteralValueContent(row)) return false;
101108
+ const argumentEdges = constructorEdgesFor(row);
101109
+ if (argumentEdges.length > 0) {
101110
+ if (independentlyOwnedBeforeAppend === void 0) {
101111
+ graph ??= createVariantMaterializedValueGraphContext(
101112
+ currentDocument(),
101113
+ document.variants ?? []
101114
+ );
101115
+ independentlyOwnedBeforeAppend = graph.independentlyOwnedValueIds;
101116
+ }
101117
+ if (argumentEdges.some(
101118
+ (edge) => !independentlyOwnedBeforeAppend.has(edge.targetValueId)
101119
+ ))
101120
+ return false;
101121
+ }
101122
+ if (referencesStored(row.value)) return false;
101123
+ if (typeof row.containerId !== "string") continue;
101124
+ if (addedIds.has(row.containerId)) {
101125
+ referencedIds2.add(row.id);
101126
+ continue;
101127
+ }
101128
+ const parent = stored.get(row.containerId);
101129
+ const placement = placements.get(row.containerId);
101130
+ if (parent === void 0 || placement === void 0) return false;
101131
+ deltaRows.set(parent.id, parent);
101132
+ roots.push({
101133
+ valueId: parent.id,
101134
+ member: placement.member,
101135
+ position: placement.position
101136
+ });
101137
+ referencedIds2.add(row.id);
101138
+ }
101139
+ for (const row of rows) {
101140
+ if (referencedIds2.has(row.id) || typeof row.classId !== "string")
101141
+ continue;
101142
+ roots.push({
101143
+ valueId: row.id,
101144
+ member: classMember(row.classId),
101145
+ position: { insideAnimationOverrideGraph: false }
101146
+ });
101147
+ }
101148
+ const deltaPlacements = findSemanticOwnerPlacementsForValues(
101149
+ { ...document, values: [...deltaRows.values()] },
101150
+ addedIds,
101151
+ roots
101152
+ );
101153
+ for (const [id2, placement] of deltaPlacements)
101154
+ placements.set(id2, placement);
101155
+ for (const row of rows) {
101156
+ stored.set(row.id, row);
101157
+ if (typeof row.containerId !== "string") continue;
101158
+ const children = childrenByContainer.get(row.containerId) ?? /* @__PURE__ */ new Set();
101159
+ children.add(row.id);
101160
+ childrenByContainer.set(row.containerId, children);
101161
+ }
101162
+ graph = void 0;
101163
+ lookups = void 0;
101164
+ expanded.clear();
101165
+ return true;
101166
+ };
101167
+ const collect = (args) => {
101168
+ const roots = new Set(args.rootIds);
101169
+ const resolve5 = (id2, member) => {
101170
+ if (args.resolveValueById !== void 0)
101171
+ return args.resolveValueById(id2) ?? stored.get(id2);
101172
+ const cached = expanded.get(id2);
101173
+ if (cached !== void 0) return cached;
101174
+ const row = stored.get(id2);
101175
+ if (row !== void 0 && member !== void 0) {
101176
+ if (!isMemberClassBase(member) && !isMemberListBase(member) && !isMemberDictionaryBase(member))
101177
+ return row;
101178
+ if (isLiteralValueContent(row) && (isMemberListBase(member) && member.listKind !== 1 /* Unordered */ && Array.isArray(row.value) || isMemberDictionaryBase(member) && row.value !== null && typeof row.value === "object" && !Array.isArray(row.value)) && [...storedValueChildReferences({ member, body: row.value })].every(
101179
+ (child) => stored.has(child.valueId)
101180
+ ))
101181
+ return row;
101182
+ if (isMemberClassBase(member) && isLiteralValueContent(row) && row.value !== null && typeof row.value === "object" && !Array.isArray(row.value)) {
101183
+ const body = row.value;
101184
+ const complete2 = schemaFor(row.classId ?? member.classId).every(
101185
+ (field) => {
101186
+ if (field.memberId === null) return true;
101187
+ const childMember = members.get(field.memberId);
101188
+ if (childMember === void 0) return false;
101189
+ if (!memberKindOwnsStoredValue(childMember.kind)) return true;
101190
+ const childId = body[field.schemaKey];
101191
+ return childId === null || typeof childId === "string" && stored.has(childId);
101192
+ }
101193
+ );
101194
+ if (complete2) return row;
101195
+ }
101196
+ }
101197
+ if (row !== void 0 && isLiteralValueContent(row) && (isVirtualInstanceRootShape(row) || typeof row.value === "object")) {
101198
+ lookups ??= initializerEvaluatorLookups(currentDocument());
101199
+ for (const value of lookups.virtualInstanceRowsForValue(id2)) {
101200
+ expanded.set(value.id, value);
101201
+ if (typeof value.containerId === "string") {
101202
+ const children = childrenByContainer.get(value.containerId) ?? /* @__PURE__ */ new Set();
101203
+ children.add(value.id);
101204
+ childrenByContainer.set(value.containerId, children);
101205
+ }
101206
+ }
101207
+ return expanded.get(id2) ?? row;
101208
+ }
101209
+ return row;
101210
+ };
101211
+ const deleted = /* @__PURE__ */ new Set();
101212
+ const visited = /* @__PURE__ */ new Set();
101213
+ const pending = args.rootIds.map((id2) => ({
101214
+ id: id2,
101215
+ member: args.rootMembers?.get(id2) ?? placements.get(id2)?.member
101216
+ }));
101217
+ while (pending.length > 0) {
101218
+ const item = pending.pop();
101219
+ if (visited.has(item.id)) continue;
101220
+ if (args.preservedValueIds?.has(item.id)) continue;
101221
+ const placement = placements.get(item.id);
101222
+ if (!roots.has(item.id) && placement !== void 0 && placement.parentValueId !== item.parentId && stored.get(item.id)?.containerId !== item.parentId)
101223
+ continue;
101224
+ visited.add(item.id);
101225
+ const durable = stored.get(item.id);
101226
+ const declaredMember = item.member ?? placement?.member ?? (typeof durable?.classId === "string" ? classMember(durable.classId) : void 0);
101227
+ const resolved = resolve5(item.id, declaredMember);
101228
+ if (durable === void 0 && resolved === void 0) continue;
101229
+ if (durable !== void 0) deleted.add(item.id);
101230
+ const row = resolved ?? durable;
101231
+ const member = declaredMember ?? (typeof row.classId === "string" ? classMember(row.classId) : void 0);
101232
+ if (member === void 0) {
101233
+ if (roots.has(item.id)) continue;
101234
+ if (Array.isArray(row.value))
101235
+ throw new Error(
101236
+ `Cannot delete value "${item.id}" descendants without its collection member.`
101237
+ );
101238
+ if (row.value !== null && typeof row.value === "object") {
101239
+ throw new Error(
101240
+ `Cannot determine ownership of object value "${item.id}" without its member.`
101241
+ );
101242
+ }
101243
+ continue;
101244
+ }
101245
+ if (durable !== void 0 && constructorEdgesFor(durable).some(
101246
+ (edge) => !independentlyOwnedBeforeAppend?.has(edge.targetValueId)
101247
+ )) {
101248
+ graph ??= createVariantMaterializedValueGraphContext(
101249
+ currentDocument(),
101250
+ document.variants ?? []
101251
+ );
101252
+ for (const ownedId of graph.collectSoftOwnedRows(
101253
+ item.id,
101254
+ args.preservedValueIds
101255
+ )) {
101256
+ if (stored.has(ownedId)) deleted.add(ownedId);
101257
+ }
101258
+ }
101259
+ if (!isMemberClassBase(member) && !isMemberListBase(member) && !isMemberDictionaryBase(member))
101260
+ continue;
101261
+ const bodies = durable === void 0 || durable === row ? [row] : [durable, row];
101262
+ for (const body of bodies) {
101263
+ if (!isLiteralValueContent(body)) continue;
101264
+ let env = envFromStamp(body.genericBindings);
101265
+ let classFields;
101266
+ if (isMemberClassBase(member)) {
101267
+ const classId = body.classId ?? member.classId;
101268
+ env = new Map([
101269
+ ...resolveInstanceEnv(
101270
+ classId,
101271
+ member.classArguments,
101272
+ document.classes
101273
+ ),
101274
+ ...env
101275
+ ]);
101276
+ classFields = schemaFor(classId).flatMap(
101277
+ (field) => field.memberId === null ? [] : [{ schemaKey: field.schemaKey, memberId: field.memberId }]
101278
+ );
101279
+ if (body.value !== null && typeof body.value === "object" && !Array.isArray(body.value)) {
101280
+ const record4 = body.value;
101281
+ const sidecars = consumeWorldPlacementSidecarKeys({
101282
+ body: record4,
101283
+ classes: document.classes,
101284
+ classId,
101285
+ label: `Value "${body.id}"`
101286
+ });
101287
+ for (const key of ["assetValueId", "layerOverrideValueId"]) {
101288
+ if (key === "assetValueId" && !sidecars.has(key)) continue;
101289
+ if (key === "layerOverrideValueId") {
101290
+ const worldKind = resolveWorldSystemClassKind(
101291
+ classId,
101292
+ document.classes
101293
+ );
101294
+ if (worldKind !== NeoWorldSystemClassKind.TileLayerLink && worldKind !== NeoWorldSystemClassKind.ObjectLayerLink)
101295
+ continue;
101296
+ }
101297
+ const id2 = record4[key];
101298
+ if (typeof id2 !== "string") continue;
101299
+ const child = stored.get(id2);
101300
+ if (child?.containerId !== body.id)
101301
+ throw new Error(
101302
+ `Value "${body.id}" sidecar "${key}" does not own "${id2}".`
101303
+ );
101304
+ pending.push({ id: id2, parentId: body.id });
101305
+ }
101306
+ }
101307
+ }
101308
+ for (const child of storedValueChildReferences({
101309
+ member,
101310
+ body: body.value,
101311
+ classFields,
101312
+ unorderedValueIds: isMemberListBase(member) && member.listKind === 1 /* Unordered */ ? [
101313
+ .../* @__PURE__ */ new Set([
101314
+ ...childrenByContainer.get(body.id) ?? [],
101315
+ ...args.unorderedListEntryIds?.(body.id) ?? []
101316
+ ])
101317
+ ] : void 0
101318
+ })) {
101319
+ const declared = members.get(child.memberId);
101320
+ if (declared === void 0)
101321
+ throw new Error(
101322
+ `Value "${body.id}" child "${child.valueId}" has missing member "${child.memberId}".`
101323
+ );
101324
+ const childMember = substituteMember(declared, env, document.members);
101325
+ pending.push({
101326
+ id: child.valueId,
101327
+ member: childMember,
101328
+ parentId: body.id
101329
+ });
101330
+ }
101331
+ }
101332
+ }
101333
+ return [...deleted];
101334
+ };
101335
+ return { collect, appendDisjointRows };
101336
+ }
101337
+ var init_owned_value_deletion = __esm({
101338
+ "../src/database/owned-value-deletion.ts"() {
101339
+ "use strict";
101340
+ init_classes();
101341
+ init_core();
101342
+ init_members();
101343
+ init_generics();
101344
+ init_inheritance();
101345
+ init_stored_value_shape();
101346
+ init_instance_provenance();
101347
+ init_evaluateInitializer();
101348
+ init_variant_value_graph();
101349
+ init_constructor_argument_ownership();
101350
+ init_world_content_sidecar_validation();
101351
+ }
101352
+ });
101353
+
100673
101354
  // ../src/database/project-version-schema-commit.ts
101355
+ function memberDefaultOwnedRootIds(document, member) {
101356
+ if (member.defaultValue == null) return [];
101357
+ const resolved = resolveMember2(member, document.members);
101358
+ let classFields;
101359
+ if (isMemberClassBase(resolved)) {
101360
+ const classId = member.defaultValue.classId ?? resolved.classId;
101361
+ classFields = mergeStoredInstanceSchema(
101362
+ classId,
101363
+ document.classes,
101364
+ document.members
101365
+ ).flatMap(
101366
+ (entry) => entry.memberId === null ? [] : [{ schemaKey: entry.schemaKey, memberId: entry.memberId }]
101367
+ );
101368
+ }
101369
+ return [
101370
+ ...storedValueChildReferences({
101371
+ member: resolved,
101372
+ body: member.defaultValue.value,
101373
+ classFields
101374
+ })
101375
+ ].map((reference2) => reference2.valueId);
101376
+ }
101377
+ function appendAuthoredOwnedValueCascadeDeletes(args) {
101378
+ const roots = /* @__PURE__ */ new Set();
101379
+ const membersById = indexRecordsById(args.document.members);
101380
+ const variantsById = indexRecordsById(args.document.variants ?? []);
101381
+ for (const change of args.authoredChanges) {
101382
+ if (change.operation !== "delete") continue;
101383
+ if (change.recordKind === "value") {
101384
+ roots.add(change.recordId);
101385
+ continue;
101386
+ }
101387
+ if (change.recordKind === "variant") {
101388
+ const variantRootId = variantsById.get(change.recordId)?.valueId;
101389
+ if (typeof variantRootId === "string") roots.add(variantRootId);
101390
+ continue;
101391
+ }
101392
+ if (change.recordKind !== "member") continue;
101393
+ const member = membersById.get(change.recordId);
101394
+ if (member === void 0) continue;
101395
+ if (typeof member.valueId === "string") roots.add(member.valueId);
101396
+ for (const valueId of memberDefaultOwnedRootIds(args.document, member)) {
101397
+ roots.add(valueId);
101398
+ }
101399
+ }
101400
+ for (const change of args.authoredChanges) {
101401
+ if (change.recordKind !== "member" || change.operation !== "update") {
101402
+ continue;
101403
+ }
101404
+ const current = membersById.get(change.recordId);
101405
+ if (current === void 0) continue;
101406
+ const next = change.nextData;
101407
+ if (current.valueId === next.valueId && canonicallyEqual2(current.defaultValue, next.defaultValue)) {
101408
+ continue;
101409
+ }
101410
+ const serverHandlesStoredToReadOnly = args.expandReadOnlySourceConversions && isAbstractMember(current) !== true && isAbstractMember(next) !== true && isReadOnlyMember(current) !== true && isReadOnlyMember(next) === true;
101411
+ if (!serverHandlesStoredToReadOnly && typeof current.valueId === "string" && current.valueId !== next.valueId) {
101412
+ roots.add(current.valueId);
101413
+ }
101414
+ for (const valueId of memberDefaultOwnedRootIds(args.document, current)) {
101415
+ roots.add(valueId);
101416
+ }
101417
+ }
101418
+ if (roots.size === 0) return;
101419
+ const authoredPost = applyProjectVersionWriteChanges(
101420
+ args.document,
101421
+ args.authoredChanges
101422
+ );
101423
+ const postScope = withVariantPlacementRoots(authoredPost);
101424
+ const postValueIds = new Set(authoredPost.values.map((value) => value.id));
101425
+ const postPlacements = findSemanticOwnerPlacementsForValues(
101426
+ postScope.document,
101427
+ postValueIds,
101428
+ postScope.roots
101429
+ );
101430
+ const preservedValueIds = new Set(postPlacements.keys());
101431
+ const preScope = withVariantPlacementRoots(args.document);
101432
+ const prePlacements = findSemanticOwnerPlacementsForValues(
101433
+ preScope.document,
101434
+ new Set(args.document.values.map((value) => value.id)),
101435
+ preScope.roots,
101436
+ true
101437
+ );
101438
+ const postValuesById = indexRecordsById(authoredPost.values);
101439
+ const survivingConstructionIds = /* @__PURE__ */ new Set();
101440
+ for (const rootId of roots) {
101441
+ let parentId = prePlacements.get(rootId)?.parentValueId;
101442
+ const visited = /* @__PURE__ */ new Set();
101443
+ while (parentId != null && !visited.has(parentId)) {
101444
+ visited.add(parentId);
101445
+ const parent = postValuesById.get(parentId);
101446
+ if (parent !== void 0 && isLiteralValueContent(parent) && isVirtualInstanceRootShape(parent) && postPlacements.has(parentId)) {
101447
+ survivingConstructionIds.add(parentId);
101448
+ break;
101449
+ }
101450
+ parentId = prePlacements.get(parentId)?.parentValueId;
101451
+ }
101452
+ }
101453
+ if (survivingConstructionIds.size > 0) {
101454
+ const resolverDocument = composeResolverDocument(
101455
+ postScope.document,
101456
+ initializerEvaluatorLookups(postScope.document)
101457
+ );
101458
+ const materializedIndex = buildVirtualInstanceMaterializedIndex({
101459
+ document: resolverDocument
101460
+ });
101461
+ for (const rootId of survivingConstructionIds) {
101462
+ const instanceRoot = postValuesById.get(rootId);
101463
+ const rootMember = postPlacements.get(rootId).member;
101464
+ const expanded = expandStoredInstance({
101465
+ document: resolverDocument,
101466
+ instanceRoot,
101467
+ rootMember,
101468
+ evaluateInitializer: evaluateMemberInitializer
101469
+ });
101470
+ const graph = resolveVirtualInstanceGraph({
101471
+ document: resolverDocument,
101472
+ instanceRoot,
101473
+ rootMember,
101474
+ expandedRoot: expanded.root,
101475
+ expandedRows: expanded.rows,
101476
+ pinnedRootSchemaKeys: expanded.pinnedRootSchemaKeys,
101477
+ materializedIndex
101478
+ });
101479
+ for (const id2 of graph.rowsById.keys()) {
101480
+ if (postValueIds.has(id2)) preservedValueIds.add(id2);
101481
+ }
101482
+ }
101483
+ }
101484
+ const cascadeIds = collectOwnedValueDeletionIds({
101485
+ document: args.document,
101486
+ placements: prePlacements,
101487
+ rootIds: [...roots],
101488
+ preservedValueIds
101489
+ });
101490
+ const existingByValueId = /* @__PURE__ */ new Map();
101491
+ for (const change of args.authoredChanges) {
101492
+ if (change.recordKind === "value") {
101493
+ existingByValueId.set(change.recordId, change);
101494
+ }
101495
+ }
101496
+ const baseHashByValueId = indexLiveContentHashesByRecordId(
101497
+ args.contentHashHeads,
101498
+ "value"
101499
+ );
101500
+ const appendedDeleteIds = /* @__PURE__ */ new Set();
101501
+ for (const valueId of cascadeIds) {
101502
+ const existing = existingByValueId.get(valueId);
101503
+ if (existing?.operation === "delete") continue;
101504
+ if (existing !== void 0) {
101505
+ throw new Error(
101506
+ `Authored value "${valueId}" is updated while its owning value graph is deleted. Reparent it from a surviving member or value in the same commit.`
101507
+ );
101508
+ }
101509
+ const expectedBaseContentHash = baseHashByValueId.get(valueId);
101510
+ if (expectedBaseContentHash === void 0) continue;
101511
+ const change = {
101512
+ recordKind: "value",
101513
+ recordId: valueId,
101514
+ operation: "delete",
101515
+ deleted: true,
101516
+ expectedBaseContentHash,
101517
+ intent: createProjectVersionIntent("value.delete", {
101518
+ source: "server-owned-value-cascade"
101519
+ })
101520
+ };
101521
+ args.authoredChanges.push(change);
101522
+ appendedDeleteIds.add(valueId);
101523
+ existingByValueId.set(valueId, change);
101524
+ }
101525
+ return appendedDeleteIds.size === 0 ? authoredPost : {
101526
+ ...authoredPost,
101527
+ values: authoredPost.values.filter(
101528
+ (value) => !appendedDeleteIds.has(value.id)
101529
+ )
101530
+ };
101531
+ }
100674
101532
  function indexRecordsById(records2) {
100675
101533
  const recordsById2 = /* @__PURE__ */ new Map();
100676
101534
  for (const record4 of records2) recordsById2.set(record4.id, record4);
@@ -100781,10 +101639,12 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
100781
101639
  authoredChanges
100782
101640
  );
100783
101641
  }
100784
- let authoredPost = applyProjectVersionWriteChanges(
100785
- args.document,
100786
- authoredChanges
100787
- );
101642
+ let authoredPost = appendAuthoredOwnedValueCascadeDeletes({
101643
+ document: args.document,
101644
+ authoredChanges,
101645
+ contentHashHeads: args.contentHashHeads,
101646
+ expandReadOnlySourceConversions: args.expandReadOnlySourceConversions === true
101647
+ }) ?? applyProjectVersionWriteChanges(args.document, authoredChanges);
100788
101648
  if (authoredPost.localizationConfig?.mainLocale !== args.document.localizationConfig?.mainLocale) {
100789
101649
  const normalized = planMemberLocalizationNormalization(
100790
101650
  authoredPost,
@@ -101184,11 +102044,6 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
101184
102044
  prepared,
101185
102045
  contentHashHeads: args.contentHashHeads
101186
102046
  });
101187
- appendVariantGraphCascadeDeletes({
101188
- document: args.document,
101189
- prepared,
101190
- contentHashHeads: args.contentHashHeads
101191
- });
101192
102047
  let localizationChanges = reconcileGeneratedLocalizedTextCreates(
101193
102048
  args.document,
101194
102049
  prepared
@@ -101344,7 +102199,8 @@ function attachPreparedValuePlacements(prepared, document) {
101344
102199
  targetValueId: edge.targetValueId,
101345
102200
  memberId: owner.memberId,
101346
102201
  parameterId: edge.parameterId,
101347
- schemaKey: owner.schemaKey
102202
+ schemaKey: owner.schemaKey,
102203
+ member: owner.member
101348
102204
  });
101349
102205
  }
101350
102206
  }
@@ -101386,8 +102242,8 @@ function attachPreparedConstructorAggregateEdges(prepared, document) {
101386
102242
  );
101387
102243
  if (valueChanges.length === 0) return;
101388
102244
  const needsGraph = valueChanges.some((change) => {
101389
- const constructorArgs = asRecord2(
101390
- asRecord2(change.nextData)?.constructorArgs
102245
+ const constructorArgs = asRecord3(
102246
+ asRecord3(change.nextData)?.constructorArgs
101391
102247
  );
101392
102248
  return constructorArgs !== null && Object.keys(constructorArgs).length > 0;
101393
102249
  });
@@ -101791,7 +102647,7 @@ function localizedTextCreateEnvelopeConfig(args) {
101791
102647
  (change) => change.recordKind === "localization-config"
101792
102648
  );
101793
102649
  if (configChange?.operation === "delete") return null;
101794
- const candidate = asRecord2(
102650
+ const candidate = asRecord3(
101795
102651
  configChange?.nextData ?? args.document.localizationConfig
101796
102652
  );
101797
102653
  if (candidate === null) return null;
@@ -102058,7 +102914,7 @@ function removeDirectBindingsFromReadOnlySourceTransitions(currentDocument, chan
102058
102914
  continue;
102059
102915
  }
102060
102916
  const current = currentMembers.get(change.recordId);
102061
- const next = asRecord2(change.nextData);
102917
+ const next = asRecord3(change.nextData);
102062
102918
  if (current === void 0 || next === null) continue;
102063
102919
  if (isAbstractMember(current) || isAbstractMember(next)) continue;
102064
102920
  if (isReadOnlyMember(current) || !isReadOnlyMember(next)) continue;
@@ -102177,7 +103033,7 @@ function prepareServerOwnedDialogueBodies(args) {
102177
103033
  }
102178
103034
  if (change.recordKind === "dialogue-node") {
102179
103035
  explicitNodeIds.add(change.recordId);
102180
- const next = asRecord2(change.nextData);
103036
+ const next = asRecord3(change.nextData);
102181
103037
  const current = currentNodes.get(change.recordId);
102182
103038
  if (typeof current?.dialogueId === "string") {
102183
103039
  changedDialogueIds.add(current.dialogueId);
@@ -103907,7 +104763,7 @@ function delegateValueRow(value) {
103907
104763
  }
103908
104764
  function inlineDelegateArgumentRow(value) {
103909
104765
  if (!isMemberValue(value) || !isLiteralValueContent(value)) return null;
103910
- const constructorArgs = asRecord2(
104766
+ const constructorArgs = asRecord3(
103911
104767
  value.constructorArgs
103912
104768
  );
103913
104769
  if (constructorArgs === null) return null;
@@ -103919,14 +104775,14 @@ function inlineDelegateArgumentRow(value) {
103919
104775
  return null;
103920
104776
  }
103921
104777
  function isUncompiledInlineDelegateArgument(argument2) {
103922
- const closure = asRecord2(argument2);
104778
+ const closure = asRecord3(argument2);
103923
104779
  if (closure === null) return false;
103924
104780
  if (typeof closure.code !== "string") return false;
103925
104781
  return !("action" in closure);
103926
104782
  }
103927
104783
  function compileInlineDelegateConstructorArguments(args) {
103928
104784
  const { document, row, ownerMember, rootOwner } = args;
103929
- const constructorArgs = asRecord2(row.constructorArgs);
104785
+ const constructorArgs = asRecord3(row.constructorArgs);
103930
104786
  if (constructorArgs === null) {
103931
104787
  throw new Error(
103932
104788
  `Value "${row.id}" was collected for inline delegate compilation without constructor arguments.`
@@ -103961,7 +104817,7 @@ function compileInlineDelegateConstructorArguments(args) {
103961
104817
  `Value "${row.id}" inline delegate compilation cannot find constructor "${constructorId ?? "none"}" on class "${schemaClass2.name}".`
103962
104818
  );
103963
104819
  }
103964
- const ownerClassArguments = asRecord2(
104820
+ const ownerClassArguments = asRecord3(
103965
104821
  ownerMember?.classArguments
103966
104822
  );
103967
104823
  const env = resolveInstanceEnv(
@@ -104402,7 +105258,7 @@ function assertUniqueChanges(changes) {
104402
105258
  }
104403
105259
  keys.add(key);
104404
105260
  if (change.operation !== "delete") {
104405
- const nextData = asRecord2(change.nextData);
105261
+ const nextData = asRecord3(change.nextData);
104406
105262
  if (nextData === null) {
104407
105263
  throw new Error(`Schema commit change "${key}" requires nextData.`);
104408
105264
  }
@@ -104414,190 +105270,6 @@ function assertUniqueChanges(changes) {
104414
105270
  }
104415
105271
  }
104416
105272
  }
104417
- function cloneAndStripClientDerivedBodies(change) {
104418
- if (change.operation === "delete" || change.nextData === void 0) {
104419
- return { ...change };
104420
- }
104421
- if (change.recordKind === "migration") {
104422
- const nextData2 = asRecord2(change.nextData);
104423
- return {
104424
- ...change,
104425
- nextData: nextData2 === null ? change.nextData : stripMigrationAction(nextData2)
104426
- };
104427
- }
104428
- if (change.recordKind === "dialogue-node") {
104429
- const nextData2 = asRecord2(change.nextData);
104430
- return {
104431
- ...change,
104432
- nextData: nextData2 === null ? change.nextData : stripDialogueNodeDerivedBodies(nextData2)
104433
- };
104434
- }
104435
- if (change.recordKind === "dialogue-group") {
104436
- const nextData2 = asRecord2(change.nextData);
104437
- return {
104438
- ...change,
104439
- nextData: nextData2 === null ? change.nextData : stripDialogueGroupDerivedBodies(nextData2)
104440
- };
104441
- }
104442
- if (change.recordKind === "constructor") {
104443
- const nextData2 = asRecord2(change.nextData);
104444
- return {
104445
- ...change,
104446
- nextData: nextData2 === null ? change.nextData : stripConstructorDerivedBodies(nextData2)
104447
- };
104448
- }
104449
- if (change.recordKind === "value") {
104450
- const nextData2 = asRecord2(change.nextData);
104451
- if (nextData2 === null) return { ...change, nextData: change.nextData };
104452
- const stripped = { ...nextData2 };
104453
- stripInitializerCompanion(stripped, "init");
104454
- stripDelegateClosureCompanion(stripped, "value");
104455
- stripInlineDelegateArgumentCompanions(stripped);
104456
- return { ...change, nextData: stripped };
104457
- }
104458
- if (change.recordKind !== "member") {
104459
- return { ...change, nextData: change.nextData };
104460
- }
104461
- const nextData = asRecord2(change.nextData);
104462
- if (nextData === null) return { ...change, nextData: change.nextData };
104463
- return {
104464
- ...change,
104465
- nextData: stripDerivedBodies(nextData)
104466
- };
104467
- }
104468
- function stripDialogueNodeDerivedBodies(node) {
104469
- const next = structuredClone(node);
104470
- stripConditionCompanions(next.conditions);
104471
- stripTextVariableCompanions(next.variables);
104472
- if (Array.isArray(next.actions)) {
104473
- for (const actionValue2 of next.actions) {
104474
- const action = asRecord2(actionValue2);
104475
- const logic = asRecord2(action?.logic);
104476
- if (logic?.type === 1 && typeof logic.code === "string") {
104477
- delete logic.action;
104478
- }
104479
- }
104480
- }
104481
- if (Array.isArray(next.outcomes)) {
104482
- for (const outcomeValue of next.outcomes) {
104483
- const outcome = asRecord2(outcomeValue);
104484
- if (outcome !== null) stripConditionCompanions(outcome.conditions);
104485
- }
104486
- }
104487
- const optionSettings = asRecord2(next.optionSettings);
104488
- if (Array.isArray(optionSettings?.options)) {
104489
- for (const optionValue of optionSettings.options) {
104490
- const option = asRecord2(optionValue);
104491
- if (option === null) continue;
104492
- stripTextVariableCompanions(option.variables);
104493
- const settings = asRecord2(option.settings);
104494
- if (settings === null) continue;
104495
- stripConditionCompanions(settings.conditions);
104496
- stripConditionCompanions(settings.selectableConditions);
104497
- }
104498
- }
104499
- return next;
104500
- }
104501
- function stripDialogueGroupDerivedBodies(group) {
104502
- const next = structuredClone(group);
104503
- stripConditionCompanions(next.conditions);
104504
- return next;
104505
- }
104506
- function stripConditionCompanions(value) {
104507
- if (!Array.isArray(value)) return;
104508
- for (const conditionValue of value) {
104509
- const condition = asRecord2(conditionValue);
104510
- if (condition?.type === 1 && typeof condition.code === "string") {
104511
- delete condition.getter;
104512
- }
104513
- }
104514
- }
104515
- function stripTextVariableCompanions(value) {
104516
- const variables = asRecord2(value);
104517
- if (variables === null) return;
104518
- for (const variableValue of Object.values(variables)) {
104519
- const variable2 = asRecord2(variableValue);
104520
- if (variable2 !== null && typeof variable2.code === "string") {
104521
- delete variable2.getter;
104522
- }
104523
- }
104524
- }
104525
- function stripDerivedBodies(member) {
104526
- const next = { ...member };
104527
- if (member.kind === 10 /* NSProperty */) {
104528
- delete next.getter;
104529
- delete next.setter;
104530
- }
104531
- if (member.kind === 23 /* NSFunction */) {
104532
- delete next.action;
104533
- }
104534
- if (member.kind === 25 /* NSDelegate */) {
104535
- stripDelegateClosureCompanion(next, "defaultValue");
104536
- }
104537
- stripInitializerCompanion(next, "defaultValue");
104538
- return next;
104539
- }
104540
- function stripInlineDelegateArgumentCompanions(record4) {
104541
- const constructorArgs = asRecord2(record4.constructorArgs);
104542
- if (constructorArgs === null) return;
104543
- let changed = false;
104544
- const stripped = { ...constructorArgs };
104545
- for (const [key, argument2] of Object.entries(constructorArgs)) {
104546
- const closure = asRecord2(argument2);
104547
- if (closure === null) continue;
104548
- if (typeof closure.code !== "string") continue;
104549
- if (!("action" in closure)) continue;
104550
- const authored = { ...closure };
104551
- delete authored.action;
104552
- stripped[key] = authored;
104553
- changed = true;
104554
- }
104555
- if (changed) record4.constructorArgs = stripped;
104556
- }
104557
- function stripDelegateClosureCompanion(record4, field) {
104558
- const container = field === "value" ? record4 : asRecord2(record4.defaultValue);
104559
- if (container === null) return;
104560
- const delegate = asRecord2(container.value);
104561
- if (delegate === null || typeof delegate.code !== "string") return;
104562
- if (!("action" in delegate)) return;
104563
- const authoredDelegate = { ...delegate };
104564
- delete authoredDelegate.action;
104565
- if (field === "value") {
104566
- record4.value = authoredDelegate;
104567
- return;
104568
- }
104569
- record4.defaultValue = { ...container, value: authoredDelegate };
104570
- }
104571
- function stripInitializerCompanion(record4, field) {
104572
- const container = field === "init" ? record4 : asRecord2(record4.defaultValue);
104573
- if (container === null) return;
104574
- const init = asRecord2(container.init);
104575
- if (init === null) return;
104576
- const authoredInit = { ...init };
104577
- delete authoredInit.compiled;
104578
- if (field === "init") {
104579
- record4.init = authoredInit;
104580
- return;
104581
- }
104582
- record4.defaultValue = { ...container, init: authoredInit };
104583
- }
104584
- function stripConstructorDerivedBodies(constructorRecord) {
104585
- const {
104586
- action: _action,
104587
- compiledBaseArguments: _compiledBaseArguments,
104588
- compiledBaseInitializerFields: _compiledBaseInitializerFields,
104589
- ...next
104590
- } = constructorRecord;
104591
- void _action;
104592
- void _compiledBaseArguments;
104593
- void _compiledBaseInitializerFields;
104594
- return next;
104595
- }
104596
- function stripMigrationAction(migration) {
104597
- const { action: _action, ...next } = migration;
104598
- void _action;
104599
- return next;
104600
- }
104601
105273
  function applyProjectVersionWriteChanges(document, changes) {
104602
105274
  return projectVersionDocumentWithChanges(document, changes, false);
104603
105275
  }
@@ -104705,7 +105377,7 @@ function applyArrayChanges(current, changes) {
104705
105377
  }
104706
105378
  return [...byId.values()];
104707
105379
  }
104708
- function asRecord2(value) {
105380
+ function asRecord3(value) {
104709
105381
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
104710
105382
  return null;
104711
105383
  }
@@ -104869,52 +105541,12 @@ function variantConstructorArgumentIsRestValue(schemaKey, value) {
104869
105541
  }
104870
105542
  return schemaKey === NEO_VARIANT_CHILD_OVERRIDES_SCHEMA_KEY && Array.isArray(value) && value.length === 0;
104871
105543
  }
104872
- function appendVariantGraphCascadeDeletes(args) {
104873
- const deletedVariantIds = /* @__PURE__ */ new Set();
104874
- for (const change of args.prepared) {
104875
- if (change.recordKind !== "variant") continue;
104876
- if (change.operation !== "delete") continue;
104877
- deletedVariantIds.add(change.recordId);
104878
- }
104879
- if (deletedVariantIds.size === 0) return;
104880
- const valueIds = collectVariantGraphValueIds({
104881
- document: args.document,
104882
- variants: args.document.variants ?? [],
104883
- variantIds: deletedVariantIds
104884
- });
104885
- const alreadyChanged = /* @__PURE__ */ new Set();
104886
- for (const change of args.prepared) {
104887
- if (change.recordKind === "value") alreadyChanged.add(change.recordId);
104888
- }
104889
- const baseHashByValueId = indexLiveContentHashesByRecordId(
104890
- args.contentHashHeads,
104891
- "value"
104892
- );
104893
- for (const valueId of valueIds) {
104894
- if (alreadyChanged.has(valueId)) continue;
104895
- const baseContentHash = baseHashByValueId.get(valueId);
104896
- if (baseContentHash === void 0) continue;
104897
- args.prepared.push({
104898
- recordKind: "value",
104899
- recordId: valueId,
104900
- operation: "delete",
104901
- // The commit boundary keys tombstones on `deleted`, not on `operation`:
104902
- // without it the change reads as an update carrying no nextData and the
104903
- // whole push is rejected. The editor spells its own graph deletes, so
104904
- // only a CLI push that tombstones a variant record reaches this arm.
104905
- deleted: true,
104906
- expectedBaseContentHash: baseContentHash,
104907
- intent: createProjectVersionIntent("value.delete", {
104908
- source: "server-variant-graph-cascade"
104909
- })
104910
- });
104911
- }
104912
- }
104913
105544
  var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, READ_ONLY_SOURCE_CONVERSION_INTENT_SOURCE, SCHEMA_RECORD_KINDS, DIALOGUE_SOURCE_RECORD_KINDS, NEO_VARIANT_SCHEMA_KEY_BY_ARGUMENT_NAME, VARIANT_CONSTRUCTOR_ARGS_SCHEMA_RECORD_KINDS;
104914
105545
  var init_project_version_schema_commit = __esm({
104915
105546
  "../src/database/project-version-schema-commit.ts"() {
104916
105547
  "use strict";
104917
105548
  init_members();
105549
+ init_neo_script_derived_bodies();
104918
105550
  init_localized_instance_override_writes();
104919
105551
  init_project_version_transaction_planning();
104920
105552
  init_members();
@@ -104959,6 +105591,10 @@ var init_project_version_schema_commit = __esm({
104959
105591
  init_virtual_instance_values();
104960
105592
  init_world_system_classes();
104961
105593
  init_neo_script_recompile_scope();
105594
+ init_stored_value_shape();
105595
+ init_owned_value_deletion();
105596
+ init_evaluateInitializer();
105597
+ init_virtual_instance_graph();
104962
105598
  SERVER_COMPILATION_PROJECT_CACHE_LIMIT = 4;
104963
105599
  serverCompilationProjectCache = /* @__PURE__ */ new Map();
104964
105600
  READ_ONLY_SOURCE_CONVERSION_INTENT_SOURCE = "server-readonly-source-conversion";
@@ -104989,77 +105625,6 @@ var init_project_version_schema_commit = __esm({
104989
105625
  }
104990
105626
  });
104991
105627
 
104992
- // ../src/database/project-record-semantics.ts
104993
- function projectRecordSemanticData(value) {
104994
- if (!isPlainRecord2(value)) return value;
104995
- const semantic = {};
104996
- for (const [key, child] of Object.entries(value)) {
104997
- if (SERVER_MANAGED_PROJECT_RECORD_FIELDS.has(key)) continue;
104998
- semantic[key] = child;
104999
- }
105000
- return semantic;
105001
- }
105002
- function projectRecordDataIsSemanticallyEqual(left, right) {
105003
- return canonicalJsonStringify2(projectRecordSemanticData(left)) === canonicalJsonStringify2(projectRecordSemanticData(right));
105004
- }
105005
- function canonicalJsonStringify2(value) {
105006
- return JSON.stringify(toCanonicalJsonValue2(value));
105007
- }
105008
- function toCanonicalJsonValue2(value) {
105009
- if (value === null) return null;
105010
- if (value === void 0) return void 0;
105011
- if (value instanceof Date) return value.toISOString();
105012
- if (typeof value === "string" || typeof value === "boolean") return value;
105013
- if (typeof value === "number") {
105014
- if (!Number.isFinite(value)) {
105015
- throw new Error("Cannot canonicalize a non-finite number.");
105016
- }
105017
- return value;
105018
- }
105019
- if (typeof value === "bigint") {
105020
- throw new Error("Cannot canonicalize bigint values.");
105021
- }
105022
- if (typeof value === "symbol") {
105023
- throw new Error("Cannot canonicalize symbol values.");
105024
- }
105025
- if (typeof value === "function") {
105026
- throw new Error("Cannot canonicalize function values.");
105027
- }
105028
- if (Array.isArray(value)) {
105029
- return value.map((item) => toCanonicalJsonValue2(item) ?? null);
105030
- }
105031
- if (!isPlainRecord2(value)) {
105032
- throw new Error("Cannot canonicalize a non-plain object.");
105033
- }
105034
- const canonical = {};
105035
- const entries = Object.entries(value).sort(
105036
- ([left], [right]) => left.localeCompare(right)
105037
- );
105038
- for (const [key, child] of entries) {
105039
- const canonicalChild = toCanonicalJsonValue2(child);
105040
- if (canonicalChild === void 0) continue;
105041
- canonical[key] = canonicalChild;
105042
- }
105043
- return canonical;
105044
- }
105045
- function isPlainRecord2(value) {
105046
- if (value === null || typeof value !== "object") return false;
105047
- const prototype = Object.getPrototypeOf(value);
105048
- return prototype === Object.prototype || prototype === null;
105049
- }
105050
- var SERVER_MANAGED_PROJECT_RECORD_FIELDS;
105051
- var init_project_record_semantics = __esm({
105052
- "../src/database/project-record-semantics.ts"() {
105053
- "use strict";
105054
- SERVER_MANAGED_PROJECT_RECORD_FIELDS = /* @__PURE__ */ new Set([
105055
- "_id",
105056
- "projectId",
105057
- "createdAt",
105058
- "updatedAt"
105059
- ]);
105060
- }
105061
- });
105062
-
105063
105628
  // ../src/database/system-protection.ts
105064
105629
  function hasSystemDisallowedOperation(system, operation) {
105065
105630
  if (system === null || system === void 0) return false;
@@ -105995,7 +106560,7 @@ function stagedChangesRequireWorldLayerBindingValidation(current, changes) {
105995
106560
  const before = classesById.get(change.recordId);
105996
106561
  if (before === void 0) return true;
105997
106562
  const after = change.nextData;
105998
- if (!isPlainRecord(after)) return true;
106563
+ if (!isPlainRecord2(after)) return true;
105999
106564
  if (before.extendsClassId !== after.extendsClassId) return true;
106000
106565
  if (isAbstractClass(before) !== isAbstractClass(after)) return true;
106001
106566
  if (!worldClassSystemBlockIsEqual(before.system, after.system)) return true;
@@ -106046,7 +106611,7 @@ function stagedAffectedWorldLayerLinkClassIds(args) {
106046
106611
  change.nextData
106047
106612
  ];
106048
106613
  for (const candidate of candidates) {
106049
- if (!isPlainRecord(candidate)) continue;
106614
+ if (!isPlainRecord2(candidate)) continue;
106050
106615
  const relationKind = candidate.relationKind;
106051
106616
  if (typeof relationKind !== "string") continue;
106052
106617
  if (!isStagedWorldLayerLinkTargetRelationKind(relationKind)) continue;
@@ -106089,9 +106654,9 @@ function worldClassSystemBlockIsEqual(before, after) {
106089
106654
  );
106090
106655
  }
106091
106656
  function hasWorldLayerOverrideMetadata(record4) {
106092
- if (!isPlainRecord(record4)) return false;
106657
+ if (!isPlainRecord2(record4)) return false;
106093
106658
  const value = record4.value;
106094
- if (!isPlainRecord(value)) return false;
106659
+ if (!isPlainRecord2(value)) return false;
106095
106660
  return typeof value.layerOverrideValueId === "string";
106096
106661
  }
106097
106662
  function assertStagedProjectInterfaceValid(projected, changes) {
@@ -106231,7 +106796,7 @@ function candidateActionListenerRowIds(projected, actions) {
106231
106796
  for (const row of projected.values) {
106232
106797
  if (storedRowActionListeners(row).length > 0) candidates.add(row.id);
106233
106798
  if (actionSchemaKeys.size === 0) continue;
106234
- if (!isPlainRecord(row.value)) continue;
106799
+ if (!isPlainRecord2(row.value)) continue;
106235
106800
  for (const schemaKey of actionSchemaKeys) {
106236
106801
  const childId = row.value[schemaKey];
106237
106802
  if (typeof childId === "string") candidates.add(childId);
@@ -106241,7 +106806,7 @@ function candidateActionListenerRowIds(projected, actions) {
106241
106806
  }
106242
106807
  function storedRowActionListeners(row) {
106243
106808
  const body = row.value;
106244
- if (!isPlainRecord(body)) return [];
106809
+ if (!isPlainRecord2(body)) return [];
106245
106810
  const listeners = body.listeners;
106246
106811
  return Array.isArray(listeners) ? listeners : [];
106247
106812
  }
@@ -106319,7 +106884,7 @@ function authoredActionListeners(action) {
106319
106884
  if (defaultValue === void 0 || defaultValue === null) return [];
106320
106885
  if (!isLiteralValueContent(defaultValue)) return [];
106321
106886
  const body = defaultValue.value;
106322
- if (!isPlainRecord(body)) return [];
106887
+ if (!isPlainRecord2(body)) return [];
106323
106888
  const listeners = body.listeners;
106324
106889
  return Array.isArray(listeners) ? listeners : [];
106325
106890
  }
@@ -106665,7 +107230,7 @@ function candidateVariantRowIds(projected, variantMembers) {
106665
107230
  candidates.add(row.id);
106666
107231
  }
106667
107232
  if (schemaKeys.size === 0) continue;
106668
- if (!isPlainRecord(row.value)) continue;
107233
+ if (!isPlainRecord2(row.value)) continue;
106669
107234
  for (const schemaKey of schemaKeys) {
106670
107235
  const childId = row.value[schemaKey];
106671
107236
  if (typeof childId === "string") candidates.add(childId);
@@ -109209,7 +109774,7 @@ function extractProjectSnapshotDerivedEdges(source) {
109209
109774
  })
109210
109775
  });
109211
109776
  }
109212
- const record4 = asRecord3(source.data);
109777
+ const record4 = asRecord4(source.data);
109213
109778
  if (source.recordKind === "dialogue-node" && record4 !== null && typeof record4.dialogueId === "string") {
109214
109779
  add({
109215
109780
  edgeKind: "dialogue-membership",
@@ -109220,7 +109785,7 @@ function extractProjectSnapshotDerivedEdges(source) {
109220
109785
  }
109221
109786
  if (source.recordKind === "value" && record4 !== null) {
109222
109787
  const body = record4.value;
109223
- if (Array.isArray(body) || asRecord3(body) !== null) {
109788
+ if (Array.isArray(body) || asRecord4(body) !== null) {
109224
109789
  for (const targetKey of collectDirectBodyChildIds(body)) {
109225
109790
  add({
109226
109791
  edgeKind: "containment-child",
@@ -109263,14 +109828,14 @@ function extractProjectSnapshotDerivedEdges(source) {
109263
109828
  })
109264
109829
  });
109265
109830
  }
109266
- const constructorArgs = record4 === null ? null : asRecord3(record4.constructorArgs);
109831
+ const constructorArgs = record4 === null ? null : asRecord4(record4.constructorArgs);
109267
109832
  return {
109268
109833
  edges: [...edges.values()].sort(compareEdges),
109269
109834
  complete: constructorArgs === null || Object.keys(constructorArgs).length === 0 || source.constructorAggregateEdges !== void 0
109270
109835
  };
109271
109836
  }
109272
109837
  function addStampBindingEdges(genericBindings, add) {
109273
- const bindings = asRecord3(genericBindings);
109838
+ const bindings = asRecord4(genericBindings);
109274
109839
  if (bindings === null) return;
109275
109840
  for (const [parameterId, stampedMemberId] of Object.entries(bindings)) {
109276
109841
  if (typeof stampedMemberId !== "string") continue;
@@ -109323,7 +109888,7 @@ function compareEdges(left, right) {
109323
109888
  return edgeIdentity(left).localeCompare(edgeIdentity(right));
109324
109889
  }
109325
109890
  function collectDirectBodyChildIds(value) {
109326
- const candidates = Array.isArray(value) ? value : Object.values(asRecord3(value) ?? {});
109891
+ const candidates = Array.isArray(value) ? value : Object.values(asRecord4(value) ?? {});
109327
109892
  return [
109328
109893
  ...new Set(
109329
109894
  candidates.filter(
@@ -109332,7 +109897,7 @@ function collectDirectBodyChildIds(value) {
109332
109897
  )
109333
109898
  ];
109334
109899
  }
109335
- function asRecord3(value) {
109900
+ function asRecord4(value) {
109336
109901
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
109337
109902
  }
109338
109903
  var PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION, STORED_PROJECT_RECORD_ID_PATTERN;
@@ -109678,7 +110243,9 @@ function commitPreparationWorldScopeKinds(args) {
109678
110243
  (schemaClass2) => typeof schemaClass2.system?.worldKind === "string" ? [schemaClass2.system.worldKind] : []
109679
110244
  )
109680
110245
  );
109681
- if (args.changes.some((change) => change.recordKind === "class")) {
110246
+ if (args.changes.some(
110247
+ (change) => change.recordKind === "class" || change.recordKind === "internal-record-relation"
110248
+ )) {
109682
110249
  return allKinds;
109683
110250
  }
109684
110251
  const kindsByClass = worldKindByClassId(args.postDocument);
@@ -110301,7 +110868,7 @@ function planCommitPreparationLoadedClosureScope(args) {
110301
110868
  if (rules.has("ancestor-paths") && record4.parentRecordKind !== null && record4.parentRecordKind !== void 0 && record4.parentRecordId !== null && record4.parentRecordId !== void 0) {
110302
110869
  rememberExact(record4.parentRecordKind, record4.parentRecordId);
110303
110870
  }
110304
- const canOwnStoredDescendants = record4.recordKind !== "value" || record4.data !== null && typeof record4.data === "object" && Reflect.get(record4.data, "value") !== null && typeof Reflect.get(record4.data, "value") === "object";
110871
+ const canOwnStoredDescendants = record4.recordKind !== "value" || !isLiteralValueContent(record4.data) || !["string", "number", "boolean"].includes(typeof record4.data.value) || typeof record4.data.classId === "string" || isVirtualInstanceRootShape(record4.data);
110305
110872
  if (rules.has("descendants") && record4.includeDescendants !== false && canOwnStoredDescendants && (record4.recordKind === "member" || record4.recordKind === "value" || record4.recordKind === "class" || record4.recordKind === "variant")) {
110306
110873
  rememberRange({
110307
110874
  rangeKind: "children",
@@ -126069,7 +126636,7 @@ function normalizeSourceFiles(inputFiles) {
126069
126636
  return files;
126070
126637
  }
126071
126638
  function readSourceFile(value, index) {
126072
- const record4 = asRecord4(value, `Project source identity file ${index}`);
126639
+ const record4 = asRecord5(value, `Project source identity file ${index}`);
126073
126640
  assertExactKeys(record4, ["path", "kind", "content"]);
126074
126641
  if (typeof record4.path !== "string" || !isSafeSourcePath(record4.path)) {
126075
126642
  throw new Error(
@@ -126104,7 +126671,7 @@ function isSafeSourcePath(path) {
126104
126671
  }
126105
126672
  return neoProjectSourceKind(path) !== null;
126106
126673
  }
126107
- function asRecord4(value, label) {
126674
+ function asRecord5(value, label) {
126108
126675
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
126109
126676
  throw new Error(`${label} must be an object.`);
126110
126677
  }
@@ -130077,7 +130644,7 @@ var init_registry2 = __esm({
130077
130644
  "schema-contract/registry.mjs"() {
130078
130645
  "use strict";
130079
130646
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
130080
- cliVersion: "0.47.0",
130647
+ cliVersion: "0.47.1",
130081
130648
  projectFileUploadBatchSize: 32,
130082
130649
  documentRecords: {
130083
130650
  member: {
@@ -136480,6 +137047,7 @@ function resolveWriteRowId(write, target, compiledAction, ctx, world) {
136480
137047
  const pointer = isObjectRecord2(target.pointer) ? target.pointer : target;
136481
137048
  const evalPointer2 = (p) => {
136482
137049
  const getter = {
137050
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
136483
137051
  parameters: compiledAction.parameters ?? [],
136484
137052
  instructions: [{ type: "return", pointer: p }],
136485
137053
  typeInfo: { type: 0, required: false }
@@ -136533,6 +137101,7 @@ function printReport(report) {
136533
137101
  var init_dialogue_dryrun = __esm({
136534
137102
  "src/commands/dialogue-dryrun.ts"() {
136535
137103
  "use strict";
137104
+ init_src();
136536
137105
  init_document();
136537
137106
  init_projection();
136538
137107
  init_neoscript2();
@@ -137118,7 +137687,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
137118
137687
  async function main() {
137119
137688
  const args = parseArgs(process.argv.slice(2));
137120
137689
  if (args.command === "--version") {
137121
- console.log("0.47.0");
137690
+ console.log("0.47.1");
137122
137691
  return;
137123
137692
  }
137124
137693
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
@@ -137234,8 +137803,7 @@ async function main() {
137234
137803
  await runDoctor2(workspace, {
137235
137804
  json,
137236
137805
  fix,
137237
- yes,
137238
- strict: boolFlag(args)
137806
+ yes
137239
137807
  });
137240
137808
  return;
137241
137809
  }