@neocompose/cli 0.19.6 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/neo.mjs CHANGED
@@ -898,6 +898,7 @@ var init_language_spec = __esm({
898
898
  "Reference",
899
899
  "Partial",
900
900
  "FunctionRef",
901
+ "NeoDelegate",
901
902
  "Dialogue",
902
903
  "Trigger",
903
904
  "Node",
@@ -1534,6 +1535,16 @@ function isNeoScriptTypeAssignable(source, target, project) {
1534
1535
  if (source.kind === "dictionary" && target.kind === "dictionary") {
1535
1536
  return isNeoScriptTypeAssignable(source.keyType, target.keyType, project) && isNeoScriptTypeAssignable(source.valueType, target.valueType, project);
1536
1537
  }
1538
+ if (source.kind === "delegate" && target.kind === "delegate") {
1539
+ return source.parameterTypes.length === target.parameterTypes.length && isNeoScriptTypeAssignable(
1540
+ source.returnType,
1541
+ target.returnType,
1542
+ project
1543
+ ) && source.parameterTypes.every((parameter3, index) => {
1544
+ const expected = target.parameterTypes[index];
1545
+ return expected !== void 0 && isNeoScriptTypeAssignable(parameter3, expected, project) && isNeoScriptTypeAssignable(expected, parameter3, project);
1546
+ });
1547
+ }
1537
1548
  return false;
1538
1549
  }
1539
1550
  function commonNeoScriptAssignableType(left, right, project) {
@@ -1588,6 +1599,13 @@ function formatType(type, project) {
1588
1599
  return `Dictionary<${formatType(type.keyType, project)}, ${formatType(type.valueType, project)}>${suffix}`;
1589
1600
  case "typeParameter":
1590
1601
  return `${type.name}${suffix}`;
1602
+ case "delegate":
1603
+ return `NeoDelegate<${[
1604
+ formatType(type.returnType, project),
1605
+ ...type.parameterTypes.map(
1606
+ (parameter3) => formatType(parameter3, project)
1607
+ )
1608
+ ].join(", ")}>${suffix}`;
1591
1609
  }
1592
1610
  }
1593
1611
  var UNKNOWN_TYPE;
@@ -6476,6 +6494,8 @@ function neoScriptPositionalTypeKey(type) {
6476
6494
  return `dictionary:${neoScriptPositionalTypeKey(type.keyType)}:${neoScriptPositionalTypeKey(type.valueType)}`;
6477
6495
  case "typeParameter":
6478
6496
  return `typeParameter:${type.id}`;
6497
+ case "delegate":
6498
+ return `delegate:${neoScriptPositionalTypeKey(type.returnType)}(${type.parameterTypes.map(neoScriptPositionalTypeKey).join(",")})`;
6479
6499
  }
6480
6500
  }
6481
6501
  function validateNeoScriptOverloadSignatures(className, signatures) {
@@ -6575,7 +6595,7 @@ var NEOSCRIPT_COMPILER_REVISION;
6575
6595
  var init_strict_ir = __esm({
6576
6596
  "../packages/neoscript-language/src/strict-ir.ts"() {
6577
6597
  "use strict";
6578
- NEOSCRIPT_COMPILER_REVISION = 6;
6598
+ NEOSCRIPT_COMPILER_REVISION = 7;
6579
6599
  }
6580
6600
  });
6581
6601
 
@@ -6731,6 +6751,12 @@ function typeRefsEqual(left, right) {
6731
6751
  if (left.kind === "set" && right.kind === "set") {
6732
6752
  return typeRefsEqual(left.elementType, right.elementType);
6733
6753
  }
6754
+ if (left.kind === "delegate" && right.kind === "delegate") {
6755
+ return typeRefsEqual(left.returnType, right.returnType) && left.parameterTypes.length === right.parameterTypes.length && left.parameterTypes.every((parameter3, index) => {
6756
+ const other = right.parameterTypes[index];
6757
+ return other !== void 0 && typeRefsEqual(parameter3, other);
6758
+ });
6759
+ }
6734
6760
  return left.kind === "dictionary" && right.kind === "dictionary" ? typeRefsEqual(left.keyType, right.keyType) && typeRefsEqual(left.valueType, right.valueType) : false;
6735
6761
  }
6736
6762
  function variable(id2, type, pointer, project) {
@@ -7104,6 +7130,15 @@ function toWireType(type, project) {
7104
7130
  ownerClassId: type.ownerClassId ?? findGenericParameterOwner(type.id, project) ?? "",
7105
7131
  genericParamId: type.id
7106
7132
  };
7133
+ case "delegate":
7134
+ return {
7135
+ type: 25 /* Delegate */,
7136
+ required: required2,
7137
+ returnTypeInfo: type.returnType.kind === "primitive" && type.returnType.name === "void" ? { type: "Void", required: true } : toWireType(type.returnType, project),
7138
+ argumentTypes: type.parameterTypes.map(
7139
+ (parameter3) => toWireType(parameter3, project)
7140
+ )
7141
+ };
7107
7142
  }
7108
7143
  }
7109
7144
  function fromWireType(type) {
@@ -7150,6 +7185,14 @@ function fromWireType(type) {
7150
7185
  nullable
7151
7186
  };
7152
7187
  }
7188
+ if (type.type === 25 /* Delegate */) {
7189
+ return {
7190
+ kind: "delegate",
7191
+ returnType: type.returnTypeInfo.type === "Void" ? { kind: "primitive", name: "void" } : fromWireType(type.returnTypeInfo),
7192
+ parameterTypes: type.argumentTypes.map(fromWireType),
7193
+ nullable
7194
+ };
7195
+ }
7153
7196
  return { kind: "primitive", name: valueKindPrimitive(type.type), nullable };
7154
7197
  }
7155
7198
  function findGenericParameterOwner(parameterId, project) {
@@ -7371,6 +7414,13 @@ function substituteTypeParameters(member, receiver, declaring) {
7371
7414
  valueType: visit(type.valueType)
7372
7415
  };
7373
7416
  }
7417
+ if (type.kind === "delegate") {
7418
+ return {
7419
+ ...type,
7420
+ returnType: visit(type.returnType),
7421
+ parameterTypes: type.parameterTypes.map(visit)
7422
+ };
7423
+ }
7374
7424
  return type;
7375
7425
  };
7376
7426
  return visit(member);
@@ -8882,6 +8932,17 @@ var init_strict_resolver = __esm({
8882
8932
  );
8883
8933
  }
8884
8934
  resolveExpression(expression, scope, expected) {
8935
+ if (expected?.kind === "delegate") {
8936
+ if (expression.kind === "lambda") {
8937
+ return this.resolveDelegateLambda(expression, expected, scope);
8938
+ }
8939
+ const methodGroup = this.resolveDelegateMethodGroup(
8940
+ expression,
8941
+ expected,
8942
+ scope
8943
+ );
8944
+ if (methodGroup !== null) return methodGroup;
8945
+ }
8885
8946
  switch (expression.kind) {
8886
8947
  case "litNull":
8887
8948
  return literal(
@@ -9123,11 +9184,174 @@ var init_strict_resolver = __esm({
9123
9184
  }
9124
9185
  case "lambda":
9125
9186
  throw new CompileError(
9126
- "A lambda is valid only as an argument to a collection function.",
9187
+ "A lambda requires a NeoDelegate expected type.",
9127
9188
  expression.pos
9128
9189
  );
9129
9190
  }
9130
9191
  }
9192
+ resolveDelegateLambda(ast, expected, outerScope) {
9193
+ if (ast.params.length !== expected.parameterTypes.length) {
9194
+ throw new CompileError(
9195
+ `Delegate lambda expects ${expected.parameterTypes.length} parameter${expected.parameterTypes.length === 1 ? "" : "s"}, got ${ast.params.length}.`,
9196
+ ast.pos
9197
+ );
9198
+ }
9199
+ const scope = new Scope(outerScope);
9200
+ const parameters = ast.params.map((parameter3, index) => {
9201
+ this.assertLocalNameAvailable(parameter3.name, scope, parameter3.pos);
9202
+ const expectedType = requiredAt(expected.parameterTypes, index);
9203
+ const declared = parameter3.type ? this.resolveType(parameter3.type) : expectedType;
9204
+ if (!isNeoScriptTypeAssignable(declared, expectedType, this.project) || !isNeoScriptTypeAssignable(expectedType, declared, this.project)) {
9205
+ throw new CompileError(
9206
+ `Delegate lambda parameter ${index + 1} must be ${this.describe(expectedType)}, got ${this.describe(declared)}.`,
9207
+ parameter3.pos
9208
+ );
9209
+ }
9210
+ const item = variable(
9211
+ `__arg_${index}__`,
9212
+ declared,
9213
+ void 0,
9214
+ this.project
9215
+ );
9216
+ scope.define(
9217
+ scopeVariable(
9218
+ parameter3.name,
9219
+ item,
9220
+ declared,
9221
+ void 0,
9222
+ "runtime" /* Runtime */
9223
+ )
9224
+ );
9225
+ return item;
9226
+ });
9227
+ this.functionControlBoundaries.push({
9228
+ controlDepth: this.controlContexts.length,
9229
+ loopFlowDepth: this.loopFlowContexts.length,
9230
+ catchDepth: this.catchContexts.length
9231
+ });
9232
+ this.lambdaDepth++;
9233
+ this.expectedReturnStack.push(expected.returnType);
9234
+ try {
9235
+ const instructions = this.resolveStatements(ast.body, scope);
9236
+ const returnsVoid = isVoid(expected.returnType);
9237
+ if (!returnsVoid && !instructionsTerminate(instructions)) {
9238
+ throw new CompileError(
9239
+ "Not every reachable delegate path returns a value or throws.",
9240
+ ast.pos
9241
+ );
9242
+ }
9243
+ const action = {
9244
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
9245
+ parameters: [this.thisVariable, this.rootVariable, ...parameters],
9246
+ instructions,
9247
+ typeInfo: returnsVoid ? toWireType({ kind: "primitive", name: "null" }, this.project) : toWireType(expected.returnType, this.project)
9248
+ };
9249
+ return literal(expected, { action }, this.project);
9250
+ } finally {
9251
+ this.expectedReturnStack.pop();
9252
+ this.lambdaDepth--;
9253
+ this.functionControlBoundaries.pop();
9254
+ }
9255
+ }
9256
+ resolveDelegateMethodGroup(expression, expected, scope) {
9257
+ let symbol;
9258
+ let receiver = null;
9259
+ let owner;
9260
+ if (expression.kind === "ident") {
9261
+ const implicit = this.implicitMember(expression.name);
9262
+ if (implicit === null || implicit.symbol.kind !== "function" && implicit.symbol.kind !== "method") {
9263
+ return null;
9264
+ }
9265
+ symbol = implicit.symbol;
9266
+ owner = implicit.owner;
9267
+ receiver = symbol.static === true ? { kind: "static", memberId: symbol.id } : {
9268
+ kind: "instance",
9269
+ expression: this.resolveIdentifier("this", scope, expression.pos)
9270
+ };
9271
+ } else if (expression.kind === "member") {
9272
+ if (expression.receiver.kind === "ident" && !scope.lookup(expression.receiver.name)) {
9273
+ owner = this.project.typeByName.get(expression.receiver.name);
9274
+ symbol = owner?.members.find(
9275
+ (candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
9276
+ );
9277
+ if (symbol === void 0) return null;
9278
+ if (symbol.static !== true) {
9279
+ throw new CompileError(
9280
+ `Member '${owner?.name}.${symbol.name}' requires an instance receiver.`,
9281
+ expression.pos
9282
+ );
9283
+ }
9284
+ receiver = { kind: "static", memberId: symbol.id };
9285
+ } else {
9286
+ const receiverExpression = this.resolveExpression(
9287
+ expression.receiver,
9288
+ scope
9289
+ );
9290
+ if (receiverExpression.type.kind !== "named") return null;
9291
+ owner = this.project.typeById.get(receiverExpression.type.typeId);
9292
+ symbol = owner?.members.find(
9293
+ (candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
9294
+ );
9295
+ if (symbol === void 0) return null;
9296
+ if (symbol.static === true) {
9297
+ throw new CompileError(
9298
+ `Static member '${owner?.name}.${symbol.name}' must be accessed through the type name, not an instance.`,
9299
+ expression.pos
9300
+ );
9301
+ }
9302
+ receiver = { kind: "instance", expression: receiverExpression };
9303
+ }
9304
+ } else {
9305
+ return null;
9306
+ }
9307
+ if (owner !== void 0)
9308
+ this.assertMemberAccessible(owner, symbol, expression.pos);
9309
+ let returnType = symbol.returnType ?? symbol.type;
9310
+ let parameterTypes = (symbol.parameters ?? []).map(
9311
+ (parameter3) => parameter3.type
9312
+ );
9313
+ if (receiver?.kind === "instance" && receiver.expression.type.kind === "named" && owner !== void 0) {
9314
+ const receiverType = receiver.expression.type;
9315
+ returnType = substituteTypeParameters(returnType, receiverType, owner);
9316
+ parameterTypes = parameterTypes.map(
9317
+ (parameter3) => substituteTypeParameters(parameter3, receiverType, owner)
9318
+ );
9319
+ }
9320
+ const expectedVoid = isVoid(expected.returnType);
9321
+ const actualVoid = isVoid(returnType);
9322
+ if (expectedVoid !== actualVoid || !expectedVoid && !isNeoScriptTypeAssignable(returnType, expected.returnType, this.project) || parameterTypes.length !== expected.parameterTypes.length || !parameterTypes.every((parameter3, index) => {
9323
+ const target = expected.parameterTypes[index];
9324
+ return target !== void 0 && isNeoScriptTypeAssignable(parameter3, target, this.project) && isNeoScriptTypeAssignable(target, parameter3, this.project);
9325
+ })) {
9326
+ throw new CompileError(
9327
+ `Function '${symbol.name}' is not assignable to ${this.describe(expected)}.`,
9328
+ expression.pos
9329
+ );
9330
+ }
9331
+ const parameters = expected.parameterTypes.map(
9332
+ (type, index) => variable(`__arg_${index}__`, type, void 0, this.project)
9333
+ );
9334
+ const call = {
9335
+ type: "callFunction" /* CallFunction */,
9336
+ memberId: symbol.id,
9337
+ receiver: receiver?.kind === "static" ? { kind: "static", memberId: receiver.memberId } : {
9338
+ kind: "instance",
9339
+ pointer: receiver?.expression.pointer ?? this.thisVariable.pointer
9340
+ },
9341
+ args: parameters.map((parameter3) => ({
9342
+ type: "variable" /* Variable */,
9343
+ variableId: parameter3.id
9344
+ })),
9345
+ callSiteId: this.nextCallSite(expression.pos)
9346
+ };
9347
+ const action = {
9348
+ compilerRevision: NEOSCRIPT_COMPILER_REVISION,
9349
+ parameters: [this.thisVariable, this.rootVariable, ...parameters],
9350
+ instructions: expectedVoid ? [{ type: "functionCall" /* FunctionCall */, call }] : [{ type: "return" /* Return */, pointer: call }],
9351
+ typeInfo: expectedVoid ? toWireType({ kind: "primitive", name: "null" }, this.project) : toWireType(expected.returnType, this.project)
9352
+ };
9353
+ return literal(expected, { action }, this.project);
9354
+ }
9131
9355
  resolveInterpolatedString(parts, scope) {
9132
9356
  const stringType = { kind: "primitive", name: "string" };
9133
9357
  const pointers = parts.map((part) => {
@@ -9949,6 +10173,16 @@ var init_strict_resolver = __esm({
9949
10173
  }
9950
10174
  }
9951
10175
  resolveCall(callee, argumentsList2, scope, pos) {
10176
+ const delegate = this.resolveDelegateCallee(callee, scope);
10177
+ if (delegate !== null) {
10178
+ return this.resolveDelegateCall(
10179
+ delegate,
10180
+ argumentsList2,
10181
+ scope,
10182
+ pos,
10183
+ callee.kind === "member" && callee.optional === true
10184
+ );
10185
+ }
9952
10186
  if (callee.kind === "ident") {
9953
10187
  const vector = vectorKind(callee.name);
9954
10188
  if (vector)
@@ -10146,6 +10380,71 @@ var init_strict_resolver = __esm({
10146
10380
  pos
10147
10381
  );
10148
10382
  }
10383
+ resolveDelegateCallee(callee, scope) {
10384
+ if (callee.kind === "ident") {
10385
+ const scoped = scope.lookup(callee.name);
10386
+ const implicit = this.implicitMember(callee.name);
10387
+ if (scoped === null && (implicit === null || implicit.symbol.kind === "function" || implicit.symbol.kind === "method")) {
10388
+ return null;
10389
+ }
10390
+ const resolved = this.resolveIdentifier(callee.name, scope, callee.pos);
10391
+ return resolved.type.kind === "delegate" ? resolved : null;
10392
+ }
10393
+ if (callee.kind !== "member") return null;
10394
+ try {
10395
+ const resolved = this.resolveMember(
10396
+ callee.receiver,
10397
+ callee.name,
10398
+ scope,
10399
+ callee.pos,
10400
+ callee.optional === true
10401
+ );
10402
+ return resolved.type.kind === "delegate" ? resolved : null;
10403
+ } catch (error) {
10404
+ if (error instanceof CompileError) return null;
10405
+ throw error;
10406
+ }
10407
+ }
10408
+ resolveDelegateCall(delegate, args, scope, pos, optional) {
10409
+ if (delegate.type.kind !== "delegate") {
10410
+ throw new Error("Delegate call received a non-delegate type.");
10411
+ }
10412
+ const delegateType = delegate.type;
10413
+ if (isNullable(delegateType) && !optional) {
10414
+ throw new CompileError(
10415
+ `Cannot call optional ${this.describe(delegate.type)} without optional chaining or force-unwrapping it.`,
10416
+ pos
10417
+ );
10418
+ }
10419
+ requireArgCount("Delegate", args, delegateType.parameterTypes.length, pos);
10420
+ const pointers = args.map((argument2, index) => {
10421
+ const expected = requiredAt(delegateType.parameterTypes, index);
10422
+ const resolved = this.resolveExpression(argument2, scope, expected);
10423
+ this.requireAssignable(
10424
+ resolved.type,
10425
+ expected,
10426
+ argument2.pos,
10427
+ `delegate argument ${index + 1}`
10428
+ );
10429
+ return resolved.pointer;
10430
+ });
10431
+ if (isVoid(delegateType.returnType)) {
10432
+ throw new CompileError(
10433
+ "A void delegate cannot be used as a value; call it as a statement instead.",
10434
+ pos
10435
+ );
10436
+ }
10437
+ return {
10438
+ pointer: {
10439
+ type: "callDelegate" /* CallDelegate */,
10440
+ delegate: delegate.pointer,
10441
+ args: pointers,
10442
+ ...optional ? { optional: true } : {},
10443
+ callSiteId: this.nextCallSite(pos)
10444
+ },
10445
+ type: optional ? { ...delegateType.returnType, nullable: true } : delegateType.returnType
10446
+ };
10447
+ }
10149
10448
  resolveClassConstructor(className, argumentsList2, scope, pos) {
10150
10449
  const schemaClass2 = this.project.typeByName.get(className);
10151
10450
  if (!schemaClass2 || schemaClass2.kind !== "class") {
@@ -10917,8 +11216,42 @@ var init_strict_resolver = __esm({
10917
11216
  };
10918
11217
  }
10919
11218
  resolveFunctionStatement(expression, scope) {
10920
- if (expression.kind !== "call" || expression.callee.kind !== "member")
10921
- return null;
11219
+ if (expression.kind !== "call") return null;
11220
+ const delegate = this.resolveDelegateCallee(expression.callee, scope);
11221
+ if (delegate?.type.kind === "delegate") {
11222
+ const delegateType = delegate.type;
11223
+ requireArgCount(
11224
+ "Delegate",
11225
+ expression.args,
11226
+ delegateType.parameterTypes.length,
11227
+ expression.pos
11228
+ );
11229
+ if (isNullable(delegateType) && !(expression.callee.kind === "member" && expression.callee.optional)) {
11230
+ throw new CompileError(
11231
+ `Cannot call optional ${this.describe(delegate.type)} without optional chaining or force-unwrapping it.`,
11232
+ expression.pos
11233
+ );
11234
+ }
11235
+ const args2 = expression.args.map((argument2, index) => {
11236
+ const expected = requiredAt(delegateType.parameterTypes, index);
11237
+ const resolved = this.resolveExpression(argument2, scope, expected);
11238
+ this.requireAssignable(
11239
+ resolved.type,
11240
+ expected,
11241
+ argument2.pos,
11242
+ `delegate argument ${index + 1}`
11243
+ );
11244
+ return resolved.pointer;
11245
+ });
11246
+ return {
11247
+ type: "callDelegate" /* CallDelegate */,
11248
+ delegate: delegate.pointer,
11249
+ args: args2,
11250
+ ...expression.callee.kind === "member" && expression.callee.optional ? { optional: true } : {},
11251
+ callSiteId: this.nextCallSite(expression.pos)
11252
+ };
11253
+ }
11254
+ if (expression.callee.kind !== "member") return null;
10922
11255
  const memberName = expression.callee.name;
10923
11256
  if (expression.callee.receiver.kind === "ident" && !scope.lookup(expression.callee.receiver.name)) {
10924
11257
  const staticType = this.project.typeByName.get(
@@ -20118,6 +20451,13 @@ function substituteInheritedSourceMember(member, baseInfo, resolvedBaseType) {
20118
20451
  valueType: substitute2(type.valueType)
20119
20452
  };
20120
20453
  }
20454
+ if (type.kind === "delegate") {
20455
+ return {
20456
+ ...type,
20457
+ returnType: substitute2(type.returnType),
20458
+ parameterTypes: type.parameterTypes.map(substitute2)
20459
+ };
20460
+ }
20121
20461
  return type;
20122
20462
  };
20123
20463
  return {
@@ -20188,6 +20528,15 @@ function sourceTypeRef(type, owner, typeIds) {
20188
20528
  ...nullable ? { nullable } : {}
20189
20529
  };
20190
20530
  }
20531
+ if (type.name === "NeoDelegate") {
20532
+ const returnType = type.typeArguments[0] ? sourceTypeRef(type.typeArguments[0], owner, typeIds) : { kind: "primitive", name: "unknown" };
20533
+ return {
20534
+ kind: "delegate",
20535
+ returnType,
20536
+ parameterTypes: type.typeArguments.slice(1).map((argument2) => sourceTypeRef(argument2, owner, typeIds)),
20537
+ ...nullable ? { nullable } : {}
20538
+ };
20539
+ }
20191
20540
  if (type.name === "Reference" && type.typeArguments[0]) {
20192
20541
  return {
20193
20542
  ...sourceTypeRef(type.typeArguments[0], owner, typeIds),
@@ -20906,6 +21255,18 @@ function validateTypeApplication(uri, type, genericParameters, environment, diag
20906
21255
  return;
20907
21256
  }
20908
21257
  const target = environment.declarations.get(type.name);
21258
+ if (type.name === "NeoDelegate") {
21259
+ if (type.typeArguments.length < 1 || type.typeArguments.length > 17) {
21260
+ diagnose(
21261
+ diagnostics,
21262
+ uri,
21263
+ type.range,
21264
+ "generic-argument-arity",
21265
+ `Type 'NeoDelegate' expects a return type followed by up to 16 parameter types, but ${type.typeArguments.length} type arguments were provided.`
21266
+ );
21267
+ }
21268
+ return;
21269
+ }
20909
21270
  const expected = target?.declaration.kind === "class" ? target.declaration.genericParameters.length : BUILTIN_ARITY.get(type.name) ?? 0;
20910
21271
  if (!target && !BUILTIN_TYPES.has(type.name)) return;
20911
21272
  if (type.typeArguments.length !== expected) {
@@ -21557,9 +21918,15 @@ function memberCompatibility(implementation, implementationSubstitution, target,
21557
21918
  environment,
21558
21919
  implementationGenericParameters
21559
21920
  ) && isClassTypedShape(targetType, environment, implementationGenericParameters);
21921
+ const permitsDelegateReturnCovariance = isClassOverride && implementationFamily === "value" && delegateShapeAssignable(
21922
+ implementationType,
21923
+ targetType,
21924
+ environment,
21925
+ implementationGenericParameters
21926
+ );
21560
21927
  const permitsStoredOverrideNullability = isClassOverride && implementation.kind === "field" && (target.member.kind === "field" || isAbstractPropertyContract(target.member, targetAccessors));
21561
21928
  const comparableImplementationType = permitsStoredOverrideNullability ? { ...implementationType, nullable: targetType.nullable } : implementationType;
21562
- if (!typesEqual(comparableImplementationType, targetType) && !((permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
21929
+ if (!typesEqual(comparableImplementationType, targetType) && !(permitsDelegateReturnCovariance || (permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
21563
21930
  comparableImplementationType,
21564
21931
  targetType,
21565
21932
  environment,
@@ -21600,6 +21967,28 @@ function memberCompatibility(implementation, implementationSubstitution, target,
21600
21967
  }
21601
21968
  return null;
21602
21969
  }
21970
+ function delegateShapeAssignable(actual, expected, environment, genericParameters) {
21971
+ if (actual.name !== "NeoDelegate" || expected.name !== "NeoDelegate") {
21972
+ return false;
21973
+ }
21974
+ if (actual.nullable !== expected.nullable) return false;
21975
+ if (actual.arguments.length !== expected.arguments.length) return false;
21976
+ const actualReturn = actual.arguments[0];
21977
+ const expectedReturn = expected.arguments[0];
21978
+ if (actualReturn === void 0 || expectedReturn === void 0) return false;
21979
+ if (!isTypeAssignable(
21980
+ actualReturn,
21981
+ expectedReturn,
21982
+ environment,
21983
+ genericParameters
21984
+ )) {
21985
+ return false;
21986
+ }
21987
+ return actual.arguments.slice(1).every((argument2, index) => {
21988
+ const expectedArgument = expected.arguments[index + 1];
21989
+ return expectedArgument !== void 0 && typesEqual(argument2, expectedArgument);
21990
+ });
21991
+ }
21603
21992
  function valueAccessors(member, environment) {
21604
21993
  if (member.kind === "field") {
21605
21994
  const owner = environment.memberOwners.get(member);
@@ -28009,6 +28398,12 @@ function normalizeTypeInfoBindings(value) {
28009
28398
  }
28010
28399
  }
28011
28400
  normalizeTypeInfoBindings(value.entryTypeInfo);
28401
+ normalizeTypeInfoBindings(value.returnTypeInfo);
28402
+ if (Array.isArray(value.argumentTypes)) {
28403
+ for (const argument2 of value.argumentTypes) {
28404
+ normalizeTypeInfoBindings(argument2);
28405
+ }
28406
+ }
28012
28407
  }
28013
28408
  function stripCompiledInitializer(value) {
28014
28409
  if (!isRecord(value)) return;
@@ -28573,6 +28968,22 @@ function memberFromDocument(record3, members, owners, classNames, context) {
28573
28968
  if (kind === MEMBER_KIND.FunctionRef) {
28574
28969
  return { ...common, kind: "functionRef" };
28575
28970
  }
28971
+ if (kind === MEMBER_KIND.NSDelegate) {
28972
+ return {
28973
+ ...common,
28974
+ kind: "delegate",
28975
+ returnType: documentReturnTypeToManifest(
28976
+ field("returnTypeInfo", void 0),
28977
+ record3,
28978
+ "returnTypeInfo"
28979
+ ),
28980
+ arguments: documentArgumentsToManifest(
28981
+ field("argumentTypes", []),
28982
+ record3,
28983
+ source.span
28984
+ )
28985
+ };
28986
+ }
28576
28987
  if (kind === MEMBER_KIND.Generic) {
28577
28988
  return {
28578
28989
  ...common,
@@ -28711,6 +29122,13 @@ function memberToDocumentFields(member, baseData3) {
28711
29122
  if (member.uiAction !== void 0) fields.uiAction = member.uiAction;
28712
29123
  }
28713
29124
  }
29125
+ if (member.kind === "delegate") {
29126
+ fields.returnTypeInfo = manifestReturnTypeToDocument(member.returnType);
29127
+ fields.argumentTypes = member.arguments.map((argument2) => ({
29128
+ name: argument2.name,
29129
+ ...manifestTypeToDocument(argument2.type)
29130
+ }));
29131
+ }
28714
29132
  if (member.kind === "generic") {
28715
29133
  fields.genericParamId = member.genericParamId;
28716
29134
  if (member.partial) fields.partial = true;
@@ -28908,6 +29326,24 @@ function documentTypeToManifest(value, record3, path) {
28908
29326
  collectionValueId: optionalStringOrNull(typeInfo.collectionValueId)
28909
29327
  };
28910
29328
  }
29329
+ if (kind === MEMBER_KIND.NSDelegate) {
29330
+ return {
29331
+ kind: "delegate",
29332
+ nullable,
29333
+ returnType: documentReturnTypeToManifest(
29334
+ typeInfo.returnTypeInfo,
29335
+ record3,
29336
+ `${path}.returnTypeInfo`
29337
+ ),
29338
+ argumentTypes: optionalArray(typeInfo.argumentTypes).map(
29339
+ (argument2, index) => documentTypeToManifest(
29340
+ argument2,
29341
+ record3,
29342
+ `${path}.argumentTypes.${index}`
29343
+ )
29344
+ )
29345
+ };
29346
+ }
28911
29347
  throw invalidDocument(
28912
29348
  record3,
28913
29349
  path,
@@ -28971,6 +29407,14 @@ function manifestTypeToDocument(type) {
28971
29407
  readOnly: type.readOnly || void 0
28972
29408
  });
28973
29409
  }
29410
+ if (type.kind === "delegate") {
29411
+ return {
29412
+ type: MEMBER_KIND.NSDelegate,
29413
+ required: required2,
29414
+ returnTypeInfo: manifestReturnTypeToDocument(type.returnType),
29415
+ argumentTypes: type.argumentTypes.map(manifestTypeToDocument)
29416
+ };
29417
+ }
28974
29418
  if (type.kind !== "lookup") {
28975
29419
  throw new Error(`No document type-info mapping for ${type.kind}.`);
28976
29420
  }
@@ -29362,7 +29806,8 @@ var init_codecs = __esm({
29362
29806
  Generic: 21,
29363
29807
  Interface: 22,
29364
29808
  NSFunction: 23,
29365
- FunctionRef: 24
29809
+ FunctionRef: 24,
29810
+ NSDelegate: 25
29366
29811
  };
29367
29812
  TYPE_KIND_BY_MEMBER_KIND = /* @__PURE__ */ new Map([
29368
29813
  [MEMBER_KIND.Null, "null"],
@@ -29413,7 +29858,8 @@ var init_codecs = __esm({
29413
29858
  ["decimal", MEMBER_KIND.Decimal],
29414
29859
  ["generic", MEMBER_KIND.Generic],
29415
29860
  ["scriptFunction", MEMBER_KIND.NSFunction],
29416
- ["functionRef", MEMBER_KIND.FunctionRef]
29861
+ ["functionRef", MEMBER_KIND.FunctionRef],
29862
+ ["delegate", MEMBER_KIND.NSDelegate]
29417
29863
  ]);
29418
29864
  TYPE_MEMBER_KIND_BY_KIND = /* @__PURE__ */ new Map([
29419
29865
  ["null", MEMBER_KIND.Null],
@@ -31609,6 +32055,14 @@ function assertMember2(value, path) {
31609
32055
  assertAbstractScriptInvariant(member, path);
31610
32056
  return;
31611
32057
  }
32058
+ if (kind === "delegate") {
32059
+ assertReturnType(member.returnType, `${path}.returnType`);
32060
+ arrayOf(member.arguments, `${path}.arguments`, assertFunctionArgument);
32061
+ if (Array.isArray(member.arguments) && member.arguments.length > 16) {
32062
+ invalid(`${path}.arguments`, "delegate arity cannot exceed 16.");
32063
+ }
32064
+ return;
32065
+ }
31612
32066
  if (kind === "generic") {
31613
32067
  nonEmptyString(member.genericParamId, `${path}.genericParamId`);
31614
32068
  if (member.partial !== void 0) {
@@ -31917,6 +32371,20 @@ function assertType2(value, path, depth = 0) {
31917
32371
  nullableNonEmptyString(type.collectionValueId, `${path}.collectionValueId`);
31918
32372
  return;
31919
32373
  }
32374
+ if (kind === "delegate") {
32375
+ knownKeys(type, path, ["kind", "nullable", "returnType", "argumentTypes"]);
32376
+ booleanAt(type.nullable, `${path}.nullable`);
32377
+ assertReturnType(type.returnType, `${path}.returnType`);
32378
+ arrayOf(
32379
+ type.argumentTypes,
32380
+ `${path}.argumentTypes`,
32381
+ (entry, entryPath) => assertType2(entry, entryPath, depth + 1)
32382
+ );
32383
+ if (Array.isArray(type.argumentTypes) && type.argumentTypes.length > 16) {
32384
+ invalid(`${path}.argumentTypes`, "delegate arity cannot exceed 16.");
32385
+ }
32386
+ return;
32387
+ }
31920
32388
  invalid(`${path}.kind`, `unsupported schema type ${JSON.stringify(kind)}.`);
31921
32389
  }
31922
32390
  function assertInterface(value, path) {
@@ -32818,7 +33286,8 @@ var init_validate = __esm({
32818
33286
  function: ["returnType", "arguments", "deferred"],
32819
33287
  scriptFunction: ["returnType", "arguments", "deferred", "script"],
32820
33288
  generic: ["genericParamId"],
32821
- functionRef: []
33289
+ functionRef: [],
33290
+ delegate: ["returnType", "arguments"]
32822
33291
  };
32823
33292
  PRIMITIVE_TYPE_KINDS = /* @__PURE__ */ new Set([
32824
33293
  "null",
@@ -35883,6 +36352,27 @@ function isNSTypeInfoGenericParam(value) {
35883
36352
  if (typeof v.genericParamId !== "string") return false;
35884
36353
  return v.genericParamId.length > 0;
35885
36354
  }
36355
+ function isNSTypeInfoDelegateInternal(value, ancestors) {
36356
+ if (!isNSTypeInfoBase(value) || value.type !== 25 /* NSDelegate */) {
36357
+ return false;
36358
+ }
36359
+ const delegate = value;
36360
+ if (ancestors.has(delegate)) return false;
36361
+ ancestors.add(delegate);
36362
+ try {
36363
+ if (!isNSTypeInfoVoid(delegate.returnTypeInfo) && !isNSTypeInfoInternal(delegate.returnTypeInfo, ancestors)) {
36364
+ return false;
36365
+ }
36366
+ if (!Array.isArray(delegate.argumentTypes) || delegate.argumentTypes.length > 16) {
36367
+ return false;
36368
+ }
36369
+ return delegate.argumentTypes.every(
36370
+ (argument2) => isNSTypeInfoInternal(argument2, ancestors)
36371
+ );
36372
+ } finally {
36373
+ ancestors.delete(delegate);
36374
+ }
36375
+ }
35886
36376
  function isNSTypeInfoCollection(value) {
35887
36377
  return isNSTypeInfoCollectionInternal(value, /* @__PURE__ */ new Set());
35888
36378
  }
@@ -35939,7 +36429,7 @@ function isNSTypeInfo(value) {
35939
36429
  return isNSTypeInfoInternal(value, /* @__PURE__ */ new Set());
35940
36430
  }
35941
36431
  function isNSTypeInfoInternal(value, ancestors) {
35942
- return isNSTypeInfoUnknown(value) || isNSTypeInfoPrimitive(value) || isNSTypeInfoAsset(value) || isNSTypeInfoVector(value) || isNSTypeInfoColor(value) || isNSTypeInfoDialogueLookup(value) || isNSTypeInfoClassInternal(value, ancestors) || isNSTypeInfoInterface(value) || isNSTypeInfoGenericParam(value) || isNSTypeInfoCollectionInternal(value, ancestors) || isNSTypeInfoLookupInternal(value, ancestors) || isNSTypeInfoEnum(value);
36432
+ return isNSTypeInfoUnknown(value) || isNSTypeInfoPrimitive(value) || isNSTypeInfoAsset(value) || isNSTypeInfoVector(value) || isNSTypeInfoColor(value) || isNSTypeInfoDialogueLookup(value) || isNSTypeInfoClassInternal(value, ancestors) || isNSTypeInfoInterface(value) || isNSTypeInfoGenericParam(value) || isNSTypeInfoDelegateInternal(value, ancestors) || isNSTypeInfoCollectionInternal(value, ancestors) || isNSTypeInfoLookupInternal(value, ancestors) || isNSTypeInfoEnum(value);
35943
36433
  }
35944
36434
  function isNSArgumentTypeInfo(value) {
35945
36435
  return isRequiredType(value, isNSArgumentTypeInfoUnsafe);
@@ -35961,6 +36451,11 @@ function typeInfoContainsUnknown(value, ancestors) {
35961
36451
  if (value.type === 6 /* List */ || value.type === 5 /* Dictionary */ || value.type === 9 /* Lookup */) {
35962
36452
  return typeInfoContainsUnknown(value.entryTypeInfo, ancestors);
35963
36453
  }
36454
+ if (value.type === 25 /* NSDelegate */) {
36455
+ return value.returnTypeInfo.type !== NS_TYPE_VOID && typeInfoContainsUnknown(value.returnTypeInfo, ancestors) || value.argumentTypes.some(
36456
+ (argument2) => typeInfoContainsUnknown(argument2, ancestors)
36457
+ );
36458
+ }
35964
36459
  if (value.type !== 7 /* Class */) return false;
35965
36460
  return Object.values(value.typeArguments ?? {}).some(
35966
36461
  (argument2) => typeInfoContainsUnknown(argument2, ancestors)
@@ -36095,6 +36590,16 @@ function isNSPointerCallFunction(value) {
36095
36590
  }
36096
36591
  return true;
36097
36592
  }
36593
+ function isNSPointerCallDelegate(value) {
36594
+ const v = value;
36595
+ if (v?.type !== "callDelegate" /* callDelegate */) return false;
36596
+ if (!isNSPointer(v.delegate)) return false;
36597
+ if (!Array.isArray(v.args) || !v.args.every(isNSPointer)) return false;
36598
+ if (typeof v.callSiteId !== "string" || v.callSiteId.length === 0) {
36599
+ return false;
36600
+ }
36601
+ return v.optional === void 0 || typeof v.optional === "boolean";
36602
+ }
36098
36603
  function isNSCallReceiver(value) {
36099
36604
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
36100
36605
  return false;
@@ -36113,7 +36618,7 @@ function isNSPointerFunctionErrorCheck(value) {
36113
36618
  return isNSFunctionErrorCheckMode(v.mode);
36114
36619
  }
36115
36620
  function isNSPointer(value) {
36116
- return isNSPointerReference(value) || isNSPointerVariable(value) || isNSPointerValue(value) || isNSPointerOperation(value) || isNSPointerFunction(value) || isNSPointerKeyOf(value) || isNSPointerListLiteral(value) || isNSPointerDictLiteral(value) || isNSPointerForceUnwrap(value) || isNSPointerIsCheck(value) || isNSPointerCallGetter(value) || isNSPointerCoalesce(value) || isNSPointerToBool(value) || isNSPointerStringify(value) || isNSPointerCallFunction(value) || isNSPointerFunctionErrorCheck(value);
36621
+ return isNSPointerReference(value) || isNSPointerVariable(value) || isNSPointerValue(value) || isNSPointerOperation(value) || isNSPointerFunction(value) || isNSPointerKeyOf(value) || isNSPointerListLiteral(value) || isNSPointerDictLiteral(value) || isNSPointerForceUnwrap(value) || isNSPointerIsCheck(value) || isNSPointerCallGetter(value) || isNSPointerCoalesce(value) || isNSPointerToBool(value) || isNSPointerStringify(value) || isNSPointerCallFunction(value) || isNSPointerCallDelegate(value) || isNSPointerFunctionErrorCheck(value);
36117
36622
  }
36118
36623
  function isNSPointers(value) {
36119
36624
  return Array.isArray(value) && value.every(isNSPointer);
@@ -36451,7 +36956,7 @@ function isNSInstructionCollectionCall(value) {
36451
36956
  function isNSInstructionFunctionCall(value) {
36452
36957
  const v = value;
36453
36958
  if (v?.type !== "functionCall" /* functionCall */) return false;
36454
- return isNSPointerCallFunction(v.call);
36959
+ return isNSPointerCallFunction(v.call) || isNSPointerCallDelegate(v.call);
36455
36960
  }
36456
36961
  function isNSLoopBinding(value) {
36457
36962
  const binding = value;
@@ -36983,6 +37488,7 @@ var init_member_kind_enum = __esm({
36983
37488
  MemberKind13[MemberKind13["Interface"] = 22] = "Interface";
36984
37489
  MemberKind13[MemberKind13["NSFunction"] = 23] = "NSFunction";
36985
37490
  MemberKind13[MemberKind13["FunctionRef"] = 24] = "FunctionRef";
37491
+ MemberKind13[MemberKind13["NSDelegate"] = 25] = "NSDelegate";
36986
37492
  return MemberKind13;
36987
37493
  })(MemberKind || {});
36988
37494
  }
@@ -37554,6 +38060,61 @@ function isMemberNSFunction(value) {
37554
38060
  if (typeof v.code !== "string" || v.code.length === 0) return false;
37555
38061
  return hasValidNSFunctionAction(v, base.returnTypeInfo, base.argumentTypes);
37556
38062
  }
38063
+ function isMemberDelegateTarget(value) {
38064
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
38065
+ const record3 = value;
38066
+ if (!hasExactKeys(record3, ["memberId", "valueId"])) return false;
38067
+ return typeof record3.memberId === "string" && record3.memberId.length > 0 && (record3.valueId === null || typeof record3.valueId === "string" && record3.valueId.length > 0);
38068
+ }
38069
+ function isNSDelegateClosureValueDraft(value) {
38070
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
38071
+ const record3 = value;
38072
+ return hasExactKeys(record3, ["code"]) && typeof record3.code === "string" && record3.code.length > 0;
38073
+ }
38074
+ function isNSDelegateClosureValue(value) {
38075
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
38076
+ const record3 = value;
38077
+ const keys = record3.code === void 0 ? ["action"] : ["code", "action"];
38078
+ if (!hasExactKeys(record3, keys)) return false;
38079
+ if (record3.code !== void 0 && (typeof record3.code !== "string" || record3.code.length === 0)) {
38080
+ return false;
38081
+ }
38082
+ return isNSFunctionWithReturnType(record3.action);
38083
+ }
38084
+ function isNSDelegateValue(value) {
38085
+ return isMemberDelegateTarget(value) || isNSDelegateClosureValueDraft(value) || isNSDelegateClosureValue(value);
38086
+ }
38087
+ function nsDelegateDirectReferenceValueId(value) {
38088
+ if (!isNSDelegateClosureValue(value)) return null;
38089
+ const instructions = value.action.instructions;
38090
+ if (instructions.length !== 1) return null;
38091
+ const instruction = instructions[0];
38092
+ if (instruction?.type !== "return" /* return */ || instruction.pointer?.type !== "reference" /* reference */) {
38093
+ return null;
38094
+ }
38095
+ return instruction.pointer.valueId;
38096
+ }
38097
+ function isMemberDelegateBase(value) {
38098
+ const v = asMemberBaseForKind(value, 25 /* NSDelegate */);
38099
+ if (v === null) return false;
38100
+ if (!isNSFunctionReturnTypeInfo(v.returnTypeInfo)) return false;
38101
+ if (!Array.isArray(v.argumentTypes) || v.argumentTypes.length > 16) {
38102
+ return false;
38103
+ }
38104
+ const names = /* @__PURE__ */ new Set();
38105
+ for (const argument2 of v.argumentTypes) {
38106
+ if (!isNSFunctionArgumentTypeInfo(argument2)) return false;
38107
+ if (!isValidCallableIdentifier(argument2.name)) return false;
38108
+ if (argument2.type === NS_TYPE_UNKNOWN) return false;
38109
+ if (names.has(argument2.name)) return false;
38110
+ names.add(argument2.name);
38111
+ }
38112
+ const defaultValue = v.defaultValue;
38113
+ if (defaultValue === void 0 || defaultValue === null) return true;
38114
+ if (!isMemberValueBase(defaultValue)) return false;
38115
+ if (isInitValueContent(defaultValue)) return true;
38116
+ return isNSDelegateValue(defaultValue.value);
38117
+ }
37557
38118
  function isFunctionRefValue(value) {
37558
38119
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
37559
38120
  const record3 = value;
@@ -37616,7 +38177,7 @@ function isMemberBase(value) {
37616
38177
  if (partial !== void 0 && v?.kind !== 7 /* Class */ && v?.kind !== 21 /* Generic */) {
37617
38178
  return false;
37618
38179
  }
37619
- const matchesConcreteType = isMemberNullBase(value) || isMemberBoolBase(value) || isMemberIntBase(value) || isMemberStringBase(value) || isMemberFloatBase(value) || isMemberDictionaryBase(value) || isMemberListBase(value) || isMemberClassBase(value) || isMemberEnumBase(value) || isMemberLookupBase(value) || isMemberDialogueLookupBase(value) || isMemberNSPropertyBase(value) || isMemberNSPropertyContractBase(value) || isMemberSpriteBase(value) || isMemberAudioBase(value) || isMemberFunctionBase(value) || isMemberNSFunctionBase(value) || isMemberNSFunction(value) || isMemberFunctionRefBase(value) || isMemberVector2Base(value) || isMemberVector2IntBase(value) || isMemberVector3Base(value) || isMemberVector3IntBase(value) || isMemberColorBase(value) || isMemberDecimalBase(value) || isMemberGenericBase(value);
38180
+ const matchesConcreteType = isMemberNullBase(value) || isMemberBoolBase(value) || isMemberIntBase(value) || isMemberStringBase(value) || isMemberFloatBase(value) || isMemberDictionaryBase(value) || isMemberListBase(value) || isMemberClassBase(value) || isMemberEnumBase(value) || isMemberLookupBase(value) || isMemberDialogueLookupBase(value) || isMemberNSPropertyBase(value) || isMemberNSPropertyContractBase(value) || isMemberSpriteBase(value) || isMemberAudioBase(value) || isMemberFunctionBase(value) || isMemberNSFunctionBase(value) || isMemberNSFunction(value) || isMemberDelegateBase(value) || isMemberFunctionRefBase(value) || isMemberVector2Base(value) || isMemberVector2IntBase(value) || isMemberVector3Base(value) || isMemberVector3IntBase(value) || isMemberColorBase(value) || isMemberDecimalBase(value) || isMemberGenericBase(value);
37620
38181
  if (!matchesConcreteType) return false;
37621
38182
  if (!isValidDocsText(v?.docsText)) return false;
37622
38183
  if (typeof v?.name !== "string") return false;
@@ -38077,7 +38638,7 @@ var init_inheritance = __esm({
38077
38638
  });
38078
38639
 
38079
38640
  // ../src/models/classes/world-system-classes.generated.ts
38080
- var WORLD_GRID_CHILDREN_MEMBER_ID, WORLD_GRID_CHILDREN_ENTRY_MEMBER_ID, WORLD_OBJECT_CHILDREN_MEMBER_ID, WORLD_OBJECT_CHILDREN_ENTRY_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILES_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILES_ENTRY_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILE_CELL_MEMBER_ID, WORLD_TILE_INSTANCE_CELL_MEMBER_ID, WORLD_TILE_LAYER_LINK_TILES_MEMBER_ID, WORLD_TILE_LAYER_LINK_TILE_ENTRY_MEMBER_ID, WORLD_OBJECT_LAYER_LINK_OBJECTS_MEMBER_ID, WORLD_OBJECT_LAYER_LINK_OBJECT_ENTRY_MEMBER_ID, WORLD_ANIMATION_CLIP_TARGET_PARAM_ID, WORLD_ANIMATION_CHILD_OVERRIDE_ENTRY_PARAM_ID, WORLD_ANIMATION_CLIP_FPS_MEMBER_ID, WORLD_ANIMATION_CLIP_DURATION_MEMBER_ID, WORLD_ANIMATION_CLIP_FRAMES_MEMBER_ID, WORLD_ANIMATION_CLIP_TRACKS_MEMBER_ID, WORLD_ANIMATION_FRAME_BASE_INDEX_MEMBER_ID, WORLD_ANIMATION_FRAME_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_ENTRY_MEMBER_ID, WORLD_ANIMATION_FRAME_ACTIONS_MEMBER_ID, WORLD_ANIMATION_CHILD_OVERRIDE_CHILD_MEMBER_ID, WORLD_ANIMATION_CHILD_OVERRIDE_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_TRACK_CHILD_MEMBER_ID, WORLD_ANIMATION_TRACK_START_FRAME_MEMBER_ID, WORLD_ANIMATION_TRACK_DIRECTION_MEMBER_ID, WORLD_ANIMATION_TRACK_OFFSET_START_INDEX_MEMBER_ID, WORLD_ANIMATION_TRACK_OFFSET_END_INDEX_MEMBER_ID, WORLD_ANIMATION_CHILD_TRACK_CLIP_KEY_MEMBER_ID, WORLD_ANIMATION_SEGMENT_DURATION_MEMBER_ID, WORLD_ANIMATION_SEGMENT_FRAMES_MEMBER_ID, WORLD_ANIMATION_SEGMENT_TRACK_CHILD_PARAM_ID, WORLD_ANIMATION_SEGMENT_TRACK_VALUE_PARAM_ID, WORLD_PLAY_DIRECTION_FORWARD_OPTION_ID, WORLD_PLAY_DIRECTION_REVERSE_OPTION_ID, WORLD_SYSTEM_CLASS_DEFINITIONS;
38641
+ var WORLD_GRID_CHILDREN_MEMBER_ID, WORLD_GRID_CHILDREN_ENTRY_MEMBER_ID, WORLD_OBJECT_CHILDREN_MEMBER_ID, WORLD_OBJECT_CHILDREN_ENTRY_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILES_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILES_ENTRY_MEMBER_ID, WORLD_OBJECT_PLACEMENT_TILE_CELL_MEMBER_ID, WORLD_TILE_INSTANCE_CELL_MEMBER_ID, WORLD_TILE_LAYER_LINK_TILES_MEMBER_ID, WORLD_TILE_LAYER_LINK_TILE_ENTRY_MEMBER_ID, WORLD_OBJECT_LAYER_LINK_OBJECTS_MEMBER_ID, WORLD_OBJECT_LAYER_LINK_OBJECT_ENTRY_MEMBER_ID, WORLD_ANIMATION_CLIP_TARGET_PARAM_ID, WORLD_ANIMATION_CHILD_OVERRIDE_ENTRY_PARAM_ID, WORLD_ANIMATION_CLIP_FPS_MEMBER_ID, WORLD_ANIMATION_CLIP_DURATION_MEMBER_ID, WORLD_ANIMATION_CLIP_FRAMES_MEMBER_ID, WORLD_ANIMATION_CLIP_TRACKS_MEMBER_ID, WORLD_ANIMATION_FRAME_BASE_INDEX_MEMBER_ID, WORLD_ANIMATION_FRAME_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_ENTRY_MEMBER_ID, WORLD_ANIMATION_FRAME_ACTIONS_MEMBER_ID, WORLD_ANIMATION_CHILD_OVERRIDE_SELECTOR_MEMBER_ID, WORLD_ANIMATION_CHILD_OVERRIDE_REFRESH_MEMBER_ID, WORLD_ANIMATION_CHILD_OVERRIDE_OVERRIDES_MEMBER_ID, WORLD_ANIMATION_TRACK_SELECTOR_MEMBER_ID, WORLD_ANIMATION_TRACK_REFRESH_MEMBER_ID, WORLD_ANIMATION_TRACK_START_FRAME_MEMBER_ID, WORLD_ANIMATION_TRACK_DIRECTION_MEMBER_ID, WORLD_ANIMATION_TRACK_OFFSET_START_INDEX_MEMBER_ID, WORLD_ANIMATION_TRACK_OFFSET_END_INDEX_MEMBER_ID, WORLD_ANIMATION_CHILD_TRACK_CLIP_KEY_MEMBER_ID, WORLD_ANIMATION_SEGMENT_DURATION_MEMBER_ID, WORLD_ANIMATION_SEGMENT_FRAMES_MEMBER_ID, WORLD_ANIMATION_SEGMENT_TRACK_CHILD_PARAM_ID, WORLD_ANIMATION_SEGMENT_TRACK_VALUE_PARAM_ID, WORLD_SELECTOR_REFRESH_ON_LOAD_OPTION_ID, WORLD_SELECTOR_REFRESH_PER_FRAME_OPTION_ID, WORLD_PLAY_DIRECTION_FORWARD_OPTION_ID, WORLD_PLAY_DIRECTION_REVERSE_OPTION_ID, WORLD_SYSTEM_CLASS_DEFINITIONS;
38081
38642
  var init_world_system_classes_generated = __esm({
38082
38643
  "../src/models/classes/world-system-classes.generated.ts"() {
38083
38644
  "use strict";
@@ -38104,9 +38665,11 @@ var init_world_system_classes_generated = __esm({
38104
38665
  WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_MEMBER_ID = "system_a5905750-c472-46a8-89e9-f04f0bf66696";
38105
38666
  WORLD_ANIMATION_FRAME_CHILD_OVERRIDES_ENTRY_MEMBER_ID = "system_86688965-6b26-529e-95f3-a4070f022582";
38106
38667
  WORLD_ANIMATION_FRAME_ACTIONS_MEMBER_ID = "system_23e05410-6428-4bd1-b085-c0390ed7fcb7";
38107
- WORLD_ANIMATION_CHILD_OVERRIDE_CHILD_MEMBER_ID = "system_6e15db41-a6f2-43fd-9793-c52fe4f3d0f8";
38668
+ WORLD_ANIMATION_CHILD_OVERRIDE_SELECTOR_MEMBER_ID = "system_48e66117-43fe-4429-97a8-964165f063ea";
38669
+ WORLD_ANIMATION_CHILD_OVERRIDE_REFRESH_MEMBER_ID = "system_ba319c4b-3419-4301-a0d6-8bc5a89e20d1";
38108
38670
  WORLD_ANIMATION_CHILD_OVERRIDE_OVERRIDES_MEMBER_ID = "system_819b3743-0c3d-4896-b679-9aeeb73255f4";
38109
- WORLD_ANIMATION_TRACK_CHILD_MEMBER_ID = "system_29abc85e-2d38-4cef-a200-88915d176d06";
38671
+ WORLD_ANIMATION_TRACK_SELECTOR_MEMBER_ID = "system_1e877396-1802-474a-9e4d-1df478d4c888";
38672
+ WORLD_ANIMATION_TRACK_REFRESH_MEMBER_ID = "system_330602f7-bbc0-4be4-9dc3-d33e9dbdbab9";
38110
38673
  WORLD_ANIMATION_TRACK_START_FRAME_MEMBER_ID = "system_5af60692-74a0-45ea-a9ba-747854989b2a";
38111
38674
  WORLD_ANIMATION_TRACK_DIRECTION_MEMBER_ID = "system_75a314b5-c799-4af6-9e64-4cde6eae1b30";
38112
38675
  WORLD_ANIMATION_TRACK_OFFSET_START_INDEX_MEMBER_ID = "system_c71caaab-df72-48c6-a291-2772288351eb";
@@ -38116,6 +38679,8 @@ var init_world_system_classes_generated = __esm({
38116
38679
  WORLD_ANIMATION_SEGMENT_FRAMES_MEMBER_ID = "system_40658ad2-b4a5-4404-bb6d-ed778088a772";
38117
38680
  WORLD_ANIMATION_SEGMENT_TRACK_CHILD_PARAM_ID = "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655";
38118
38681
  WORLD_ANIMATION_SEGMENT_TRACK_VALUE_PARAM_ID = "system_03497842-3381-45a2-b2fa-b2dee36c2759";
38682
+ WORLD_SELECTOR_REFRESH_ON_LOAD_OPTION_ID = "system_88c5d17a-b73e-47a1-a96e-4ebe16e6d200";
38683
+ WORLD_SELECTOR_REFRESH_PER_FRAME_OPTION_ID = "system_dc350ac4-de4b-4d1c-9b46-097dc5b4180f";
38119
38684
  WORLD_PLAY_DIRECTION_FORWARD_OPTION_ID = "system_2e4ca40e-f305-49c6-a91b-b99d56239ba0";
38120
38685
  WORLD_PLAY_DIRECTION_REVERSE_OPTION_ID = "system_6478d195-3905-48db-befe-d276eb5478f0";
38121
38686
  WORLD_SYSTEM_CLASS_DEFINITIONS = [
@@ -38952,8 +39517,12 @@ var init_world_system_classes_generated = __esm({
38952
39517
  isAbstract: false,
38953
39518
  constructorProjections: [
38954
39519
  {
38955
- memberId: "system_6e15db41-a6f2-43fd-9793-c52fe4f3d0f8",
38956
- parameterName: "id"
39520
+ memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
39521
+ parameterName: "selector"
39522
+ },
39523
+ {
39524
+ memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
39525
+ parameterName: "overrides"
38957
39526
  }
38958
39527
  ],
38959
39528
  genericParams: [
@@ -38965,13 +39534,26 @@ var init_world_system_classes_generated = __esm({
38965
39534
  ],
38966
39535
  schemaFields: [
38967
39536
  {
38968
- memberId: "system_6e15db41-a6f2-43fd-9793-c52fe4f3d0f8",
38969
- memberKind: "lookup",
38970
- collectionMemberId: "system_bb5d2cf1-a0dd-4eba-a62e-0e1bf0177071",
38971
- collectionValueId: null,
39537
+ memberId: "system_48e66117-43fe-4429-97a8-964165f063ea",
39538
+ memberKind: "delegate",
39539
+ returnTypeInfo: {
39540
+ type: 21,
39541
+ required: true,
39542
+ ownerClassId: "system_e2e88eba-5335-4a16-9dcf-2c0e1951e8bd",
39543
+ genericParamId: "system_de23448a-45be-4e3f-8965-072a545e08f0"
39544
+ },
39545
+ argumentTypes: [],
39546
+ required: true,
39547
+ schemaKey: "Selector"
39548
+ },
39549
+ {
39550
+ memberId: "system_ba319c4b-3419-4301-a0d6-8bc5a89e20d1",
39551
+ memberKind: "enum",
39552
+ defaultValue: ["system_88c5d17a-b73e-47a1-a96e-4ebe16e6d200"],
39553
+ enumId: "system_fb8a4243-fa52-4142-8097-765d9e86ff25",
38972
39554
  multiselect: false,
38973
39555
  required: true,
38974
- schemaKey: "Child"
39556
+ schemaKey: "Refresh"
38975
39557
  },
38976
39558
  {
38977
39559
  memberId: "system_819b3743-0c3d-4896-b679-9aeeb73255f4",
@@ -38989,15 +39571,33 @@ var init_world_system_classes_generated = __esm({
38989
39571
  name: "NeoAnimationTrackBase",
38990
39572
  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.",
38991
39573
  isAbstract: true,
39574
+ constructorProjections: [
39575
+ {
39576
+ memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
39577
+ parameterName: "selector"
39578
+ }
39579
+ ],
38992
39580
  schemaFields: [
38993
39581
  {
38994
- memberId: "system_29abc85e-2d38-4cef-a200-88915d176d06",
38995
- memberKind: "lookup",
38996
- collectionMemberId: "system_bb5d2cf1-a0dd-4eba-a62e-0e1bf0177071",
38997
- collectionValueId: null,
39582
+ memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
39583
+ memberKind: "delegate",
39584
+ returnTypeInfo: {
39585
+ type: 7,
39586
+ required: true,
39587
+ classId: "system_61b30a92-90dc-4bf8-8503-ee4f6414effc"
39588
+ },
39589
+ argumentTypes: [],
39590
+ required: true,
39591
+ schemaKey: "Selector"
39592
+ },
39593
+ {
39594
+ memberId: "system_330602f7-bbc0-4be4-9dc3-d33e9dbdbab9",
39595
+ memberKind: "enum",
39596
+ defaultValue: ["system_88c5d17a-b73e-47a1-a96e-4ebe16e6d200"],
39597
+ enumId: "system_fb8a4243-fa52-4142-8097-765d9e86ff25",
38998
39598
  multiselect: false,
38999
39599
  required: true,
39000
- schemaKey: "Child"
39600
+ schemaKey: "Refresh"
39001
39601
  },
39002
39602
  {
39003
39603
  memberId: "system_5af60692-74a0-45ea-a9ba-747854989b2a",
@@ -39056,8 +39656,12 @@ var init_world_system_classes_generated = __esm({
39056
39656
  isAbstract: false,
39057
39657
  constructorProjections: [
39058
39658
  {
39059
- memberId: "system_29abc85e-2d38-4cef-a200-88915d176d06",
39060
- parameterName: "id"
39659
+ memberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
39660
+ parameterName: "selector"
39661
+ },
39662
+ {
39663
+ memberId: "system_2c816624-0281-46d3-9ed5-d20bd43519f4",
39664
+ parameterName: "clipKey"
39061
39665
  }
39062
39666
  ],
39063
39667
  schemaFields: [
@@ -39079,8 +39683,8 @@ var init_world_system_classes_generated = __esm({
39079
39683
  isAbstract: true,
39080
39684
  constructorProjections: [
39081
39685
  {
39082
- memberId: "system_87900a74-0d7c-4dfc-a6f6-3bd204ebb8f6",
39083
- parameterName: "id"
39686
+ memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
39687
+ parameterName: "selector"
39084
39688
  }
39085
39689
  ],
39086
39690
  genericParams: [
@@ -39093,21 +39697,19 @@ var init_world_system_classes_generated = __esm({
39093
39697
  ],
39094
39698
  schemaFields: [
39095
39699
  {
39096
- memberId: "system_87900a74-0d7c-4dfc-a6f6-3bd204ebb8f6",
39097
- memberKind: "lookup",
39098
- extendsMemberId: "system_29abc85e-2d38-4cef-a200-88915d176d06",
39700
+ memberId: "system_b29e7ab9-0b8e-4399-84c1-1203070b75dd",
39701
+ memberKind: "delegate",
39702
+ extendsMemberId: "system_1e877396-1802-474a-9e4d-1df478d4c888",
39099
39703
  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.",
39100
- collectionMemberId: "system_bb5d2cf1-a0dd-4eba-a62e-0e1bf0177071",
39101
- collectionValueId: null,
39102
- multiselect: false,
39103
- declaredTypeInfo: {
39704
+ returnTypeInfo: {
39104
39705
  type: 21,
39105
39706
  required: true,
39106
39707
  ownerClassId: "system_fd551dd8-6e6b-4044-9f32-7445ab344200",
39107
39708
  genericParamId: "system_d4fe9f71-d9d9-4baf-bc52-8de16933b655"
39108
39709
  },
39710
+ argumentTypes: [],
39109
39711
  required: true,
39110
- schemaKey: "Child"
39712
+ schemaKey: "Selector"
39111
39713
  },
39112
39714
  {
39113
39715
  memberId: "system_d2d0bf9b-211f-4b2f-bff3-3d6da5766abd",
@@ -39756,6 +40358,7 @@ var init_generics = __esm({
39756
40358
  13 /* Function */,
39757
40359
  23 /* NSFunction */,
39758
40360
  24 /* FunctionRef */,
40361
+ 25 /* NSDelegate */,
39759
40362
  21 /* Generic */
39760
40363
  ]);
39761
40364
  }
@@ -41958,6 +42561,13 @@ function primitiveFallbackValue(document, member) {
41958
42561
  if (isMemberAudioBase(member)) {
41959
42562
  return { value: pendingAudioValue() };
41960
42563
  }
42564
+ if (member.kind === 25 /* NSDelegate */) {
42565
+ return {
42566
+ value: {
42567
+ code: '() => { throw "Not implemented exception"; }'
42568
+ }
42569
+ };
42570
+ }
41961
42571
  if (member.kind === 21 /* Generic */) {
41962
42572
  throw new Error(
41963
42573
  `Unreachable: Generic member "${member.name}" must be substituted through its binding environment before default value construction \u2014 a substitution site was skipped upstream (https://github.com/ryanbliss/neo-compose-specs/tree/main/new-features/complete/class-generics.md \xA74.1).`
@@ -43540,6 +44150,23 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
43540
44150
  }
43541
44151
  return { ...common, kind: "functionRef" };
43542
44152
  }
44153
+ if (name === "NeoDelegate") {
44154
+ if (partial) {
44155
+ throw new Error("Partial<T> requires a Class or Class generic target.");
44156
+ }
44157
+ const returnType = requiredTypeArgument(fieldType, 0);
44158
+ return {
44159
+ ...common,
44160
+ kind: "delegate",
44161
+ returnType: returnType.name === "void" ? { kind: "void", nullable: false } : lowerType(context, returnType, ownerClass),
44162
+ arguments: fieldType.arguments.slice(1).map((argumentType, index) => ({
44163
+ name: `p${index + 1}`,
44164
+ type: lowerType(context, argumentType, ownerClass),
44165
+ source: span(declaration),
44166
+ selectionSpan: span(declaration)
44167
+ }))
44168
+ };
44169
+ }
43543
44170
  if (name === "bool" || name === "null") {
43544
44171
  return { ...common, kind: name };
43545
44172
  }
@@ -44111,6 +44738,18 @@ function lowerType(context, type, ownerClass) {
44111
44738
  readOnly: false
44112
44739
  };
44113
44740
  }
44741
+ if (type.name === "Partial") {
44742
+ return lowerType(context, requiredTypeArgument(type, 0), ownerClass);
44743
+ }
44744
+ if (type.name === "NeoDelegate") {
44745
+ const returnType = requiredTypeArgument(type, 0);
44746
+ return {
44747
+ kind: "delegate",
44748
+ nullable,
44749
+ returnType: returnType.name === "void" ? { kind: "void", nullable: false } : lowerType(context, returnType, ownerClass),
44750
+ argumentTypes: type.arguments.slice(1).map((argument2) => lowerType(context, argument2, ownerClass))
44751
+ };
44752
+ }
44114
44753
  const classId = context.classIdsByName.get(type.name);
44115
44754
  if (classId) {
44116
44755
  const parameters = context.genericParametersByClass.get(classId);
@@ -44154,7 +44793,7 @@ function lowerDefault(context, initializer, type, ownerClass, base, memberId, st
44154
44793
  return base?.defaultValue && "serverValueId" in base.defaultValue ? base.defaultValue : null;
44155
44794
  }
44156
44795
  const expression = parseExpression(initializer);
44157
- if (initializerRequiresEvaluation(
44796
+ if (!isStoredDelegateLiteral(type, expression) && initializerRequiresEvaluation(
44158
44797
  context.declaredConstructors,
44159
44798
  expression,
44160
44799
  type.name,
@@ -44168,7 +44807,15 @@ function lowerDefault(context, initializer, type, ownerClass, base, memberId, st
44168
44807
  if (context.rowBackedDefaultMemberIds.has(memberId) && base?.defaultValue && !("serverValueId" in base.defaultValue)) {
44169
44808
  return base.defaultValue;
44170
44809
  }
44171
- let value = lowerExpressionValue(context, expression, type, ownerClass, path);
44810
+ let value = lowerExpressionValue(
44811
+ context,
44812
+ expression,
44813
+ type,
44814
+ ownerClass,
44815
+ path,
44816
+ EMPTY_GENERIC_TYPE_ENVIRONMENT,
44817
+ initializer
44818
+ );
44172
44819
  if (value !== null && storesSelectionArray && !Array.isArray(value)) {
44173
44820
  value = [value];
44174
44821
  }
@@ -44215,12 +44862,12 @@ function manifestTypeFromAstType(type) {
44215
44862
  arguments: (type.typeArguments ?? []).map(manifestTypeFromAstType)
44216
44863
  };
44217
44864
  }
44218
- function lowerExpressionValue(context, expression, declaredExpected, ownerClass, path, genericEnvironment = EMPTY_GENERIC_TYPE_ENVIRONMENT) {
44865
+ function lowerExpressionValue(context, expression, declaredExpected, ownerClass, path, genericEnvironment = EMPTY_GENERIC_TYPE_ENVIRONMENT, sourceText) {
44219
44866
  const expected = substituteGenericTypeNames(
44220
44867
  declaredExpected,
44221
44868
  genericEnvironment
44222
44869
  );
44223
- if (initializerRequiresEvaluation(
44870
+ if (!isStoredDelegateLiteral(expected, expression) && initializerRequiresEvaluation(
44224
44871
  context.declaredConstructors,
44225
44872
  expression,
44226
44873
  expected.name,
@@ -44238,7 +44885,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44238
44885
  expected,
44239
44886
  ownerClass,
44240
44887
  path,
44241
- genericEnvironment
44888
+ genericEnvironment,
44889
+ sourceText
44242
44890
  );
44243
44891
  }
44244
44892
  switch (expression.kind) {
@@ -44263,7 +44911,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44263
44911
  expected,
44264
44912
  ownerClass,
44265
44913
  path,
44266
- genericEnvironment
44914
+ genericEnvironment,
44915
+ sourceText
44267
44916
  );
44268
44917
  if (typeof operand === "number") return -operand;
44269
44918
  if (expected.name === "decimal" && typeof operand === "string") {
@@ -44293,7 +44942,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44293
44942
  entry,
44294
44943
  ownerClass,
44295
44944
  `${path}[${index}]`,
44296
- genericEnvironment
44945
+ genericEnvironment,
44946
+ sourceText
44297
44947
  )
44298
44948
  );
44299
44949
  }
@@ -44307,7 +44957,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44307
44957
  { name: "string", nullable: false, arguments: [] },
44308
44958
  ownerClass,
44309
44959
  path,
44310
- genericEnvironment
44960
+ genericEnvironment,
44961
+ sourceText
44311
44962
  );
44312
44963
  if (typeof key !== "string")
44313
44964
  throw new Error("Dictionary keys must be strings.");
@@ -44317,7 +44968,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44317
44968
  valueType,
44318
44969
  ownerClass,
44319
44970
  `${path}[${JSON.stringify(key)}]`,
44320
- genericEnvironment
44971
+ genericEnvironment,
44972
+ sourceText
44321
44973
  );
44322
44974
  }
44323
44975
  return value;
@@ -44386,11 +45038,24 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44386
45038
  structuredLeafAssignmentType(partialExpected, declaredType),
44387
45039
  ownerClass,
44388
45040
  `${path}.${assignment.name}`,
44389
- innerEnvironment
45041
+ innerEnvironment,
45042
+ sourceText
44390
45043
  );
44391
45044
  }
44392
45045
  return result;
44393
45046
  }
45047
+ case "lambda": {
45048
+ if (expected.name !== "NeoDelegate") {
45049
+ throw new Error(
45050
+ `A lambda at ${path} requires a NeoDelegate expected type.`
45051
+ );
45052
+ }
45053
+ const code = sourceText === void 0 ? null : lambdaExpressionSource(sourceText, expression.pos);
45054
+ if (code === null || code.length === 0) {
45055
+ throw new Error(`Delegate value ${path} has no recoverable source.`);
45056
+ }
45057
+ return { code: normalizeInitializerSource(code) };
45058
+ }
44394
45059
  case "call": {
44395
45060
  if (expression.callee.kind === "ident" && expression.callee.name === "Reference") {
44396
45061
  const index = expression.argumentNames?.findIndex((name) => name === "id") ?? -1;
@@ -44460,6 +45125,56 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
44460
45125
  );
44461
45126
  }
44462
45127
  }
45128
+ function isStoredDelegateLiteral(type, expression) {
45129
+ if (type.name !== "NeoDelegate") return false;
45130
+ let current = expression;
45131
+ while (current.kind === "annotated") current = current.expression;
45132
+ return current.kind === "lambda";
45133
+ }
45134
+ function lambdaExpressionSource(source, pos) {
45135
+ let start = 0;
45136
+ for (let line = 1; line < pos.line; line += 1) {
45137
+ const next = source.indexOf("\n", start);
45138
+ if (next < 0) return null;
45139
+ start = next + 1;
45140
+ }
45141
+ start = Math.min(start + pos.column - 1, source.length);
45142
+ const arrow = source.indexOf("=>", start);
45143
+ if (arrow < 0) return null;
45144
+ const bodyStart = source.indexOf("{", arrow + 2);
45145
+ if (bodyStart < 0) return null;
45146
+ let depth = 0;
45147
+ let quote6 = null;
45148
+ let escaped = false;
45149
+ for (let index = bodyStart; index < source.length; index += 1) {
45150
+ const character = source[index];
45151
+ if (quote6 !== null) {
45152
+ if (escaped) escaped = false;
45153
+ else if (character === "\\") escaped = true;
45154
+ else if (character === quote6) quote6 = null;
45155
+ continue;
45156
+ }
45157
+ if (character === '"' || character === "'") {
45158
+ quote6 = character;
45159
+ continue;
45160
+ }
45161
+ if (character === "/" && source[index + 1] === "/") {
45162
+ const newline = source.indexOf("\n", index + 2);
45163
+ index = newline < 0 ? source.length : newline;
45164
+ continue;
45165
+ }
45166
+ if (character === "/" && source[index + 1] === "*") {
45167
+ const close = source.indexOf("*/", index + 2);
45168
+ index = close < 0 ? source.length : close + 1;
45169
+ continue;
45170
+ }
45171
+ if (character === "{") depth += 1;
45172
+ if (character !== "}") continue;
45173
+ depth -= 1;
45174
+ if (depth === 0) return source.slice(start, index + 1).trim();
45175
+ }
45176
+ return null;
45177
+ }
44463
45178
  function lowerStructuredLeafDefault(context, kind, expression, expectedType, ownerClass, partialExpected, path) {
44464
45179
  const label = `${structuredLeafLabel(kind, path)} default`;
44465
45180
  const partial = structuredLeafPartialLiteral(expression);
@@ -44586,6 +45301,18 @@ function manifestTypeForMember(context, member) {
44586
45301
  if (member.kind === "functionRef") {
44587
45302
  return { name: "FunctionRef", nullable, arguments: [] };
44588
45303
  }
45304
+ if (member.kind === "delegate") {
45305
+ return {
45306
+ name: "NeoDelegate",
45307
+ nullable,
45308
+ arguments: [
45309
+ member.returnType.kind === "void" ? { name: "void", nullable: false, arguments: [] } : manifestTypeForSchemaType(context, member.returnType),
45310
+ ...member.arguments.map(
45311
+ (argument2) => manifestTypeForSchemaType(context, argument2.type)
45312
+ )
45313
+ ]
45314
+ };
45315
+ }
44589
45316
  if (member.kind === "enum") {
44590
45317
  return {
44591
45318
  name: context.baseEnums.get(member.enumId)?.name ?? "object",
@@ -44595,6 +45322,99 @@ function manifestTypeForMember(context, member) {
44595
45322
  }
44596
45323
  return { name: "object", nullable, arguments: [] };
44597
45324
  }
45325
+ function manifestTypeForSchemaType(context, type) {
45326
+ const nullable = type.nullable;
45327
+ switch (type.kind) {
45328
+ case "unknown":
45329
+ return { name: "object", nullable, arguments: [] };
45330
+ case "null":
45331
+ case "bool":
45332
+ case "int":
45333
+ case "string":
45334
+ case "float":
45335
+ case "decimal":
45336
+ return { name: type.kind, nullable, arguments: [] };
45337
+ case "sprite":
45338
+ return { name: "SpriteInfo", nullable, arguments: [] };
45339
+ case "audio":
45340
+ return { name: "AudioClipInfo", nullable, arguments: [] };
45341
+ case "vector2":
45342
+ return { name: "Vector2", nullable, arguments: [] };
45343
+ case "vector2Int":
45344
+ return { name: "Vector2Int", nullable, arguments: [] };
45345
+ case "vector3":
45346
+ return { name: "Vector3", nullable, arguments: [] };
45347
+ case "vector3Int":
45348
+ return { name: "Vector3Int", nullable, arguments: [] };
45349
+ case "dialogueLookup":
45350
+ return { name: "Dialogue", nullable, arguments: [] };
45351
+ case "color":
45352
+ return { name: "Color", nullable, arguments: [] };
45353
+ case "class": {
45354
+ const schemaClass2 = context.baseClasses.get(type.classId);
45355
+ return {
45356
+ name: schemaClass2?.name ?? "object",
45357
+ nullable,
45358
+ arguments: schemaClass2?.genericParameters.map((parameter3) => type.classArguments[parameter3.id]).filter(
45359
+ (argument2) => argument2 !== void 0
45360
+ ).map((argument2) => manifestTypeForSchemaType(context, argument2)) ?? []
45361
+ };
45362
+ }
45363
+ case "interface":
45364
+ return {
45365
+ name: context.baseInterfaces.get(type.interfaceId)?.name ?? "object",
45366
+ nullable,
45367
+ arguments: []
45368
+ };
45369
+ case "generic":
45370
+ return {
45371
+ name: genericParameterName(context, type.genericParamId),
45372
+ nullable,
45373
+ arguments: []
45374
+ };
45375
+ case "enum":
45376
+ return {
45377
+ name: context.baseEnums.get(type.enumId)?.name ?? "object",
45378
+ nullable,
45379
+ arguments: []
45380
+ };
45381
+ case "list":
45382
+ return {
45383
+ name: "List",
45384
+ nullable,
45385
+ arguments: [manifestTypeForSchemaType(context, type.entryType)]
45386
+ };
45387
+ case "dictionary":
45388
+ return {
45389
+ name: "Dictionary",
45390
+ nullable,
45391
+ arguments: [
45392
+ type.keyEnumId === null ? { name: "string", nullable: false, arguments: [] } : {
45393
+ name: context.baseEnums.get(type.keyEnumId)?.name ?? "object",
45394
+ nullable: false,
45395
+ arguments: []
45396
+ },
45397
+ manifestTypeForSchemaType(context, type.entryType)
45398
+ ]
45399
+ };
45400
+ case "lookup":
45401
+ return manifestTypeForSchemaType(context, {
45402
+ ...type.entryType,
45403
+ nullable
45404
+ });
45405
+ case "delegate":
45406
+ return {
45407
+ name: "NeoDelegate",
45408
+ nullable,
45409
+ arguments: [
45410
+ type.returnType.kind === "void" ? { name: "void", nullable: false, arguments: [] } : manifestTypeForSchemaType(context, type.returnType),
45411
+ ...type.argumentTypes.map(
45412
+ (argument2) => manifestTypeForSchemaType(context, argument2)
45413
+ )
45414
+ ]
45415
+ };
45416
+ }
45417
+ }
44598
45418
  function genericParameterName(context, genericParamId) {
44599
45419
  for (const parameters of context.genericParametersByClass.values()) {
44600
45420
  for (const [name, id2] of parameters) {
@@ -46466,6 +47286,14 @@ function renderMemberType(context, member, enclosingClassId) {
46466
47286
  case "functionRef":
46467
47287
  value = "FunctionRef";
46468
47288
  break;
47289
+ case "delegate":
47290
+ value = `NeoDelegate<${[
47291
+ renderReturnType(context, member.returnType),
47292
+ ...member.arguments.map(
47293
+ (argument2) => renderType(context, argument2.type)
47294
+ )
47295
+ ].join(", ")}>`;
47296
+ break;
46469
47297
  }
46470
47298
  if ((member.kind === "class" || member.kind === "generic") && member.partial === true) {
46471
47299
  value = `Partial<${value}>`;
@@ -46553,6 +47381,12 @@ function renderType(context, type) {
46553
47381
  case "lookup":
46554
47382
  value = renderType(context, type.entryType);
46555
47383
  break;
47384
+ case "delegate":
47385
+ value = `NeoDelegate<${[
47386
+ renderReturnType(context, type.returnType),
47387
+ ...type.argumentTypes.map((argument2) => renderType(context, argument2))
47388
+ ].join(", ")}>`;
47389
+ break;
46556
47390
  }
46557
47391
  return type.nullable && value !== "null" ? `${value}?` : value;
46558
47392
  }
@@ -52246,6 +53080,16 @@ function objectInitializerSlices(authoredSlice) {
52246
53080
  }
52247
53081
  return assignments;
52248
53082
  }
53083
+ function constructorArgumentValueSlices(authoredSlice) {
53084
+ const expression = initializerExpressionSlice(authoredSlice);
53085
+ if (expression === void 0) return [];
53086
+ return topLevelEntrySlices(expression, "(", ")").map((entry) => {
53087
+ const separator = entry.indexOf(":");
53088
+ return normalizeInitializerSource(
53089
+ separator < 0 ? entry : entry.slice(separator + 1)
53090
+ );
53091
+ });
53092
+ }
52249
53093
  function initializerExpressionSlice(authoredSlice) {
52250
53094
  if (authoredSlice === void 0) return void 0;
52251
53095
  let text = normalizeInitializerSource(authoredSlice);
@@ -52335,7 +53179,8 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
52335
53179
  baseBody,
52336
53180
  body,
52337
53181
  binding,
52338
- environment
53182
+ environment,
53183
+ binding.initializer
52339
53184
  );
52340
53185
  for (const assignment of expression.initializer ?? []) {
52341
53186
  const childMember = classMemberByName(context, classId, assignment.name);
@@ -52609,7 +53454,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
52609
53454
  member,
52610
53455
  inheritedEnvironment
52611
53456
  );
52612
- if (initializerRequiresEvaluation(
53457
+ if (resolvedMember.kind !== "delegate" && initializerRequiresEvaluation(
52613
53458
  context.declaredConstructors,
52614
53459
  expression,
52615
53460
  memberClassName(context, resolvedMember),
@@ -52683,10 +53528,12 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
52683
53528
  path
52684
53529
  );
52685
53530
  const body = {};
53531
+ const argumentSlices = constructorArgumentValueSlices(authoredSlice);
52686
53532
  for (const {
52687
53533
  projectedMember,
52688
53534
  schemaKey,
52689
- target
53535
+ argument: argument2,
53536
+ argumentIndex
52690
53537
  } of resolveConstructorProjectionArguments(
52691
53538
  context,
52692
53539
  effectiveClass,
@@ -52700,18 +53547,39 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
52700
53547
  if (rows.has(childValueId)) {
52701
53548
  throw new Error(`Value construction reuses identity ${childValueId}.`);
52702
53549
  }
52703
- const projectionStamp = materializedRowStamp(
53550
+ if (projectedMember.kind === "lookup") {
53551
+ if (argument2.kind !== "litString") {
53552
+ throw new Error(
53553
+ `Class value ${path}.${schemaKey} requires a value-row id string literal.`
53554
+ );
53555
+ }
53556
+ const projectionStamp = materializedRowStamp(
53557
+ context,
53558
+ materializedChild(context, materialization, schemaKey)
53559
+ );
53560
+ rows.set(childValueId, {
53561
+ id: childValueId,
53562
+ memberId: projectedMember.id,
53563
+ value: [argument2.value],
53564
+ classId: null,
53565
+ ...projectionStamp === null ? {} : { sourceValueId: projectionStamp }
53566
+ });
53567
+ body[schemaKey] = childValueId;
53568
+ continue;
53569
+ }
53570
+ body[schemaKey] = lowerSeedChild(
52704
53571
  context,
52705
- materializedChild(context, materialization, schemaKey)
53572
+ projectedMember,
53573
+ argument2,
53574
+ source,
53575
+ childPath,
53576
+ rows,
53577
+ localizedTexts,
53578
+ void 0,
53579
+ environment,
53580
+ materializedChild(context, materialization, schemaKey),
53581
+ argumentSlices[argumentIndex]
52706
53582
  );
52707
- rows.set(childValueId, {
52708
- id: childValueId,
52709
- memberId: projectedMember.id,
52710
- value: [target.id],
52711
- classId: null,
52712
- ...projectionStamp === null ? {} : { sourceValueId: projectionStamp }
52713
- });
52714
- body[schemaKey] = childValueId;
52715
53583
  }
52716
53584
  for (const assignment of expression.initializer ?? []) {
52717
53585
  const childMember = classMemberByName(
@@ -52836,7 +53704,8 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
52836
53704
  expression,
52837
53705
  { id: valueId, value: null },
52838
53706
  source,
52839
- inheritedEnvironment
53707
+ inheritedEnvironment,
53708
+ authoredSlice
52840
53709
  );
52841
53710
  value = lowered.value;
52842
53711
  classId = typeof lowered.classId === "string" ? lowered.classId : null;
@@ -52993,7 +53862,7 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
52993
53862
  member,
52994
53863
  environment
52995
53864
  );
52996
- if (initializerRequiresEvaluation(
53865
+ if (resolvedMember.kind !== "delegate" && initializerRequiresEvaluation(
52997
53866
  context.declaredConstructors,
52998
53867
  expression,
52999
53868
  memberClassName(context, resolvedMember),
@@ -53083,6 +53952,16 @@ function lowerValueBody(context, member, expression, base, source, environment,
53083
53952
  ...next,
53084
53953
  value: lowerFunctionReference(context, expression, source.ownerClassId)
53085
53954
  };
53955
+ case "delegate":
53956
+ return {
53957
+ ...next,
53958
+ value: lowerDelegateValue(
53959
+ context,
53960
+ expression,
53961
+ source.ownerClassId,
53962
+ authoredSlice
53963
+ )
53964
+ };
53086
53965
  case "class":
53087
53966
  return lowerClassValue(
53088
53967
  context,
@@ -53164,7 +54043,8 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
53164
54043
  baseBody,
53165
54044
  body,
53166
54045
  source,
53167
- environment
54046
+ environment,
54047
+ authoredSlice
53168
54048
  );
53169
54049
  for (const assignment of expression.initializer ?? []) {
53170
54050
  const childMember = classMemberByName(context, classId, assignment.name);
@@ -53224,7 +54104,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
53224
54104
  ...classId === currentClassId ? {} : { classId }
53225
54105
  };
53226
54106
  }
53227
- function lowerConstructorProjections(context, schemaClass2, expression, base, baseBody, body, source, environment) {
54107
+ function lowerConstructorProjections(context, schemaClass2, expression, base, baseBody, body, source, environment, authoredSlice) {
53228
54108
  const resolved = resolveConstructorProjectionArguments(
53229
54109
  context,
53230
54110
  schemaClass2,
@@ -53233,20 +54113,44 @@ function lowerConstructorProjections(context, schemaClass2, expression, base, ba
53233
54113
  environment,
53234
54114
  source
53235
54115
  );
53236
- for (const { schemaKey, target } of resolved) {
54116
+ const argumentSlices = constructorArgumentValueSlices(authoredSlice);
54117
+ for (const {
54118
+ schemaKey,
54119
+ projectedMember,
54120
+ argument: argument2,
54121
+ argumentIndex
54122
+ } of resolved) {
53237
54123
  const childValueId = baseBody[schemaKey];
53238
54124
  if (typeof childValueId !== "string") {
53239
54125
  throw new Error(
53240
54126
  `Class value ${String(base.id)}.${schemaKey} has no existing structural row.`
53241
54127
  );
53242
54128
  }
53243
- const projectedBase = valueBase(context, childValueId);
53244
- addReconstructed(
54129
+ if (projectedMember.kind === "lookup") {
54130
+ if (argument2.kind !== "litString") {
54131
+ throw new Error(
54132
+ `Class value ${String(base.id)}.${schemaKey} requires a value-row id string literal.`
54133
+ );
54134
+ }
54135
+ const projectedBase = valueBase(context, childValueId);
54136
+ addReconstructed(
54137
+ context,
54138
+ "value",
54139
+ childValueId,
54140
+ { ...valueFileFields(projectedBase), value: [argument2.value] },
54141
+ source.source
54142
+ );
54143
+ body[schemaKey] = childValueId;
54144
+ continue;
54145
+ }
54146
+ lowerValueRow(
53245
54147
  context,
53246
- "value",
54148
+ projectedMember,
54149
+ argument2,
53247
54150
  childValueId,
53248
- { ...valueFileFields(projectedBase), value: [target.id] },
53249
- source.source
54151
+ source,
54152
+ environment,
54153
+ argumentSlices[argumentIndex]
53250
54154
  );
53251
54155
  body[schemaKey] = childValueId;
53252
54156
  }
@@ -53350,14 +54254,6 @@ function resolveConstructorProjectionArguments(context, schemaClass2, expression
53350
54254
  });
53351
54255
  continue;
53352
54256
  }
53353
- if (argument2.kind !== "litString") {
53354
- context.loweringFailures.push({
53355
- message: `Constructor '${signature}' parameter '${parameterName}' projects a row identity, so its argument must be a value-row id string literal.`,
53356
- code: "non-literal-constructor-argument",
53357
- site: referenceSite(source, argument2)
53358
- });
53359
- continue;
53360
- }
53361
54257
  const schemaKey = inheritedProjectionSchemaKey(
53362
54258
  context.classes,
53363
54259
  schemaClass2.id,
@@ -53372,29 +54268,40 @@ function resolveConstructorProjectionArguments(context, schemaClass2, expression
53372
54268
  continue;
53373
54269
  }
53374
54270
  const projectedMember = context.members.get(projection.memberId);
53375
- if (projectedMember?.kind !== "lookup") {
54271
+ if (projectedMember === void 0) {
53376
54272
  context.loweringFailures.push({
53377
- message: `Constructor '${signature}' parameter '${parameterName}' projects member ${projection.memberId}, which is ${projectedMember === void 0 ? "in no member of this project" : `a ${projectedMember.kind} member`} and not the Lookup field a projection writes.`,
54273
+ message: `Constructor '${signature}' parameter '${parameterName}' projects member ${projection.memberId}, which is not present in this project.`,
53378
54274
  code: "unprojectable-constructor-argument",
53379
54275
  site: referenceSite(source, argument2)
53380
54276
  });
53381
54277
  continue;
53382
54278
  }
53383
- context.referenceObligations.push({
53384
- kind: "constructorProjection",
53385
- site: referenceSite(source, argument2),
53386
- schemaClassId: schemaClass2.id,
53387
- parameterName,
53388
- projectedMemberId: projectedMember.id,
53389
- targetId: argument2.value,
53390
- ownerValueId,
53391
- environment
53392
- });
54279
+ if (projectedMember.kind === "lookup") {
54280
+ if (argument2.kind !== "litString") {
54281
+ context.loweringFailures.push({
54282
+ message: `Constructor '${signature}' parameter '${parameterName}' projects a row identity, so its argument must be a value-row id string literal.`,
54283
+ code: "non-literal-constructor-argument",
54284
+ site: referenceSite(source, argument2)
54285
+ });
54286
+ continue;
54287
+ }
54288
+ context.referenceObligations.push({
54289
+ kind: "constructorProjection",
54290
+ site: referenceSite(source, argument2),
54291
+ schemaClassId: schemaClass2.id,
54292
+ parameterName,
54293
+ projectedMemberId: projectedMember.id,
54294
+ targetId: argument2.value,
54295
+ ownerValueId,
54296
+ environment
54297
+ });
54298
+ }
53393
54299
  resolved.push({
53394
54300
  parameterName,
53395
54301
  projectedMember,
53396
54302
  schemaKey,
53397
- target: { id: argument2.value, kind: "value" }
54303
+ argument: argument2,
54304
+ argumentIndex: index
53398
54305
  });
53399
54306
  }
53400
54307
  return resolved;
@@ -53447,13 +54354,24 @@ function inferAnimationChildOverrideLowerEnvironment(context, schemaClass2, expr
53447
54354
  );
53448
54355
  const argument2 = argumentIndex === void 0 || argumentIndex < 0 ? void 0 : expression.args[argumentIndex];
53449
54356
  const target = argument2?.kind === "litString" ? valueData(context, argument2.value) : null;
53450
- const targetClassId = target && typeof target.classId === "string" ? target.classId : null;
54357
+ const targetClassId = target && typeof target.classId === "string" ? target.classId : selectorReferenceReturnClassId(context, argument2);
53451
54358
  if (targetClassId === null) return inherited;
53452
54359
  return new Map(inherited).set(
53453
54360
  parameter3.id,
53454
54361
  inferredGenericClassBinding(targetClassId)
53455
54362
  );
53456
54363
  }
54364
+ function selectorReferenceReturnClassId(context, expression) {
54365
+ if (expression?.kind !== "lambda") return null;
54366
+ const returned = expression.body.find(
54367
+ (statement) => statement.kind === "return" && statement.expr !== null
54368
+ )?.expr;
54369
+ if (returned?.kind !== "call" || returned.callee.kind !== "ident" || returned.callee.name !== "Reference" || returned.typeArguments?.length !== 1) {
54370
+ return null;
54371
+ }
54372
+ const className = astTypeNameV4(returned.typeArguments[0]);
54373
+ return className === null ? null : context.classesByName.get(className)?.id ?? null;
54374
+ }
53457
54375
  function animationChildOverrideSeedBindings(context, schemaClass2, environment, source, path) {
53458
54376
  if (schemaClass2.system?.worldKind !== "animationChildOverride") {
53459
54377
  return void 0;
@@ -54661,6 +55579,36 @@ function lowerFunctionReference(context, expression, ownerClassId) {
54661
55579
  }
54662
55580
  return { functionMemberId: target.id };
54663
55581
  }
55582
+ function lowerDelegateValue(context, expression, ownerClassId, authoredSlice) {
55583
+ if (expression.kind === "lambda") {
55584
+ const code = initializerExpressionSlice(authoredSlice);
55585
+ if (code === void 0) {
55586
+ throw new Error(
55587
+ "Delegate lambdas require recoverable authored source so the server can compile their closure."
55588
+ );
55589
+ }
55590
+ return { code };
55591
+ }
55592
+ const path = memberPath(expression);
55593
+ const symbol = path?.startsWith("this.") ? path.slice("this.".length) : path;
55594
+ if (symbol === null || symbol === void 0 || symbol.includes(".")) {
55595
+ throw new Error(
55596
+ "Delegate method groups require a function, NSFunction, or NSDelegate member on the current Class."
55597
+ );
55598
+ }
55599
+ if (ownerClassId === void 0) {
55600
+ throw new Error(
55601
+ `Delegate ${symbol} cannot be resolved without its owning Class.`
55602
+ );
55603
+ }
55604
+ const target = classMemberByName(context, ownerClassId, symbol);
55605
+ if (target.kind !== "function" && target.kind !== "scriptFunction" && target.kind !== "delegate") {
55606
+ throw new Error(
55607
+ `Delegate ${symbol} does not resolve to a function, NSFunction, or NSDelegate member.`
55608
+ );
55609
+ }
55610
+ return { memberId: target.id, valueId: null };
55611
+ }
54664
55612
  function fileTargetId(context, expression, registry) {
54665
55613
  const path = memberPath(expression);
54666
55614
  if (path !== null) {
@@ -54840,6 +55788,7 @@ function emitValueBody(context, member, value, visited, targetTyped, environment
54840
55788
  if (kind === 9) return referenceValue(context, member, body, false);
54841
55789
  if (kind === 18) return referenceValue(context, member, body, true);
54842
55790
  if (kind === 24) return functionReferenceValue(context, body);
55791
+ if (kind === 25) return delegateValue(context, body);
54843
55792
  if (kind === 12) {
54844
55793
  return fileValue(
54845
55794
  context,
@@ -54882,7 +55831,8 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
54882
55831
  context,
54883
55832
  classId,
54884
55833
  value.value,
54885
- visited
55834
+ visited,
55835
+ storedEnvironment
54886
55836
  );
54887
55837
  const environment = inferAnimationChildOverrideEmitEnvironment(
54888
55838
  context,
@@ -54983,7 +55933,7 @@ function manifestMemberTypeName(context, member) {
54983
55933
  }
54984
55934
  return fixedSourceTypeNameForKind(member.kind) ?? member.kind;
54985
55935
  }
54986
- function constructorProjectionSource(context, classId, body, visited) {
55936
+ function constructorProjectionSource(context, classId, body, visited, environment) {
54987
55937
  const projections = inheritedConstructorProjections(
54988
55938
  context.manifestClasses,
54989
55939
  classId
@@ -54999,18 +55949,42 @@ function constructorProjectionSource(context, classId, body, visited) {
54999
55949
  );
55000
55950
  const childValueId = schemaKey === null ? void 0 : body[schemaKey];
55001
55951
  const childValue = typeof childValueId === "string" ? context.values.get(childValueId) : void 0;
55002
- const targetIds = Array.isArray(childValue?.value) ? childValue.value.filter(
55003
- (entry) => typeof entry === "string"
55004
- ) : [];
55005
- if (schemaKey === null || typeof childValueId !== "string" || targetIds.length !== 1) {
55952
+ const projectedMember = context.members.get(projection.memberId);
55953
+ if (schemaKey === null || typeof childValueId !== "string" || childValue === void 0 || projectedMember === void 0) {
55006
55954
  throw new Error(
55007
- `Class ${context.manifestClasses.get(classId)?.name ?? classId} constructor projection ${projection.parameterName} requires exactly one referenced value.`
55955
+ `Class ${context.manifestClasses.get(classId)?.name ?? classId} constructor projection ${projection.parameterName} has no stored projected value.`
55008
55956
  );
55009
55957
  }
55010
- visited.add(childValueId);
55011
55958
  memberIds.add(projection.memberId);
55012
- targetValueIds.push(targetIds[0]);
55013
- argumentsValue.push(`${projection.parameterName}: ${quote4(targetIds[0])}`);
55959
+ if (numberField(projectedMember, "kind") === 9) {
55960
+ const targetIds = Array.isArray(childValue.value) ? childValue.value.filter(
55961
+ (entry) => typeof entry === "string"
55962
+ ) : [];
55963
+ if (targetIds.length !== 1) {
55964
+ throw new Error(
55965
+ `Class ${context.manifestClasses.get(classId)?.name ?? classId} constructor projection ${projection.parameterName} requires exactly one referenced value.`
55966
+ );
55967
+ }
55968
+ visited.add(childValueId);
55969
+ targetValueIds.push(targetIds[0]);
55970
+ argumentsValue.push(
55971
+ `${projection.parameterName}: ${quote4(targetIds[0])}`
55972
+ );
55973
+ continue;
55974
+ }
55975
+ argumentsValue.push(
55976
+ `${projection.parameterName}: ${emitValue(
55977
+ context,
55978
+ projectedMember,
55979
+ childValueId,
55980
+ {
55981
+ definitionSite: true,
55982
+ writeIdentity: false,
55983
+ environment,
55984
+ visited
55985
+ }
55986
+ )}`
55987
+ );
55014
55988
  }
55015
55989
  return { arguments: argumentsValue, memberIds, targetValueIds };
55016
55990
  }
@@ -55325,6 +56299,29 @@ function functionReferenceValue(context, body) {
55325
56299
  }
55326
56300
  return target.name;
55327
56301
  }
56302
+ function delegateValue(context, body) {
56303
+ if (!isObjectRecord2(body)) {
56304
+ throw new Error("NSDelegate value is not a closure or bound target.");
56305
+ }
56306
+ if (typeof body.code === "string") return body.code;
56307
+ if (typeof body.memberId !== "string") {
56308
+ throw new Error("NSDelegate bound target is missing memberId.");
56309
+ }
56310
+ if (body.valueId !== null && body.valueId !== void 0) {
56311
+ throw new Error(
56312
+ "NSDelegate instance-bound target cannot be represented by current project source."
56313
+ );
56314
+ }
56315
+ const target = context.members.get(body.memberId);
56316
+ if (target === void 0 || typeof target.name !== "string") {
56317
+ throw new Error(`NSDelegate target ${body.memberId} was not pulled.`);
56318
+ }
56319
+ const kind = numberField(target, "kind");
56320
+ if (kind !== 10 && kind !== 23 && kind !== 25) {
56321
+ throw new Error(`NSDelegate target ${body.memberId} is not callable.`);
56322
+ }
56323
+ return target.name;
56324
+ }
55328
56325
  function fileValue(context, kind, label, body) {
55329
56326
  if (body === null || body === void 0) return "null";
55330
56327
  if (!isObjectRecord2(body)) {
@@ -58326,7 +59323,8 @@ var init_animation_clips = __esm({
58326
59323
  frameNode,
58327
59324
  frameClassId,
58328
59325
  childIds: authoredChildren.ids,
58329
- childStoragePath: authoredChildren.storagePath
59326
+ childStoragePath: authoredChildren.storagePath,
59327
+ selectorOwnerNode: targetDefinition
58330
59328
  });
58331
59329
  this.validateActions({
58332
59330
  clipName: clipMember.name,
@@ -58342,6 +59340,7 @@ var init_animation_clips = __esm({
58342
59340
  clipClassId: clipMember.classId,
58343
59341
  childIds: authoredChildren.ids,
58344
59342
  childStoragePath: authoredChildren.storagePath,
59343
+ selectorOwnerNode: targetDefinition,
58345
59344
  duration
58346
59345
  });
58347
59346
  }
@@ -58355,12 +59354,16 @@ var init_animation_clips = __esm({
58355
59354
  const seenChildren = /* @__PURE__ */ new Set();
58356
59355
  for (const row of rows) {
58357
59356
  const rowClassId = this.requireNodeClassId(row, "animationChildOverride");
58358
- const childId = this.requireSingleLookupField(
59357
+ const selected2 = this.resolveSelector(
58359
59358
  row,
58360
59359
  rowClassId,
58361
- WORLD_ANIMATION_CHILD_OVERRIDE_CHILD_MEMBER_ID,
59360
+ WORLD_ANIMATION_CHILD_OVERRIDE_SELECTOR_MEMBER_ID,
59361
+ WORLD_ANIMATION_CHILD_OVERRIDE_REFRESH_MEMBER_ID,
59362
+ args.selectorOwnerNode,
58362
59363
  `Animation clip "${args.clipName}" frame ${args.frameIndex} child override`
58363
59364
  );
59365
+ if (selected2 === null) continue;
59366
+ const { childId, childClassId, childNode: child } = selected2;
58364
59367
  if (!args.childIds.has(childId)) {
58365
59368
  throw new Error(
58366
59369
  `Animation clip "${args.clipName}" frame ${args.frameIndex} references child "${childId}" outside the owner's authored Children graph.`
@@ -58372,13 +59375,6 @@ var init_animation_clips = __esm({
58372
59375
  );
58373
59376
  }
58374
59377
  seenChildren.add(childId);
58375
- const child = this.valueById.get(childId);
58376
- const childClassId = child === void 0 ? null : this.rowClassId(child);
58377
- if (child === void 0 || childClassId === null) {
58378
- throw new Error(
58379
- `Animation clip "${args.clipName}" frame ${args.frameIndex} references missing class-backed child "${childId}".`
58380
- );
58381
- }
58382
59378
  const bindingMemberId = row.genericBindings?.[WORLD_ANIMATION_CHILD_OVERRIDE_ENTRY_PARAM_ID];
58383
59379
  const bindingMember = typeof bindingMemberId === "string" ? this.memberById.get(bindingMemberId) : void 0;
58384
59380
  const bindingClassId = isMemberClass(bindingMember) ? bindingMember.classId : null;
@@ -58475,10 +59471,12 @@ var init_animation_clips = __esm({
58475
59471
  track,
58476
59472
  trackClassId: row.classId,
58477
59473
  childIds: args.childIds,
59474
+ selectorOwnerNode: args.selectorOwnerNode,
58478
59475
  duration: args.duration,
58479
59476
  label
58480
59477
  });
58481
59478
  if (row.kind === "childClip") {
59479
+ if (child === null) continue;
58482
59480
  this.validateChildClipTrack({
58483
59481
  track,
58484
59482
  trackClassId: row.classId,
@@ -58491,8 +59489,6 @@ var init_animation_clips = __esm({
58491
59489
  }
58492
59490
  this.validateSegmentTrack({
58493
59491
  trackClassId: row.classId,
58494
- childClassId: child.childClassId,
58495
- childId: child.childId,
58496
59492
  childStoragePath: args.childStoragePath,
58497
59493
  label
58498
59494
  });
@@ -58533,22 +59529,17 @@ var init_animation_clips = __esm({
58533
59529
  * segment's length is instance data this document does not have.
58534
59530
  */
58535
59531
  validateTrackBase(args) {
58536
- const childId = this.requireSingleLookupField(
59532
+ const selected2 = this.resolveSelector(
58537
59533
  args.track,
58538
59534
  args.trackClassId,
58539
- WORLD_ANIMATION_TRACK_CHILD_MEMBER_ID,
59535
+ WORLD_ANIMATION_TRACK_SELECTOR_MEMBER_ID,
59536
+ WORLD_ANIMATION_TRACK_REFRESH_MEMBER_ID,
59537
+ args.selectorOwnerNode,
58540
59538
  args.label
58541
59539
  );
58542
- if (!args.childIds.has(childId)) {
59540
+ if (selected2 !== null && !args.childIds.has(selected2.childId)) {
58543
59541
  throw new Error(
58544
- `${args.label} references child "${childId}" outside the owner's authored Children graph.`
58545
- );
58546
- }
58547
- const childNode = this.valueById.get(childId);
58548
- const childClassId = childNode === void 0 ? null : this.rowClassId(childNode);
58549
- if (childNode === void 0 || childClassId === null) {
58550
- throw new Error(
58551
- `${args.label} references missing class-backed child "${childId}".`
59542
+ `${args.label} references child "${selected2.childId}" outside the owner's authored Children graph.`
58552
59543
  );
58553
59544
  }
58554
59545
  const startFrame = this.requireIntegerField(
@@ -58567,7 +59558,36 @@ var init_animation_clips = __esm({
58567
59558
  }
58568
59559
  this.validateTrackDirection(args.track, args.trackClassId, args.label);
58569
59560
  this.validateTrackCropWindow(args.track, args.trackClassId, args.label);
58570
- return { childId, childClassId, childNode };
59561
+ return selected2;
59562
+ }
59563
+ resolveSelector(parent, classId, selectorMemberId, refreshMemberId, _selectorOwnerNode, label) {
59564
+ this.validateSelectorRefresh(parent, classId, refreshMemberId, label);
59565
+ const selector = this.scalarField(parent, classId, selectorMemberId);
59566
+ if (!isNSDelegateValue(selector)) {
59567
+ throw new Error(`${label} must carry a valid NeoDelegate selector.`);
59568
+ }
59569
+ const directReferenceId = nsDelegateDirectReferenceValueId(selector);
59570
+ if (directReferenceId === null) return null;
59571
+ const childNode = this.valueById.get(directReferenceId);
59572
+ if (childNode === void 0) {
59573
+ throw new Error(`${label} selector did not resolve a stored child row.`);
59574
+ }
59575
+ const childClassId = this.rowClassId(childNode);
59576
+ if (childClassId === null) {
59577
+ throw new Error(
59578
+ `${label} selector resolved child "${childNode.id}" without a class.`
59579
+ );
59580
+ }
59581
+ return { childId: childNode.id, childClassId, childNode };
59582
+ }
59583
+ validateSelectorRefresh(parent, classId, memberId, label) {
59584
+ const value = this.scalarField(parent, classId, memberId);
59585
+ if (value === void 0 || value === null) return;
59586
+ if (!Array.isArray(value) || value.length !== 1 || value[0] !== WORLD_SELECTOR_REFRESH_ON_LOAD_OPTION_ID && value[0] !== WORLD_SELECTOR_REFRESH_PER_FRAME_OPTION_ID) {
59587
+ throw new Error(
59588
+ `${label} Refresh must be exactly one NeoSelectorRefreshKind option.`
59589
+ );
59590
+ }
58571
59591
  }
58572
59592
  validateTrackDirection(track, trackClassId, label) {
58573
59593
  const authored = this.scalarField(
@@ -58692,13 +59712,6 @@ var init_animation_clips = __esm({
58692
59712
  `${args.label} class "${trackClassName}" does not bind its TChild generic to a Class member.`
58693
59713
  );
58694
59714
  }
58695
- if (!this.classDescendsFrom(args.childClassId, boundChildClassId)) {
58696
- const boundName = this.classById.get(boundChildClassId)?.name ?? boundChildClassId;
58697
- const childName = this.classById.get(args.childClassId)?.name ?? args.childClassId;
58698
- throw new Error(
58699
- `${args.label} plays against child "${args.childId}" of class "${childName}", which does not descend from the track's bound TChild "${boundName}".`
58700
- );
58701
- }
58702
59715
  const targetEntry = mergeStoredInstanceSchema(
58703
59716
  boundChildClassId,
58704
59717
  this.document.classes,
@@ -66789,6 +67802,20 @@ function memberRuntimeType(record3, context, seen = /* @__PURE__ */ new Set(), g
66789
67802
  return primitive2("void", true);
66790
67803
  case 24 /* FunctionRef */:
66791
67804
  return UNKNOWN_TYPE2;
67805
+ case 25 /* NSDelegate */:
67806
+ if (!isMemberDelegateBase(member)) return UNKNOWN_TYPE2;
67807
+ return {
67808
+ kind: "delegate",
67809
+ returnType: functionReturnType(
67810
+ member.returnTypeInfo,
67811
+ context,
67812
+ genericEnvironment
67813
+ ),
67814
+ parameterTypes: member.argumentTypes.map(
67815
+ (argument2) => toLanguageType(argument2, context, genericEnvironment)
67816
+ ),
67817
+ nullable: !required2
67818
+ };
66792
67819
  case 21 /* Generic */: {
66793
67820
  const genericParamId = getOptionalString(member, "genericParamId");
66794
67821
  if (!genericParamId) return UNKNOWN_TYPE2;
@@ -66983,6 +68010,19 @@ function toLanguageType(type, context, genericEnvironment) {
66983
68010
  ),
66984
68011
  nullable: !required2
66985
68012
  };
68013
+ case 25 /* NSDelegate */:
68014
+ return {
68015
+ kind: "delegate",
68016
+ returnType: functionReturnType(
68017
+ type.returnTypeInfo,
68018
+ context,
68019
+ genericEnvironment
68020
+ ),
68021
+ parameterTypes: type.argumentTypes.map(
68022
+ (argument2) => toLanguageType(argument2, context, genericEnvironment)
68023
+ ),
68024
+ nullable: !required2
68025
+ };
66986
68026
  case 21 /* Generic */: {
66987
68027
  const environmentEntry = genericEnvironment?.get(type.genericParamId);
66988
68028
  if (environmentEntry?.kind === "member") {
@@ -67951,6 +68991,7 @@ function pushConstructionFrame(ctx, label) {
67951
68991
  "Class construction requires an effect-capable evaluator Session scope."
67952
68992
  );
67953
68993
  }
68994
+ consumeBudget(ctx, "workUnits", 1, "work unit");
67954
68995
  if (state.constructionStack.length >= MAX_CONSTRUCTION_DEPTH) {
67955
68996
  const chain = [...state.constructionStack, label].join(" -> ");
67956
68997
  throw new NSGetterRuntimeError(
@@ -67994,6 +69035,7 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = []) {
67994
69035
  const ownsInvocationState = ctx.__executionState === void 0;
67995
69036
  const requestedWrites = [];
67996
69037
  const runtimeCtx = withEvaluationRuntime(ctx, requestedWrites);
69038
+ consumeBudget(runtimeCtx, "workUnits", 1, "work unit");
67997
69039
  const writes = runtimeCtx.__executionState?.writes ?? requestedWrites;
67998
69040
  const existingIds = new Set(runtimeCtx.__runtimeSessionValues.keys());
67999
69041
  const scope = createTopLevelScope(runtimeCtx);
@@ -68044,6 +69086,7 @@ function evaluateNSAction(action, ctx) {
68044
69086
  const ownsInvocationState = ctx.__executionState === void 0;
68045
69087
  const writes = [];
68046
69088
  const runtimeCtx = withEvaluationRuntime(ctx, writes);
69089
+ consumeBudget(runtimeCtx, "workUnits", 1, "work unit");
68047
69090
  const existingIds = new Set(runtimeCtx.__runtimeSessionValues.keys());
68048
69091
  const scope = createTopLevelScope(runtimeCtx);
68049
69092
  try {
@@ -68074,6 +69117,7 @@ function evaluateNSFunction(action, ctx, args) {
68074
69117
  const ownsInvocationState = ctx.__executionState === void 0;
68075
69118
  const writes = [];
68076
69119
  const runtimeCtx = withEvaluationRuntime(ctx, writes);
69120
+ consumeBudget(runtimeCtx, "workUnits", 1, "work unit");
68077
69121
  const existingIds = new Set(runtimeCtx.__runtimeSessionValues.keys());
68078
69122
  const runtimeArgs = remapRuntimeArguments(args, runtimeCtx);
68079
69123
  let value;
@@ -68126,14 +69170,62 @@ function withEvaluationRuntime(ctx, writes) {
68126
69170
  __executionState: ctx.__executionState ?? {
68127
69171
  writes,
68128
69172
  functionStack: [],
69173
+ delegateStack: [],
68129
69174
  constructorGroups: /* @__PURE__ */ new Map(),
68130
69175
  ownedValueAttachments: /* @__PURE__ */ new Map(),
68131
69176
  constructionStack: [],
68132
- loopIterations: 0
69177
+ loopIterations: 0,
69178
+ budget: createExecutionBudget(ctx.executionBudgetLimits)
68133
69179
  },
68134
69180
  __indexes: ctx.__executionState === void 0 || ctx.__valueOverlay === void 0 ? void 0 : ctx.__indexes
68135
69181
  };
68136
69182
  }
69183
+ function createExecutionBudget(requested) {
69184
+ const limits = { ...DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS };
69185
+ for (const key of Object.keys(limits)) {
69186
+ const value = requested?.[key];
69187
+ if (value === void 0) continue;
69188
+ if (!Number.isSafeInteger(value)) {
69189
+ throw new NeoScriptResourceLimitError(
69190
+ `NeoScript ${key} limit must be a safe integer.`
69191
+ );
69192
+ }
69193
+ if (value < 0) {
69194
+ throw new NeoScriptResourceLimitError(
69195
+ `NeoScript ${key} limit must not be negative.`
69196
+ );
69197
+ }
69198
+ if (value > DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS[key]) {
69199
+ throw new NeoScriptResourceLimitError(
69200
+ `NeoScript ${key} limit cannot exceed the safety ceiling of ${DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS[key]}.`
69201
+ );
69202
+ }
69203
+ limits[key] = value;
69204
+ }
69205
+ return {
69206
+ limits,
69207
+ workUnits: 0,
69208
+ collectionVisits: 0,
69209
+ producedCollectionEntries: 0,
69210
+ constructedSessionRows: 0,
69211
+ producedStringCharacters: 0
69212
+ };
69213
+ }
69214
+ function consumeBudget(ctx, counter, amount, label) {
69215
+ const budget = ctx.__executionState?.budget;
69216
+ if (budget === void 0) {
69217
+ throw new NSGetterRuntimeError(
69218
+ "NeoScript work executed without a shared execution budget."
69219
+ );
69220
+ }
69221
+ const limit = budget.limits[counter];
69222
+ if (amount > limit - budget[counter]) {
69223
+ throw new NeoScriptResourceLimitError(
69224
+ `NeoScript ${label} limit of ${limit} exceeded.`
69225
+ );
69226
+ }
69227
+ budget[counter] += amount;
69228
+ }
68137
69229
  function staticBindingMap(bindings) {
68138
69230
  if (bindings === void 0) return /* @__PURE__ */ new Map();
68139
69231
  if (bindings instanceof Map) return new Map(bindings);
@@ -68508,11 +69600,12 @@ function consumeLoopIteration(ctx) {
68508
69600
  );
68509
69601
  }
68510
69602
  if (state.loopIterations >= MAX_LOOP_ITERATIONS) {
68511
- throw new NSGetterRuntimeError(
69603
+ throw new NeoScriptResourceLimitError(
68512
69604
  `NeoScript loop iteration limit of ${MAX_LOOP_ITERATIONS} exceeded.`
68513
69605
  );
68514
69606
  }
68515
69607
  state.loopIterations += 1;
69608
+ consumeBudget(ctx, "workUnits", 1, "work unit");
68516
69609
  }
68517
69610
  function synchronizeExistingBindings(parent, child, bindingIds) {
68518
69611
  for (const bindingId of bindingIds) {
@@ -68682,6 +69775,7 @@ function validateTryInstruction(instruction) {
68682
69775
  }
68683
69776
  function evalInstructions(instructions, scope, ctx, options) {
68684
69777
  for (const ins of instructions) {
69778
+ consumeBudget(ctx, "workUnits", 1, "work unit");
68685
69779
  switch (ins.type) {
68686
69780
  case "variable" /* variable */: {
68687
69781
  let value = evalPointer(ins.variable.pointer, scope, ctx);
@@ -68796,7 +69890,7 @@ function evalInstructions(instructions, scope, ctx, options) {
68796
69890
  }
68797
69891
  case "forEach" /* forEach */: {
68798
69892
  const collection = evalPointer(ins.collectionPointer, scope, ctx);
68799
- const membership = snapshotCollectionMembership(collection);
69893
+ const membership = snapshotCollectionMembership(collection, ctx);
68800
69894
  const parentBindingIds = [...scope.keys()];
68801
69895
  const loopScope = createChildScope(scope);
68802
69896
  markReadonlyBinding(
@@ -69166,6 +70260,7 @@ function resolvedDestinationFieldsForContainer(targetValue, ctx) {
69166
70260
  return containerValueId === null ? {} : { resolvedDestination: { containerValueId } };
69167
70261
  }
69168
70262
  function dispatchNSSetter(target, value, scope, ctx, writes) {
70263
+ consumeBudget(ctx, "workUnits", 1, "work unit");
69169
70264
  if (target.type !== "callGetter" /* callGetter */) {
69170
70265
  throw new NSGetterRuntimeError(
69171
70266
  "Setter write target must be a callGetter pointer."
@@ -69269,8 +70364,22 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
69269
70364
  const targetValue = evalPointer(ins.target.pointer, scope, ctx);
69270
70365
  const args = ins.args.map((arg) => evalPointer(arg, scope, ctx));
69271
70366
  const isLookupSet = ins.target.typeInfo.type === 9 /* Lookup */;
70367
+ if (ins.mutation === "Add" /* Add */) {
70368
+ consumeBudget(
70369
+ ctx,
70370
+ "producedCollectionEntries",
70371
+ 1,
70372
+ "produced collection entry"
70373
+ );
70374
+ }
69272
70375
  if (ins.target.pointer.type === "variable" /* variable */) {
69273
- applyLocalCollectionMutation(targetValue, ins.mutation, args, isLookupSet);
70376
+ applyLocalCollectionMutation(
70377
+ targetValue,
70378
+ ins.mutation,
70379
+ args,
70380
+ ctx,
70381
+ isLookupSet
70382
+ );
69274
70383
  invalidateEvaluatorIndexes(ctx);
69275
70384
  scope.set(ins.target.pointer.variableId, targetValue);
69276
70385
  return;
@@ -69300,6 +70409,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
69300
70409
  targetValue,
69301
70410
  ins.mutation,
69302
70411
  overlayArgs,
70412
+ ctx,
69303
70413
  isLookupSet
69304
70414
  );
69305
70415
  invalidateEvaluatorIndexes(ctx);
@@ -69360,12 +70470,22 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
69360
70470
  return;
69361
70471
  }
69362
70472
  }
69363
- function applyLocalCollectionMutation(targetValue, mutation, args, unique = false) {
70473
+ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique = false) {
69364
70474
  validateCollectionMutation(targetValue, mutation, args);
69365
70475
  switch (mutation) {
69366
70476
  case "Add" /* Add */:
69367
70477
  if (Array.isArray(targetValue)) {
69368
- if (!unique || !targetValue.some((entry) => jsEqual(entry, args[0]))) {
70478
+ let alreadyPresent = false;
70479
+ if (unique) {
70480
+ for (const entry of targetValue) {
70481
+ consumeBudget(ctx, "collectionVisits", 1, "collection visit");
70482
+ if (jsEqual(entry, args[0])) {
70483
+ alreadyPresent = true;
70484
+ break;
70485
+ }
70486
+ }
70487
+ }
70488
+ if (!alreadyPresent) {
69369
70489
  targetValue.push(args[0]);
69370
70490
  }
69371
70491
  return;
@@ -69374,7 +70494,14 @@ function applyLocalCollectionMutation(targetValue, mutation, args, unique = fals
69374
70494
  return;
69375
70495
  case "Remove" /* Remove */:
69376
70496
  if (Array.isArray(targetValue)) {
69377
- const index = targetValue.findIndex((entry) => jsEqual(entry, args[0]));
70497
+ let index = -1;
70498
+ for (let candidate = 0; candidate < targetValue.length; candidate += 1) {
70499
+ consumeBudget(ctx, "collectionVisits", 1, "collection visit");
70500
+ if (jsEqual(targetValue[candidate], args[0])) {
70501
+ index = candidate;
70502
+ break;
70503
+ }
70504
+ }
69378
70505
  if (index >= 0) targetValue.splice(index, 1);
69379
70506
  return;
69380
70507
  }
@@ -69391,10 +70518,18 @@ function applyLocalCollectionMutation(targetValue, mutation, args, unique = fals
69391
70518
  }
69392
70519
  case "Clear" /* Clear */:
69393
70520
  if (Array.isArray(targetValue)) {
70521
+ consumeBudget(
70522
+ ctx,
70523
+ "collectionVisits",
70524
+ targetValue.length,
70525
+ "collection visit"
70526
+ );
69394
70527
  targetValue.length = 0;
69395
70528
  return;
69396
70529
  }
69397
- for (const key of Object.keys(objectArg(targetValue, "Clear target"))) {
70530
+ const keys = Object.keys(objectArg(targetValue, "Clear target"));
70531
+ consumeBudget(ctx, "collectionVisits", keys.length, "collection visit");
70532
+ for (const key of keys) {
69398
70533
  delete objectArg(targetValue, "Clear target")[key];
69399
70534
  }
69400
70535
  return;
@@ -69529,8 +70664,17 @@ function evalStaticMember(memberId, ctx) {
69529
70664
  }
69530
70665
  function evalPointer(pointer, scope, ctx) {
69531
70666
  switch (pointer.type) {
69532
- case "value" /* value */:
69533
- return pointer.value.value;
70667
+ case "value" /* value */: {
70668
+ const value = pointer.value.value;
70669
+ if (isNSDelegateClosureValue(value)) {
70670
+ return {
70671
+ ...value,
70672
+ [DELEGATE_LEXICAL_THIS]: ctx.thisValue,
70673
+ [DELEGATE_LEXICAL_ROOT]: ctx.rootValue
70674
+ };
70675
+ }
70676
+ return value;
70677
+ }
69534
70678
  case "variable" /* variable */: {
69535
70679
  if (!scope.has(pointer.variableId)) {
69536
70680
  throw new NSGetterRuntimeError(
@@ -69568,8 +70712,20 @@ function evalPointer(pointer, scope, ctx) {
69568
70712
  case "function" /* function */:
69569
70713
  return evalFunction(pointer.function, scope, ctx);
69570
70714
  case "listLiteral" /* listLiteral */:
70715
+ consumeBudget(
70716
+ ctx,
70717
+ "producedCollectionEntries",
70718
+ pointer.entries.length,
70719
+ "produced collection entry"
70720
+ );
69571
70721
  return pointer.entries.map((e) => evalPointer(e, scope, ctx));
69572
70722
  case "dictLiteral" /* dictLiteral */: {
70723
+ consumeBudget(
70724
+ ctx,
70725
+ "producedCollectionEntries",
70726
+ pointer.entries.length,
70727
+ "produced collection entry"
70728
+ );
69573
70729
  const out = {};
69574
70730
  for (const e of pointer.entries) {
69575
70731
  const k = evalPointer(e.key, scope, ctx);
@@ -69622,6 +70778,7 @@ function evalPointer(pointer, scope, ctx) {
69622
70778
  `Function call '${member.name}' resolves to non-callable member kind ${MemberKind[member.kind]}.`
69623
70779
  );
69624
70780
  }
70781
+ consumeBudget(ctx, "workUnits", 1, "work unit");
69625
70782
  if (member.kind === 13 /* Function */) {
69626
70783
  throw new NativeFunctionDelegateUnavailableError(
69627
70784
  `Cannot evaluate native Function '${member.name}' in web preview because no native delegate is available.`
@@ -69677,6 +70834,17 @@ function evalPointer(pointer, scope, ctx) {
69677
70834
  state.functionStack.pop();
69678
70835
  }
69679
70836
  }
70837
+ case "callDelegate" /* callDelegate */: {
70838
+ const delegate = evalPointer(pointer.delegate, scope, ctx);
70839
+ if (delegate === null || delegate === void 0) {
70840
+ if (pointer.optional === true) return null;
70841
+ throw new NSGetterRuntimeError(
70842
+ "Cannot invoke a null NeoDelegate value."
70843
+ );
70844
+ }
70845
+ const args = pointer.args.map((arg) => evalPointer(arg, scope, ctx));
70846
+ return invokeDelegateValue(delegate, args, ctx);
70847
+ }
69680
70848
  case "functionErrorCheck" /* functionErrorCheck */: {
69681
70849
  try {
69682
70850
  evalPointer(pointer.call, scope, ctx);
@@ -69685,7 +70853,7 @@ function evalPointer(pointer, scope, ctx) {
69685
70853
  if (err instanceof NativeFunctionDelegateUnavailableError) {
69686
70854
  return pointer.mode === "doesNotThrow" /* DoesNotThrow */;
69687
70855
  }
69688
- if (err instanceof NSGetterRuntimeError) {
70856
+ if (isCatchableNSRuntimeError(err)) {
69689
70857
  return pointer.mode === "throws" /* Throws */;
69690
70858
  }
69691
70859
  throw err;
@@ -69702,7 +70870,14 @@ function evalPointer(pointer, scope, ctx) {
69702
70870
  }
69703
70871
  case "stringify" /* stringify */: {
69704
70872
  const v = evalPointer(pointer.pointer, scope, ctx);
69705
- return formatForInterp(v, pointer.sourceType, ctx);
70873
+ const formatted = formatForInterp(v, pointer.sourceType, ctx);
70874
+ consumeBudget(
70875
+ ctx,
70876
+ "producedStringCharacters",
70877
+ formatted.length,
70878
+ "produced string character"
70879
+ );
70880
+ return formatted;
69706
70881
  }
69707
70882
  }
69708
70883
  }
@@ -69717,6 +70892,174 @@ function resolveEffectiveCallableMember(pointer, receiver, ctx) {
69717
70892
  const runtimeMember = resolveRuntimeSchemaMember(receiver, schemaKey, ctx);
69718
70893
  return runtimeMember ?? staticMember;
69719
70894
  }
70895
+ function invokeDelegateValue(value, args, ctx) {
70896
+ if (isNSDelegateClosureValueDraft(value)) {
70897
+ throw new NSGetterRuntimeError(
70898
+ "NeoDelegate closure has source code but no compiled action."
70899
+ );
70900
+ }
70901
+ if (isNSDelegateClosureValue(value)) {
70902
+ const closure = value;
70903
+ const thisValue = delegateClosureLexicalThis(closure, ctx);
70904
+ return executeCompiledFunction(
70905
+ value.action,
70906
+ {
70907
+ ...ctx,
70908
+ thisValue,
70909
+ rootValue: closure[DELEGATE_LEXICAL_ROOT] ?? ctx.rootValue
70910
+ },
70911
+ args,
70912
+ value.action.typeInfo.type === 0 /* Null */
70913
+ );
70914
+ }
70915
+ if (!isMemberDelegateTarget(value)) {
70916
+ throw new NSGetterRuntimeError(
70917
+ "NeoDelegate value is neither a closure nor a bound member target."
70918
+ );
70919
+ }
70920
+ const member = evalMemberById(ctx.vm, value.memberId);
70921
+ if (member === null) {
70922
+ throw new NSGetterRuntimeError(
70923
+ `NeoDelegate target member '${value.memberId}' does not exist.`
70924
+ );
70925
+ }
70926
+ const state = ctx.__executionState;
70927
+ if (state === void 0) {
70928
+ throw new NSGetterRuntimeError(
70929
+ "NeoDelegate invocation reached an evaluator without execution state."
70930
+ );
70931
+ }
70932
+ const frame = `${member.name}[${value.valueId ?? "default"}]`;
70933
+ if (state.delegateStack.includes(frame)) {
70934
+ throw new NSGetterRuntimeError(
70935
+ `NeoDelegate target cycle: ${[...state.delegateStack, frame].join(" -> ")}.`
70936
+ );
70937
+ }
70938
+ if (state.delegateStack.length >= 64) {
70939
+ throw new NSGetterRuntimeError(
70940
+ `NeoDelegate call stack exceeded 64 frames: ${[
70941
+ ...state.delegateStack,
70942
+ frame
70943
+ ].join(" -> ")}.`
70944
+ );
70945
+ }
70946
+ let receiver = null;
70947
+ if (value.valueId !== null) {
70948
+ const row = evalValueById(
70949
+ ctx.vm,
70950
+ value.valueId,
70951
+ ctx.__runtimeSessionValues,
70952
+ ctx.__valueOverlay
70953
+ );
70954
+ if (row === null) {
70955
+ throw new NSGetterRuntimeError(
70956
+ `NeoDelegate target '${member.name}' has missing receiver value '${value.valueId}'.`
70957
+ );
70958
+ }
70959
+ receiver = row.value;
70960
+ }
70961
+ state.delegateStack.push(frame);
70962
+ try {
70963
+ if (member.kind === 13 /* Function */) {
70964
+ throw new NativeFunctionDelegateUnavailableError(
70965
+ `Cannot evaluate native Function '${member.name}' in web preview because no native delegate is available.`
70966
+ );
70967
+ }
70968
+ if (member.kind === 23 /* NSFunction */) {
70969
+ const signature = resolveCallableSignature(member.id, member.kind, ctx);
70970
+ const action = resolveCompiledNSFunction(member.id, ctx);
70971
+ if (signature === null || action === null) {
70972
+ throw new NSGetterRuntimeError(
70973
+ `NeoDelegate target NSFunction '${member.name}' has no valid compiled body.`
70974
+ );
70975
+ }
70976
+ const runtimeSignature = receiver === null ? signature : substituteCallableSignatureForReceiver(signature, receiver, ctx);
70977
+ return executeCompiledFunction(
70978
+ action,
70979
+ { ...ctx, thisValue: receiver },
70980
+ args,
70981
+ runtimeSignature.returnTypeInfo.type === NS_TYPE_VOID,
70982
+ runtimeSignature
70983
+ );
70984
+ }
70985
+ if (member.kind === 25 /* NSDelegate */) {
70986
+ let nested;
70987
+ if (receiver !== null) {
70988
+ const schemaKey = cachedSchemaKeyForMember(member.id, ctx);
70989
+ if (schemaKey === null || typeof receiver !== "object" || !Object.prototype.hasOwnProperty.call(receiver, schemaKey)) {
70990
+ throw new NSGetterRuntimeError(
70991
+ `NeoDelegate target '${member.name}' is missing from its receiver.`
70992
+ );
70993
+ }
70994
+ nested = resolveValueIfIdForMember(
70995
+ receiver[schemaKey],
70996
+ member,
70997
+ ctx
70998
+ );
70999
+ } else if (member.defaultValue !== void 0 && member.defaultValue !== null && isLiteralValueContent(member.defaultValue)) {
71000
+ nested = member.defaultValue.value;
71001
+ } else {
71002
+ throw new NSGetterRuntimeError(
71003
+ `NeoDelegate target '${member.name}' has no declaration default.`
71004
+ );
71005
+ }
71006
+ return invokeDelegateValue(nested, args, ctx);
71007
+ }
71008
+ throw new NSGetterRuntimeError(
71009
+ `NeoDelegate target '${member.name}' resolves to non-callable member kind ${MemberKind[member.kind]}.`
71010
+ );
71011
+ } finally {
71012
+ state.delegateStack.pop();
71013
+ }
71014
+ }
71015
+ function delegateClosureLexicalThis(closure, ctx) {
71016
+ if (Object.prototype.hasOwnProperty.call(closure, DELEGATE_LEXICAL_THIS)) {
71017
+ return closure[DELEGATE_LEXICAL_THIS];
71018
+ }
71019
+ const closureRow = trackedRowForValueReference(closure, ctx);
71020
+ if (closureRow === null) {
71021
+ throw new NSGetterRuntimeError(
71022
+ "Stored NeoDelegate closure has no resolvable value row; lexical this cannot be reconstructed from ownership."
71023
+ );
71024
+ }
71025
+ const owners = /* @__PURE__ */ new Map();
71026
+ for (const link of evaluatorIndexes(ctx).parentLinksByChildId.get(
71027
+ closureRow.id
71028
+ ) ?? []) {
71029
+ const parent = evalValueById(
71030
+ ctx.vm,
71031
+ link.parentId,
71032
+ ctx.__runtimeSessionValues,
71033
+ ctx.__valueOverlay
71034
+ );
71035
+ if (parent === null) continue;
71036
+ if (typeof parent.value !== "object") continue;
71037
+ if (parent.value === null) continue;
71038
+ if (Array.isArray(parent.value)) continue;
71039
+ const classId = classIdForValueRow(parent, ctx);
71040
+ if (classId === void 0) continue;
71041
+ const owningMember = memberForCustomSchemaValue(classId, link.key, ctx);
71042
+ if (owningMember?.kind !== 25 /* NSDelegate */) continue;
71043
+ owners.set(parent.id, parent.value);
71044
+ }
71045
+ if (owners.size === 0) {
71046
+ throw new NSGetterRuntimeError(
71047
+ `Stored NeoDelegate closure value '${closureRow.id}' has no owning class instance; lexical this cannot be reconstructed from ownership.`
71048
+ );
71049
+ }
71050
+ if (owners.size > 1) {
71051
+ throw new NSGetterRuntimeError(
71052
+ `Stored NeoDelegate closure value '${closureRow.id}' has multiple owning class instances (${[...owners.keys()].join(", ")}); lexical this is ambiguous.`
71053
+ );
71054
+ }
71055
+ const owner = owners.values().next();
71056
+ if (owner.done) {
71057
+ throw new NSGetterRuntimeError(
71058
+ `Stored NeoDelegate closure value '${closureRow.id}' lost its owning class instance during lexical-this resolution.`
71059
+ );
71060
+ }
71061
+ return owner.value;
71062
+ }
69720
71063
  function resolveCallableSignature(memberId, memberKind, ctx) {
69721
71064
  const cacheKey = `${memberKind}:${memberId}`;
69722
71065
  const cache = evaluatorResolutionCache(ctx).callableSignatureByKey;
@@ -70644,11 +71987,11 @@ function evalOperation(operation, scope, ctx) {
70644
71987
  if (operation.type === "arithmetic" /* arithmetic */) {
70645
71988
  const op = operation.arithmetic;
70646
71989
  const operands = op.pointers.map((p) => evalPointer(p, scope, ctx));
70647
- return applyArithmetic(op.type, operands, op.decimal === true);
71990
+ return applyArithmetic(op.type, operands, op.decimal === true, ctx);
70648
71991
  }
70649
71992
  return evalBooleanExpression(operation.expression, scope, ctx);
70650
71993
  }
70651
- function applyArithmetic(op, operands, decimal2) {
71994
+ function applyArithmetic(op, operands, decimal2, ctx) {
70652
71995
  if (operands.length === 0) {
70653
71996
  throw new NSGetterRuntimeError("Arithmetic operation with no operands");
70654
71997
  }
@@ -70656,10 +71999,24 @@ function applyArithmetic(op, operands, decimal2) {
70656
71999
  return applyDecimalArithmetic(op, operands);
70657
72000
  }
70658
72001
  if (op === "+" /* addition */ && operands.every((o) => typeof o === "string")) {
70659
- return operands.join("");
72002
+ const result = operands.join("");
72003
+ consumeBudget(
72004
+ ctx,
72005
+ "producedStringCharacters",
72006
+ result.length,
72007
+ "produced string character"
72008
+ );
72009
+ return result;
70660
72010
  }
70661
72011
  if (op === "+" /* addition */ && operands.some((o) => typeof o === "string")) {
70662
- return operands.map((o) => stringifyForInterp(o)).join("");
72012
+ const result = operands.map((o) => stringifyForInterp(o)).join("");
72013
+ consumeBudget(
72014
+ ctx,
72015
+ "producedStringCharacters",
72016
+ result.length,
72017
+ "produced string character"
72018
+ );
72019
+ return result;
70663
72020
  }
70664
72021
  const numbers = operands.map((o) => {
70665
72022
  if (typeof o === "number") return o;
@@ -71054,12 +72411,36 @@ function evalFunction(fn, scope, ctx) {
71054
72411
  );
71055
72412
  }
71056
72413
  switch (fn.info.op) {
71057
- case "toLower":
71058
- return receiver.toLowerCase();
71059
- case "toUpper":
71060
- return receiver.toUpperCase();
71061
- case "trim":
71062
- return receiver.trim();
72414
+ case "toLower": {
72415
+ const result = receiver.toLowerCase();
72416
+ consumeBudget(
72417
+ ctx,
72418
+ "producedStringCharacters",
72419
+ result.length,
72420
+ "produced string character"
72421
+ );
72422
+ return result;
72423
+ }
72424
+ case "toUpper": {
72425
+ const result = receiver.toUpperCase();
72426
+ consumeBudget(
72427
+ ctx,
72428
+ "producedStringCharacters",
72429
+ result.length,
72430
+ "produced string character"
72431
+ );
72432
+ return result;
72433
+ }
72434
+ case "trim": {
72435
+ const result = receiver.trim();
72436
+ consumeBudget(
72437
+ ctx,
72438
+ "producedStringCharacters",
72439
+ result.length,
72440
+ "produced string character"
72441
+ );
72442
+ return result;
72443
+ }
71063
72444
  case "startsWith":
71064
72445
  case "endsWith": {
71065
72446
  if (fn.info.argPointer === void 0) {
@@ -71084,6 +72465,7 @@ function evalFunction(fn, scope, ctx) {
71084
72465
  const isList = Array.isArray(c);
71085
72466
  const out = isList ? [] : {};
71086
72467
  iterateCollection(c, ctx, (entry, key, valueId) => {
72468
+ consumeBudget(ctx, "workUnits", 1, "work unit");
71087
72469
  const innerScope = pushParams(
71088
72470
  scope,
71089
72471
  innerFn.parameters,
@@ -71101,6 +72483,12 @@ function evalFunction(fn, scope, ctx) {
71101
72483
  evaluationOptions(ctx, false)
71102
72484
  );
71103
72485
  if (result.kind === "return" && result.value === true) {
72486
+ consumeBudget(
72487
+ ctx,
72488
+ "producedCollectionEntries",
72489
+ 1,
72490
+ "produced collection entry"
72491
+ );
71104
72492
  if (isList) {
71105
72493
  out.push(valueId ?? entry);
71106
72494
  } else {
@@ -71123,6 +72511,7 @@ function evalFunction(fn, scope, ctx) {
71123
72511
  found = entry;
71124
72512
  return;
71125
72513
  }
72514
+ consumeBudget(ctx, "workUnits", 1, "work unit");
71126
72515
  const innerScope = pushParams(
71127
72516
  scope,
71128
72517
  innerFn.parameters,
@@ -71153,6 +72542,7 @@ function evalFunction(fn, scope, ctx) {
71153
72542
  const isList = Array.isArray(c);
71154
72543
  const out = [];
71155
72544
  iterateCollection(c, ctx, (entry, key) => {
72545
+ consumeBudget(ctx, "workUnits", 1, "work unit");
71156
72546
  const innerScope = pushParams(
71157
72547
  scope,
71158
72548
  innerFn.parameters,
@@ -71166,6 +72556,12 @@ function evalFunction(fn, scope, ctx) {
71166
72556
  evaluationOptions(ctx, false)
71167
72557
  );
71168
72558
  if (result.kind === "return") {
72559
+ consumeBudget(
72560
+ ctx,
72561
+ "producedCollectionEntries",
72562
+ 1,
72563
+ "produced collection entry"
72564
+ );
71169
72565
  out.push(result.value);
71170
72566
  }
71171
72567
  });
@@ -71541,6 +72937,25 @@ function publishConstructedRows(args) {
71541
72937
  "Class construction requires an effect-capable evaluator Session scope."
71542
72938
  );
71543
72939
  }
72940
+ consumeBudget(
72941
+ ctx,
72942
+ "constructedSessionRows",
72943
+ createdValues.length,
72944
+ "constructed Session row"
72945
+ );
72946
+ let producedEntries = 0;
72947
+ for (const row of createdValues) {
72948
+ if (Array.isArray(row.value)) producedEntries += row.value.length;
72949
+ else if (typeof row.value === "object" && row.value !== null) {
72950
+ producedEntries += Object.keys(row.value).length;
72951
+ }
72952
+ }
72953
+ consumeBudget(
72954
+ ctx,
72955
+ "producedCollectionEntries",
72956
+ producedEntries,
72957
+ "produced collection entry"
72958
+ );
71544
72959
  const retained = new Set(createdValues.map((row) => row.id));
71545
72960
  for (const rowId of beforeRetain) {
71546
72961
  if (retained.has(rowId)) continue;
@@ -72953,9 +74368,10 @@ function collectionLength(c) {
72953
74368
  `Cannot Count() ${typeof c}; expected list, dictionary, or string`
72954
74369
  );
72955
74370
  }
72956
- function snapshotCollectionMembership(collection) {
74371
+ function snapshotCollectionMembership(collection, ctx) {
72957
74372
  const membership = [];
72958
74373
  const valid = forEachRawCollectionEntry(collection, ({ raw }) => {
74374
+ consumeBudget(ctx, "collectionVisits", 1, "collection visit");
72959
74375
  membership.push(raw);
72960
74376
  });
72961
74377
  if (valid) return membership;
@@ -72990,12 +74406,14 @@ function forEachRawCollectionEntry(c, callback) {
72990
74406
  function collectionEntries(c, ctx) {
72991
74407
  const entries = [];
72992
74408
  forEachRawCollectionEntry(c, ({ raw }) => {
74409
+ consumeBudget(ctx, "collectionVisits", 1, "collection visit");
72993
74410
  entries.push(resolveValueIfId(raw, ctx));
72994
74411
  });
72995
74412
  return entries;
72996
74413
  }
72997
74414
  function iterateCollection(c, ctx, callback) {
72998
74415
  forEachRawCollectionEntry(c, ({ raw, key, valueId }) => {
74416
+ consumeBudget(ctx, "collectionVisits", 1, "collection visit");
72999
74417
  const entry = resolveValueIfId(raw, ctx);
73000
74418
  callback(entry, key, valueId);
73001
74419
  });
@@ -73011,7 +74429,7 @@ function pushParams(parent, parameters, positional, isList) {
73011
74429
  }
73012
74430
  return child;
73013
74431
  }
73014
- var NonCatchableNSGetterRuntimeError, NativeFunctionDelegateUnavailableError, CorruptNeoScriptIRError, liveListIndexesByProject, MAX_CONSTRUCTION_DEPTH, MAX_LOOP_ITERATIONS, LazyValueOverlay, readonlyBindingErrorsByScope, READONLY_FOREACH_BINDING_ERROR, READONLY_CATCH_BINDING_ERROR;
74432
+ var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, NonCatchableNSGetterRuntimeError, NativeFunctionDelegateUnavailableError, CorruptNeoScriptIRError, NeoScriptResourceLimitError, DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS, liveListIndexesByProject, MAX_CONSTRUCTION_DEPTH, MAX_LOOP_ITERATIONS, LazyValueOverlay, readonlyBindingErrorsByScope, READONLY_FOREACH_BINDING_ERROR, READONLY_CATCH_BINDING_ERROR;
73015
74433
  var init_evaluateNSGetter = __esm({
73016
74434
  "../src/view-models/neoscript-evaluator/evaluateNSGetter.ts"() {
73017
74435
  "use strict";
@@ -73027,12 +74445,27 @@ var init_evaluateNSGetter = __esm({
73027
74445
  init_core();
73028
74446
  init_member_storage_key();
73029
74447
  init_project2();
74448
+ DELEGATE_LEXICAL_THIS = /* @__PURE__ */ Symbol("neoDelegateLexicalThis");
74449
+ DELEGATE_LEXICAL_ROOT = /* @__PURE__ */ Symbol("neoDelegateLexicalRoot");
73030
74450
  NonCatchableNSGetterRuntimeError = class extends NSGetterRuntimeError {
73031
74451
  };
73032
74452
  NativeFunctionDelegateUnavailableError = class extends NonCatchableNSGetterRuntimeError {
73033
74453
  };
73034
74454
  CorruptNeoScriptIRError = class extends NonCatchableNSGetterRuntimeError {
73035
74455
  };
74456
+ NeoScriptResourceLimitError = class extends NonCatchableNSGetterRuntimeError {
74457
+ constructor(message) {
74458
+ super(message);
74459
+ this.name = "NeoScriptResourceLimitError";
74460
+ }
74461
+ };
74462
+ DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS = Object.freeze({
74463
+ workUnits: 1e5,
74464
+ collectionVisits: 1e5,
74465
+ producedCollectionEntries: 1e4,
74466
+ constructedSessionRows: 1e3,
74467
+ producedStringCharacters: 1024 * 1024
74468
+ });
73036
74469
  liveListIndexesByProject = /* @__PURE__ */ new WeakMap();
73037
74470
  MAX_CONSTRUCTION_DEPTH = 64;
73038
74471
  MAX_LOOP_ITERATIONS = 1e4;
@@ -74292,6 +75725,58 @@ function compileAuthoredMemberBodies(args) {
74292
75725
  compileNSPropertyBodies(args);
74293
75726
  compileNSFunctionBody(args);
74294
75727
  compileMemberInitializerBody(args);
75728
+ compileMemberDelegateDefault(args);
75729
+ }
75730
+ function compileDelegateClosureValue(code, signature) {
75731
+ const compiled = compileNSGetter(`return ${code};`, {
75732
+ project: signature.project,
75733
+ projectFiles: signature.projectFiles ?? [],
75734
+ members: [...signature.members],
75735
+ classes: [...signature.classes],
75736
+ enums: [...signature.enums],
75737
+ interfaces: [...signature.interfaces ?? []],
75738
+ constructors: [...signature.constructors ?? []],
75739
+ thisClass: signature.thisClass,
75740
+ returnTypeInfo: {
75741
+ type: 25 /* NSDelegate */,
75742
+ required: true,
75743
+ returnTypeInfo: signature.returnTypeInfo,
75744
+ argumentTypes: [...signature.argumentTypes]
75745
+ },
75746
+ functionName: signature.name
75747
+ });
75748
+ const instruction = compiled.instructions[0];
75749
+ if (compiled.instructions.length !== 1 || instruction?.type !== "return" /* return */ || instruction.pointer?.type !== "value" /* value */) {
75750
+ throw new Error(
75751
+ `NeoDelegate closure "${signature.name}" did not compile to one closure literal.`
75752
+ );
75753
+ }
75754
+ const value = instruction.pointer.value.value;
75755
+ if (!value || typeof value !== "object" || !("action" in value)) {
75756
+ throw new Error(
75757
+ `NeoDelegate closure "${signature.name}" compiled without an action.`
75758
+ );
75759
+ }
75760
+ const action = value.action;
75761
+ if (!isNSFunctionWithReturnType(action)) {
75762
+ throw new Error(
75763
+ `NeoDelegate closure "${signature.name}" compiled an invalid action.`
75764
+ );
75765
+ }
75766
+ return { code, action };
75767
+ }
75768
+ function compileMemberDelegateDefault(args) {
75769
+ if (!isMemberDelegateBase(args.member)) return;
75770
+ const defaultValue = args.member.defaultValue;
75771
+ if (defaultValue === void 0 || !isLiteralValueContent(defaultValue) || !isNSDelegateClosureValueDraft(defaultValue.value)) {
75772
+ return;
75773
+ }
75774
+ defaultValue.value = compileDelegateClosureValue(defaultValue.value.code, {
75775
+ ...args,
75776
+ returnTypeInfo: args.member.returnTypeInfo,
75777
+ argumentTypes: args.member.argumentTypes,
75778
+ name: args.member.name
75779
+ });
74295
75780
  }
74296
75781
  function compileConstructorRecord(args) {
74297
75782
  const owner = args.classes.find(
@@ -74534,6 +76019,18 @@ function resolveMemberDeclaredTypeInfo(member, members) {
74534
76019
  enumId: resolved.enumId
74535
76020
  };
74536
76021
  }
76022
+ if (isMemberDelegateBase(resolved)) {
76023
+ return {
76024
+ type: 25 /* NSDelegate */,
76025
+ required: resolved.required,
76026
+ returnTypeInfo: resolved.returnTypeInfo,
76027
+ argumentTypes: resolved.argumentTypes.map((argument2) => {
76028
+ const { name, ...typeInfo } = argument2;
76029
+ void name;
76030
+ return typeInfo;
76031
+ })
76032
+ };
76033
+ }
74537
76034
  if (isMemberListBase(resolved) || isMemberDictionaryBase(resolved)) {
74538
76035
  const entry = members.find(
74539
76036
  (candidate) => candidate.id === resolved.entryMemberId
@@ -83955,6 +85452,13 @@ function prepareServerOwnedSchemaCommit(args) {
83955
85452
  requiresCompleteSweep,
83956
85453
  contentHashHeads: args.contentHashHeads
83957
85454
  });
85455
+ prepareServerOwnedDelegateValueBodies({
85456
+ document: args.document,
85457
+ postDocument,
85458
+ prepared,
85459
+ requiresCompleteSweep,
85460
+ contentHashHeads: args.contentHashHeads
85461
+ });
83958
85462
  const committedDocument = applyProjectVersionWriteChanges(
83959
85463
  args.document,
83960
85464
  prepared
@@ -85956,6 +87460,119 @@ function prepareServerOwnedValueInitializerBodies(args) {
85956
87460
  });
85957
87461
  }
85958
87462
  }
87463
+ function delegateValueRow(value) {
87464
+ if (!isMemberValue(value) || !isLiteralValueContent(value)) return null;
87465
+ if (!isNSDelegateClosureValueDraft(value.value) && !isNSDelegateClosureValue(value.value)) {
87466
+ return null;
87467
+ }
87468
+ return typeof value.value.code === "string" ? value : null;
87469
+ }
87470
+ function prepareServerOwnedDelegateValueBodies(args) {
87471
+ const explicitRows = /* @__PURE__ */ new Map();
87472
+ for (let index = 0; index < args.prepared.length; index += 1) {
87473
+ const change = args.prepared[index];
87474
+ if (change?.recordKind !== "value" || change.operation === "delete") {
87475
+ continue;
87476
+ }
87477
+ const row = delegateValueRow(change.nextData);
87478
+ if (row !== null) explicitRows.set(index, row);
87479
+ }
87480
+ const sweepRows = args.requiresCompleteSweep ? args.postDocument.values.filter(
87481
+ (value) => delegateValueRow(value) !== null && !args.prepared.some(
87482
+ (change) => change.recordKind === "value" && change.recordId === value.id
87483
+ )
87484
+ ) : [];
87485
+ if (explicitRows.size === 0 && sweepRows.length === 0) return;
87486
+ const committedDocument = applyProjectVersionWriteChanges(
87487
+ args.postDocument,
87488
+ args.prepared
87489
+ );
87490
+ const targetIds = /* @__PURE__ */ new Set([
87491
+ ...[...explicitRows.values()].map((row) => row.id),
87492
+ ...sweepRows.map((row) => row.id)
87493
+ ]);
87494
+ const rootOwnerByValueId = /* @__PURE__ */ new Map();
87495
+ const ownerByValueId = resolveOwnerMembersForValues(
87496
+ committedDocument,
87497
+ targetIds,
87498
+ void 0,
87499
+ rootOwnerByValueId
87500
+ );
87501
+ const compileOne = (document, row) => {
87502
+ const member = ownerByValueId.get(row.id);
87503
+ if (!isMemberDelegateBase(member)) {
87504
+ throw new Error(
87505
+ `Value "${row.id}" carries a NeoDelegate closure but no NeoDelegate member in this project version stores it.`
87506
+ );
87507
+ }
87508
+ row.value = compileDelegateClosureValue(row.value.code, {
87509
+ project: document.project,
87510
+ projectFiles: document.projectFiles,
87511
+ members: document.members,
87512
+ classes: document.classes,
87513
+ enums: document.enums,
87514
+ interfaces: document.interfaces,
87515
+ constructors: document.constructors ?? [],
87516
+ thisClass: findSchemaPlacement(
87517
+ rootOwnerByValueId.get(row.id)?.id ?? "",
87518
+ document.classes
87519
+ )?.ownerClass ?? null,
87520
+ returnTypeInfo: member.returnTypeInfo,
87521
+ argumentTypes: member.argumentTypes,
87522
+ name: `${member.name} value`
87523
+ });
87524
+ };
87525
+ for (const [index, row] of explicitRows) {
87526
+ const compiled = { ...row, value: { ...row.value } };
87527
+ compileOne(committedDocument, compiled);
87528
+ const change = args.prepared[index];
87529
+ if (change !== void 0) {
87530
+ args.prepared[index] = { ...change, nextData: compiled };
87531
+ }
87532
+ }
87533
+ if (sweepRows.length === 0) return;
87534
+ const currentById = new Map(
87535
+ args.document.values.map((value) => [value.id, value])
87536
+ );
87537
+ const hashById = new Map(
87538
+ args.contentHashHeads.filter((head) => head.recordKind === "value" && !head.deleted).map((head) => [head.recordId, head.contentHash])
87539
+ );
87540
+ for (const row of sweepRows) {
87541
+ const compiled = { ...row, value: { ...row.value } };
87542
+ try {
87543
+ compileOne(committedDocument, compiled);
87544
+ } catch (postWriteError) {
87545
+ const current2 = delegateValueRow(
87546
+ structuredClone(currentById.get(row.id))
87547
+ );
87548
+ if (current2 === null) throw postWriteError;
87549
+ try {
87550
+ compileOne(args.document, current2);
87551
+ } catch (preWriteError) {
87552
+ if (sameCompileFailure(preWriteError, postWriteError)) continue;
87553
+ }
87554
+ throw postWriteError;
87555
+ }
87556
+ const current = currentById.get(row.id);
87557
+ if (current === void 0 || canonicallyEqual2(current, compiled)) continue;
87558
+ const contentHash = hashById.get(row.id);
87559
+ if (contentHash === void 0) {
87560
+ throw new Error(
87561
+ `Cannot safely refresh the compiled NeoDelegate closure for value "${row.id}": its current content hash is unavailable.`
87562
+ );
87563
+ }
87564
+ args.prepared.push({
87565
+ recordKind: "value",
87566
+ recordId: row.id,
87567
+ operation: "update",
87568
+ nextData: compiled,
87569
+ intent: createProjectVersionIntent("value.update", {
87570
+ source: "server-neoscript-recompile"
87571
+ }),
87572
+ expectedBaseContentHash: contentHash
87573
+ });
87574
+ }
87575
+ }
85959
87576
  function prepareServerOwnedConstructorBodies(args) {
85960
87577
  const currentById = new Map(
85961
87578
  (args.document.constructors ?? []).map((record3) => [record3.id, record3])
@@ -86245,6 +87862,7 @@ function cloneAndStripClientDerivedBodies(change) {
86245
87862
  if (nextData2 === null) return { ...change, nextData: change.nextData };
86246
87863
  const stripped = { ...nextData2 };
86247
87864
  stripInitializerCompanion(stripped, "init");
87865
+ stripDelegateClosureCompanion(stripped, "value");
86248
87866
  return { ...change, nextData: stripped };
86249
87867
  }
86250
87868
  if (change.recordKind !== "member") {
@@ -86323,9 +87941,26 @@ function stripDerivedBodies(member) {
86323
87941
  if (member.kind === 23 /* NSFunction */) {
86324
87942
  delete next.action;
86325
87943
  }
87944
+ if (member.kind === 25 /* NSDelegate */) {
87945
+ stripDelegateClosureCompanion(next, "defaultValue");
87946
+ }
86326
87947
  stripInitializerCompanion(next, "defaultValue");
86327
87948
  return next;
86328
87949
  }
87950
+ function stripDelegateClosureCompanion(record3, field) {
87951
+ const container = field === "value" ? record3 : asRecord2(record3.defaultValue);
87952
+ if (container === null) return;
87953
+ const delegate = asRecord2(container.value);
87954
+ if (delegate === null || typeof delegate.code !== "string") return;
87955
+ if (!("action" in delegate)) return;
87956
+ const authoredDelegate = { ...delegate };
87957
+ delete authoredDelegate.action;
87958
+ if (field === "value") {
87959
+ record3.value = authoredDelegate;
87960
+ return;
87961
+ }
87962
+ record3.defaultValue = { ...container, value: authoredDelegate };
87963
+ }
86329
87964
  function stripInitializerCompanion(record3, field) {
86330
87965
  const container = field === "init" ? record3 : asRecord2(record3.defaultValue);
86331
87966
  if (container === null) return;