@neocompose/cli 0.22.3 → 0.22.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.5] - 2026-08-04
4
+
5
+ ### Fixed
6
+
7
+ - Pull reconstructs required constructor calls from legacy declaration rows
8
+ whose projected fields remain initializer-backed, including animation segment
9
+ frames that depend on their declaring class's parameters.
10
+ - Existing call-site initializer blocks may repeat a field settled by a required
11
+ constructor, preserving the language's normal last-write-wins semantics while
12
+ old canonical source converges.
13
+ - System-schema repair restores tombstoned constructor-projected declaration
14
+ rows, rewrites only callers that reference retired member identities, and
15
+ recompiles only the impacted records through the normal push pipeline.
16
+
17
+ ## [0.22.4] - 2026-08-04
18
+
19
+ ### Fixed
20
+
21
+ - Normal and reset pulls now replay stored immutable system constructions and
22
+ resolve constructor parameter scopes through deeply nested initializer rows.
23
+ - Pull projection accepts migrated constructor arguments on implicitly typed
24
+ list entries, including animation segment frames.
25
+
3
26
  ## [0.22.3] - 2026-08-04
4
27
 
5
28
  ### Fixed
package/dist/neo.mjs CHANGED
@@ -8954,7 +8954,8 @@ var init_strict_resolver = __esm({
8954
8954
  className,
8955
8955
  expression,
8956
8956
  scope,
8957
- expression.pos
8957
+ expression.pos,
8958
+ expected
8958
8959
  );
8959
8960
  }
8960
8961
  if (expression.argumentNames && !projectionCall) {
@@ -10396,11 +10397,18 @@ var init_strict_resolver = __esm({
10396
10397
  pos
10397
10398
  );
10398
10399
  }
10399
- const signature = schemaClass2.constructorSignature;
10400
+ const replayingStoredConstruction = this.context.storedConstructionReplay === true;
10401
+ if (schemaClass2.constructorUnavailableReason === "immutableOnly" && !replayingStoredConstruction) {
10402
+ throw new CompileError(
10403
+ `Cannot construct Immutable-only Class '${className}'; constructors create writable Session values.`,
10404
+ pos
10405
+ );
10406
+ }
10407
+ const signature = schemaClass2.constructorSignature ?? (replayingStoredConstruction ? schemaClass2.storedConstructionReplaySignature : void 0);
10400
10408
  if (!signature) {
10401
10409
  const open = (schemaClass2.typeParameters?.length ?? 0) > 0;
10402
10410
  throw new CompileError(
10403
- schemaClass2.constructorUnavailableReason === "immutableOnly" ? `Cannot construct Immutable-only Class '${className}'; constructors create writable Session values.` : open ? `Cannot construct open generic Class '${className}'; construct a closed named descendant.` : `Class '${className}' does not expose a generated public constructor.`,
10411
+ open ? `Cannot construct open generic Class '${className}'; construct a closed named descendant.` : `Class '${className}' does not expose a generated public constructor.`,
10404
10412
  pos
10405
10413
  );
10406
10414
  }
@@ -10581,7 +10589,7 @@ var init_strict_resolver = __esm({
10581
10589
  * the call site's initializer block is carried through to be applied last
10582
10590
  * (§6.1 step 4).
10583
10591
  */
10584
- resolveDeclaredConstructor(className, expression, scope, pos) {
10592
+ resolveDeclaredConstructor(className, expression, scope, pos, expected) {
10585
10593
  const schemaClass2 = this.project.typeByName.get(className);
10586
10594
  if (!schemaClass2 || schemaClass2.kind !== "class") {
10587
10595
  throw new CompileError(
@@ -10595,13 +10603,30 @@ var init_strict_resolver = __esm({
10595
10603
  pos
10596
10604
  );
10597
10605
  }
10598
- if (schemaClass2.constructorUnavailableReason === "immutableOnly") {
10606
+ if (schemaClass2.constructorUnavailableReason === "immutableOnly" && this.context.storedConstructionReplay !== true) {
10599
10607
  throw new CompileError(
10600
10608
  `Cannot construct Immutable-only Class '${className}'; constructors create writable Session values.`,
10601
10609
  pos
10602
10610
  );
10603
10611
  }
10604
- const declared = schemaClass2.declaredConstructors ?? [];
10612
+ const targetType = this.constructorTargetType(
10613
+ schemaClass2,
10614
+ expression,
10615
+ expected
10616
+ );
10617
+ const declared = (schemaClass2.declaredConstructors ?? []).map(
10618
+ (constructor2) => ({
10619
+ ...constructor2,
10620
+ parameters: constructor2.parameters.map((parameter3) => ({
10621
+ ...parameter3,
10622
+ type: substituteTypeParameters(
10623
+ parameter3.type,
10624
+ targetType,
10625
+ schemaClass2
10626
+ )
10627
+ }))
10628
+ })
10629
+ );
10605
10630
  const argumentNames = expression.args.map(
10606
10631
  (_, index) => expression.argumentNames?.[index] ?? null
10607
10632
  );
@@ -10642,10 +10667,7 @@ var init_strict_resolver = __esm({
10642
10667
  expression,
10643
10668
  scope
10644
10669
  );
10645
- const classType = {
10646
- kind: "named",
10647
- typeId: schemaClass2.id
10648
- };
10670
+ const classType = targetType;
10649
10671
  const schemaClassInfo = toWireType(classType, this.project);
10650
10672
  if (schemaClassInfo.type !== 7 /* Class */) {
10651
10673
  throw new Error(
@@ -26032,9 +26054,6 @@ function attachConstructorSignature(type, environment) {
26032
26054
  )) {
26033
26055
  return type;
26034
26056
  }
26035
- if (resolvedAllowedStorage(type.id, environment) === "immutable") {
26036
- return { ...type, constructorUnavailableReason: "immutableOnly" };
26037
- }
26038
26057
  const constructorSignature2 = buildNeoScriptConstructorSignature(
26039
26058
  type.id,
26040
26059
  type.members,
@@ -26052,6 +26071,13 @@ function attachConstructorSignature(type, environment) {
26052
26071
  } : null;
26053
26072
  }
26054
26073
  );
26074
+ if (resolvedAllowedStorage(type.id, environment) === "immutable") {
26075
+ return {
26076
+ ...type,
26077
+ storedConstructionReplaySignature: constructorSignature2,
26078
+ constructorUnavailableReason: "immutableOnly"
26079
+ };
26080
+ }
26055
26081
  return { ...type, constructorSignature: constructorSignature2 };
26056
26082
  }
26057
26083
  function resolvedAllowedStorage(classId, environment) {
@@ -38844,8 +38870,145 @@ function substituteMember(member, env, members) {
38844
38870
  };
38845
38871
  return substituted;
38846
38872
  }
38873
+ if (isMemberDelegateBase(resolved)) {
38874
+ const returnTypeInfo = substituteNestedTypeInfo(
38875
+ resolved.returnTypeInfo,
38876
+ env,
38877
+ members
38878
+ );
38879
+ let argumentsChanged = false;
38880
+ const argumentTypes = resolved.argumentTypes.map((argument2) => {
38881
+ const substituted2 = substituteNestedTypeInfo(argument2, env, members);
38882
+ if (substituted2 === argument2) return argument2;
38883
+ argumentsChanged = true;
38884
+ return { ...substituted2, name: argument2.name };
38885
+ });
38886
+ if (returnTypeInfo === resolved.returnTypeInfo && !argumentsChanged) {
38887
+ return resolved;
38888
+ }
38889
+ const substituted = {
38890
+ ...resolved,
38891
+ returnTypeInfo,
38892
+ argumentTypes
38893
+ };
38894
+ return substituted;
38895
+ }
38847
38896
  return resolved;
38848
38897
  }
38898
+ function substituteNestedTypeInfo(typeInfo, env, members) {
38899
+ if (typeInfo.type === 21 /* Generic */) {
38900
+ const entry = env.get(typeInfo.genericParamId);
38901
+ if (entry === void 0) {
38902
+ throw new Error(
38903
+ `substituteMember: callable type references generic param "${typeInfo.genericParamId}", which is not present in the binding environment.`
38904
+ );
38905
+ }
38906
+ if (entry.kind === "unbound") return typeInfo;
38907
+ const binding = members.find(
38908
+ (candidate) => candidate.id === entry.memberId
38909
+ );
38910
+ if (binding === void 0) {
38911
+ throw new Error(
38912
+ `substituteMember: callable type binding member "${entry.memberId}" for generic param "${typeInfo.genericParamId}" does not exist in the document.`
38913
+ );
38914
+ }
38915
+ return genericBindingTypeInfo(binding, env, members);
38916
+ }
38917
+ if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
38918
+ return {
38919
+ ...typeInfo,
38920
+ entryTypeInfo: substituteNestedTypeInfo(
38921
+ typeInfo.entryTypeInfo,
38922
+ env,
38923
+ members
38924
+ )
38925
+ };
38926
+ }
38927
+ if (typeInfo.type === 7 /* Class */) {
38928
+ const typeArguments = typeInfo.typeArguments;
38929
+ if (typeArguments === void 0) return typeInfo;
38930
+ return {
38931
+ ...typeInfo,
38932
+ typeArguments: Object.fromEntries(
38933
+ Object.entries(typeArguments).map(([parameterId, argument2]) => [
38934
+ parameterId,
38935
+ substituteNestedTypeInfo(argument2, env, members)
38936
+ ])
38937
+ )
38938
+ };
38939
+ }
38940
+ if (typeInfo.type === 25 /* NSDelegate */) {
38941
+ return {
38942
+ ...typeInfo,
38943
+ returnTypeInfo: substituteNestedTypeInfo(
38944
+ typeInfo.returnTypeInfo,
38945
+ env,
38946
+ members
38947
+ ),
38948
+ argumentTypes: typeInfo.argumentTypes.map(
38949
+ (argument2) => substituteNestedTypeInfo(argument2, env, members)
38950
+ )
38951
+ };
38952
+ }
38953
+ return typeInfo;
38954
+ }
38955
+ function genericBindingTypeInfo(rawMember, env, members) {
38956
+ return typeInfoFromArgumentSignature(
38957
+ typeArgumentSignatureOfMember(rawMember, env, members)
38958
+ );
38959
+ }
38960
+ function typeInfoFromArgumentSignature(signature) {
38961
+ if (signature.type === 7 /* Class */) {
38962
+ const classSignature = signature;
38963
+ return {
38964
+ type: 7 /* Class */,
38965
+ required: classSignature.required,
38966
+ classId: classSignature.classId,
38967
+ ...Object.keys(classSignature.args).length === 0 ? {} : {
38968
+ typeArguments: Object.fromEntries(
38969
+ Object.entries(classSignature.args).map(
38970
+ ([parameterId, argument2]) => [
38971
+ parameterId,
38972
+ typeInfoFromArgumentSignature(argument2)
38973
+ ]
38974
+ )
38975
+ )
38976
+ }
38977
+ };
38978
+ }
38979
+ if (signature.type === 8 /* Enum */) {
38980
+ const enumSignature = signature;
38981
+ return {
38982
+ type: 8 /* Enum */,
38983
+ required: enumSignature.required,
38984
+ enumId: enumSignature.enumId
38985
+ };
38986
+ }
38987
+ if (signature.type === 6 /* List */) {
38988
+ const listSignature = signature;
38989
+ return {
38990
+ type: 6 /* List */,
38991
+ required: listSignature.required,
38992
+ entryTypeInfo: typeInfoFromArgumentSignature(listSignature.entry)
38993
+ };
38994
+ }
38995
+ if (signature.type === 5 /* Dictionary */) {
38996
+ const dictionarySignature = signature;
38997
+ return {
38998
+ type: 5 /* Dictionary */,
38999
+ required: dictionarySignature.required,
39000
+ entryTypeInfo: typeInfoFromArgumentSignature(dictionarySignature.entry),
39001
+ ...dictionarySignature.keyEnumId === void 0 ? {} : { keyEnumId: dictionarySignature.keyEnumId }
39002
+ };
39003
+ }
39004
+ const typeInfo = { type: signature.type, required: signature.required };
39005
+ if (!isNSTypeInfo(typeInfo)) {
39006
+ throw new Error(
39007
+ `substituteMember: generic binding kind ${signature.type} cannot appear in a NeoScript callable type.`
39008
+ );
39009
+ }
39010
+ return typeInfo;
39011
+ }
38849
39012
  function resolveTerminalBinding(genericParamId, slotName, env, members) {
38850
39013
  const entry = env.get(genericParamId);
38851
39014
  if (entry === void 0) {
@@ -39126,6 +39289,7 @@ var init_generics = __esm({
39126
39289
  "../src/models/classes/generics.ts"() {
39127
39290
  "use strict";
39128
39291
  init_member_kinds();
39292
+ init_neoscript();
39129
39293
  init_world_system_classes();
39130
39294
  init_structural_narrow();
39131
39295
  init_inheritance();
@@ -51136,7 +51300,33 @@ function constructorSignature(schemaClass2, members, context, genericEnvironment
51136
51300
  return {};
51137
51301
  }
51138
51302
  if (resolveAllowedStorage(schemaClass2.id, context.vm.classes) === "immutable" /* Immutable */) {
51139
- return { constructorUnavailableReason: "immutableOnly" };
51303
+ const signature2 = buildNeoScriptConstructorSignature(
51304
+ schemaClass2.id,
51305
+ members,
51306
+ (memberId) => {
51307
+ const record3 = analyzerMemberById(context.vm, memberId);
51308
+ if (!record3) return null;
51309
+ try {
51310
+ const resolved = substituteMember(
51311
+ record3,
51312
+ genericEnvironment,
51313
+ context.vm.members
51314
+ );
51315
+ return {
51316
+ required: resolved.required,
51317
+ defaultValue: "defaultValue" in resolved ? resolved.defaultValue : void 0
51318
+ };
51319
+ } catch {
51320
+ return projections.some(
51321
+ (projection) => projection.memberId === memberId
51322
+ ) ? { required: true } : null;
51323
+ }
51324
+ }
51325
+ );
51326
+ return {
51327
+ storedConstructionReplaySignature: signature2,
51328
+ constructorUnavailableReason: "immutableOnly"
51329
+ };
51140
51330
  }
51141
51331
  const signature = buildNeoScriptConstructorSignature(
51142
51332
  schemaClass2.id,
@@ -52306,6 +52496,7 @@ function compileStrict(code, context) {
52306
52496
  deferred: context.deferred,
52307
52497
  functionName: context.functionName,
52308
52498
  migrationContext: context.migrationContext,
52499
+ storedConstructionReplay: context.storedConstructionReplay,
52309
52500
  valueAliases: context.valueAliases,
52310
52501
  implicitMemberAccess: context.implicitMemberAccess,
52311
52502
  declaringType: context.declaringType,
@@ -52370,9 +52561,10 @@ function createContext(ctx, options) {
52370
52561
  analyzer,
52371
52562
  ctx.compilationProject
52372
52563
  );
52373
- if (ctx.implicitMemberAccess !== true) return adapted;
52564
+ const replayContext = ctx.storedConstructionReplay === true ? { ...adapted, storedConstructionReplay: true } : adapted;
52565
+ if (ctx.implicitMemberAccess !== true) return replayContext;
52374
52566
  return {
52375
- ...adapted,
52567
+ ...replayContext,
52376
52568
  ...ctx.staticMember === true ? { thisClass: void 0 } : {},
52377
52569
  implicitMemberAccess: true,
52378
52570
  ...adapted.thisClass ? { declaringType: adapted.thisClass } : {},
@@ -52681,7 +52873,8 @@ function compileValueRowInitializerBody(args) {
52681
52873
  args.initializerOwnerClass,
52682
52874
  args.constructors ?? []
52683
52875
  ),
52684
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject }
52876
+ ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
52877
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
52685
52878
  })
52686
52879
  );
52687
52880
  } catch (error) {
@@ -54975,7 +55168,12 @@ function makeEvaluatorLookups(members, values, options = {}) {
54975
55168
  if (options.includeValueGraphIndexes === true) {
54976
55169
  return {
54977
55170
  ...lookups,
54978
- evaluatorIndexes: buildEvaluatorBaseIndexes(members, values, valMap)
55171
+ evaluatorIndexes: buildEvaluatorBaseIndexes(members, values, valMap),
55172
+ ...options.constructorInitializerDocument === void 0 ? {} : {
55173
+ constructorInitializerIndexes: buildConstructorInitializerIndexes(
55174
+ options.constructorInitializerDocument
55175
+ )
55176
+ }
54979
55177
  };
54980
55178
  }
54981
55179
  return lookups;
@@ -58891,12 +59089,19 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
58891
59089
  `Cannot construct abstract Class '${schemaClass2.name}'.`
58892
59090
  );
58893
59091
  }
58894
- if (!isClosedClass(classId, ctx.vm.classes)) {
59092
+ const replaySlot = ctx.__storedConstructionReplaySlot;
59093
+ const classArguments2 = replaySlot?.classId === classId ? replaySlot.classArguments : void 0;
59094
+ const instanceEnv = resolveInstanceEnv(
59095
+ classId,
59096
+ classArguments2,
59097
+ ctx.vm.classes
59098
+ );
59099
+ if (firstUnboundParamId(instanceEnv) !== null) {
58895
59100
  throw new NSGetterRuntimeError(
58896
59101
  `Cannot construct open generic Class '${schemaClass2.name}'.`
58897
59102
  );
58898
59103
  }
58899
- if (resolveAllowedStorage(classId, ctx.vm.classes) === "immutable" /* Immutable */) {
59104
+ if (resolveAllowedStorage(classId, ctx.vm.classes) === "immutable" /* Immutable */ && ctx.storedConstructionReplay !== true) {
58900
59105
  throw new NSGetterRuntimeError(
58901
59106
  `Cannot construct Immutable-only Class '${schemaClass2.name}'.`
58902
59107
  );
@@ -58916,7 +59121,6 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
58916
59121
  const schemaByKey = new Map(
58917
59122
  mergedSchema.map((entry) => [entry.schemaKey, entry])
58918
59123
  );
58919
- const instanceEnv = resolveInstanceEnv(classId, void 0, ctx.vm.classes);
58920
59124
  const seenSchemaKeys = /* @__PURE__ */ new Set();
58921
59125
  const seenMemberIds = /* @__PURE__ */ new Set();
58922
59126
  const fields = [];
@@ -58967,7 +59171,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
58967
59171
  );
58968
59172
  }
58969
59173
  if (!requireEveryRequiredField) {
58970
- return { schemaClass: schemaClass2, fields, instanceEnv };
59174
+ return { schemaClass: schemaClass2, fields, instanceEnv, classArguments: classArguments2 };
58971
59175
  }
58972
59176
  for (const entry of mergedSchema) {
58973
59177
  const rawMember = evalMemberById(ctx.vm, entry.memberId);
@@ -58990,7 +59194,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
58990
59194
  );
58991
59195
  }
58992
59196
  }
58993
- return { schemaClass: schemaClass2, fields, instanceEnv };
59197
+ return { schemaClass: schemaClass2, fields, instanceEnv, classArguments: classArguments2 };
58994
59198
  }
58995
59199
  function assertConstructorFieldSlotWritable(args) {
58996
59200
  const surfaceEntry = mergeInstanceSchema(
@@ -59073,11 +59277,12 @@ function evaluateConstructorFields(descriptor, scope, ctx) {
59073
59277
  return { validated, value };
59074
59278
  });
59075
59279
  }
59076
- function syntheticConstructorMember(schemaClass2) {
59280
+ function syntheticConstructorMember(schemaClass2, classArguments2) {
59077
59281
  return {
59078
59282
  name: `new ${schemaClass2.name}`,
59079
59283
  kind: 7 /* Class */,
59080
59284
  classId: schemaClass2.id,
59285
+ ...classArguments2 === void 0 ? {} : { classArguments: classArguments2 },
59081
59286
  locked: false,
59082
59287
  required: true,
59083
59288
  isStatic: false,
@@ -59308,7 +59513,10 @@ function constructClassValueWithinFrame(descriptor, scope, ctx) {
59308
59513
  const schemaClass2 = descriptor.schemaClass;
59309
59514
  const classId = schemaClass2.id;
59310
59515
  const supplied = evaluateConstructorFields(descriptor, scope, ctx);
59311
- const syntheticMember = syntheticConstructorMember(schemaClass2);
59516
+ const syntheticMember = syntheticConstructorMember(
59517
+ schemaClass2,
59518
+ descriptor.classArguments
59519
+ );
59312
59520
  const createdValues = [];
59313
59521
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
59314
59522
  let root;
@@ -59778,55 +59986,70 @@ function constructorInitializerIndexes(ctx) {
59778
59986
  if (ctx.__constructorInitializerIndexes !== void 0) {
59779
59987
  return ctx.__constructorInitializerIndexes;
59780
59988
  }
59989
+ const shared = ctx.vm.databaseVM?.constructorInitializerIndexes;
59990
+ if (shared !== void 0) {
59991
+ ctx.__constructorInitializerIndexes = shared;
59992
+ return shared;
59993
+ }
59994
+ const built = buildConstructorInitializerIndexes(ctx.vm);
59995
+ ctx.__constructorInitializerIndexes = built;
59996
+ return built;
59997
+ }
59998
+ function buildConstructorInitializerIndexes(vm) {
59781
59999
  const initializerScopeMemberIds = /* @__PURE__ */ new WeakMap();
59782
60000
  const initializerByValueId = /* @__PURE__ */ new Map();
59783
- for (const row of ctx.vm.values) {
60001
+ for (const row of vm.values) {
59784
60002
  const initializer = Reflect.get(row, "init");
59785
60003
  if (initializer !== void 0)
59786
60004
  initializerByValueId.set(row.id, initializer);
59787
60005
  }
59788
- for (const member of ctx.vm.members) {
60006
+ for (const member of vm.members) {
59789
60007
  const defaultValue = member.defaultValue;
59790
60008
  if (isInitValueContent(defaultValue)) {
59791
60009
  initializerScopeMemberIds.set(defaultValue.init, member.id);
59792
- continue;
59793
60010
  }
59794
- if (!isLiteralValueContent(defaultValue)) continue;
59795
- const value = defaultValue.value;
59796
- const valueIds = Array.isArray(value) ? value : typeof value === "object" && value !== null ? Object.values(value) : [];
59797
- for (const valueId of valueIds) {
59798
- if (typeof valueId !== "string") continue;
59799
- const initializer = initializerByValueId.get(valueId);
59800
- if (initializer !== void 0) {
59801
- initializerScopeMemberIds.set(initializer, member.id);
59802
- }
60011
+ }
60012
+ const initializerRootOwners = /* @__PURE__ */ new Map();
60013
+ resolveOwnerMembersForValues(
60014
+ {
60015
+ classes: vm.classes,
60016
+ members: vm.members,
60017
+ values: vm.values
60018
+ },
60019
+ new Set(initializerByValueId.keys()),
60020
+ void 0,
60021
+ initializerRootOwners
60022
+ );
60023
+ for (const [valueId, initializer] of initializerByValueId) {
60024
+ const rootOwnerId = Reflect.get(
60025
+ initializerRootOwners.get(valueId) ?? {},
60026
+ "id"
60027
+ );
60028
+ if (typeof rootOwnerId === "string") {
60029
+ initializerScopeMemberIds.set(initializer, rootOwnerId);
59803
60030
  }
59804
60031
  }
59805
60032
  const declaringClassIdsByMemberId = /* @__PURE__ */ new Map();
59806
- for (const schemaClass2 of ctx.vm.classes) {
60033
+ for (const schemaClass2 of vm.classes) {
59807
60034
  for (const memberId of Object.values(schemaClass2.schema)) {
59808
60035
  const owners = declaringClassIdsByMemberId.get(memberId) ?? /* @__PURE__ */ new Set();
59809
60036
  owners.add(schemaClass2.id);
59810
60037
  declaringClassIdsByMemberId.set(memberId, owners);
59811
60038
  }
59812
60039
  }
59813
- const memberById = new Map(
59814
- ctx.vm.members.map((member) => [member.id, member])
59815
- );
60040
+ const memberById = new Map(vm.members.map((member) => [member.id, member]));
59816
60041
  const containerMemberIdByEntryId = /* @__PURE__ */ new Map();
59817
- for (const member of ctx.vm.members) {
60042
+ for (const member of vm.members) {
59818
60043
  if (isMemberList(member) || isMemberDictionary(member)) {
59819
60044
  containerMemberIdByEntryId.set(member.entryMemberId, member.id);
59820
60045
  }
59821
60046
  }
59822
- const built = {
60047
+ return {
59823
60048
  initializerScopeMemberIds,
59824
60049
  declaringClassIdsByMemberId,
59825
60050
  memberById,
59826
60051
  containerMemberIdByEntryId
59827
60052
  };
59828
- ctx.__constructorInitializerIndexes = built;
59829
- return built;
59830
60053
  }
59831
60054
  function prepareConstructorArgumentScopes(record3, argumentValues, ctx) {
59832
60055
  const values = /* @__PURE__ */ new Map();
@@ -60077,7 +60300,10 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
60077
60300
  textureTemplates: ctx.vm.textureTemplates ?? []
60078
60301
  },
60079
60302
  projectId: ctx.vm.project.id,
60080
- member: syntheticConstructorMember(schemaClass2),
60303
+ member: syntheticConstructorMember(
60304
+ schemaClass2,
60305
+ descriptor.classArguments
60306
+ ),
60081
60307
  topLevelClassId: classId,
60082
60308
  createdValues,
60083
60309
  storageKeyDeclarations,
@@ -61173,6 +61399,7 @@ var init_evaluateNSGetter = __esm({
61173
61399
  init_interfaces();
61174
61400
  init_neoscript();
61175
61401
  init_NSGetterRuntimeError();
61402
+ init_value_row_owner_members();
61176
61403
  init_decimal();
61177
61404
  init_members();
61178
61405
  init_core();
@@ -61279,17 +61506,20 @@ var init_evaluateNSGetter = __esm({
61279
61506
 
61280
61507
  // ../src/view-models/neoscript-evaluator/evaluateInitializer.ts
61281
61508
  function initializerEvaluatorLookups(document) {
61282
- const key = document;
61509
+ const key = document.evaluatorCache?.key ?? document;
61510
+ const revision = document.evaluatorCache?.revision;
61283
61511
  const cached = evaluatorLookupsByDocument.get(key);
61284
- if (cached !== void 0 && cached.members === document.members && cached.values === document.values) {
61512
+ if (cached !== void 0 && (revision === void 0 ? cached.members === document.members && cached.values === document.values : cached.revision === revision)) {
61285
61513
  return cached.lookups;
61286
61514
  }
61287
61515
  const lookups = makeEvaluatorLookups(document.members, document.values, {
61288
- includeValueGraphIndexes: true
61516
+ includeValueGraphIndexes: true,
61517
+ constructorInitializerDocument: document
61289
61518
  });
61290
61519
  evaluatorLookupsByDocument.set(key, {
61291
61520
  members: document.members,
61292
61521
  values: document.values,
61522
+ revision,
61293
61523
  lookups
61294
61524
  });
61295
61525
  return lookups;
@@ -61339,6 +61569,15 @@ function evaluateMemberInitializer(args) {
61339
61569
  rootValue: buildInitializerRootValue(args.document),
61340
61570
  saveStaticBindings: args.saveStaticBindings,
61341
61571
  sessionStaticBindings: args.sessionStaticBindings,
61572
+ ...args.storedConstructionReplay === true ? {
61573
+ storedConstructionReplay: true,
61574
+ ...isMemberClassBase(args.member) ? {
61575
+ __storedConstructionReplaySlot: {
61576
+ classId: args.member.classId,
61577
+ classArguments: args.member.classArguments ?? {}
61578
+ }
61579
+ } : {}
61580
+ } : {},
61342
61581
  __constructedArgumentsByValue: /* @__PURE__ */ new WeakMap(),
61343
61582
  __createdStorageKeyDeclarations: args.storageKeyDeclarations ?? /* @__PURE__ */ new Map()
61344
61583
  };
@@ -61361,6 +61600,7 @@ var evaluatorLookupsByDocument;
61361
61600
  var init_evaluateInitializer = __esm({
61362
61601
  "../src/view-models/neoscript-evaluator/evaluateInitializer.ts"() {
61363
61602
  "use strict";
61603
+ init_members();
61364
61604
  init_project2();
61365
61605
  init_NSGetterRuntimeError();
61366
61606
  init_evaluateNSGetter();
@@ -61387,7 +61627,8 @@ function evaluateInitializerMaterialization(args) {
61387
61627
  member: args.member,
61388
61628
  document: args.document,
61389
61629
  createdValues,
61390
- storageKeyDeclarations
61630
+ storageKeyDeclarations,
61631
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
61391
61632
  });
61392
61633
  return { evaluated, createdValues, storageKeyDeclarations };
61393
61634
  }
@@ -61395,7 +61636,8 @@ function materializeInitializerValue(args) {
61395
61636
  const { evaluated, createdValues, storageKeyDeclarations } = evaluateInitializerMaterialization({
61396
61637
  init: args.row.init,
61397
61638
  member: args.member,
61398
- document: args.document
61639
+ document: args.document,
61640
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
61399
61641
  });
61400
61642
  const {
61401
61643
  init: _init,
@@ -77143,22 +77385,29 @@ function prepareServerOwnedDelegateValueBodies(args) {
77143
77385
  `Value "${row.id}" carries a NeoDelegate closure but no NeoDelegate member in this project version stores it.`
77144
77386
  );
77145
77387
  }
77146
- row.value = compileDelegateClosureValue(row.value.code, {
77147
- project: document.project,
77148
- projectFiles: document.projectFiles,
77149
- members: document.members,
77150
- classes: document.classes,
77151
- enums: document.enums,
77152
- interfaces: document.interfaces,
77153
- constructors: document.constructors ?? [],
77154
- thisClass: findSchemaPlacement(
77155
- rootOwnerByValueId.get(row.id)?.id ?? "",
77156
- document.classes
77157
- )?.ownerClass ?? null,
77158
- returnTypeInfo: member.returnTypeInfo,
77159
- argumentTypes: member.argumentTypes,
77160
- name: `${member.name} value`
77161
- });
77388
+ const rootOwner = rootOwnerByValueId.get(row.id);
77389
+ const thisClass = findSchemaPlacement(rootOwner?.id ?? "", document.classes)?.ownerClass ?? null;
77390
+ try {
77391
+ row.value = compileDelegateClosureValue(row.value.code, {
77392
+ project: document.project,
77393
+ projectFiles: document.projectFiles,
77394
+ members: document.members,
77395
+ classes: document.classes,
77396
+ enums: document.enums,
77397
+ interfaces: document.interfaces,
77398
+ constructors: document.constructors ?? [],
77399
+ thisClass,
77400
+ returnTypeInfo: member.returnTypeInfo,
77401
+ argumentTypes: member.argumentTypes,
77402
+ name: `${member.name} value`
77403
+ });
77404
+ } catch (error) {
77405
+ const detail = error instanceof Error ? error.message : String(error);
77406
+ throw new Error(
77407
+ `Value "${row.id}" NeoDelegate closure failed under member "${member.name}" (${getOptionalString(member, "id") ?? "unknown"}), root owner "${rootOwner?.name ?? "unknown"}" (${getOptionalString(rootOwner, "id") ?? "unknown"}), lexical class "${thisClass?.name ?? "none"}" (${thisClass?.id ?? "none"}), and return type ${canonicalJsonStringify(member.returnTypeInfo)}: ${detail}`,
77408
+ { cause: error }
77409
+ );
77410
+ }
77162
77411
  };
77163
77412
  for (const [index, row] of explicitRows) {
77164
77413
  const compiled = { ...row, value: { ...row.value } };
@@ -77713,6 +77962,7 @@ var init_project_version_schema_commit = __esm({
77713
77962
  init_members();
77714
77963
  init_inheritance();
77715
77964
  init_generics();
77965
+ init_core();
77716
77966
  init_world_content_sidecar_validation();
77717
77967
  init_project_document_value_overlay();
77718
77968
  init_project2();
@@ -81133,6 +81383,7 @@ function replayStoredConstructionV4(args) {
81133
81383
  // Instance calls are self-contained. Declaration calls inherit the class
81134
81384
  // header parameters that are in lexical scope at their source site.
81135
81385
  initializerOwnerClass: args.initializerOwnerClass ?? null,
81386
+ storedConstructionReplay: true,
81136
81387
  ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject }
81137
81388
  });
81138
81389
  if (!isMemberValue(candidate) || !isInitValueContent(candidate)) {
@@ -81151,14 +81402,19 @@ function replayStoredConstructionV4(args) {
81151
81402
  // Constructor-only rows have no structural member owner. Use the same
81152
81403
  // explicit typed descriptor for evaluation that compiled the replay.
81153
81404
  member: compileMember,
81154
- row: candidate
81405
+ row: candidate,
81406
+ storedConstructionReplay: true
81155
81407
  });
81156
81408
  break;
81157
81409
  } catch (error) {
81158
81410
  if (!(error instanceof UncompiledInitializerRuntimeError) || error.memberId === null || compiledDependencies.has(error.memberId)) {
81159
81411
  throw error;
81160
81412
  }
81161
- compilePulledMemberInitializerBodyV4(document, error.memberId);
81413
+ compilePulledMemberInitializerBodyV4(
81414
+ document,
81415
+ error.memberId,
81416
+ args.compilationProject
81417
+ );
81162
81418
  compiledDependencies.add(error.memberId);
81163
81419
  }
81164
81420
  }
@@ -81208,7 +81464,7 @@ function assertPulledConstructorsCompiled(document) {
81208
81464
  );
81209
81465
  }
81210
81466
  }
81211
- function compilePulledMemberInitializerBodyV4(document, memberId) {
81467
+ function compilePulledMemberInitializerBodyV4(document, memberId, compilationProject) {
81212
81468
  const compileArgs = {
81213
81469
  project: document.project,
81214
81470
  projectFiles: document.projectFiles,
@@ -81230,7 +81486,8 @@ function compilePulledMemberInitializerBodyV4(document, memberId) {
81230
81486
  compileMemberInitializerBody({
81231
81487
  ...compileArgs,
81232
81488
  member,
81233
- thisClass
81489
+ thisClass,
81490
+ ...compilationProject === void 0 ? {} : { compilationProject }
81234
81491
  });
81235
81492
  }
81236
81493
  function readPulledProjectDocumentV4(records2) {
@@ -81304,10 +81561,13 @@ function buildValueEmitContext(records2, manifest) {
81304
81561
  const symbolsByValueId = staticSymbols(classes, members);
81305
81562
  let document;
81306
81563
  const readDocument = () => document ??= readPulledProjectDocumentV4(records2);
81564
+ let compilationProject;
81565
+ const readCompilationProject = () => compilationProject ??= createNeoScriptCompilationProject(readDocument());
81307
81566
  let materializedGraph;
81308
81567
  return {
81309
81568
  records: records2,
81310
81569
  readDocument,
81570
+ readCompilationProject,
81311
81571
  readMaterializedGraph: () => {
81312
81572
  if (materializedGraph !== void 0) return materializedGraph;
81313
81573
  materializedGraph = new MaterializedValueGraphContext(
@@ -81455,8 +81715,10 @@ function animationConstructorProjectionTargetValueIds(context, classId, value) {
81455
81715
  return [];
81456
81716
  }
81457
81717
  const targetIds = [];
81458
- for (const projection of inheritedConstructorProjections2(
81718
+ for (const projection of effectiveConstructorProjections(
81459
81719
  context.manifestClasses,
81720
+ context.manifestConstructors,
81721
+ context.manifestMembers,
81460
81722
  classId
81461
81723
  )) {
81462
81724
  const schemaKey = inheritedProjectionSchemaKey(
@@ -82434,9 +82696,10 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
82434
82696
  const assignmentSlices = objectInitializerSlices(binding.initializer);
82435
82697
  for (const assignment of expression.initializer ?? []) {
82436
82698
  const childMember = classMemberByName(context, classId, assignment.name);
82437
- if (inheritedConstructorProjections2(context.classes, schemaClass2.id).some(
82438
- (projection) => projection.memberId === childMember.id
82439
- )) {
82699
+ if (inheritedLegacyConstructorProjections(
82700
+ context.classes,
82701
+ schemaClass2.id
82702
+ ).some((projection) => projection.memberId === childMember.id)) {
82440
82703
  throw new Error(
82441
82704
  `Default value ${binding.label}.${assignment.name} is constructor-projected and must be set through its named constructor argument.`
82442
82705
  );
@@ -82847,7 +83110,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
82847
83110
  effectiveClass.id,
82848
83111
  assignment.name
82849
83112
  );
82850
- if (inheritedConstructorProjections2(
83113
+ if (inheritedLegacyConstructorProjections(
82851
83114
  context.classes,
82852
83115
  effectiveClass.id
82853
83116
  ).some((projection) => projection.memberId === childMember.id)) {
@@ -83350,9 +83613,10 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
83350
83613
  }
83351
83614
  for (const assignment of expression.initializer ?? []) {
83352
83615
  const childMember = classMemberByName(context, classId, assignment.name);
83353
- if (inheritedConstructorProjections2(context.classes, schemaClass2.id).some(
83354
- (projection) => projection.memberId === childMember.id
83355
- )) {
83616
+ if (inheritedLegacyConstructorProjections(
83617
+ context.classes,
83618
+ schemaClass2.id
83619
+ ).some((projection) => projection.memberId === childMember.id)) {
83356
83620
  throw new Error(
83357
83621
  `Class value ${String(base.id)}.${assignment.name} is constructor-projected and must be set through its named constructor argument.`
83358
83622
  );
@@ -83532,7 +83796,7 @@ function classInheritanceChain(classes, classId) {
83532
83796
  }
83533
83797
  return chain;
83534
83798
  }
83535
- function inheritedConstructorProjections2(classes, classId) {
83799
+ function inheritedLegacyConstructorProjections(classes, classId) {
83536
83800
  const resolved = [];
83537
83801
  const claimed = /* @__PURE__ */ new Set();
83538
83802
  for (const schemaClass2 of classInheritanceChain(classes, classId)) {
@@ -83544,6 +83808,67 @@ function inheritedConstructorProjections2(classes, classId) {
83544
83808
  }
83545
83809
  return resolved;
83546
83810
  }
83811
+ function effectiveConstructorProjections(classes, constructors, members, classId) {
83812
+ const schemaClass2 = classes.get(classId);
83813
+ const requiredId = schemaClass2?.requiredConstructorId;
83814
+ if (schemaClass2 === void 0 || requiredId === void 0) {
83815
+ return inheritedLegacyConstructorProjections(classes, classId);
83816
+ }
83817
+ const required2 = constructors.get(requiredId);
83818
+ if (required2 === void 0) return [];
83819
+ const projected = requiredConstructorProjectionMap(
83820
+ classes,
83821
+ constructors,
83822
+ members,
83823
+ classId,
83824
+ /* @__PURE__ */ new Set()
83825
+ );
83826
+ if (required2.arguments.some((parameter3) => !projected.has(parameter3.name))) {
83827
+ return [];
83828
+ }
83829
+ return required2.arguments.map((parameter3) => ({
83830
+ parameterName: parameter3.name,
83831
+ memberId: projected.get(parameter3.name)
83832
+ }));
83833
+ }
83834
+ function requiredConstructorProjectionMap(classes, constructors, members, classId, visited) {
83835
+ if (visited.has(classId)) return /* @__PURE__ */ new Map();
83836
+ const schemaClass2 = classes.get(classId);
83837
+ const requiredId = schemaClass2?.requiredConstructorId;
83838
+ const required2 = requiredId === void 0 ? void 0 : constructors.get(requiredId);
83839
+ if (schemaClass2 === void 0 || required2 === void 0) return /* @__PURE__ */ new Map();
83840
+ const result = /* @__PURE__ */ new Map();
83841
+ for (const memberId of Object.values(schemaClass2.schema)) {
83842
+ const initializer = members.get(memberId)?.defaultValue;
83843
+ if (initializer === null || initializer === void 0 || !("init" in initializer)) {
83844
+ continue;
83845
+ }
83846
+ const parameterName = initializer.init.code.trim();
83847
+ if (required2.arguments.some((parameter3) => parameter3.name === parameterName)) {
83848
+ result.set(parameterName, memberId);
83849
+ }
83850
+ }
83851
+ const baseClassId = schemaClass2.extendsClassId;
83852
+ if (baseClassId === null) return result;
83853
+ const base = requiredConstructorProjectionMap(
83854
+ classes,
83855
+ constructors,
83856
+ members,
83857
+ baseClassId,
83858
+ /* @__PURE__ */ new Set([...visited, classId])
83859
+ );
83860
+ for (const forwarded of required2.baseArguments ?? []) {
83861
+ const sourceName = forwarded.code.trim();
83862
+ if (!required2.arguments.some((parameter3) => parameter3.name === sourceName)) {
83863
+ continue;
83864
+ }
83865
+ const memberId = base.get(forwarded.name);
83866
+ if (memberId !== void 0 && !result.has(sourceName)) {
83867
+ result.set(sourceName, memberId);
83868
+ }
83869
+ }
83870
+ return result;
83871
+ }
83547
83872
  function inheritedProjectionSchemaKey(classes, classId, memberId) {
83548
83873
  for (const schemaClass2 of classInheritanceChain(classes, classId)) {
83549
83874
  for (const [schemaKey, declared] of Object.entries(schemaClass2.schema)) {
@@ -83553,8 +83878,10 @@ function inheritedProjectionSchemaKey(classes, classId, memberId) {
83553
83878
  return null;
83554
83879
  }
83555
83880
  function resolveConstructorProjectionArguments(context, schemaClass2, expression, ownerValueId, environment, source) {
83556
- const projections = inheritedConstructorProjections2(
83881
+ const projections = effectiveConstructorProjections(
83557
83882
  context.classes,
83883
+ context.manifestConstructors,
83884
+ context.members,
83558
83885
  schemaClass2.id
83559
83886
  );
83560
83887
  const signature = describeProjectedConstructor(schemaClass2.name, projections);
@@ -85208,13 +85535,37 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
85208
85535
  if (!isObjectRecord2(value.value))
85209
85536
  return targetTyped ? "new()" : `new ${classValueTypeName(context, classId, member, storedEnvironment)}()`;
85210
85537
  const schema = isObjectRecord2(schemaClass2.schema) ? schemaClass2.schema : {};
85211
- const projection = constructorProjectionSource(
85212
- context,
85213
- classId,
85214
- value.value,
85215
- visited,
85216
- storedEnvironment
85217
- );
85538
+ const hasStoredConstruction = isObjectRecord2(value.constructorArgs);
85539
+ let projection;
85540
+ try {
85541
+ projection = hasStoredConstruction ? {
85542
+ arguments: [],
85543
+ memberIds: new Set(
85544
+ effectiveConstructorProjections(
85545
+ context.manifestClasses,
85546
+ context.manifestConstructors,
85547
+ context.manifestMembers,
85548
+ classId
85549
+ ).map((entry) => entry.memberId)
85550
+ ),
85551
+ targetValueIds: animationConstructorProjectionTargetValueIds(
85552
+ context,
85553
+ classId,
85554
+ value
85555
+ )
85556
+ } : constructorProjectionSource(
85557
+ context,
85558
+ classId,
85559
+ value.value,
85560
+ visited,
85561
+ storedEnvironment
85562
+ );
85563
+ } catch (error) {
85564
+ throw new Error(
85565
+ `Constructor projection for value "${String(value.id ?? "unknown")}" of class "${schemaClass2.name}" cannot be emitted: ${error instanceof Error ? error.message : String(error)}`,
85566
+ { cause: error }
85567
+ );
85568
+ }
85218
85569
  const environment = inferAnimationChildOverrideEmitEnvironment(
85219
85570
  context,
85220
85571
  classId,
@@ -85222,15 +85573,23 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
85222
85573
  storedEnvironment
85223
85574
  );
85224
85575
  const name = classValueTypeName(context, classId, member, environment);
85225
- const storedConstruction = storedConstructorCallSource(
85226
- context,
85227
- schemaClass2,
85228
- value,
85229
- name,
85230
- environment,
85231
- visited,
85232
- targetTyped
85233
- );
85576
+ let storedConstruction;
85577
+ try {
85578
+ storedConstruction = storedConstructorCallSource(
85579
+ context,
85580
+ schemaClass2,
85581
+ value,
85582
+ name,
85583
+ environment,
85584
+ visited,
85585
+ targetTyped
85586
+ );
85587
+ } catch (error) {
85588
+ throw new Error(
85589
+ `Stored construction for value "${String(value.id ?? "unknown")}" of class "${name}" cannot be emitted: ${error instanceof Error ? error.message : String(error)}`,
85590
+ { cause: error }
85591
+ );
85592
+ }
85234
85593
  if (storedConstruction !== null && typeof value.id === "string") {
85235
85594
  context.materializedConstructors.set(value.id, storedConstruction);
85236
85595
  }
@@ -85248,7 +85607,7 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
85248
85607
  context,
85249
85608
  value.id,
85250
85609
  replayConstruction,
85251
- member
85610
+ concreteClassMemberForReplay(member, environment)
85252
85611
  );
85253
85612
  const replayRoot = replayRows === null || typeof value.id !== "string" ? void 0 : replayRows.get(value.id);
85254
85613
  const replayGraph = replayRows === null || typeof value.id !== "string" ? null : context.readMaterializedGraph().withRowOverrides(
@@ -85334,11 +85693,27 @@ function storedConstructionReplayRows(context, valueId, code, member) {
85334
85693
  document: context.readDocument(),
85335
85694
  valueId,
85336
85695
  code,
85337
- member
85696
+ member,
85697
+ compilationProject: context.readCompilationProject()
85338
85698
  });
85339
85699
  context.constructionReplays.set(valueId, replay);
85340
85700
  return replay;
85341
85701
  }
85702
+ function concreteClassMemberForReplay(member, environment) {
85703
+ if (numberField(member, "kind") !== 7 /* Class */) return member;
85704
+ const classArguments2 = isObjectRecord2(member.classArguments) ? member.classArguments : {};
85705
+ let changed = false;
85706
+ const concreteArguments = Object.fromEntries(
85707
+ Object.entries(classArguments2).map(([genericParamId, binding]) => {
85708
+ const forwardedParamId = isObjectRecord2(binding) && binding.kind === "generic" && typeof binding.genericParamId === "string" ? binding.genericParamId : null;
85709
+ const bindingMemberId = environment.get(genericParamId) ?? (forwardedParamId === null ? void 0 : environment.get(forwardedParamId));
85710
+ if (bindingMemberId === void 0) return [genericParamId, binding];
85711
+ changed = true;
85712
+ return [genericParamId, { kind: "member", memberId: bindingMemberId }];
85713
+ })
85714
+ );
85715
+ return changed ? { ...member, classArguments: concreteArguments } : member;
85716
+ }
85342
85717
  function materializedValueSubgraphsEqual(context, currentGraph, replayGraph, currentId, replayId, member, environment) {
85343
85718
  const resolvedMember = resolveGenericValueMember(
85344
85719
  context,
@@ -85510,8 +85885,30 @@ function storedConstructorArgumentSource(context, type, value, environment, visi
85510
85885
  false
85511
85886
  );
85512
85887
  }
85888
+ case "generic": {
85889
+ const bindingId = environment.get(type.genericParamId);
85890
+ const inferredClassId = inferredGenericClassId(bindingId);
85891
+ const resolvedType = inferredClassId === null ? bindingId === void 0 ? null : schemaTypeForBindingMember(context, bindingId, environment) : {
85892
+ kind: "class",
85893
+ nullable: type.nullable,
85894
+ classId: inferredClassId,
85895
+ classArguments: {}
85896
+ };
85897
+ if (resolvedType === null) {
85898
+ throw new Error(
85899
+ `Stored Generic constructor argument cannot resolve parameter ${type.genericParamId}.`
85900
+ );
85901
+ }
85902
+ return storedConstructorArgumentSource(
85903
+ context,
85904
+ { ...resolvedType, nullable: type.nullable || resolvedType.nullable },
85905
+ value,
85906
+ environment,
85907
+ visited,
85908
+ cloneAggregateArguments
85909
+ );
85910
+ }
85513
85911
  case "interface":
85514
- case "generic":
85515
85912
  case "list":
85516
85913
  case "dictionary":
85517
85914
  if (typeof value !== "string") {
@@ -85562,6 +85959,147 @@ function storedConstructorArgumentSource(context, type, value, environment, visi
85562
85959
  );
85563
85960
  }
85564
85961
  }
85962
+ function schemaTypeForBindingMember(context, memberId, environment, visited = /* @__PURE__ */ new Set()) {
85963
+ if (visited.has(memberId)) {
85964
+ throw new Error(
85965
+ `Stored constructor argument generic binding contains a member cycle at ${memberId}.`
85966
+ );
85967
+ }
85968
+ const member = context.manifestMembers.get(memberId);
85969
+ if (member === void 0) {
85970
+ throw new Error(
85971
+ `Stored constructor argument generic binding names missing member ${memberId}.`
85972
+ );
85973
+ }
85974
+ const nullable = !member.required;
85975
+ const nextVisited = /* @__PURE__ */ new Set([...visited, memberId]);
85976
+ switch (member.kind) {
85977
+ case "null":
85978
+ case "bool":
85979
+ case "int":
85980
+ case "string":
85981
+ case "float":
85982
+ case "decimal":
85983
+ case "sprite":
85984
+ case "audio":
85985
+ case "vector2":
85986
+ case "vector2Int":
85987
+ case "vector3":
85988
+ case "vector3Int":
85989
+ case "color":
85990
+ return { kind: member.kind, nullable };
85991
+ case "class":
85992
+ return {
85993
+ kind: "class",
85994
+ nullable,
85995
+ classId: member.classId,
85996
+ classArguments: Object.fromEntries(
85997
+ Object.entries(member.classArguments).map(
85998
+ ([parameterId, binding]) => [
85999
+ parameterId,
86000
+ binding.kind === "member" ? schemaTypeForBindingMember(
86001
+ context,
86002
+ binding.memberId,
86003
+ environment,
86004
+ nextVisited
86005
+ ) : schemaTypeForBindingMember(
86006
+ context,
86007
+ requiredGenericBindingMemberId(
86008
+ environment,
86009
+ binding.genericParamId
86010
+ ),
86011
+ environment,
86012
+ nextVisited
86013
+ )
86014
+ ]
86015
+ )
86016
+ )
86017
+ };
86018
+ case "enum":
86019
+ return { kind: "enum", nullable, enumId: member.enumId };
86020
+ case "list":
86021
+ return {
86022
+ kind: "list",
86023
+ nullable,
86024
+ entryType: schemaTypeForBindingMember(
86025
+ context,
86026
+ member.entryMemberId,
86027
+ environment,
86028
+ nextVisited
86029
+ ),
86030
+ listMemberId: member.id,
86031
+ readOnly: member.isReadOnly
86032
+ };
86033
+ case "dictionary":
86034
+ return {
86035
+ kind: "dictionary",
86036
+ nullable,
86037
+ entryType: schemaTypeForBindingMember(
86038
+ context,
86039
+ member.entryMemberId,
86040
+ environment,
86041
+ nextVisited
86042
+ ),
86043
+ keyEnumId: member.key.kind === "enum" ? member.key.enumId : null,
86044
+ readOnly: member.isReadOnly
86045
+ };
86046
+ case "lookup": {
86047
+ if (member.declaredType !== null) {
86048
+ return { ...member.declaredType, nullable };
86049
+ }
86050
+ const collection = context.manifestMembers.get(member.collectionMemberId);
86051
+ if (collection?.kind !== "list" && collection?.kind !== "dictionary") {
86052
+ throw new Error(
86053
+ `Stored constructor argument Lookup binding ${member.id} has no collection entry type.`
86054
+ );
86055
+ }
86056
+ return {
86057
+ kind: "lookup",
86058
+ nullable,
86059
+ entryType: schemaTypeForBindingMember(
86060
+ context,
86061
+ collection.entryMemberId,
86062
+ environment,
86063
+ nextVisited
86064
+ ),
86065
+ collectionMemberId: member.collectionMemberId,
86066
+ collectionValueId: member.collectionValueId
86067
+ };
86068
+ }
86069
+ case "dialogueLookup":
86070
+ return { kind: "dialogueLookup", nullable };
86071
+ case "delegate":
86072
+ return {
86073
+ kind: "delegate",
86074
+ nullable,
86075
+ returnType: member.returnType,
86076
+ argumentTypes: member.arguments.map((argument2) => argument2.type)
86077
+ };
86078
+ case "generic":
86079
+ return schemaTypeForBindingMember(
86080
+ context,
86081
+ requiredGenericBindingMemberId(environment, member.genericParamId),
86082
+ environment,
86083
+ nextVisited
86084
+ );
86085
+ case "computed":
86086
+ case "function":
86087
+ case "scriptFunction":
86088
+ case "functionRef":
86089
+ throw new Error(
86090
+ `Stored constructor argument cannot use ${member.kind} member ${member.id} as a generic type binding.`
86091
+ );
86092
+ }
86093
+ }
86094
+ function requiredGenericBindingMemberId(environment, genericParamId) {
86095
+ const bindingId = environment.get(genericParamId);
86096
+ if (bindingId === void 0 || inferredGenericClassId(bindingId) !== null) {
86097
+ throw new Error(
86098
+ `Stored constructor argument cannot resolve generic binding ${genericParamId} to a member.`
86099
+ );
86100
+ }
86101
+ return bindingId;
86102
+ }
85565
86103
  function storedAggregateCloneSource(context, type, valueId, environment) {
85566
86104
  if (!context.values.has(valueId)) {
85567
86105
  throw new Error(
@@ -85861,8 +86399,10 @@ function manifestMemberTypeName(context, member) {
85861
86399
  return fixedSourceTypeNameForKind(member.kind) ?? member.kind;
85862
86400
  }
85863
86401
  function constructorProjectionSource(context, classId, body, visited, environment) {
85864
- const projections = inheritedConstructorProjections2(
86402
+ const projections = effectiveConstructorProjections(
85865
86403
  context.manifestClasses,
86404
+ context.manifestConstructors,
86405
+ context.manifestMembers,
85866
86406
  classId
85867
86407
  );
85868
86408
  const argumentsValue = [];
@@ -86456,6 +86996,7 @@ var init_value_sources = __esm({
86456
86996
  init_member_value_id();
86457
86997
  init_members();
86458
86998
  init_compile_ns_property();
86999
+ init_compile();
86459
87000
  init_constructor_argument_ownership();
86460
87001
  init_structured_leaf_source();
86461
87002
  init_member_kind_type_names();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.22.3",
3
+ "version": "0.22.5",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ description: >-
9
9
  `@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
10
10
  ---
11
11
 
12
- <!-- reviewed-through-cli: 0.22.3 -->
12
+ <!-- reviewed-through-cli: 0.22.5 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -78,7 +78,7 @@ wrappers.
78
78
  The marker near the top of `SKILL.md` must exactly match the package version:
79
79
 
80
80
  ```html
81
- <!-- reviewed-through-cli: 0.22.3 -->
81
+ <!-- reviewed-through-cli: 0.22.5 -->
82
82
  ```
83
83
 
84
84
  The quoted version above is checked too, so this instruction cannot go stale