@neocompose/cli 0.52.5 → 0.53.0

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
@@ -5012,6 +5012,15 @@ function identPathSegments(expression) {
5012
5012
  if (receiver === null) return null;
5013
5013
  return [...receiver, expression.name];
5014
5014
  }
5015
+ function receiverNarrowings(path, rootEntry, scope) {
5016
+ const facts = [];
5017
+ for (let dot = path.indexOf("."); dot !== -1; dot = path.indexOf(".", dot + 1)) {
5018
+ const prefix = path.slice(0, dot);
5019
+ const type = scope.lookupNarrowedType(prefix, rootEntry);
5020
+ if (type !== null) facts.push([prefix, type]);
5021
+ }
5022
+ return facts;
5023
+ }
5015
5024
  function pathRoot(path) {
5016
5025
  const dot = path.indexOf(".");
5017
5026
  return dot === -1 ? path : path.slice(0, dot);
@@ -7536,7 +7545,15 @@ var init_strict_resolver = __esm({
7536
7545
  if (assignedPath) {
7537
7546
  const rootEntry = scope.lookup(pathRoot(assignedPath));
7538
7547
  if (rootEntry) {
7548
+ const receiverFacts = receiverNarrowings(
7549
+ assignedPath,
7550
+ rootEntry,
7551
+ scope
7552
+ );
7539
7553
  scope.invalidate(rootEntry);
7554
+ for (const [path, type] of receiverFacts) {
7555
+ scope.narrow(path, rootEntry, type);
7556
+ }
7540
7557
  if (statement.op === "=" && !isNullable(value.type)) {
7541
7558
  scope.narrow(assignedPath, rootEntry, {
7542
7559
  ...target.type,
@@ -7627,7 +7644,17 @@ var init_strict_resolver = __esm({
7627
7644
  const assignedPath = canonicalPath(statement.target);
7628
7645
  if (assignedPath) {
7629
7646
  const rootEntry = scope.lookup(pathRoot(assignedPath));
7630
- if (rootEntry) scope.invalidate(rootEntry);
7647
+ if (rootEntry) {
7648
+ const receiverFacts = receiverNarrowings(
7649
+ assignedPath,
7650
+ rootEntry,
7651
+ scope
7652
+ );
7653
+ scope.invalidate(rootEntry);
7654
+ for (const [path, type] of receiverFacts) {
7655
+ scope.narrow(path, rootEntry, type);
7656
+ }
7657
+ }
7631
7658
  }
7632
7659
  const kind = statement.op === "+=" ? "addActionListener" /* AddActionListener */ : "removeActionListener" /* RemoveActionListener */;
7633
7660
  return {
@@ -53539,11 +53566,14 @@ function requiredMembersForConstruction(classId, document, classArguments2) {
53539
53566
  );
53540
53567
  }
53541
53568
  function contextFor(document, env = /* @__PURE__ */ new Map()) {
53542
- return {
53543
- document,
53544
- membersById: new Map(document.members.map((member) => [member.id, member])),
53545
- env
53546
- };
53569
+ const indexed = document.memberById;
53570
+ if (indexed !== void 0) {
53571
+ return { document, memberById: (id2) => indexed(id2) ?? void 0, env };
53572
+ }
53573
+ const membersById = new Map(
53574
+ document.members.map((member) => [member.id, member])
53575
+ );
53576
+ return { document, memberById: (id2) => membersById.get(id2), env };
53547
53577
  }
53548
53578
  function unsettledMembers(classId, context, classArguments2, path) {
53549
53579
  const previousEnv = context.env;
@@ -53561,7 +53591,7 @@ function unsettledMembers(classId, context, classArguments2, path) {
53561
53591
  }
53562
53592
  }
53563
53593
  function constructionMembers(classId, context) {
53564
- const { document, membersById, env } = context;
53594
+ const { document, memberById: memberById2, env } = context;
53565
53595
  if (firstUnboundParamId(env) !== null) return [];
53566
53596
  const result = [];
53567
53597
  for (const entry of mergeStoredInstanceSchema(
@@ -53569,7 +53599,7 @@ function constructionMembers(classId, context) {
53569
53599
  document.classes,
53570
53600
  document.members
53571
53601
  )) {
53572
- const raw = membersById.get(entry.memberId);
53602
+ const raw = memberById2(entry.memberId);
53573
53603
  if (raw === void 0) continue;
53574
53604
  const member = {
53575
53605
  ...raw,
@@ -53632,7 +53662,7 @@ function valueSettlesConstruction(member, body, context, path, storedRow = false
53632
53662
  if (isCollection) {
53633
53663
  if (body.genericBindings != null)
53634
53664
  context.env = envFromStamp(body.genericBindings);
53635
- const entry = context.membersById.get(member.entryMemberId);
53665
+ const entry = context.memberById(member.entryMemberId);
53636
53666
  if (entry === void 0) return false;
53637
53667
  const resolvedEntry = substituteMember(
53638
53668
  entry,
@@ -68044,6 +68074,247 @@ var init_read_class_member = __esm({
68044
68074
  }
68045
68075
  });
68046
68076
 
68077
+ // ../src/runtime/neoscript/unattributable-reads.ts
68078
+ function ownershipChainRead(kind, rowId) {
68079
+ return `${kind}:${rowId}`;
68080
+ }
68081
+ function containerEntriesRead(containerId) {
68082
+ return `${CONTAINER_ENTRIES_PREFIX}${containerId}`;
68083
+ }
68084
+ function classifyUnattributableRead(reason) {
68085
+ for (const prefix of OWNERSHIP_CHAIN_PREFIXES) {
68086
+ if (reason.startsWith(prefix)) {
68087
+ return { scope: "ownership-chain" /* OwnershipChain */ };
68088
+ }
68089
+ }
68090
+ if (reason.startsWith(CONTAINER_ENTRIES_PREFIX)) {
68091
+ return {
68092
+ scope: "container" /* Container */,
68093
+ containerId: reason.slice(CONTAINER_ENTRIES_PREFIX.length)
68094
+ };
68095
+ }
68096
+ return { scope: "corpus" /* Corpus */ };
68097
+ }
68098
+ var OWNERSHIP_CHAIN_PREFIXES, CONTAINER_ENTRIES_PREFIX, OWNERSHIP_CHAIN_READ;
68099
+ var init_unattributable_reads = __esm({
68100
+ "../src/runtime/neoscript/unattributable-reads.ts"() {
68101
+ "use strict";
68102
+ OWNERSHIP_CHAIN_PREFIXES = [
68103
+ "generic-parent-resolution:",
68104
+ "member-owner-resolution:",
68105
+ "owned-value-parents:",
68106
+ "declaration-owner-resolution:"
68107
+ ];
68108
+ CONTAINER_ENTRIES_PREFIX = "container-entries:";
68109
+ OWNERSHIP_CHAIN_READ = ownershipChainRead(
68110
+ "member-owner-resolution",
68111
+ "*"
68112
+ );
68113
+ }
68114
+ });
68115
+
68116
+ // ../src/runtime/neoscript/cell-pattern.ts
68117
+ function integer2(value, name, minimum = -2147483648) {
68118
+ if (typeof value !== "number" || !Number.isInteger(value)) {
68119
+ throw new TypeError(`${name} must be an integer.`);
68120
+ }
68121
+ if (value < minimum) {
68122
+ throw new RangeError(`${name} must be at least ${minimum}.`);
68123
+ }
68124
+ if (value > 2147483647) {
68125
+ throw new RangeError(`${name} exceeds the supported integer range.`);
68126
+ }
68127
+ return value === 0 ? 0 : value;
68128
+ }
68129
+ function vector(value, name) {
68130
+ if (!isVector2IntValue(value)) {
68131
+ throw new TypeError(`${name} must be a Vector2Int.`);
68132
+ }
68133
+ return { x: integer2(value.x, `${name}.x`), y: integer2(value.y, `${name}.y`) };
68134
+ }
68135
+ function exclusion(value) {
68136
+ if (!Array.isArray(value) || value.length !== 1) {
68137
+ throw new TypeError(
68138
+ "excluding must select one NeoCellPatternExcluding option."
68139
+ );
68140
+ }
68141
+ if (value[0] === NEO_CELL_PATTERN_EXCLUDING_OPTION_IDS.None) return "none";
68142
+ if (value[0] === NEO_CELL_PATTERN_EXCLUDING_OPTION_IDS.Center)
68143
+ return "center";
68144
+ throw new RangeError("excluding is not a NeoCellPatternExcluding option.");
68145
+ }
68146
+ function reserve(ctx, count) {
68147
+ if (!Number.isSafeInteger(count) || count < 0) {
68148
+ throw new RangeError("Cell pattern contains too many offsets.");
68149
+ }
68150
+ ctx.reserveEntries(count);
68151
+ }
68152
+ function appendShell(result, radius, minX, maxX, minY, maxY) {
68153
+ if (radius === 0) {
68154
+ if (minX <= 0 && maxX >= 0 && minY <= 0 && maxY >= 0)
68155
+ result.push({ x: 0, y: 0 });
68156
+ return;
68157
+ }
68158
+ const firstY = Math.max(minY, -radius) || 0;
68159
+ const lastY = Math.min(maxY, radius);
68160
+ if (firstY > lastY) return;
68161
+ if (-radius >= minX && -radius <= maxX) {
68162
+ for (let y = firstY; y <= lastY; y++) result.push({ x: -radius, y });
68163
+ }
68164
+ const bottom = -radius >= minY && -radius <= maxY;
68165
+ const top = radius !== 0 && radius >= minY && radius <= maxY;
68166
+ if (bottom || top) {
68167
+ const firstX = Math.max(minX, -radius + 1) || 0;
68168
+ const lastX = Math.min(maxX, radius - 1);
68169
+ for (let x = firstX; x <= lastX; x++) {
68170
+ if (bottom) result.push({ x, y: -radius });
68171
+ if (top) result.push({ x, y: radius });
68172
+ }
68173
+ }
68174
+ if (radius !== 0 && radius >= minX && radius <= maxX) {
68175
+ for (let y = firstY; y <= lastY; y++) result.push({ x: radius, y });
68176
+ }
68177
+ }
68178
+ function rectangle(ctx, minX, maxX, minY, maxY, excluding) {
68179
+ const count = (maxX - minX + 1) * (maxY - minY + 1);
68180
+ reserve(ctx, count - (excluding === "center" ? 1 : 0));
68181
+ const offsets = [];
68182
+ const radius = Math.max(-minX, maxX, -minY, maxY);
68183
+ for (let shell = excluding === "center" ? 1 : 0; shell <= radius; shell++) {
68184
+ appendShell(offsets, shell, minX, maxX, minY, maxY);
68185
+ }
68186
+ return offsets;
68187
+ }
68188
+ function translated(offsets, origin, ctx) {
68189
+ reserve(ctx, offsets.length);
68190
+ return offsets.map((offset) => ({
68191
+ x: integer2(offset.x + origin.x, "Translated cell.x"),
68192
+ y: integer2(offset.y + origin.y, "Translated cell.y")
68193
+ }));
68194
+ }
68195
+ function isCenter(offset) {
68196
+ return offset.x === 0 && offset.y === 0;
68197
+ }
68198
+ function evaluateCellPatternNative(memberId, receiver, args, ctx) {
68199
+ if (!NEO_CELL_PATTERN_PURE_NATIVE_MEMBER_IDS.has(memberId)) {
68200
+ return { handled: false };
68201
+ }
68202
+ const pattern = (offsets2) => ({
68203
+ handled: true,
68204
+ value: ctx.constructPattern(offsets2)
68205
+ });
68206
+ switch (memberId) {
68207
+ case NEO_CELL_PATTERN_MEMBER_IDS.Box: {
68208
+ const x = integer2(args[0], "Box radiusX", 0);
68209
+ const y = args[1] === null ? x : integer2(args[1], "Box radiusY", 0);
68210
+ return pattern(rectangle(ctx, -x, x, -y, y, exclusion(args[2])));
68211
+ }
68212
+ case NEO_CELL_PATTERN_MEMBER_IDS.Cross: {
68213
+ const x = integer2(args[0], "Cross radiusX", 0);
68214
+ const y = args[1] === null ? x : integer2(args[1], "Cross radiusY", 0);
68215
+ const excluding = exclusion(args[2]);
68216
+ reserve(ctx, 2 * (x + y) + (excluding === "none" ? 1 : 0));
68217
+ const offsets2 = excluding === "none" ? [{ x: 0, y: 0 }] : [];
68218
+ for (let distance = 1; distance <= Math.max(x, y); distance++) {
68219
+ if (distance <= x)
68220
+ offsets2.push({ x: -distance, y: 0 }, { x: distance, y: 0 });
68221
+ if (distance <= y)
68222
+ offsets2.push({ x: 0, y: -distance }, { x: 0, y: distance });
68223
+ }
68224
+ return pattern(offsets2);
68225
+ }
68226
+ case NEO_CELL_PATTERN_MEMBER_IDS.Ring: {
68227
+ const radius = integer2(args[0], "Ring radius", 0);
68228
+ reserve(ctx, radius === 0 ? 1 : 8 * radius);
68229
+ const offsets2 = [];
68230
+ appendShell(offsets2, radius, -radius, radius, -radius, radius);
68231
+ return pattern(offsets2);
68232
+ }
68233
+ case NEO_CELL_PATTERN_MEMBER_IDS.Rect: {
68234
+ const size = vector(args[0], "Rect size");
68235
+ integer2(size.x, "Rect size.x", 1);
68236
+ integer2(size.y, "Rect size.y", 1);
68237
+ return pattern(rectangle(ctx, 0, size.x - 1, 0, size.y - 1, "none"));
68238
+ }
68239
+ case NEO_CELL_PATTERN_MEMBER_IDS.Line: {
68240
+ const direction = vector(args[0], "Line direction");
68241
+ if (isCenter(direction))
68242
+ throw new RangeError("Line direction must be non-zero.");
68243
+ const length = integer2(args[1], "Line length", 0);
68244
+ const excluding = exclusion(args[2]);
68245
+ reserve(ctx, length + (excluding === "none" ? 1 : 0));
68246
+ integer2(direction.x * length, "Line endpoint.x");
68247
+ integer2(direction.y * length, "Line endpoint.y");
68248
+ const offsets2 = excluding === "none" ? [{ x: 0, y: 0 }] : [];
68249
+ for (let step = 1; step <= length; step++) {
68250
+ offsets2.push({ x: direction.x * step, y: direction.y * step });
68251
+ }
68252
+ return pattern(offsets2);
68253
+ }
68254
+ }
68255
+ const offsets = ctx.readPattern(receiver);
68256
+ ctx.visitEntries(offsets.length);
68257
+ switch (memberId) {
68258
+ case NEO_CELL_PATTERN_MEMBER_IDS.Contains: {
68259
+ const offset = vector(args[0], "Contains offset");
68260
+ return {
68261
+ handled: true,
68262
+ value: offsets.some(
68263
+ (cell) => cell.x === offset.x && cell.y === offset.y
68264
+ )
68265
+ };
68266
+ }
68267
+ case NEO_CELL_PATTERN_MEMBER_IDS.Cells:
68268
+ return {
68269
+ handled: true,
68270
+ value: translated(offsets, vector(args[0], "Cells origin"), ctx)
68271
+ };
68272
+ case NEO_CELL_PATTERN_MEMBER_IDS.WithCenter:
68273
+ if (offsets.some(isCenter)) return { handled: true, value: receiver };
68274
+ reserve(ctx, offsets.length + 1);
68275
+ return pattern([{ x: 0, y: 0 }, ...offsets]);
68276
+ case NEO_CELL_PATTERN_MEMBER_IDS.WithoutCenter: {
68277
+ let count = 0;
68278
+ for (const offset of offsets) if (!isCenter(offset)) count++;
68279
+ if (count === offsets.length) return { handled: true, value: receiver };
68280
+ reserve(ctx, count);
68281
+ return pattern(offsets.filter((offset) => !isCenter(offset)));
68282
+ }
68283
+ case NEO_CELL_PATTERN_MEMBER_IDS.Translate: {
68284
+ const offset = vector(args[0], "Translate offset");
68285
+ if (isCenter(offset)) return { handled: true, value: receiver };
68286
+ return pattern(translated(offsets, offset, ctx));
68287
+ }
68288
+ case NEO_CELL_PATTERN_MEMBER_IDS.Union: {
68289
+ const other = ctx.readPattern(args[0]);
68290
+ ctx.visitEntries(other.length);
68291
+ const seen = /* @__PURE__ */ new Set();
68292
+ const result = [];
68293
+ for (const source of [offsets, other]) {
68294
+ for (const offset of source) {
68295
+ const key = `${offset.x},${offset.y}`;
68296
+ if (seen.has(key)) continue;
68297
+ reserve(ctx, 1);
68298
+ seen.add(key);
68299
+ result.push(offset);
68300
+ }
68301
+ }
68302
+ return pattern(result);
68303
+ }
68304
+ default:
68305
+ throw new Error(
68306
+ `Cell pattern native member '${memberId}' has no implementation.`
68307
+ );
68308
+ }
68309
+ }
68310
+ var init_cell_pattern2 = __esm({
68311
+ "../src/runtime/neoscript/cell-pattern.ts"() {
68312
+ "use strict";
68313
+ init_src();
68314
+ init_member_kinds();
68315
+ }
68316
+ });
68317
+
68047
68318
  // ../src/models/project/project-types.ts
68048
68319
  function isProject(value) {
68049
68320
  const v = value;
@@ -68827,588 +69098,6 @@ var init_project2 = __esm({
68827
69098
  }
68828
69099
  });
68829
69100
 
68830
- // ../src/models/members/stored-value-placement-index.ts
68831
- function buildStoredValuePlacementIndex(args) {
68832
- return createStoredValuePlacementTraversal(args)();
68833
- }
68834
- function createStoredValuePlacementTraversal(args, trackReferences = false) {
68835
- const membersById = /* @__PURE__ */ new Map();
68836
- for (const member of args.members) membersById.set(member.id, member);
68837
- const valuesById = args.indexedRows?.valuesById ?? new Map(args.values.map((row) => [row.id, row]));
68838
- const unorderedEntriesByContainerId = /* @__PURE__ */ new Map();
68839
- for (const value of args.indexedRows === void 0 ? args.values : []) {
68840
- if (typeof value.containerId !== "string") continue;
68841
- const entries = unorderedEntriesByContainerId.get(value.containerId);
68842
- if (entries === void 0) {
68843
- unorderedEntriesByContainerId.set(value.containerId, [value]);
68844
- } else {
68845
- entries.push(value);
68846
- }
68847
- }
68848
- for (const entries of unorderedEntriesByContainerId.values()) {
68849
- entries.sort((left, right) => left.id.localeCompare(right.id));
68850
- }
68851
- const constructorsById = new Map(
68852
- args.constructors.map((constructor2) => [constructor2.id, constructor2])
68853
- );
68854
- const resolveConstructorSettlement = createConstructorSettlementResolver({
68855
- classes: args.classes,
68856
- constructors: args.constructors,
68857
- members: args.members
68858
- });
68859
- const resolvedMemberById = /* @__PURE__ */ new Map();
68860
- const resolvedMember = (member) => {
68861
- const cached = resolvedMemberById.get(member.id);
68862
- if (cached !== void 0) return cached;
68863
- const resolved = resolveMember2(member, args.members);
68864
- resolvedMemberById.set(member.id, resolved);
68865
- return resolved;
68866
- };
68867
- const storedSchemaByClassId = /* @__PURE__ */ new Map();
68868
- const storedSchema = (classId) => {
68869
- const cached = storedSchemaByClassId.get(classId);
68870
- if (cached !== void 0) return cached;
68871
- const schema = mergeStoredInstanceSchema(
68872
- classId,
68873
- args.classes,
68874
- args.members
68875
- );
68876
- storedSchemaByClassId.set(classId, schema);
68877
- return schema;
68878
- };
68879
- return (roots) => {
68880
- const queue = [...roots ?? []];
68881
- if (roots === void 0) {
68882
- for (const root of projectRootMembersInDisplayOrder(args.project)) {
68883
- const member = membersById.get(root.memberId);
68884
- if (member === void 0 || typeof member.valueId !== "string")
68885
- continue;
68886
- queue.push({
68887
- memberId: member.id,
68888
- parentValueId: null,
68889
- source: {
68890
- kind: "root",
68891
- label: root.root.label,
68892
- sourcePath: `root.${root.root.key}`
68893
- },
68894
- valueId: member.valueId
68895
- });
68896
- }
68897
- for (const member of args.members) {
68898
- if (!isStaticMember(member) || memberAccessOf(member) !== 0 /* Public */)
68899
- continue;
68900
- const valueId = args.resolveStaticValueId(member.id);
68901
- if (valueId === null) continue;
68902
- const placement = findSchemaPlacement(member.id, args.classes);
68903
- if (placement === null) continue;
68904
- queue.push({
68905
- memberId: member.id,
68906
- parentValueId: null,
68907
- source: {
68908
- kind: "static",
68909
- label: placement.schemaKey,
68910
- ownerClassName: placement.ownerClass.name,
68911
- sourcePath: `static:${member.id}`
68912
- },
68913
- valueId
68914
- });
68915
- }
68916
- }
68917
- const placementByValueId = /* @__PURE__ */ new Map();
68918
- const mutablePlacementsByClassId = /* @__PURE__ */ new Map();
68919
- const mutablePlacementsByMemberId = /* @__PURE__ */ new Map();
68920
- const mutablePlacementsByKind = /* @__PURE__ */ new Map();
68921
- for (let cursor = 0; cursor < queue.length; cursor += 1) {
68922
- const item = queue[cursor];
68923
- if (item === void 0 || placementByValueId.has(item.valueId)) continue;
68924
- const authoredValue = valuesById.get(item.valueId);
68925
- const storedMember = membersById.get(item.memberId);
68926
- if (authoredValue === void 0 || storedMember === void 0) continue;
68927
- const value = args.resolveValue === void 0 ? authoredValue : args.resolveValue(authoredValue);
68928
- if (value === null) continue;
68929
- const placement = item;
68930
- placementByValueId.set(value.id, placement);
68931
- appendPlacement(mutablePlacementsByMemberId, storedMember.id, placement);
68932
- const member = resolvedMember(storedMember);
68933
- appendPlacement(mutablePlacementsByKind, member.kind, placement);
68934
- if (isMemberClassBase(member)) {
68935
- const classId = value.classId ?? member.classId;
68936
- appendPlacement(mutablePlacementsByClassId, classId, placement);
68937
- if (!isLiteralValueContent(value) || !isStringRecord4(value.value)) {
68938
- continue;
68939
- }
68940
- const settledChildrenBySchemaKey = /* @__PURE__ */ new Map();
68941
- const constructor2 = typeof value.instanceConstructorId === "string" ? constructorsById.get(value.instanceConstructorId) : void 0;
68942
- if (constructor2 !== void 0 && constructor2.classId === classId && value.constructorArgs != null) {
68943
- for (const [
68944
- index,
68945
- parameter4
68946
- ] of constructor2.argumentTypes.entries()) {
68947
- const settled = resolveConstructorSettlement(
68948
- classId,
68949
- parameter4.name,
68950
- constructor2.id
68951
- );
68952
- if (settled === null || Object.hasOwn(value.value, settled.schemaKey)) {
68953
- continue;
68954
- }
68955
- const childValueId = value.constructorArgs[constructorActionParameterId(constructor2, index)];
68956
- if (typeof childValueId === "string") {
68957
- settledChildrenBySchemaKey.set(settled.schemaKey, childValueId);
68958
- }
68959
- }
68960
- }
68961
- for (const entry of storedSchema(classId)) {
68962
- const childMember = membersById.get(entry.memberId);
68963
- const childValueId = value.value[entry.schemaKey] ?? settledChildrenBySchemaKey.get(entry.schemaKey);
68964
- if (childMember === void 0 || typeof childValueId !== "string") {
68965
- continue;
68966
- }
68967
- if (memberAccessOf(childMember) !== 0 /* Public */) continue;
68968
- queue.push({
68969
- memberId: childMember.id,
68970
- parentValueId: value.id,
68971
- source: { kind: "classField", schemaKey: entry.schemaKey },
68972
- valueId: childValueId
68973
- });
68974
- }
68975
- continue;
68976
- }
68977
- if (!isMemberListBase(member) && !isMemberDictionaryBase(member)) {
68978
- continue;
68979
- }
68980
- const entryMember = membersById.get(member.entryMemberId);
68981
- if (entryMember === void 0) continue;
68982
- if (isMemberDictionaryBase(member)) {
68983
- if (!isStringRecord4(value.value)) continue;
68984
- for (const [key, childValueId] of Object.entries(value.value)) {
68985
- queue.push({
68986
- memberId: entryMember.id,
68987
- parentValueId: value.id,
68988
- source: {
68989
- kind: "collectionEntry",
68990
- containerMemberId: storedMember.id,
68991
- entry: { kind: "dict", key, valueId: childValueId }
68992
- },
68993
- valueId: childValueId
68994
- });
68995
- }
68996
- continue;
68997
- }
68998
- const entries = listKindOf(member) === 1 /* Unordered */ ? args.indexedRows === void 0 ? unorderedEntriesByContainerId.get(value.id) ?? [] : args.indexedRows.unorderedListEntryIds(value.id).flatMap((id2) => {
68999
- const row = valuesById.get(id2);
69000
- return row === void 0 ? [] : [row];
69001
- }) : Array.isArray(value.value) ? value.value.flatMap((childValueId) => {
69002
- if (typeof childValueId !== "string") return [];
69003
- const childValue = valuesById.get(childValueId);
69004
- return childValue === void 0 ? [] : [childValue];
69005
- }) : [];
69006
- for (const [index, childValue] of entries.entries()) {
69007
- queue.push({
69008
- memberId: entryMember.id,
69009
- parentValueId: value.id,
69010
- source: {
69011
- kind: "collectionEntry",
69012
- containerMemberId: storedMember.id,
69013
- entry: { kind: "list", index, valueId: childValue.id }
69014
- },
69015
- valueId: childValue.id
69016
- });
69017
- }
69018
- }
69019
- const referencesByParentId = /* @__PURE__ */ new Map();
69020
- if (trackReferences) {
69021
- for (const id2 of placementByValueId.keys())
69022
- referencesByParentId.set(id2, /* @__PURE__ */ new Set());
69023
- for (const item of queue) {
69024
- if (item.parentValueId !== null)
69025
- referencesByParentId.get(item.parentValueId)?.add(item.valueId);
69026
- }
69027
- }
69028
- return {
69029
- referencesByParentId,
69030
- placementByValueId,
69031
- placementsByClassId: mutablePlacementsByClassId,
69032
- placementsByKind: mutablePlacementsByKind,
69033
- placementsByMemberId: mutablePlacementsByMemberId
69034
- };
69035
- };
69036
- }
69037
- function createStoredValuePlacementBatch(args) {
69038
- const traverse = createStoredValuePlacementTraversal(args, true);
69039
- const initial = traverse();
69040
- const placementByValueId = new Map(initial.placementByValueId);
69041
- const childrenByParentId = /* @__PURE__ */ new Map();
69042
- const referencingParentsById = /* @__PURE__ */ new Map();
69043
- const referencesByParentId = /* @__PURE__ */ new Map();
69044
- const declaredRootIds = new Set(
69045
- args.members.flatMap(
69046
- (member) => typeof member.valueId === "string" ? [member.valueId] : []
69047
- )
69048
- );
69049
- const indexPlacement = (placement) => {
69050
- if (placement.parentValueId === null) return;
69051
- const children = childrenByParentId.get(placement.parentValueId) ?? /* @__PURE__ */ new Set();
69052
- children.add(placement.valueId);
69053
- childrenByParentId.set(placement.parentValueId, children);
69054
- };
69055
- for (const placement of placementByValueId.values())
69056
- indexPlacement(placement);
69057
- const indexReferences2 = (parentId, references) => {
69058
- for (const id2 of referencesByParentId.get(parentId) ?? []) {
69059
- const parents = referencingParentsById.get(id2);
69060
- parents?.delete(parentId);
69061
- if (parents?.size === 0) referencingParentsById.delete(id2);
69062
- }
69063
- referencesByParentId.set(parentId, new Set(references));
69064
- for (const id2 of references) {
69065
- const parents = referencingParentsById.get(id2) ?? /* @__PURE__ */ new Set();
69066
- parents.add(parentId);
69067
- referencingParentsById.set(id2, parents);
69068
- }
69069
- };
69070
- for (const [parentId, references] of initial.referencesByParentId)
69071
- indexReferences2(parentId, references);
69072
- const rebuild = () => {
69073
- const rebuilt = traverse();
69074
- placementByValueId.clear();
69075
- childrenByParentId.clear();
69076
- referencesByParentId.clear();
69077
- referencingParentsById.clear();
69078
- for (const placement of rebuilt.placementByValueId.values()) {
69079
- placementByValueId.set(placement.valueId, placement);
69080
- indexPlacement(placement);
69081
- }
69082
- for (const [parentId, references] of rebuilt.referencesByParentId)
69083
- indexReferences2(parentId, references);
69084
- };
69085
- return {
69086
- placementByValueId,
69087
- /** Call after the external row/membership indexes have received these replacements. */
69088
- refresh(rows, previousRows) {
69089
- const affected = /* @__PURE__ */ new Set();
69090
- const consider = (id2) => {
69091
- if (typeof id2 === "string" && placementByValueId.has(id2))
69092
- affected.add(id2);
69093
- };
69094
- let needsRootRebuild = false;
69095
- for (const row of rows) {
69096
- consider(row.id);
69097
- if (!placementByValueId.has(row.id)) {
69098
- for (const parentId of referencingParentsById.get(row.id) ?? [])
69099
- consider(parentId);
69100
- }
69101
- if (!placementByValueId.has(row.id) && declaredRootIds.has(row.id))
69102
- needsRootRebuild = true;
69103
- }
69104
- const previousById = new Map(
69105
- previousRows.flatMap(
69106
- (row) => row === void 0 ? [] : [[row.id, row]]
69107
- )
69108
- );
69109
- for (const row of rows) {
69110
- const previous = previousById.get(row.id);
69111
- if (previous?.containerId === row.containerId) continue;
69112
- consider(previous?.containerId);
69113
- consider(row.containerId);
69114
- }
69115
- if (needsRootRebuild) {
69116
- rebuild();
69117
- return;
69118
- }
69119
- const hasAffectedAncestor = /* @__PURE__ */ new Map();
69120
- const rootSeeds = [];
69121
- for (const id2 of affected) {
69122
- const placement = placementByValueId.get(id2);
69123
- let parent = placement.parentValueId;
69124
- const path = [];
69125
- let found = false;
69126
- while (parent !== null) {
69127
- if (affected.has(parent)) {
69128
- found = true;
69129
- break;
69130
- }
69131
- const cached = hasAffectedAncestor.get(parent);
69132
- if (cached !== void 0) {
69133
- found = cached;
69134
- break;
69135
- }
69136
- path.push(parent);
69137
- parent = placementByValueId.get(parent)?.parentValueId ?? null;
69138
- }
69139
- for (const ancestor of path) hasAffectedAncestor.set(ancestor, found);
69140
- if (!found) rootSeeds.push(placement);
69141
- }
69142
- const removed = /* @__PURE__ */ new Set();
69143
- const queue = rootSeeds.map((root) => root.valueId);
69144
- for (let index = 0; index < queue.length; index += 1) {
69145
- const id2 = queue[index];
69146
- if (removed.has(id2)) continue;
69147
- removed.add(id2);
69148
- for (const child of childrenByParentId.get(id2) ?? []) queue.push(child);
69149
- }
69150
- for (const id2 of removed) {
69151
- const oldParent = placementByValueId.get(id2)?.parentValueId;
69152
- for (const parentId of referencingParentsById.get(id2) ?? []) {
69153
- if (!removed.has(parentId) && parentId !== oldParent && placementByValueId.has(parentId)) {
69154
- rebuild();
69155
- return;
69156
- }
69157
- }
69158
- }
69159
- for (const id2 of removed) {
69160
- const parent = placementByValueId.get(id2)?.parentValueId;
69161
- if (typeof parent === "string")
69162
- childrenByParentId.get(parent)?.delete(id2);
69163
- childrenByParentId.delete(id2);
69164
- placementByValueId.delete(id2);
69165
- }
69166
- const next = traverse(rootSeeds);
69167
- for (const [id2, placement] of next.placementByValueId) {
69168
- const existing = placementByValueId.get(id2);
69169
- if (existing !== void 0 && existing.parentValueId !== placement.parentValueId) {
69170
- rebuild();
69171
- return;
69172
- }
69173
- }
69174
- for (const id2 of removed) indexReferences2(id2, /* @__PURE__ */ new Set());
69175
- for (const [parentId, references] of next.referencesByParentId)
69176
- indexReferences2(parentId, references);
69177
- for (const placement of next.placementByValueId.values()) {
69178
- placementByValueId.set(placement.valueId, placement);
69179
- indexPlacement(placement);
69180
- }
69181
- }
69182
- };
69183
- }
69184
- function appendPlacement(index, key, placement) {
69185
- const placements = index.get(key);
69186
- if (placements === void 0) {
69187
- index.set(key, [placement]);
69188
- } else {
69189
- placements.push(placement);
69190
- }
69191
- }
69192
- function isStringRecord4(value) {
69193
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
69194
- return false;
69195
- }
69196
- return Object.values(value).every((item) => typeof item === "string");
69197
- }
69198
- var init_stored_value_placement_index = __esm({
69199
- "../src/models/members/stored-value-placement-index.ts"() {
69200
- "use strict";
69201
- init_inheritance();
69202
- init_constructor_parameter_settlement();
69203
- init_constructors2();
69204
- init_project2();
69205
- init_member_kinds();
69206
- init_members();
69207
- }
69208
- });
69209
-
69210
- // ../src/runtime/neoscript/cell-pattern.ts
69211
- function integer2(value, name, minimum = -2147483648) {
69212
- if (typeof value !== "number" || !Number.isInteger(value)) {
69213
- throw new TypeError(`${name} must be an integer.`);
69214
- }
69215
- if (value < minimum) {
69216
- throw new RangeError(`${name} must be at least ${minimum}.`);
69217
- }
69218
- if (value > 2147483647) {
69219
- throw new RangeError(`${name} exceeds the supported integer range.`);
69220
- }
69221
- return value === 0 ? 0 : value;
69222
- }
69223
- function vector(value, name) {
69224
- if (!isVector2IntValue(value)) {
69225
- throw new TypeError(`${name} must be a Vector2Int.`);
69226
- }
69227
- return { x: integer2(value.x, `${name}.x`), y: integer2(value.y, `${name}.y`) };
69228
- }
69229
- function exclusion(value) {
69230
- if (!Array.isArray(value) || value.length !== 1) {
69231
- throw new TypeError(
69232
- "excluding must select one NeoCellPatternExcluding option."
69233
- );
69234
- }
69235
- if (value[0] === NEO_CELL_PATTERN_EXCLUDING_OPTION_IDS.None) return "none";
69236
- if (value[0] === NEO_CELL_PATTERN_EXCLUDING_OPTION_IDS.Center)
69237
- return "center";
69238
- throw new RangeError("excluding is not a NeoCellPatternExcluding option.");
69239
- }
69240
- function reserve(ctx, count) {
69241
- if (!Number.isSafeInteger(count) || count < 0) {
69242
- throw new RangeError("Cell pattern contains too many offsets.");
69243
- }
69244
- ctx.reserveEntries(count);
69245
- }
69246
- function appendShell(result, radius, minX, maxX, minY, maxY) {
69247
- if (radius === 0) {
69248
- if (minX <= 0 && maxX >= 0 && minY <= 0 && maxY >= 0)
69249
- result.push({ x: 0, y: 0 });
69250
- return;
69251
- }
69252
- const firstY = Math.max(minY, -radius) || 0;
69253
- const lastY = Math.min(maxY, radius);
69254
- if (firstY > lastY) return;
69255
- if (-radius >= minX && -radius <= maxX) {
69256
- for (let y = firstY; y <= lastY; y++) result.push({ x: -radius, y });
69257
- }
69258
- const bottom = -radius >= minY && -radius <= maxY;
69259
- const top = radius !== 0 && radius >= minY && radius <= maxY;
69260
- if (bottom || top) {
69261
- const firstX = Math.max(minX, -radius + 1) || 0;
69262
- const lastX = Math.min(maxX, radius - 1);
69263
- for (let x = firstX; x <= lastX; x++) {
69264
- if (bottom) result.push({ x, y: -radius });
69265
- if (top) result.push({ x, y: radius });
69266
- }
69267
- }
69268
- if (radius !== 0 && radius >= minX && radius <= maxX) {
69269
- for (let y = firstY; y <= lastY; y++) result.push({ x: radius, y });
69270
- }
69271
- }
69272
- function rectangle(ctx, minX, maxX, minY, maxY, excluding) {
69273
- const count = (maxX - minX + 1) * (maxY - minY + 1);
69274
- reserve(ctx, count - (excluding === "center" ? 1 : 0));
69275
- const offsets = [];
69276
- const radius = Math.max(-minX, maxX, -minY, maxY);
69277
- for (let shell = excluding === "center" ? 1 : 0; shell <= radius; shell++) {
69278
- appendShell(offsets, shell, minX, maxX, minY, maxY);
69279
- }
69280
- return offsets;
69281
- }
69282
- function translated(offsets, origin, ctx) {
69283
- reserve(ctx, offsets.length);
69284
- return offsets.map((offset) => ({
69285
- x: integer2(offset.x + origin.x, "Translated cell.x"),
69286
- y: integer2(offset.y + origin.y, "Translated cell.y")
69287
- }));
69288
- }
69289
- function isCenter(offset) {
69290
- return offset.x === 0 && offset.y === 0;
69291
- }
69292
- function evaluateCellPatternNative(memberId, receiver, args, ctx) {
69293
- if (!NEO_CELL_PATTERN_PURE_NATIVE_MEMBER_IDS.has(memberId)) {
69294
- return { handled: false };
69295
- }
69296
- const pattern = (offsets2) => ({
69297
- handled: true,
69298
- value: ctx.constructPattern(offsets2)
69299
- });
69300
- switch (memberId) {
69301
- case NEO_CELL_PATTERN_MEMBER_IDS.Box: {
69302
- const x = integer2(args[0], "Box radiusX", 0);
69303
- const y = args[1] === null ? x : integer2(args[1], "Box radiusY", 0);
69304
- return pattern(rectangle(ctx, -x, x, -y, y, exclusion(args[2])));
69305
- }
69306
- case NEO_CELL_PATTERN_MEMBER_IDS.Cross: {
69307
- const x = integer2(args[0], "Cross radiusX", 0);
69308
- const y = args[1] === null ? x : integer2(args[1], "Cross radiusY", 0);
69309
- const excluding = exclusion(args[2]);
69310
- reserve(ctx, 2 * (x + y) + (excluding === "none" ? 1 : 0));
69311
- const offsets2 = excluding === "none" ? [{ x: 0, y: 0 }] : [];
69312
- for (let distance = 1; distance <= Math.max(x, y); distance++) {
69313
- if (distance <= x)
69314
- offsets2.push({ x: -distance, y: 0 }, { x: distance, y: 0 });
69315
- if (distance <= y)
69316
- offsets2.push({ x: 0, y: -distance }, { x: 0, y: distance });
69317
- }
69318
- return pattern(offsets2);
69319
- }
69320
- case NEO_CELL_PATTERN_MEMBER_IDS.Ring: {
69321
- const radius = integer2(args[0], "Ring radius", 0);
69322
- reserve(ctx, radius === 0 ? 1 : 8 * radius);
69323
- const offsets2 = [];
69324
- appendShell(offsets2, radius, -radius, radius, -radius, radius);
69325
- return pattern(offsets2);
69326
- }
69327
- case NEO_CELL_PATTERN_MEMBER_IDS.Rect: {
69328
- const size = vector(args[0], "Rect size");
69329
- integer2(size.x, "Rect size.x", 1);
69330
- integer2(size.y, "Rect size.y", 1);
69331
- return pattern(rectangle(ctx, 0, size.x - 1, 0, size.y - 1, "none"));
69332
- }
69333
- case NEO_CELL_PATTERN_MEMBER_IDS.Line: {
69334
- const direction = vector(args[0], "Line direction");
69335
- if (isCenter(direction))
69336
- throw new RangeError("Line direction must be non-zero.");
69337
- const length = integer2(args[1], "Line length", 0);
69338
- const excluding = exclusion(args[2]);
69339
- reserve(ctx, length + (excluding === "none" ? 1 : 0));
69340
- integer2(direction.x * length, "Line endpoint.x");
69341
- integer2(direction.y * length, "Line endpoint.y");
69342
- const offsets2 = excluding === "none" ? [{ x: 0, y: 0 }] : [];
69343
- for (let step = 1; step <= length; step++) {
69344
- offsets2.push({ x: direction.x * step, y: direction.y * step });
69345
- }
69346
- return pattern(offsets2);
69347
- }
69348
- }
69349
- const offsets = ctx.readPattern(receiver);
69350
- ctx.visitEntries(offsets.length);
69351
- switch (memberId) {
69352
- case NEO_CELL_PATTERN_MEMBER_IDS.Contains: {
69353
- const offset = vector(args[0], "Contains offset");
69354
- return {
69355
- handled: true,
69356
- value: offsets.some(
69357
- (cell) => cell.x === offset.x && cell.y === offset.y
69358
- )
69359
- };
69360
- }
69361
- case NEO_CELL_PATTERN_MEMBER_IDS.Cells:
69362
- return {
69363
- handled: true,
69364
- value: translated(offsets, vector(args[0], "Cells origin"), ctx)
69365
- };
69366
- case NEO_CELL_PATTERN_MEMBER_IDS.WithCenter:
69367
- if (offsets.some(isCenter)) return { handled: true, value: receiver };
69368
- reserve(ctx, offsets.length + 1);
69369
- return pattern([{ x: 0, y: 0 }, ...offsets]);
69370
- case NEO_CELL_PATTERN_MEMBER_IDS.WithoutCenter: {
69371
- let count = 0;
69372
- for (const offset of offsets) if (!isCenter(offset)) count++;
69373
- if (count === offsets.length) return { handled: true, value: receiver };
69374
- reserve(ctx, count);
69375
- return pattern(offsets.filter((offset) => !isCenter(offset)));
69376
- }
69377
- case NEO_CELL_PATTERN_MEMBER_IDS.Translate: {
69378
- const offset = vector(args[0], "Translate offset");
69379
- if (isCenter(offset)) return { handled: true, value: receiver };
69380
- return pattern(translated(offsets, offset, ctx));
69381
- }
69382
- case NEO_CELL_PATTERN_MEMBER_IDS.Union: {
69383
- const other = ctx.readPattern(args[0]);
69384
- ctx.visitEntries(other.length);
69385
- const seen = /* @__PURE__ */ new Set();
69386
- const result = [];
69387
- for (const source of [offsets, other]) {
69388
- for (const offset of source) {
69389
- const key = `${offset.x},${offset.y}`;
69390
- if (seen.has(key)) continue;
69391
- reserve(ctx, 1);
69392
- seen.add(key);
69393
- result.push(offset);
69394
- }
69395
- }
69396
- return pattern(result);
69397
- }
69398
- default:
69399
- throw new Error(
69400
- `Cell pattern native member '${memberId}' has no implementation.`
69401
- );
69402
- }
69403
- }
69404
- var init_cell_pattern2 = __esm({
69405
- "../src/runtime/neoscript/cell-pattern.ts"() {
69406
- "use strict";
69407
- init_src();
69408
- init_member_kinds();
69409
- }
69410
- });
69411
-
69412
69101
  // ../src/models/classes/world-layer-link-target.ts
69413
69102
  function validateWorldLayerLinkClassTargets(args) {
69414
69103
  const relationResolver = createEffectiveClassRelationResolver(args);
@@ -69600,6 +69289,7 @@ var init_initializer_context = __esm({
69600
69289
  "../src/runtime/neoscript/initializer-context.ts"() {
69601
69290
  "use strict";
69602
69291
  init_collections();
69292
+ init_unattributable_reads();
69603
69293
  init_world_grid_query_reads();
69604
69294
  InitializerReadSet = class {
69605
69295
  valueIds = /* @__PURE__ */ new Set();
@@ -69610,9 +69300,28 @@ var init_initializer_context = __esm({
69610
69300
  worldQueries = new WorldGridQueryReadSet();
69611
69301
  hasValuePlacementRead = false;
69612
69302
  hasUnattributableValueRead = false;
69613
- recordUnattributableValueRead = (_reason) => {
69614
- void _reason;
69303
+ /**
69304
+ * The unattributable reads by scope, for a fork of the same document to
69305
+ * re-attribute; see {@link classifyUnattributableRead}. Ownership-chain
69306
+ * reads collapse to one flag: their inputs are already in `valueIds`.
69307
+ */
69308
+ hasOwnershipChainRead = false;
69309
+ containerEntryReadIds = /* @__PURE__ */ new Set();
69310
+ corpusReadReasons = /* @__PURE__ */ new Set();
69311
+ recordUnattributableValueRead = (reason) => {
69615
69312
  this.hasUnattributableValueRead = true;
69313
+ const read = classifyUnattributableRead(reason);
69314
+ switch (read.scope) {
69315
+ case "ownership-chain" /* OwnershipChain */:
69316
+ this.hasOwnershipChainRead = true;
69317
+ return;
69318
+ case "container" /* Container */:
69319
+ this.containerEntryReadIds.add(read.containerId);
69320
+ return;
69321
+ case "corpus" /* Corpus */:
69322
+ this.corpusReadReasons.add(reason);
69323
+ return;
69324
+ }
69616
69325
  };
69617
69326
  recordValuePlacementRead = () => {
69618
69327
  this.hasValuePlacementRead = true;
@@ -70528,10 +70237,10 @@ function evaluatorOwnershipCachesForBase(base) {
70528
70237
  evaluatorOwnershipCachesByBase.set(base, created);
70529
70238
  return created;
70530
70239
  }
70531
- function createEvaluatorBaseIndexBuild(members, values, valueById) {
70532
- const indexes2 = {
70240
+ function blankEvaluatorIndexes(memberByValueId) {
70241
+ return {
70533
70242
  rowByValueReference: /* @__PURE__ */ new WeakMap(),
70534
- memberByValueId: /* @__PURE__ */ new Map(),
70243
+ memberByValueId,
70535
70244
  parentLinksByChildId: /* @__PURE__ */ new Map(),
70536
70245
  indexedRowIds: /* @__PURE__ */ new Set(),
70537
70246
  indexedOverlayValues: /* @__PURE__ */ new Map(),
@@ -70548,6 +70257,9 @@ function createEvaluatorBaseIndexBuild(members, values, valueById) {
70548
70257
  constructorOwnershipDirtyValueIds: /* @__PURE__ */ new Set(),
70549
70258
  memberByRowId: /* @__PURE__ */ new Map()
70550
70259
  };
70260
+ }
70261
+ function createEvaluatorBaseIndexBuild(members, values, valueById) {
70262
+ const indexes2 = blankEvaluatorIndexes(/* @__PURE__ */ new Map());
70551
70263
  const membersByValueId = /* @__PURE__ */ new Map();
70552
70264
  for (const member of members) {
70553
70265
  if (typeof member.valueId === "string") {
@@ -70640,6 +70352,114 @@ function createEvaluatorLookupsBuild(members, storedValues, options = {}) {
70640
70352
  }
70641
70353
  };
70642
70354
  }
70355
+ function layerEvaluatorLookups(base, overlay) {
70356
+ const baseIndexes = base.evaluatorIndexes;
70357
+ if (baseIndexes === void 0) {
70358
+ throw new Error(
70359
+ "Layered evaluator lookups require a base with value graph indexes."
70360
+ );
70361
+ }
70362
+ const baseConstructorIndexes = base.constructorInitializerIndexes;
70363
+ if (baseConstructorIndexes === void 0) {
70364
+ throw new Error(
70365
+ "Layered evaluator lookups require a base with constructor initializer indexes."
70366
+ );
70367
+ }
70368
+ const masked = (id2) => overlay.rows.has(id2) || overlay.hiddenIds.has(id2);
70369
+ const local = blankEvaluatorIndexes(baseIndexes.memberByValueId);
70370
+ const localUnorderedMembership = /* @__PURE__ */ new Map();
70371
+ for (const row of overlay.rows.values()) {
70372
+ indexEvaluatorRow(local, row);
70373
+ if (typeof row.containerId !== "string") continue;
70374
+ const bucket = localUnorderedMembership.get(row.containerId) ?? [];
70375
+ bucket.push(row.id);
70376
+ localUnorderedMembership.set(row.containerId, bucket);
70377
+ }
70378
+ const parentLinks = /* @__PURE__ */ new Map();
70379
+ const parentLinksFor = (childId) => {
70380
+ const cached = parentLinks.get(childId);
70381
+ if (cached !== void 0) return cached;
70382
+ const inherited = (baseIndexes.parentLinksByChildId.get(childId) ?? []).filter((link) => !masked(link.parentId));
70383
+ const own = local.parentLinksByChildId.get(childId) ?? [];
70384
+ const merged = inherited.length === 0 ? own : [...inherited, ...own];
70385
+ parentLinks.set(childId, merged);
70386
+ return merged.length === 0 ? void 0 : merged;
70387
+ };
70388
+ const unorderedMembership = /* @__PURE__ */ new Map();
70389
+ const unorderedListEntryIds2 = (containerId) => {
70390
+ const cached = unorderedMembership.get(containerId);
70391
+ if (cached !== void 0) return cached;
70392
+ const own = localUnorderedMembership.get(containerId) ?? [];
70393
+ const inherited = overlay.rows.has(containerId) ? [] : (base.unorderedListEntryIds?.(containerId) ?? []).filter(
70394
+ (id2) => !masked(id2)
70395
+ );
70396
+ const merged = [...inherited, ...own].sort();
70397
+ unorderedMembership.set(containerId, merged);
70398
+ return merged;
70399
+ };
70400
+ const evaluatorIndexes2 = {
70401
+ rows: overlay.values,
70402
+ valueById: overlay.valuesById,
70403
+ rowByValueReference: {
70404
+ get: (value) => {
70405
+ const own = local.rowByValueReference.get(value);
70406
+ if (own !== void 0) return own;
70407
+ const inherited = baseIndexes.rowByValueReference.get(value);
70408
+ return inherited === void 0 || masked(inherited.id) ? void 0 : inherited;
70409
+ }
70410
+ },
70411
+ memberByValueId: baseIndexes.memberByValueId,
70412
+ membersByValueId: baseIndexes.membersByValueId,
70413
+ parentLinksByChildId: { get: parentLinksFor },
70414
+ indexedRowIds: {
70415
+ has: (id2) => local.indexedRowIds.has(id2) || !masked(id2) && baseIndexes.indexedRowIds.has(id2)
70416
+ },
70417
+ rowsBySourceValueId: {
70418
+ get: (sourceValueId) => {
70419
+ const inherited = (baseIndexes.rowsBySourceValueId.get(sourceValueId) ?? []).filter((row) => !masked(row.id));
70420
+ const own = local.rowsBySourceValueId.get(sourceValueId) ?? [];
70421
+ if (inherited.length === 0 && own.length === 0) return void 0;
70422
+ return inherited.length === 0 ? own : [...inherited, ...own];
70423
+ }
70424
+ }
70425
+ };
70426
+ const scopeByValueId = /* @__PURE__ */ new Map();
70427
+ const scopeFor = (row) => {
70428
+ const shadowed = baseConstructorIndexes.initializerScopeMemberIdsByValueId.get(row.id);
70429
+ if (shadowed !== void 0) return shadowed;
70430
+ const visited = /* @__PURE__ */ new Set();
70431
+ let currentId = row.id;
70432
+ while (!visited.has(currentId)) {
70433
+ visited.add(currentId);
70434
+ const link = parentLinksFor(currentId)?.[0];
70435
+ if (link === void 0) break;
70436
+ currentId = link.parentId;
70437
+ }
70438
+ return baseIndexes.memberByValueId.get(currentId)?.id;
70439
+ };
70440
+ for (const row of overlay.rows.values()) {
70441
+ if (!isInitValueContent(row)) continue;
70442
+ const scope = scopeFor(row);
70443
+ if (scope !== void 0) scopeByValueId.set(row.id, scope);
70444
+ }
70445
+ const constructorInitializerIndexes2 = {
70446
+ initializerScopeMemberIds: baseConstructorIndexes.initializerScopeMemberIds,
70447
+ initializerScopeMemberIdsByValueId: {
70448
+ get: (id2) => overlay.rows.has(id2) ? scopeByValueId.get(id2) : overlay.hiddenIds.has(id2) ? void 0 : baseConstructorIndexes.initializerScopeMemberIdsByValueId.get(id2)
70449
+ },
70450
+ schemaIndex: baseConstructorIndexes.schemaIndex
70451
+ };
70452
+ return {
70453
+ memberById: (id2) => base.memberById(id2),
70454
+ valueById: (id2) => overlay.rows.get(id2) ?? (overlay.hiddenIds.has(id2) ? null : base.valueById(id2)),
70455
+ hasStoredValueId: (id2) => overlay.rows.has(id2) || !overlay.hiddenIds.has(id2) && (base.hasStoredValueId?.(id2) ?? false),
70456
+ unorderedListEntryIds: unorderedListEntryIds2,
70457
+ virtualInstanceRowsForValue: () => [],
70458
+ rowForValueReference: (value) => evaluatorIndexes2.rowByValueReference.get(value) ?? null,
70459
+ evaluatorIndexes: evaluatorIndexes2,
70460
+ constructorInitializerIndexes: constructorInitializerIndexes2
70461
+ };
70462
+ }
70643
70463
  function evaluatorIndexes(ctx) {
70644
70464
  const overlayRevision = ctx.__valueOverlay instanceof LazyValueOverlay ? ctx.__valueOverlay.revision : void 0;
70645
70465
  if (ctx.__indexes !== void 0 && ctx.__indexes.overlayRevision === overlayRevision) {
@@ -71612,6 +71432,7 @@ function ownedConstructorArgumentValues(row, ctx, readRow) {
71612
71432
  }
71613
71433
  const owned = [];
71614
71434
  const collect = (value, rawTypeInfo, parameterId) => {
71435
+ if (!genericParametersConcretelyBound(rawTypeInfo, genericEnv)) return;
71615
71436
  let typeInfo = rawTypeInfo;
71616
71437
  try {
71617
71438
  typeInfo = substituteRuntimeTypeInfo(
@@ -71770,9 +71591,7 @@ function finalizeConstructorAllocations(ctx, returnValue, ownsInvocationState, r
71770
71591
  }
71771
71592
  }
71772
71593
  }
71773
- ctx.onUnattributableValueRead?.(
71774
- `constructor-argument-list:${argumentId}`
71775
- );
71594
+ ctx.onUnattributableValueRead?.(containerEntriesRead(argumentId));
71776
71595
  for (const childId of containerEntryIds(argumentId)) {
71777
71596
  scanCreationDataRow({
71778
71597
  id: childId,
@@ -71835,7 +71654,7 @@ function finalizeConstructorAllocations(ctx, returnValue, ownsInvocationState, r
71835
71654
  if (member !== null && isMemberListBase(member)) {
71836
71655
  const entryMember = evalMemberById(ctx.vm, member.entryMemberId);
71837
71656
  if (listKindOf(member) === 1 /* Unordered */) {
71838
- ctx.onUnattributableValueRead?.(`constructed-unordered-list:${row.id}`);
71657
+ ctx.onUnattributableValueRead?.(containerEntriesRead(row.id));
71839
71658
  for (const childId of containerEntryIds(row.id)) {
71840
71659
  scanOwnedRow(childId, entryMember);
71841
71660
  }
@@ -74323,7 +74142,9 @@ function runtimeGenericEnvForValueRow(row, ctx, visited, readRow) {
74323
74142
  }
74324
74143
  function runtimeParentGenericEnv(row, ctx, visited, readRow) {
74325
74144
  const result = /* @__PURE__ */ new Map();
74326
- ctx.onUnattributableValueRead?.(`generic-parent-resolution:${row.id}`);
74145
+ ctx.onUnattributableValueRead?.(
74146
+ ownershipChainRead("generic-parent-resolution", row.id)
74147
+ );
74327
74148
  for (const link of evaluatorParentLinks(evaluatorIndexes(ctx), row.id)) {
74328
74149
  const parent = readRow === void 0 ? evalValueById(
74329
74150
  ctx,
@@ -74351,6 +74172,24 @@ function overlayConcreteGenericEntries(target, source) {
74351
74172
  }
74352
74173
  }
74353
74174
  }
74175
+ function genericParametersConcretelyBound(typeInfo, env) {
74176
+ if (typeInfo.type === 21 /* Generic */) {
74177
+ return env.get(typeInfo.genericParamId)?.kind === "member";
74178
+ }
74179
+ if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
74180
+ return genericParametersConcretelyBound(typeInfo.entryTypeInfo, env);
74181
+ }
74182
+ if (typeInfo.type === 25 /* NSDelegate */) {
74183
+ return genericParametersConcretelyBound(typeInfo.returnTypeInfo, env) && typeInfo.argumentTypes.every(
74184
+ (argument2) => genericParametersConcretelyBound(argument2, env)
74185
+ );
74186
+ }
74187
+ if (typeInfo.type !== 7 /* Class */) return true;
74188
+ for (const argument2 of Object.values(typeInfo.typeArguments ?? {})) {
74189
+ if (!genericParametersConcretelyBound(argument2, env)) return false;
74190
+ }
74191
+ return true;
74192
+ }
74354
74193
  function substituteRuntimeTypeInfo(typeInfo, env, ctx) {
74355
74194
  if (typeInfo.type === 21 /* Generic */) {
74356
74195
  const binding = env.get(typeInfo.genericParamId);
@@ -75308,7 +75147,9 @@ function resolveMemberForValueRow(row, ctx, visited) {
75308
75147
  if (syntheticMemberId !== null) {
75309
75148
  return evalMemberById(ctx.vm, syntheticMemberId);
75310
75149
  }
75311
- ctx.onUnattributableValueRead?.(`member-owner-resolution:${row.id}`);
75150
+ ctx.onUnattributableValueRead?.(
75151
+ ownershipChainRead("member-owner-resolution", row.id)
75152
+ );
75312
75153
  for (const link of evaluatorParentLinks(indexes2, row.id)) {
75313
75154
  const parent = evalValueById(
75314
75155
  ctx,
@@ -76721,7 +76562,8 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
76721
76562
  members: ctx.vm.members,
76722
76563
  constructors: ctx.vm.constructors ?? [],
76723
76564
  values: ctx.vm.values,
76724
- valueById: ctx.vm.databaseVM?.valueById
76565
+ valueById: ctx.vm.databaseVM?.valueById,
76566
+ memberById: evaluatorDefaultValueDocument(ctx).memberById
76725
76567
  };
76726
76568
  const classArguments2 = slotArguments ?? resolveConstructionTypeArguments(
76727
76569
  info.schemaClassInfo.typeArguments,
@@ -79310,7 +79152,9 @@ function currentOwnedValueAttachments(valueId, ctx) {
79310
79152
  });
79311
79153
  }
79312
79154
  }
79313
- ctx.onUnattributableValueRead?.(`owned-value-parents:${valueId}`);
79155
+ ctx.onUnattributableValueRead?.(
79156
+ ownershipChainRead("owned-value-parents", valueId)
79157
+ );
79314
79158
  const parentIds = new Set(
79315
79159
  evaluatorParentLinks(indexes2, valueId).map((link) => link.parentId)
79316
79160
  );
@@ -79592,9 +79436,7 @@ function cloneConstructorArgumentGraph(args) {
79592
79436
  if (listKindOf(member) === 1 /* Unordered */) {
79593
79437
  clone.value = [];
79594
79438
  const entryEnv2 = envFromStamp(clone.genericBindings);
79595
- args.ctx.onUnattributableValueRead?.(
79596
- `constructor-import-list:${source.id}`
79597
- );
79439
+ args.ctx.onUnattributableValueRead?.(containerEntriesRead(source.id));
79598
79440
  const entries = evaluatorValues(args.ctx).filter((row) => row.containerId === source.id).sort((left, right) => left.id.localeCompare(right.id));
79599
79441
  for (const entry of entries) {
79600
79442
  cloneRow2(entry, entryMember, entryEnv2, clone.id);
@@ -79731,7 +79573,7 @@ function materializeConstructorArgumentValue(args) {
79731
79573
  let sourceEntries = args.value;
79732
79574
  if (listKindOf(args.member) === 1 /* Unordered */ && trackedValueId !== null) {
79733
79575
  args.ctx.onUnattributableValueRead?.(
79734
- `constructor-argument-list:${trackedValueId}`
79576
+ containerEntriesRead(trackedValueId)
79735
79577
  );
79736
79578
  const rows = [];
79737
79579
  for (const entry of evaluatorValues(args.ctx)) {
@@ -80126,9 +79968,7 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
80126
79968
  entryTypeInfo
80127
79969
  ).id;
80128
79970
  });
80129
- ctx.onUnattributableValueRead?.(
80130
- `class-clone-unordered-list:${sourceRow.id}`
80131
- );
79971
+ ctx.onUnattributableValueRead?.(containerEntriesRead(sourceRow.id));
80132
79972
  for (const child of evaluatorValues(ctx)) {
80133
79973
  if (child.containerId !== sourceRow.id) continue;
80134
79974
  cloneRow2(child, entryMember, id2, entryTypeInfo);
@@ -80377,6 +80217,7 @@ var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, NonCatchableNSGetterRuntimeErr
80377
80217
  var init_evaluateNSGetter = __esm({
80378
80218
  "../src/runtime/neoscript/evaluateNSGetter.ts"() {
80379
80219
  "use strict";
80220
+ init_unattributable_reads();
80380
80221
  init_value_row_owner_members();
80381
80222
  init_src();
80382
80223
  init_cell_pattern2();
@@ -80690,7 +80531,7 @@ function materializeMemberDefaultValue(args) {
80690
80531
  const createdValues = [];
80691
80532
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
80692
80533
  args.readTracking?.recordUnattributableValueRead(
80693
- `declaration-owner-resolution:${args.envelope.id}`
80534
+ ownershipChainRead("declaration-owner-resolution", args.envelope.id)
80694
80535
  );
80695
80536
  const declarationArguments = (member, init, sourceValueId) => {
80696
80537
  const { valuesById, rootOwners } = declarationInitializerContext(
@@ -80772,6 +80613,7 @@ var declarationInitializerContextByDocument;
80772
80613
  var init_initializer_materialization = __esm({
80773
80614
  "../src/runtime/initializer-materialization.ts"() {
80774
80615
  "use strict";
80616
+ init_unattributable_reads();
80775
80617
  init_deep_clone_plain_data();
80776
80618
  init_members();
80777
80619
  init_inheritance();
@@ -80784,6 +80626,386 @@ var init_initializer_materialization = __esm({
80784
80626
  }
80785
80627
  });
80786
80628
 
80629
+ // ../src/models/members/stored-value-placement-index.ts
80630
+ function buildStoredValuePlacementIndex(args) {
80631
+ return createStoredValuePlacementTraversal(args)();
80632
+ }
80633
+ function createStoredValuePlacementTraversal(args, trackReferences = false) {
80634
+ const membersById = /* @__PURE__ */ new Map();
80635
+ for (const member of args.members) membersById.set(member.id, member);
80636
+ const valuesById = args.indexedRows?.valuesById ?? new Map(args.values.map((row) => [row.id, row]));
80637
+ const unorderedEntriesByContainerId = /* @__PURE__ */ new Map();
80638
+ for (const value of args.indexedRows === void 0 ? args.values : []) {
80639
+ if (typeof value.containerId !== "string") continue;
80640
+ const entries = unorderedEntriesByContainerId.get(value.containerId);
80641
+ if (entries === void 0) {
80642
+ unorderedEntriesByContainerId.set(value.containerId, [value]);
80643
+ } else {
80644
+ entries.push(value);
80645
+ }
80646
+ }
80647
+ for (const entries of unorderedEntriesByContainerId.values()) {
80648
+ entries.sort((left, right) => left.id.localeCompare(right.id));
80649
+ }
80650
+ const constructorsById = new Map(
80651
+ args.constructors.map((constructor2) => [constructor2.id, constructor2])
80652
+ );
80653
+ const resolveConstructorSettlement = createConstructorSettlementResolver({
80654
+ classes: args.classes,
80655
+ constructors: args.constructors,
80656
+ members: args.members
80657
+ });
80658
+ const resolvedMemberById = /* @__PURE__ */ new Map();
80659
+ const resolvedMember = (member) => {
80660
+ const cached = resolvedMemberById.get(member.id);
80661
+ if (cached !== void 0) return cached;
80662
+ const resolved = resolveMember2(member, args.members);
80663
+ resolvedMemberById.set(member.id, resolved);
80664
+ return resolved;
80665
+ };
80666
+ const storedSchemaByClassId = /* @__PURE__ */ new Map();
80667
+ const storedSchema = (classId) => {
80668
+ const cached = storedSchemaByClassId.get(classId);
80669
+ if (cached !== void 0) return cached;
80670
+ const schema = mergeStoredInstanceSchema(
80671
+ classId,
80672
+ args.classes,
80673
+ args.members
80674
+ );
80675
+ storedSchemaByClassId.set(classId, schema);
80676
+ return schema;
80677
+ };
80678
+ return (roots) => {
80679
+ const queue = [...roots ?? []];
80680
+ if (roots === void 0) {
80681
+ for (const root of projectRootMembersInDisplayOrder(args.project)) {
80682
+ const member = membersById.get(root.memberId);
80683
+ if (member === void 0 || typeof member.valueId !== "string")
80684
+ continue;
80685
+ queue.push({
80686
+ memberId: member.id,
80687
+ parentValueId: null,
80688
+ source: {
80689
+ kind: "root",
80690
+ label: root.root.label,
80691
+ sourcePath: `root.${root.root.key}`
80692
+ },
80693
+ valueId: member.valueId
80694
+ });
80695
+ }
80696
+ for (const member of args.members) {
80697
+ if (!isStaticMember(member) || memberAccessOf(member) !== 0 /* Public */)
80698
+ continue;
80699
+ const valueId = args.resolveStaticValueId(member.id);
80700
+ if (valueId === null) continue;
80701
+ const placement = findSchemaPlacement(member.id, args.classes);
80702
+ if (placement === null) continue;
80703
+ queue.push({
80704
+ memberId: member.id,
80705
+ parentValueId: null,
80706
+ source: {
80707
+ kind: "static",
80708
+ label: placement.schemaKey,
80709
+ ownerClassName: placement.ownerClass.name,
80710
+ sourcePath: `static:${member.id}`
80711
+ },
80712
+ valueId
80713
+ });
80714
+ }
80715
+ }
80716
+ const placementByValueId = /* @__PURE__ */ new Map();
80717
+ const mutablePlacementsByClassId = /* @__PURE__ */ new Map();
80718
+ const mutablePlacementsByMemberId = /* @__PURE__ */ new Map();
80719
+ const mutablePlacementsByKind = /* @__PURE__ */ new Map();
80720
+ for (let cursor = 0; cursor < queue.length; cursor += 1) {
80721
+ const item = queue[cursor];
80722
+ if (item === void 0 || placementByValueId.has(item.valueId)) continue;
80723
+ const authoredValue = valuesById.get(item.valueId);
80724
+ const storedMember = membersById.get(item.memberId);
80725
+ if (authoredValue === void 0 || storedMember === void 0) continue;
80726
+ const value = args.resolveValue === void 0 ? authoredValue : args.resolveValue(authoredValue);
80727
+ if (value === null) continue;
80728
+ const placement = item;
80729
+ placementByValueId.set(value.id, placement);
80730
+ appendPlacement(mutablePlacementsByMemberId, storedMember.id, placement);
80731
+ const member = resolvedMember(storedMember);
80732
+ appendPlacement(mutablePlacementsByKind, member.kind, placement);
80733
+ if (isMemberClassBase(member)) {
80734
+ const classId = value.classId ?? member.classId;
80735
+ appendPlacement(mutablePlacementsByClassId, classId, placement);
80736
+ if (!isLiteralValueContent(value) || !isStringRecord4(value.value)) {
80737
+ continue;
80738
+ }
80739
+ const settledChildrenBySchemaKey = /* @__PURE__ */ new Map();
80740
+ const constructor2 = typeof value.instanceConstructorId === "string" ? constructorsById.get(value.instanceConstructorId) : void 0;
80741
+ if (constructor2 !== void 0 && constructor2.classId === classId && value.constructorArgs != null) {
80742
+ for (const [
80743
+ index,
80744
+ parameter4
80745
+ ] of constructor2.argumentTypes.entries()) {
80746
+ const settled = resolveConstructorSettlement(
80747
+ classId,
80748
+ parameter4.name,
80749
+ constructor2.id
80750
+ );
80751
+ if (settled === null || Object.hasOwn(value.value, settled.schemaKey)) {
80752
+ continue;
80753
+ }
80754
+ const childValueId = value.constructorArgs[constructorActionParameterId(constructor2, index)];
80755
+ if (typeof childValueId === "string") {
80756
+ settledChildrenBySchemaKey.set(settled.schemaKey, childValueId);
80757
+ }
80758
+ }
80759
+ }
80760
+ for (const entry of storedSchema(classId)) {
80761
+ const childMember = membersById.get(entry.memberId);
80762
+ const childValueId = value.value[entry.schemaKey] ?? settledChildrenBySchemaKey.get(entry.schemaKey);
80763
+ if (childMember === void 0 || typeof childValueId !== "string") {
80764
+ continue;
80765
+ }
80766
+ if (memberAccessOf(childMember) !== 0 /* Public */) continue;
80767
+ queue.push({
80768
+ memberId: childMember.id,
80769
+ parentValueId: value.id,
80770
+ source: { kind: "classField", schemaKey: entry.schemaKey },
80771
+ valueId: childValueId
80772
+ });
80773
+ }
80774
+ continue;
80775
+ }
80776
+ if (!isMemberListBase(member) && !isMemberDictionaryBase(member)) {
80777
+ continue;
80778
+ }
80779
+ const entryMember = membersById.get(member.entryMemberId);
80780
+ if (entryMember === void 0) continue;
80781
+ if (isMemberDictionaryBase(member)) {
80782
+ if (!isStringRecord4(value.value)) continue;
80783
+ for (const [key, childValueId] of Object.entries(value.value)) {
80784
+ queue.push({
80785
+ memberId: entryMember.id,
80786
+ parentValueId: value.id,
80787
+ source: {
80788
+ kind: "collectionEntry",
80789
+ containerMemberId: storedMember.id,
80790
+ entry: { kind: "dict", key, valueId: childValueId }
80791
+ },
80792
+ valueId: childValueId
80793
+ });
80794
+ }
80795
+ continue;
80796
+ }
80797
+ const entries = listKindOf(member) === 1 /* Unordered */ ? args.indexedRows === void 0 ? unorderedEntriesByContainerId.get(value.id) ?? [] : args.indexedRows.unorderedListEntryIds(value.id).flatMap((id2) => {
80798
+ const row = valuesById.get(id2);
80799
+ return row === void 0 ? [] : [row];
80800
+ }) : Array.isArray(value.value) ? value.value.flatMap((childValueId) => {
80801
+ if (typeof childValueId !== "string") return [];
80802
+ const childValue = valuesById.get(childValueId);
80803
+ return childValue === void 0 ? [] : [childValue];
80804
+ }) : [];
80805
+ for (const [index, childValue] of entries.entries()) {
80806
+ queue.push({
80807
+ memberId: entryMember.id,
80808
+ parentValueId: value.id,
80809
+ source: {
80810
+ kind: "collectionEntry",
80811
+ containerMemberId: storedMember.id,
80812
+ entry: { kind: "list", index, valueId: childValue.id }
80813
+ },
80814
+ valueId: childValue.id
80815
+ });
80816
+ }
80817
+ }
80818
+ const referencesByParentId = /* @__PURE__ */ new Map();
80819
+ if (trackReferences) {
80820
+ for (const id2 of placementByValueId.keys())
80821
+ referencesByParentId.set(id2, /* @__PURE__ */ new Set());
80822
+ for (const item of queue) {
80823
+ if (item.parentValueId !== null)
80824
+ referencesByParentId.get(item.parentValueId)?.add(item.valueId);
80825
+ }
80826
+ }
80827
+ return {
80828
+ referencesByParentId,
80829
+ placementByValueId,
80830
+ placementsByClassId: mutablePlacementsByClassId,
80831
+ placementsByKind: mutablePlacementsByKind,
80832
+ placementsByMemberId: mutablePlacementsByMemberId
80833
+ };
80834
+ };
80835
+ }
80836
+ function createStoredValuePlacementBatch(args) {
80837
+ const traverse = createStoredValuePlacementTraversal(args, true);
80838
+ const initial = traverse();
80839
+ const placementByValueId = new Map(initial.placementByValueId);
80840
+ const childrenByParentId = /* @__PURE__ */ new Map();
80841
+ const referencingParentsById = /* @__PURE__ */ new Map();
80842
+ const referencesByParentId = /* @__PURE__ */ new Map();
80843
+ const declaredRootIds = new Set(
80844
+ args.members.flatMap(
80845
+ (member) => typeof member.valueId === "string" ? [member.valueId] : []
80846
+ )
80847
+ );
80848
+ const indexPlacement = (placement) => {
80849
+ if (placement.parentValueId === null) return;
80850
+ const children = childrenByParentId.get(placement.parentValueId) ?? /* @__PURE__ */ new Set();
80851
+ children.add(placement.valueId);
80852
+ childrenByParentId.set(placement.parentValueId, children);
80853
+ };
80854
+ for (const placement of placementByValueId.values())
80855
+ indexPlacement(placement);
80856
+ const indexReferences2 = (parentId, references) => {
80857
+ for (const id2 of referencesByParentId.get(parentId) ?? []) {
80858
+ const parents = referencingParentsById.get(id2);
80859
+ parents?.delete(parentId);
80860
+ if (parents?.size === 0) referencingParentsById.delete(id2);
80861
+ }
80862
+ referencesByParentId.set(parentId, new Set(references));
80863
+ for (const id2 of references) {
80864
+ const parents = referencingParentsById.get(id2) ?? /* @__PURE__ */ new Set();
80865
+ parents.add(parentId);
80866
+ referencingParentsById.set(id2, parents);
80867
+ }
80868
+ };
80869
+ for (const [parentId, references] of initial.referencesByParentId)
80870
+ indexReferences2(parentId, references);
80871
+ const rebuild = () => {
80872
+ const rebuilt = traverse();
80873
+ placementByValueId.clear();
80874
+ childrenByParentId.clear();
80875
+ referencesByParentId.clear();
80876
+ referencingParentsById.clear();
80877
+ for (const placement of rebuilt.placementByValueId.values()) {
80878
+ placementByValueId.set(placement.valueId, placement);
80879
+ indexPlacement(placement);
80880
+ }
80881
+ for (const [parentId, references] of rebuilt.referencesByParentId)
80882
+ indexReferences2(parentId, references);
80883
+ };
80884
+ return {
80885
+ placementByValueId,
80886
+ /** Call after the external row/membership indexes have received these replacements. */
80887
+ refresh(rows, previousRows) {
80888
+ const affected = /* @__PURE__ */ new Set();
80889
+ const consider = (id2) => {
80890
+ if (typeof id2 === "string" && placementByValueId.has(id2))
80891
+ affected.add(id2);
80892
+ };
80893
+ let needsRootRebuild = false;
80894
+ for (const row of rows) {
80895
+ consider(row.id);
80896
+ if (!placementByValueId.has(row.id)) {
80897
+ for (const parentId of referencingParentsById.get(row.id) ?? [])
80898
+ consider(parentId);
80899
+ }
80900
+ if (!placementByValueId.has(row.id) && declaredRootIds.has(row.id))
80901
+ needsRootRebuild = true;
80902
+ }
80903
+ const previousById = new Map(
80904
+ previousRows.flatMap(
80905
+ (row) => row === void 0 ? [] : [[row.id, row]]
80906
+ )
80907
+ );
80908
+ for (const row of rows) {
80909
+ const previous = previousById.get(row.id);
80910
+ if (previous?.containerId === row.containerId) continue;
80911
+ consider(previous?.containerId);
80912
+ consider(row.containerId);
80913
+ }
80914
+ if (needsRootRebuild) {
80915
+ rebuild();
80916
+ return;
80917
+ }
80918
+ const hasAffectedAncestor = /* @__PURE__ */ new Map();
80919
+ const rootSeeds = [];
80920
+ for (const id2 of affected) {
80921
+ const placement = placementByValueId.get(id2);
80922
+ let parent = placement.parentValueId;
80923
+ const path = [];
80924
+ let found = false;
80925
+ while (parent !== null) {
80926
+ if (affected.has(parent)) {
80927
+ found = true;
80928
+ break;
80929
+ }
80930
+ const cached = hasAffectedAncestor.get(parent);
80931
+ if (cached !== void 0) {
80932
+ found = cached;
80933
+ break;
80934
+ }
80935
+ path.push(parent);
80936
+ parent = placementByValueId.get(parent)?.parentValueId ?? null;
80937
+ }
80938
+ for (const ancestor of path) hasAffectedAncestor.set(ancestor, found);
80939
+ if (!found) rootSeeds.push(placement);
80940
+ }
80941
+ const removed = /* @__PURE__ */ new Set();
80942
+ const queue = rootSeeds.map((root) => root.valueId);
80943
+ for (let index = 0; index < queue.length; index += 1) {
80944
+ const id2 = queue[index];
80945
+ if (removed.has(id2)) continue;
80946
+ removed.add(id2);
80947
+ for (const child of childrenByParentId.get(id2) ?? []) queue.push(child);
80948
+ }
80949
+ for (const id2 of removed) {
80950
+ const oldParent = placementByValueId.get(id2)?.parentValueId;
80951
+ for (const parentId of referencingParentsById.get(id2) ?? []) {
80952
+ if (!removed.has(parentId) && parentId !== oldParent && placementByValueId.has(parentId)) {
80953
+ rebuild();
80954
+ return;
80955
+ }
80956
+ }
80957
+ }
80958
+ for (const id2 of removed) {
80959
+ const parent = placementByValueId.get(id2)?.parentValueId;
80960
+ if (typeof parent === "string")
80961
+ childrenByParentId.get(parent)?.delete(id2);
80962
+ childrenByParentId.delete(id2);
80963
+ placementByValueId.delete(id2);
80964
+ }
80965
+ const next = traverse(rootSeeds);
80966
+ for (const [id2, placement] of next.placementByValueId) {
80967
+ const existing = placementByValueId.get(id2);
80968
+ if (existing !== void 0 && existing.parentValueId !== placement.parentValueId) {
80969
+ rebuild();
80970
+ return;
80971
+ }
80972
+ }
80973
+ for (const id2 of removed) indexReferences2(id2, /* @__PURE__ */ new Set());
80974
+ for (const [parentId, references] of next.referencesByParentId)
80975
+ indexReferences2(parentId, references);
80976
+ for (const placement of next.placementByValueId.values()) {
80977
+ placementByValueId.set(placement.valueId, placement);
80978
+ indexPlacement(placement);
80979
+ }
80980
+ }
80981
+ };
80982
+ }
80983
+ function appendPlacement(index, key, placement) {
80984
+ const placements = index.get(key);
80985
+ if (placements === void 0) {
80986
+ index.set(key, [placement]);
80987
+ } else {
80988
+ placements.push(placement);
80989
+ }
80990
+ }
80991
+ function isStringRecord4(value) {
80992
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
80993
+ return false;
80994
+ }
80995
+ return Object.values(value).every((item) => typeof item === "string");
80996
+ }
80997
+ var init_stored_value_placement_index = __esm({
80998
+ "../src/models/members/stored-value-placement-index.ts"() {
80999
+ "use strict";
81000
+ init_inheritance();
81001
+ init_constructor_parameter_settlement();
81002
+ init_constructors2();
81003
+ init_project2();
81004
+ init_member_kinds();
81005
+ init_members();
81006
+ }
81007
+ });
81008
+
80787
81009
  // ../src/runtime/virtual-instance-graph.ts
80788
81010
  function buildVirtualInstanceMaterializedIndex(args) {
80789
81011
  const rowsById = new Map(
@@ -80907,8 +81129,14 @@ function expandStoredInstance(args) {
80907
81129
  for (const read of readTracking.worldQueries) {
80908
81130
  recorder?.recordWorldQueryRead?.(read);
80909
81131
  }
80910
- if (readTracking.hasUnattributableValueRead) {
80911
- recorder?.recordGlobalRead("initializer-runtime");
81132
+ if (readTracking.hasOwnershipChainRead) {
81133
+ recorder?.recordGlobalRead(OWNERSHIP_CHAIN_READ);
81134
+ }
81135
+ for (const containerId of readTracking.containerEntryReadIds) {
81136
+ recorder?.recordGlobalRead(containerEntriesRead(containerId));
81137
+ }
81138
+ for (const reason of readTracking.corpusReadReasons) {
81139
+ recorder?.recordGlobalRead(reason);
80912
81140
  }
80913
81141
  }
80914
81142
  };
@@ -83211,9 +83439,66 @@ function createHeadlessVirtualInstanceResolver(args) {
83211
83439
  const failedRootIds = /* @__PURE__ */ new Set();
83212
83440
  const expandedRowById = /* @__PURE__ */ new Map();
83213
83441
  const expandedRowByRecord = /* @__PURE__ */ new WeakMap();
83442
+ const readsByRootId = /* @__PURE__ */ new Map();
83443
+ const activeReads = [];
83444
+ const sharedByReceiverId = /* @__PURE__ */ new Map();
83445
+ const mergeReads = (reads) => {
83446
+ for (const active of activeReads) {
83447
+ if (active === reads) continue;
83448
+ for (const id2 of reads.valueIds) active.valueIds.add(id2);
83449
+ for (const id2 of reads.containerIds) active.containerIds.add(id2);
83450
+ if (reads.global) active.global = true;
83451
+ }
83452
+ };
83453
+ const recorder = {
83454
+ recordValueRead: (id2) => {
83455
+ for (const active of activeReads) active.valueIds.add(id2);
83456
+ args.readRecorder?.recordValueRead(id2);
83457
+ },
83458
+ recordLocalizedTextRead: (id2) => args.readRecorder?.recordLocalizedTextRead(id2),
83459
+ recordVariantRead: (id2) => args.readRecorder?.recordVariantRead(id2),
83460
+ recordStaticMemberRead: (id2) => args.readRecorder?.recordStaticMemberRead(id2),
83461
+ recordContainerMembershipRead: (id2) => {
83462
+ for (const active of activeReads) active.containerIds.add(id2);
83463
+ args.readRecorder?.recordContainerMembershipRead(id2);
83464
+ },
83465
+ recordWorldQueryRead: (read) => {
83466
+ for (const active of activeReads) active.global = true;
83467
+ args.readRecorder?.recordWorldQueryRead?.(read);
83468
+ },
83469
+ recordValuePlacementRead: () => args.readRecorder?.recordValuePlacementRead(),
83470
+ recordGlobalRead: (reason) => {
83471
+ const read = classifyUnattributableRead(reason);
83472
+ if (read.scope === "container" /* Container */) {
83473
+ for (const active of activeReads)
83474
+ active.containerIds.add(read.containerId);
83475
+ } else if (read.scope === "corpus" /* Corpus */) {
83476
+ for (const active of activeReads) active.global = true;
83477
+ }
83478
+ args.readRecorder?.recordGlobalRead(reason);
83479
+ }
83480
+ };
83481
+ const remember = (graph, rows) => {
83482
+ graphRowsByRootId.set(graph.instanceRootId, rows);
83483
+ for (const [id2, row] of graph.rowsById) {
83484
+ expandedRowById.set(id2, row);
83485
+ graphByValueId.set(id2, graph);
83486
+ if (typeof row.value === "object" && row.value !== null) {
83487
+ expandedRowByRecord.set(row.value, row);
83488
+ }
83489
+ }
83490
+ for (const id2 of graph.locationsById.keys()) {
83491
+ graphByValueId.set(id2, graph);
83492
+ }
83493
+ graphByValueId.set(graph.instanceRootId, graph);
83494
+ };
83214
83495
  const expandRoot = (rootId, declaredMember) => {
83215
83496
  const cached = graphRowsByRootId.get(rootId);
83216
- if (cached !== void 0) return cached;
83497
+ if (cached !== void 0) {
83498
+ const reads2 = readsByRootId.get(rootId);
83499
+ if (reads2 !== void 0) mergeReads(reads2);
83500
+ return cached;
83501
+ }
83217
83502
  if (failedRootIds.has(rootId)) return emptyRows;
83218
83503
  const instanceRoot = rawById.get(rootId);
83219
83504
  if (instanceRoot === void 0 || declaredMember === void 0) {
@@ -83229,6 +83514,12 @@ function createHeadlessVirtualInstanceResolver(args) {
83229
83514
  failedRootIds.add(rootId);
83230
83515
  return emptyRows;
83231
83516
  }
83517
+ const reads = {
83518
+ valueIds: /* @__PURE__ */ new Set(),
83519
+ containerIds: /* @__PURE__ */ new Set(),
83520
+ global: false
83521
+ };
83522
+ activeReads.push(reads);
83232
83523
  try {
83233
83524
  const resolverDocument = resolverDocumentOnce();
83234
83525
  materializedIndex ??= buildVirtualInstanceMaterializedIndex({
@@ -83241,33 +83532,52 @@ function createHeadlessVirtualInstanceResolver(args) {
83241
83532
  instanceRoot,
83242
83533
  rootMember: member,
83243
83534
  materializedIndex,
83244
- readRecorder: args.readRecorder
83535
+ readRecorder: recorder
83245
83536
  });
83246
83537
  const rows = [...graph.rowsById.values()];
83247
- graphRowsByRootId.set(rootId, rows);
83248
- for (const [id2, row] of graph.rowsById) {
83249
- expandedRowById.set(id2, row);
83250
- graphByValueId.set(id2, graph);
83251
- if (typeof row.value === "object" && row.value !== null) {
83252
- expandedRowByRecord.set(row.value, row);
83253
- }
83254
- }
83255
- for (const id2 of graph.locationsById.keys()) {
83256
- graphByValueId.set(id2, graph);
83257
- }
83258
- graphByValueId.set(rootId, graph);
83538
+ readsByRootId.set(rootId, reads);
83539
+ remember(graph, rows);
83259
83540
  return rows;
83260
83541
  } catch {
83261
83542
  failedRootIds.add(rootId);
83262
83543
  return emptyRows;
83263
- }
83544
+ } finally {
83545
+ activeReads.pop();
83546
+ mergeReads(reads);
83547
+ }
83548
+ };
83549
+ const adoptSharedExpansion = (receiverValueId) => {
83550
+ const share = args.shareFrom;
83551
+ if (share === void 0 || share.masked(receiverValueId)) return null;
83552
+ const adopted = sharedByReceiverId.get(receiverValueId);
83553
+ if (adopted !== void 0) {
83554
+ mergeReads(adopted.reads);
83555
+ return adopted.rows;
83556
+ }
83557
+ const shared = share.resolver.shareExpansion(
83558
+ receiverValueId,
83559
+ share.masked,
83560
+ share.containerChanged
83561
+ );
83562
+ if (shared === null) return null;
83563
+ for (const id2 of shared.reads.valueIds) recorder.recordValueRead(id2);
83564
+ for (const id2 of shared.reads.containerIds)
83565
+ recorder.recordContainerMembershipRead(id2);
83566
+ if (graphRowsByRootId.get(shared.graph.instanceRootId) === void 0) {
83567
+ readsByRootId.set(shared.graph.instanceRootId, shared.reads);
83568
+ remember(shared.graph, shared.rows);
83569
+ }
83570
+ sharedByReceiverId.set(receiverValueId, shared);
83571
+ return shared.rows;
83264
83572
  };
83265
83573
  const virtualInstanceRowsForValue = (receiverValueId) => {
83266
- args.readRecorder?.recordValuePlacementRead();
83267
- args.readRecorder?.recordValueRead(receiverValueId);
83574
+ const adopted = adoptSharedExpansion(receiverValueId);
83575
+ if (adopted !== null) return adopted;
83576
+ recorder.recordValuePlacementRead();
83577
+ recorder.recordValueRead(receiverValueId);
83268
83578
  let placement = placements().get(receiverValueId) ?? null;
83269
83579
  while (placement !== null) {
83270
- args.readRecorder?.recordValueRead(placement.valueId);
83580
+ recorder.recordValueRead(placement.valueId);
83271
83581
  const raw = rawById.get(placement.valueId);
83272
83582
  if (raw !== void 0 && isLiteralValueContent(raw) && isStoredClassResolutionRoot(raw)) {
83273
83583
  return expandRoot(
@@ -83297,6 +83607,33 @@ function createHeadlessVirtualInstanceResolver(args) {
83297
83607
  if (known !== void 0) return known;
83298
83608
  virtualInstanceRowsForValue(valueId);
83299
83609
  return graphByValueId.get(valueId) ?? null;
83610
+ },
83611
+ shareExpansion: (receiverValueId, masked, containerChanged) => {
83612
+ const reads = {
83613
+ valueIds: /* @__PURE__ */ new Set(),
83614
+ containerIds: /* @__PURE__ */ new Set(),
83615
+ global: false
83616
+ };
83617
+ activeReads.push(reads);
83618
+ let rows;
83619
+ try {
83620
+ rows = virtualInstanceRowsForValue(receiverValueId);
83621
+ } finally {
83622
+ activeReads.pop();
83623
+ mergeReads(reads);
83624
+ }
83625
+ const first = rows[0];
83626
+ if (first === void 0 || reads.global) return null;
83627
+ for (const id2 of reads.valueIds) if (masked(id2)) return null;
83628
+ for (const id2 of reads.containerIds)
83629
+ if (containerChanged(id2)) return null;
83630
+ const graph = graphByValueId.get(first.id);
83631
+ if (graph === void 0) {
83632
+ throw new Error(
83633
+ `Virtual expansion for receiver "${receiverValueId}" has rows but no graph.`
83634
+ );
83635
+ }
83636
+ return { graph, rows, reads };
83300
83637
  }
83301
83638
  };
83302
83639
  }
@@ -83334,6 +83671,7 @@ var init_virtual_instance_graph = __esm({
83334
83671
  init_initializer_context();
83335
83672
  init_src();
83336
83673
  init_initializer_materialization();
83674
+ init_unattributable_reads();
83337
83675
  KEPT_ROW_SAMPLE_LIMIT = 12;
83338
83676
  CORPUS_SCANNING_MEMBER_KINDS = /* @__PURE__ */ new Set([
83339
83677
  9 /* Lookup */,
@@ -83354,6 +83692,20 @@ var init_virtual_instance_graph = __esm({
83354
83692
  });
83355
83693
 
83356
83694
  // ../src/runtime/neoscript/evaluateInitializer.ts
83695
+ function sharedHeadlessResolver(overlay) {
83696
+ const base = overlay.base;
83697
+ if (base.databaseVM !== void 0) return void 0;
83698
+ initializerEvaluatorLookups(base);
83699
+ const resolver = headlessResolversByLookupKey.get(
83700
+ initializerEvaluatorCacheKey(base)
83701
+ );
83702
+ if (resolver === void 0) return void 0;
83703
+ return {
83704
+ resolver,
83705
+ masked: (id2) => overlay.rows.has(id2) || overlay.hiddenIds.has(id2),
83706
+ containerChanged: (id2) => overlay.changedContainerIds.has(id2)
83707
+ };
83708
+ }
83357
83709
  function initializerEvaluatorLookups(document, readTracking) {
83358
83710
  const trackedHeadless = readTracking !== void 0 && document.databaseVM === void 0;
83359
83711
  const indexKey = initializerEvaluatorCacheKey(document);
@@ -83418,10 +83770,12 @@ function initializerEvaluatorLookups(document, readTracking) {
83418
83770
  indexKey,
83419
83771
  revision
83420
83772
  );
83773
+ const shareFrom = document.databaseVM === void 0 && document.evaluatorOverlay !== void 0 ? sharedHeadlessResolver(document.evaluatorOverlay) : void 0;
83421
83774
  const headlessVirtualResolver = document.databaseVM === void 0 ? createHeadlessVirtualInstanceResolver({
83422
83775
  evaluateInitializer: evaluateMemberInitializer,
83423
83776
  document,
83424
83777
  resolverLookups: () => lookups,
83778
+ ...shareFrom === void 0 ? {} : { shareFrom },
83425
83779
  ...readTracking === void 0 ? {} : { readRecorder: virtualReadRecorder(readTracking) }
83426
83780
  }) : null;
83427
83781
  const lookups = {
@@ -83491,6 +83845,8 @@ function initializerEvaluatorLookups(document, readTracking) {
83491
83845
  revision,
83492
83846
  lookups
83493
83847
  });
83848
+ if (headlessVirtualResolver !== null)
83849
+ headlessResolversByLookupKey.set(lookupKey, headlessVirtualResolver);
83494
83850
  }
83495
83851
  return lookups;
83496
83852
  }
@@ -83499,10 +83855,18 @@ function indexedInitializerEvaluatorLookups(document, key, revision) {
83499
83855
  if (cached !== void 0 && (revision === void 0 ? cached.members === document.members && cached.values === document.values : cached.revision === revision)) {
83500
83856
  return cached.lookups;
83501
83857
  }
83502
- const lookups = makeEvaluatorLookups(document.members, document.values, {
83858
+ const overlay = document.evaluatorOverlay;
83859
+ const lookups = overlay === void 0 ? makeEvaluatorLookups(document.members, document.values, {
83503
83860
  includeValueGraphIndexes: true,
83504
83861
  constructorInitializerDocument: document
83505
- });
83862
+ }) : layerEvaluatorLookups(
83863
+ indexedInitializerEvaluatorLookups(
83864
+ overlay.base,
83865
+ initializerEvaluatorCacheKey(overlay.base),
83866
+ initializerEvaluatorCacheRevision(overlay.base)
83867
+ ),
83868
+ overlay
83869
+ );
83506
83870
  indexedEvaluatorLookupsByDocument.set(key, {
83507
83871
  members: document.members,
83508
83872
  values: document.values,
@@ -83855,7 +84219,7 @@ function evaluateMemberInitializer(args) {
83855
84219
  }
83856
84220
  };
83857
84221
  }
83858
- var evaluatorLookupsByDocument, indexedEvaluatorLookupsByDocument;
84222
+ var evaluatorLookupsByDocument, headlessResolversByLookupKey, indexedEvaluatorLookupsByDocument;
83859
84223
  var init_evaluateInitializer = __esm({
83860
84224
  "../src/runtime/neoscript/evaluateInitializer.ts"() {
83861
84225
  "use strict";
@@ -83868,32 +84232,39 @@ var init_evaluateInitializer = __esm({
83868
84232
  init_virtual_instance_graph();
83869
84233
  init_initializer_context();
83870
84234
  evaluatorLookupsByDocument = /* @__PURE__ */ new WeakMap();
84235
+ headlessResolversByLookupKey = /* @__PURE__ */ new WeakMap();
83871
84236
  indexedEvaluatorLookupsByDocument = /* @__PURE__ */ new WeakMap();
83872
84237
  }
83873
84238
  });
83874
84239
 
83875
- // ../src/runtime/materialize-values.ts
83876
- function materializeInitializerValue2(args) {
83877
- return materializeInitializerValue({
83878
- ...args,
83879
- evaluateInitializer: evaluateMemberInitializer
84240
+ // ../src/runtime/effective-value-reader.ts
84241
+ function rootReadScope(document) {
84242
+ const cached = rootReadScopes.get(document);
84243
+ if (cached !== void 0 && cached.members === document.members && cached.values === document.values && cached.variants === document.variants) {
84244
+ return cached.scope;
84245
+ }
84246
+ const scope = withVariantOwnershipRoots(
84247
+ expandPackedDocumentValues(document),
84248
+ document.variants ?? []
84249
+ );
84250
+ const created = scope.document === document ? scope : {
84251
+ ...scope,
84252
+ document: { ...scope.document, evaluatorCache: void 0 }
84253
+ };
84254
+ rootReadScopes.set(document, {
84255
+ members: document.members,
84256
+ values: document.values,
84257
+ variants: document.variants,
84258
+ scope: created
83880
84259
  });
84260
+ return created;
83881
84261
  }
83882
- function materializeMemberDefaultValue2(args) {
83883
- return materializeMemberDefaultValue({
83884
- ...args,
83885
- evaluateInitializer: evaluateMemberInitializer
83886
- });
84262
+ function genericEnvironmentKey2(env) {
84263
+ if (env === void 0 || env.size === 0) return "";
84264
+ return canonicalJsonStringify(
84265
+ [...env].sort(([left], [right]) => left.localeCompare(right))
84266
+ );
83887
84267
  }
83888
- var init_materialize_values = __esm({
83889
- "../src/runtime/materialize-values.ts"() {
83890
- "use strict";
83891
- init_evaluateInitializer();
83892
- init_initializer_materialization();
83893
- }
83894
- });
83895
-
83896
- // ../src/runtime/effective-value-reader.ts
83897
84268
  function createTypedValueNormalizer(reader, document, childrenByContainerId, parameterTypesForRow, memberById2, memberTypeInfo, genericEnvironmentForRow, rowIdentities) {
83898
84269
  const visiting = /* @__PURE__ */ new Set();
83899
84270
  const completed = /* @__PURE__ */ new Map();
@@ -84135,7 +84506,7 @@ function isStringRecord5(value) {
84135
84506
  function isAggregateTypeInfo2(type) {
84136
84507
  return type.type === 7 /* Class */ || type.type === 22 /* Interface */ || type.type === 6 /* List */ || type.type === 5 /* Dictionary */;
84137
84508
  }
84138
- var EffectiveValueReader;
84509
+ var rootReadScopes, EffectiveValueReader;
84139
84510
  var init_effective_value_reader = __esm({
84140
84511
  "../src/runtime/effective-value-reader.ts"() {
84141
84512
  "use strict";
@@ -84149,9 +84520,10 @@ var init_effective_value_reader = __esm({
84149
84520
  init_members();
84150
84521
  init_packed_value_encoding();
84151
84522
  init_read_class_member();
84152
- init_materialize_values();
84523
+ init_initializer_materialization();
84153
84524
  init_evaluateInitializer();
84154
84525
  init_virtual_instance_graph();
84526
+ rootReadScopes = /* @__PURE__ */ new WeakMap();
84155
84527
  EffectiveValueReader = class _EffectiveValueReader {
84156
84528
  constructor(document, overrides = /* @__PURE__ */ new Map(), context = {}, base) {
84157
84529
  this.document = document;
@@ -84163,18 +84535,12 @@ var init_effective_value_reader = __esm({
84163
84535
  "Effective value reads require a complete document snapshot; use initializerEvaluationSnapshot() for a live database."
84164
84536
  );
84165
84537
  }
84538
+ this.root = base?.root ?? this;
84166
84539
  if (base === void 0) {
84167
- const expanded = expandPackedDocumentValues(document);
84168
- const scope = withVariantOwnershipRoots(
84169
- expanded,
84170
- document.variants ?? []
84171
- );
84540
+ const scope = rootReadScope(document);
84172
84541
  this.document = scope.document;
84173
84542
  for (const [id2, member] of scope.rootMembersByValueId)
84174
84543
  this.placements.set(id2, member);
84175
- } else {
84176
- for (const [id2, member] of base.placements)
84177
- this.placements.set(id2, member);
84178
84544
  }
84179
84545
  if (overrides.size > 0) {
84180
84546
  const rows = [...overrides.values()];
@@ -84191,15 +84557,22 @@ var init_effective_value_reader = __esm({
84191
84557
  overrides;
84192
84558
  context;
84193
84559
  base;
84560
+ root;
84194
84561
  schemas = /* @__PURE__ */ new Map();
84195
84562
  placements = /* @__PURE__ */ new Map();
84196
84563
  effectiveRows = /* @__PURE__ */ new Map();
84197
- defaultRows = /* @__PURE__ */ new WeakMap();
84564
+ /** Declaration defaults by member identity and closed generic environment. */
84565
+ defaultRows = /* @__PURE__ */ new Map();
84566
+ /** Initializer-free declaration defaults, shared by every fork (root only). */
84567
+ sharedDefaultRows = /* @__PURE__ */ new Map();
84568
+ /** Every row a shared declaration default minted, readable from every fork. */
84569
+ declarationRows = /* @__PURE__ */ new Map();
84198
84570
  effectiveChildren = /* @__PURE__ */ new Map();
84199
84571
  resolvedRoots = /* @__PURE__ */ new Set();
84200
84572
  normalizer;
84201
84573
  identityNormalizers = /* @__PURE__ */ new WeakMap();
84202
84574
  resolvedDocument;
84575
+ indexedDocument;
84203
84576
  materializedIndex;
84204
84577
  graphCache;
84205
84578
  createNormalizer(rowIdentities) {
@@ -84207,33 +84580,87 @@ var init_effective_value_reader = __esm({
84207
84580
  this,
84208
84581
  this.document,
84209
84582
  { get: (id2) => this.children(id2) },
84210
- (row) => this.graph.constructorParameterTypes(row, this.placements.get(row.id)),
84583
+ (row) => this.graph.constructorParameterTypes(row, this.placementFor(row.id)),
84211
84584
  (id2) => this.graph.memberForId(id2),
84212
84585
  (member, env) => this.graph.typeInfoForMember(member, env),
84213
- (row) => this.graph.genericEnvironmentForRow(row, this.placements.get(row.id)),
84586
+ (row) => this.graph.genericEnvironmentForRow(row, this.placementFor(row.id)),
84214
84587
  rowIdentities
84215
84588
  );
84216
84589
  }
84590
+ /** The base document with this context's override rows spliced in. */
84217
84591
  get readDocument() {
84218
84592
  if (this.resolvedDocument !== void 0) return this.resolvedDocument;
84593
+ const baseDocument = this.base?.readDocument ?? this.document;
84219
84594
  if (this.overrides.size === 0)
84220
- return this.resolvedDocument = this.document;
84595
+ return this.resolvedDocument = baseDocument;
84221
84596
  const values = [];
84222
- for (const row of this.document.values) {
84223
- if (this.overrides.has(row.id)) continue;
84224
- if (row.containerId && this.overrides.has(row.containerId)) continue;
84597
+ const valuesById = /* @__PURE__ */ new Map();
84598
+ const hiddenIds = /* @__PURE__ */ new Set();
84599
+ const changedContainerIds = new Set(this.overrides.keys());
84600
+ for (const row of baseDocument.values) {
84601
+ if (this.overrides.has(row.id)) {
84602
+ if (row.containerId) changedContainerIds.add(row.containerId);
84603
+ continue;
84604
+ }
84605
+ if (row.containerId && this.overrides.has(row.containerId)) {
84606
+ hiddenIds.add(row.id);
84607
+ continue;
84608
+ }
84225
84609
  values.push(row);
84610
+ valuesById.set(row.id, row);
84611
+ }
84612
+ for (const row of this.overrides.values()) {
84613
+ if (row.containerId) changedContainerIds.add(row.containerId);
84614
+ values.push(row);
84615
+ valuesById.set(row.id, row);
84226
84616
  }
84227
- for (const row of this.overrides.values()) values.push(row);
84228
84617
  this.resolvedDocument = {
84229
- ...this.document,
84618
+ ...baseDocument,
84230
84619
  databaseVM: void 0,
84231
- valueById: void 0,
84232
84620
  evaluatorCache: void 0,
84233
- values
84621
+ evaluatorOverlay: {
84622
+ base: baseDocument,
84623
+ rows: this.overrides,
84624
+ hiddenIds,
84625
+ changedContainerIds,
84626
+ values,
84627
+ valuesById
84628
+ },
84629
+ values,
84630
+ valueById: (id2) => valuesById.get(id2) ?? null
84234
84631
  };
84235
84632
  return this.resolvedDocument;
84236
84633
  }
84634
+ /**
84635
+ * The root's read document with id indexes and the shared schema cache, so
84636
+ * declaration-default materialization never scans the document for a row,
84637
+ * a member, or a class schema.
84638
+ */
84639
+ get declarationDocument() {
84640
+ if (this.indexedDocument !== void 0) return this.indexedDocument;
84641
+ const document = this.readDocument;
84642
+ this.indexedDocument = {
84643
+ ...document,
84644
+ // Same rows as the read document: share its evaluator indexes.
84645
+ evaluatorCache: document.evaluatorCache ?? {
84646
+ key: document,
84647
+ revision: void 0
84648
+ },
84649
+ valueById: document.valueById ?? ((id2) => this.graph.valuesById.get(id2) ?? null),
84650
+ memberById: document.memberById ?? ((id2) => this.memberForId(id2)),
84651
+ storedInstanceSchema: (classId) => this.schema(classId)
84652
+ };
84653
+ return this.indexedDocument;
84654
+ }
84655
+ membersById;
84656
+ memberForId(memberId) {
84657
+ if (this.membersById === void 0) {
84658
+ this.membersById = /* @__PURE__ */ new Map();
84659
+ for (const member of this.document.members)
84660
+ this.membersById.set(member.id, member);
84661
+ }
84662
+ return this.membersById.get(memberId) ?? null;
84663
+ }
84237
84664
  get graph() {
84238
84665
  return this.base?.graph ?? (this.graphCache ??= new MaterializedValueGraphContext(
84239
84666
  this.document,
@@ -84241,8 +84668,25 @@ var init_effective_value_reader = __esm({
84241
84668
  this.placements
84242
84669
  ));
84243
84670
  }
84671
+ schema(classId) {
84672
+ const cached = this.root.schemas.get(classId);
84673
+ if (cached !== void 0) return cached;
84674
+ const schema = mergeStoredInstanceSchema(
84675
+ classId,
84676
+ this.document.classes,
84677
+ this.document.members
84678
+ );
84679
+ this.root.schemas.set(classId, schema);
84680
+ return schema;
84681
+ }
84244
84682
  rawRow(id2) {
84245
- return this.overrides.get(id2) ?? this.base?.rawRow(id2) ?? this.graph.valuesById.get(id2);
84683
+ const override = this.overrides.get(id2);
84684
+ if (override !== void 0) return override;
84685
+ if (this.base !== void 0) return this.base.rawRow(id2);
84686
+ return this.declarationRows.get(id2) ?? this.graph.valuesById.get(id2);
84687
+ }
84688
+ placementFor(valueId) {
84689
+ return this.placements.get(valueId) ?? this.base?.placementFor(valueId);
84246
84690
  }
84247
84691
  overrideChildren;
84248
84692
  rememberRows(rows) {
@@ -84295,21 +84739,13 @@ var init_effective_value_reader = __esm({
84295
84739
  return row;
84296
84740
  if (this.resolvedRoots.has(valueId)) return row;
84297
84741
  if (this.mode(valueId) === "partial") return row;
84298
- let schema = this.schemas.get(classId);
84299
- if (schema === void 0) {
84300
- schema = mergeStoredInstanceSchema(
84301
- classId,
84302
- this.document.classes,
84303
- this.document.members
84304
- );
84305
- this.schemas.set(classId, schema);
84306
- }
84742
+ const schema = this.schema(classId);
84307
84743
  if (schema.every(
84308
84744
  (entry) => Object.prototype.hasOwnProperty.call(row.value, entry.schemaKey)
84309
84745
  ))
84310
84746
  return row;
84311
84747
  this.resolvedRoots.add(valueId);
84312
- const member = this.placements.get(valueId) ?? this.graph.ownerForValue(valueId) ?? {
84748
+ const member = this.placementFor(valueId) ?? this.graph.ownerForValue(valueId) ?? {
84313
84749
  name: "Value",
84314
84750
  kind: 7 /* Class */,
84315
84751
  classId,
@@ -84361,26 +84797,52 @@ var init_effective_value_reader = __esm({
84361
84797
  return rows;
84362
84798
  }
84363
84799
  memberForValue(valueId) {
84364
- return this.placements.get(valueId) ?? this.graph.ownerForValue(valueId);
84800
+ return this.placementFor(valueId) ?? this.graph.ownerForValue(valueId);
84365
84801
  }
84366
84802
  mode(valueId) {
84367
84803
  return getField(this.memberForValue(valueId), "payload") === 1 /* Partial */ ? "partial" : "runtime";
84368
84804
  }
84805
+ /**
84806
+ * The declared default graph for a member position.
84807
+ *
84808
+ * A default that evaluated no initializer is a clone of declaration rows,
84809
+ * which no replay overrides, so the root reader keeps it for every fork. A
84810
+ * default that ran an initializer read this context's document and stays
84811
+ * with this context.
84812
+ */
84369
84813
  declarationRow(member, genericEnv) {
84370
- const cached = this.defaultRows.get(member)?.get(genericEnv);
84814
+ const memberId = getField(member, "id");
84815
+ const memberKey = typeof memberId === "string" ? memberId : member;
84816
+ const envKey = genericEnvironmentKey2(genericEnv);
84817
+ const shared = this.root.sharedDefaultRows.get(memberKey)?.get(envKey);
84818
+ if (shared !== void 0) return shared;
84819
+ const cached = this.defaultRows.get(memberKey)?.get(envKey);
84371
84820
  if (cached !== void 0) return cached;
84372
- const result = materializeMemberDefaultValue2({
84821
+ let evaluatedInitializer = false;
84822
+ const result = materializeMemberDefaultValue({
84373
84823
  ...this.context,
84374
- document: this.readDocument,
84824
+ evaluateInitializer: (args) => {
84825
+ evaluatedInitializer = true;
84826
+ return evaluateMemberInitializer(args);
84827
+ },
84828
+ document: this.declarationDocument,
84375
84829
  member,
84376
84830
  genericEnv,
84377
84831
  envelope: buildNewValue(this.document.project.id, { value: null }),
84378
84832
  declarationRoot: true
84379
84833
  });
84380
- this.rememberRows([result.root, ...result.createdValues]);
84381
- const contexts = this.defaultRows.get(member) ?? /* @__PURE__ */ new Map();
84382
- contexts.set(genericEnv, result.root);
84383
- this.defaultRows.set(member, contexts);
84834
+ const rows = [result.root, ...result.createdValues];
84835
+ const owner = evaluatedInitializer ? this : this.root;
84836
+ owner.rememberRows(rows);
84837
+ const cache = evaluatedInitializer ? owner.defaultRows : owner.sharedDefaultRows;
84838
+ if (!evaluatedInitializer)
84839
+ for (const row of rows) owner.declarationRows.set(row.id, row);
84840
+ let contexts = cache.get(memberKey);
84841
+ if (contexts === void 0) {
84842
+ contexts = /* @__PURE__ */ new Map();
84843
+ cache.set(memberKey, contexts);
84844
+ }
84845
+ contexts.set(envKey, result.root);
84384
84846
  return result.root;
84385
84847
  }
84386
84848
  normalizeConstructorArguments(args, root, placement) {
@@ -84403,12 +84865,7 @@ var init_effective_value_reader = __esm({
84403
84865
  return normalizer.normalizeTypedRow(valueId, typeInfo, placement, env);
84404
84866
  }
84405
84867
  withRowOverrides(rows) {
84406
- return new _EffectiveValueReader(
84407
- this.readDocument,
84408
- rows,
84409
- this.context,
84410
- this
84411
- );
84868
+ return new _EffectiveValueReader(this.document, rows, this.context, this);
84412
84869
  }
84413
84870
  };
84414
84871
  }
@@ -84913,6 +85370,21 @@ var init_init_source = __esm({
84913
85370
  }
84914
85371
  });
84915
85372
 
85373
+ // ../src/runtime/materialize-values.ts
85374
+ function materializeInitializerValue2(args) {
85375
+ return materializeInitializerValue({
85376
+ ...args,
85377
+ evaluateInitializer: evaluateMemberInitializer
85378
+ });
85379
+ }
85380
+ var init_materialize_values = __esm({
85381
+ "../src/runtime/materialize-values.ts"() {
85382
+ "use strict";
85383
+ init_evaluateInitializer();
85384
+ init_initializer_materialization();
85385
+ }
85386
+ });
85387
+
84916
85388
  // ../src/database/project-read-base.ts
84917
85389
  import { ConvexError } from "convex/values";
84918
85390
  function readProjectReadBase(value) {
@@ -88927,16 +89399,26 @@ function collectStructuralDependencyRecords(document, currentDocument, changedCl
88927
89399
  return records2;
88928
89400
  }
88929
89401
  function classPlacementsForMember(memberId, document) {
88930
- const placements = /* @__PURE__ */ new Set();
88931
- for (const schemaClass2 of document.classes) {
88932
- const surface = mergeSchemas(
88933
- resolveInheritanceChain(schemaClass2.id, document.classes)
88934
- );
88935
- if (surface.some((entry) => entry.memberId === memberId)) {
88936
- placements.add(schemaClass2.id);
89402
+ let index = classPlacementIndexes.get(document.classes);
89403
+ if (index === void 0) {
89404
+ const built = /* @__PURE__ */ new Map();
89405
+ for (const schemaClass2 of document.classes) {
89406
+ const surface = mergeSchemas(
89407
+ resolveInheritanceChain(schemaClass2.id, document.classes)
89408
+ );
89409
+ for (const entry of surface) {
89410
+ let owners = built.get(entry.memberId);
89411
+ if (owners === void 0) {
89412
+ owners = /* @__PURE__ */ new Set();
89413
+ built.set(entry.memberId, owners);
89414
+ }
89415
+ owners.add(schemaClass2.id);
89416
+ }
88937
89417
  }
89418
+ index = built;
89419
+ classPlacementIndexes.set(document.classes, index);
88938
89420
  }
88939
- return placements;
89421
+ return index.get(memberId) ?? NO_PLACEMENTS;
88940
89422
  }
88941
89423
  function explicitTargetIds(changes) {
88942
89424
  const result = {
@@ -89192,7 +89674,7 @@ function withoutFields(value, ignored) {
89192
89674
  Object.entries(value).filter(([field]) => !ignored.has(field))
89193
89675
  );
89194
89676
  }
89195
- var NON_CONTRACT_MEMBER_FIELDS, NS_PROPERTY_BODY_FIELDS, NS_FUNCTION_BODY_FIELDS;
89677
+ var NON_CONTRACT_MEMBER_FIELDS, NS_PROPERTY_BODY_FIELDS, NS_FUNCTION_BODY_FIELDS, NO_PLACEMENTS, classPlacementIndexes;
89196
89678
  var init_neo_script_recompile_scope = __esm({
89197
89679
  "../src/database/neo-script-recompile-scope.ts"() {
89198
89680
  "use strict";
@@ -89233,6 +89715,8 @@ var init_neo_script_recompile_scope = __esm({
89233
89715
  "bodyMode",
89234
89716
  "uiAction"
89235
89717
  ]);
89718
+ NO_PLACEMENTS = /* @__PURE__ */ new Set();
89719
+ classPlacementIndexes = /* @__PURE__ */ new WeakMap();
89236
89720
  }
89237
89721
  });
89238
89722
 
@@ -96825,11 +97309,8 @@ function materializePreparedInstanceInitializers(args) {
96825
97309
  compiledDocument,
96826
97310
  compiledDocument.variants ?? []
96827
97311
  );
96828
- let currentGraph = null;
96829
- const requireCurrentGraph = () => currentGraph ??= createVariantMaterializedValueGraphContext(
96830
- materializationScope.document,
96831
- materializationScope.document.variants ?? []
96832
- );
97312
+ let currentReader = null;
97313
+ const requireCurrentReader = () => currentReader ??= new EffectiveValueReader(materializationScope.document);
96833
97314
  const owners = resolveSemanticOwnerMembersForValues(
96834
97315
  materializationScope.document,
96835
97316
  new Set(sites.keys()),
@@ -96870,8 +97351,7 @@ function materializePreparedInstanceInitializers(args) {
96870
97351
  // scope that compiled and evaluated this initializer. Stored replay
96871
97352
  // closes its generic slot from the same ephemeral member id, so its
96872
97353
  // expansion must read that scoped document too.
96873
- currentDocument: materializationScope.document,
96874
- currentGraph: requireCurrentGraph(),
97354
+ currentReader: requireCurrentReader(),
96875
97355
  currentRoot: existingRoot,
96876
97356
  rootMember: member,
96877
97357
  replayRoot: materialized.root,
@@ -96966,8 +97446,7 @@ function replayedCreationDataMatches(args) {
96966
97446
  if (replayArgs !== void 0 && replayArgs !== null) {
96967
97447
  const currentArgs = args.currentRoot.constructorArgs;
96968
97448
  if (currentArgs === void 0 || currentArgs === null || !constructorArgumentsSemanticallyEqual({
96969
- currentDocument: args.currentDocument,
96970
- currentGraph: args.currentGraph,
97449
+ currentReader: args.currentReader,
96971
97450
  currentRoot: args.currentRoot,
96972
97451
  rootMember: args.rootMember,
96973
97452
  current: currentArgs,
@@ -97131,7 +97610,7 @@ function reconcileInitializerMaterializationTransport(args) {
97131
97610
  }
97132
97611
  }
97133
97612
  function constructorArgumentsSemanticallyEqual(args) {
97134
- const current = new EffectiveValueReader(args.currentDocument);
97613
+ const current = args.currentReader;
97135
97614
  const replayRows = /* @__PURE__ */ new Map([
97136
97615
  [args.replayRoot.id, args.replayRoot]
97137
97616
  ]);
@@ -98694,7 +99173,8 @@ function materializeAuthoredSeedRow(args) {
98694
99173
  const literalArgs = { ...args, row: args.row };
98695
99174
  const rowCarriesCompleteConstructionRecipe = carriesCompleteConstructionRecipe(args.row);
98696
99175
  const belongsToSparseConstruction = args.sparseConstructionRoot || rowCarriesCompleteConstructionRecipe;
98697
- if (isMemberClassBase(resolvedStoredMember) && args.row.value !== null && !belongsToSparseConstruction) {
99176
+ const rowIsStored = args.replaceExistingIds.has(args.row.id);
99177
+ if (isMemberClassBase(resolvedStoredMember) && args.row.value !== null && !belongsToSparseConstruction && !rowIsStored) {
98698
99178
  return materializeLegacyAuthoredClassSeedRow({
98699
99179
  args: literalArgs,
98700
99180
  member: resolvedStoredMember
@@ -99276,6 +99756,22 @@ function prepareServerOwnedValueInitializerBodies(args) {
99276
99756
  const currentValueById = new Map(
99277
99757
  args.document.values.map((value) => [value.id, value])
99278
99758
  );
99759
+ const compilationProjects = /* @__PURE__ */ new WeakMap();
99760
+ const compilationProjectFor = (document) => {
99761
+ const cached = compilationProjects.get(document);
99762
+ if (cached !== void 0) return cached;
99763
+ const compilationProject = cachedServerCompilationProject({
99764
+ project: document.project,
99765
+ projectFiles: document.projectFiles,
99766
+ members: document.members,
99767
+ classes: document.classes,
99768
+ enums: document.enums,
99769
+ interfaces: document.interfaces,
99770
+ constructors: document.constructors ?? []
99771
+ });
99772
+ compilationProjects.set(document, compilationProject);
99773
+ return compilationProject;
99774
+ };
99279
99775
  const compileOne = (document, row, documentValuesById) => {
99280
99776
  const member = ownerByValueId.get(row.id);
99281
99777
  if (member === void 0) {
@@ -99297,6 +99793,7 @@ function prepareServerOwnedValueInitializerBodies(args) {
99297
99793
  enums: document.enums,
99298
99794
  interfaces: document.interfaces,
99299
99795
  constructors: document.constructors ?? [],
99796
+ compilationProject: compilationProjectFor(document),
99300
99797
  member,
99301
99798
  valueRow: row,
99302
99799
  valueId: row.id,
@@ -99480,21 +99977,29 @@ function compileInlineDelegateConstructorArguments(args) {
99480
99977
  env,
99481
99978
  document.members
99482
99979
  );
99483
- compiled[argumentKey] = compileDelegateClosureValue(argument2.code, {
99484
- project: document.project,
99485
- projectFiles: document.projectFiles,
99486
- members: document.members,
99487
- classes: document.classes,
99488
- enums: document.enums,
99489
- interfaces: document.interfaces,
99490
- constructors: document.constructors ?? [],
99491
- variants: document.variants ?? [],
99492
- variantFolders: document.variantFolders ?? [],
99493
- thisClass,
99494
- returnTypeInfo: substituted.returnTypeInfo,
99495
- argumentTypes: substituted.argumentTypes,
99496
- name: `${settledMember.name} argument`
99497
- });
99980
+ try {
99981
+ compiled[argumentKey] = compileDelegateClosureValue(argument2.code, {
99982
+ project: document.project,
99983
+ projectFiles: document.projectFiles,
99984
+ members: document.members,
99985
+ classes: document.classes,
99986
+ enums: document.enums,
99987
+ interfaces: document.interfaces,
99988
+ constructors: document.constructors ?? [],
99989
+ variants: document.variants ?? [],
99990
+ variantFolders: document.variantFolders ?? [],
99991
+ thisClass,
99992
+ returnTypeInfo: substituted.returnTypeInfo,
99993
+ argumentTypes: substituted.argumentTypes,
99994
+ name: `${settledMember.name} argument`
99995
+ });
99996
+ } catch (error) {
99997
+ const detail = error instanceof Error ? error.message : String(error);
99998
+ throw new Error(
99999
+ `Value "${row.id}" (class "${schemaClass2.name}", root owner "${rootOwner?.name ?? "unknown"}") has a NeoDelegate closure for constructor parameter "${parameter4.name}" that does not compile: ${detail}`,
100000
+ { cause: error }
100001
+ );
100002
+ }
99498
100003
  }
99499
100004
  return compiled;
99500
100005
  }
@@ -99537,8 +100042,9 @@ function prepareServerOwnedDelegateValueBodies(args) {
99537
100042
  const compileOne = (document, row) => {
99538
100043
  const member = ownerByValueId.get(row.id);
99539
100044
  if (!isMemberDelegateBase(member)) {
100045
+ const placement = typeof row.containerId === "string" ? `container "${row.containerId}"` : `map key "${row.mapKey ?? "none"}"`;
99540
100046
  throw new Error(
99541
- `Value "${row.id}" carries a NeoDelegate closure but no NeoDelegate member in this project version stores it.`
100047
+ `Value "${row.id}" (${placement}, owner ${member === void 0 ? "unresolved" : `"${member.name}" of kind ${member.kind}`}) carries a NeoDelegate closure but no NeoDelegate member in this project version stores it: ${row.value.code.slice(0, 120)}`
99542
100048
  );
99543
100049
  }
99544
100050
  const rootOwner = rootOwnerByValueId.get(row.id);
@@ -117872,9 +118378,24 @@ function prepareServerPreparationChanges(args) {
117872
118378
  };
117873
118379
  const prepareFull = (discardedScopedAttempt) => {
117874
118380
  if (discardedScopedAttempt) args.resetReplayIds?.();
117875
- return prepareServerOwnedSchemaCommit(preparationArgs);
118381
+ const finish = startPerformanceSpan("server-preparation-full");
118382
+ try {
118383
+ return prepareServerOwnedSchemaCommit(preparationArgs);
118384
+ } finally {
118385
+ finish();
118386
+ }
118387
+ };
118388
+ const validate2 = (prepared) => {
118389
+ const finish = startPerformanceSpan("server-preparation-validate");
118390
+ try {
118391
+ assertProjectVersionWholeGraphWritesValid({
118392
+ document,
118393
+ changes: prepared
118394
+ });
118395
+ } finally {
118396
+ finish();
118397
+ }
117876
118398
  };
117877
- const validate2 = (prepared) => assertProjectVersionWholeGraphWritesValid({ document, changes: prepared });
117878
118399
  if (args.forceRecompile === true) {
117879
118400
  const prepared = prepareFull(false);
117880
118401
  validate2(prepared);
@@ -117932,9 +118453,15 @@ function prepareServerPreparationChanges(args) {
117932
118453
  document: scopedDocument,
117933
118454
  contentHashHeads: scopedHeads
117934
118455
  });
118456
+ let lastPass = null;
117935
118457
  for (; ; ) {
118458
+ const finishPass = startPerformanceSpan("server-preparation-pass", {
118459
+ pass: lastPass === null ? COMMIT_PREPARATION_PASS_ORDER[0] : nextCommitPreparationPass(lastPass) ?? "final"
118460
+ });
117936
118461
  const step = passes.next();
118462
+ finishPass();
117937
118463
  if (step.done) return step.value;
118464
+ lastPass = step.value.pass;
117938
118465
  const topUpRequest = planCommitPreparationInitialScope({
117939
118466
  pass: nextCommitPreparationPass(step.value.pass) ?? step.value.pass,
117940
118467
  document: scopedDocument,
@@ -118212,6 +118739,7 @@ var init_server_preparation_preflight = __esm({
118212
118739
  init_project_world_placement_bindings();
118213
118740
  init_build_default_member_value();
118214
118741
  init_packed_value_encoding();
118742
+ init_performance();
118215
118743
  init_projection();
118216
118744
  init_trusted_commit_verification();
118217
118745
  ServerPreparationPreflightError = class extends Error {
@@ -118628,7 +119156,31 @@ function compilePulledMemberInitializerBodyV4(document, memberId, compilationPro
118628
119156
  ...compilationProject === void 0 ? {} : { compilationProject }
118629
119157
  });
118630
119158
  }
119159
+ function samePulledRecords(left, right) {
119160
+ if (left === right) return true;
119161
+ if (left.size !== right.size) return false;
119162
+ for (const [key, record6] of left) {
119163
+ const other = right.get(key);
119164
+ if (other === void 0) return false;
119165
+ if (other === record6) continue;
119166
+ if (other.recordKind !== record6.recordKind || other.recordId !== record6.recordId || other.contentHash !== record6.contentHash || other.deleted !== record6.deleted || other.data !== record6.data) {
119167
+ return false;
119168
+ }
119169
+ }
119170
+ return true;
119171
+ }
118631
119172
  function readPulledProjectDocumentV4(records2) {
119173
+ for (const recent of recentPulledDocuments) {
119174
+ if (samePulledRecords(recent.records, records2)) return recent.document;
119175
+ }
119176
+ const document = readPulledProjectDocumentUncachedV4(records2);
119177
+ recentPulledDocuments.unshift({ records: records2, document });
119178
+ if (recentPulledDocuments.length > RECENT_PULLED_DOCUMENT_LIMIT) {
119179
+ recentPulledDocuments.pop();
119180
+ }
119181
+ return document;
119182
+ }
119183
+ function readPulledProjectDocumentUncachedV4(records2) {
118632
119184
  const raw = structuredClone(
118633
119185
  pulledProjectDocumentRaw(
118634
119186
  replayWorkspace(completeProspectiveRecordCreateEnvelopes(records2))
@@ -118741,7 +119293,7 @@ function replayWorkspace(records2) {
118741
119293
  state: { records: stateRecords }
118742
119294
  };
118743
119295
  }
118744
- var pulledBodyCompileSites, pulledInitializerCompilerStates, pulledMemberCompilationIndexes, pulledValueInitializerCompilationSites;
119296
+ var pulledBodyCompileSites, pulledInitializerCompilerStates, pulledMemberCompilationIndexes, pulledValueInitializerCompilationSites, recentPulledDocuments, RECENT_PULLED_DOCUMENT_LIMIT;
118745
119297
  var init_initializer_replay = __esm({
118746
119298
  "src/project-source/initializer-replay.ts"() {
118747
119299
  "use strict";
@@ -118760,6 +119312,8 @@ var init_initializer_replay = __esm({
118760
119312
  pulledInitializerCompilerStates = /* @__PURE__ */ new WeakMap();
118761
119313
  pulledMemberCompilationIndexes = /* @__PURE__ */ new WeakMap();
118762
119314
  pulledValueInitializerCompilationSites = /* @__PURE__ */ new WeakMap();
119315
+ recentPulledDocuments = [];
119316
+ RECENT_PULLED_DOCUMENT_LIMIT = 4;
118763
119317
  }
118764
119318
  });
118765
119319
 
@@ -129594,6 +130148,10 @@ function readProjectVersionTransactionStatus(value, transactionId) {
129594
130148
  value.preparationPhase ?? null,
129595
130149
  `Project transaction "${transactionId}" preparationPhase`
129596
130150
  ),
130151
+ preparationStep: readNullableString(
130152
+ value.preparationStep ?? null,
130153
+ `Project transaction "${transactionId}" preparationStep`
130154
+ ),
129597
130155
  preparationCompletedCount: readNullableCount(
129598
130156
  value.preparationCompletedCount ?? null,
129599
130157
  `Project transaction "${transactionId}" preparationCompletedCount`
@@ -129701,6 +130259,25 @@ function createPushProgressReporter(json) {
129701
130259
  }
129702
130260
  };
129703
130261
  }
130262
+ function isPreparationPass(name) {
130263
+ return Object.hasOwn(PREPARATION_PASS_LABELS, name);
130264
+ }
130265
+ function preparationStepLabel(step) {
130266
+ if (step.startsWith("pass:")) {
130267
+ const pass = step.slice("pass:".length);
130268
+ return isPreparationPass(pass) ? PREPARATION_PASS_LABELS[pass] : step;
130269
+ }
130270
+ switch (step) {
130271
+ case "document-read":
130272
+ return "reading records";
130273
+ case "validate":
130274
+ return "validating the graph";
130275
+ case "plan":
130276
+ return "planning writes";
130277
+ default:
130278
+ return step;
130279
+ }
130280
+ }
129704
130281
  function projectTransactionProgressLabel(event) {
129705
130282
  if (event.type === "push-progress") {
129706
130283
  return `Uploading files\u2026 ${event.completedFiles.toLocaleString("en-US")}/${event.totalFiles.toLocaleString("en-US")} (${formatByteProgress(event.completedBytes)}/${formatByteProgress(event.totalBytes)})`;
@@ -129714,7 +130291,8 @@ function projectTransactionProgressLabel(event) {
129714
130291
  return "Verifying uploaded files on server\u2026";
129715
130292
  }
129716
130293
  if (event.preparationPhase === "compile") {
129717
- return "Compiling affected NeoScript on server\u2026";
130294
+ const step = event.preparationStep ?? null;
130295
+ return step === null ? "Compiling affected NeoScript on server\u2026" : `Compiling affected NeoScript on server\u2026 ${preparationStepLabel(step)}`;
129718
130296
  }
129719
130297
  if (typeof event.preparationCompletedCount === "number" && typeof event.preparationTotalCount === "number" && typeof event.preparationUnit === "string") {
129720
130298
  const remaining = Math.max(
@@ -129757,6 +130335,7 @@ function progressEventFromAccepted(accepted) {
129757
130335
  errorCode: null,
129758
130336
  errorMessage: null,
129759
130337
  preparationPhase: null,
130338
+ preparationStep: null,
129760
130339
  preparationCompletedCount: null,
129761
130340
  preparationTotalCount: null,
129762
130341
  preparationUnit: null
@@ -129775,6 +130354,7 @@ function progressEventFromStatus(status) {
129775
130354
  errorCode: status.errorCode,
129776
130355
  errorMessage: status.errorMessage,
129777
130356
  preparationPhase: status.preparationPhase,
130357
+ preparationStep: status.preparationStep,
129778
130358
  preparationCompletedCount: status.preparationCompletedCount,
129779
130359
  preparationTotalCount: status.preparationTotalCount,
129780
130360
  preparationUnit: status.preparationUnit
@@ -132512,7 +133092,7 @@ function compileMigrationAction(context, migrationData, locator) {
132512
133092
  locator
132513
133093
  );
132514
133094
  }
132515
- var compileNSVoidBody2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createNeoScriptCompilationProject2, ProjectTransactionInterruptedError, ProjectTransactionFailedError, LocalCandidateArtifactError, SERVER_MINTED_PUSH_RECORD_KINDS;
133095
+ var compileNSVoidBody2, compileNSFunction2, compileNSGetter2, compileNSSetter2, createNeoScriptCompilationProject2, ProjectTransactionInterruptedError, ProjectTransactionFailedError, PREPARATION_PASS_LABELS, LocalCandidateArtifactError, SERVER_MINTED_PUSH_RECORD_KINDS;
132516
133096
  var init_push = __esm({
132517
133097
  "src/commands/push.ts"() {
132518
133098
  "use strict";
@@ -132587,6 +133167,14 @@ var init_push = __esm({
132587
133167
  }
132588
133168
  status;
132589
133169
  };
133170
+ PREPARATION_PASS_LABELS = {
133171
+ "neo-script-recompile-targets": "selecting recompile targets",
133172
+ "authored-value-seeds": "seeding authored values",
133173
+ "variant-child-override-binding-members": "binding variant overrides",
133174
+ "prepared-instance-initializers": "materializing initializers",
133175
+ "delegate-value-bodies": "compiling delegate bodies",
133176
+ "variant-constructor-args": "checking variant constructor arguments"
133177
+ };
132590
133178
  LocalCandidateArtifactError = class extends Error {
132591
133179
  constructor(cause) {
132592
133180
  super(cause instanceof Error ? cause.message : String(cause));
@@ -133292,7 +133880,7 @@ import {
133292
133880
  rmSync as rmSync6,
133293
133881
  writeFileSync as writeFileSync9
133294
133882
  } from "node:fs";
133295
- import { dirname as dirname9, join as join12, relative as relative7, sep as sep7 } from "node:path";
133883
+ import { dirname as dirname8, join as join12, relative as relative7, sep as sep7 } from "node:path";
133296
133884
  function prepareWorkspaceResetV4(workspace, document, options = {}) {
133297
133885
  const emissionRecords = options.regenerateSourceNames ? regenerateDialogueSourceNamesV4(document.records) : document.records;
133298
133886
  const layoutWorkspace = workspaceForSourceLayoutV4(workspace, document);
@@ -133332,7 +133920,7 @@ function resetWorkspaceToProjectSourcesV4(workspace, document, options = {}) {
133332
133920
  }
133333
133921
  for (const file of emitted.files) {
133334
133922
  const absolute = resolveSourcePath(file.path);
133335
- mkdirSync9(dirname9(absolute), { recursive: true });
133923
+ mkdirSync9(dirname8(absolute), { recursive: true });
133336
133924
  if (existsSync10(absolute) && readFileSync14(absolute, "utf8") === file.content) {
133337
133925
  continue;
133338
133926
  }
@@ -133760,7 +134348,7 @@ import {
133760
134348
  existsSync as existsSync12,
133761
134349
  readFileSync as readFileSync15
133762
134350
  } from "node:fs";
133763
- import { dirname as dirname10 } from "node:path";
134351
+ import { dirname as dirname9 } from "node:path";
133764
134352
  async function runPull(workspace, options, progress = spinner("Checking local workspace\u2026")) {
133765
134353
  if (options.reset) {
133766
134354
  await runResetPull(workspace, progress);
@@ -134245,7 +134833,7 @@ async function finishFormat4Pull(args) {
134245
134833
  if (content === void 0) continue;
134246
134834
  const marked = conflictPaths.has(path) && detectConflictMarkers(content) !== null;
134247
134835
  if (marked) markedPaths.add(path);
134248
- mkdirSync10(dirname10(absolute), { recursive: true });
134836
+ mkdirSync10(dirname9(absolute), { recursive: true });
134249
134837
  if (existing !== null && !marked && !rewritePaths.has(path)) continue;
134250
134838
  if (existing !== content) {
134251
134839
  writeFileSync10(absolute, content, "utf8");
@@ -137789,7 +138377,7 @@ var init_registry2 = __esm({
137789
138377
  "schema-contract/registry.mjs"() {
137790
138378
  "use strict";
137791
138379
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
137792
- cliVersion: "0.52.5",
138380
+ cliVersion: "0.53.0",
137793
138381
  projectFileUploadBatchSize: 32,
137794
138382
  documentRecords: {
137795
138383
  member: {
@@ -139226,7 +139814,7 @@ import {
139226
139814
  } from "node:fs";
139227
139815
  import {
139228
139816
  basename as basename3,
139229
- dirname as dirname11,
139817
+ dirname as dirname10,
139230
139818
  isAbsolute as isAbsolute3,
139231
139819
  join as join15,
139232
139820
  relative as relative8,
@@ -139518,7 +140106,7 @@ function cachedTestCandidate(workspace, inputFingerprint) {
139518
140106
  }
139519
140107
  if (typeof parsed.documentSha256 !== "string") return null;
139520
140108
  const documentJson = readFileSync18(
139521
- join15(dirname11(candidatePath), "document.json"),
140109
+ join15(dirname10(candidatePath), "document.json"),
139522
140110
  "utf8"
139523
140111
  );
139524
140112
  if (createHash11("sha256").update(documentJson).digest("hex") !== parsed.documentSha256) {
@@ -139539,7 +140127,7 @@ function cacheTestCandidate(workspace, inputFingerprint, candidate) {
139539
140127
  const documentJson = JSON.stringify(candidate.document);
139540
140128
  const documentSha256 = createHash11("sha256").update(documentJson).digest("hex");
139541
140129
  const candidatePath = testCandidateCachePath(workspace, inputFingerprint);
139542
- atomicWrite(join15(dirname11(candidatePath), "document.json"), documentJson);
140130
+ atomicWrite(join15(dirname10(candidatePath), "document.json"), documentJson);
139543
140131
  atomicWrite(
139544
140132
  candidatePath,
139545
140133
  JSON.stringify({
@@ -140383,7 +140971,7 @@ async function executeRegisteredSpec(registered, document, selected, timeoutMs,
140383
140971
  return { tests: results, failures: fileFailures, testDurationMs };
140384
140972
  }
140385
140973
  function atomicWrite(path, content) {
140386
- mkdirSync12(dirname11(path), { recursive: true });
140974
+ mkdirSync12(dirname10(path), { recursive: true });
140387
140975
  const temporary = `${path}.tmp-${String(process.pid)}-${randomUUID6()}`;
140388
140976
  writeFileSync12(temporary, content, "utf8");
140389
140977
  renameSync7(temporary, path);
@@ -144924,7 +145512,7 @@ import {
144924
145512
  unlinkSync,
144925
145513
  writeFileSync as writeFileSync14
144926
145514
  } from "node:fs";
144927
- import { dirname as dirname12, join as join18 } from "node:path";
145515
+ import { dirname as dirname11, join as join18 } from "node:path";
144928
145516
  function validatePath(path) {
144929
145517
  if (!/^Generated\/[a-zA-Z0-9_%./-]+\.g\.cs$/.test(path))
144930
145518
  throw new Error(`Invalid generated file path: ${path}`);
@@ -145047,7 +145635,7 @@ function writeUnityGeneratedFiles(directory, projectId, files) {
145047
145635
  if (content === null) {
145048
145636
  if (existsSync17(path)) unlinkSync(path);
145049
145637
  } else {
145050
- mkdirSync14(dirname12(path), { recursive: true });
145638
+ mkdirSync14(dirname11(path), { recursive: true });
145051
145639
  writeFileSync14(path, content);
145052
145640
  }
145053
145641
  };
@@ -145662,7 +146250,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
145662
146250
  async function main() {
145663
146251
  const args = parseArgs(process.argv.slice(2));
145664
146252
  if (args.command === "--version") {
145665
- console.log("0.52.5");
146253
+ console.log("0.53.0");
145666
146254
  return;
145667
146255
  }
145668
146256
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {