@neocompose/cli 0.76.2 → 0.76.3

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
@@ -10011,13 +10011,16 @@ function constructionMembers(classId, context) {
10011
10011
  }
10012
10012
  function createMemberDefaultConstructionChecker(document) {
10013
10013
  const context = contextFor(document);
10014
- return (member, genericEnv = /* @__PURE__ */ new Map()) => {
10014
+ return (member, genericEnv = /* @__PURE__ */ new Map(), readValueIds) => {
10015
10015
  const previousEnv = context.env;
10016
+ const previousReads = context.readValueIds;
10016
10017
  context.env = genericEnv;
10018
+ context.readValueIds = readValueIds;
10017
10019
  try {
10018
10020
  return defaultSettlesConstruction(member, context, /* @__PURE__ */ new Set());
10019
10021
  } finally {
10020
10022
  context.env = previousEnv;
10023
+ context.readValueIds = previousReads;
10021
10024
  }
10022
10025
  };
10023
10026
  }
@@ -10128,6 +10131,7 @@ function valueSettlesConstruction(member, body, context, path, storedRow = false
10128
10131
  }
10129
10132
  function suppliedValueSettlesConstruction(member, value, context, path) {
10130
10133
  if (typeof value === "string") {
10134
+ context.readValueIds?.add(value);
10131
10135
  let row;
10132
10136
  if (context.document.valueById !== void 0) {
10133
10137
  row = context.document.valueById(value);
@@ -11312,74 +11316,84 @@ function recordStorageKeyDeclaration(sink, valueId, member) {
11312
11316
  if (declaration === STORAGE_KEY_INHERIT) return;
11313
11317
  sink.set(valueId, declaration);
11314
11318
  }
11315
- function createDefaultValueResolutionCache() {
11319
+ function createDefaultSchemaResolutionCache() {
11316
11320
  return {
11317
11321
  memberByIdIndex: null,
11318
11322
  instanceEnvironmentByKey: /* @__PURE__ */ new Map(),
11319
- materializationPlanByClassAndEnvironment: /* @__PURE__ */ new Map(),
11320
11323
  resolvedMemberById: /* @__PURE__ */ new Map(),
11321
11324
  storedSchemaByClassId: /* @__PURE__ */ new Map(),
11322
- validatedInitializerContainers: /* @__PURE__ */ new WeakSet(),
11325
+ validatedInitializerContainers: /* @__PURE__ */ new WeakSet()
11326
+ };
11327
+ }
11328
+ function createDefaultValueResolutionCache(schema = createDefaultSchemaResolutionCache()) {
11329
+ return {
11330
+ schema,
11331
+ materializationPlanByClassAndEnvironment: /* @__PURE__ */ new Map(),
11323
11332
  memberDefaultConstructionChecker: null
11324
11333
  };
11325
11334
  }
11326
11335
  function withIndexedDefaultValueDocument(document, options = {}) {
11327
11336
  const cache = options.cache ?? createDefaultValueResolutionCache();
11328
- if (cache.memberByIdIndex === null && options.memberById === void 0 && document.memberById === void 0) {
11329
- cache.memberByIdIndex = new Map(
11337
+ const schemaCache = cache.schema;
11338
+ if (schemaCache.memberByIdIndex === null && options.memberById === void 0 && document.memberById === void 0) {
11339
+ schemaCache.memberByIdIndex = new Map(
11330
11340
  document.members.map((member) => [member.id, member])
11331
11341
  );
11332
11342
  }
11333
11343
  const indexed = {
11334
11344
  ...document,
11335
- memberById: (id2) => options.memberById?.(id2) ?? document.memberById?.(id2) ?? cache.memberByIdIndex?.get(id2) ?? null,
11345
+ memberById: (id2) => options.memberById?.(id2) ?? document.memberById?.(id2) ?? schemaCache.memberByIdIndex?.get(id2) ?? null,
11336
11346
  resolvedMember: (member) => {
11337
11347
  const memberId = "id" in member ? member.id : void 0;
11338
11348
  if (typeof memberId !== "string") {
11339
11349
  return resolveMember(member, document.members);
11340
11350
  }
11341
- const cached = cache.resolvedMemberById.get(memberId);
11351
+ const cached = schemaCache.resolvedMemberById.get(memberId);
11342
11352
  if (cached !== void 0) return cached;
11343
11353
  const resolved = resolveMember(member, document.members);
11344
- cache.resolvedMemberById.set(memberId, resolved);
11354
+ schemaCache.resolvedMemberById.set(memberId, resolved);
11345
11355
  return resolved;
11346
11356
  },
11347
11357
  storedInstanceSchema: (classId) => {
11348
- const cached = cache.storedSchemaByClassId.get(classId);
11358
+ const cached = schemaCache.storedSchemaByClassId.get(classId);
11349
11359
  if (cached !== void 0) return cached;
11350
11360
  const schema = resolvedClassSchema(
11351
11361
  classId,
11352
11362
  document.classes,
11353
11363
  document.members
11354
11364
  ).surface;
11355
- cache.storedSchemaByClassId.set(classId, schema);
11365
+ schemaCache.storedSchemaByClassId.set(classId, schema);
11356
11366
  return schema;
11357
11367
  },
11358
11368
  instanceEnv: (classId, classArguments2) => {
11359
11369
  const key = `${classId}:${JSON.stringify(classArguments2 ?? null)}`;
11360
- const cached = cache.instanceEnvironmentByKey.get(key);
11370
+ const cached = schemaCache.instanceEnvironmentByKey.get(key);
11361
11371
  if (cached !== void 0) return cached;
11362
11372
  const environment = resolveInstanceEnv(
11363
11373
  classId,
11364
11374
  classArguments2,
11365
11375
  document.classes
11366
11376
  );
11367
- cache.instanceEnvironmentByKey.set(key, environment);
11377
+ schemaCache.instanceEnvironmentByKey.set(key, environment);
11368
11378
  return environment;
11369
11379
  },
11370
11380
  isInitValueContent: (value) => {
11371
11381
  if (typeof value !== "object" || value === null) return false;
11372
- if (cache.validatedInitializerContainers.has(value)) return true;
11382
+ if (schemaCache.validatedInitializerContainers.has(value)) return true;
11373
11383
  if (!isInitValueContent(value)) return false;
11374
- cache.validatedInitializerContainers.add(value);
11384
+ schemaCache.validatedInitializerContainers.add(value);
11375
11385
  return true;
11376
11386
  },
11377
- memberDefaultSettlesConstruction: (member, environment) => {
11387
+ memberDefaultSettlesConstruction: (member, environment, readValueIds) => {
11378
11388
  cache.memberDefaultConstructionChecker ??= createMemberDefaultConstructionChecker({
11379
11389
  ...indexed,
11380
11390
  constructors: document.constructors ?? []
11381
11391
  });
11382
- return cache.memberDefaultConstructionChecker(member, environment);
11392
+ return cache.memberDefaultConstructionChecker(
11393
+ member,
11394
+ environment,
11395
+ readValueIds
11396
+ );
11383
11397
  },
11384
11398
  createValueRow: options.createValueRow ?? document.createValueRow
11385
11399
  };
@@ -11431,12 +11445,20 @@ function buildDefaultClassMaterializationPlan(document, classId, instanceEnv) {
11431
11445
  ...document,
11432
11446
  constructors: document.constructors ?? []
11433
11447
  });
11434
- return storedSchemaOf(document, classId).flatMap(
11448
+ const reads = {
11449
+ valueIds: /* @__PURE__ */ new Set(),
11450
+ containerIds: /* @__PURE__ */ new Set()
11451
+ };
11452
+ const entries = storedSchemaOf(document, classId).flatMap(
11435
11453
  (entry) => {
11436
11454
  if (entry.memberId === null) return [];
11437
11455
  const childMember = findMemberInDocument(document, entry.memberId);
11438
11456
  if (!memberKindOwnsStoredValue(childMember.kind)) return [];
11439
- if (instanceEnv.size === 0 && isConstantMember(document, resolvedInDocument(document, childMember)))
11457
+ if (instanceEnv.size === 0 && isConstantMember(
11458
+ document,
11459
+ resolvedInDocument(document, childMember),
11460
+ reads
11461
+ ))
11440
11462
  return [];
11441
11463
  const member = substituteMember(
11442
11464
  childMember,
@@ -11448,14 +11470,19 @@ function buildDefaultClassMaterializationPlan(document, classId, instanceEnv) {
11448
11470
  {
11449
11471
  schemaKey: entry.schemaKey,
11450
11472
  member,
11451
- defaultSettlesConstruction: settlesConstruction(member, instanceEnv),
11473
+ defaultSettlesConstruction: settlesConstruction(
11474
+ member,
11475
+ instanceEnv,
11476
+ reads.valueIds
11477
+ ),
11452
11478
  directScalarBody: directScalarDefaultBody(document, member)
11453
11479
  }
11454
11480
  ];
11455
11481
  }
11456
11482
  );
11483
+ return { entries, reads };
11457
11484
  }
11458
- function isConstantMember(document, resolved) {
11485
+ function isConstantMember(document, resolved, reads) {
11459
11486
  if (isStaticMember(resolved)) return false;
11460
11487
  const fixedness = fixednessOf(resolved, 0 /* Writable */);
11461
11488
  if (fixedness === 0 /* Writable */) return false;
@@ -11468,7 +11495,8 @@ function isConstantMember(document, resolved) {
11468
11495
  document,
11469
11496
  rows: /* @__PURE__ */ new Set(),
11470
11497
  declarations: /* @__PURE__ */ new Set(),
11471
- classes: /* @__PURE__ */ new Set()
11498
+ classes: /* @__PURE__ */ new Set(),
11499
+ reads
11472
11500
  },
11473
11501
  resolved,
11474
11502
  declared,
@@ -11542,6 +11570,8 @@ function declarationVaries(walk, member, body, rowId, scope) {
11542
11570
  return owned !== Object.keys(value).length;
11543
11571
  }
11544
11572
  if (isMemberListBase(member)) {
11573
+ if (rowId !== null && listKindOf(member) === 1 /* Unordered */)
11574
+ walk.reads?.containerIds.add(rowId);
11545
11575
  const entryIds = listKindOf(member) !== 1 /* Unordered */ ? value : rowId === null ? [] : document.unorderedListEntryIds?.(rowId) ?? (walk.membership ??= buildUnorderedListMembershipIndex(
11546
11576
  document.values
11547
11577
  )).get(rowId) ?? [];
@@ -11574,6 +11604,7 @@ function rowVaries(walk, member, valueId, scope) {
11574
11604
  const key = scopeKey(valueId, scope);
11575
11605
  if (walk.rows.has(key)) return false;
11576
11606
  walk.rows.add(key);
11607
+ walk.reads?.valueIds.add(valueId);
11577
11608
  const { document } = walk;
11578
11609
  const row = document.valueById?.(valueId) ?? (walk.rowById ??= new Map(
11579
11610
  document.values.map((value) => [value.id, value])
@@ -11877,6 +11908,7 @@ function buildDefaultMemberValueCore(args, resolvedMember) {
11877
11908
  effectiveClassId,
11878
11909
  childEnv
11879
11910
  );
11911
+ args.document.recordPlanReads?.(materializationPlan.reads);
11880
11912
  const record7 = member.payload === 1 /* Partial */ ? {} : cloneDefaultClassRecord({
11881
11913
  document: args.document,
11882
11914
  projectId: args.projectId,
@@ -12070,7 +12102,7 @@ function completeDefaultClassRecord(args) {
12070
12102
  member: resolvedChildMember,
12071
12103
  defaultSettlesConstruction: defaultSettlesConstruction2,
12072
12104
  directScalarBody
12073
- } of args.member.payload === 1 /* Partial */ ? [] : args.materializationPlan) {
12105
+ } of args.member.payload === 1 /* Partial */ ? [] : args.materializationPlan.entries) {
12074
12106
  if (storageKeyReferencesParentClass(
12075
12107
  normalizeStorageKeyDeclaration(resolvedChildMember.storageKey)
12076
12108
  )) {
@@ -12390,6 +12422,7 @@ function cloneDefaultValueForMemberCore(args, sourceValue) {
12390
12422
  effectiveClassId,
12391
12423
  childEnv
12392
12424
  );
12425
+ args.document.recordPlanReads?.(materializationPlan.reads);
12393
12426
  const anchorsParentClassPartition = sourceValue.constructorArgs == null && completeDefaultClassRecord({
12394
12427
  ...args,
12395
12428
  member,
@@ -37059,7 +37092,10 @@ var init_strict_resolver = __esm({
37059
37092
  const resolved = this.resolveIdentifier(callee.name, scope, callee.pos);
37060
37093
  return resolved.type.kind === "delegate" || resolved.type.kind === "action" ? resolved : null;
37061
37094
  }
37062
- if (callee.kind !== "member") return null;
37095
+ if (callee.kind !== "member") {
37096
+ const resolved = this.resolveExpression(callee, scope);
37097
+ return resolved.type.kind === "delegate" ? resolved : null;
37098
+ }
37063
37099
  try {
37064
37100
  const resolved = this.resolveMember(
37065
37101
  callee.receiver,
@@ -45493,7 +45529,7 @@ function validateExpression(expression, expected, scope, environment, uri, range
45493
45529
  if (expected && expression.kind !== "contextualEnum" && expression.kind !== "annotated" && !isReferenceCall(expression)) {
45494
45530
  const actual = inferExpressionType(expression, scope, environment);
45495
45531
  const explicitConstruction = expression.kind === "new" && expression.className !== null && expected.name !== "Partial";
45496
- const assignable = actual === void 0 || (explicitConstruction ? constructionTypesAssignable(actual, expected, scope, environment) : semanticTypesAssignable(actual, expected));
45532
+ const assignable = actual === void 0 || (explicitConstruction ? constructionTypesAssignable(actual, expected, scope, environment) : semanticTypesAssignable(actual, expected, environment));
45497
45533
  if (actual && !assignable) {
45498
45534
  pushDiagnostic(
45499
45535
  diagnostics,
@@ -45508,13 +45544,18 @@ function validateExpression(expression, expected, scope, environment, uri, range
45508
45544
  );
45509
45545
  }
45510
45546
  }
45511
- if (expression.kind === "contextualEnum") {
45512
- const enumeration = expected ? environment.enums.get(expected.name) : void 0;
45547
+ const qualifiedEnum = qualifiedEnumReceiver(expression, scope, environment);
45548
+ if (expression.kind === "contextualEnum" || expression.kind === "member" && qualifiedEnum !== void 0) {
45549
+ let enumeration = qualifiedEnum;
45550
+ if (expression.kind === "contextualEnum" && expected !== void 0) {
45551
+ enumeration = environment.enums.get(expected.name);
45552
+ }
45553
+ const optionRange = anchor ? anchorSpan(anchor, expression.pos, 1) : range2;
45513
45554
  if (!enumeration) {
45514
45555
  pushDiagnostic(
45515
45556
  diagnostics,
45516
45557
  uri,
45517
- range2,
45558
+ optionRange,
45518
45559
  "contextual-enum-without-expected-type",
45519
45560
  `Cannot infer enum option '.${expression.name}' without one expected enum type.`
45520
45561
  );
@@ -45522,7 +45563,7 @@ function validateExpression(expression, expected, scope, environment, uri, range
45522
45563
  pushDiagnostic(
45523
45564
  diagnostics,
45524
45565
  uri,
45525
- range2,
45566
+ optionRange,
45526
45567
  "unknown-contextual-enum-option",
45527
45568
  `Enum '${enumeration.name}' has no option '${expression.name}'.`
45528
45569
  );
@@ -45598,7 +45639,8 @@ function validateExpression(expression, expected, scope, environment, uri, range
45598
45639
  for (const entry of expression.entries) {
45599
45640
  validateExpression(
45600
45641
  entry.key,
45601
- key,
45642
+ // Enum dictionaries also preserve quoted option IDs, including orphaned IDs.
45643
+ entry.key.kind === "litString" ? void 0 : key,
45602
45644
  scope,
45603
45645
  environment,
45604
45646
  uri,
@@ -45689,7 +45731,7 @@ function validateExpression(expression, expected, scope, environment, uri, range
45689
45731
  scope,
45690
45732
  environment
45691
45733
  );
45692
- const branchType = expected ?? commonSemanticAssignableType(trueType, falseType);
45734
+ const branchType = expected ?? commonSemanticAssignableType(trueType, falseType, environment);
45693
45735
  validateExpression(
45694
45736
  expression.whenTrue,
45695
45737
  branchType,
@@ -46292,7 +46334,7 @@ function substituteSemanticType(type, bindings) {
46292
46334
  );
46293
46335
  return { ...type, arguments: argumentsList2 };
46294
46336
  }
46295
- function semanticTypesAssignable(actual, expected) {
46337
+ function semanticTypesAssignable(actual, expected, environment) {
46296
46338
  if (actual.name === "null") {
46297
46339
  return expected.name === "null" || expected.nullable === true;
46298
46340
  }
@@ -46307,18 +46349,13 @@ function semanticTypesAssignable(actual, expected) {
46307
46349
  if (actual.name === "float" && expected.name === "decimal") {
46308
46350
  return actual.nullable !== true || expected.nullable === true;
46309
46351
  }
46310
- if (Object.prototype.hasOwnProperty.call(
46311
- NEO_PROJECT_SOURCE_RECORD_CONTRACT.enums,
46312
- expected.name
46313
- )) {
46314
- return false;
46315
- }
46352
+ if (environment.enums.has(expected.name)) return false;
46316
46353
  if (SEMANTIC_PRIMITIVE_TYPE_NAMES.has(expected.name) && SEMANTIC_PRIMITIVE_TYPE_NAMES.has(actual.name)) {
46317
46354
  return false;
46318
46355
  }
46319
46356
  return true;
46320
46357
  }
46321
- function commonSemanticAssignableType(left, right) {
46358
+ function commonSemanticAssignableType(left, right, environment) {
46322
46359
  if (left === void 0) return right;
46323
46360
  if (right === void 0) return left;
46324
46361
  if (left.name === "null" && right.name === "null") return left;
@@ -46339,8 +46376,8 @@ function commonSemanticAssignableType(left, right) {
46339
46376
  nullable: left.nullable === true || right.nullable === true
46340
46377
  };
46341
46378
  }
46342
- if (semanticTypesAssignable(left, right)) return right;
46343
- if (semanticTypesAssignable(right, left)) return left;
46379
+ if (semanticTypesAssignable(left, right, environment)) return right;
46380
+ if (semanticTypesAssignable(right, left, environment)) return left;
46344
46381
  return void 0;
46345
46382
  }
46346
46383
  function constructionTypesAssignable(actual, expected, scope, environment) {
@@ -46515,6 +46552,14 @@ function validateInlineAnnotation(annotation2, environment, uri, range2, diagnos
46515
46552
  diagnostics
46516
46553
  );
46517
46554
  }
46555
+ function qualifiedEnumReceiver(expression, scope, environment) {
46556
+ if (expression.kind !== "member") return void 0;
46557
+ if (expression.receiver.kind !== "ident") return void 0;
46558
+ const name = expression.receiver.name;
46559
+ if (scope.has(name)) return void 0;
46560
+ if (environment.globals.has(name)) return void 0;
46561
+ return environment.enums.get(name);
46562
+ }
46518
46563
  function inferExpressionType(expression, scope, environment) {
46519
46564
  if (expression.kind === "annotated")
46520
46565
  return inferExpressionType(expression.expression, scope, environment);
@@ -46567,12 +46612,11 @@ function inferExpressionType(expression, scope, environment) {
46567
46612
  scope,
46568
46613
  environment
46569
46614
  );
46570
- return commonSemanticAssignableType(whenTrue, whenFalse);
46615
+ return commonSemanticAssignableType(whenTrue, whenFalse, environment);
46571
46616
  }
46572
46617
  if (expression.kind === "member") {
46573
- if (expression.receiver.kind === "ident" && environment.enums.has(expression.receiver.name)) {
46574
- return { name: expression.receiver.name };
46575
- }
46618
+ const enumeration = qualifiedEnumReceiver(expression, scope, environment);
46619
+ if (enumeration !== void 0) return { name: enumeration.name };
46576
46620
  const receiverType = inferExpressionType(
46577
46621
  expression.receiver,
46578
46622
  scope,
@@ -52896,7 +52940,7 @@ var init_registry = __esm({
52896
52940
  "../packages/manifest/schema-contract/registry.mjs"() {
52897
52941
  "use strict";
52898
52942
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
52899
- cliVersion: "0.76.2",
52943
+ cliVersion: "0.76.3",
52900
52944
  projectFileUploadBatchSize: 32,
52901
52945
  documentRecords: {
52902
52946
  member: {
@@ -62877,7 +62921,7 @@ function collectDerivedBodySites(recordKind, record7) {
62877
62921
  });
62878
62922
  }
62879
62923
  if (record7.kind === 25 /* NSDelegate */) {
62880
- collectDelegateClosureSite(asRecord2(record7.defaultValue), sites, false);
62924
+ collectDelegateClosureSite(asRecord2(record7.defaultValue), sites, true);
62881
62925
  }
62882
62926
  collectInitializerSite(asRecord2(record7.defaultValue), sites);
62883
62927
  return sites;
@@ -66018,10 +66062,15 @@ var init_lookup_declared_type = __esm({
66018
66062
  });
66019
66063
 
66020
66064
  // ../packages/neoscript-runtime/src/values/member-declared-type-info.ts
66021
- function resolveMemberDeclaredTypeInfo(member, members) {
66022
- return resolveMemberDeclaredTypeInfoInternal(member, members, /* @__PURE__ */ new Set());
66065
+ function resolveMemberDeclaredTypeInfo(member, members, ownerClass = null) {
66066
+ return resolveMemberDeclaredTypeInfoInternal(
66067
+ member,
66068
+ members,
66069
+ /* @__PURE__ */ new Set(),
66070
+ ownerClass
66071
+ );
66023
66072
  }
66024
- function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
66073
+ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass) {
66025
66074
  const resolved = resolveMember(member, members);
66026
66075
  const memberId = getField(resolved, "id");
66027
66076
  if (typeof memberId === "string" && seen.has(memberId)) return null;
@@ -66039,7 +66088,8 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
66039
66088
  const argumentType = resolveMemberDeclaredTypeInfoInternal(
66040
66089
  argumentMember,
66041
66090
  members,
66042
- nextSeen
66091
+ nextSeen,
66092
+ ownerClass
66043
66093
  );
66044
66094
  return argumentType === null ? [] : [[genericParamId, argumentType]];
66045
66095
  }
@@ -66105,7 +66155,8 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
66105
66155
  const entryTypeInfo = resolveMemberDeclaredTypeInfoInternal(
66106
66156
  entry,
66107
66157
  members,
66108
- nextSeen
66158
+ nextSeen,
66159
+ ownerClass
66109
66160
  );
66110
66161
  if (entryTypeInfo === null) return null;
66111
66162
  return {
@@ -66122,12 +66173,29 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
66122
66173
  if (collection === void 0) return null;
66123
66174
  return lookupDeclaredTypeInfo2(
66124
66175
  resolved,
66125
- resolveMemberDeclaredTypeInfoInternal(collection, members, nextSeen)
66176
+ resolveMemberDeclaredTypeInfoInternal(
66177
+ collection,
66178
+ members,
66179
+ nextSeen,
66180
+ ownerClass
66181
+ )
66126
66182
  );
66127
66183
  }
66128
66184
  if (resolved.kind === 9 /* Lookup */) return null;
66129
66185
  if (!memberKindSupportsStorage(resolved.kind)) return null;
66130
- if (resolved.kind === 21 /* Generic */) return null;
66186
+ if (isMemberGenericBase(resolved)) {
66187
+ if (ownerClass === null) return null;
66188
+ const declaration = ownerClass.genericParams?.find(
66189
+ (parameter4) => parameter4.id === resolved.genericParamId
66190
+ );
66191
+ if (declaration === void 0) return null;
66192
+ return {
66193
+ type: 21 /* Generic */,
66194
+ required: isRequiredMember(resolved),
66195
+ ownerClassId: ownerClass.id,
66196
+ genericParamId: declaration.id
66197
+ };
66198
+ }
66131
66199
  return {
66132
66200
  type: resolved.kind,
66133
66201
  required: isRequiredMember(resolved)
@@ -69840,6 +69908,8 @@ function compileDelegateClosureValue(code, signature) {
69840
69908
  variants: [...signature.variants ?? []],
69841
69909
  variantFolders: [...signature.variantFolders ?? []],
69842
69910
  thisClass: signature.thisClass,
69911
+ implicitMemberAccess: true,
69912
+ staticMember: signature.staticMember,
69843
69913
  returnTypeInfo: {
69844
69914
  type: 25 /* NSDelegate */,
69845
69915
  required: true,
@@ -70097,7 +70167,11 @@ function compileMemberInitializerBody(args) {
70097
70167
  );
70098
70168
  }
70099
70169
  const members = replaceMember(args.members, args.member);
70100
- const returnTypeInfo = resolveMemberDeclaredTypeInfo(args.member, members) ?? initializerGenericTypeInfo(args.member, args.thisClass);
70170
+ const returnTypeInfo = resolveMemberDeclaredTypeInfo(
70171
+ args.member,
70172
+ members,
70173
+ args.thisClass
70174
+ );
70101
70175
  if (returnTypeInfo === null) {
70102
70176
  throw new Error(
70103
70177
  `Member "${args.member.name}" has an initializer but no resolvable declared type.`
@@ -70131,19 +70205,6 @@ function compileMemberInitializerBody(args) {
70131
70205
  }
70132
70206
  Object.assign(defaultValue.init, { compiled });
70133
70207
  }
70134
- function initializerGenericTypeInfo(member, ownerClass) {
70135
- if (!isMemberGenericBase(member) || ownerClass === null) return null;
70136
- const declaration = ownerClass.genericParams?.find(
70137
- (parameter4) => parameter4.id === member.genericParamId
70138
- );
70139
- if (declaration === void 0) return null;
70140
- return {
70141
- type: 21 /* Generic */,
70142
- required: isRequiredMember(member),
70143
- ownerClassId: ownerClass.id,
70144
- genericParamId: declaration.id
70145
- };
70146
- }
70147
70208
  function compileValueRowInitializerBody(args) {
70148
70209
  const container = args.valueRow;
70149
70210
  if (!isInitValueContent(container)) return;
@@ -70223,12 +70284,25 @@ function compileMemberDelegateDefault(args) {
70223
70284
  if (defaultValue === void 0 || !isLiteralValueContent(defaultValue) || !isNSDelegateClosureValueDraft(defaultValue.value)) {
70224
70285
  return;
70225
70286
  }
70226
- defaultValue.value = compileDelegateClosureValue(defaultValue.value.code, {
70227
- ...args,
70228
- returnTypeInfo: args.member.returnTypeInfo,
70229
- argumentTypes: args.member.argumentTypes,
70230
- name: args.member.name
70231
- });
70287
+ const code = defaultValue.value.code;
70288
+ try {
70289
+ defaultValue.value = compileDelegateClosureValue(code, {
70290
+ ...args,
70291
+ staticMember: isStaticMember(args.member),
70292
+ returnTypeInfo: args.member.returnTypeInfo,
70293
+ argumentTypes: args.member.argumentTypes,
70294
+ name: args.member.name
70295
+ });
70296
+ } catch (error) {
70297
+ throwNamedBodyCompileFailure({
70298
+ error,
70299
+ memberId: args.member.id,
70300
+ memberName: args.member.name,
70301
+ valueId: null,
70302
+ code,
70303
+ codePosition: delegateClosureCodePosition
70304
+ });
70305
+ }
70232
70306
  }
70233
70307
  function compileConstructorRecord(args) {
70234
70308
  const owner = args.classes.find(
@@ -71361,21 +71435,16 @@ function classifyUnattributableRead(reason) {
71361
71435
  }
71362
71436
  return { scope: "corpus" /* Corpus */ };
71363
71437
  }
71364
- var OWNERSHIP_CHAIN_PREFIXES, CONTAINER_ENTRIES_PREFIX, OWNERSHIP_CHAIN_READ;
71438
+ var OWNERSHIP_CHAIN_PREFIXES, CONTAINER_ENTRIES_PREFIX;
71365
71439
  var init_unattributable_reads = __esm({
71366
71440
  "../packages/neoscript-runtime/src/neoscript/unattributable-reads.ts"() {
71367
71441
  "use strict";
71368
71442
  OWNERSHIP_CHAIN_PREFIXES = [
71369
71443
  "generic-parent-resolution:",
71370
71444
  "member-owner-resolution:",
71371
- "owned-value-parents:",
71372
- "declaration-owner-resolution:"
71445
+ "owned-value-parents:"
71373
71446
  ];
71374
71447
  CONTAINER_ENTRIES_PREFIX = "container-entries:";
71375
- OWNERSHIP_CHAIN_READ = ownershipChainRead(
71376
- "member-owner-resolution",
71377
- "*"
71378
- );
71379
71448
  }
71380
71449
  });
71381
71450
 
@@ -71394,12 +71463,13 @@ function valueIdsWithSourceChains(targetValueIds, valuesById) {
71394
71463
  }
71395
71464
  return result;
71396
71465
  }
71397
- function initializerOwnerContext(document, valueId, rootOwners, valuesById) {
71466
+ function initializerOwnerContext(document, valueId, rootOwners, valuesById, recordValueRead) {
71398
71467
  const visited = /* @__PURE__ */ new Set();
71399
71468
  let currentId = valueId;
71400
71469
  let lexicalRoot = rootOwners.get(valueId);
71401
71470
  while (currentId !== null && !visited.has(currentId)) {
71402
71471
  visited.add(currentId);
71472
+ recordValueRead?.(currentId);
71403
71473
  const sourceValueId = valuesById.get(currentId)?.sourceValueId;
71404
71474
  if (typeof sourceValueId !== "string") break;
71405
71475
  currentId = sourceValueId;
@@ -72330,9 +72400,8 @@ var init_initializer_context = __esm({
72330
72400
  /**
72331
72401
  * The unattributable reads by scope, for a fork of the same document to
72332
72402
  * re-attribute; see {@link classifyUnattributableRead}. Ownership-chain
72333
- * reads collapse to one flag: their inputs are already in `valueIds`.
72403
+ * reads need no record: their inputs are already in `valueIds`.
72334
72404
  */
72335
- hasOwnershipChainRead = false;
72336
72405
  containerEntryReadIds = /* @__PURE__ */ new Set();
72337
72406
  corpusReadReasons = /* @__PURE__ */ new Set();
72338
72407
  recordUnattributableValueRead = (reason) => {
@@ -72340,7 +72409,6 @@ var init_initializer_context = __esm({
72340
72409
  const read = classifyUnattributableRead(reason);
72341
72410
  switch (read.scope) {
72342
72411
  case "ownership-chain" /* OwnershipChain */:
72343
- this.hasOwnershipChainRead = true;
72344
72412
  return;
72345
72413
  case "container" /* Container */:
72346
72414
  this.containerEntryReadIds.add(read.containerId);
@@ -72375,6 +72443,10 @@ function getWorldGridQueryIndex(source) {
72375
72443
  building.delete(source.cacheKey);
72376
72444
  }
72377
72445
  }
72446
+ function readsAny(reads, ids) {
72447
+ for (const id2 of ids) if (reads.has(id2)) return true;
72448
+ return false;
72449
+ }
72378
72450
  function buildIndex(source) {
72379
72451
  const reads = new InitializerReadSet();
72380
72452
  const relations = createEffectiveClassRelationResolver(source);
@@ -72456,8 +72528,13 @@ function buildIndex(source) {
72456
72528
  occupiedCells += 1;
72457
72529
  };
72458
72530
  const discoveryReads = new InitializerReadSet();
72531
+ const placedRecordIds = /* @__PURE__ */ new Set();
72459
72532
  for (const root of source.rows) {
72460
- const grid = typeof root.classId !== "string" ? source.readRow(root.id, discoveryReads) : root;
72533
+ let grid = root;
72534
+ if (typeof root.classId !== "string") {
72535
+ if (record5(root.value) !== null) placedRecordIds.add(root.id);
72536
+ grid = source.readRow(root.id, discoveryReads);
72537
+ }
72461
72538
  if (typeof grid?.classId !== "string" || kinds.get(grid.classId) !== NeoWorldSystemClassKind.TileGrid)
72462
72539
  continue;
72463
72540
  const effectiveGrid = readRow(root.id);
@@ -72550,11 +72627,18 @@ function buildIndex(source) {
72550
72627
  }
72551
72628
  }
72552
72629
  }
72553
- return new WorldGridQueryIndex(grids, placements, reads, {
72554
- rowsScanned: source.rows.length,
72555
- placementsIndexed,
72556
- occupiedCells
72557
- });
72630
+ return new WorldGridQueryIndex(
72631
+ grids,
72632
+ placements,
72633
+ reads,
72634
+ kinds,
72635
+ placedRecordIds,
72636
+ {
72637
+ rowsScanned: source.rows.length,
72638
+ placementsIndexed,
72639
+ occupiedCells
72640
+ }
72641
+ );
72558
72642
  }
72559
72643
  function record5(value) {
72560
72644
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -72618,16 +72702,56 @@ var init_world_grid_query = __esm({
72618
72702
  indexes2 = /* @__PURE__ */ new WeakMap();
72619
72703
  building = /* @__PURE__ */ new WeakSet();
72620
72704
  WorldGridQueryIndex = class {
72621
- constructor(grids, placements, geometryReads, metrics) {
72705
+ constructor(grids, placements, geometryReads, kinds, placedRecordIds, metrics) {
72622
72706
  this.grids = grids;
72623
72707
  this.placements = placements;
72624
72708
  this.geometryReads = geometryReads;
72709
+ this.kinds = kinds;
72710
+ this.placedRecordIds = placedRecordIds;
72625
72711
  this.metrics = metrics;
72626
72712
  }
72627
72713
  grids;
72628
72714
  placements;
72629
72715
  geometryReads;
72716
+ kinds;
72717
+ placedRecordIds;
72630
72718
  metrics;
72719
+ /**
72720
+ * Whether edits to these rows can change the index. Ownership-chain reads
72721
+ * need no flag: every ancestor they visit is in `geometryReads.valueIds`.
72722
+ * Discovery checks every row's effective class without recording a read,
72723
+ * so a changed row it could now index as a grid counts as well. A record it
72724
+ * classed by placement keeps that placement through its own writes, so only
72725
+ * its stamp can change.
72726
+ */
72727
+ readsValues(valueIds, classIdOf, stampOf) {
72728
+ const reads = this.geometryReads;
72729
+ if (reads.corpusReadReasons.size > 0) return true;
72730
+ for (const id2 of valueIds) {
72731
+ if (reads.valueIds.has(id2)) return true;
72732
+ const classId = this.placedRecordIds.has(id2) ? stampOf(id2) : classIdOf(id2);
72733
+ if (classId !== null && this.kinds.get(classId) === NeoWorldSystemClassKind.TileGrid)
72734
+ return true;
72735
+ }
72736
+ return false;
72737
+ }
72738
+ /** Whether entry changes in these containers can change the index. */
72739
+ readsContainers(containerIds) {
72740
+ const reads = this.geometryReads;
72741
+ for (const id2 of containerIds) {
72742
+ if (reads.containerIds.has(id2)) return true;
72743
+ if (reads.containerEntryReadIds.has(id2)) return true;
72744
+ }
72745
+ return false;
72746
+ }
72747
+ /** Whether edits to these localized texts can change the index. */
72748
+ readsLocalizedTexts(textIds) {
72749
+ return readsAny(this.geometryReads.localizedTextIds, textIds);
72750
+ }
72751
+ /** Whether edits to these variants can change the index. */
72752
+ readsVariants(variantIds) {
72753
+ return readsAny(this.geometryReads.variantIds, variantIds);
72754
+ }
72631
72755
  placement(valueId, reads) {
72632
72756
  reads?.add({ kind: "placement", valueId });
72633
72757
  const matches = this.placements.get(valueId) ?? [];
@@ -74111,8 +74235,8 @@ function evaluatorResolutionCache(ctx) {
74111
74235
  compiledFunctionByMemberId: /* @__PURE__ */ new Map(),
74112
74236
  compiledGetterByMemberId: /* @__PURE__ */ new Map(),
74113
74237
  compiledSetterByMemberId: /* @__PURE__ */ new Map(),
74114
- defaultValueResolutionCache: createDefaultValueResolutionCache(),
74115
- validatedConstructorDescriptorByInfo: /* @__PURE__ */ new WeakMap(),
74238
+ defaultSchema: createDefaultSchemaResolutionCache(),
74239
+ valueGenerations: /* @__PURE__ */ new WeakMap(),
74116
74240
  effectiveStorageResolver: void 0
74117
74241
  };
74118
74242
  resolutionCacheByMembers.set(members, {
@@ -74151,6 +74275,24 @@ function cachedInstanceEnv(classId, classArguments2, ctx) {
74151
74275
  function cachedIsInitValueContent(value, ctx) {
74152
74276
  return evaluatorDefaultValueDocument(ctx).isInitValueContent(value);
74153
74277
  }
74278
+ function evaluatorValueGeneration(ctx) {
74279
+ const { values, databaseVM } = ctx.vm;
74280
+ const valueGeneration = databaseVM?.valueGeneration;
74281
+ const resolution = evaluatorResolutionCache(ctx);
74282
+ const key = databaseVM ?? values;
74283
+ const entry = resolution.valueGenerations.get(key);
74284
+ if (entry !== void 0 && entry.values === values && entry.valueGeneration === valueGeneration) {
74285
+ return entry;
74286
+ }
74287
+ const generation = {
74288
+ values,
74289
+ valueGeneration,
74290
+ defaults: createDefaultValueResolutionCache(resolution.defaultSchema),
74291
+ constructorDescriptors: /* @__PURE__ */ new WeakMap()
74292
+ };
74293
+ resolution.valueGenerations.set(key, generation);
74294
+ return generation;
74295
+ }
74154
74296
  function evaluatorDefaultValueDocument(ctx) {
74155
74297
  if (ctx.__defaultValueDocument !== void 0) {
74156
74298
  return ctx.__defaultValueDocument;
@@ -74171,7 +74313,7 @@ function evaluatorDefaultValueDocument(ctx) {
74171
74313
  projectFiles: ctx.vm.projectFiles ?? [],
74172
74314
  textureTemplates: ctx.vm.textureTemplates ?? []
74173
74315
  },
74174
- { cache: evaluatorResolutionCache(ctx).defaultValueResolutionCache }
74316
+ { cache: evaluatorValueGeneration(ctx).defaults }
74175
74317
  );
74176
74318
  ctx.__defaultValueDocument = document;
74177
74319
  return document;
@@ -76596,8 +76738,12 @@ function bindOmittedConstantSlot(destination, member, value, ctx) {
76596
76738
  if (isMemberClassBase(member) || isMemberListBase(member) || isMemberDictionaryBase(member))
76597
76739
  return false;
76598
76740
  const resolved = resolveMember(member, ctx.vm.members);
76599
- if (!isConstantMember(constructorDefaultValueDocument(ctx, member), resolved))
76600
- return false;
76741
+ const decision = constantMemberDecision(
76742
+ constructorDefaultValueDocument(ctx, member),
76743
+ resolved
76744
+ );
76745
+ recordDeclarationReads(ctx, decision.reads);
76746
+ if (!decision.constant) return false;
76601
76747
  const { createdValues } = construction;
76602
76748
  const staged = createdValues.length;
76603
76749
  const row = materializeConstructorArgumentValue({
@@ -78979,6 +79125,17 @@ function ensureVirtualExpansionIndexed(rows, ctx, existingIndexes) {
78979
79125
  );
78980
79126
  indexes3.indexedVirtualRowSets.add(rows);
78981
79127
  }
79128
+ function recordDeclarationReads(ctx, reads) {
79129
+ for (const id2 of reads.valueIds) ctx.valueDependencies?.add(id2);
79130
+ for (const id2 of reads.containerIds) ctx.containerDependencies?.add(id2);
79131
+ }
79132
+ function constantMemberDecision(document, member) {
79133
+ const reads = {
79134
+ valueIds: /* @__PURE__ */ new Set(),
79135
+ containerIds: /* @__PURE__ */ new Set()
79136
+ };
79137
+ return { constant: isConstantMember(document, member, reads), reads };
79138
+ }
78982
79139
  function readDeclarationDefault(member, ctx) {
78983
79140
  if (member?.defaultValue === void 0 || member.defaultValue === null) {
78984
79141
  return { matched: false };
@@ -78993,16 +79150,20 @@ function readDeclarationDefault(member, ctx) {
78993
79150
  constantDeclarationRoots.set(session, shared);
78994
79151
  }
78995
79152
  }
78996
- const known = shared?.get(member.id);
78997
- if (typeof known === "string" && session?.has(known) === true) {
79153
+ let known = shared?.get(member.id);
79154
+ if (known !== void 0) recordDeclarationReads(ctx, known.reads);
79155
+ if (known?.root !== void 0 && session?.has(known.root) === true) {
78998
79156
  return {
78999
79157
  matched: true,
79000
- value: resolveValueIfIdForMember(known, member, ctx)
79158
+ value: resolveValueIfIdForMember(known.root, member, ctx)
79001
79159
  };
79002
79160
  }
79003
79161
  const document = constructorDefaultValueDocument(ctx, member);
79004
- const constant = shared !== void 0 && known !== false && (known !== void 0 || isConstantMember(document, member));
79005
- if (shared !== void 0 && !constant) shared.set(member.id, false);
79162
+ if (shared !== void 0 && known === void 0) {
79163
+ known = constantMemberDecision(document, member);
79164
+ recordDeclarationReads(ctx, known.reads);
79165
+ shared.set(member.id, known);
79166
+ }
79006
79167
  const created = [];
79007
79168
  const closeFrame = pushConstructionFrame(ctx, `${member.name} declaration`);
79008
79169
  try {
@@ -79028,7 +79189,7 @@ function readDeclarationDefault(member, ctx) {
79028
79189
  )
79029
79190
  });
79030
79191
  stageConstructedRows([root, ...created], ctx);
79031
- if (constant) shared?.set(member.id, root.id);
79192
+ if (known?.constant === true) known.root = root.id;
79032
79193
  return {
79033
79194
  matched: true,
79034
79195
  value: resolveValueIfIdForMember(root.id, member, ctx)
@@ -79352,6 +79513,10 @@ function resolveMemberForValueRow(row, ctx, visited) {
79352
79513
  function worldGridQueryIndexForContext(context) {
79353
79514
  const ctx = withEvaluationRuntime(context, []);
79354
79515
  const vm = ctx.vm;
79516
+ const database = vm.databaseVM;
79517
+ const overlayRevision = ctx.__valueOverlay instanceof LazyValueOverlay ? ctx.__valueOverlay.worldRevision : 0;
79518
+ if (overlayRevision === 0 && database?.worldGridQueryIndex !== void 0)
79519
+ return database.worldGridQueryIndex();
79355
79520
  const readContexts = /* @__PURE__ */ new WeakMap();
79356
79521
  let geometryOverlay;
79357
79522
  const readContext = (reads) => {
@@ -79374,24 +79539,26 @@ function worldGridQueryIndexForContext(context) {
79374
79539
  readContexts.set(reads, next);
79375
79540
  return next;
79376
79541
  };
79377
- const overlayRevision = ctx.__valueOverlay instanceof LazyValueOverlay ? ctx.__valueOverlay.worldRevision : 0;
79542
+ const recording = (reads, read) => database?.recordVirtualInstanceReads === void 0 ? read() : database.recordVirtualInstanceReads(reads, read);
79543
+ const host = vm.worldQueryCache;
79378
79544
  return getWorldGridQueryIndex({
79379
- cacheKey: overlayRevision > 0 && ctx.__valueOverlay !== void 0 ? ctx.__valueOverlay : vm.worldQueryCache?.key ?? vm.databaseVM?.evaluatorIndexes ?? vm.values,
79545
+ cacheKey: overlayRevision > 0 && ctx.__valueOverlay !== void 0 ? ctx.__valueOverlay : host?.key ?? vm.databaseVM?.evaluatorIndexes ?? vm.values,
79380
79546
  revision: [
79381
- ...vm.worldQueryCache?.revision ?? vm.databaseVM?.worldQueryRevision ?? [],
79382
- vm.values,
79383
- vm.classes,
79384
- vm.members,
79385
- vm.internalRecordRelations,
79386
- vm.variants,
79387
- vm.variantFolders,
79388
- vm.schemaRevision,
79547
+ ...host?.revision ?? [
79548
+ vm.values,
79549
+ vm.classes,
79550
+ vm.members,
79551
+ vm.internalRecordRelations,
79552
+ vm.variants,
79553
+ vm.variantFolders,
79554
+ vm.schemaRevision
79555
+ ],
79389
79556
  ...overlayRevision === 0 ? [] : [ctx.__valueOverlay, overlayRevision]
79390
79557
  ],
79391
79558
  rows: vm.values,
79392
79559
  classes: vm.classes,
79393
79560
  relations: vm.internalRecordRelations ?? [],
79394
- readRow(id2, reads) {
79561
+ readRow: (id2, reads) => recording(reads, () => {
79395
79562
  const current = readContext(reads);
79396
79563
  const row = evalValueById(
79397
79564
  current,
@@ -79402,8 +79569,8 @@ function worldGridQueryIndexForContext(context) {
79402
79569
  if (row === null || typeof row.classId === "string") return row;
79403
79570
  const classId = classIdForValueRow(row, current);
79404
79571
  return classId === void 0 ? row : { ...row, classId };
79405
- },
79406
- readField(id2, key, reads) {
79572
+ }),
79573
+ readField: (id2, key, reads) => recording(reads, () => {
79407
79574
  const current = readContext(reads);
79408
79575
  const row = evalValueById(
79409
79576
  current,
@@ -79422,8 +79589,8 @@ function worldGridQueryIndexForContext(context) {
79422
79589
  thisValue: row.value,
79423
79590
  thisValueRowId: row.id
79424
79591
  });
79425
- },
79426
- valueId(value, reads) {
79592
+ }),
79593
+ valueId: (value, reads) => recording(reads, () => {
79427
79594
  const current = readContext(reads);
79428
79595
  if (typeof value === "string" && evalValueById(
79429
79596
  current,
@@ -79433,7 +79600,7 @@ function worldGridQueryIndexForContext(context) {
79433
79600
  ) !== null)
79434
79601
  return value;
79435
79602
  return trackedRowForValueReference(value, current)?.id ?? null;
79436
- }
79603
+ })
79437
79604
  });
79438
79605
  }
79439
79606
  function readSystemNativeField(value, key, ctx) {
@@ -81059,7 +81226,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
81059
81226
  }
81060
81227
  const genericSlot = ctx.__constructionGenericSlots?.toReversed().find((slot) => slot.classId === classId) ?? ctx.__storedConstructionReplaySlot;
81061
81228
  const slotArguments = genericSlot?.classId === classId ? genericSlot.classArguments : void 0;
81062
- const descriptorCache = evaluatorResolutionCache(ctx).validatedConstructorDescriptorByInfo;
81229
+ const descriptorCache = evaluatorValueGeneration(ctx).constructorDescriptors;
81063
81230
  const descriptorCacheKey = `${requireEveryRequiredField}:${ctx.storedConstructionReplay === true}:${JSON.stringify(slotArguments ?? info.schemaClassInfo.typeArguments ?? null)}`;
81064
81231
  const cachedDescriptor = descriptorCache.get(info)?.get(descriptorCacheKey);
81065
81232
  if (cachedDescriptor !== void 0) return cachedDescriptor;
@@ -81676,6 +81843,8 @@ function constructClassValue(info, scope, ctx) {
81676
81843
  }
81677
81844
  }
81678
81845
  function constructorDefaultValueDocument(ctx, syntheticMember2) {
81846
+ const database = ctx.vm.databaseVM;
81847
+ const entryIdsOf = database?.unorderedListEntryIds?.bind(database);
81679
81848
  return {
81680
81849
  listenerDefaultCapture: ctx.listenerDefaultCapture,
81681
81850
  beforeValueAllocation: ctx.beforeValueAllocation,
@@ -81688,11 +81857,24 @@ function constructorDefaultValueDocument(ctx, syntheticMember2) {
81688
81857
  // immutable base plus its indexes avoids copying and linearly scanning
81689
81858
  // the entire project for every constructor replay.
81690
81859
  values: ctx.vm.values,
81691
- memberById: ctx.vm.databaseVM?.memberById,
81692
- valueById: ctx.vm.databaseVM?.defaultValueById ?? ctx.vm.databaseVM?.valueById,
81860
+ memberById: database?.memberById,
81861
+ // The declaration rows a default clones are reads of this evaluation.
81862
+ ...database === void 0 ? {} : {
81863
+ valueById: (id2) => {
81864
+ ctx.valueDependencies?.add(id2);
81865
+ return database.defaultValueById !== void 0 ? database.defaultValueById(id2) : database.valueById(id2);
81866
+ }
81867
+ },
81868
+ ...entryIdsOf === void 0 ? {} : {
81869
+ unorderedListEntryIds: (containerId) => {
81870
+ ctx.containerDependencies?.add(containerId);
81871
+ return entryIdsOf(containerId);
81872
+ }
81873
+ },
81693
81874
  resolvedMember: (member) => member === syntheticMember2 ? syntheticMember2 : cachedResolvedMember(member, ctx),
81694
81875
  storedInstanceSchema: (nestedClassId) => cachedStoredInstanceSchema(nestedClassId, ctx),
81695
81876
  storedInstanceMaterializationPlan: (nestedClassId, instanceEnv) => cachedStoredInstanceMaterializationPlan(nestedClassId, instanceEnv, ctx),
81877
+ recordPlanReads: (reads) => recordDeclarationReads(ctx, reads),
81696
81878
  instanceEnv: (nestedClassId, classArguments2) => cachedInstanceEnv(nestedClassId, classArguments2, ctx),
81697
81879
  isInitValueContent: (value) => cachedIsInitValueContent(value, ctx),
81698
81880
  createValueRow: (projectId, body) => buildNewValue(
@@ -86537,43 +86719,50 @@ function claimVirtualIdentity(args) {
86537
86719
  args.claimedVirtualIds.set(virtualId, args.pathKey);
86538
86720
  return { sourceIdentity: sourceIdentity3, virtualId };
86539
86721
  }
86540
- function expandStoredInstance(args) {
86541
- const recorder = args.readRecorder ?? null;
86542
- const readTracking = recorder === null ? void 0 : new InitializerReadSet();
86543
- const trackMaterialization = readTracking === void 0 ? (materialize) => materialize() : (materialize) => {
86722
+ function materializationReadTracking(recorder) {
86723
+ if (recorder === void 0)
86724
+ return { readTracking: void 0, trackMaterialization: (m) => m() };
86725
+ const readTracking = new InitializerReadSet();
86726
+ const trackMaterialization = (materialize) => {
86544
86727
  try {
86545
86728
  return materialize();
86546
86729
  } finally {
86547
86730
  for (const valueId of readTracking.valueIds) {
86548
- recorder?.recordValueRead(valueId);
86731
+ recorder.recordValueRead(valueId);
86549
86732
  }
86550
86733
  for (const textId of readTracking.localizedTextIds) {
86551
- recorder?.recordLocalizedTextRead(textId);
86734
+ recorder.recordLocalizedTextRead(textId);
86552
86735
  }
86553
86736
  for (const variantId of readTracking.variantIds) {
86554
- recorder?.recordVariantRead(variantId);
86737
+ recorder.recordVariantRead(variantId);
86555
86738
  }
86556
86739
  for (const memberId of readTracking.staticMemberIds) {
86557
- recorder?.recordStaticMemberRead(memberId);
86740
+ recorder.recordStaticMemberRead(memberId);
86558
86741
  }
86559
86742
  for (const containerId of readTracking.containerIds) {
86560
- recorder?.recordContainerMembershipRead(containerId);
86743
+ recorder.recordContainerMembershipRead(containerId);
86561
86744
  }
86562
86745
  for (const read of readTracking.worldQueries) {
86563
- recorder?.recordWorldQueryRead?.(read);
86746
+ recorder.recordWorldQueryRead?.(read);
86564
86747
  }
86565
- if (readTracking.hasOwnershipChainRead) {
86566
- recorder?.recordGlobalRead(OWNERSHIP_CHAIN_READ);
86748
+ if (readTracking.hasValuePlacementRead) {
86749
+ recorder.recordValuePlacementRead();
86567
86750
  }
86568
86751
  for (const containerId of readTracking.containerEntryReadIds) {
86569
- recorder?.recordGlobalRead(containerEntriesRead(containerId));
86752
+ recorder.recordContainerMembershipRead(containerId);
86570
86753
  }
86571
86754
  for (const reason of readTracking.corpusReadReasons) {
86572
- recorder?.recordGlobalRead(reason);
86755
+ recorder.recordGlobalRead(reason);
86573
86756
  }
86574
86757
  }
86575
86758
  };
86576
- recorder?.recordValueRead(args.instanceRoot.id);
86759
+ return { readTracking, trackMaterialization };
86760
+ }
86761
+ function expandStoredInstance(args) {
86762
+ const { readTracking, trackMaterialization } = materializationReadTracking(
86763
+ args.readRecorder
86764
+ );
86765
+ args.readRecorder?.recordValueRead(args.instanceRoot.id);
86577
86766
  const rootMember = resolveMember(args.rootMember, args.document.members);
86578
86767
  if (!isMemberClassBase(rootMember)) {
86579
86768
  throw new Error(
@@ -86609,11 +86798,6 @@ function expandStoredInstance(args) {
86609
86798
  `Virtual expansion root "${args.instanceRoot.id}" is missing required constructor arguments.`
86610
86799
  );
86611
86800
  }
86612
- const constructorArguments4 = storedConstructorReplayArguments(
86613
- requiredConstructor,
86614
- storedArgs,
86615
- instanceRoot.id
86616
- );
86617
86801
  const {
86618
86802
  value: _value,
86619
86803
  classId: _classId,
@@ -86634,6 +86818,34 @@ function expandStoredInstance(args) {
86634
86818
  instanceRoot
86635
86819
  );
86636
86820
  const replayMember = closedRootMember === rootMember ? rootMember : { ...closedRootMember, classId };
86821
+ let environment;
86822
+ const constructorArguments4 = storedConstructorReplayArguments(
86823
+ requiredConstructor === null ? null : {
86824
+ ...requiredConstructor,
86825
+ argumentTypes: requiredConstructor.argumentTypes.map((argument2) => {
86826
+ if (argument2.type !== 21 /* Generic */) return argument2;
86827
+ environment ??= resolveInstanceEnv(
86828
+ classId,
86829
+ replayMember.classArguments,
86830
+ args.document.classes
86831
+ );
86832
+ const type = substituteInheritedCallableTypeInfo(
86833
+ argument2,
86834
+ environment,
86835
+ args.document.classes,
86836
+ args.document.members
86837
+ );
86838
+ if (type.type === NS_TYPE_VOID) {
86839
+ throw new Error(
86840
+ `Constructor parameter "${argument2.name}" on "${classId}" cannot have type void.`
86841
+ );
86842
+ }
86843
+ return { ...type, name: argument2.name };
86844
+ })
86845
+ },
86846
+ storedArgs,
86847
+ instanceRoot.id
86848
+ );
86637
86849
  const replay = (fields) => {
86638
86850
  const init = storedConstructorReplayInitializer({
86639
86851
  classId,
@@ -86698,11 +86910,7 @@ function expandStoredInstance(args) {
86698
86910
  function resolveVirtualInstanceGraph(args) {
86699
86911
  const expansion = args.expansionIndex ?? indexExpansion(args);
86700
86912
  const recorder = args.readRecorder ?? null;
86701
- if (recorder !== null) {
86702
- recorder.recordValueRead(args.instanceRoot.id);
86703
- const unattributable = firstUnattributableExpansionMember(expansion);
86704
- if (unattributable !== null) recorder.recordGlobalRead(unattributable);
86705
- }
86913
+ recorder?.recordValueRead(args.instanceRoot.id);
86706
86914
  const materializedById = args.materializedIndex?.rowsById ?? new Map(
86707
86915
  (args.materializedRows ?? args.document.values).map((row) => [
86708
86916
  row.id,
@@ -87257,15 +87465,6 @@ function mergeExpandedAndMaterializedRow(expanded, materialized) {
87257
87465
  if (merged.sourceValueId === materialized.id) delete merged.sourceValueId;
87258
87466
  return merged;
87259
87467
  }
87260
- function firstUnattributableExpansionMember(expansion) {
87261
- for (const node of expansion.nodesByPath.values()) {
87262
- const member = node.member;
87263
- if (CORPUS_SCANNING_MEMBER_KINDS.has(member.kind)) {
87264
- return `corpus-scanning-member-kind:${node.memberId}`;
87265
- }
87266
- }
87267
- return null;
87268
- }
87269
87468
  function recordKeysLost(kept, candidate) {
87270
87469
  if (!isLiteralValueContent(kept)) return [];
87271
87470
  if (!isLiteralValueContent(candidate)) return [];
@@ -87298,9 +87497,10 @@ function prepareStoredClassValueResolution(args) {
87298
87497
  ...args.document,
87299
87498
  // Construction checks share the existing schema index across every nested default.
87300
87499
  memberById: args.document.memberById ?? ((id2) => schema.member(id2) ?? null),
87301
- evaluatorCache: {
87302
- key: initializerEvaluatorCacheKey(args.document),
87303
- revision: initializerEvaluatorCacheRevision(args.document)
87500
+ // The same rows under a fresh object: share its evaluator caches.
87501
+ evaluatorCache: args.document.evaluatorCache ?? {
87502
+ key: args.document,
87503
+ revision: void 0
87304
87504
  },
87305
87505
  listenerDefaultCapture: {
87306
87506
  begin: () => {
@@ -87510,27 +87710,32 @@ function expandStoredClassValue(args) {
87510
87710
  }
87511
87711
  const classId = root.classId ?? member.classId;
87512
87712
  args.readRecorder?.recordValueRead(root.id);
87513
- args.readRecorder?.recordGlobalRead("declaration-default");
87514
- const materialized = materializeMemberDefaultValue({
87515
- saveStaticBindings: args.saveStaticBindings,
87516
- sessionStaticBindings: args.sessionStaticBindings,
87517
- evaluateInitializer: args.evaluateInitializer,
87518
- document: args.document,
87519
- member: closeClassArgumentsFromRowStamp(
87520
- {
87521
- ...member,
87522
- classId,
87523
- defaultValue: derivesContentFromMemberDefault({
87524
- member,
87525
- instanceRoot: root,
87526
- effectiveClassId: classId
87527
- }) ? member.defaultValue : void 0
87528
- },
87529
- root
87530
- ),
87531
- envelope: root,
87532
- declarationRoot: true
87533
- });
87713
+ const { readTracking, trackMaterialization } = materializationReadTracking(
87714
+ args.readRecorder
87715
+ );
87716
+ const materialized = trackMaterialization(
87717
+ () => materializeMemberDefaultValue({
87718
+ ...readTracking === void 0 ? {} : { readTracking },
87719
+ saveStaticBindings: args.saveStaticBindings,
87720
+ sessionStaticBindings: args.sessionStaticBindings,
87721
+ evaluateInitializer: args.evaluateInitializer,
87722
+ document: args.document,
87723
+ member: closeClassArgumentsFromRowStamp(
87724
+ {
87725
+ ...member,
87726
+ classId,
87727
+ defaultValue: derivesContentFromMemberDefault({
87728
+ member,
87729
+ instanceRoot: root,
87730
+ effectiveClassId: classId
87731
+ }) ? member.defaultValue : void 0
87732
+ },
87733
+ root
87734
+ ),
87735
+ envelope: root,
87736
+ declarationRoot: true
87737
+ })
87738
+ );
87534
87739
  return {
87535
87740
  root: { ...root, classId, value: materialized.root.value },
87536
87741
  rows: materialized.createdValues,
@@ -89207,6 +89412,17 @@ function variantSwapDeclaredMember(document, rootValueId) {
89207
89412
  if (placement === void 0) return void 0;
89208
89413
  return document.members.find((member) => member.id === placement.memberId);
89209
89414
  }
89415
+ function emptyExpansionReads() {
89416
+ return {
89417
+ valueIds: /* @__PURE__ */ new Set(),
89418
+ containerIds: /* @__PURE__ */ new Set(),
89419
+ localizedTextIds: /* @__PURE__ */ new Set(),
89420
+ variantIds: /* @__PURE__ */ new Set(),
89421
+ staticMemberIds: /* @__PURE__ */ new Set(),
89422
+ global: false,
89423
+ merged: /* @__PURE__ */ new WeakSet()
89424
+ };
89425
+ }
89210
89426
  function createHeadlessVirtualInstanceResolver(args) {
89211
89427
  const { document } = args;
89212
89428
  const membersById = args.membersById ?? new Map(document.members.map((member) => [member.id, member]));
@@ -89230,16 +89446,22 @@ function createHeadlessVirtualInstanceResolver(args) {
89230
89446
  const emptyRows = [];
89231
89447
  const graphByValueId = /* @__PURE__ */ new Map();
89232
89448
  const failedRootIds = /* @__PURE__ */ new Set();
89449
+ const expandingRootIds = /* @__PURE__ */ new Set();
89233
89450
  const expandedRowById = /* @__PURE__ */ new Map();
89234
89451
  const expandedRowByRecord = /* @__PURE__ */ new WeakMap();
89235
89452
  const readsByRootId = /* @__PURE__ */ new Map();
89236
89453
  const activeReads = [];
89237
89454
  const sharedByReceiverId = /* @__PURE__ */ new Map();
89455
+ const callerReads = /* @__PURE__ */ new WeakMap();
89238
89456
  const mergeReads = (reads) => {
89239
89457
  for (const active of activeReads) {
89240
- if (active === reads) continue;
89458
+ if (active === reads || active.merged.has(reads)) continue;
89459
+ active.merged.add(reads);
89241
89460
  for (const id2 of reads.valueIds) active.valueIds.add(id2);
89242
89461
  for (const id2 of reads.containerIds) active.containerIds.add(id2);
89462
+ for (const id2 of reads.localizedTextIds) active.localizedTextIds.add(id2);
89463
+ for (const id2 of reads.variantIds) active.variantIds.add(id2);
89464
+ for (const id2 of reads.staticMemberIds) active.staticMemberIds.add(id2);
89243
89465
  if (reads.global) active.global = true;
89244
89466
  }
89245
89467
  };
@@ -89248,9 +89470,18 @@ function createHeadlessVirtualInstanceResolver(args) {
89248
89470
  for (const active of activeReads) active.valueIds.add(id2);
89249
89471
  args.readRecorder?.recordValueRead(id2);
89250
89472
  },
89251
- recordLocalizedTextRead: (id2) => args.readRecorder?.recordLocalizedTextRead(id2),
89252
- recordVariantRead: (id2) => args.readRecorder?.recordVariantRead(id2),
89253
- recordStaticMemberRead: (id2) => args.readRecorder?.recordStaticMemberRead(id2),
89473
+ recordLocalizedTextRead: (id2) => {
89474
+ for (const active of activeReads) active.localizedTextIds.add(id2);
89475
+ args.readRecorder?.recordLocalizedTextRead(id2);
89476
+ },
89477
+ recordVariantRead: (id2) => {
89478
+ for (const active of activeReads) active.variantIds.add(id2);
89479
+ args.readRecorder?.recordVariantRead(id2);
89480
+ },
89481
+ recordStaticMemberRead: (id2) => {
89482
+ for (const active of activeReads) active.staticMemberIds.add(id2);
89483
+ args.readRecorder?.recordStaticMemberRead(id2);
89484
+ },
89254
89485
  recordContainerMembershipRead: (id2) => {
89255
89486
  for (const active of activeReads) active.containerIds.add(id2);
89256
89487
  args.readRecorder?.recordContainerMembershipRead(id2);
@@ -89296,6 +89527,7 @@ function createHeadlessVirtualInstanceResolver(args) {
89296
89527
  if (reads2 !== void 0) mergeReads(reads2);
89297
89528
  return cached;
89298
89529
  }
89530
+ if (expandingRootIds.has(rootId)) return emptyRows;
89299
89531
  if (failedRootIds.has(rootId)) return emptyRows;
89300
89532
  const instanceRoot = rawById.get(rootId);
89301
89533
  if (instanceRoot === void 0 || declaredMember === void 0) {
@@ -89311,12 +89543,9 @@ function createHeadlessVirtualInstanceResolver(args) {
89311
89543
  failedRootIds.add(rootId);
89312
89544
  return emptyRows;
89313
89545
  }
89314
- const reads = {
89315
- valueIds: /* @__PURE__ */ new Set(),
89316
- containerIds: /* @__PURE__ */ new Set(),
89317
- global: false
89318
- };
89546
+ const reads = emptyExpansionReads();
89319
89547
  activeReads.push(reads);
89548
+ expandingRootIds.add(rootId);
89320
89549
  try {
89321
89550
  const resolverDocument = resolverDocumentOnce();
89322
89551
  materializedIndex ??= buildVirtualInstanceMaterializedIndex({
@@ -89340,6 +89569,7 @@ function createHeadlessVirtualInstanceResolver(args) {
89340
89569
  failedRootIds.add(rootId);
89341
89570
  return emptyRows;
89342
89571
  } finally {
89572
+ expandingRootIds.delete(rootId);
89343
89573
  activeReads.pop();
89344
89574
  mergeReads(reads);
89345
89575
  }
@@ -89358,9 +89588,15 @@ function createHeadlessVirtualInstanceResolver(args) {
89358
89588
  share.containerChanged
89359
89589
  );
89360
89590
  if (shared === null) return null;
89591
+ recorder.recordValuePlacementRead();
89361
89592
  for (const id2 of shared.reads.valueIds) recorder.recordValueRead(id2);
89362
89593
  for (const id2 of shared.reads.containerIds)
89363
89594
  recorder.recordContainerMembershipRead(id2);
89595
+ for (const id2 of shared.reads.localizedTextIds)
89596
+ recorder.recordLocalizedTextRead(id2);
89597
+ for (const id2 of shared.reads.variantIds) recorder.recordVariantRead(id2);
89598
+ for (const id2 of shared.reads.staticMemberIds)
89599
+ recorder.recordStaticMemberRead(id2);
89364
89600
  if (graphRowsByRootId.get(shared.graph.instanceRootId) === void 0) {
89365
89601
  readsByRootId.set(shared.graph.instanceRootId, shared.reads);
89366
89602
  remember(shared.graph, shared.rows);
@@ -89404,7 +89640,16 @@ function createHeadlessVirtualInstanceResolver(args) {
89404
89640
  return graph?.instanceRootId === rootId ? graph : null;
89405
89641
  },
89406
89642
  virtualInstanceRowsForValue,
89407
- valueById: (id2) => expandedRowById.get(id2) ?? null,
89643
+ valueById: (id2) => {
89644
+ const row = expandedRowById.get(id2);
89645
+ if (row === void 0) return null;
89646
+ if (activeReads.length > 0) {
89647
+ const rootId = graphByValueId.get(id2)?.instanceRootId;
89648
+ const reads = rootId === void 0 ? void 0 : readsByRootId.get(rootId);
89649
+ if (reads !== void 0) mergeReads(reads);
89650
+ }
89651
+ return row;
89652
+ },
89408
89653
  rowForValueReference: (value) => expandedRowByRecord.get(value) ?? null,
89409
89654
  virtualInstanceGraphForValue: (valueId) => {
89410
89655
  const known = graphByValueId.get(valueId);
@@ -89416,11 +89661,7 @@ function createHeadlessVirtualInstanceResolver(args) {
89416
89661
  return graphByValueId.get(valueId) ?? null;
89417
89662
  },
89418
89663
  shareExpansion: (receiverValueId, masked, containerChanged) => {
89419
- const reads = {
89420
- valueIds: /* @__PURE__ */ new Set(),
89421
- containerIds: /* @__PURE__ */ new Set(),
89422
- global: false
89423
- };
89664
+ const reads = emptyExpansionReads();
89424
89665
  activeReads.push(reads);
89425
89666
  let rows;
89426
89667
  try {
@@ -89441,6 +89682,29 @@ function createHeadlessVirtualInstanceResolver(args) {
89441
89682
  );
89442
89683
  }
89443
89684
  return { graph, rows, reads };
89685
+ },
89686
+ recordReads: (target, read) => {
89687
+ let reads = callerReads.get(target);
89688
+ if (reads === void 0) {
89689
+ reads = {
89690
+ valueIds: target.valueIds,
89691
+ containerIds: target.containerIds,
89692
+ localizedTextIds: target.localizedTextIds,
89693
+ variantIds: target.variantIds,
89694
+ staticMemberIds: target.staticMemberIds,
89695
+ global: false,
89696
+ merged: /* @__PURE__ */ new WeakSet()
89697
+ };
89698
+ callerReads.set(target, reads);
89699
+ }
89700
+ activeReads.push(reads);
89701
+ try {
89702
+ return read();
89703
+ } finally {
89704
+ activeReads.pop();
89705
+ if (reads.global)
89706
+ target.recordUnattributableValueRead("virtual-instance-expansion");
89707
+ }
89444
89708
  }
89445
89709
  };
89446
89710
  }
@@ -89456,7 +89720,7 @@ function assertStoredConstructionStamp(root, classId = root.classId) {
89456
89720
  );
89457
89721
  }
89458
89722
  }
89459
- var KEPT_ROW_SAMPLE_LIMIT, CORPUS_SCANNING_MEMBER_KINDS, VirtualExpansionUnsupportedError, ROOT_PATH, OpenGenericComparisonError, SYNTHETIC_LINEAGE_PREFIXES, resolverDocumentsByDocument;
89723
+ var KEPT_ROW_SAMPLE_LIMIT, VirtualExpansionUnsupportedError, ROOT_PATH, OpenGenericComparisonError, SYNTHETIC_LINEAGE_PREFIXES, resolverDocumentsByDocument;
89460
89724
  var init_virtual_instance_graph = __esm({
89461
89725
  "../packages/neoscript-runtime/src/virtual-instance-graph.ts"() {
89462
89726
  "use strict";
@@ -89475,6 +89739,7 @@ var init_virtual_instance_graph = __esm({
89475
89739
  init_member_value_id();
89476
89740
  init_stored_value_placement_index();
89477
89741
  init_unordered_list_membership();
89742
+ init_neoscript_types();
89478
89743
  init_neoscript_guards();
89479
89744
  init_project_schema_index();
89480
89745
  init_initializer_context();
@@ -89482,10 +89747,6 @@ var init_virtual_instance_graph = __esm({
89482
89747
  init_initializer_materialization();
89483
89748
  init_unattributable_reads();
89484
89749
  KEPT_ROW_SAMPLE_LIMIT = 12;
89485
- CORPUS_SCANNING_MEMBER_KINDS = /* @__PURE__ */ new Set([
89486
- 9 /* Lookup */,
89487
- 18 /* DialogueLookup */
89488
- ]);
89489
89750
  VirtualExpansionUnsupportedError = class extends Error {
89490
89751
  constructor(message) {
89491
89752
  super(message);
@@ -89534,6 +89795,10 @@ function initializerEvaluatorLookups(document, readTracking) {
89534
89795
  ...databaseVM.changeListenerDefaultsForOwner === void 0 ? {} : {
89535
89796
  changeListenerDefaultsForOwner: (id2) => databaseVM.changeListenerDefaultsForOwner(id2)
89536
89797
  },
89798
+ // Read live: this wrapper outlives a scalar's nullness change.
89799
+ get valueGeneration() {
89800
+ return databaseVM.valueGeneration;
89801
+ },
89537
89802
  memberById: (id2) => databaseVM.memberById(id2),
89538
89803
  valueById: (id2) => databaseVM.valueById(id2),
89539
89804
  defaultValueById: (id2) => databaseVM.defaultValueById?.(id2) ?? databaseVM.valueById(id2),
@@ -89560,6 +89825,7 @@ function initializerEvaluatorLookups(document, readTracking) {
89560
89825
  return resolved;
89561
89826
  },
89562
89827
  virtualInstanceRowsForValue: (receiverValueId) => databaseVM.virtualInstanceRowsForValue(receiverValueId),
89828
+ ...databaseVM.worldGridQueryIndex === void 0 ? {} : { worldGridQueryIndex: () => databaseVM.worldGridQueryIndex() },
89563
89829
  rowForValueReference: (value) => databaseVM.rowForValueReference?.(value) ?? null,
89564
89830
  resolveVariantInstanceGraph: (args) => {
89565
89831
  const resolver = databaseVM.resolveVariantInstanceGraph;
@@ -89588,88 +89854,45 @@ function initializerEvaluatorLookups(document, readTracking) {
89588
89854
  indexKey,
89589
89855
  revision
89590
89856
  );
89591
- const shareFrom = document.databaseVM === void 0 && document.evaluatorOverlay !== void 0 ? sharedHeadlessResolver(document.evaluatorOverlay) : void 0;
89857
+ const shareFrom = document.evaluatorOverlay === void 0 ? void 0 : sharedHeadlessResolver(document.evaluatorOverlay);
89592
89858
  let hasListenerMetadata;
89593
- const headlessVirtualResolver = document.databaseVM === void 0 ? createHeadlessVirtualInstanceResolver({
89859
+ const headlessVirtualResolver = createHeadlessVirtualInstanceResolver({
89594
89860
  evaluateInitializer: evaluateMemberInitializer,
89595
89861
  document,
89596
89862
  resolverLookups: () => lookups,
89597
89863
  ...shareFrom === void 0 ? {} : { shareFrom },
89598
89864
  ...readTracking === void 0 ? {} : { readRecorder: virtualReadRecorder(readTracking) }
89599
- }) : null;
89865
+ });
89600
89866
  const lookups = {
89601
89867
  ...indexedLookups,
89602
- ...document.databaseVM === void 0 && headlessVirtualResolver !== null ? {
89603
- changeListenerDefaultsForOwner: (id2) => {
89604
- if (!(hasListenerMetadata ??= hasAuthoredChangeListenerMetadata(document)))
89605
- return void 0;
89606
- const inherited = headlessVirtualResolver.virtualInstanceGraphForValue(id2)?.listenerDefaultsByOwner?.get(id2);
89607
- const authored = authoredChangeListenerOwners(document.values).get(
89608
- id2
89609
- );
89610
- return inherited === void 0 ? authored : { ...inherited, ...authored };
89611
- },
89612
- defaultValueById: (id2) => declarationDefaultSource(
89613
- id2,
89614
- indexedLookups.valueById(id2),
89615
- headlessVirtualResolver.virtualInstanceGraphForValue
89616
- ),
89617
- valueById: (id2) => indexedLookups.valueById(id2) ?? headlessVirtualResolver.valueById(id2),
89618
- rowForValueReference: (value) => indexedLookups.rowForValueReference?.(value) ?? headlessVirtualResolver.rowForValueReference(value),
89619
- virtualInstanceRowsForValue: (receiverValueId) => headlessVirtualResolver.virtualInstanceRowsForValue(
89620
- receiverValueId
89621
- ),
89622
- // Headless hosts still evaluate `ToVariant` during
89623
- // stored-construction replay — production's variant-constructed
89624
- // placements collapse through exactly this path. The shared core
89625
- // resolves against the plain document, with these lookups as the
89626
- // nested resolver.
89627
- resolveVariantInstanceGraph: (args) => resolveVariantInstanceGraphForDocument({
89628
- evaluateInitializer: evaluateMemberInitializer,
89629
- document,
89630
- resolverLookups: lookups,
89631
- ...readTracking === void 0 ? {} : { readRecorder: virtualReadRecorder(readTracking) },
89632
- ...args
89633
- })
89634
- } : {
89635
- get worldQueryRevision() {
89636
- return document.databaseVM?.worldQueryRevision;
89637
- },
89638
- memberById: (id2) => document.databaseVM?.memberById(id2) ?? null,
89639
- valueById: (id2) => document.databaseVM?.valueById(id2) ?? null,
89640
- variantById: (id2) => document.databaseVM?.variantById?.(id2) ?? null,
89641
- // The VM's `valueById` answers EXPANDED-first: a collapse-stamped
89642
- // root resolves to a record the VM minted, an object the raw value
89643
- // index has never seen. Reference-identity dispatch (`.Id`, `is`,
89644
- // lookup selection) must reach the VM's reverse map for those
89645
- // records — dropping to the raw index alone made every lookup
89646
- // variant's initializer report "produced a value with no backing
89647
- // row" once P75 expansion started succeeding.
89648
- rowForValueReference: (value) => indexedLookups.rowForValueReference?.(value) ?? document.databaseVM?.rowForValueReference?.(value) ?? null,
89649
- unorderedListEntryIds: (containerValueId) => {
89650
- const resolved = document.databaseVM?.unorderedListEntryIds?.(containerValueId) ?? indexedLookups.unorderedListEntryIds?.(containerValueId);
89651
- if (resolved === void 0) {
89652
- throw new Error(
89653
- `Evaluator database resolves no unordered-list membership for container "${containerValueId}".`
89654
- );
89655
- }
89656
- return resolved;
89657
- },
89658
- virtualInstanceRowsForValue: (receiverValueId) => {
89659
- const databaseVM = document.databaseVM;
89660
- if (databaseVM === void 0) return [];
89661
- return databaseVM.virtualInstanceRowsForValue(receiverValueId);
89662
- },
89663
- resolveVariantInstanceGraph: (args) => {
89664
- const resolver = document.databaseVM?.resolveVariantInstanceGraph;
89665
- if (resolver === void 0) {
89666
- throw new Error(
89667
- "Evaluator database has no virtual variant resolver."
89668
- );
89669
- }
89670
- return resolver.call(document.databaseVM, args);
89671
- }
89672
- }
89868
+ changeListenerDefaultsForOwner: (id2) => {
89869
+ if (!(hasListenerMetadata ??= hasAuthoredChangeListenerMetadata(document)))
89870
+ return void 0;
89871
+ const inherited = headlessVirtualResolver.virtualInstanceGraphForValue(id2)?.listenerDefaultsByOwner?.get(id2);
89872
+ const authored = authoredChangeListenerOwners(document.values).get(id2);
89873
+ return inherited === void 0 ? authored : { ...inherited, ...authored };
89874
+ },
89875
+ defaultValueById: (id2) => declarationDefaultSource(
89876
+ id2,
89877
+ indexedLookups.valueById(id2),
89878
+ headlessVirtualResolver.virtualInstanceGraphForValue
89879
+ ),
89880
+ valueById: (id2) => indexedLookups.valueById(id2) ?? headlessVirtualResolver.valueById(id2),
89881
+ rowForValueReference: (value) => indexedLookups.rowForValueReference?.(value) ?? headlessVirtualResolver.rowForValueReference(value),
89882
+ virtualInstanceRowsForValue: (receiverValueId) => headlessVirtualResolver.virtualInstanceRowsForValue(receiverValueId),
89883
+ recordVirtualInstanceReads: (reads, read) => headlessVirtualResolver.recordReads(reads, read),
89884
+ // Headless hosts still evaluate `ToVariant` during
89885
+ // stored-construction replay — production's variant-constructed
89886
+ // placements collapse through exactly this path. The shared core
89887
+ // resolves against the plain document, with these lookups as the
89888
+ // nested resolver.
89889
+ resolveVariantInstanceGraph: (args) => resolveVariantInstanceGraphForDocument({
89890
+ evaluateInitializer: evaluateMemberInitializer,
89891
+ document,
89892
+ resolverLookups: lookups,
89893
+ ...readTracking === void 0 ? {} : { readRecorder: virtualReadRecorder(readTracking) },
89894
+ ...args
89895
+ })
89673
89896
  };
89674
89897
  if (!trackedHeadless) {
89675
89898
  evaluatorLookupsByDocument.set(lookupKey, {
@@ -89678,8 +89901,7 @@ function initializerEvaluatorLookups(document, readTracking) {
89678
89901
  revision,
89679
89902
  lookups
89680
89903
  });
89681
- if (headlessVirtualResolver !== null)
89682
- headlessResolversByLookupKey.set(lookupKey, headlessVirtualResolver);
89904
+ headlessResolversByLookupKey.set(lookupKey, headlessVirtualResolver);
89683
89905
  }
89684
89906
  return lookups;
89685
89907
  }
@@ -90186,6 +90408,40 @@ function declarationInitializerContext(document) {
90186
90408
  });
90187
90409
  return created;
90188
90410
  }
90411
+ function defaultValuePlans(document) {
90412
+ const key = document.databaseVM ?? initializerEvaluatorCacheKey(document);
90413
+ const revision = initializerEvaluatorCacheRevision(document);
90414
+ const valueGeneration = document.databaseVM?.valueGeneration;
90415
+ const cached = defaultValuePlansByDocument.get(key);
90416
+ if (cached !== void 0 && (revision === void 0 ? cached.members === document.members && cached.classes === document.classes && cached.values === document.values && cached.constructors === document.constructors : cached.revision === revision && cached.valueGeneration === valueGeneration)) {
90417
+ return cached.plans;
90418
+ }
90419
+ const lookups = initializerEvaluatorLookups(document);
90420
+ const plans = withIndexedDefaultValueDocument({
90421
+ project: document.project,
90422
+ members: document.members,
90423
+ classes: document.classes,
90424
+ enums: document.enums,
90425
+ values: document.values,
90426
+ constructors: document.constructors,
90427
+ projectFiles: document.projectFiles,
90428
+ textureTemplates: document.textureTemplates,
90429
+ memberById: lookups.memberById,
90430
+ valueById: lookups.defaultValueById ?? lookups.valueById,
90431
+ // A host database without list membership falls back to `values`.
90432
+ unorderedListEntryIds: document.databaseVM?.unorderedListEntryIds === void 0 && document.databaseVM !== void 0 ? void 0 : lookups.unorderedListEntryIds
90433
+ });
90434
+ defaultValuePlansByDocument.set(key, {
90435
+ members: document.members,
90436
+ classes: document.classes,
90437
+ values: document.values,
90438
+ constructors: document.constructors,
90439
+ revision,
90440
+ valueGeneration,
90441
+ plans
90442
+ });
90443
+ return plans;
90444
+ }
90189
90445
  function evaluateInitializerMaterialization(args) {
90190
90446
  const createdValues = [];
90191
90447
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
@@ -90293,9 +90549,6 @@ function materializeInitializerValue(args) {
90293
90549
  function materializeMemberDefaultValue(args) {
90294
90550
  const createdValues = [];
90295
90551
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
90296
- args.readTracking?.recordUnattributableValueRead(
90297
- ownershipChainRead("declaration-owner-resolution", args.envelope.id)
90298
- );
90299
90552
  const declarationArguments = (member, init, sourceValueId) => {
90300
90553
  const { valuesById, rootOwners } = declarationInitializerContext(
90301
90554
  args.document
@@ -90304,7 +90557,8 @@ function materializeMemberDefaultValue(args) {
90304
90557
  args.document,
90305
90558
  sourceValueId,
90306
90559
  rootOwners,
90307
- valuesById
90560
+ valuesById,
90561
+ (id2) => args.readTracking?.valueIds.add(id2)
90308
90562
  ).ownerClass : typeof Reflect.get(member, "id") === "string" ? findSchemaPlacement(
90309
90563
  String(Reflect.get(member, "id")),
90310
90564
  args.document.classes
@@ -90326,15 +90580,38 @@ function materializeMemberDefaultValue(args) {
90326
90580
  );
90327
90581
  };
90328
90582
  let lookups;
90583
+ const evaluatorLookups = () => lookups ??= initializerEvaluatorLookups(args.document, args.readTracking);
90584
+ const plans = args.readTracking !== void 0 && args.document.databaseVM === void 0 ? void 0 : defaultValuePlans(args.document);
90329
90585
  const built = buildDefaultMemberValue({
90330
90586
  document: {
90331
90587
  ...args.document,
90588
+ // The declaration rows a default clones are reads of this
90589
+ // materialization, like any row its initializers read.
90332
90590
  valueById: (id2) => {
90333
- lookups ??= initializerEvaluatorLookups(
90334
- args.document,
90335
- args.readTracking
90336
- );
90337
- return (lookups.defaultValueById ?? lookups.valueById)(id2);
90591
+ args.readTracking?.valueIds.add(id2);
90592
+ const database = evaluatorLookups();
90593
+ return database.defaultValueById !== void 0 ? database.defaultValueById(id2) : database.valueById(id2);
90594
+ },
90595
+ unorderedListEntryIds: (containerId) => {
90596
+ args.readTracking?.containerIds.add(containerId);
90597
+ const entryIds = evaluatorLookups().unorderedListEntryIds?.(containerId);
90598
+ if (entryIds === void 0) {
90599
+ throw new Error(
90600
+ `Initializer lookups resolve no unordered-list membership for container "${containerId}".`
90601
+ );
90602
+ }
90603
+ return entryIds;
90604
+ },
90605
+ // Not `resolvedMember`: its id-keyed cache would answer for the
90606
+ // caller's rewritten copy of a member with the stored original.
90607
+ ...plans === void 0 ? {} : {
90608
+ instanceEnv: plans.instanceEnv,
90609
+ storedInstanceMaterializationPlan: plans.storedInstanceMaterializationPlan
90610
+ },
90611
+ recordPlanReads: (reads) => {
90612
+ for (const id2 of reads.valueIds) args.readTracking?.valueIds.add(id2);
90613
+ for (const id2 of reads.containerIds)
90614
+ args.readTracking?.containerIds.add(id2);
90338
90615
  }
90339
90616
  },
90340
90617
  projectId: args.envelope.projectId,
@@ -90385,11 +90662,10 @@ function materializeMemberDefaultValue(args) {
90385
90662
  });
90386
90663
  return { root, createdValues: interior, pinnedRootSchemaKeys: /* @__PURE__ */ new Set() };
90387
90664
  }
90388
- var declarationInitializerContextByDocument;
90665
+ var declarationInitializerContextByDocument, defaultValuePlansByDocument;
90389
90666
  var init_initializer_materialization = __esm({
90390
90667
  "../packages/neoscript-runtime/src/initializer-materialization.ts"() {
90391
90668
  "use strict";
90392
- init_unattributable_reads();
90393
90669
  init_deep_clone_plain_data();
90394
90670
  init_members();
90395
90671
  init_inheritance();
@@ -90400,6 +90676,7 @@ var init_initializer_materialization = __esm({
90400
90676
  init_value_row_owner_members();
90401
90677
  init_initializer_identifiers();
90402
90678
  declarationInitializerContextByDocument = /* @__PURE__ */ new WeakMap();
90679
+ defaultValuePlansByDocument = /* @__PURE__ */ new WeakMap();
90403
90680
  }
90404
90681
  });
90405
90682
 
@@ -90415,7 +90692,13 @@ function rootReadScope(document) {
90415
90692
  );
90416
90693
  const created = scope.document === document ? scope : {
90417
90694
  ...scope,
90418
- document: { ...scope.document, evaluatorCache: void 0 }
90695
+ // Packed rows expand into new rows: the base's caches and world
90696
+ // index slot describe the document before expansion.
90697
+ document: {
90698
+ ...scope.document,
90699
+ evaluatorCache: void 0,
90700
+ worldQueryCache: void 0
90701
+ }
90419
90702
  };
90420
90703
  rootReadScopes.set(document, {
90421
90704
  members: document.members,
@@ -90799,6 +91082,8 @@ var init_effective_value_reader = __esm({
90799
91082
  ...baseDocument,
90800
91083
  databaseVM: void 0,
90801
91084
  evaluatorCache: void 0,
91085
+ // The base's world index slot covers the base rows, not these.
91086
+ worldQueryCache: void 0,
90802
91087
  evaluatorOverlay: {
90803
91088
  containerMembership: this.context.containerMembership,
90804
91089
  base: baseDocument,
@@ -92831,10 +93116,16 @@ function isEvaluatedOnlyExpression(expression) {
92831
93116
  case "unary":
92832
93117
  if (expression.op !== "-") return true;
92833
93118
  return isEvaluatedOnlyExpression(expression.operand);
93119
+ case "member":
93120
+ return !isNamePath(expression.receiver);
92834
93121
  default:
92835
93122
  return false;
92836
93123
  }
92837
93124
  }
93125
+ function isNamePath(expression) {
93126
+ if (expression.kind === "ident") return true;
93127
+ return expression.kind === "member" && isNamePath(expression.receiver);
93128
+ }
92838
93129
  function isLiteralCall(expression) {
92839
93130
  if (expression.callee.kind === "ident" && expression.callee.name === "Reference") {
92840
93131
  return true;
@@ -95569,6 +95860,21 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
95569
95860
  if (expected.name === NEO_VARIANT_TYPE_NAME || expected.name === NEO_LOOKUP_VARIANT_TYPE_NAME) {
95570
95861
  return lowerVariantDefault(context, expression, expected, path);
95571
95862
  }
95863
+ const enumName = expected.name === "List" ? expected.arguments[0]?.name ?? expected.name : expected.name;
95864
+ const enumId = context.enumIdsByName.get(enumName);
95865
+ if (enumId !== void 0 && (expression.kind === "contextualEnum" || expression.kind === "member")) {
95866
+ const optionName = enumOptionSpelling(expression, enumName, path);
95867
+ if (optionName === null) {
95868
+ throw new Error(`${path} requires .Option or ${enumName}.Option values.`);
95869
+ }
95870
+ const optionId = context.enumOptionsByName.get(enumId)?.get(optionName);
95871
+ if (optionId === void 0) {
95872
+ throw new Error(
95873
+ `Enum ${enumName} has no option ${JSON.stringify(optionName)}.`
95874
+ );
95875
+ }
95876
+ return optionId;
95877
+ }
95572
95878
  switch (expression.kind) {
95573
95879
  case "litNull":
95574
95880
  if (!expected.nullable) {
@@ -95602,19 +95908,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
95602
95908
  }
95603
95909
  throw new Error("Unary minus requires a numeric persisted default.");
95604
95910
  }
95605
- case "contextualEnum": {
95606
- const enumId = context.enumIdsByName.get(expected.name) ?? (expected.name === "List" ? context.enumIdsByName.get(expected.arguments[0]?.name ?? "") : void 0);
95607
- if (!enumId) {
95608
- throw new Error(`Cannot infer enum case .${expression.name}.`);
95609
- }
95610
- const optionId = context.enumOptionsByName.get(enumId)?.get(expression.name);
95611
- if (!optionId) {
95612
- throw new Error(
95613
- `Enum has no option ${JSON.stringify(expression.name)}.`
95614
- );
95615
- }
95616
- return optionId;
95617
- }
95911
+ case "contextualEnum":
95912
+ throw new Error(`Cannot infer enum case .${expression.name}.`);
95618
95913
  case "litList": {
95619
95914
  const entry = expected.arguments[0] ?? expected;
95620
95915
  return expression.elements.map(
@@ -98333,7 +98628,17 @@ function referenceTargetType(context, member, enclosingClassId) {
98333
98628
  );
98334
98629
  }
98335
98630
  function renderNestedValue(context, member, value, enclosingClassId) {
98336
- if (typeof value === "string" && member.kind !== "string" && member.kind !== "decimal" && member.kind !== "enum") {
98631
+ if (typeof value === "string" && member.kind !== "string" && member.kind !== "decimal") {
98632
+ if (member.kind === "enum") {
98633
+ const option = required(
98634
+ context.enums,
98635
+ member.enumId,
98636
+ "enum"
98637
+ ).options.find(
98638
+ (candidate) => candidate.id === value || candidate.key === value
98639
+ );
98640
+ if (option !== void 0) return `.${option.name}`;
98641
+ }
98337
98642
  return `Reference<${referenceTargetType(context, member, enclosingClassId)}>(id: ${quote(value)})`;
98338
98643
  }
98339
98644
  return renderDefaultValue(
@@ -109368,6 +109673,129 @@ var init_project_commit_preparation_scoped_loader = __esm({
109368
109673
  }
109369
109674
  });
109370
109675
 
109676
+ // ../src/database/compiled-construction-types.ts
109677
+ function compiledConstructionTypeMembers(members, bodies, projectId) {
109678
+ const created = [];
109679
+ let existingIds;
109680
+ const byType = /* @__PURE__ */ new Map();
109681
+ const key = (type) => canonicalJsonStringify(type);
109682
+ const intern = (type) => {
109683
+ const signature = key(type);
109684
+ const existing = byType.get(signature);
109685
+ if (existing !== void 0) return existing;
109686
+ if (type.type === 21 /* Generic */ || type.type === NS_TYPE_UNKNOWN)
109687
+ return null;
109688
+ const id2 = v5_default(
109689
+ `neo:compiled-construction-type:${projectId}:${signature}`,
109690
+ v5_default.URL
109691
+ );
109692
+ existingIds ??= new Set(members.map((member) => member.id));
109693
+ if (existingIds.has(id2)) {
109694
+ byType.set(signature, id2);
109695
+ return id2;
109696
+ }
109697
+ const common = {
109698
+ id: id2,
109699
+ projectId,
109700
+ createdAt: 0,
109701
+ updatedAt: 0,
109702
+ name: "Type argument",
109703
+ kind: type.type,
109704
+ requirement: type.required ? 1 /* Required */ : 0 /* Optional */
109705
+ };
109706
+ const fields = (() => {
109707
+ if (type.type === 6 /* List */ || type.type === 5 /* Dictionary */) {
109708
+ const entryMemberId = intern(type.entryTypeInfo);
109709
+ if (entryMemberId === null) return null;
109710
+ return {
109711
+ entryMemberId,
109712
+ ...type.keyEnumId === void 0 ? {} : { keyKind: 1 /* Enum */, keyEnumId: type.keyEnumId }
109713
+ };
109714
+ } else if (type.type === 7 /* Class */) {
109715
+ const classArguments2 = {};
109716
+ for (const [parameter4, argument2] of Object.entries(
109717
+ type.typeArguments ?? {}
109718
+ )) {
109719
+ const memberId = intern(argument2);
109720
+ if (memberId === null) return null;
109721
+ classArguments2[parameter4] = {
109722
+ kind: 1 /* Member */,
109723
+ memberId
109724
+ };
109725
+ }
109726
+ return {
109727
+ classId: type.classId,
109728
+ ...Object.keys(classArguments2).length === 0 ? {} : { classArguments: classArguments2 }
109729
+ };
109730
+ } else if (type.type === 8 /* Enum */) {
109731
+ return { enumId: type.enumId };
109732
+ } else if (type.type === 25 /* NSDelegate */) {
109733
+ return {
109734
+ returnTypeInfo: type.returnTypeInfo,
109735
+ argumentTypes: type.argumentTypes
109736
+ };
109737
+ } else if (type.type === 26 /* NSAction */) {
109738
+ return { argumentTypes: type.argumentTypes };
109739
+ } else if (type.type === 22 /* Interface */ || type.type === 9 /* Lookup */ || type.type === 18 /* DialogueLookup */) {
109740
+ return null;
109741
+ } else {
109742
+ return {};
109743
+ }
109744
+ })();
109745
+ if (fields === null) return null;
109746
+ created.push({ ...common, ...fields });
109747
+ existingIds.add(id2);
109748
+ byType.set(signature, id2);
109749
+ return id2;
109750
+ };
109751
+ const visited = /* @__PURE__ */ new Set();
109752
+ const visit = (value) => {
109753
+ if (value === null || typeof value !== "object" || visited.has(value))
109754
+ return;
109755
+ visited.add(value);
109756
+ const argumentsValue = getField(
109757
+ getField(value, "schemaClassInfo"),
109758
+ "typeArguments"
109759
+ );
109760
+ if (argumentsValue !== null && typeof argumentsValue === "object") {
109761
+ for (const type of Object.values(argumentsValue))
109762
+ if (isNSTypeInfo(type)) intern(type);
109763
+ }
109764
+ for (const child2 of Object.values(value)) visit(child2);
109765
+ };
109766
+ for (const body of bodies) visit(body);
109767
+ return created;
109768
+ }
109769
+ function withCompiledConstructionTypes(document, body) {
109770
+ const members = document.members;
109771
+ const projectId = getField(document.project, "id");
109772
+ if (!Array.isArray(members)) {
109773
+ throw new Error("Construction type descriptors require a member array.");
109774
+ }
109775
+ if (!members.every(
109776
+ (member) => typeof getField(member, "id") === "string"
109777
+ )) {
109778
+ throw new Error(
109779
+ "Construction type descriptors require an ID on every member record."
109780
+ );
109781
+ }
109782
+ if (typeof projectId !== "string") {
109783
+ throw new Error("Construction type descriptors require a project ID.");
109784
+ }
109785
+ const created = compiledConstructionTypeMembers(members, [body], projectId);
109786
+ return created.length === 0 ? document : { ...document, members: [...members, ...created] };
109787
+ }
109788
+ var init_compiled_construction_types = __esm({
109789
+ "../src/database/compiled-construction-types.ts"() {
109790
+ "use strict";
109791
+ init_dist_node();
109792
+ init_core();
109793
+ init_neoscript_guards();
109794
+ init_neoscript();
109795
+ init_project_content_hash();
109796
+ }
109797
+ });
109798
+
109371
109799
  // ../src/database/lookup-target-class-contract.ts
109372
109800
  function lookupTargetClassContractViolation(args) {
109373
109801
  const actualClassId = typeof args.targetClassId === "string" ? args.targetClassId : null;
@@ -112474,11 +112902,7 @@ function appendAuthoredOwnedValueCascadeDeletes(args) {
112474
112902
  authoredPost,
112475
112903
  new Set(replayCandidates.keys())
112476
112904
  );
112477
- if (authoredCandidateIds.size > 0) {
112478
- args.earlyDelegateCompilation.contractHash = hashCanonicalJson(
112479
- neoScriptCompilationProjectContract(authoredPost)
112480
- );
112481
- }
112905
+ let contractHash;
112482
112906
  for (const [id2, row] of replayCandidates) {
112483
112907
  let compiled = row;
112484
112908
  const closure = delegateValueRow(compiled);
@@ -112495,6 +112919,9 @@ function appendAuthoredOwnedValueCascadeDeletes(args) {
112495
112919
  args.earlyDelegateCompilation.rows.set(id2, {
112496
112920
  source: row,
112497
112921
  compiled,
112922
+ contractHash: contractHash ??= hashCanonicalJson(
112923
+ neoScriptCompilationProjectContract(authoredPost)
112924
+ ),
112498
112925
  ...compiler.ownershipIds(id2)
112499
112926
  });
112500
112927
  }
@@ -112707,7 +113134,6 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
112707
113134
  }).map(cloneAndStripClientDerivedBodies)
112708
113135
  });
112709
113136
  const earlyDelegateCompilation = {
112710
- contractHash: null,
112711
113137
  rows: /* @__PURE__ */ new Map()
112712
113138
  };
112713
113139
  let authoredPost = appendAuthoredOwnedValueCascadeDeletes({
@@ -113034,6 +113460,27 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
113034
113460
  targetIds: recompileTargets.constructorIds,
113035
113461
  contentHashHeads: args.contentHashHeads
113036
113462
  });
113463
+ const constructionTypeMembers = [...sourceMembers];
113464
+ const appendConstructionTypes = () => {
113465
+ const created = compiledConstructionTypeMembers(
113466
+ constructionTypeMembers,
113467
+ prepared.map((change) => change.nextData),
113468
+ args.document.project.id
113469
+ );
113470
+ constructionTypeMembers.push(...created);
113471
+ const changes = created.map((member) => ({
113472
+ recordKind: "member",
113473
+ recordId: member.id,
113474
+ operation: "create",
113475
+ nextData: member,
113476
+ intent: createProjectVersionIntent("member.create", {
113477
+ source: "compiled-construction-type"
113478
+ })
113479
+ }));
113480
+ prepared.push(...changes);
113481
+ return changes;
113482
+ };
113483
+ appendConstructionTypes();
113037
113484
  const postDocument = applyProjectVersionWriteChanges(args.document, prepared);
113038
113485
  const listIndexErrors = validateDocumentListIndexes({
113039
113486
  members: postDocument.members,
@@ -113074,6 +113521,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
113074
113521
  recompileTargets,
113075
113522
  contentHashHeads: args.contentHashHeads
113076
113523
  });
113524
+ appendConstructionTypes();
113077
113525
  args.passLifecycle?.("complete", "neo-script-recompile-targets");
113078
113526
  yield {
113079
113527
  pass: "neo-script-recompile-targets",
@@ -113099,6 +113547,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
113099
113547
  targetIds: recompileTargets.valueIds,
113100
113548
  contentHashHeads: args.contentHashHeads
113101
113549
  });
113550
+ appendConstructionTypes();
113102
113551
  args.passLifecycle?.("complete", "authored-value-seeds");
113103
113552
  yield { pass: "authored-value-seeds", preparedChanges: prepared };
113104
113553
  args.passLifecycle?.("start", "variant-child-override-binding-members");
@@ -113113,6 +113562,12 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
113113
113562
  preparedChanges: prepared
113114
113563
  };
113115
113564
  args.passLifecycle?.("start", "prepared-instance-initializers");
113565
+ compileInitializerReadableDelegateRows({
113566
+ document: args.document,
113567
+ prepared,
113568
+ earlyDelegateCompilation,
113569
+ appendConstructionTypes
113570
+ });
113116
113571
  materializePreparedInstanceInitializers({
113117
113572
  document: args.document,
113118
113573
  prepared,
@@ -113143,6 +113598,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
113143
113598
  physicalValues: args.document.physicalValues,
113144
113599
  earlyDelegateCompilation
113145
113600
  });
113601
+ appendConstructionTypes();
113146
113602
  args.passLifecycle?.("complete", "delegate-value-bodies");
113147
113603
  yield { pass: "delegate-value-bodies", preparedChanges: prepared };
113148
113604
  args.passLifecycle?.("start", "variant-constructor-args");
@@ -115197,6 +115653,8 @@ function commitInitEvaluator(document, createdValues) {
115197
115653
  function hasAuthoredNeoScriptBody(member) {
115198
115654
  if (member.kind === 10 /* NSProperty */) return true;
115199
115655
  if (member.kind === 23 /* NSFunction */) return true;
115656
+ if (isMemberDelegateBase(member) && isLiteralValueContent(member.defaultValue) && (isNSDelegateClosureValueDraft(member.defaultValue.value) || isNSDelegateClosureValue(member.defaultValue.value)))
115657
+ return true;
115200
115658
  return isInitValueContent(member.defaultValue);
115201
115659
  }
115202
115660
  function touchedInitializerFilter(prepared) {
@@ -115731,6 +116189,7 @@ function compileInlineDelegateConstructorArguments(args) {
115731
116189
  returnTypeInfo: substituted.returnTypeInfo,
115732
116190
  argumentTypes: substituted.argumentTypes,
115733
116191
  name: `${settledMember.name} argument`,
116192
+ staticMember: rootOwner !== void 0 && isStaticMember(rootOwner),
115734
116193
  compilationProject: args.compilationProject
115735
116194
  });
115736
116195
  } catch (error) {
@@ -115775,8 +116234,9 @@ function carriesValueBody(content) {
115775
116234
  if (isNSDelegateClosureValue(value)) return true;
115776
116235
  return carriesUncompiledInlineDelegateArgument(content);
115777
116236
  }
115778
- function assertValueBodiesCompile(args) {
115779
- if (args.valueIds.size === 0) return;
116237
+ function compileValueBodies(args) {
116238
+ const closures = [];
116239
+ if (args.valueIds.size === 0) return closures;
115780
116240
  const { scope } = args;
115781
116241
  const compiler = createDelegateValueBodyCompiler(
115782
116242
  scope.document,
@@ -115787,7 +116247,7 @@ function assertValueBodiesCompile(args) {
115787
116247
  const value = scope.valuesById.get(id2);
115788
116248
  if (value === void 0) continue;
115789
116249
  const closure = delegateValueRow(value);
115790
- if (closure !== null) compiler.compileClosure(closure);
116250
+ if (closure !== null) closures.push(compiler.compileClosure(closure));
115791
116251
  const inline = inlineDelegateArgumentRow(value);
115792
116252
  if (inline !== null) compiler.compileInline(inline);
115793
116253
  const init = initBackedValueRow(value);
@@ -115801,6 +116261,7 @@ function assertValueBodiesCompile(args) {
115801
116261
  valuesById: scope.valuesById
115802
116262
  });
115803
116263
  }
116264
+ return closures;
115804
116265
  }
115805
116266
  function createDelegateValueBodyCompiler(postDocument, targetIds, prepared) {
115806
116267
  const scope = prepared ?? delegateValueBodyOwnership(postDocument, targetIds);
@@ -115845,6 +116306,7 @@ function createDelegateValueBodyCompiler(postDocument, targetIds, prepared) {
115845
116306
  returnTypeInfo: member.returnTypeInfo,
115846
116307
  argumentTypes: member.argumentTypes,
115847
116308
  name: `${member.name} value`,
116309
+ staticMember: rootOwner !== void 0 && isStaticMember(rootOwner),
115848
116310
  compilationProject: compilationProjectFor(document)
115849
116311
  });
115850
116312
  } catch (error) {
@@ -115870,7 +116332,8 @@ function createDelegateValueBodyCompiler(postDocument, targetIds, prepared) {
115870
116332
  ownerMemberId: getOptionalString(ownerByValueId.get(valueId), "id") ?? null,
115871
116333
  rootOwnerId: rootOwnerByValueId.get(valueId)?.id ?? null
115872
116334
  });
115873
- return { compileClosure, compileInline, ownershipIds };
116335
+ const ownsClosure = (valueId) => isMemberDelegateBase(ownerByValueId.get(valueId));
116336
+ return { compileClosure, compileInline, ownershipIds, ownsClosure };
115874
116337
  }
115875
116338
  function delegateValueBodyOwnership(postDocument, targetIds) {
115876
116339
  const scope = withVariantOwnershipRoots(
@@ -115886,6 +116349,57 @@ function delegateValueBodyOwnership(postDocument, targetIds) {
115886
116349
  );
115887
116350
  return { document: scope.document, ownerByValueId, rootOwnerByValueId };
115888
116351
  }
116352
+ function compileInitializerReadableDelegateRows(args) {
116353
+ const rows = /* @__PURE__ */ new Map();
116354
+ let replaysInitializer = false;
116355
+ for (let index = 0; index < args.prepared.length; index += 1) {
116356
+ const change = args.prepared[index];
116357
+ if (change?.recordKind !== "value" || change.operation === "delete") {
116358
+ continue;
116359
+ }
116360
+ if (isMemberValue(change.nextData) && isInitValueContent(change.nextData)) {
116361
+ replaysInitializer = true;
116362
+ }
116363
+ const row = delegateValueRow(change.nextData);
116364
+ if (row !== null && isNSDelegateClosureValueDraft(row.value)) {
116365
+ rows.set(index, row);
116366
+ }
116367
+ }
116368
+ if (!replaysInitializer || rows.size === 0) return;
116369
+ const postDocument = applyProjectVersionWriteChanges(
116370
+ args.document,
116371
+ args.prepared
116372
+ );
116373
+ const compiler = createDelegateValueBodyCompiler(
116374
+ postDocument,
116375
+ new Set(Array.from(rows.values(), (row) => row.id))
116376
+ );
116377
+ const compiled = [];
116378
+ for (const [index, row] of rows) {
116379
+ if (!compiler.ownsClosure(row.id)) continue;
116380
+ const next = compiler.compileClosure(row);
116381
+ args.prepared[index] = { ...args.prepared[index], nextData: next };
116382
+ compiled.push({ row: next, ...compiler.ownershipIds(row.id) });
116383
+ }
116384
+ if (compiled.length === 0) return;
116385
+ const contractHash = hashCanonicalJson(
116386
+ neoScriptCompilationProjectContract(
116387
+ projectVersionDocumentWithChanges(
116388
+ postDocument,
116389
+ args.appendConstructionTypes(),
116390
+ true
116391
+ )
116392
+ )
116393
+ );
116394
+ for (const { row, ...ownership } of compiled) {
116395
+ args.earlyDelegateCompilation.rows.set(row.id, {
116396
+ source: row,
116397
+ compiled: row,
116398
+ contractHash,
116399
+ ...ownership
116400
+ });
116401
+ }
116402
+ }
115889
116403
  function prepareServerOwnedDelegateValueBodies(args) {
115890
116404
  const explicitRows = /* @__PURE__ */ new Map();
115891
116405
  const inlineArgumentRows = /* @__PURE__ */ new Map();
@@ -115916,11 +116430,13 @@ function prepareServerOwnedDelegateValueBodies(args) {
115916
116430
  targetIds
115917
116431
  );
115918
116432
  const early = args.earlyDelegateCompilation;
115919
- const sameCompilerContract = early.rows.size > 0 && early.contractHash === hashCanonicalJson(neoScriptCompilationProjectContract(committedDocument));
116433
+ const contractHash = early.rows.size === 0 ? null : hashCanonicalJson(
116434
+ neoScriptCompilationProjectContract(committedDocument)
116435
+ );
115920
116436
  const reusableEarlyRow = (row) => {
115921
- if (!sameCompilerContract) return null;
115922
116437
  const candidate = early.rows.get(row.id);
115923
116438
  if (candidate?.source !== row) return null;
116439
+ if (candidate.contractHash !== contractHash) return null;
115924
116440
  const ownership = compiler.ownershipIds(row.id);
115925
116441
  return ownership.ownerMemberId === candidate.ownerMemberId && ownership.rootOwnerId === candidate.rootOwnerId ? candidate.compiled : null;
115926
116442
  };
@@ -116436,6 +116952,7 @@ var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, SCHEM
116436
116952
  var init_project_version_schema_commit = __esm({
116437
116953
  "../src/database/project-version-schema-commit.ts"() {
116438
116954
  "use strict";
116955
+ init_compiled_construction_types();
116439
116956
  init_member_kinds();
116440
116957
  init_project_schema_index();
116441
116958
  init_lookup_target_class_contract();
@@ -125140,6 +125657,7 @@ function compilePulledUncompiledConstructorsV4(document, compilationProject, rep
125140
125657
  assertPulledConstructorsCompiled(document, replayContext);
125141
125658
  }
125142
125659
  function compilePulledProjectDocumentForEvaluationV4(document, compilationProject, targets) {
125660
+ const compiled = [];
125143
125661
  const sharedCompilationProject = compilationProject ?? createNeoScriptCompilationProject({
125144
125662
  project: document.project,
125145
125663
  projectFiles: document.projectFiles,
@@ -125172,6 +125690,7 @@ function compilePulledProjectDocumentForEvaluationV4(document, compilationProjec
125172
125690
  `constructor:${constructor2.id}`
125173
125691
  )
125174
125692
  });
125693
+ compiled.push(constructor2);
125175
125694
  }
125176
125695
  assertPulledConstructorsCompiled(document);
125177
125696
  const memberIndex = documentMemberCompilationIndex(document);
@@ -125185,6 +125704,7 @@ function compilePulledProjectDocumentForEvaluationV4(document, compilationProjec
125185
125704
  scriptSources: targets?.scriptSources?.get(`member:${member.id}`),
125186
125705
  thisClass: memberIndex.ownerClassesByMemberId.get(member.id) ?? null
125187
125706
  });
125707
+ compiled.push(member);
125188
125708
  } catch (error) {
125189
125709
  if (error instanceof CompileError) {
125190
125710
  pulledBodyCompileSites.set(error, {
@@ -125195,6 +125715,7 @@ function compilePulledProjectDocumentForEvaluationV4(document, compilationProjec
125195
125715
  throw error;
125196
125716
  }
125197
125717
  }
125718
+ return compiled;
125198
125719
  }
125199
125720
  function assertPulledConstructorsCompiled(document, replayContext) {
125200
125721
  if (replayContext !== void 0 && replayContext.document !== document) {
@@ -127682,7 +128203,7 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
127682
128203
  );
127683
128204
  const baseData3 = stateData(context, "member", memberId);
127684
128205
  const annotatedExpression = annotatedValue(expression).expression;
127685
- if (requiresEvaluation)
128206
+ if (requiresEvaluation || member.kind === "delegate" && annotatedExpression.kind === "lambda")
127686
128207
  context.initializerSites.set(
127687
128208
  memberId,
127688
128209
  referenceSite(binding, annotatedExpression)
@@ -136261,13 +136782,15 @@ function materializeInitializersLocallyV4(args) {
136261
136782
  written.push({
136262
136783
  recordKind: "value",
136263
136784
  recordId: seed.valueId,
136264
- operation: "create"
136785
+ operation: "create",
136786
+ nextData: records3.get(`value:${seed.valueId}`)?.data
136265
136787
  });
136266
136788
  for (const row of seed.values ?? [])
136267
136789
  written.push({
136268
136790
  recordKind: "value",
136269
136791
  recordId: row.id,
136270
- operation: "create"
136792
+ operation: "create",
136793
+ nextData: records3.get(`value:${row.id}`)?.data
136271
136794
  });
136272
136795
  }
136273
136796
  const touched = touchedInitializerFilter(written);
@@ -136277,9 +136800,16 @@ function materializeInitializersLocallyV4(args) {
136277
136800
  return touched.touches("value", change.recordId, data);
136278
136801
  return change.recordKind === "member" && isObjectRecord2(data) && touched.touches("member", change.recordId, data.defaultValue);
136279
136802
  });
136280
- const valueBodyIds = writtenValueBodyIds(args.changes);
136803
+ const valueBodyIds = writtenValueBodyIds(written);
136281
136804
  const compilesValueBodies = valueBodyIds.size > 0;
136282
- if (sourceRoots.size === 0 && !validatesTouched && !compilesValueBodies)
136805
+ const compilesDelegateDefaults = written.some((change) => {
136806
+ if (change.recordKind !== "member" || change.operation === "delete")
136807
+ return false;
136808
+ const data = records3.get(`member:${change.recordId}`)?.data;
136809
+ const defaultValue = getField(data, "defaultValue");
136810
+ return isLiteralValueContent(defaultValue) && isNSDelegateClosureValueDraft(defaultValue.value);
136811
+ });
136812
+ if (sourceRoots.size === 0 && !validatesTouched && !compilesValueBodies && !compilesDelegateDefaults)
136283
136813
  return { roots: [] };
136284
136814
  const pulledDocument = readPulledProjectDocumentV4(records3);
136285
136815
  const variantScope = withVariantOwnershipRoots(
@@ -136303,7 +136833,7 @@ function materializeInitializersLocallyV4(args) {
136303
136833
  const pendingRoots = new Set(
136304
136834
  [...sourceRoots].filter((id2) => rootKinds.get(id2) !== "declaration").sort()
136305
136835
  );
136306
- if (pendingRoots.size === 0 && !validatesTouched && !compilesValueBodies)
136836
+ if (pendingRoots.size === 0 && !validatesTouched && !compilesValueBodies && !compilesDelegateDefaults)
136307
136837
  return { roots };
136308
136838
  const replayedRoots = new Set(pendingRoots);
136309
136839
  const compilationProject = createNeoScriptCompilationProject(authoredDocument);
@@ -136339,7 +136869,7 @@ function materializeInitializersLocallyV4(args) {
136339
136869
  changedBodies.constructorIds.add(id2);
136340
136870
  }
136341
136871
  }
136342
- compilePulledProjectDocumentForEvaluationV4(
136872
+ const compiledBodies = compilePulledProjectDocumentForEvaluationV4(
136343
136873
  authoredDocument,
136344
136874
  compilationProject,
136345
136875
  changedBodies
@@ -136347,11 +136877,11 @@ function materializeInitializersLocallyV4(args) {
136347
136877
  assertPulledConstructorsCompiled(authoredDocument);
136348
136878
  const compiledBodyIds = new Set(valueBodyIds);
136349
136879
  for (const id2 of replayedRoots) compiledBodyIds.delete(id2);
136350
- const batch = createInitializerMaterializationBatch(
136880
+ let batch = createInitializerMaterializationBatch(
136351
136881
  authoredDocument,
136352
136882
  pendingRoots
136353
136883
  );
136354
- assertValueBodiesCompile({
136884
+ const compiledClosures = compileValueBodies({
136355
136885
  scope: {
136356
136886
  document: authoredDocument,
136357
136887
  compilationProject,
@@ -136363,10 +136893,40 @@ function materializeInitializersLocallyV4(args) {
136363
136893
  valueIds: compiledBodyIds
136364
136894
  });
136365
136895
  const compiledInitializers = /* @__PURE__ */ new Map();
136896
+ const templateContext = createPulledConstructionReplayContext({
136897
+ document: authoredDocument,
136898
+ valuesById: batch.valuesById
136899
+ });
136900
+ for (const id2 of pendingRoots) {
136901
+ replayStoredConstructionV4({
136902
+ records: records3,
136903
+ document: authoredDocument,
136904
+ valueId: id2,
136905
+ code: initializerCode(records3, id2),
136906
+ compilationProject,
136907
+ replayContext: templateContext,
136908
+ member: rootOwners.get(id2),
136909
+ evaluate: false,
136910
+ onCompiledInitializer: (init) => compiledInitializers.set(id2, init)
136911
+ });
136912
+ }
136913
+ const typeMembers = compiledConstructionTypeMembers(
136914
+ authoredDocument.members,
136915
+ [compiledBodies, compiledClosures, [...compiledInitializers.values()]],
136916
+ authoredDocument.project.id
136917
+ );
136918
+ const replayDocument = typeMembers.length === 0 ? authoredDocument : {
136919
+ ...authoredDocument,
136920
+ members: [...authoredDocument.members, ...typeMembers]
136921
+ };
136922
+ if (replayDocument !== authoredDocument) {
136923
+ batch = createInitializerMaterializationBatch(replayDocument, pendingRoots);
136924
+ }
136925
+ batch.upsert(compiledClosures);
136366
136926
  materializeInitializerDependencies(pendingRoots, (sourceValueId) => {
136367
136927
  const batchDocument = batch.document();
136368
136928
  const document = {
136369
- ...authoredDocument,
136929
+ ...replayDocument,
136370
136930
  values: batchDocument.values,
136371
136931
  databaseVM: batchDocument.databaseVM
136372
136932
  };
@@ -136490,6 +137050,7 @@ function materializeInitializersLocallyV4(args) {
136490
137050
  const batchDocument = batch.document();
136491
137051
  const document = {
136492
137052
  ...pulledDocument,
137053
+ members: [...pulledDocument.members, ...typeMembers],
136493
137054
  values: batchDocument.values,
136494
137055
  databaseVM: batchDocument.databaseVM
136495
137056
  };
@@ -136649,6 +137210,7 @@ var init_local_initializer_materialization = __esm({
136649
137210
  init_constructor_argument_ownership();
136650
137211
  init_neo_script_recompile_scope();
136651
137212
  init_compiler_adapter();
137213
+ init_compiled_construction_types();
136652
137214
  init_project_version_schema_commit();
136653
137215
  init_value_row_owner_members();
136654
137216
  init_variant_value_graph();
@@ -142492,12 +143054,33 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
142492
143054
  diagnostic2.range,
142493
143055
  diagnostic2.relatedInformation
142494
143056
  );
142495
- if (positioned.severity === "error") parseErrors.push(positioned);
142496
- else parseWarnings.push(positioned);
143057
+ if (positioned.severity === "error") {
143058
+ parseErrors.push(positioned);
143059
+ const errors = errorsByUri.get(diagnostic2.uri) ?? [];
143060
+ errors.push(diagnostic2);
143061
+ errorsByUri.set(diagnostic2.uri, errors);
143062
+ } else parseWarnings.push(positioned);
142497
143063
  }
143064
+ const nextErrorByUri = /* @__PURE__ */ new Map();
143065
+ for (const errors of errorsByUri.values()) {
143066
+ errors.sort(
143067
+ (left, right) => positionCompare(left.range.start, right.range.start)
143068
+ );
143069
+ }
143070
+ const invalidLocal = analysis.values.globals.some(({ source }) => {
143071
+ const errors = errorsByUri.get(source.uri);
143072
+ if (errors === void 0) return false;
143073
+ let index = nextErrorByUri.get(source.uri) ?? 0;
143074
+ while (index < errors.length && positionCompare(errors[index].range.start, source.range.start) < 0) {
143075
+ index++;
143076
+ }
143077
+ nextErrorByUri.set(source.uri, index);
143078
+ const error = errors[index];
143079
+ return error !== void 0 && sourceRangeContains(source.range, error.range.start);
143080
+ });
142498
143081
  if (analysis.diagnostics.some(
142499
143082
  (diagnostic2) => diagnostic2.severity === "error" && (diagnostic2.code === "duplicate-project-id" || diagnostic2.code === "invalid-project-global-initializer" || diagnostic2.code === "local-initializer-use" || diagnostic2.code === "local-initializer-cycle")
142500
- )) {
143083
+ ) || invalidLocal) {
142501
143084
  return refusedStatus(conflictedFiles, parseErrors, parseWarnings);
142502
143085
  }
142503
143086
  const rootDeclaration = analysis.configuration.globals.find(
@@ -142529,12 +143112,6 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
142529
143112
  );
142530
143113
  }
142531
143114
  const diagnostic = sourceDiagnosticMapper(analysis);
142532
- for (const error of analysis.diagnostics) {
142533
- if (error.severity !== "error") continue;
142534
- const errors = errorsByUri.get(error.uri) ?? [];
142535
- errors.push(error);
142536
- errorsByUri.set(error.uri, errors);
142537
- }
142538
143115
  const validAnalysis = {
142539
143116
  ...analysis,
142540
143117
  configuration: {
@@ -144638,6 +145215,7 @@ var ANIMATION_DOCUMENT_RECORD_KINDS, ANIMATION_REPLAY_RECORD_KINDS, PROSPECTIVE_
144638
145215
  var init_workspace_status_core = __esm({
144639
145216
  "src/project-source/workspace-status-core.ts"() {
144640
145217
  "use strict";
145218
+ init_project_source_tokens();
144641
145219
  init_project_root();
144642
145220
  init_source_text();
144643
145221
  init_dialogue_body_validation();
@@ -148192,7 +148770,7 @@ function complete(snapshot, position) {
148192
148770
  candidates = switchCaseCandidates;
148193
148771
  } else if (tail && (tail.kind === "punctuation" && tail.text === "." || tail.kind === "operator" && tail.text === "?.")) {
148194
148772
  const receiverTokens = expressionTokensBefore(tokens, tokens.length - 1);
148195
- if (receiverTokens.length === 0 || isContextualCompletionDot(snapshot.source.text, word.start)) {
148773
+ if (receiverTokens.length === 0 || isContextualCompletionDot(snapshot, word.start)) {
148196
148774
  candidates = contextualEnumCompletionItems(
148197
148775
  snapshot,
148198
148776
  expectedTypeAt(snapshot, word.start),
@@ -148878,19 +149456,16 @@ function contextualEnumCompletionItems(snapshot, expected, word) {
148878
149456
  };
148879
149457
  });
148880
149458
  }
148881
- function isContextualCompletionDot(text, wordStart) {
148882
- if (text[wordStart - 1] !== ".") return false;
148883
- let cursor = wordStart - 2;
148884
- while (cursor >= 0 && /\s/.test(text[cursor] ?? "")) cursor--;
148885
- const beforeDot = text[cursor];
148886
- if (beforeDot !== void 0 && /[A-Za-z0-9_]/.test(beforeDot)) {
148887
- let start = cursor;
148888
- while (start > 0 && /[A-Za-z0-9_]/.test(text[start - 1] ?? "")) start--;
148889
- while (start < cursor && /[0-9]/.test(text[start] ?? "")) start++;
148890
- const precedingWord = text.slice(start, cursor + 1);
148891
- return precedingWord === "return" || precedingWord === "case";
148892
- }
148893
- return beforeDot === void 0 || !/[A-Za-z0-9_\])}]/.test(beforeDot);
149459
+ function isContextualCompletionDot(snapshot, wordStart) {
149460
+ const { tokens } = scriptFeatureIndex(snapshot);
149461
+ const dot = firstIndex(tokens, (token) => token.start >= wordStart) - 1;
149462
+ if (tokens[dot]?.text !== ".") return false;
149463
+ const previous = tokens[dot - 1];
149464
+ if (!previous) return true;
149465
+ if (previous.kind === "keyword")
149466
+ return previous.text === "return" || previous.text === "case";
149467
+ if (previous.kind === "operator") return previous.text !== "!";
149468
+ return previous.kind === "punctuation" && ![")", "]", "}"].includes(previous.text);
148894
149469
  }
148895
149470
  function resolvedCallArgumentAt(snapshot, offset, body = lambdaBodyAt(snapshot, offset)) {
148896
149471
  const argument2 = callArgumentAt(snapshot, offset, body);
@@ -148909,17 +149484,32 @@ function expectedTypeAt(snapshot, offset, body = lambdaBodyAt(snapshot, offset),
148909
149484
  offset,
148910
149485
  body
148911
149486
  )) {
148912
- const initializer = initializerExpectedType(snapshot, offset);
149487
+ const initializer = initializerExpectedType(
149488
+ snapshot,
149489
+ offset,
149490
+ body?.start ?? 0
149491
+ );
148913
149492
  if (initializer !== void 0) return initializer;
148914
149493
  const features = scriptFeatureIndex(snapshot);
148915
149494
  if (argument2 && !isCollectionOpener(features, innermostOpener(features, offset))) {
148916
149495
  const { call, index, symbol } = argument2;
148917
- const parameterType = call.kind === "constructor" ? constructorParameterTypeAt(
148918
- constructionType(snapshot, call),
148919
- call,
148920
- index,
148921
- snapshot
148922
- ) : boundParameter(symbol?.parameters ?? [], call, index)?.type;
149496
+ let parameterType;
149497
+ if (call.kind === "constructor") {
149498
+ parameterType = constructorParameterTypeAt(
149499
+ constructionType(snapshot, call),
149500
+ call,
149501
+ index,
149502
+ snapshot
149503
+ ) ?? void 0;
149504
+ } else if (symbol?.type.kind === "delegate" && !symbol.returnType) {
149505
+ parameterType = symbol.type.parameterTypes[index];
149506
+ } else {
149507
+ parameterType = boundParameter(
149508
+ symbol?.parameters ?? [],
149509
+ call,
149510
+ index
149511
+ )?.type;
149512
+ }
148923
149513
  if (parameterType) {
148924
149514
  return expectedCollectionElementType(
148925
149515
  parameterType,
@@ -148996,8 +149586,25 @@ function expectedTypeAt(snapshot, offset, body = lambdaBodyAt(snapshot, offset),
148996
149586
  }
148997
149587
  const throwToken = tokens.slice(boundary + 1).find((token) => token.kind === "keyword" && token.text === "throw");
148998
149588
  if (throwToken) return { kind: "primitive", name: "string" };
148999
- if (body) return null;
149000
149589
  const returnToken = tokens.slice(boundary + 1).find((token) => token.kind === "keyword" && token.text === "return");
149590
+ if (body) {
149591
+ const bodyIndex = firstIndex(
149592
+ features.tokens,
149593
+ (token) => token.end >= body.start
149594
+ );
149595
+ const block = features.tokens[bodyIndex]?.text === "{";
149596
+ if (block && !returnToken) return null;
149597
+ const arrow = features.tokens[block ? bodyIndex - 1 : bodyIndex];
149598
+ if (arrow?.text !== "=>") return null;
149599
+ const delegate = expectedTypeAt(snapshot, arrow.start);
149600
+ if (delegate?.kind !== "delegate") return null;
149601
+ return expectedCollectionElementType(
149602
+ delegate.returnType,
149603
+ tokens,
149604
+ returnToken?.end ?? body.start,
149605
+ offset
149606
+ );
149607
+ }
149001
149608
  if (returnToken && snapshot.context.returnType) {
149002
149609
  return expectedCollectionElementType(
149003
149610
  snapshot.context.returnType,
@@ -149145,12 +149752,13 @@ function initializerConstruction(snapshot, brace, constructor2) {
149145
149752
  }
149146
149753
  return construction;
149147
149754
  }
149148
- function initializerExpectedType(snapshot, offset) {
149755
+ function initializerExpectedType(snapshot, offset, bodyStart) {
149149
149756
  const features = scriptFeatureIndex(snapshot);
149150
149757
  const { tokens, enclosingOpener, callOpenings, objectInitializers } = features;
149151
149758
  let brace = innermostOpener(features, offset);
149152
149759
  for (; brace >= 0; brace = enclosingOpener[brace]) {
149153
149760
  const opener = tokens[brace];
149761
+ if (opener.start < bodyStart) return void 0;
149154
149762
  if (opener.text === "{") break;
149155
149763
  if (opener.text === "(" && callOpenings.has(opener.start)) return void 0;
149156
149764
  }
@@ -149644,10 +150252,7 @@ function resolveReference(snapshot, reference2) {
149644
150252
  return receiver ? resolveMemberOf(snapshot, reference2, receiver) : null;
149645
150253
  }
149646
150254
  function resolveMemberReceiver(snapshot, reference2) {
149647
- const expectedEnum = isContextualCompletionDot(
149648
- snapshot.source.text,
149649
- reference2.start
149650
- ) ? expectedEnumTypeAt(snapshot, reference2.start) : null;
150255
+ const expectedEnum = isContextualCompletionDot(snapshot, reference2.start) ? expectedEnumTypeAt(snapshot, reference2.start) : null;
149651
150256
  if (expectedEnum && enumMemberNamed(expectedEnum, reference2.name))
149652
150257
  return { kind: "enum", type: expectedEnum };
149653
150258
  const index = scriptFeatureIndex(snapshot);
@@ -149770,8 +150375,9 @@ function switchCaseEnumContext(snapshot, offset) {
149770
150375
  }
149771
150376
  return null;
149772
150377
  }
149773
- function resolveChain(snapshot, tokens, offset) {
150378
+ function resolveChain(snapshot, tokens, offset, expectedType) {
149774
150379
  if (tokens.length === 0) return null;
150380
+ const contextualConstructor = tokens[0]?.text === NEOSCRIPT_CONSTRUCTOR_KEYWORD && tokens[1]?.text === "(" && expectedType?.kind === "named" ? snapshot.project.typeById.get(expectedType.typeId) : void 0;
149775
150381
  const constructorType = tokens[0]?.kind === "identifier" && tokens[0].text === NEOSCRIPT_CONSTRUCTOR_KEYWORD && tokens[1]?.kind === "identifier" ? snapshot.project.typeByName.get(tokens[1].text) : void 0;
149776
150382
  const staticRoot = tokens[0]?.kind === "type" ? snapshot.project.typeByName.get(tokens[0].text) : void 0;
149777
150383
  let current;
@@ -149789,11 +150395,11 @@ function resolveChain(snapshot, tokens, offset) {
149789
150395
  staticType: staticRoot
149790
150396
  };
149791
150397
  cursor = 1;
149792
- } else if (constructorType?.constructorSignature) {
150398
+ } else if (contextualConstructor || constructorType?.constructorSignature) {
149793
150399
  current = {
149794
- type: constructedTypeRef(snapshot, constructorType, tokens, 1)
150400
+ type: contextualConstructor ? expectedType : constructedTypeRef(snapshot, constructorType, tokens, 1)
149795
150401
  };
149796
- cursor = new Parser(tokens, 1).typeEnd();
150402
+ cursor = contextualConstructor ? 1 : new Parser(tokens, 1).typeEnd();
149797
150403
  if (cursor < 0) return current;
149798
150404
  if (tokens[cursor]?.text === "(") {
149799
150405
  const close = findClosingToken(tokens, cursor, "(", ")");
@@ -149849,7 +150455,8 @@ function resolveChain(snapshot, tokens, offset) {
149849
150455
  }
149850
150456
  if (token.kind === "punctuation" && token.text === "(") {
149851
150457
  const close = findClosingToken(tokens, cursor, "(", ")");
149852
- const fallbackType = current.symbol?.returnType ?? current.type;
150458
+ const valueReturnType = current.type.kind === "delegate" ? current.type.returnType : current.type;
150459
+ const fallbackType = current.symbol?.returnType ?? valueReturnType;
149853
150460
  const callType = (current.symbol?.name === "Select" || current.symbol?.name === "SelectMany") && close >= 0 ? inferSelectResultType(
149854
150461
  tokens.slice(cursor + 1, close),
149855
150462
  snapshot,
@@ -150263,30 +150870,77 @@ function inferLocalType(local, snapshot) {
150263
150870
  }
150264
150871
  return UNKNOWN_TYPE;
150265
150872
  }
150266
- function inferExpressionType2(rawTokens, snapshot, offset) {
150873
+ function inferExpressionType2(rawTokens, snapshot, offset, expectedType) {
150267
150874
  const tokens = unwrapExpressionTokens(rawTokens);
150268
150875
  const first = tokens[0];
150269
150876
  if (!first) return UNKNOWN_TYPE;
150877
+ const question = topLevelTokenIndex(tokens, (token) => token.text === "?");
150878
+ if (question > 0) {
150879
+ const branches = tokens.slice(question + 1);
150880
+ let nested = 0;
150881
+ const colon = topLevelTokenIndex(branches, (token) => {
150882
+ if (token.text === "?") nested++;
150883
+ if (token.text !== ":") return false;
150884
+ return nested-- === 0;
150885
+ });
150886
+ if (colon < 0) return UNKNOWN_TYPE;
150887
+ const whenTrue = unwrapExpressionTokens(branches.slice(0, colon));
150888
+ const whenFalse = unwrapExpressionTokens(branches.slice(colon + 1));
150889
+ const inferFalseFirst = whenTrue[0]?.text === "null" || whenTrue[0]?.text === ".";
150890
+ let left;
150891
+ let right;
150892
+ if (inferFalseFirst && !expectedType) {
150893
+ right = inferExpressionType2(whenFalse, snapshot, offset);
150894
+ left = inferExpressionType2(whenTrue, snapshot, offset, right);
150895
+ } else {
150896
+ left = inferExpressionType2(whenTrue, snapshot, offset, expectedType);
150897
+ right = inferExpressionType2(
150898
+ whenFalse,
150899
+ snapshot,
150900
+ offset,
150901
+ expectedType ?? left
150902
+ );
150903
+ }
150904
+ return commonNeoScriptAssignableType(left, right, snapshot.project) ?? UNKNOWN_TYPE;
150905
+ }
150270
150906
  if (first.kind === "string") {
150271
150907
  return { kind: "primitive", name: "string" };
150272
150908
  }
150273
- if (first.kind === "keyword" && first.text === "null") return UNKNOWN_TYPE;
150909
+ if (first.kind === "keyword" && first.text === "null") {
150910
+ return expectedType ? withNullability(expectedType, true) : UNKNOWN_TYPE;
150911
+ }
150912
+ if (first.text === "." && expectedType?.kind === "named") {
150913
+ const type = snapshot.project.typeById.get(expectedType.typeId);
150914
+ if (type?.kind === "enum" && tokens[1] && enumMemberNamed(type, tokens[1].text))
150915
+ return expectedType;
150916
+ }
150274
150917
  if (first.kind === "punctuation" && first.text === "[" && matchingDelimiterIndex(tokens, 0) === tokens.length - 1) {
150275
150918
  const entries = splitTopLevel2(tokens.slice(1, -1), ",");
150276
- if (entries.length === 0) return UNKNOWN_TYPE;
150919
+ const expectedElement = expectedType?.kind === "list" ? expectedType.elementType : void 0;
150920
+ if (entries.length === 0)
150921
+ return expectedType?.kind === "list" ? expectedType : UNKNOWN_TYPE;
150277
150922
  const elementType = commonInferredType(
150278
- entries.map((entry) => inferExpressionType2(entry, snapshot, offset)),
150923
+ entries.map(
150924
+ (entry) => inferExpressionType2(entry, snapshot, offset, expectedElement)
150925
+ ),
150279
150926
  snapshot.project
150280
150927
  );
150281
150928
  return elementType === UNKNOWN_TYPE ? UNKNOWN_TYPE : { kind: "list", elementType };
150282
150929
  }
150283
150930
  if (first.kind === "punctuation" && first.text === "{" && matchingDelimiterIndex(tokens, 0) === tokens.length - 1) {
150284
150931
  const entries = splitTopLevel2(tokens.slice(1, -1), ",");
150285
- if (entries.length === 0) return UNKNOWN_TYPE;
150932
+ const expectedValue = expectedType?.kind === "dictionary" ? expectedType.valueType : void 0;
150933
+ if (entries.length === 0)
150934
+ return expectedType?.kind === "dictionary" ? expectedType : UNKNOWN_TYPE;
150286
150935
  const valueType = commonInferredType(
150287
150936
  entries.map((entry) => {
150288
150937
  const colon = topLevelTokenIndex(entry, (token) => token.text === ":");
150289
- return colon < 0 ? UNKNOWN_TYPE : inferExpressionType2(entry.slice(colon + 1), snapshot, offset);
150938
+ return colon < 0 ? UNKNOWN_TYPE : inferExpressionType2(
150939
+ entry.slice(colon + 1),
150940
+ snapshot,
150941
+ offset,
150942
+ expectedValue
150943
+ );
150290
150944
  }),
150291
150945
  snapshot.project
150292
150946
  );
@@ -150348,7 +151002,7 @@ function inferExpressionType2(rawTokens, snapshot, offset) {
150348
151002
  if (first.kind === "operator" && (first.text === "!" || first.text === "-")) {
150349
151003
  return first.text === "!" ? { kind: "primitive", name: "bool" } : inferExpressionType2(tokens.slice(1), snapshot, offset);
150350
151004
  }
150351
- return resolveChain(snapshot, tokens, offset)?.type ?? UNKNOWN_TYPE;
151005
+ return resolveChain(snapshot, tokens, offset, expectedType)?.type ?? UNKNOWN_TYPE;
150352
151006
  }
150353
151007
  function unwrapExpressionTokens(tokens) {
150354
151008
  let result = tokens;
@@ -180139,8 +180793,9 @@ function createPostPushCompileContext(schema) {
180139
180793
  const classesById = /* @__PURE__ */ new Map();
180140
180794
  const ownersByMemberId = /* @__PURE__ */ new Map();
180141
180795
  for (const member of schema.members) {
180142
- if (typeof member.id !== "string") continue;
180143
- if (!membersById.has(member.id)) membersById.set(member.id, member);
180796
+ const id2 = member.id;
180797
+ if (typeof id2 !== "string") continue;
180798
+ if (!membersById.has(id2)) membersById.set(id2, member);
180144
180799
  }
180145
180800
  for (const schemaClass2 of schema.classes) {
180146
180801
  if (typeof schemaClass2.id === "string" && !classesById.has(schemaClass2.id)) {
@@ -180166,7 +180821,6 @@ function createPostPushCompileContext(schema) {
180166
180821
  };
180167
180822
  }
180168
180823
  function containingClass(context, memberId) {
180169
- if (typeof memberId !== "string") return null;
180170
180824
  return context.ownersByMemberId.get(memberId) ?? null;
180171
180825
  }
180172
180826
  function bodyOwnerName(thisClass) {
@@ -180175,7 +180829,7 @@ function bodyOwnerName(thisClass) {
180175
180829
  return thisClass.name;
180176
180830
  }
180177
180831
  function compileNSPropertyChange(context, memberData, locator) {
180178
- const memberId = memberData.id;
180832
+ const memberId = String(memberData.id);
180179
180833
  const thisClass = containingClass(context, memberId);
180180
180834
  const returnTypeInfo = resolveNSPropertyReturnTypeInfo2(
180181
180835
  memberData,
@@ -180183,7 +180837,7 @@ function compileNSPropertyChange(context, memberData, locator) {
180183
180837
  );
180184
180838
  const bodyIdentity = {
180185
180839
  recordKind: "member",
180186
- recordId: String(memberId),
180840
+ recordId: memberId,
180187
180841
  ownerName: bodyOwnerName(thisClass),
180188
180842
  memberName: String(memberData.name ?? memberId)
180189
180843
  };
@@ -180194,7 +180848,7 @@ function compileNSPropertyChange(context, memberData, locator) {
180194
180848
  () => compileNSGetter2(code, {
180195
180849
  source: context.scriptSources.get(`member:${memberId}`)?.getter,
180196
180850
  ...context.project(),
180197
- memberId: String(memberData.id),
180851
+ memberId,
180198
180852
  thisClass,
180199
180853
  returnTypeInfo,
180200
180854
  dialogueContext: null,
@@ -180213,7 +180867,7 @@ function compileNSPropertyChange(context, memberData, locator) {
180213
180867
  () => compileNSSetter2(setterCode, {
180214
180868
  source: context.scriptSources.get(`member:${memberId}`)?.setter,
180215
180869
  ...context.project(),
180216
- memberId: String(memberData.id),
180870
+ memberId,
180217
180871
  thisClass,
180218
180872
  valueTypeInfo: returnTypeInfo,
180219
180873
  implicitMemberAccess: true,
@@ -180234,26 +180888,28 @@ function compileNSFunctionChange(context, memberData, locator) {
180234
180888
  return next;
180235
180889
  }
180236
180890
  const code = memberData.code;
180891
+ const memberId = String(memberData.id);
180892
+ const memberName = String(memberData.name ?? memberId);
180237
180893
  const contract = resolveNSFunctionContract(memberData, context.membersById);
180238
- const thisClass = containingClass(context, memberData.id);
180894
+ const thisClass = containingClass(context, memberId);
180239
180895
  next.action = compileNeoScriptBodyOrThrow(
180240
180896
  () => compileNSFunction2(code, {
180241
- source: context.scriptSources.get(`member:${memberData.id}`)?.action,
180897
+ source: context.scriptSources.get(`member:${memberId}`)?.action,
180242
180898
  ...context.project(),
180243
- memberId: String(memberData.id),
180899
+ memberId,
180244
180900
  thisClass,
180245
180901
  returnTypeInfo: contract.returnTypeInfo,
180246
180902
  argumentTypes: contract.argumentTypes,
180247
180903
  deferred: contract.deferred,
180248
- functionName: String(memberData.name ?? memberData.id),
180904
+ functionName: memberName,
180249
180905
  implicitMemberAccess: true,
180250
180906
  staticMember: memberData.modifier === 3
180251
180907
  }),
180252
180908
  {
180253
180909
  recordKind: "member",
180254
- recordId: String(memberData.id),
180910
+ recordId: memberId,
180255
180911
  ownerName: bodyOwnerName(thisClass),
180256
- memberName: String(memberData.name ?? memberData.id),
180912
+ memberName,
180257
180913
  unit: "function",
180258
180914
  code
180259
180915
  },
@@ -180313,17 +180969,18 @@ function prepareCompleteNeoScriptBodyChanges(workspace, status, schema, options
180313
180969
  ["constructor", schema.constructors]
180314
180970
  ]) {
180315
180971
  for (const row of records3) {
180316
- if (typeof row.id !== "string") continue;
180317
- if (!refreshSourceLocations && !changedSources.has(recordStateKey(kind, row.id)))
180972
+ const id2 = row.id;
180973
+ if (typeof id2 !== "string") continue;
180974
+ if (!refreshSourceLocations && !changedSources.has(recordStateKey(kind, id2)))
180318
180975
  continue;
180319
- const owner = kind === "constructor" ? context.classesById.get(String(row.classId)) : context.ownersByMemberId.get(row.id);
180976
+ const owner = kind === "constructor" ? context.classesById.get(String(row.classId)) : context.ownersByMemberId.get(id2);
180320
180977
  if (typeof owner?.name !== "string") continue;
180321
180978
  const sources2 = {};
180322
180979
  for (const key of ["getter", "setter", "action"]) {
180323
180980
  const code = row[key === "setter" ? "setterCode" : "code"];
180324
180981
  if (typeof code !== "string") continue;
180325
180982
  const unit = kind === "constructor" ? "constructor" : key === "action" ? "function" : key;
180326
- const body = kind === "constructor" ? constructorBodies.get(row.id) : bodies.get(bodyKey(owner.name, String(row.name), unit));
180983
+ const body = kind === "constructor" ? constructorBodies.get(id2) : bodies.get(bodyKey(owner.name, String(row.name), unit));
180327
180984
  if (!body?.ir.source) continue;
180328
180985
  let text = sourceTexts.get(body.uri);
180329
180986
  if (text === void 0) {
@@ -180340,7 +180997,7 @@ function prepareCompleteNeoScriptBodyChanges(workspace, status, schema, options
180340
180997
  );
180341
180998
  if (source) sources2[key] = { code, source };
180342
180999
  }
180343
- context.scriptSources.set(`${kind}:${row.id}`, sources2);
181000
+ context.scriptSources.set(`${kind}:${id2}`, sources2);
180344
181001
  }
180345
181002
  }
180346
181003
  status.scriptSources = context.scriptSources;
@@ -180348,25 +181005,21 @@ function prepareCompleteNeoScriptBodyChanges(workspace, status, schema, options
180348
181005
  status.changes.filter((change) => change.recordKind === "member").map((change) => [change.recordId, change])
180349
181006
  );
180350
181007
  const explicitlyChangedMemberIds = new Set(changesById.keys());
180351
- const movedMemberIds = new Set(
180352
- schema.members.filter((member) => {
180353
- const source = context.scriptSources.get(`member:${member.id}`);
180354
- return source && neoScriptSourceLocationsChanged(
180355
- neoScriptRecordSources(member),
180356
- source
180357
- );
180358
- }).map((member) => String(member.id))
180359
- );
181008
+ const movedMemberIds = /* @__PURE__ */ new Set();
180360
181009
  const compiledMembers = schema.members.map((member) => {
180361
- if (!completeSweep && !explicitlyChangedMemberIds.has(String(member.id)) && !movedMemberIds.has(String(member.id))) {
180362
- return member;
180363
- }
180364
- if (!completeSweep && !explicitlyChangedMemberIds.has(String(member.id))) {
180365
- const base = workspace.state.records[recordStateKey("member", String(member.id))]?.data;
180366
- const sources2 = context.scriptSources.get(`member:${member.id}`);
180367
- if (isObjectRecord2(base) && sources2) {
180368
- const moved = remapNeoScriptRecord(base, sources2);
180369
- if (moved) return mergeCompiledNeoScriptBody(member, moved);
181010
+ const id2 = String(member.id);
181011
+ if (!completeSweep && !explicitlyChangedMemberIds.has(id2)) {
181012
+ const sources2 = context.scriptSources.get(`member:${id2}`);
181013
+ if (sources2 === void 0 || !neoScriptSourceLocationsChanged(
181014
+ neoScriptRecordSources(member),
181015
+ sources2
181016
+ ))
181017
+ return member;
181018
+ movedMemberIds.add(id2);
181019
+ const base = workspace.state.records[recordStateKey("member", id2)]?.data;
181020
+ if (isObjectRecord2(base)) {
181021
+ const remapped = remapNeoScriptRecord(base, sources2);
181022
+ if (remapped) return mergeCompiledNeoScriptBody(member, remapped);
180370
181023
  }
180371
181024
  }
180372
181025
  if (member.kind === 10 /* NSProperty */) {
@@ -186712,6 +187365,7 @@ function validateRegistrationAction(action, allowRegistration) {
186712
187365
  }
186713
187366
  }
186714
187367
  function registerSpec(spec, document) {
187368
+ document = withCompiledConstructionTypes(document, spec.action);
186715
187369
  validateRegistrationAction(spec.action, true);
186716
187370
  const root = {
186717
187371
  name: "",
@@ -186792,7 +187446,7 @@ function registerSpec(spec, document) {
186792
187446
  makeEvaluatorContext(document, interceptor),
186793
187447
  []
186794
187448
  );
186795
- return { spec, root, tests };
187449
+ return { spec, root, tests, document };
186796
187450
  }
186797
187451
  function mockResponse(environment, mock, selected, call) {
186798
187452
  if (selected === null) {
@@ -187215,13 +187869,13 @@ function prepareTestEvaluator(document) {
187215
187869
  async function executeTestFile(spec, document, selected, timeoutMs, interrupted = () => false) {
187216
187870
  return executeRegisteredSpec(
187217
187871
  registerSpec(spec, document),
187218
- document,
187219
187872
  selected,
187220
187873
  timeoutMs,
187221
187874
  interrupted
187222
187875
  );
187223
187876
  }
187224
- async function executeRegisteredSpec(registered, document, selected, timeoutMs, interrupted) {
187877
+ async function executeRegisteredSpec(registered, selected, timeoutMs, interrupted) {
187878
+ const document = registered.document;
187225
187879
  let restoredRuntimeSources = false;
187226
187880
  const reportFailure = (error, position, member = null) => {
187227
187881
  if (error instanceof NSGetterRuntimeError && error.node !== void 0 && (error.source === void 0 || error.callerNode !== void 0 && runtimeSource(error.callerNode) === void 0)) {
@@ -187564,7 +188218,6 @@ async function runTest(workspace, options, dependencies = {}) {
187564
188218
  entry.spec,
187565
188219
  await executeRegisteredSpec(
187566
188220
  entry,
187567
- rawDocument,
187568
188221
  selectedIds,
187569
188222
  timeoutMs,
187570
188223
  () => interrupted
@@ -187837,6 +188490,7 @@ var TEST_BUILD_CACHE_LIMIT_BYTES, ABANDONED_TEMP_MAX_AGE_MS, TEST_CANDIDATE_CACH
187837
188490
  var init_test = __esm({
187838
188491
  "src/commands/test.ts"() {
187839
188492
  "use strict";
188493
+ init_compiled_construction_types();
187840
188494
  init_debug();
187841
188495
  init_neoscript_debug();
187842
188496
  init_strict_compile_error();
@@ -194819,7 +195473,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
194819
195473
  async function main() {
194820
195474
  const args = parseArgs(process.argv.slice(2));
194821
195475
  if (args.command === "--version") {
194822
- console.log("0.76.2");
195476
+ console.log("0.76.3");
194823
195477
  return;
194824
195478
  }
194825
195479
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {