@neocompose/cli 0.22.2 → 0.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.3] - 2026-08-04
4
+
5
+ ### Fixed
6
+
7
+ - Bundled Neo system classes now derive required and optional constructors from
8
+ their authored declarations as first-class `system_*` constructor records
9
+ instead of repurposing constructor projections.
10
+ - Pull, source lowering, local initializer replay, and push preserve those
11
+ constructors and their inherited parameter scopes, including initializer-
12
+ backed child rows such as animation segment frames.
13
+
3
14
  ## [0.22.2] - 2026-08-04
4
15
 
5
16
  ### 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,
@@ -29056,7 +29059,7 @@ function memberFromDocument(record3, members, owners, classNames, context) {
29056
29059
  );
29057
29060
  const modifier = memberModifier(overrideOf, isVirtual, isAbstract);
29058
29061
  const defaultValue = defaultValueFromDocument(
29059
- field("defaultValue", null),
29062
+ overrideOf !== null && !Object.hasOwn(data, "defaultValue") ? null : field("defaultValue", null),
29060
29063
  record3
29061
29064
  );
29062
29065
  const docsText = optionalDocsText(data.docsText, record3, "docsText");
@@ -36759,7 +36762,9 @@ function isMemberGenericBase(value) {
36759
36762
  if (!isSystemMetadata(v.system)) return false;
36760
36763
  if (v.system.kind !== SystemProtectionKind.WorldAuthoring) return false;
36761
36764
  }
36762
- if (v.defaultValue !== void 0 && v.defaultValue !== null) return false;
36765
+ if (v.defaultValue !== void 0 && v.defaultValue !== null && !isInitValueContent(v.defaultValue)) {
36766
+ return false;
36767
+ }
36763
36768
  if (v.required === true) return false;
36764
36769
  return true;
36765
36770
  }
@@ -38101,10 +38106,20 @@ var init_world_system_classes_generated = __esm({
38101
38106
  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
38107
  extendsWorldKind: "animationFrameBase",
38103
38108
  isAbstract: false,
38104
- constructorProjections: [
38109
+ requiredConstructorId: "system_498d073e-0018-5828-af2b-22b113c31380",
38110
+ constructors: [
38105
38111
  {
38106
- memberId: "system_b71d1f73-da72-49de-ab9a-911cc9bffa43",
38107
- parameterName: "value"
38112
+ constructorId: "system_498d073e-0018-5828-af2b-22b113c31380",
38113
+ argumentTypes: [
38114
+ {
38115
+ name: "value",
38116
+ type: 21,
38117
+ required: true,
38118
+ ownerClassId: "system_9c4f3bfb-f0d8-4231-a7e7-9115bab8d5ab",
38119
+ genericParamId: "system_887b11d3-e56a-47ff-8d01-e2fcefb846a1"
38120
+ }
38121
+ ],
38122
+ code: null
38108
38123
  }
38109
38124
  ],
38110
38125
  genericParams: [
@@ -38114,6 +38129,7 @@ var init_world_system_classes_generated = __esm({
38114
38129
  {
38115
38130
  memberId: "system_b71d1f73-da72-49de-ab9a-911cc9bffa43",
38116
38131
  memberKind: "generic",
38132
+ defaultInitializerCode: "value",
38117
38133
  genericParamId: "system_887b11d3-e56a-47ff-8d01-e2fcefb846a1",
38118
38134
  required: false,
38119
38135
  schemaKey: "Value"
@@ -38191,14 +38207,32 @@ var init_world_system_classes_generated = __esm({
38191
38207
  name: "NeoAnimationChildOverride",
38192
38208
  docsText: "What one child looks like while a clip frame holds: which child, and the\nvalues to override on it.",
38193
38209
  isAbstract: false,
38194
- constructorProjections: [
38210
+ requiredConstructorId: "system_2fefcc00-08ab-5a16-a76a-758beac24ef1",
38211
+ constructors: [
38195
38212
  {
38196
- memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
38197
- parameterName: "selector"
38198
- },
38199
- {
38200
- memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
38201
- parameterName: "overrides"
38213
+ constructorId: "system_2fefcc00-08ab-5a16-a76a-758beac24ef1",
38214
+ argumentTypes: [
38215
+ {
38216
+ name: "selector",
38217
+ type: 25,
38218
+ required: true,
38219
+ returnTypeInfo: {
38220
+ type: 21,
38221
+ required: true,
38222
+ ownerClassId: "system_e2e88eba-5335-4a16-9dcf-2c0e1951e8bd",
38223
+ genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0"
38224
+ },
38225
+ argumentTypes: []
38226
+ },
38227
+ {
38228
+ name: "overrides",
38229
+ type: 21,
38230
+ required: true,
38231
+ ownerClassId: "system_e2e88eba-5335-4a16-9dcf-2c0e1951e8bd",
38232
+ genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0"
38233
+ }
38234
+ ],
38235
+ code: null
38202
38236
  }
38203
38237
  ],
38204
38238
  genericParams: [
@@ -38212,6 +38246,7 @@ var init_world_system_classes_generated = __esm({
38212
38246
  {
38213
38247
  memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
38214
38248
  memberKind: "delegate",
38249
+ defaultInitializerCode: "selector",
38215
38250
  returnTypeInfo: {
38216
38251
  type: 21,
38217
38252
  required: true,
@@ -38234,6 +38269,7 @@ var init_world_system_classes_generated = __esm({
38234
38269
  {
38235
38270
  memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
38236
38271
  memberKind: "generic",
38272
+ defaultInitializerCode: "overrides",
38237
38273
  genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0",
38238
38274
  partial: true,
38239
38275
  required: false,
@@ -38247,16 +38283,31 @@ var init_world_system_classes_generated = __esm({
38247
38283
  name: "NeoAnimationTrackBase",
38248
38284
  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
38285
  isAbstract: true,
38250
- constructorProjections: [
38286
+ requiredConstructorId: "system_8980d09b-0a6d-5461-9615-2f524515b1af",
38287
+ constructors: [
38251
38288
  {
38252
- memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38253
- parameterName: "selector"
38289
+ constructorId: "system_8980d09b-0a6d-5461-9615-2f524515b1af",
38290
+ argumentTypes: [
38291
+ {
38292
+ name: "selector",
38293
+ type: 25,
38294
+ required: true,
38295
+ returnTypeInfo: {
38296
+ type: 7,
38297
+ required: true,
38298
+ classId: "system_61b30a92-90dc-4bf8-8503-ee4f6414effc"
38299
+ },
38300
+ argumentTypes: []
38301
+ }
38302
+ ],
38303
+ code: null
38254
38304
  }
38255
38305
  ],
38256
38306
  schemaFields: [
38257
38307
  {
38258
38308
  memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38259
38309
  memberKind: "delegate",
38310
+ defaultInitializerCode: "selector",
38260
38311
  returnTypeInfo: {
38261
38312
  type: 7,
38262
38313
  required: true,
@@ -38330,20 +38381,33 @@ var init_world_system_classes_generated = __esm({
38330
38381
  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
38382
  extendsWorldKind: "animationTrack",
38332
38383
  isAbstract: false,
38333
- constructorProjections: [
38384
+ requiredConstructorId: "system_6baa12a7-be86-5ae0-82da-2fed308320a0",
38385
+ constructors: [
38334
38386
  {
38335
- memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38336
- parameterName: "selector"
38337
- },
38338
- {
38339
- memberId: "system_2c816624-0281-46d3-9ed5-d20bd43519f4",
38340
- parameterName: "clipKey"
38387
+ constructorId: "system_6baa12a7-be86-5ae0-82da-2fed308320a0",
38388
+ argumentTypes: [
38389
+ {
38390
+ name: "selector",
38391
+ type: 25,
38392
+ required: true,
38393
+ returnTypeInfo: {
38394
+ type: 7,
38395
+ required: true,
38396
+ classId: "system_61b30a92-90dc-4bf8-8503-ee4f6414effc"
38397
+ },
38398
+ argumentTypes: []
38399
+ },
38400
+ { name: "clipKey", type: 3, required: true }
38401
+ ],
38402
+ code: null,
38403
+ baseArguments: [{ name: "selector", code: "selector" }]
38341
38404
  }
38342
38405
  ],
38343
38406
  schemaFields: [
38344
38407
  {
38345
38408
  memberId: "system_2c816624-0281-46d3-9ed5-d20bd43519f4",
38346
38409
  memberKind: "string",
38410
+ defaultInitializerCode: "clipKey",
38347
38411
  localizable: false,
38348
38412
  required: true,
38349
38413
  schemaKey: "ClipKey"
@@ -38357,10 +38421,26 @@ var init_world_system_classes_generated = __esm({
38357
38421
  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
38422
  extendsWorldKind: "animationTrack",
38359
38423
  isAbstract: true,
38360
- constructorProjections: [
38424
+ requiredConstructorId: "system_1e7f8826-5392-5b4c-8cc3-6052d20e5280",
38425
+ constructors: [
38361
38426
  {
38362
- memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
38363
- parameterName: "selector"
38427
+ constructorId: "system_1e7f8826-5392-5b4c-8cc3-6052d20e5280",
38428
+ argumentTypes: [
38429
+ {
38430
+ name: "selector",
38431
+ type: 25,
38432
+ required: true,
38433
+ returnTypeInfo: {
38434
+ type: 21,
38435
+ required: true,
38436
+ ownerClassId: "system_fd551dd8-6e6b-4044-9f32-7445ab344200",
38437
+ genericParamId: "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655"
38438
+ },
38439
+ argumentTypes: []
38440
+ }
38441
+ ],
38442
+ code: null,
38443
+ baseArguments: [{ name: "selector", code: "selector" }]
38364
38444
  }
38365
38445
  ],
38366
38446
  genericParams: [
@@ -38376,6 +38456,7 @@ var init_world_system_classes_generated = __esm({
38376
38456
  memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
38377
38457
  memberKind: "delegate",
38378
38458
  extendsMemberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
38459
+ defaultInitializerCode: "selector",
38379
38460
  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
38461
  returnTypeInfo: {
38381
38462
  type: 21,
@@ -38417,6 +38498,28 @@ var init_world_system_classes_generated = __esm({
38417
38498
  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
38499
  extendsWorldKind: "animationSegmentTrack",
38419
38500
  isAbstract: true,
38501
+ requiredConstructorId: "system_9a3f52ca-872a-50a5-aad9-e9a040f40802",
38502
+ constructors: [
38503
+ {
38504
+ constructorId: "system_9a3f52ca-872a-50a5-aad9-e9a040f40802",
38505
+ argumentTypes: [
38506
+ {
38507
+ name: "selector",
38508
+ type: 25,
38509
+ required: true,
38510
+ returnTypeInfo: {
38511
+ type: 21,
38512
+ required: true,
38513
+ ownerClassId: "system_24b70585-0798-49ad-b650-4c118bac1eb1",
38514
+ genericParamId: "system_4de90637-6a3b-4bba-95ef-2ff9dfb05268"
38515
+ },
38516
+ argumentTypes: []
38517
+ }
38518
+ ],
38519
+ code: null,
38520
+ baseArguments: [{ name: "selector", code: "selector" }]
38521
+ }
38522
+ ],
38420
38523
  extendsGenericBindings: {
38421
38524
  "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655": {
38422
38525
  kind: "generic",
@@ -47886,20 +47989,60 @@ function buildDeclaredConstructorIndex(analysis) {
47886
47989
  if (declaration.constructors.length === 0) continue;
47887
47990
  byClassName.set(declaration.name, declaration.constructors);
47888
47991
  }
47889
- return { byClassName, requiredByClassName };
47992
+ return {
47993
+ byClassName,
47994
+ requiredByClassName,
47995
+ persistedByClassName: /* @__PURE__ */ new Map(),
47996
+ persistedRequiredByClassName: /* @__PURE__ */ new Map()
47997
+ };
47998
+ }
47999
+ function withPersistedConstructorSignatures(index, classes, constructors) {
48000
+ const byId = new Map(constructors.map((entry) => [entry.id, entry]));
48001
+ const persistedByClassName = /* @__PURE__ */ new Map();
48002
+ const persistedRequiredByClassName = /* @__PURE__ */ new Map();
48003
+ for (const schemaClass2 of classes) {
48004
+ if (schemaClass2.requiredConstructorId !== void 0) {
48005
+ const required2 = byId.get(schemaClass2.requiredConstructorId);
48006
+ if (required2 !== void 0) {
48007
+ persistedRequiredByClassName.set(
48008
+ schemaClass2.name,
48009
+ required2.arguments.map((argument2) => argument2.name)
48010
+ );
48011
+ }
48012
+ }
48013
+ const overloads = (schemaClass2.constructorIds ?? []).flatMap((id2) => {
48014
+ const constructor2 = byId.get(id2);
48015
+ return constructor2 === void 0 ? [] : [constructor2.arguments.map((argument2) => argument2.name)];
48016
+ });
48017
+ if (overloads.length > 0) {
48018
+ persistedByClassName.set(schemaClass2.name, overloads);
48019
+ }
48020
+ }
48021
+ return {
48022
+ ...index,
48023
+ persistedByClassName,
48024
+ persistedRequiredByClassName
48025
+ };
47890
48026
  }
47891
48027
  function declaresConstructors(index, className) {
47892
48028
  if (className === null) return false;
47893
48029
  if (index.requiredByClassName.has(className)) return true;
47894
- return (index.byClassName.get(className)?.length ?? 0) > 0;
48030
+ if (index.persistedRequiredByClassName.has(className)) return true;
48031
+ return (index.byClassName.get(className)?.length ?? 0) > 0 || (index.persistedByClassName.get(className)?.length ?? 0) > 0;
47895
48032
  }
47896
48033
  function declaresParameterlessConstructor(index, className) {
47897
48034
  if (className === null) return false;
47898
48035
  const required2 = index.requiredByClassName.get(className);
47899
48036
  if (required2 !== void 0 && required2.parameters.length === 0) return true;
48037
+ const persistedRequired = index.persistedRequiredByClassName.get(className);
48038
+ if (persistedRequired !== void 0 && persistedRequired.length === 0) {
48039
+ return true;
48040
+ }
47900
48041
  const declared = index.byClassName.get(className);
47901
- if (declared === void 0) return false;
47902
- return declared.some((entry) => entry.parameters.length === 0);
48042
+ if (declared?.some((entry) => entry.parameters.length === 0) === true) {
48043
+ return true;
48044
+ }
48045
+ return index.persistedByClassName.get(className)?.some((parameters) => parameters.length === 0) ?? false;
47903
48046
  }
47904
48047
  function initializerRequiresEvaluation(index, expression, targetClassName, runtimeIdentifiers = /* @__PURE__ */ new Set()) {
47905
48048
  if (expression.kind === "annotated") {
@@ -47925,8 +48068,10 @@ function initializerRequiresEvaluation(index, expression, targetClassName, runti
47925
48068
  function requiredConstructorParameterNames(index, className) {
47926
48069
  if (className === null) return /* @__PURE__ */ new Set();
47927
48070
  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));
48071
+ if (required2 !== void 0) {
48072
+ return new Set(required2.parameters.map((parameter3) => parameter3.name));
48073
+ }
48074
+ return new Set(index.persistedRequiredByClassName.get(className) ?? []);
47930
48075
  }
47931
48076
  function expressionReadsRuntimeIdentifier(expression, runtimeIdentifiers) {
47932
48077
  if (runtimeIdentifiers.size === 0) return false;
@@ -48019,7 +48164,9 @@ var init_declared_constructors2 = __esm({
48019
48164
  init_src();
48020
48165
  EMPTY_DECLARED_CONSTRUCTOR_INDEX = {
48021
48166
  byClassName: /* @__PURE__ */ new Map(),
48022
- requiredByClassName: /* @__PURE__ */ new Map()
48167
+ requiredByClassName: /* @__PURE__ */ new Map(),
48168
+ persistedByClassName: /* @__PURE__ */ new Map(),
48169
+ persistedRequiredByClassName: /* @__PURE__ */ new Map()
48023
48170
  };
48024
48171
  }
48025
48172
  });
@@ -50961,7 +51108,14 @@ function classToLanguageType(schemaClass2, context) {
50961
51108
  type: {
50962
51109
  kind: "typeParameter",
50963
51110
  id: parameter3.id,
50964
- name: parameter3.name
51111
+ name: parameter3.name,
51112
+ ownerClassId: schemaClass2.id,
51113
+ ...parameter3.constraint === void 0 || parameter3.constraint === null ? {} : {
51114
+ constraint: namedType(
51115
+ parameter3.constraint.kind === "class" ? parameter3.constraint.classId : parameter3.constraint.enumId,
51116
+ true
51117
+ )
51118
+ }
50965
51119
  },
50966
51120
  location: virtualIdentifierLocation(
50967
51121
  context,
@@ -51788,10 +51942,20 @@ function toLanguageType(type, context, genericEnvironment) {
51788
51942
  const name = owner?.genericParams?.find(
51789
51943
  (parameter3) => parameter3.id === effectiveParamId
51790
51944
  )?.name ?? effectiveParamId;
51945
+ const declaration = owner?.genericParams?.find(
51946
+ (parameter3) => parameter3.id === effectiveParamId
51947
+ );
51791
51948
  return {
51792
51949
  kind: "typeParameter",
51793
51950
  id: effectiveParamId,
51794
51951
  name,
51952
+ ...owner === void 0 ? {} : { ownerClassId: owner.id },
51953
+ ...declaration?.constraint === void 0 || declaration.constraint === null ? {} : {
51954
+ constraint: namedType(
51955
+ declaration.constraint.kind === "class" ? declaration.constraint.classId : declaration.constraint.enumId,
51956
+ true
51957
+ )
51958
+ },
51795
51959
  nullable: !required2
51796
51960
  };
51797
51961
  }
@@ -52432,7 +52596,7 @@ function compileMemberInitializerBody(args) {
52432
52596
  );
52433
52597
  }
52434
52598
  const members = replaceMember(args.members, args.member);
52435
- const returnTypeInfo = resolveMemberDeclaredTypeInfo(args.member, members);
52599
+ const returnTypeInfo = resolveMemberDeclaredTypeInfo(args.member, members) ?? initializerGenericTypeInfo(args.member, args.thisClass);
52436
52600
  if (returnTypeInfo === null) {
52437
52601
  throw new Error(
52438
52602
  `Member "${args.member.name}" has an initializer but no resolvable declared type.`
@@ -52469,6 +52633,19 @@ function compileMemberInitializerBody(args) {
52469
52633
  }
52470
52634
  Object.assign(defaultValue.init, { compiled });
52471
52635
  }
52636
+ function initializerGenericTypeInfo(member, ownerClass) {
52637
+ if (!isMemberGenericBase(member) || ownerClass === null) return null;
52638
+ const declaration = ownerClass.genericParams?.find(
52639
+ (parameter3) => parameter3.id === member.genericParamId
52640
+ );
52641
+ if (declaration === void 0) return null;
52642
+ return {
52643
+ type: 21 /* Generic */,
52644
+ required: member.required,
52645
+ ownerClassId: ownerClass.id,
52646
+ genericParamId: declaration.id
52647
+ };
52648
+ }
52472
52649
  function compileValueRowInitializerBody(args) {
52473
52650
  const container = args.valueRow;
52474
52651
  if (!isInitValueContent(container)) return;
@@ -52644,6 +52821,11 @@ function compileConstructorBaseArguments(args, owner) {
52644
52821
  `Constructor "${args.constructor.id}" binds base argument "${baseArgument.name}", which base constructor "${baseConstructor.id}" does not declare.`
52645
52822
  );
52646
52823
  }
52824
+ const returnTypeInfo = substituteConstructorBaseType(
52825
+ parameter3,
52826
+ owner,
52827
+ args
52828
+ );
52647
52829
  return compileUnit2(
52648
52830
  "getter",
52649
52831
  () => compileNSInitializer(baseArgument.code, {
@@ -52655,7 +52837,7 @@ function compileConstructorBaseArguments(args, owner) {
52655
52837
  interfaces: [...args.interfaces ?? []],
52656
52838
  constructors: args.constructors,
52657
52839
  ...args.compilationProject === void 0 ? {} : { compilationProject: args.compilationProject },
52658
- returnTypeInfo: parameter3,
52840
+ returnTypeInfo,
52659
52841
  argumentTypes,
52660
52842
  initializerName: `${owner.name} base argument ${baseArgument.name}`
52661
52843
  })
@@ -52664,6 +52846,65 @@ function compileConstructorBaseArguments(args, owner) {
52664
52846
  );
52665
52847
  Object.assign(args.constructor, { compiledBaseArguments });
52666
52848
  }
52849
+ function substituteConstructorBaseType(typeInfo, owner, args) {
52850
+ if (typeInfo.type === 21 /* Generic */) {
52851
+ const binding = resolveGenericEnv(owner.id, args.classes).get(
52852
+ typeInfo.genericParamId
52853
+ );
52854
+ if (binding === void 0) return typeInfo;
52855
+ if (binding.kind === "unbound") {
52856
+ return {
52857
+ ...typeInfo,
52858
+ ownerClassId: owner.id,
52859
+ genericParamId: binding.paramId
52860
+ };
52861
+ }
52862
+ const member = args.members.find(
52863
+ (candidate) => candidate.id === binding.memberId
52864
+ );
52865
+ if (member === void 0) {
52866
+ throw new Error(
52867
+ `Constructor "${args.constructor.id}" resolves generic parameter "${typeInfo.genericParamId}" to missing member "${binding.memberId}".`
52868
+ );
52869
+ }
52870
+ return resolveMemberDeclaredTypeInfo(member, args.members) ?? typeInfo;
52871
+ }
52872
+ if (typeInfo.type === 25 /* NSDelegate */) {
52873
+ return {
52874
+ ...typeInfo,
52875
+ returnTypeInfo: substituteConstructorBaseType(
52876
+ typeInfo.returnTypeInfo,
52877
+ owner,
52878
+ args
52879
+ ),
52880
+ argumentTypes: typeInfo.argumentTypes.map(
52881
+ (argument2) => substituteConstructorBaseType(argument2, owner, args)
52882
+ )
52883
+ };
52884
+ }
52885
+ if (typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
52886
+ return {
52887
+ ...typeInfo,
52888
+ entryTypeInfo: substituteConstructorBaseType(
52889
+ typeInfo.entryTypeInfo,
52890
+ owner,
52891
+ args
52892
+ )
52893
+ };
52894
+ }
52895
+ if (typeInfo.type !== 7 /* Class */ || typeInfo.typeArguments === void 0) {
52896
+ return typeInfo;
52897
+ }
52898
+ return {
52899
+ ...typeInfo,
52900
+ typeArguments: Object.fromEntries(
52901
+ Object.entries(typeInfo.typeArguments).map(([parameterId, argument2]) => [
52902
+ parameterId,
52903
+ substituteConstructorBaseType(argument2, owner, args)
52904
+ ])
52905
+ )
52906
+ };
52907
+ }
52667
52908
  function compileConstructorBaseInitializerFields(args, owner) {
52668
52909
  const fields = args.constructor.baseInitializerFields ?? [];
52669
52910
  if (fields.length === 0) {
@@ -52983,6 +53224,7 @@ var init_compile_ns_property = __esm({
52983
53224
  "use strict";
52984
53225
  init_members();
52985
53226
  init_inheritance();
53227
+ init_generics();
52986
53228
  init_neoscript();
52987
53229
  init_core();
52988
53230
  init_lookup_declared_type();
@@ -53196,6 +53438,19 @@ var init_value_row_owner_members = __esm({
53196
53438
  });
53197
53439
 
53198
53440
  // ../src/database/constructor-argument-ownership.ts
53441
+ function constructorActionParameterId(constructor2, index) {
53442
+ const action = constructor2.action;
53443
+ if (action !== null && typeof action === "object") {
53444
+ const parameters = action.parameters;
53445
+ if (Array.isArray(parameters)) {
53446
+ const parameter3 = parameters[index + 2];
53447
+ if (parameter3 !== null && typeof parameter3 === "object" && typeof parameter3.id === "string") {
53448
+ return parameter3.id;
53449
+ }
53450
+ }
53451
+ }
53452
+ return `__arg_${index}__`;
53453
+ }
53199
53454
  function createTypedValueNormalizer(rows, document, childrenByContainerId, parameterTypesForRow, memberById, memberTypeInfo) {
53200
53455
  const visiting = /* @__PURE__ */ new Set();
53201
53456
  const normalizeLiteral = (value) => {
@@ -53550,7 +53805,7 @@ var init_constructor_argument_ownership = __esm({
53550
53805
  }
53551
53806
  const env = rowGenericEnvironment(this.document, root);
53552
53807
  for (let index = 0; index < constructor2.argumentTypes.length; index += 1) {
53553
- const parameterId = constructor2.action.parameters[index + 2]?.id;
53808
+ const parameterId = constructorActionParameterId(constructor2, index);
53554
53809
  const rawTypeInfo = constructor2.argumentTypes[index];
53555
53810
  if (parameterId === void 0 || rawTypeInfo === void 0) continue;
53556
53811
  const typeInfo = this.resolveTypeInfo(rawTypeInfo, env);
@@ -57590,6 +57845,8 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
57590
57845
  return isDecimalString(value);
57591
57846
  case 3 /* String */:
57592
57847
  return typeof value === "string";
57848
+ case 25 /* NSDelegate */:
57849
+ return isNSDelegateClosureValue(value) || isMemberDelegateTarget(value);
57593
57850
  case 11 /* Sprite */:
57594
57851
  return isRuntimeSpriteValue(value);
57595
57852
  case 12 /* Audio */:
@@ -59079,7 +59336,15 @@ function constructClassValueWithinFrame(descriptor, scope, ctx) {
59079
59336
  // A class with no declared constructors can still carry init-backed
59080
59337
  // member defaults (P43 §2, `string Foo = StaticFunc("bar")`), so the
59081
59338
  // schema-derived path evaluates them exactly as the declared one does.
59082
- initEvaluator: constructionInitEvaluator(ctx, createdValues),
59339
+ initEvaluator: constructionInitEvaluator(
59340
+ ctx,
59341
+ createdValues,
59342
+ {
59343
+ valuesByClassId: /* @__PURE__ */ new Map(),
59344
+ missingScopeReason: "no-constructor"
59345
+ },
59346
+ classId
59347
+ ),
59083
59348
  constructorRoot: {
59084
59349
  providedSchemaKeys: new Set(
59085
59350
  supplied.filter((entry) => entry.value !== null).map((entry) => entry.validated.schemaKey)
@@ -59330,15 +59595,17 @@ function runDeclaredConstructorChain(args) {
59330
59595
  args.visitedConstructorIds.add(record3.id);
59331
59596
  const baseRecord = resolveBaseConstructorRecord(record3, ctx);
59332
59597
  if (baseRecord !== null) {
59598
+ const preparedBaseArguments = args.preparedArgumentScopes.valuesByClassId.get(baseRecord.classId);
59333
59599
  runDeclaredConstructorChain({
59334
59600
  record: baseRecord,
59335
- argumentValues: evaluateBaseConstructorArguments(
59601
+ argumentValues: preparedBaseArguments ?? evaluateBaseConstructorArguments(
59336
59602
  record3,
59337
59603
  baseRecord,
59338
59604
  args.argumentValues,
59339
59605
  args.thisValue,
59340
59606
  ctx
59341
59607
  ),
59608
+ preparedArgumentScopes: args.preparedArgumentScopes,
59342
59609
  thisValue: args.thisValue,
59343
59610
  ctx,
59344
59611
  visitedConstructorIds: args.visitedConstructorIds,
@@ -59443,13 +59710,165 @@ function evaluateBaseInitializerFields(args) {
59443
59710
  return { validated, value };
59444
59711
  });
59445
59712
  }
59446
- function constructionInitEvaluator(ctx, createdValues, argumentValues = []) {
59447
- return (member, init) => evaluateInitializerInContext(
59448
- init,
59449
- member,
59450
- ctx,
59451
- createdValues,
59452
- argumentValues
59713
+ function constructionInitEvaluator(ctx, createdValues, argumentScopes, constructedClassId) {
59714
+ const indexes = constructorInitializerIndexes(ctx);
59715
+ const inheritanceChain = resolveInheritanceChain(
59716
+ constructedClassId,
59717
+ ctx.vm.classes
59718
+ );
59719
+ const owningClassId = (memberId) => {
59720
+ const visited = /* @__PURE__ */ new Set();
59721
+ let currentId = memberId;
59722
+ while (currentId !== void 0 && !visited.has(currentId)) {
59723
+ visited.add(currentId);
59724
+ const declaringClassIds = indexes.declaringClassIdsByMemberId.get(currentId);
59725
+ const owner = inheritanceChain.find(
59726
+ (schemaClass2) => declaringClassIds?.has(schemaClass2.id)
59727
+ );
59728
+ if (owner !== void 0) return owner.id;
59729
+ currentId = indexes.containerMemberIdByEntryId.get(currentId) ?? indexes.memberById.get(currentId)?.extendsMemberId;
59730
+ }
59731
+ return null;
59732
+ };
59733
+ return (member, init) => {
59734
+ if (init.compiled === void 0) {
59735
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59736
+ }
59737
+ const memberId = Reflect.get(member, "id");
59738
+ const scopeMemberId = indexes.initializerScopeMemberIds.get(init) ?? (typeof memberId === "string" ? memberId : "");
59739
+ const ownerClassId = owningClassId(scopeMemberId);
59740
+ const expectedArgumentCount = init.compiled?.parameters.slice(2).length;
59741
+ if (ownerClassId === null) {
59742
+ if (expectedArgumentCount !== void 0 && expectedArgumentCount > 0) {
59743
+ throw new NSGetterRuntimeError(
59744
+ `Member initializer '${member.name}' has ${expectedArgumentCount} constructor parameter(s), but its declaring class scope could not be resolved.`
59745
+ );
59746
+ }
59747
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59748
+ }
59749
+ const scopedArguments = argumentScopes.valuesByClassId.get(ownerClassId);
59750
+ if (scopedArguments === void 0) {
59751
+ if (expectedArgumentCount === 0) {
59752
+ return evaluateInitializerInContext(init, member, ctx, createdValues);
59753
+ }
59754
+ if (argumentScopes.missingScopeReason === "no-constructor") {
59755
+ throw new NSGetterRuntimeError(
59756
+ `Member initializer '${member.name}' on '${ownerClassId}' cannot read constructor parameters because schema-derived construction invoked no constructor.`
59757
+ );
59758
+ }
59759
+ throw new NSGetterRuntimeError(
59760
+ `Member initializer '${member.name}' on '${ownerClassId}' cannot read constructor parameters because its ': base(...)' arguments depend on initialized 'this'.`
59761
+ );
59762
+ }
59763
+ if (expectedArgumentCount !== void 0 && expectedArgumentCount !== scopedArguments.length) {
59764
+ throw new NSGetterRuntimeError(
59765
+ `Member initializer '${member.name}' on '${ownerClassId}' expected ${expectedArgumentCount} constructor argument(s), got ${scopedArguments.length}.`
59766
+ );
59767
+ }
59768
+ return evaluateInitializerInContext(
59769
+ init,
59770
+ member,
59771
+ ctx,
59772
+ createdValues,
59773
+ scopedArguments
59774
+ );
59775
+ };
59776
+ }
59777
+ function constructorInitializerIndexes(ctx) {
59778
+ if (ctx.__constructorInitializerIndexes !== void 0) {
59779
+ return ctx.__constructorInitializerIndexes;
59780
+ }
59781
+ const initializerScopeMemberIds = /* @__PURE__ */ new WeakMap();
59782
+ const initializerByValueId = /* @__PURE__ */ new Map();
59783
+ for (const row of ctx.vm.values) {
59784
+ const initializer = Reflect.get(row, "init");
59785
+ if (initializer !== void 0)
59786
+ initializerByValueId.set(row.id, initializer);
59787
+ }
59788
+ for (const member of ctx.vm.members) {
59789
+ const defaultValue = member.defaultValue;
59790
+ if (isInitValueContent(defaultValue)) {
59791
+ initializerScopeMemberIds.set(defaultValue.init, member.id);
59792
+ continue;
59793
+ }
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
+ }
59803
+ }
59804
+ }
59805
+ const declaringClassIdsByMemberId = /* @__PURE__ */ new Map();
59806
+ for (const schemaClass2 of ctx.vm.classes) {
59807
+ for (const memberId of Object.values(schemaClass2.schema)) {
59808
+ const owners = declaringClassIdsByMemberId.get(memberId) ?? /* @__PURE__ */ new Set();
59809
+ owners.add(schemaClass2.id);
59810
+ declaringClassIdsByMemberId.set(memberId, owners);
59811
+ }
59812
+ }
59813
+ const memberById = new Map(
59814
+ ctx.vm.members.map((member) => [member.id, member])
59815
+ );
59816
+ const containerMemberIdByEntryId = /* @__PURE__ */ new Map();
59817
+ for (const member of ctx.vm.members) {
59818
+ if (isMemberList(member) || isMemberDictionary(member)) {
59819
+ containerMemberIdByEntryId.set(member.entryMemberId, member.id);
59820
+ }
59821
+ }
59822
+ const built = {
59823
+ initializerScopeMemberIds,
59824
+ declaringClassIdsByMemberId,
59825
+ memberById,
59826
+ containerMemberIdByEntryId
59827
+ };
59828
+ ctx.__constructorInitializerIndexes = built;
59829
+ return built;
59830
+ }
59831
+ function prepareConstructorArgumentScopes(record3, argumentValues, ctx) {
59832
+ const values = /* @__PURE__ */ new Map();
59833
+ let current = record3;
59834
+ let currentValues = argumentValues;
59835
+ while (current !== null) {
59836
+ values.set(current.classId, currentValues);
59837
+ const base = resolveBaseConstructorRecord(current, ctx);
59838
+ if (base === null) break;
59839
+ if (baseArgumentGettersReferenceThis(current)) break;
59840
+ currentValues = evaluateBaseConstructorArguments(
59841
+ current,
59842
+ base,
59843
+ currentValues,
59844
+ null,
59845
+ ctx
59846
+ );
59847
+ current = base;
59848
+ }
59849
+ return {
59850
+ valuesByClassId: values,
59851
+ missingScopeReason: record3 === null ? "no-constructor" : "base-arguments-depend-on-this"
59852
+ };
59853
+ }
59854
+ function baseArgumentGettersReferenceThis(record3) {
59855
+ return (record3.compiledBaseArguments ?? []).some((getter) => {
59856
+ const thisParameter = getter.parameters[0];
59857
+ return thisParameter !== void 0 && runtimeValueReferencesVariable(getter.instructions, thisParameter.id);
59858
+ });
59859
+ }
59860
+ function runtimeValueReferencesVariable(value, variableId, visited = /* @__PURE__ */ new WeakSet()) {
59861
+ if (typeof value !== "object" || value === null) return false;
59862
+ if (visited.has(value)) return false;
59863
+ visited.add(value);
59864
+ if (Reflect.get(value, "type") === "variable" /* variable */ && Reflect.get(value, "variableId") === variableId) {
59865
+ return true;
59866
+ }
59867
+ const children = Object.values(Object.getOwnPropertyDescriptors(value)).filter(
59868
+ (descriptor) => "value" in descriptor
59869
+ ).map((descriptor) => descriptor.value);
59870
+ return children.some(
59871
+ (child) => runtimeValueReferencesVariable(child, variableId, visited)
59453
59872
  );
59454
59873
  }
59455
59874
  function evaluateInitializerInContext(init, member, ctx, createdValues, argumentValues = []) {
@@ -59636,6 +60055,11 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59636
60055
  const schemaClass2 = descriptor.schemaClass;
59637
60056
  const classId = schemaClass2.id;
59638
60057
  const argumentValues = record3 === null ? [] : evaluateDeclaredConstructorArguments(info, record3, scope, ctx);
60058
+ const preparedArgumentScopes = prepareConstructorArgumentScopes(
60059
+ record3,
60060
+ argumentValues,
60061
+ ctx
60062
+ );
59639
60063
  const createdValues = [];
59640
60064
  const storageKeyDeclarations = /* @__PURE__ */ new Map();
59641
60065
  let root;
@@ -59660,7 +60084,8 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59660
60084
  initEvaluator: constructionInitEvaluator(
59661
60085
  ctx,
59662
60086
  createdValues,
59663
- argumentValues
60087
+ preparedArgumentScopes,
60088
+ classId
59664
60089
  ),
59665
60090
  constructorRoot: {
59666
60091
  providedSchemaKeys: new Set(
@@ -59721,6 +60146,7 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
59721
60146
  runDeclaredConstructorChain({
59722
60147
  record: record3,
59723
60148
  argumentValues,
60149
+ preparedArgumentScopes,
59724
60150
  thisValue: root.value,
59725
60151
  ctx,
59726
60152
  visitedConstructorIds: /* @__PURE__ */ new Set(),
@@ -60906,6 +61332,7 @@ function evaluateMemberInitializer(args) {
60906
61332
  constructors: args.document.constructors,
60907
61333
  interfaces: args.document.interfaces,
60908
61334
  localizedTexts: args.document.localizedTexts,
61335
+ localizationConfig: args.document.localizationConfig,
60909
61336
  databaseVM: initializerEvaluatorLookups(args.document)
60910
61337
  },
60911
61338
  thisValue: null,
@@ -61070,6 +61497,14 @@ function isNeoClassConstructorBase(value) {
61070
61497
  }
61071
61498
  return v.compiledBaseInitializerFields === void 0 || v.compiledBaseInitializerFields === null;
61072
61499
  }
61500
+ function isUncompiledNeoClassConstructor(value) {
61501
+ if (!isNeoClassConstructorBase(value)) return false;
61502
+ const v = value;
61503
+ if (typeof v.id !== "string" || v.id.length === 0) return false;
61504
+ if (typeof v.projectId !== "string" || v.projectId.length === 0) return false;
61505
+ if (!isEpochMillis(v.createdAt)) return false;
61506
+ return isEpochMillis(v.updatedAt);
61507
+ }
61073
61508
  function hasValidConstructorAction(action, argumentTypes) {
61074
61509
  if (!isNSFunctionWithReturnType(action)) return false;
61075
61510
  if (action.typeInfo.type !== 0 /* Null */) return false;
@@ -62461,7 +62896,7 @@ function readProjectDocument(value, options = {}) {
62461
62896
  constructors: readOptionalArrayField(
62462
62897
  value,
62463
62898
  "constructors",
62464
- isNeoClassConstructor
62899
+ options.constructors === "authored-or-compiled" ? (candidate) => isNeoClassConstructor(candidate) || isUncompiledNeoClassConstructor(candidate) : isNeoClassConstructor
62465
62900
  ),
62466
62901
  internalRecordRelations: readOptionalArrayField(
62467
62902
  value,
@@ -68291,6 +68726,7 @@ function collectNeoScriptRecompileTargets(args) {
68291
68726
  if (args.forceRecompile === true) return completeTargets(args.postDocument);
68292
68727
  const explicit = explicitTargetIds(args.changes);
68293
68728
  const { impactedIds, impactedTypeNames, constructedClassIds } = collectChangedContractIds(args);
68729
+ for (const id2 of args.additionalImpactedIds ?? []) impactedIds.add(id2);
68294
68730
  includeDerivedConstructionContracts(
68295
68731
  constructedClassIds,
68296
68732
  args.postDocument.classes
@@ -69349,9 +69785,17 @@ function materializeInitializersLocallyV4(args) {
69349
69785
  );
69350
69786
  if (sourceRoots.size === 0) return { roots: [] };
69351
69787
  let document = readPulledProjectDocumentV4(records2);
69352
- const rootOwners = resolveOwnerMembersForValues(document, sourceRoots);
69788
+ const rootKinds = /* @__PURE__ */ new Map();
69789
+ const rootOwners = resolveOwnerMembersForValues(
69790
+ document,
69791
+ sourceRoots,
69792
+ void 0,
69793
+ void 0,
69794
+ rootKinds
69795
+ );
69353
69796
  const roots = [];
69354
69797
  for (const sourceValueId of sourceRoots) {
69798
+ if (rootKinds.get(sourceValueId) === "declaration") continue;
69355
69799
  const rootOwner = rootOwners.get(sourceValueId);
69356
69800
  if (rootOwner === void 0) {
69357
69801
  throw new Error(
@@ -70399,18 +70843,26 @@ function replayAnimationDeclarationInitializersV4(records2, document) {
70399
70843
  const rootOwner = rootOwners.get(row.id);
70400
70844
  const rootOwnerId = Reflect.get(rootOwner ?? {}, "id");
70401
70845
  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
- });
70846
+ let replay;
70847
+ try {
70848
+ replay = replayStoredConstructionV4({
70849
+ records: pulled,
70850
+ valueId: row.id,
70851
+ code,
70852
+ member: owner,
70853
+ compileDocumentBodies: true,
70854
+ initializerOwnerClass,
70855
+ // A parameterized declaration is a template. Its arguments exist only
70856
+ // at concrete construction sites, so validate the authored body here
70857
+ // without fabricating values for the class header parameters.
70858
+ evaluate: initializerOwnerClass?.requiredConstructorId === void 0 || initializerOwnerClass.requiredConstructorId === null
70859
+ });
70860
+ } catch (error) {
70861
+ throw new Error(
70862
+ `Animation declaration replay failed for value "${row.id}": ${error instanceof Error ? error.message : String(error)}`,
70863
+ { cause: error }
70864
+ );
70865
+ }
70414
70866
  for (const [id2, value] of replay) {
70415
70867
  if (!isMemberValue(value)) {
70416
70868
  throw new Error(
@@ -74089,7 +74541,8 @@ function prepareServerOwnedSchemaCommit(args) {
74089
74541
  const hasValueChange = authoredChanges.some(
74090
74542
  (change) => change.recordKind === "value"
74091
74543
  );
74092
- if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange) {
74544
+ const hasAdditionalContractImpact = (args.additionalImpactedIds?.size ?? 0) > 0;
74545
+ if (!hasSchemaChange && !hasMigrationChange && !hasDialogueSourceChange && !hasValueChange && !hasAdditionalContractImpact) {
74093
74546
  return authoredChanges;
74094
74547
  }
74095
74548
  const authoredPostDocument = applyProjectVersionWriteChanges(
@@ -74100,6 +74553,7 @@ function prepareServerOwnedSchemaCommit(args) {
74100
74553
  currentDocument: args.document,
74101
74554
  postDocument: authoredPostDocument,
74102
74555
  changes: authoredChanges,
74556
+ additionalImpactedIds: args.additionalImpactedIds,
74103
74557
  forceRecompile: args.forceRecompile
74104
74558
  });
74105
74559
  const explicitlyChangedMemberIds = new Set(
@@ -77493,6 +77947,19 @@ function isOpaqueNSTypeInfo(value, ancestors = /* @__PURE__ */ new Set()) {
77493
77947
  if (value.type === 22) {
77494
77948
  return typeof value.interfaceId === "string" && value.interfaceId.length > 0;
77495
77949
  }
77950
+ if (value.type === 25) {
77951
+ if (!Array.isArray(value.argumentTypes) || ancestors.has(value)) {
77952
+ return false;
77953
+ }
77954
+ ancestors.add(value);
77955
+ try {
77956
+ return isOpaqueNSFunctionReturnTypeInfo(value.returnTypeInfo) && value.argumentTypes.every(
77957
+ (argument2) => isOpaqueNSTypeInfo(argument2, ancestors)
77958
+ );
77959
+ } finally {
77960
+ ancestors.delete(value);
77961
+ }
77962
+ }
77496
77963
  if (value.type === 5 || value.type === 6) {
77497
77964
  if (ancestors.has(value)) return false;
77498
77965
  ancestors.add(value);
@@ -77522,6 +77989,11 @@ function opaqueTypeInfoContainsUnknown(value) {
77522
77989
  if (value.type === 5 || value.type === 6 || value.type === 9) {
77523
77990
  return isRecord8(value.entryTypeInfo) && opaqueTypeInfoContainsUnknown(value.entryTypeInfo);
77524
77991
  }
77992
+ if (value.type === 25) {
77993
+ return isRecord8(value.returnTypeInfo) && opaqueTypeInfoContainsUnknown(value.returnTypeInfo) || Array.isArray(value.argumentTypes) && value.argumentTypes.some(
77994
+ (argument2) => isRecord8(argument2) && opaqueTypeInfoContainsUnknown(argument2)
77995
+ );
77996
+ }
77525
77997
  if (value.type !== 7 || !isRecord8(value.typeArguments)) return false;
77526
77998
  return Object.values(value.typeArguments).some(
77527
77999
  (argument2) => isRecord8(argument2) && opaqueTypeInfoContainsUnknown(argument2)
@@ -77536,6 +78008,10 @@ function isOpaqueNSFunctionReturnTypeInfo(value) {
77536
78008
  function isOpaqueNSFunctionArgumentTypeInfo(value) {
77537
78009
  return isOpaqueNSTypeInfo(value) && isOpaqueCallableIdentifier(value.name) && !opaqueTypeInfoContainsUnknown(value);
77538
78010
  }
78011
+ function isOpaqueConstructorArgumentTypeInfo(value) {
78012
+ if (!isRecord8(value)) return false;
78013
+ return isOpaqueNSTypeInfo(value) && (value.name === "value" || isOpaqueCallableIdentifier(value.name)) && !opaqueTypeInfoContainsUnknown(value);
78014
+ }
77539
78015
  function memberSignature(member) {
77540
78016
  if (member.kind === "property") {
77541
78017
  return `property:${member.settable === true}:${stableTypeInfo(member.typeInfo)}`;
@@ -78887,7 +79363,7 @@ function assertOpaqueConstructorValid(declaredConstructor) {
78887
79363
  );
78888
79364
  }
78889
79365
  const argumentTypes = declaredConstructor.argumentTypes;
78890
- if (!argumentTypes.every(isOpaqueNSFunctionArgumentTypeInfo)) {
79366
+ if (!argumentTypes.every(isOpaqueConstructorArgumentTypeInfo)) {
78891
79367
  throw new Error(
78892
79368
  `Constructor "${declaredConstructor.id}" argumentTypes are invalid.`
78893
79369
  );
@@ -80665,6 +81141,7 @@ function replayStoredConstructionV4(args) {
80665
81141
  );
80666
81142
  }
80667
81143
  if (args.evaluate === false) return /* @__PURE__ */ new Map();
81144
+ assertPulledConstructorsCompiled(document);
80668
81145
  const compiledDependencies = /* @__PURE__ */ new Set();
80669
81146
  let materialized;
80670
81147
  for (; ; ) {
@@ -80705,6 +81182,7 @@ function compilePulledProjectDocumentBodiesV4(document) {
80705
81182
  for (const constructor2 of compileArgs.constructors) {
80706
81183
  compileConstructorRecord({ ...compileArgs, constructor: constructor2 });
80707
81184
  }
81185
+ assertPulledConstructorsCompiled(document);
80708
81186
  const ownerClassByMemberId = new Map(
80709
81187
  compileArgs.classes.flatMap(
80710
81188
  (schemaClass2) => Object.values(schemaClass2.schema).map(
@@ -80720,6 +81198,16 @@ function compilePulledProjectDocumentBodiesV4(document) {
80720
81198
  });
80721
81199
  }
80722
81200
  }
81201
+ function assertPulledConstructorsCompiled(document) {
81202
+ const uncompiled = (document.constructors ?? []).find(
81203
+ (constructor2) => !isNeoClassConstructor(constructor2)
81204
+ );
81205
+ if (uncompiled !== void 0) {
81206
+ throw new Error(
81207
+ `Constructor "${uncompiled.id}" was read from authored source but was not compiled before evaluation.`
81208
+ );
81209
+ }
81210
+ }
80723
81211
  function compilePulledMemberInitializerBodyV4(document, memberId) {
80724
81212
  const compileArgs = {
80725
81213
  project: document.project,
@@ -80747,7 +81235,8 @@ function compilePulledMemberInitializerBodyV4(document, memberId) {
80747
81235
  }
80748
81236
  function readPulledProjectDocumentV4(records2) {
80749
81237
  return readProjectDocument(
80750
- pulledProjectDocumentRaw(replayWorkspace(records2))
81238
+ pulledProjectDocumentRaw(replayWorkspace(records2)),
81239
+ { constructors: "authored-or-compiled" }
80751
81240
  );
80752
81241
  }
80753
81242
  function replayWorkspace(records2) {
@@ -80787,6 +81276,7 @@ var init_initializer_replay = __esm({
80787
81276
  init_project_document_read();
80788
81277
  init_server_preparation_preflight();
80789
81278
  init_projection();
81279
+ init_constructors2();
80790
81280
  init_neoscript_evaluator();
80791
81281
  }
80792
81282
  });
@@ -81154,7 +81644,12 @@ function buildValueLowerContext(state, manifest, options = {}) {
81154
81644
  const classesByName = new Map(
81155
81645
  manifest.classes.map((entry) => [entry.name, entry])
81156
81646
  );
81157
- const declaredConstructorIndex = options.analysis === void 0 ? EMPTY_DECLARED_CONSTRUCTOR_INDEX : buildDeclaredConstructorIndex(options.analysis);
81647
+ const sourceConstructorIndex = options.analysis === void 0 ? EMPTY_DECLARED_CONSTRUCTOR_INDEX : buildDeclaredConstructorIndex(options.analysis);
81648
+ const declaredConstructorIndex = withPersistedConstructorSignatures(
81649
+ sourceConstructorIndex,
81650
+ manifest.classes,
81651
+ manifest.constructors
81652
+ );
81158
81653
  return {
81159
81654
  state,
81160
81655
  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.3",
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.3 -->
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.3 -->
82
82
  ```
83
83
 
84
84
  The quoted version above is checked too, so this instruction cannot go stale