@neocompose/cli 0.22.2 → 0.22.4

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,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.4] - 2026-08-04
4
+
5
+ ### Fixed
6
+
7
+ - Normal and reset pulls now replay stored immutable system constructions and
8
+ resolve constructor parameter scopes through deeply nested initializer rows.
9
+ - Pull projection accepts migrated constructor arguments on implicitly typed
10
+ list entries, including animation segment frames.
11
+
12
+ ## [0.22.3] - 2026-08-04
13
+
14
+ ### Fixed
15
+
16
+ - Bundled Neo system classes now derive required and optional constructors from
17
+ their authored declarations as first-class `system_*` constructor records
18
+ instead of repurposing constructor projections.
19
+ - Pull, source lowering, local initializer replay, and push preserve those
20
+ constructors and their inherited parameter scopes, including initializer-
21
+ backed child rows such as animation segment frames.
22
+
3
23
  ## [0.22.2] - 2026-08-04
4
24
 
5
25
  ### Changed
package/dist/neo.mjs CHANGED
@@ -1369,6 +1369,9 @@ function isNeoScriptTypeAssignable(source, target, project) {
1369
1369
  if (source.kind === "typeParameter" && target.kind === "typeParameter") {
1370
1370
  return source.id === target.id;
1371
1371
  }
1372
+ if (source.kind === "typeParameter" && source.constraint !== void 0) {
1373
+ return isNeoScriptTypeAssignable(source.constraint, target, project);
1374
+ }
1372
1375
  if (source.kind === "list" && target.kind === "list") {
1373
1376
  return isNeoScriptTypeAssignable(
1374
1377
  source.elementType,
@@ -10393,11 +10396,18 @@ var init_strict_resolver = __esm({
10393
10396
  pos
10394
10397
  );
10395
10398
  }
10396
- const signature = schemaClass2.constructorSignature;
10399
+ const replayingStoredConstruction = this.context.storedConstructionReplay === true;
10400
+ if (schemaClass2.constructorUnavailableReason === "immutableOnly" && !replayingStoredConstruction) {
10401
+ throw new CompileError(
10402
+ `Cannot construct Immutable-only Class '${className}'; constructors create writable Session values.`,
10403
+ pos
10404
+ );
10405
+ }
10406
+ const signature = schemaClass2.constructorSignature ?? (replayingStoredConstruction ? schemaClass2.storedConstructionReplaySignature : void 0);
10397
10407
  if (!signature) {
10398
10408
  const open = (schemaClass2.typeParameters?.length ?? 0) > 0;
10399
10409
  throw new CompileError(
10400
- 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.`,
10410
+ open ? `Cannot construct open generic Class '${className}'; construct a closed named descendant.` : `Class '${className}' does not expose a generated public constructor.`,
10401
10411
  pos
10402
10412
  );
10403
10413
  }
@@ -10592,7 +10602,7 @@ var init_strict_resolver = __esm({
10592
10602
  pos
10593
10603
  );
10594
10604
  }
10595
- if (schemaClass2.constructorUnavailableReason === "immutableOnly") {
10605
+ if (schemaClass2.constructorUnavailableReason === "immutableOnly" && this.context.storedConstructionReplay !== true) {
10596
10606
  throw new CompileError(
10597
10607
  `Cannot construct Immutable-only Class '${className}'; constructors create writable Session values.`,
10598
10608
  pos
@@ -26029,9 +26039,6 @@ function attachConstructorSignature(type, environment) {
26029
26039
  )) {
26030
26040
  return type;
26031
26041
  }
26032
- if (resolvedAllowedStorage(type.id, environment) === "immutable") {
26033
- return { ...type, constructorUnavailableReason: "immutableOnly" };
26034
- }
26035
26042
  const constructorSignature2 = buildNeoScriptConstructorSignature(
26036
26043
  type.id,
26037
26044
  type.members,
@@ -26049,6 +26056,13 @@ function attachConstructorSignature(type, environment) {
26049
26056
  } : null;
26050
26057
  }
26051
26058
  );
26059
+ if (resolvedAllowedStorage(type.id, environment) === "immutable") {
26060
+ return {
26061
+ ...type,
26062
+ storedConstructionReplaySignature: constructorSignature2,
26063
+ constructorUnavailableReason: "immutableOnly"
26064
+ };
26065
+ }
26052
26066
  return { ...type, constructorSignature: constructorSignature2 };
26053
26067
  }
26054
26068
  function resolvedAllowedStorage(classId, environment) {
@@ -29056,7 +29070,7 @@ function memberFromDocument(record3, members, owners, classNames, context) {
29056
29070
  );
29057
29071
  const modifier = memberModifier(overrideOf, isVirtual, isAbstract);
29058
29072
  const defaultValue = defaultValueFromDocument(
29059
- field("defaultValue", null),
29073
+ overrideOf !== null && !Object.hasOwn(data, "defaultValue") ? null : field("defaultValue", null),
29060
29074
  record3
29061
29075
  );
29062
29076
  const docsText = optionalDocsText(data.docsText, record3, "docsText");
@@ -36759,7 +36773,9 @@ function isMemberGenericBase(value) {
36759
36773
  if (!isSystemMetadata(v.system)) return false;
36760
36774
  if (v.system.kind !== SystemProtectionKind.WorldAuthoring) return false;
36761
36775
  }
36762
- if (v.defaultValue !== void 0 && v.defaultValue !== null) return false;
36776
+ if (v.defaultValue !== void 0 && v.defaultValue !== null && !isInitValueContent(v.defaultValue)) {
36777
+ return false;
36778
+ }
36763
36779
  if (v.required === true) return false;
36764
36780
  return true;
36765
36781
  }
@@ -38101,10 +38117,20 @@ var init_world_system_classes_generated = __esm({
38101
38117
  docsText: "One value at a frame index inside a segment. It holds until the next row\nyou author, or until the segment's Duration runs out.",
38102
38118
  extendsWorldKind: "animationFrameBase",
38103
38119
  isAbstract: false,
38104
- constructorProjections: [
38120
+ requiredConstructorId: "system_498d073e-0018-5828-af2b-22b113c31380",
38121
+ constructors: [
38105
38122
  {
38106
- memberId: "system_b71d1f73-da72-49de-ab9a-911cc9bffa43",
38107
- parameterName: "value"
38123
+ constructorId: "system_498d073e-0018-5828-af2b-22b113c31380",
38124
+ argumentTypes: [
38125
+ {
38126
+ name: "value",
38127
+ type: 21,
38128
+ required: true,
38129
+ ownerClassId: "system_9c4f3bfb-f0d8-4231-a7e7-9115bab8d5ab",
38130
+ genericParamId: "system_887b11d3-e56a-47ff-8d01-e2fcefb846a1"
38131
+ }
38132
+ ],
38133
+ code: null
38108
38134
  }
38109
38135
  ],
38110
38136
  genericParams: [
@@ -38114,6 +38140,7 @@ var init_world_system_classes_generated = __esm({
38114
38140
  {
38115
38141
  memberId: "system_b71d1f73-da72-49de-ab9a-911cc9bffa43",
38116
38142
  memberKind: "generic",
38143
+ defaultInitializerCode: "value",
38117
38144
  genericParamId: "system_887b11d3-e56a-47ff-8d01-e2fcefb846a1",
38118
38145
  required: false,
38119
38146
  schemaKey: "Value"
@@ -38191,14 +38218,32 @@ var init_world_system_classes_generated = __esm({
38191
38218
  name: "NeoAnimationChildOverride",
38192
38219
  docsText: "What one child looks like while a clip frame holds: which child, and the\nvalues to override on it.",
38193
38220
  isAbstract: false,
38194
- constructorProjections: [
38195
- {
38196
- memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
38197
- parameterName: "selector"
38198
- },
38221
+ requiredConstructorId: "system_2fefcc00-08ab-5a16-a76a-758beac24ef1",
38222
+ constructors: [
38199
38223
  {
38200
- memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
38201
- parameterName: "overrides"
38224
+ constructorId: "system_2fefcc00-08ab-5a16-a76a-758beac24ef1",
38225
+ argumentTypes: [
38226
+ {
38227
+ name: "selector",
38228
+ type: 25,
38229
+ required: true,
38230
+ returnTypeInfo: {
38231
+ type: 21,
38232
+ required: true,
38233
+ ownerClassId: "system_e2e88eba-5335-4a16-9dcf-2c0e1951e8bd",
38234
+ genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0"
38235
+ },
38236
+ argumentTypes: []
38237
+ },
38238
+ {
38239
+ name: "overrides",
38240
+ type: 21,
38241
+ required: true,
38242
+ ownerClassId: "system_e2e88eba-5335-4a16-9dcf-2c0e1951e8bd",
38243
+ genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0"
38244
+ }
38245
+ ],
38246
+ code: null
38202
38247
  }
38203
38248
  ],
38204
38249
  genericParams: [
@@ -38212,6 +38257,7 @@ var init_world_system_classes_generated = __esm({
38212
38257
  {
38213
38258
  memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
38214
38259
  memberKind: "delegate",
38260
+ defaultInitializerCode: "selector",
38215
38261
  returnTypeInfo: {
38216
38262
  type: 21,
38217
38263
  required: true,
@@ -38234,6 +38280,7 @@ var init_world_system_classes_generated = __esm({
38234
38280
  {
38235
38281
  memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
38236
38282
  memberKind: "generic",
38283
+ defaultInitializerCode: "overrides",
38237
38284
  genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0",
38238
38285
  partial: true,
38239
38286
  required: false,
@@ -38247,16 +38294,31 @@ var init_world_system_classes_generated = __esm({
38247
38294
  name: "NeoAnimationTrackBase",
38248
38295
  docsText: "A lane on a clip's timeline: which child it plays against, when it starts,\nwhich way it runs, and which slice of the content to use. Both kinds of\ntrack derive from this, so playing a child clip reversed or cropped is\nsomething you author on the lane rather than pass in when you play it.",
38249
38296
  isAbstract: true,
38250
- constructorProjections: [
38297
+ requiredConstructorId: "system_8980d09b-0a6d-5461-9615-2f524515b1af",
38298
+ constructors: [
38251
38299
  {
38252
- memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38253
- parameterName: "selector"
38300
+ constructorId: "system_8980d09b-0a6d-5461-9615-2f524515b1af",
38301
+ argumentTypes: [
38302
+ {
38303
+ name: "selector",
38304
+ type: 25,
38305
+ required: true,
38306
+ returnTypeInfo: {
38307
+ type: 7,
38308
+ required: true,
38309
+ classId: "system_61b30a92-90dc-4bf8-8503-ee4f6414effc"
38310
+ },
38311
+ argumentTypes: []
38312
+ }
38313
+ ],
38314
+ code: null
38254
38315
  }
38255
38316
  ],
38256
38317
  schemaFields: [
38257
38318
  {
38258
38319
  memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38259
38320
  memberKind: "delegate",
38321
+ defaultInitializerCode: "selector",
38260
38322
  returnTypeInfo: {
38261
38323
  type: 7,
38262
38324
  required: true,
@@ -38330,20 +38392,33 @@ var init_world_system_classes_generated = __esm({
38330
38392
  docsText: "Plays another object's clip on this clip's timeline, looked up by name. The\nlane is as long as the clip it names.",
38331
38393
  extendsWorldKind: "animationTrack",
38332
38394
  isAbstract: false,
38333
- constructorProjections: [
38334
- {
38335
- memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38336
- parameterName: "selector"
38337
- },
38395
+ requiredConstructorId: "system_6baa12a7-be86-5ae0-82da-2fed308320a0",
38396
+ constructors: [
38338
38397
  {
38339
- memberId: "system_2c816624-0281-46d3-9ed5-d20bd43519f4",
38340
- parameterName: "clipKey"
38398
+ constructorId: "system_6baa12a7-be86-5ae0-82da-2fed308320a0",
38399
+ argumentTypes: [
38400
+ {
38401
+ name: "selector",
38402
+ type: 25,
38403
+ required: true,
38404
+ returnTypeInfo: {
38405
+ type: 7,
38406
+ required: true,
38407
+ classId: "system_61b30a92-90dc-4bf8-8503-ee4f6414effc"
38408
+ },
38409
+ argumentTypes: []
38410
+ },
38411
+ { name: "clipKey", type: 3, required: true }
38412
+ ],
38413
+ code: null,
38414
+ baseArguments: [{ name: "selector", code: "selector" }]
38341
38415
  }
38342
38416
  ],
38343
38417
  schemaFields: [
38344
38418
  {
38345
38419
  memberId: "system_2c816624-0281-46d3-9ed5-d20bd43519f4",
38346
38420
  memberKind: "string",
38421
+ defaultInitializerCode: "clipKey",
38347
38422
  localizable: false,
38348
38423
  required: true,
38349
38424
  schemaKey: "ClipKey"
@@ -38357,10 +38432,26 @@ var init_world_system_classes_generated = __esm({
38357
38432
  docsText: "Plays a sequence of values onto one member of one child, on the owning\nclip's clock. Where a child track hands off to another clip, this lane is a\nleaf: it writes one value per frame to the member its subclass targets.\n\nDerive from it with the child type you author against, so that a Segment\ngetter can reach that child's own members.",
38358
38433
  extendsWorldKind: "animationTrack",
38359
38434
  isAbstract: true,
38360
- constructorProjections: [
38435
+ requiredConstructorId: "system_1e7f8826-5392-5b4c-8cc3-6052d20e5280",
38436
+ constructors: [
38361
38437
  {
38362
- memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
38363
- parameterName: "selector"
38438
+ constructorId: "system_1e7f8826-5392-5b4c-8cc3-6052d20e5280",
38439
+ argumentTypes: [
38440
+ {
38441
+ name: "selector",
38442
+ type: 25,
38443
+ required: true,
38444
+ returnTypeInfo: {
38445
+ type: 21,
38446
+ required: true,
38447
+ ownerClassId: "system_fd551dd8-6e6b-4044-9f32-7445ab344200",
38448
+ genericParamId: "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655"
38449
+ },
38450
+ argumentTypes: []
38451
+ }
38452
+ ],
38453
+ code: null,
38454
+ baseArguments: [{ name: "selector", code: "selector" }]
38364
38455
  }
38365
38456
  ],
38366
38457
  genericParams: [
@@ -38376,6 +38467,7 @@ var init_world_system_classes_generated = __esm({
38376
38467
  memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
38377
38468
  memberKind: "delegate",
38378
38469
  extendsMemberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38470
+ defaultInitializerCode: "selector",
38379
38471
  docsText: "The child this lane plays against, typed as the child class you derived with, so a Segment getter can read that child's own members.",
38380
38472
  returnTypeInfo: {
38381
38473
  type: 21,
@@ -38417,6 +38509,28 @@ var init_world_system_classes_generated = __esm({
38417
38509
  docsText: "Plays a sprite segment onto a sprite child's Sprite member \u2014 the lane that\nanimates a sprite over time. Derive from it to say where the segment comes\nfrom; Segment is left for you to fill in, so every lane that plays is one of\nyour own classes.",
38418
38510
  extendsWorldKind: "animationSegmentTrack",
38419
38511
  isAbstract: true,
38512
+ requiredConstructorId: "system_9a3f52ca-872a-50a5-aad9-e9a040f40802",
38513
+ constructors: [
38514
+ {
38515
+ constructorId: "system_9a3f52ca-872a-50a5-aad9-e9a040f40802",
38516
+ argumentTypes: [
38517
+ {
38518
+ name: "selector",
38519
+ type: 25,
38520
+ required: true,
38521
+ returnTypeInfo: {
38522
+ type: 21,
38523
+ required: true,
38524
+ ownerClassId: "system_24b70585-0798-49ad-b650-4c118bac1eb1",
38525
+ genericParamId: "system_4de90637-6a3b-4bba-95ef-2ff9dfb05268"
38526
+ },
38527
+ argumentTypes: []
38528
+ }
38529
+ ],
38530
+ code: null,
38531
+ baseArguments: [{ name: "selector", code: "selector" }]
38532
+ }
38533
+ ],
38420
38534
  extendsGenericBindings: {
38421
38535
  "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655": {
38422
38536
  kind: "generic",
@@ -47886,20 +48000,60 @@ function buildDeclaredConstructorIndex(analysis) {
47886
48000
  if (declaration.constructors.length === 0) continue;
47887
48001
  byClassName.set(declaration.name, declaration.constructors);
47888
48002
  }
47889
- return { byClassName, requiredByClassName };
48003
+ return {
48004
+ byClassName,
48005
+ requiredByClassName,
48006
+ persistedByClassName: /* @__PURE__ */ new Map(),
48007
+ persistedRequiredByClassName: /* @__PURE__ */ new Map()
48008
+ };
48009
+ }
48010
+ function withPersistedConstructorSignatures(index, classes, constructors) {
48011
+ const byId = new Map(constructors.map((entry) => [entry.id, entry]));
48012
+ const persistedByClassName = /* @__PURE__ */ new Map();
48013
+ const persistedRequiredByClassName = /* @__PURE__ */ new Map();
48014
+ for (const schemaClass2 of classes) {
48015
+ if (schemaClass2.requiredConstructorId !== void 0) {
48016
+ const required2 = byId.get(schemaClass2.requiredConstructorId);
48017
+ if (required2 !== void 0) {
48018
+ persistedRequiredByClassName.set(
48019
+ schemaClass2.name,
48020
+ required2.arguments.map((argument2) => argument2.name)
48021
+ );
48022
+ }
48023
+ }
48024
+ const overloads = (schemaClass2.constructorIds ?? []).flatMap((id2) => {
48025
+ const constructor2 = byId.get(id2);
48026
+ return constructor2 === void 0 ? [] : [constructor2.arguments.map((argument2) => argument2.name)];
48027
+ });
48028
+ if (overloads.length > 0) {
48029
+ persistedByClassName.set(schemaClass2.name, overloads);
48030
+ }
48031
+ }
48032
+ return {
48033
+ ...index,
48034
+ persistedByClassName,
48035
+ persistedRequiredByClassName
48036
+ };
47890
48037
  }
47891
48038
  function declaresConstructors(index, className) {
47892
48039
  if (className === null) return false;
47893
48040
  if (index.requiredByClassName.has(className)) return true;
47894
- return (index.byClassName.get(className)?.length ?? 0) > 0;
48041
+ if (index.persistedRequiredByClassName.has(className)) return true;
48042
+ return (index.byClassName.get(className)?.length ?? 0) > 0 || (index.persistedByClassName.get(className)?.length ?? 0) > 0;
47895
48043
  }
47896
48044
  function declaresParameterlessConstructor(index, className) {
47897
48045
  if (className === null) return false;
47898
48046
  const required2 = index.requiredByClassName.get(className);
47899
48047
  if (required2 !== void 0 && required2.parameters.length === 0) return true;
48048
+ const persistedRequired = index.persistedRequiredByClassName.get(className);
48049
+ if (persistedRequired !== void 0 && persistedRequired.length === 0) {
48050
+ return true;
48051
+ }
47900
48052
  const declared = index.byClassName.get(className);
47901
- if (declared === void 0) return false;
47902
- return declared.some((entry) => entry.parameters.length === 0);
48053
+ if (declared?.some((entry) => entry.parameters.length === 0) === true) {
48054
+ return true;
48055
+ }
48056
+ return index.persistedByClassName.get(className)?.some((parameters) => parameters.length === 0) ?? false;
47903
48057
  }
47904
48058
  function initializerRequiresEvaluation(index, expression, targetClassName, runtimeIdentifiers = /* @__PURE__ */ new Set()) {
47905
48059
  if (expression.kind === "annotated") {
@@ -47925,8 +48079,10 @@ function initializerRequiresEvaluation(index, expression, targetClassName, runti
47925
48079
  function requiredConstructorParameterNames(index, className) {
47926
48080
  if (className === null) return /* @__PURE__ */ new Set();
47927
48081
  const required2 = index.requiredByClassName.get(className);
47928
- if (required2 === void 0) return /* @__PURE__ */ new Set();
47929
- return new Set(required2.parameters.map((parameter3) => parameter3.name));
48082
+ if (required2 !== void 0) {
48083
+ return new Set(required2.parameters.map((parameter3) => parameter3.name));
48084
+ }
48085
+ return new Set(index.persistedRequiredByClassName.get(className) ?? []);
47930
48086
  }
47931
48087
  function expressionReadsRuntimeIdentifier(expression, runtimeIdentifiers) {
47932
48088
  if (runtimeIdentifiers.size === 0) return false;
@@ -48019,7 +48175,9 @@ var init_declared_constructors2 = __esm({
48019
48175
  init_src();
48020
48176
  EMPTY_DECLARED_CONSTRUCTOR_INDEX = {
48021
48177
  byClassName: /* @__PURE__ */ new Map(),
48022
- requiredByClassName: /* @__PURE__ */ new Map()
48178
+ requiredByClassName: /* @__PURE__ */ new Map(),
48179
+ persistedByClassName: /* @__PURE__ */ new Map(),
48180
+ persistedRequiredByClassName: /* @__PURE__ */ new Map()
48023
48181
  };
48024
48182
  }
48025
48183
  });
@@ -50961,7 +51119,14 @@ function classToLanguageType(schemaClass2, context) {
50961
51119
  type: {
50962
51120
  kind: "typeParameter",
50963
51121
  id: parameter3.id,
50964
- name: parameter3.name
51122
+ name: parameter3.name,
51123
+ ownerClassId: schemaClass2.id,
51124
+ ...parameter3.constraint === void 0 || parameter3.constraint === null ? {} : {
51125
+ constraint: namedType(
51126
+ parameter3.constraint.kind === "class" ? parameter3.constraint.classId : parameter3.constraint.enumId,
51127
+ true
51128
+ )
51129
+ }
50965
51130
  },
50966
51131
  location: virtualIdentifierLocation(
50967
51132
  context,
@@ -50982,7 +51147,33 @@ function constructorSignature(schemaClass2, members, context, genericEnvironment
50982
51147
  return {};
50983
51148
  }
50984
51149
  if (resolveAllowedStorage(schemaClass2.id, context.vm.classes) === "immutable" /* Immutable */) {
50985
- return { constructorUnavailableReason: "immutableOnly" };
51150
+ const signature2 = buildNeoScriptConstructorSignature(
51151
+ schemaClass2.id,
51152
+ members,
51153
+ (memberId) => {
51154
+ const record3 = analyzerMemberById(context.vm, memberId);
51155
+ if (!record3) return null;
51156
+ try {
51157
+ const resolved = substituteMember(
51158
+ record3,
51159
+ genericEnvironment,
51160
+ context.vm.members
51161
+ );
51162
+ return {
51163
+ required: resolved.required,
51164
+ defaultValue: "defaultValue" in resolved ? resolved.defaultValue : void 0
51165
+ };
51166
+ } catch {
51167
+ return projections.some(
51168
+ (projection) => projection.memberId === memberId
51169
+ ) ? { required: true } : null;
51170
+ }
51171
+ }
51172
+ );
51173
+ return {
51174
+ storedConstructionReplaySignature: signature2,
51175
+ constructorUnavailableReason: "immutableOnly"
51176
+ };
50986
51177
  }
50987
51178
  const signature = buildNeoScriptConstructorSignature(
50988
51179
  schemaClass2.id,
@@ -51788,10 +51979,20 @@ function toLanguageType(type, context, genericEnvironment) {
51788
51979
  const name = owner?.genericParams?.find(
51789
51980
  (parameter3) => parameter3.id === effectiveParamId
51790
51981
  )?.name ?? effectiveParamId;
51982
+ const declaration = owner?.genericParams?.find(
51983
+ (parameter3) => parameter3.id === effectiveParamId
51984
+ );
51791
51985
  return {
51792
51986
  kind: "typeParameter",
51793
51987
  id: effectiveParamId,
51794
51988
  name,
51989
+ ...owner === void 0 ? {} : { ownerClassId: owner.id },
51990
+ ...declaration?.constraint === void 0 || declaration.constraint === null ? {} : {
51991
+ constraint: namedType(
51992
+ declaration.constraint.kind === "class" ? declaration.constraint.classId : declaration.constraint.enumId,
51993
+ true
51994
+ )
51995
+ },
51795
51996
  nullable: !required2
51796
51997
  };
51797
51998
  }
@@ -52142,6 +52343,7 @@ function compileStrict(code, context) {
52142
52343
  deferred: context.deferred,
52143
52344
  functionName: context.functionName,
52144
52345
  migrationContext: context.migrationContext,
52346
+ storedConstructionReplay: context.storedConstructionReplay,
52145
52347
  valueAliases: context.valueAliases,
52146
52348
  implicitMemberAccess: context.implicitMemberAccess,
52147
52349
  declaringType: context.declaringType,
@@ -52206,9 +52408,10 @@ function createContext(ctx, options) {
52206
52408
  analyzer,
52207
52409
  ctx.compilationProject
52208
52410
  );
52209
- if (ctx.implicitMemberAccess !== true) return adapted;
52411
+ const replayContext = ctx.storedConstructionReplay === true ? { ...adapted, storedConstructionReplay: true } : adapted;
52412
+ if (ctx.implicitMemberAccess !== true) return replayContext;
52210
52413
  return {
52211
- ...adapted,
52414
+ ...replayContext,
52212
52415
  ...ctx.staticMember === true ? { thisClass: void 0 } : {},
52213
52416
  implicitMemberAccess: true,
52214
52417
  ...adapted.thisClass ? { declaringType: adapted.thisClass } : {},
@@ -52432,7 +52635,7 @@ function compileMemberInitializerBody(args) {
52432
52635
  );
52433
52636
  }
52434
52637
  const members = replaceMember(args.members, args.member);
52435
- const returnTypeInfo = resolveMemberDeclaredTypeInfo(args.member, members);
52638
+ const returnTypeInfo = resolveMemberDeclaredTypeInfo(args.member, members) ?? initializerGenericTypeInfo(args.member, args.thisClass);
52436
52639
  if (returnTypeInfo === null) {
52437
52640
  throw new Error(
52438
52641
  `Member "${args.member.name}" has an initializer but no resolvable declared type.`
@@ -52469,6 +52672,19 @@ function compileMemberInitializerBody(args) {
52469
52672
  }
52470
52673
  Object.assign(defaultValue.init, { compiled });
52471
52674
  }
52675
+ function initializerGenericTypeInfo(member, ownerClass) {
52676
+ if (!isMemberGenericBase(member) || ownerClass === null) return null;
52677
+ const declaration = ownerClass.genericParams?.find(
52678
+ (parameter3) => parameter3.id === member.genericParamId
52679
+ );
52680
+ if (declaration === void 0) return null;
52681
+ return {
52682
+ type: 21 /* Generic */,
52683
+ required: member.required,
52684
+ ownerClassId: ownerClass.id,
52685
+ genericParamId: declaration.id
52686
+ };
52687
+ }
52472
52688
  function compileValueRowInitializerBody(args) {
52473
52689
  const container = args.valueRow;
52474
52690
  if (!isInitValueContent(container)) return;
@@ -52504,7 +52720,8 @@ function compileValueRowInitializerBody(args) {
52504
52720
  args.initializerOwnerClass,
52505
52721
  args.constructors ?? []
52506
52722
  ),
52507
- ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject }
52723
+ ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
52724
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
52508
52725
  })
52509
52726
  );
52510
52727
  } catch (error) {
@@ -52644,6 +52861,11 @@ function compileConstructorBaseArguments(args, owner) {
52644
52861
  `Constructor "${args.constructor.id}" binds base argument "${baseArgument.name}", which base constructor "${baseConstructor.id}" does not declare.`
52645
52862
  );
52646
52863
  }
52864
+ const returnTypeInfo = substituteConstructorBaseType(
52865
+ parameter3,
52866
+ owner,
52867
+ args
52868
+ );
52647
52869
  return compileUnit2(
52648
52870
  "getter",
52649
52871
  () => compileNSInitializer(baseArgument.code, {
@@ -52655,7 +52877,7 @@ function compileConstructorBaseArguments(args, owner) {
52655
52877
  interfaces: [...args.interfaces ?? []],
52656
52878
  constructors: args.constructors,
52657
52879
  ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
52658
- returnTypeInfo: parameter3,
52880
+ returnTypeInfo,
52659
52881
  argumentTypes,
52660
52882
  initializerName: `${owner.name} base argument ${baseArgument.name}`
52661
52883
  })
@@ -52664,6 +52886,65 @@ function compileConstructorBaseArguments(args, owner) {
52664
52886
  );
52665
52887
  Object.assign(args.constructor, { compiledBaseArguments });
52666
52888
  }
52889
+ function substituteConstructorBaseType(typeInfo, owner, args) {
52890
+ if (typeInfo.type === 21 /* Generic */) {
52891
+ const binding = resolveGenericEnv(owner.id, args.classes).get(
52892
+ typeInfo.genericParamId
52893
+ );
52894
+ if (binding === void 0) return typeInfo;
52895
+ if (binding.kind === "unbound") {
52896
+ return {
52897
+ ...typeInfo,
52898
+ ownerClassId: owner.id,
52899
+ genericParamId: binding.paramId
52900
+ };
52901
+ }
52902
+ const member = args.members.find(
52903
+ (candidate) => candidate.id === binding.memberId
52904
+ );
52905
+ if (member === void 0) {
52906
+ throw new Error(
52907
+ `Constructor "${args.constructor.id}" resolves generic parameter "${typeInfo.genericParamId}" to missing member "${binding.memberId}".`
52908
+ );
52909
+ }
52910
+ return resolveMemberDeclaredTypeInfo(member, args.members) ?? typeInfo;
52911
+ }
52912
+ if (typeInfo.type === 25 /* NSDelegate */) {
52913
+ return {
52914
+ ...typeInfo,
52915
+ returnTypeInfo: substituteConstructorBaseType(
52916
+ typeInfo.returnTypeInfo,
52917
+ owner,
52918
+ args
52919
+ ),
52920
+ argumentTypes: typeInfo.argumentTypes.map(
52921
+ (argument2) => substituteConstructorBaseType(argument2, owner, args)
52922
+ )
52923
+ };
52924
+ }
52925
+ if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
52926
+ return {
52927
+ ...typeInfo,
52928
+ entryTypeInfo: substituteConstructorBaseType(
52929
+ typeInfo.entryTypeInfo,
52930
+ owner,
52931
+ args
52932
+ )
52933
+ };
52934
+ }
52935
+ if (typeInfo.type !== 7 /* Class */ || typeInfo.typeArguments === void 0) {
52936
+ return typeInfo;
52937
+ }
52938
+ return {
52939
+ ...typeInfo,
52940
+ typeArguments: Object.fromEntries(
52941
+ Object.entries(typeInfo.typeArguments).map(([parameterId, argument2]) => [
52942
+ parameterId,
52943
+ substituteConstructorBaseType(argument2, owner, args)
52944
+ ])
52945
+ )
52946
+ };
52947
+ }
52667
52948
  function compileConstructorBaseInitializerFields(args, owner) {
52668
52949
  const fields = args.constructor.baseInitializerFields ?? [];
52669
52950
  if (fields.length === 0) {
@@ -52983,6 +53264,7 @@ var init_compile_ns_property = __esm({
52983
53264
  "use strict";
52984
53265
  init_members();
52985
53266
  init_inheritance();
53267
+ init_generics();
52986
53268
  init_neoscript();
52987
53269
  init_core();
52988
53270
  init_lookup_declared_type();
@@ -53196,6 +53478,19 @@ var init_value_row_owner_members = __esm({
53196
53478
  });
53197
53479
 
53198
53480
  // ../src/database/constructor-argument-ownership.ts
53481
+ function constructorActionParameterId(constructor2, index) {
53482
+ const action = constructor2.action;
53483
+ if (action !== null && typeof action === "object") {
53484
+ const parameters = action.parameters;
53485
+ if (Array.isArray(parameters)) {
53486
+ const parameter3 = parameters[index + 2];
53487
+ if (parameter3 !== null && typeof parameter3 === "object" && typeof parameter3.id === "string") {
53488
+ return parameter3.id;
53489
+ }
53490
+ }
53491
+ }
53492
+ return `__arg_${index}__`;
53493
+ }
53199
53494
  function createTypedValueNormalizer(rows, document, childrenByContainerId, parameterTypesForRow, memberById, memberTypeInfo) {
53200
53495
  const visiting = /* @__PURE__ */ new Set();
53201
53496
  const normalizeLiteral = (value) => {
@@ -53550,7 +53845,7 @@ var init_constructor_argument_ownership = __esm({
53550
53845
  }
53551
53846
  const env = rowGenericEnvironment(this.document, root);
53552
53847
  for (let index = 0; index < constructor2.argumentTypes.length; index += 1) {
53553
- const parameterId = constructor2.action.parameters[index + 2]?.id;
53848
+ const parameterId = constructorActionParameterId(constructor2, index);
53554
53849
  const rawTypeInfo = constructor2.argumentTypes[index];
53555
53850
  if (parameterId === void 0 || rawTypeInfo === void 0) continue;
53556
53851
  const typeInfo = this.resolveTypeInfo(rawTypeInfo, env);
@@ -54720,7 +55015,12 @@ function makeEvaluatorLookups(members, values, options = {}) {
54720
55015
  if (options.includeValueGraphIndexes === true) {
54721
55016
  return {
54722
55017
  ...lookups,
54723
- evaluatorIndexes: buildEvaluatorBaseIndexes(members, values, valMap)
55018
+ evaluatorIndexes: buildEvaluatorBaseIndexes(members, values, valMap),
55019
+ ...options.constructorInitializerDocument === void 0 ? {} : {
55020
+ constructorInitializerIndexes: buildConstructorInitializerIndexes(
55021
+ options.constructorInitializerDocument
55022
+ )
55023
+ }
54724
55024
  };
54725
55025
  }
54726
55026
  return lookups;
@@ -57590,6 +57890,8 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
57590
57890
  return isDecimalString(value);
57591
57891
  case 3 /* String */:
57592
57892
  return typeof value === "string";
57893
+ case 25 /* NSDelegate */:
57894
+ return isNSDelegateClosureValue(value) || isMemberDelegateTarget(value);
57593
57895
  case 11 /* Sprite */:
57594
57896
  return isRuntimeSpriteValue(value);
57595
57897
  case 12 /* Audio */:
@@ -58639,7 +58941,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
58639
58941
  `Cannot construct open generic Class '${schemaClass2.name}'.`
58640
58942
  );
58641
58943
  }
58642
- if (resolveAllowedStorage(classId, ctx.vm.classes) === "immutable" /* Immutable */) {
58944
+ if (resolveAllowedStorage(classId, ctx.vm.classes) === "immutable" /* Immutable */ && ctx.storedConstructionReplay !== true) {
58643
58945
  throw new NSGetterRuntimeError(
58644
58946
  `Cannot construct Immutable-only Class '${schemaClass2.name}'.`
58645
58947
  );
@@ -59079,7 +59381,15 @@ function constructClassValueWithinFrame(descriptor, scope, ctx) {
59079
59381
  // A class with no declared constructors can still carry init-backed
59080
59382
  // member defaults (P43 §2, `string Foo = StaticFunc("bar")`), so the
59081
59383
  // schema-derived path evaluates them exactly as the declared one does.
59082
- initEvaluator: constructionInitEvaluator(ctx, createdValues),
59384
+ initEvaluator: constructionInitEvaluator(
59385
+ ctx,
59386
+ createdValues,
59387
+ {
59388
+ valuesByClassId: /* @__PURE__ */ new Map(),
59389
+ missingScopeReason: "no-constructor"
59390
+ },
59391
+ classId
59392
+ ),
59083
59393
  constructorRoot: {
59084
59394
  providedSchemaKeys: new Set(
59085
59395
  supplied.filter((entry) => entry.value !== null).map((entry) => entry.validated.schemaKey)
@@ -59330,15 +59640,17 @@ function runDeclaredConstructorChain(args) {
59330
59640
  args.visitedConstructorIds.add(record3.id);
59331
59641
  const baseRecord = resolveBaseConstructorRecord(record3, ctx);
59332
59642
  if (baseRecord !== null) {
59643
+ const preparedBaseArguments = args.preparedArgumentScopes.valuesByClassId.get(baseRecord.classId);
59333
59644
  runDeclaredConstructorChain({
59334
59645
  record: baseRecord,
59335
- argumentValues: evaluateBaseConstructorArguments(
59646
+ argumentValues: preparedBaseArguments ?? evaluateBaseConstructorArguments(
59336
59647
  record3,
59337
59648
  baseRecord,
59338
59649
  args.argumentValues,
59339
59650
  args.thisValue,
59340
59651
  ctx
59341
59652
  ),
59653
+ preparedArgumentScopes: args.preparedArgumentScopes,
59342
59654
  thisValue: args.thisValue,
59343
59655
  ctx,
59344
59656
  visitedConstructorIds: args.visitedConstructorIds,
@@ -59443,13 +59755,180 @@ function evaluateBaseInitializerFields(args) {
59443
59755
  return { validated, value };
59444
59756
  });
59445
59757
  }
59446
- function constructionInitEvaluator(ctx, createdValues, argumentValues = []) {
59447
- return (member, init) => evaluateInitializerInContext(
59448
- init,
59449
- member,
59450
- ctx,
59451
- createdValues,
59452
- argumentValues
59758
+ function constructionInitEvaluator(ctx, createdValues, argumentScopes, constructedClassId) {
59759
+ const indexes = constructorInitializerIndexes(ctx);
59760
+ const inheritanceChain = resolveInheritanceChain(
59761
+ constructedClassId,
59762
+ ctx.vm.classes
59763
+ );
59764
+ const owningClassId = (memberId) => {
59765
+ const visited = /* @__PURE__ */ new Set();
59766
+ let currentId = memberId;
59767
+ while (currentId !== void 0 && !visited.has(currentId)) {
59768
+ visited.add(currentId);
59769
+ const declaringClassIds = indexes.declaringClassIdsByMemberId.get(currentId);
59770
+ const owner = inheritanceChain.find(
59771
+ (schemaClass2) => declaringClassIds?.has(schemaClass2.id)
59772
+ );
59773
+ if (owner !== void 0) return owner.id;
59774
+ currentId = indexes.containerMemberIdByEntryId.get(currentId) ?? indexes.memberById.get(currentId)?.extendsMemberId;
59775
+ }
59776
+ return null;
59777
+ };
59778
+ return (member, init) => {
59779
+ if (init.compiled === void 0) {
59780
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59781
+ }
59782
+ const memberId = Reflect.get(member, "id");
59783
+ const scopeMemberId = indexes.initializerScopeMemberIds.get(init) ?? (typeof memberId === "string" ? memberId : "");
59784
+ const ownerClassId = owningClassId(scopeMemberId);
59785
+ const expectedArgumentCount = init.compiled?.parameters.slice(2).length;
59786
+ if (ownerClassId === null) {
59787
+ if (expectedArgumentCount !== void 0 && expectedArgumentCount > 0) {
59788
+ throw new NSGetterRuntimeError(
59789
+ `Member initializer '${member.name}' has ${expectedArgumentCount} constructor parameter(s), but its declaring class scope could not be resolved.`
59790
+ );
59791
+ }
59792
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59793
+ }
59794
+ const scopedArguments = argumentScopes.valuesByClassId.get(ownerClassId);
59795
+ if (scopedArguments === void 0) {
59796
+ if (expectedArgumentCount === 0) {
59797
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59798
+ }
59799
+ if (argumentScopes.missingScopeReason === "no-constructor") {
59800
+ throw new NSGetterRuntimeError(
59801
+ `Member initializer '${member.name}' on '${ownerClassId}' cannot read constructor parameters because schema-derived construction invoked no constructor.`
59802
+ );
59803
+ }
59804
+ throw new NSGetterRuntimeError(
59805
+ `Member initializer '${member.name}' on '${ownerClassId}' cannot read constructor parameters because its ': base(...)' arguments depend on initialized 'this'.`
59806
+ );
59807
+ }
59808
+ if (expectedArgumentCount !== void 0 && expectedArgumentCount !== scopedArguments.length) {
59809
+ throw new NSGetterRuntimeError(
59810
+ `Member initializer '${member.name}' on '${ownerClassId}' expected ${expectedArgumentCount} constructor argument(s), got ${scopedArguments.length}.`
59811
+ );
59812
+ }
59813
+ return evaluateInitializerInContext(
59814
+ init,
59815
+ member,
59816
+ ctx,
59817
+ createdValues,
59818
+ scopedArguments
59819
+ );
59820
+ };
59821
+ }
59822
+ function constructorInitializerIndexes(ctx) {
59823
+ if (ctx.__constructorInitializerIndexes !== void 0) {
59824
+ return ctx.__constructorInitializerIndexes;
59825
+ }
59826
+ const shared = ctx.vm.databaseVM?.constructorInitializerIndexes;
59827
+ if (shared !== void 0) {
59828
+ ctx.__constructorInitializerIndexes = shared;
59829
+ return shared;
59830
+ }
59831
+ const built = buildConstructorInitializerIndexes(ctx.vm);
59832
+ ctx.__constructorInitializerIndexes = built;
59833
+ return built;
59834
+ }
59835
+ function buildConstructorInitializerIndexes(vm) {
59836
+ const initializerScopeMemberIds = /* @__PURE__ */ new WeakMap();
59837
+ const initializerByValueId = /* @__PURE__ */ new Map();
59838
+ for (const row of vm.values) {
59839
+ const initializer = Reflect.get(row, "init");
59840
+ if (initializer !== void 0)
59841
+ initializerByValueId.set(row.id, initializer);
59842
+ }
59843
+ for (const member of vm.members) {
59844
+ const defaultValue = member.defaultValue;
59845
+ if (isInitValueContent(defaultValue)) {
59846
+ initializerScopeMemberIds.set(defaultValue.init, member.id);
59847
+ }
59848
+ }
59849
+ const initializerRootOwners = /* @__PURE__ */ new Map();
59850
+ resolveOwnerMembersForValues(
59851
+ {
59852
+ classes: vm.classes,
59853
+ members: vm.members,
59854
+ values: vm.values
59855
+ },
59856
+ new Set(initializerByValueId.keys()),
59857
+ void 0,
59858
+ initializerRootOwners
59859
+ );
59860
+ for (const [valueId, initializer] of initializerByValueId) {
59861
+ const rootOwnerId = Reflect.get(
59862
+ initializerRootOwners.get(valueId) ?? {},
59863
+ "id"
59864
+ );
59865
+ if (typeof rootOwnerId === "string") {
59866
+ initializerScopeMemberIds.set(initializer, rootOwnerId);
59867
+ }
59868
+ }
59869
+ const declaringClassIdsByMemberId = /* @__PURE__ */ new Map();
59870
+ for (const schemaClass2 of vm.classes) {
59871
+ for (const memberId of Object.values(schemaClass2.schema)) {
59872
+ const owners = declaringClassIdsByMemberId.get(memberId) ?? /* @__PURE__ */ new Set();
59873
+ owners.add(schemaClass2.id);
59874
+ declaringClassIdsByMemberId.set(memberId, owners);
59875
+ }
59876
+ }
59877
+ const memberById = new Map(vm.members.map((member) => [member.id, member]));
59878
+ const containerMemberIdByEntryId = /* @__PURE__ */ new Map();
59879
+ for (const member of vm.members) {
59880
+ if (isMemberList(member) || isMemberDictionary(member)) {
59881
+ containerMemberIdByEntryId.set(member.entryMemberId, member.id);
59882
+ }
59883
+ }
59884
+ return {
59885
+ initializerScopeMemberIds,
59886
+ declaringClassIdsByMemberId,
59887
+ memberById,
59888
+ containerMemberIdByEntryId
59889
+ };
59890
+ }
59891
+ function prepareConstructorArgumentScopes(record3, argumentValues, ctx) {
59892
+ const values = /* @__PURE__ */ new Map();
59893
+ let current = record3;
59894
+ let currentValues = argumentValues;
59895
+ while (current !== null) {
59896
+ values.set(current.classId, currentValues);
59897
+ const base = resolveBaseConstructorRecord(current, ctx);
59898
+ if (base === null) break;
59899
+ if (baseArgumentGettersReferenceThis(current)) break;
59900
+ currentValues = evaluateBaseConstructorArguments(
59901
+ current,
59902
+ base,
59903
+ currentValues,
59904
+ null,
59905
+ ctx
59906
+ );
59907
+ current = base;
59908
+ }
59909
+ return {
59910
+ valuesByClassId: values,
59911
+ missingScopeReason: record3 === null ? "no-constructor" : "base-arguments-depend-on-this"
59912
+ };
59913
+ }
59914
+ function baseArgumentGettersReferenceThis(record3) {
59915
+ return (record3.compiledBaseArguments ?? []).some((getter) => {
59916
+ const thisParameter = getter.parameters[0];
59917
+ return thisParameter !== void 0 && runtimeValueReferencesVariable(getter.instructions, thisParameter.id);
59918
+ });
59919
+ }
59920
+ function runtimeValueReferencesVariable(value, variableId, visited = /* @__PURE__ */ new WeakSet()) {
59921
+ if (typeof value !== "object" || value === null) return false;
59922
+ if (visited.has(value)) return false;
59923
+ visited.add(value);
59924
+ if (Reflect.get(value, "type") === "variable" /* variable */ && Reflect.get(value, "variableId") === variableId) {
59925
+ return true;
59926
+ }
59927
+ const children = Object.values(Object.getOwnPropertyDescriptors(value)).filter(
59928
+ (descriptor) => "value" in descriptor
59929
+ ).map((descriptor) => descriptor.value);
59930
+ return children.some(
59931
+ (child) => runtimeValueReferencesVariable(child, variableId, visited)
59453
59932
  );
59454
59933
  }
59455
59934
  function evaluateInitializerInContext(init, member, ctx, createdValues, argumentValues = []) {
@@ -59636,6 +60115,11 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59636
60115
  const schemaClass2 = descriptor.schemaClass;
59637
60116
  const classId = schemaClass2.id;
59638
60117
  const argumentValues = record3 === null ? [] : evaluateDeclaredConstructorArguments(info, record3, scope, ctx);
60118
+ const preparedArgumentScopes = prepareConstructorArgumentScopes(
60119
+ record3,
60120
+ argumentValues,
60121
+ ctx
60122
+ );
59639
60123
  const createdValues = [];
59640
60124
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
59641
60125
  let root;
@@ -59660,7 +60144,8 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59660
60144
  initEvaluator: constructionInitEvaluator(
59661
60145
  ctx,
59662
60146
  createdValues,
59663
- argumentValues
60147
+ preparedArgumentScopes,
60148
+ classId
59664
60149
  ),
59665
60150
  constructorRoot: {
59666
60151
  providedSchemaKeys: new Set(
@@ -59721,6 +60206,7 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59721
60206
  runDeclaredConstructorChain({
59722
60207
  record: record3,
59723
60208
  argumentValues,
60209
+ preparedArgumentScopes,
59724
60210
  thisValue: root.value,
59725
60211
  ctx,
59726
60212
  visitedConstructorIds: /* @__PURE__ */ new Set(),
@@ -60747,6 +61233,7 @@ var init_evaluateNSGetter = __esm({
60747
61233
  init_interfaces();
60748
61234
  init_neoscript();
60749
61235
  init_NSGetterRuntimeError();
61236
+ init_value_row_owner_members();
60750
61237
  init_decimal();
60751
61238
  init_members();
60752
61239
  init_core();
@@ -60853,17 +61340,20 @@ var init_evaluateNSGetter = __esm({
60853
61340
 
60854
61341
  // ../src/view-models/neoscript-evaluator/evaluateInitializer.ts
60855
61342
  function initializerEvaluatorLookups(document) {
60856
- const key = document;
61343
+ const key = document.evaluatorCache?.key ?? document;
61344
+ const revision = document.evaluatorCache?.revision;
60857
61345
  const cached = evaluatorLookupsByDocument.get(key);
60858
- if (cached !== void 0 && cached.members === document.members && cached.values === document.values) {
61346
+ if (cached !== void 0 && (revision === void 0 ? cached.members === document.members && cached.values === document.values : cached.revision === revision)) {
60859
61347
  return cached.lookups;
60860
61348
  }
60861
61349
  const lookups = makeEvaluatorLookups(document.members, document.values, {
60862
- includeValueGraphIndexes: true
61350
+ includeValueGraphIndexes: true,
61351
+ constructorInitializerDocument: document
60863
61352
  });
60864
61353
  evaluatorLookupsByDocument.set(key, {
60865
61354
  members: document.members,
60866
61355
  values: document.values,
61356
+ revision,
60867
61357
  lookups
60868
61358
  });
60869
61359
  return lookups;
@@ -60906,12 +61396,14 @@ function evaluateMemberInitializer(args) {
60906
61396
  constructors: args.document.constructors,
60907
61397
  interfaces: args.document.interfaces,
60908
61398
  localizedTexts: args.document.localizedTexts,
61399
+ localizationConfig: args.document.localizationConfig,
60909
61400
  databaseVM: initializerEvaluatorLookups(args.document)
60910
61401
  },
60911
61402
  thisValue: null,
60912
61403
  rootValue: buildInitializerRootValue(args.document),
60913
61404
  saveStaticBindings: args.saveStaticBindings,
60914
61405
  sessionStaticBindings: args.sessionStaticBindings,
61406
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {},
60915
61407
  __constructedArgumentsByValue: /* @__PURE__ */ new WeakMap(),
60916
61408
  __createdStorageKeyDeclarations: args.storageKeyDeclarations ?? /* @__PURE__ */ new Map()
60917
61409
  };
@@ -60960,7 +61452,8 @@ function evaluateInitializerMaterialization(args) {
60960
61452
  member: args.member,
60961
61453
  document: args.document,
60962
61454
  createdValues,
60963
- storageKeyDeclarations
61455
+ storageKeyDeclarations,
61456
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
60964
61457
  });
60965
61458
  return { evaluated, createdValues, storageKeyDeclarations };
60966
61459
  }
@@ -60968,7 +61461,8 @@ function materializeInitializerValue(args) {
60968
61461
  const { evaluated, createdValues, storageKeyDeclarations } = evaluateInitializerMaterialization({
60969
61462
  init: args.row.init,
60970
61463
  member: args.member,
60971
- document: args.document
61464
+ document: args.document,
61465
+ ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
60972
61466
  });
60973
61467
  const {
60974
61468
  init: _init,
@@ -61070,6 +61564,14 @@ function isNeoClassConstructorBase(value) {
61070
61564
  }
61071
61565
  return v.compiledBaseInitializerFields === void 0 || v.compiledBaseInitializerFields === null;
61072
61566
  }
61567
+ function isUncompiledNeoClassConstructor(value) {
61568
+ if (!isNeoClassConstructorBase(value)) return false;
61569
+ const v = value;
61570
+ if (typeof v.id !== "string" || v.id.length === 0) return false;
61571
+ if (typeof v.projectId !== "string" || v.projectId.length === 0) return false;
61572
+ if (!isEpochMillis(v.createdAt)) return false;
61573
+ return isEpochMillis(v.updatedAt);
61574
+ }
61073
61575
  function hasValidConstructorAction(action, argumentTypes) {
61074
61576
  if (!isNSFunctionWithReturnType(action)) return false;
61075
61577
  if (action.typeInfo.type !== 0 /* Null */) return false;
@@ -62461,7 +62963,7 @@ function readProjectDocument(value, options = {}) {
62461
62963
  constructors: readOptionalArrayField(
62462
62964
  value,
62463
62965
  "constructors",
62464
- isNeoClassConstructor
62966
+ options.constructors === "authored-or-compiled" ? (candidate) => isNeoClassConstructor(candidate) || isUncompiledNeoClassConstructor(candidate) : isNeoClassConstructor
62465
62967
  ),
62466
62968
  internalRecordRelations: readOptionalArrayField(
62467
62969
  value,
@@ -68291,6 +68793,7 @@ function collectNeoScriptRecompileTargets(args) {
68291
68793
  if (args.forceRecompile === true) return completeTargets(args.postDocument);
68292
68794
  const explicit = explicitTargetIds(args.changes);
68293
68795
  const { impactedIds, impactedTypeNames, constructedClassIds } = collectChangedContractIds(args);
68796
+ for (const id2 of args.additionalImpactedIds ?? []) impactedIds.add(id2);
68294
68797
  includeDerivedConstructionContracts(
68295
68798
  constructedClassIds,
68296
68799
  args.postDocument.classes
@@ -69349,9 +69852,17 @@ function materializeInitializersLocallyV4(args) {
69349
69852
  );
69350
69853
  if (sourceRoots.size === 0) return { roots: [] };
69351
69854
  let document = readPulledProjectDocumentV4(records2);
69352
- const rootOwners = resolveOwnerMembersForValues(document, sourceRoots);
69855
+ const rootKinds = /* @__PURE__ */ new Map();
69856
+ const rootOwners = resolveOwnerMembersForValues(
69857
+ document,
69858
+ sourceRoots,
69859
+ void 0,
69860
+ void 0,
69861
+ rootKinds
69862
+ );
69353
69863
  const roots = [];
69354
69864
  for (const sourceValueId of sourceRoots) {
69865
+ if (rootKinds.get(sourceValueId) === "declaration") continue;
69355
69866
  const rootOwner = rootOwners.get(sourceValueId);
69356
69867
  if (rootOwner === void 0) {
69357
69868
  throw new Error(
@@ -70399,18 +70910,26 @@ function replayAnimationDeclarationInitializersV4(records2, document) {
70399
70910
  const rootOwner = rootOwners.get(row.id);
70400
70911
  const rootOwnerId = Reflect.get(rootOwner ?? {}, "id");
70401
70912
  const initializerOwnerClass = typeof rootOwnerId !== "string" ? null : findSchemaPlacement(rootOwnerId, document.classes)?.ownerClass ?? null;
70402
- const replay = replayStoredConstructionV4({
70403
- records: pulled,
70404
- valueId: row.id,
70405
- code,
70406
- member: owner,
70407
- compileDocumentBodies: true,
70408
- initializerOwnerClass,
70409
- // A parameterized declaration is a template. Its arguments exist only
70410
- // at concrete construction sites, so validate the authored body here
70411
- // without fabricating values for the class header parameters.
70412
- evaluate: initializerOwnerClass?.requiredConstructorId === void 0 || initializerOwnerClass.requiredConstructorId === null
70413
- });
70913
+ let replay;
70914
+ try {
70915
+ replay = replayStoredConstructionV4({
70916
+ records: pulled,
70917
+ valueId: row.id,
70918
+ code,
70919
+ member: owner,
70920
+ compileDocumentBodies: true,
70921
+ initializerOwnerClass,
70922
+ // A parameterized declaration is a template. Its arguments exist only
70923
+ // at concrete construction sites, so validate the authored body here
70924
+ // without fabricating values for the class header parameters.
70925
+ evaluate: initializerOwnerClass?.requiredConstructorId === void 0 || initializerOwnerClass.requiredConstructorId === null
70926
+ });
70927
+ } catch (error) {
70928
+ throw new Error(
70929
+ `Animation declaration replay failed for value "${row.id}": ${error instanceof Error ? error.message : String(error)}`,
70930
+ { cause: error }
70931
+ );
70932
+ }
70414
70933
  for (const [id2, value] of replay) {
70415
70934
  if (!isMemberValue(value)) {
70416
70935
  throw new Error(
@@ -74089,7 +74608,8 @@ function prepareServerOwnedSchemaCommit(args) {
74089
74608
  const hasValueChange = authoredChanges.some(
74090
74609
  (change) => change.recordKind === "value"
74091
74610
  );
74092
- if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange) {
74611
+ const hasAdditionalContractImpact = (args.additionalImpactedIds?.size ?? 0) > 0;
74612
+ if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange && !hasAdditionalContractImpact) {
74093
74613
  return authoredChanges;
74094
74614
  }
74095
74615
  const authoredPostDocument = applyProjectVersionWriteChanges(
@@ -74100,6 +74620,7 @@ function prepareServerOwnedSchemaCommit(args) {
74100
74620
  currentDocument: args.document,
74101
74621
  postDocument: authoredPostDocument,
74102
74622
  changes: authoredChanges,
74623
+ additionalImpactedIds: args.additionalImpactedIds,
74103
74624
  forceRecompile: args.forceRecompile
74104
74625
  });
74105
74626
  const explicitlyChangedMemberIds = new Set(
@@ -77493,6 +78014,19 @@ function isOpaqueNSTypeInfo(value, ancestors = /* @__PURE__ */ new Set()) {
77493
78014
  if (value.type === 22) {
77494
78015
  return typeof value.interfaceId === "string" && value.interfaceId.length > 0;
77495
78016
  }
78017
+ if (value.type === 25) {
78018
+ if (!Array.isArray(value.argumentTypes) || ancestors.has(value)) {
78019
+ return false;
78020
+ }
78021
+ ancestors.add(value);
78022
+ try {
78023
+ return isOpaqueNSFunctionReturnTypeInfo(value.returnTypeInfo) && value.argumentTypes.every(
78024
+ (argument2) => isOpaqueNSTypeInfo(argument2, ancestors)
78025
+ );
78026
+ } finally {
78027
+ ancestors.delete(value);
78028
+ }
78029
+ }
77496
78030
  if (value.type === 5 || value.type === 6) {
77497
78031
  if (ancestors.has(value)) return false;
77498
78032
  ancestors.add(value);
@@ -77522,6 +78056,11 @@ function opaqueTypeInfoContainsUnknown(value) {
77522
78056
  if (value.type === 5 || value.type === 6 || value.type === 9) {
77523
78057
  return isRecord8(value.entryTypeInfo) && opaqueTypeInfoContainsUnknown(value.entryTypeInfo);
77524
78058
  }
78059
+ if (value.type === 25) {
78060
+ return isRecord8(value.returnTypeInfo) && opaqueTypeInfoContainsUnknown(value.returnTypeInfo) || Array.isArray(value.argumentTypes) && value.argumentTypes.some(
78061
+ (argument2) => isRecord8(argument2) && opaqueTypeInfoContainsUnknown(argument2)
78062
+ );
78063
+ }
77525
78064
  if (value.type !== 7 || !isRecord8(value.typeArguments)) return false;
77526
78065
  return Object.values(value.typeArguments).some(
77527
78066
  (argument2) => isRecord8(argument2) && opaqueTypeInfoContainsUnknown(argument2)
@@ -77536,6 +78075,10 @@ function isOpaqueNSFunctionReturnTypeInfo(value) {
77536
78075
  function isOpaqueNSFunctionArgumentTypeInfo(value) {
77537
78076
  return isOpaqueNSTypeInfo(value) && isOpaqueCallableIdentifier(value.name) && !opaqueTypeInfoContainsUnknown(value);
77538
78077
  }
78078
+ function isOpaqueConstructorArgumentTypeInfo(value) {
78079
+ if (!isRecord8(value)) return false;
78080
+ return isOpaqueNSTypeInfo(value) && (value.name === "value" || isOpaqueCallableIdentifier(value.name)) && !opaqueTypeInfoContainsUnknown(value);
78081
+ }
77539
78082
  function memberSignature(member) {
77540
78083
  if (member.kind === "property") {
77541
78084
  return `property:${member.settable === true}:${stableTypeInfo(member.typeInfo)}`;
@@ -78887,7 +79430,7 @@ function assertOpaqueConstructorValid(declaredConstructor) {
78887
79430
  );
78888
79431
  }
78889
79432
  const argumentTypes = declaredConstructor.argumentTypes;
78890
- if (!argumentTypes.every(isOpaqueNSFunctionArgumentTypeInfo)) {
79433
+ if (!argumentTypes.every(isOpaqueConstructorArgumentTypeInfo)) {
78891
79434
  throw new Error(
78892
79435
  `Constructor "${declaredConstructor.id}" argumentTypes are invalid.`
78893
79436
  );
@@ -80657,6 +81200,7 @@ function replayStoredConstructionV4(args) {
80657
81200
  // Instance calls are self-contained. Declaration calls inherit the class
80658
81201
  // header parameters that are in lexical scope at their source site.
80659
81202
  initializerOwnerClass: args.initializerOwnerClass ?? null,
81203
+ storedConstructionReplay: true,
80660
81204
  ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject }
80661
81205
  });
80662
81206
  if (!isMemberValue(candidate) || !isInitValueContent(candidate)) {
@@ -80665,6 +81209,7 @@ function replayStoredConstructionV4(args) {
80665
81209
  );
80666
81210
  }
80667
81211
  if (args.evaluate === false) return /* @__PURE__ */ new Map();
81212
+ assertPulledConstructorsCompiled(document);
80668
81213
  const compiledDependencies = /* @__PURE__ */ new Set();
80669
81214
  let materialized;
80670
81215
  for (; ; ) {
@@ -80674,7 +81219,8 @@ function replayStoredConstructionV4(args) {
80674
81219
  // Constructor-only rows have no structural member owner. Use the same
80675
81220
  // explicit typed descriptor for evaluation that compiled the replay.
80676
81221
  member: compileMember,
80677
- row: candidate
81222
+ row: candidate,
81223
+ storedConstructionReplay: true
80678
81224
  });
80679
81225
  break;
80680
81226
  } catch (error) {
@@ -80705,6 +81251,7 @@ function compilePulledProjectDocumentBodiesV4(document) {
80705
81251
  for (const constructor2 of compileArgs.constructors) {
80706
81252
  compileConstructorRecord({ ...compileArgs, constructor: constructor2 });
80707
81253
  }
81254
+ assertPulledConstructorsCompiled(document);
80708
81255
  const ownerClassByMemberId = new Map(
80709
81256
  compileArgs.classes.flatMap(
80710
81257
  (schemaClass2) => Object.values(schemaClass2.schema).map(
@@ -80720,6 +81267,16 @@ function compilePulledProjectDocumentBodiesV4(document) {
80720
81267
  });
80721
81268
  }
80722
81269
  }
81270
+ function assertPulledConstructorsCompiled(document) {
81271
+ const uncompiled = (document.constructors ?? []).find(
81272
+ (constructor2) => !isNeoClassConstructor(constructor2)
81273
+ );
81274
+ if (uncompiled !== void 0) {
81275
+ throw new Error(
81276
+ `Constructor "${uncompiled.id}" was read from authored source but was not compiled before evaluation.`
81277
+ );
81278
+ }
81279
+ }
80723
81280
  function compilePulledMemberInitializerBodyV4(document, memberId) {
80724
81281
  const compileArgs = {
80725
81282
  project: document.project,
@@ -80747,7 +81304,8 @@ function compilePulledMemberInitializerBodyV4(document, memberId) {
80747
81304
  }
80748
81305
  function readPulledProjectDocumentV4(records2) {
80749
81306
  return readProjectDocument(
80750
- pulledProjectDocumentRaw(replayWorkspace(records2))
81307
+ pulledProjectDocumentRaw(replayWorkspace(records2)),
81308
+ { constructors: "authored-or-compiled" }
80751
81309
  );
80752
81310
  }
80753
81311
  function replayWorkspace(records2) {
@@ -80787,6 +81345,7 @@ var init_initializer_replay = __esm({
80787
81345
  init_project_document_read();
80788
81346
  init_server_preparation_preflight();
80789
81347
  init_projection();
81348
+ init_constructors2();
80790
81349
  init_neoscript_evaluator();
80791
81350
  }
80792
81351
  });
@@ -81154,7 +81713,12 @@ function buildValueLowerContext(state, manifest, options = {}) {
81154
81713
  const classesByName = new Map(
81155
81714
  manifest.classes.map((entry) => [entry.name, entry])
81156
81715
  );
81157
- const declaredConstructorIndex = options.analysis === void 0 ? EMPTY_DECLARED_CONSTRUCTOR_INDEX : buildDeclaredConstructorIndex(options.analysis);
81716
+ const sourceConstructorIndex = options.analysis === void 0 ? EMPTY_DECLARED_CONSTRUCTOR_INDEX : buildDeclaredConstructorIndex(options.analysis);
81717
+ const declaredConstructorIndex = withPersistedConstructorSignatures(
81718
+ sourceConstructorIndex,
81719
+ manifest.classes,
81720
+ manifest.constructors
81721
+ );
81158
81722
  return {
81159
81723
  state,
81160
81724
  members,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.22.2",
3
+ "version": "0.22.4",
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.2 -->
12
+ <!-- reviewed-through-cli: 0.22.4 -->
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.2 -->
81
+ <!-- reviewed-through-cli: 0.22.4 -->
82
82
  ```
83
83
 
84
84
  The quoted version above is checked too, so this instruction cannot go stale