@neocompose/cli 0.89.8 → 0.89.10

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.
@@ -25397,6 +25397,7 @@ function indexRuntimeCollectionChange(collection, entry, ctx, removedEntries = n
25397
25397
  indexes4.memberByRowId.clear();
25398
25398
  }
25399
25399
  if (Array.isArray(collection)) forgetLocalListIndexes(ctx, collection);
25400
+ else indexes4.declaredListByArray = /* @__PURE__ */ new WeakMap();
25400
25401
  markOverlayMutated(ctx, collection);
25401
25402
  if (ctx.__valueOverlay instanceof LazyValueOverlay)
25402
25403
  indexes4.overlayRevision = ctx.__valueOverlay.revision;
@@ -29012,6 +29013,7 @@ function replaceRowValue(row, value, receiver, ctx) {
29012
29013
  unindexEvaluatorRow(indexes4, row, true);
29013
29014
  row.value = value;
29014
29015
  indexEvaluatorRow(indexes4, row, true);
29016
+ indexes4.declaredListByArray = /* @__PURE__ */ new WeakMap();
29015
29017
  markOverlayMutated(ctx, receiver);
29016
29018
  if (ctx.__valueOverlay instanceof LazyValueOverlay)
29017
29019
  indexes4.overlayRevision = ctx.__valueOverlay.revision;
@@ -33268,6 +33270,17 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
33268
33270
  case 8 /* Enum */:
33269
33271
  return Array.isArray(value) && value.every((v) => typeof v === "string");
33270
33272
  case 7 /* Class */: {
33273
+ if (isVariantClassId(checkType.classId)) {
33274
+ if (!isVariantRefValue(value)) return false;
33275
+ const targetParameter = evaluatorSchemaIndex(ctx).classesById.get(
33276
+ checkType.classId
33277
+ )?.genericParams?.[0];
33278
+ const target = targetParameter === void 0 ? void 0 : receiverClosedTypeArguments(checkType.typeArguments, ctx)?.[targetParameter.id];
33279
+ return target?.type !== 7 /* Class */ || evaluatorSchemaIndex(ctx).classIsOrExtends(
33280
+ value.classId,
33281
+ target.classId
33282
+ );
33283
+ }
33271
33284
  if (typeof value !== "object") return false;
33272
33285
  const row = trackedRowForValueReference(value, ctx);
33273
33286
  const runtimeClassId = row === null ? void 0 : classIdForValueRow(row, ctx);
@@ -38464,6 +38477,21 @@ function encodeRequiredConstructorArgument(args) {
38464
38477
  `Constructor argument '${args.parameterId}' has an unresolved generic type.`
38465
38478
  );
38466
38479
  }
38480
+ if (args.typeInfo.type === 7 /* Class */ && isVariantClassId(args.typeInfo.classId)) {
38481
+ if (args.value === null || args.value === void 0) return null;
38482
+ const selection = readVariantSelection(
38483
+ args.value,
38484
+ `Constructor argument '${args.parameterId}'`
38485
+ );
38486
+ if (selection.rowValueId !== null) {
38487
+ adoptTracked(selection.rowValueId, "variant-row");
38488
+ }
38489
+ return {
38490
+ classId: selection.classId,
38491
+ variantId: selection.variantId,
38492
+ ...selection.rowValueId === null ? {} : { rowValueId: selection.rowValueId }
38493
+ };
38494
+ }
38467
38495
  if (args.typeInfo.type === 7 /* Class */ || args.typeInfo.type === 22 /* Interface */) {
38468
38496
  if (args.value === null || args.value === void 0) return null;
38469
38497
  const aggregateId2 = trackedId ?? replayedAggregateId;
@@ -38599,6 +38627,16 @@ function readVariantSelection(value, label) {
38599
38627
  }
38600
38628
  return { classId, variantId, rowValueId: rowValueId ?? null };
38601
38629
  }
38630
+ function variantConstructorRecord(row, schemaKeys) {
38631
+ const recipe = isLiteralValueContent(row) ? row.constructorArgs : void 0;
38632
+ const result = {};
38633
+ if (recipe == null) return result;
38634
+ for (let index = 0; index < schemaKeys.length; index++) {
38635
+ const argument2 = recipe[`__arg_${index}__`];
38636
+ if (argument2 !== void 0) result[schemaKeys[index]] = argument2;
38637
+ }
38638
+ return result;
38639
+ }
38602
38640
  function resolveVariantGraph(selection, ctx) {
38603
38641
  const variantId = selection.variantId;
38604
38642
  if (variantId === null) {
@@ -38636,20 +38674,14 @@ function resolveVariantGraph(selection, ctx) {
38636
38674
  );
38637
38675
  }
38638
38676
  const effectiveRoot = { ...root };
38639
- const recipe = row.constructorArgs;
38640
- if (typeof recipe === "object" && recipe !== null) {
38641
- const settledVariantSlots = [
38642
- ["Initialize", 0],
38643
- ["Apply", 1],
38644
- ["Overrides", 2],
38645
- ["ChildOverrides", 3]
38646
- ];
38647
- for (const [schemaKey, argumentIndex] of settledVariantSlots) {
38648
- if (effectiveRoot[schemaKey] !== void 0) continue;
38649
- const argument2 = recipe[`__arg_${argumentIndex}__`];
38650
- if (argument2 === void 0 || argument2 === null) continue;
38651
- effectiveRoot[schemaKey] = argument2;
38652
- }
38677
+ const recipe = variantConstructorRecord(row, [
38678
+ "Initialize",
38679
+ "Apply",
38680
+ "Overrides",
38681
+ "ChildOverrides"
38682
+ ]);
38683
+ for (const [key, value] of Object.entries(recipe)) {
38684
+ if (effectiveRoot[key] === void 0) effectiveRoot[key] = value;
38653
38685
  }
38654
38686
  return {
38655
38687
  variantId,
@@ -38744,7 +38776,7 @@ function invokeVariantClosure(args) {
38744
38776
  [DELEGATE_LEXICAL_THIS]: lexicalThis,
38745
38777
  [DELEGATE_LEXICAL_ROOT]: ctx.rootValue
38746
38778
  };
38747
- return invokeDelegateValue(bound, parameters, ctx);
38779
+ return invokeDelegateValue(bound, parameters, ctx, void 0, lexicalThis);
38748
38780
  }
38749
38781
  function writeVariantOverrideSlot(target, schemaKey, value, ctx, answeredValueIds) {
38750
38782
  assertStoredReplayMutableValue(target, ctx, "variant override", schemaKey);
@@ -38940,6 +38972,32 @@ function replacesInterfaceSlotRow(member, target, overrideRow, ctx) {
38940
38972
  if (targetRow === null) return false;
38941
38973
  return classIdForValueRow(targetRow, ctx) !== overrideRow.classId;
38942
38974
  }
38975
+ function readVariantChildOverrideSlot(entryRow, schemaKey, ctx) {
38976
+ const entry = readRowValue(entryRow, ctx);
38977
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry))
38978
+ return null;
38979
+ const classId = classIdForValueRow(entryRow, ctx);
38980
+ const memberId = classId == null ? null : cachedMergedSchemaMemberId(classId, schemaKey, ctx);
38981
+ const member = memberId === null ? null : evalMemberById(ctx.vm, memberId);
38982
+ if (member === null) {
38983
+ throw new NSGetterRuntimeError(
38984
+ `Child override '${entryRow.id}' has no '${schemaKey}' member.`
38985
+ );
38986
+ }
38987
+ const slot = readClassMember({
38988
+ member,
38989
+ schemaKey,
38990
+ record: entry,
38991
+ expandedRecord: () => variantConstructorRecord(entryRow, ["Selector", "Overrides"]),
38992
+ mode: "runtime"
38993
+ });
38994
+ if (slot.kind === "value") return slot.value;
38995
+ if (slot.kind === "declaration") {
38996
+ const result = readDeclarationDefault(member, ctx);
38997
+ return result.matched ? result.value : null;
38998
+ }
38999
+ return null;
39000
+ }
38943
39001
  function applyVariantDeclarativeHalves(instance, graph, ctx, answeredValueIds) {
38944
39002
  applyVariantPartial(
38945
39003
  instance,
@@ -38978,14 +39036,13 @@ function applyVariantDeclarativeHalves(instance, graph, ctx, answeredValueIds) {
38978
39036
  `Variant '${graph.name}' references missing child-override row '${entryId}'.`
38979
39037
  );
38980
39038
  }
38981
- const entry = entryRow.value;
39039
+ const entry = readRowValue(entryRow, ctx);
38982
39040
  if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
38983
39041
  continue;
38984
39042
  }
38985
- const entryRecord = entry;
38986
39043
  const label = `Variant '${graph.name}' child override '${entryId}'`;
38987
39044
  const child = invokeVariantClosure({
38988
- closureValueId: entryRecord.Selector,
39045
+ closureValueId: readVariantChildOverrideSlot(entryRow, "Selector", ctx),
38989
39046
  ctx,
38990
39047
  label: `${label} Selector`,
38991
39048
  lexicalThis: instance,
@@ -38998,7 +39055,7 @@ function applyVariantDeclarativeHalves(instance, graph, ctx, answeredValueIds) {
38998
39055
  }
38999
39056
  applyVariantPartial(
39000
39057
  child,
39001
- entryRecord.Overrides,
39058
+ readVariantChildOverrideSlot(entryRow, "Overrides", ctx),
39002
39059
  ctx,
39003
39060
  label,
39004
39061
  answeredValueIds
@@ -39120,7 +39177,7 @@ function collectVariantDeclarativeAnsweredSlots(instance, graph, ctx) {
39120
39177
  }
39121
39178
  const label = `Variant '${graph.name}' child override '${entryId}'`;
39122
39179
  const child = invokeVariantClosure({
39123
- closureValueId: Reflect.get(entryRow.value, "Selector"),
39180
+ closureValueId: readVariantChildOverrideSlot(entryRow, "Selector", ctx),
39124
39181
  ctx,
39125
39182
  label: `${label} Selector`,
39126
39183
  lexicalThis: instance,
@@ -39133,7 +39190,7 @@ function collectVariantDeclarativeAnsweredSlots(instance, graph, ctx) {
39133
39190
  }
39134
39191
  collectVariantPartialAnsweredSlots(
39135
39192
  child,
39136
- Reflect.get(entryRow.value, "Overrides"),
39193
+ readVariantChildOverrideSlot(entryRow, "Overrides", ctx),
39137
39194
  ctx,
39138
39195
  label,
39139
39196
  slots
@@ -45504,22 +45561,29 @@ function lookupEntryTypeInfo2(member, collectionTypeInfo) {
45504
45561
  }
45505
45562
 
45506
45563
  // ../packages/neoscript-runtime/src/values/member-declared-type-info.ts
45507
- function resolveMemberDeclaredTypeInfo(member, members2, ownerClass = null, env) {
45564
+ function resolveMemberDeclaredTypeInfo(member, members2, classes, ownerClass = null, env) {
45508
45565
  return resolveMemberDeclaredTypeInfoInternal(
45509
45566
  member,
45510
45567
  members2,
45568
+ classes,
45511
45569
  /* @__PURE__ */ new Set(),
45512
45570
  ownerClass,
45513
45571
  env,
45514
45572
  ownerClass === null ? void 0 : classConstrainedGenerics([ownerClass])
45515
45573
  );
45516
45574
  }
45517
- function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClass, env, isClassConstrained) {
45575
+ function resolveMemberDeclaredTypeInfoInternal(member, members2, classes, seen, ownerClass, env, isClassConstrained) {
45518
45576
  const resolved = env === void 0 ? resolveMember(member, members2) : substituteMember(member, env, members2);
45519
45577
  const memberId = getField(resolved, "id");
45520
45578
  if (typeof memberId === "string" && seen.has(memberId)) return null;
45521
45579
  const nextSeen = typeof memberId === "string" ? /* @__PURE__ */ new Set([...seen, memberId]) : new Set(seen);
45522
45580
  if (isMemberNSPropertyBase(resolved)) return resolved.returnTypeInfo;
45581
+ if (isMemberVariantBase(resolved)) {
45582
+ return variantMemberDeclaredTypeInfo(
45583
+ resolved,
45584
+ neoVariantSystemClass(classes, resolved.valueTypeInfo != null)
45585
+ );
45586
+ }
45523
45587
  if (isClassSlotMember(resolved)) {
45524
45588
  const typeArguments = Object.fromEntries(
45525
45589
  Object.entries(declaredSlotArguments(resolved) ?? {}).flatMap(
@@ -45539,6 +45603,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
45539
45603
  const argumentType2 = resolveMemberDeclaredTypeInfoInternal(
45540
45604
  argumentMember,
45541
45605
  members2,
45606
+ classes,
45542
45607
  nextSeen,
45543
45608
  ownerClass,
45544
45609
  env,
@@ -45609,6 +45674,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
45609
45674
  const typeInfo = resolveMemberDeclaredTypeInfoInternal(
45610
45675
  descriptor,
45611
45676
  members2,
45677
+ classes,
45612
45678
  nextSeen,
45613
45679
  ownerClass,
45614
45680
  env,
@@ -45637,6 +45703,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
45637
45703
  const entryTypeInfo = resolveMemberDeclaredTypeInfoInternal(
45638
45704
  entry,
45639
45705
  members2,
45706
+ classes,
45640
45707
  nextSeen,
45641
45708
  ownerClass,
45642
45709
  env,
@@ -45661,6 +45728,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
45661
45728
  return resolveMemberDeclaredTypeInfoInternal(
45662
45729
  collection,
45663
45730
  members2,
45731
+ classes,
45664
45732
  nextSeen,
45665
45733
  ownerClass,
45666
45734
  env,
@@ -45703,6 +45771,15 @@ function recordEntries(value) {
45703
45771
  if (typeof value !== "object" || value === null) return [];
45704
45772
  return Object.values(value);
45705
45773
  }
45774
+ function isVariantArgument(value, typeInfo) {
45775
+ return typeInfo?.type === 7 /* Class */ && isVariantClassId(typeInfo.classId) && isVariantRefValue(value);
45776
+ }
45777
+ function remapVariantArgument(value, typeInfo, remap) {
45778
+ if (!isVariantArgument(value, typeInfo)) return value;
45779
+ if (typeof value.rowValueId !== "string") return value;
45780
+ const rowValueId = remap(value.rowValueId);
45781
+ return rowValueId === value.rowValueId ? value : { ...value, rowValueId };
45782
+ }
45706
45783
  var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
45707
45784
  /**
45708
45785
  * P79 §7a. Generic in the caller's document view so a pass typed against a
@@ -45939,7 +46016,7 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
45939
46016
  const typeInfo = parameterTypes.get(parameterId);
45940
46017
  return [
45941
46018
  parameterId,
45942
- typeInfo !== void 0 && (isAggregateTypeInfo(typeInfo) || typeInfo.type === 29 /* Reference */) && typeof argument2 === "string" ? rewriteId(argument2) : argument2
46019
+ typeInfo !== void 0 && (isAggregateTypeInfo(typeInfo) || typeInfo.type === 29 /* Reference */) && typeof argument2 === "string" ? rewriteId(argument2) : remapVariantArgument(argument2, typeInfo, rewriteId)
45943
46020
  ];
45944
46021
  }
45945
46022
  )
@@ -45975,15 +46052,18 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
45975
46052
  ids.push(edge.targetValueId);
45976
46053
  return ids;
45977
46054
  }
45978
- /** The targets a row's Reference creation data names (P112 §1.1). */
46055
+ /** Reference targets and bound lookup rows retained by creation data. */
45979
46056
  referenceArgumentIds(row) {
45980
46057
  if (!isLiteralValueContent(row)) return [];
45981
46058
  const args = row.constructorArgs;
45982
46059
  if (args === void 0 || args === null) return [];
45983
46060
  const ids = [];
45984
- for (const parameterId of this.referenceParameterIds(row)) {
46061
+ for (const [parameterId, typeInfo] of this.constructorParameterTypes(row)) {
45985
46062
  const argument2 = args[parameterId];
45986
- if (typeof argument2 === "string") ids.push(argument2);
46063
+ if (typeInfo.type === 29 /* Reference */ && typeof argument2 === "string")
46064
+ ids.push(argument2);
46065
+ else if (isVariantArgument(argument2, typeInfo) && typeof argument2.rowValueId === "string")
46066
+ ids.push(argument2.rowValueId);
45987
46067
  }
45988
46068
  return ids;
45989
46069
  }
@@ -45992,23 +46072,23 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
45992
46072
  const args = row.constructorArgs;
45993
46073
  if (args === void 0 || args === null) return args;
45994
46074
  let remapped;
45995
- for (const parameterId of this.referenceParameterIds(
46075
+ for (const [parameterId, typeInfo] of this.constructorParameterTypes(
45996
46076
  row,
45997
46077
  contextualMember
45998
46078
  )) {
45999
46079
  const argument2 = args[parameterId];
46000
- if (typeof argument2 !== "string") continue;
46001
- const target = remap(argument2);
46080
+ const target = typeInfo.type === 29 /* Reference */ && typeof argument2 === "string" ? remap(argument2) : remapVariantArgument(argument2, typeInfo, remap);
46002
46081
  if (target !== argument2) (remapped ??= { ...args })[parameterId] = target;
46003
46082
  }
46004
46083
  return remapped ?? args;
46005
46084
  }
46006
- *referenceParameterIds(row, contextualMember) {
46007
- for (const [parameterId, typeInfo] of this.constructorParameterTypes(
46008
- row,
46009
- contextualMember
46010
- ))
46011
- if (typeInfo.type === 29 /* Reference */) yield parameterId;
46085
+ *variantArgumentSelections(row) {
46086
+ if (!isLiteralValueContent(row)) return;
46087
+ if (row.constructorArgs == null) return;
46088
+ for (const [parameterId, typeInfo] of this.constructorParameterTypes(row)) {
46089
+ const argument2 = row.constructorArgs[parameterId];
46090
+ if (isVariantArgument(argument2, typeInfo)) yield argument2;
46091
+ }
46012
46092
  }
46013
46093
  slotEntries(row) {
46014
46094
  const value = row.value;
@@ -46109,6 +46189,17 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
46109
46189
  if (member === void 0) return null;
46110
46190
  return this.memberTypeInfo(member, env);
46111
46191
  }
46192
+ if ((rawTypeInfo.type === 7 /* Class */ || rawTypeInfo.type === 22 /* Interface */) && rawTypeInfo.typeArguments !== void 0) {
46193
+ const typeArguments = {};
46194
+ for (const [parameterId, argument2] of Object.entries(
46195
+ rawTypeInfo.typeArguments
46196
+ )) {
46197
+ const resolved = this.resolveTypeInfo(argument2, env);
46198
+ if (resolved === null) return null;
46199
+ typeArguments[parameterId] = resolved;
46200
+ }
46201
+ return { ...rawTypeInfo, typeArguments };
46202
+ }
46112
46203
  if (rawTypeInfo.type === 30 /* Tuple */) {
46113
46204
  const elements = [];
46114
46205
  for (const element of rawTypeInfo.elements) {
@@ -46140,7 +46231,8 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
46140
46231
  const member = substituteMember(rawMember, env, this.document.members);
46141
46232
  const typeInfo = resolveMemberDeclaredTypeInfo(
46142
46233
  member,
46143
- this.document.members
46234
+ this.document.members,
46235
+ this.document.classes
46144
46236
  );
46145
46237
  return typeInfo === null ? null : this.resolveTypeInfo(typeInfo, env);
46146
46238
  } catch {
@@ -46377,7 +46469,11 @@ function tryResolveTypeInfo(document2, rawTypeInfo, env) {
46377
46469
  function tryMemberTypeInfo(document2, rawMember, env) {
46378
46470
  try {
46379
46471
  const member = substituteMember(rawMember, env, document2.members);
46380
- const typeInfo = resolveMemberDeclaredTypeInfo(member, document2.members);
46472
+ const typeInfo = resolveMemberDeclaredTypeInfo(
46473
+ member,
46474
+ document2.members,
46475
+ document2.classes
46476
+ );
46381
46477
  if (typeInfo === null) return null;
46382
46478
  return tryResolveTypeInfo(document2, typeInfo, env);
46383
46479
  } catch {
@@ -58921,11 +59017,97 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
58921
59017
  if (callee.kind !== "member") return null;
58922
59018
  const isInitialize = callee.name === VARIANT_INITIALIZE_NAME;
58923
59019
  const isApply = callee.name === VARIANT_APPLY_NAME;
58924
- if (!isInitialize && !isApply) return null;
59020
+ const isBind = callee.name === "Bind";
59021
+ if (!isInitialize && !isApply && !isBind) return null;
58925
59022
  if (callee.receiver.kind === "ident" && !this.hasValueReceiver(callee.receiver.name, scope) && this.project.typeByName.has(callee.receiver.name)) {
58926
59023
  return null;
58927
59024
  }
58928
59025
  const receiver = receiverValue ? receiverValue() : this.resolveExpression(callee.receiver, scope);
59026
+ if (isBind) {
59027
+ const variantInfo2 = this.variantTypeInfo(receiver.type);
59028
+ if (variantInfo2 === null) return null;
59029
+ if (variantInfo2.valueType === null) {
59030
+ throw new CompileError("Only a lookup variant can bind a row.", pos);
59031
+ }
59032
+ if (callee.optional === true) {
59033
+ throw new CompileError("Bind requires a non-null lookup variant.", pos);
59034
+ }
59035
+ if (receiver.pointer.type !== "variant" /* Variant */) {
59036
+ throw new CompileError(
59037
+ "Bind requires a declared lookup variant path.",
59038
+ pos
59039
+ );
59040
+ }
59041
+ requireArgCount("NeoLookupVariant.Bind", argumentsList2, 1, pos);
59042
+ const row2 = argumentsList2[0];
59043
+ if (row2.kind !== "call") {
59044
+ throw new CompileError(
59045
+ 'Bind requires Reference(id: "value-id").',
59046
+ row2.pos
59047
+ );
59048
+ }
59049
+ if (row2.callee.kind !== "ident" || row2.callee.name !== "Reference") {
59050
+ throw new CompileError(
59051
+ "Bind requires a Reference row argument.",
59052
+ row2.pos
59053
+ );
59054
+ }
59055
+ requireArgCount("Bind Reference", row2.args, 1, row2.pos);
59056
+ if (row2.argumentNames?.[0] !== "id") {
59057
+ throw new CompileError(
59058
+ 'Bind requires Reference(id: "value-id").',
59059
+ row2.pos
59060
+ );
59061
+ }
59062
+ const id = row2.args[0];
59063
+ if (id.kind !== "litString") {
59064
+ throw new CompileError(
59065
+ "Bound row id must be a string literal.",
59066
+ id.pos
59067
+ );
59068
+ }
59069
+ if (id.value.length === 0) {
59070
+ throw new CompileError("Bound row id must not be empty.", id.pos);
59071
+ }
59072
+ if (row2.typeArguments !== void 0) {
59073
+ if (row2.typeArguments.length !== 1) {
59074
+ throw new CompileError(
59075
+ "Reference requires exactly one generic target type.",
59076
+ row2.pos
59077
+ );
59078
+ }
59079
+ this.requireAssignable(
59080
+ this.resolveType(row2.typeArguments[0]),
59081
+ variantInfo2.valueType,
59082
+ row2.pos,
59083
+ "Lookup variant row"
59084
+ );
59085
+ }
59086
+ const rowType = this.context.persistedReferenceTypes?.get(id.value);
59087
+ if (rowType !== void 0) {
59088
+ this.requireAssignable(
59089
+ neoScriptReadType(rowType),
59090
+ variantInfo2.valueType,
59091
+ row2.pos,
59092
+ "Lookup variant row"
59093
+ );
59094
+ }
59095
+ const bound = this.project.typeByName.get(NEO_VARIANT_TYPE_NAME);
59096
+ if (bound === void 0) {
59097
+ throw new CompileError(
59098
+ `The seeded '${NEO_VARIANT_TYPE_NAME}' class is missing.`,
59099
+ pos
59100
+ );
59101
+ }
59102
+ return {
59103
+ pointer: { ...receiver.pointer, rowValueId: id.value },
59104
+ type: {
59105
+ kind: "named",
59106
+ typeId: bound.id,
59107
+ typeArguments: receiver.type.kind === "named" ? receiver.type.typeArguments?.slice(0, 1) ?? [] : []
59108
+ }
59109
+ };
59110
+ }
58929
59111
  if (isInitialize) {
58930
59112
  const variantInfo2 = this.variantTypeInfo(receiver.type);
58931
59113
  if (variantInfo2 === null) return null;
@@ -60827,6 +61009,33 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
60827
61009
  typeArguments
60828
61010
  );
60829
61011
  }
61012
+ if (callee.kind === "lambda" && expected !== void 0) {
61013
+ rejectTypeArguments();
61014
+ const parameterTypes = callee.params.map((parameter3) => {
61015
+ if (parameter3.type === null) {
61016
+ throw new CompileError(
61017
+ "An immediately invoked lambda requires explicit parameter types.",
61018
+ parameter3.pos
61019
+ );
61020
+ }
61021
+ return this.resolveType(parameter3.type);
61022
+ });
61023
+ return this.resolveDelegateCall(
61024
+ this.resolveDelegateLambda(
61025
+ callee,
61026
+ {
61027
+ kind: "delegate",
61028
+ parameterTypes,
61029
+ returnType: expected
61030
+ },
61031
+ scope
61032
+ ),
61033
+ argumentsList2,
61034
+ scope,
61035
+ pos,
61036
+ false
61037
+ );
61038
+ }
60830
61039
  const variantCall = this.resolveVariantCall(
60831
61040
  callee,
60832
61041
  argumentsList2,
@@ -71527,7 +71736,7 @@ function resolveAnalyzerMember(context, member) {
71527
71736
  }
71528
71737
 
71529
71738
  // ../src/runtime/neoscript/neoscript-language-context-adapter.ts
71530
- var NEOSCRIPT_COMPILER_ADAPTER_REVISION = 6;
71739
+ var NEOSCRIPT_COMPILER_ADAPTER_REVISION = 8;
71531
71740
  var UNKNOWN_TYPE = {
71532
71741
  kind: "primitive",
71533
71742
  name: "unknown"
@@ -73817,6 +74026,7 @@ function compileMemberInitializerBody(args) {
73817
74026
  const returnTypeInfo = resolveMemberDeclaredTypeInfo(
73818
74027
  args.member,
73819
74028
  members2,
74029
+ args.classes,
73820
74030
  args.thisClass
73821
74031
  );
73822
74032
  if (returnTypeInfo === null) {
@@ -73864,7 +74074,8 @@ function compileValueRowInitializerBody(args) {
73864
74074
  }
73865
74075
  const returnTypeInfo = resolveMemberDeclaredTypeInfo(
73866
74076
  args.member,
73867
- args.members
74077
+ args.members,
74078
+ args.classes
73868
74079
  );
73869
74080
  if (returnTypeInfo === null) {
73870
74081
  throw new Error(
@@ -73997,7 +74208,9 @@ function compilationProjectForDocument(document2, state) {
73997
74208
  classes: document2.classes,
73998
74209
  enums: document2.enums,
73999
74210
  interfaces: document2.interfaces,
74000
- constructors: document2.constructors ?? []
74211
+ constructors: document2.constructors ?? [],
74212
+ variants: document2.variants ?? [],
74213
+ variantFolders: document2.variantFolders ?? []
74001
74214
  });
74002
74215
  return state.compilationProject;
74003
74216
  }
@@ -74093,6 +74306,8 @@ function compileValueInitializerDependency(document2, valueId, compilationProjec
74093
74306
  enums: document2.enums,
74094
74307
  interfaces: document2.interfaces,
74095
74308
  constructors: document2.constructors ?? [],
74309
+ variants: document2.variants ?? [],
74310
+ variantFolders: document2.variantFolders ?? [],
74096
74311
  member: site.member,
74097
74312
  valueRow: { ...site.row },
74098
74313
  valueId: site.row.id,
@@ -74111,7 +74326,9 @@ function compileMemberInitializerDependency(document2, memberId, compilationProj
74111
74326
  classes: document2.classes,
74112
74327
  enums: document2.enums,
74113
74328
  interfaces: document2.interfaces,
74114
- constructors: document2.constructors ?? []
74329
+ constructors: document2.constructors ?? [],
74330
+ variants: document2.variants ?? [],
74331
+ variantFolders: document2.variantFolders ?? []
74115
74332
  };
74116
74333
  const memberIndex = documentMemberCompilationIndex(document2);
74117
74334
  const member = memberIndex.membersById.get(memberId);
@@ -86384,7 +86601,9 @@ function buildNeoScriptProject(document2) {
86384
86601
  classes: document2.classes,
86385
86602
  enums: document2.enums,
86386
86603
  interfaces: document2.interfaces,
86387
- constructors: document2.constructors ?? []
86604
+ constructors: document2.constructors ?? [],
86605
+ variants: document2.variants,
86606
+ variantFolders: document2.variantFolders
86388
86607
  });
86389
86608
  }
86390
86609
  function neoScriptProjectFingerprint(document2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.89.8",
3
+ "version": "0.89.10",
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.89.8 -->
12
+ <!-- reviewed-through-cli: 0.89.10 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -143,7 +143,7 @@ The marker near the top of `SKILL.md` must exactly match the package version,
143
143
  and this quoted copy is checked too:
144
144
 
145
145
  ```html
146
- <!-- reviewed-through-cli: 0.89.8 -->
146
+ <!-- reviewed-through-cli: 0.89.10 -->
147
147
  ```
148
148
 
149
149
  Keep this skill on current behavior. Upgrade steps, rollout prerequisites,
@@ -31,6 +31,26 @@ Foo value = new(bar: "BAR", isFun: true) { IsFun = false };
31
31
  - A header constructor disables implicit parameterless `new` and forbids
32
32
  other constructor overloads. Its derived identity takes no `@id`.
33
33
 
34
+ ## Variant parameters
35
+
36
+ Constructors accept `NeoVariant<T>` and `NeoLookupVariant<T, TValue>` selections,
37
+ including nullable selections and generic targets such as `NeoVariant<Kid<int>>`.
38
+ A member initializer can retain the selection for each instance:
39
+
40
+ ```neo
41
+ class Box : NeoObject {}
42
+ class Made(NeoVariant<Box> selection) {
43
+ public NeoVariant<Box> Selection = selection;
44
+ }
45
+ Made value = new(Box.Variants.Base);
46
+ ```
47
+
48
+ Push and export retain the selected variant and any bound lookup row for replay.
49
+ `null` is an empty nullable selection; `Box.Variants.Base` selects the base class.
50
+ To pass a bound lookup selection directly, use a declared variant path and a
51
+ stored row ID, such as `new Made(Box.Variants.Seeds.BySeed.Bind(Reference(id: "row-id")))`.
52
+ This compiles to a fixed selection; `Bind` does not evaluate a dynamic row expression.
53
+
34
54
  ## Declared constructors
35
55
 
36
56
  Declare overloadable constructors as members when each body owns its own
@@ -39,6 +39,9 @@ abstract class Item<TContext extends SomeClass> : INamed {
39
39
  The `@id`s above are pulled IDs. New declarations omit them; push assigns them.
40
40
  Never put `@id` on inferred list/dictionary entry types or derived structural
41
41
  descriptors.
42
+ Generic bindings and their nested collection descriptors follow the owning
43
+ declaration's identity. Deleting and recreating an idless declaration creates
44
+ fresh bindings; retaining its pulled IDs preserves them.
42
45
 
43
46
  ## Modifiers
44
47
 
@@ -50,6 +50,8 @@ return this.Beds
50
50
  entries. Declared index lookups (`items.Index.Name[key]`) preserve the source
51
51
  entries' write permissions: writable fields can be updated through unique
52
52
  results or a bucket's entries, while bucket membership stays read-only.
53
+ Subsequent index lookups reflect writes to indexed fields, including writes
54
+ through `Where` results.
53
55
 
54
56
  ## Reductions
55
57
 
@@ -18,6 +18,8 @@ List<Item> ready = this.Items.Where((item) => item.Count > 0);
18
18
  - Call any non-null delegate expression directly: `callbacks[0](value)`,
19
19
  `(cond ? a : b)()`, `Factory.Make()()`. Force-unwrap a nullable one first:
20
20
  `callbacks["key"]!()`. Void delegates are statements only.
21
+ - A typed lambda can be called immediately when its result has an expected
22
+ type: `int n = ((int x) => x + 1)(2);`. Declare each parameter's type.
21
23
  - Inside a class body, invoke delegate and action members directly:
22
24
  `Selector()`, `OnUpdated()`.
23
25