@neocompose/cli 0.89.2 → 0.89.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19377,7 +19377,7 @@ var init_registry = __esm({
19377
19377
  "../packages/manifest/schema-contract/registry.mjs"() {
19378
19378
  "use strict";
19379
19379
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
19380
- cliVersion: "0.89.2",
19380
+ cliVersion: "0.89.3",
19381
19381
  projectFileUploadBatchSize: 32,
19382
19382
  documentRecords: {
19383
19383
  member: {
@@ -28182,7 +28182,7 @@ function suppressesInheritedSetter(contract) {
28182
28182
  function generatedValueTypeInfo(ctx, member) {
28183
28183
  const required2 = isRequiredMember(member);
28184
28184
  if (isMemberTupleBase(member)) return memberTypeInfoForCodegen(ctx, member);
28185
- const slotType = classSlotTypeInfo(member, required2);
28185
+ const slotType = classSlotTypeInfo(ctx, member, required2);
28186
28186
  if (slotType !== null) return slotType;
28187
28187
  const returnType = nsPropertyReturnTypeInfo(member);
28188
28188
  if (returnType !== null) return returnType;
@@ -28191,19 +28191,64 @@ function generatedValueTypeInfo(ctx, member) {
28191
28191
  if (declaredType !== null) return declaredType;
28192
28192
  const entry = resolveLookupEntryMember(ctx, member);
28193
28193
  if (entry === null) return null;
28194
- return classSlotTypeInfo(entry, required2);
28194
+ return classSlotTypeInfo(ctx, entry, required2);
28195
28195
  }
28196
28196
  return null;
28197
28197
  }
28198
- function classSlotTypeInfo(member, required2) {
28198
+ function genericParamTypeInfo(ctx, genericParamId, required2) {
28199
+ const declaration = findGenericParamDeclaration(genericParamId, ctx.classes);
28200
+ if (declaration === null) {
28201
+ ctx.diagnostics.push({
28202
+ severity: "error",
28203
+ message: `Generic param "${genericParamId}" is not declared by any type in the export.`,
28204
+ path: "genericParamId"
28205
+ });
28206
+ return null;
28207
+ }
28208
+ return {
28209
+ type: 21 /* Generic */,
28210
+ required: required2,
28211
+ ownerClassId: declaration.declaringClass.id,
28212
+ genericParamId
28213
+ };
28214
+ }
28215
+ function classSlotTypeInfo(ctx, member, required2) {
28216
+ if (!isClassSlotMember(member)) return null;
28217
+ const typeArguments = {};
28218
+ for (const [parameterId, binding] of Object.entries(
28219
+ declaredSlotArguments(member) ?? {}
28220
+ )) {
28221
+ if (isForwardedGenericBinding(binding)) {
28222
+ const typeInfo = genericParamTypeInfo(ctx, binding.genericParamId, true);
28223
+ if (typeInfo === null) return null;
28224
+ typeArguments[parameterId] = typeInfo;
28225
+ } else {
28226
+ const argument2 = resolveMemberById(
28227
+ ctx,
28228
+ binding.memberId,
28229
+ "classArguments"
28230
+ );
28231
+ if (argument2 === null) return null;
28232
+ const typeInfo = memberTypeInfoForCodegen(ctx, argument2);
28233
+ if (typeInfo === null) return null;
28234
+ typeArguments[parameterId] = typeInfo;
28235
+ }
28236
+ }
28237
+ const argumentsField = Object.keys(typeArguments).length === 0 ? {} : { typeArguments };
28199
28238
  if (isClassTypedMember(member)) {
28200
- return { type: 7 /* Class */, classId: member.classId, required: required2 };
28239
+ return {
28240
+ type: 7 /* Class */,
28241
+ classId: member.classId,
28242
+ required: required2,
28243
+ ...argumentsField
28244
+ };
28201
28245
  }
28202
28246
  if (isInterfaceTypedMember(member)) {
28203
28247
  return {
28204
28248
  type: 22 /* Interface */,
28205
28249
  interfaceId: member.interfaceId,
28206
- required: required2
28250
+ required: required2,
28251
+ ...argumentsField
28207
28252
  };
28208
28253
  }
28209
28254
  return null;
@@ -30341,6 +30386,8 @@ function pointerOwnershipForStorage(storage) {
30341
30386
  }
30342
30387
  function memberTypeInfoForCodegen(ctx, member) {
30343
30388
  const required2 = isRequiredMember(member);
30389
+ if (isMemberGenericBase(member))
30390
+ return genericParamTypeInfo(ctx, member.genericParamId, required2);
30344
30391
  if (isMemberTupleBase(member)) {
30345
30392
  const elements = [];
30346
30393
  for (const [index, id2] of member.elementMemberIds.entries()) {
@@ -30355,7 +30402,7 @@ function memberTypeInfoForCodegen(ctx, member) {
30355
30402
  }
30356
30403
  return { type: 30 /* Tuple */, required: required2, elements };
30357
30404
  }
30358
- const slotType = classSlotTypeInfo(member, required2);
30405
+ const slotType = classSlotTypeInfo(ctx, member, required2);
30359
30406
  if (slotType !== null) return slotType;
30360
30407
  if (isMemberLookupBase(member)) {
30361
30408
  if (member.collectionMemberId === void 0) {
@@ -30880,6 +30927,337 @@ var init_NSGetterRuntimeError = __esm({
30880
30927
  }
30881
30928
  });
30882
30929
 
30930
+ // ../packages/models/src/decimal/decimal-math.ts
30931
+ function pow10(exponent) {
30932
+ return TEN ** BigInt(exponent);
30933
+ }
30934
+ function assertCanonicalInput(value, argName) {
30935
+ const violation = getDecimalStringViolation(value);
30936
+ if (violation !== null) {
30937
+ throw new Error(
30938
+ `Decimal argument "${argName}" (${JSON.stringify(value)}) ${violation}.`
30939
+ );
30940
+ }
30941
+ }
30942
+ function parseDecimalString(value) {
30943
+ return parseDecimalArg(value, "value");
30944
+ }
30945
+ function parseDecimalArg(value, argName) {
30946
+ assertCanonicalInput(value, argName);
30947
+ const negative = value.startsWith("-");
30948
+ const unsigned = negative ? value.slice(1) : value;
30949
+ const pointIndex = unsigned.indexOf(".");
30950
+ const digits = pointIndex === -1 ? unsigned : unsigned.slice(0, pointIndex) + unsigned.slice(pointIndex + 1);
30951
+ const scale = pointIndex === -1 ? 0 : unsigned.length - pointIndex - 1;
30952
+ const magnitude = BigInt(digits);
30953
+ return { coefficient: negative ? -magnitude : magnitude, scale };
30954
+ }
30955
+ function formatDecimalParts(parts) {
30956
+ const negative = parts.coefficient < 0n;
30957
+ const digits = (negative ? -parts.coefficient : parts.coefficient).toString();
30958
+ let unsigned;
30959
+ if (parts.scale === 0) {
30960
+ unsigned = digits;
30961
+ } else {
30962
+ const padded = digits.padStart(parts.scale + 1, "0");
30963
+ const pointIndex = padded.length - parts.scale;
30964
+ unsigned = `${padded.slice(0, pointIndex)}.${padded.slice(pointIndex)}`;
30965
+ }
30966
+ if (parts.coefficient === 0n) return unsigned;
30967
+ return negative ? `-${unsigned}` : unsigned;
30968
+ }
30969
+ function significantDigitCount(coefficient) {
30970
+ const magnitude = coefficient < 0n ? -coefficient : coefficient;
30971
+ return magnitude.toString().length;
30972
+ }
30973
+ function assertWithinEnvelope(parts, operation) {
30974
+ if (significantDigitCount(parts.coefficient) > DECIMAL_MAX_SIGNIFICANT_DIGITS) {
30975
+ throw new DecimalOverflowError(
30976
+ `Decimal overflow in ${operation}: the exact result exceeds ${DECIMAL_MAX_SIGNIFICANT_DIGITS} significant digits. Round explicitly (Round/Divide) to reduce precision.`
30977
+ );
30978
+ }
30979
+ if (parts.scale > DECIMAL_MAX_SCALE) {
30980
+ throw new DecimalOverflowError(
30981
+ `Decimal overflow in ${operation}: the exact result exceeds scale ${DECIMAL_MAX_SCALE}. Round explicitly (Round/Divide) to reduce precision.`
30982
+ );
30983
+ }
30984
+ return parts;
30985
+ }
30986
+ function alignScales(a, b) {
30987
+ const scale = Math.max(a.scale, b.scale);
30988
+ return {
30989
+ a: a.coefficient * pow10(scale - a.scale),
30990
+ b: b.coefficient * pow10(scale - b.scale),
30991
+ scale
30992
+ };
30993
+ }
30994
+ function compareDecimalStrings(a, b) {
30995
+ const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
30996
+ if (aligned.a < aligned.b) return -1;
30997
+ if (aligned.a > aligned.b) return 1;
30998
+ return 0;
30999
+ }
31000
+ function minDecimalStrings(a, b) {
31001
+ return compareDecimalStrings(a, b) <= 0 ? a : b;
31002
+ }
31003
+ function maxDecimalStrings(a, b) {
31004
+ return compareDecimalStrings(a, b) >= 0 ? a : b;
31005
+ }
31006
+ function clampDecimalStrings(value, min, max) {
31007
+ if (compareDecimalStrings(min, max) > 0) {
31008
+ throw new DecimalClampRangeError(MATH_CLAMP_RANGE_MESSAGE);
31009
+ }
31010
+ if (compareDecimalStrings(value, min) < 0) return min;
31011
+ if (compareDecimalStrings(value, max) > 0) return max;
31012
+ return value;
31013
+ }
31014
+ function absDecimalString(value) {
31015
+ const parts = parseDecimalArg(value, "value");
31016
+ const magnitude = parts.coefficient < 0n ? -parts.coefficient : parts.coefficient;
31017
+ return formatDecimalParts({ coefficient: magnitude, scale: parts.scale });
31018
+ }
31019
+ function addDecimalStrings(a, b) {
31020
+ const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
31021
+ return formatDecimalParts(
31022
+ assertWithinEnvelope(
31023
+ { coefficient: aligned.a + aligned.b, scale: aligned.scale },
31024
+ "addition"
31025
+ )
31026
+ );
31027
+ }
31028
+ function subtractDecimalStrings(a, b) {
31029
+ const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
31030
+ return formatDecimalParts(
31031
+ assertWithinEnvelope(
31032
+ { coefficient: aligned.a - aligned.b, scale: aligned.scale },
31033
+ "subtraction"
31034
+ )
31035
+ );
31036
+ }
31037
+ function multiplyDecimalStrings(a, b) {
31038
+ const left = parseDecimalArg(a, "a");
31039
+ const right = parseDecimalArg(b, "b");
31040
+ return formatDecimalParts(
31041
+ assertWithinEnvelope(
31042
+ {
31043
+ coefficient: left.coefficient * right.coefficient,
31044
+ scale: left.scale + right.scale
31045
+ },
31046
+ "multiplication"
31047
+ )
31048
+ );
31049
+ }
31050
+ function assertDigitsInRange(digits, operation) {
31051
+ if (!Number.isInteger(digits)) {
31052
+ throw new DecimalDigitsRangeError(
31053
+ `Decimal ${operation} digits must be an integer (received ${digits}).`
31054
+ );
31055
+ }
31056
+ if (digits < 0 || digits > DECIMAL_MAX_SCALE) {
31057
+ throw new DecimalDigitsRangeError(
31058
+ `Decimal ${operation} digits must be between 0 and ${DECIMAL_MAX_SCALE} (received ${digits}).`
31059
+ );
31060
+ }
31061
+ }
31062
+ function roundDecimalParts(parts, digits, midpoint) {
31063
+ if (digits >= parts.scale) return parts;
31064
+ const divisor = pow10(parts.scale - digits);
31065
+ const negative = parts.coefficient < 0n;
31066
+ const magnitude = negative ? -parts.coefficient : parts.coefficient;
31067
+ let quotient = magnitude / divisor;
31068
+ const doubled = magnitude % divisor * 2n;
31069
+ const tieRoundsUp = midpoint === "awayFromZero" || quotient % 2n === 1n;
31070
+ if (doubled > divisor || doubled === divisor && tieRoundsUp) {
31071
+ quotient += 1n;
31072
+ }
31073
+ return { coefficient: negative ? -quotient : quotient, scale: digits };
31074
+ }
31075
+ function roundDecimalString(value, digits) {
31076
+ assertDigitsInRange(digits, "round");
31077
+ const rounded = roundDecimalParts(
31078
+ parseDecimalArg(value, "value"),
31079
+ digits,
31080
+ "toEven"
31081
+ );
31082
+ return formatDecimalParts(assertWithinEnvelope(rounded, "round"));
31083
+ }
31084
+ function toIntegralParts(parts, direction) {
31085
+ if (parts.scale === 0) return parts;
31086
+ const divisor = pow10(parts.scale);
31087
+ const quotient = parts.coefficient / divisor;
31088
+ const remainder = parts.coefficient % divisor;
31089
+ if (remainder === 0n) return { coefficient: quotient, scale: 0 };
31090
+ if (direction === "floor" && remainder < 0n) {
31091
+ return { coefficient: quotient - 1n, scale: 0 };
31092
+ }
31093
+ if (direction === "ceiling" && remainder > 0n) {
31094
+ return { coefficient: quotient + 1n, scale: 0 };
31095
+ }
31096
+ return { coefficient: quotient, scale: 0 };
31097
+ }
31098
+ function floorDecimalString(value) {
31099
+ const parts = toIntegralParts(parseDecimalArg(value, "value"), "floor");
31100
+ return formatDecimalParts(assertWithinEnvelope(parts, "floor"));
31101
+ }
31102
+ function ceilingDecimalString(value) {
31103
+ const parts = toIntegralParts(parseDecimalArg(value, "value"), "ceiling");
31104
+ return formatDecimalParts(assertWithinEnvelope(parts, "ceiling"));
31105
+ }
31106
+ function truncateDecimalString(value) {
31107
+ const parts = toIntegralParts(parseDecimalArg(value, "value"), "truncate");
31108
+ return formatDecimalParts(assertWithinEnvelope(parts, "truncate"));
31109
+ }
31110
+ function divideDecimalStrings(a, b, digits) {
31111
+ assertDigitsInRange(digits, "divide");
31112
+ const dividend = parseDecimalArg(a, "a");
31113
+ const divisor = parseDecimalArg(b, "b");
31114
+ if (divisor.coefficient === 0n) {
31115
+ throw new DecimalDivisionByZeroError(
31116
+ `Decimal division by zero: ${JSON.stringify(a)} / ${JSON.stringify(b)}.`
31117
+ );
31118
+ }
31119
+ const exponent = divisor.scale - dividend.scale + digits;
31120
+ let numerator = dividend.coefficient;
31121
+ let denominator = divisor.coefficient;
31122
+ if (exponent >= 0) {
31123
+ numerator *= pow10(exponent);
31124
+ } else {
31125
+ denominator *= pow10(-exponent);
31126
+ }
31127
+ const negative = numerator < 0n !== denominator < 0n;
31128
+ const absNumerator = numerator < 0n ? -numerator : numerator;
31129
+ const absDenominator = denominator < 0n ? -denominator : denominator;
31130
+ let quotient = absNumerator / absDenominator;
31131
+ const remainder = absNumerator % absDenominator;
31132
+ const doubled = remainder * 2n;
31133
+ if (doubled > absDenominator || doubled === absDenominator && quotient % 2n === 1n) {
31134
+ quotient += 1n;
31135
+ }
31136
+ const parts = {
31137
+ coefficient: negative ? -quotient : quotient,
31138
+ scale: digits
31139
+ };
31140
+ return formatDecimalParts(assertWithinEnvelope(parts, "division"));
31141
+ }
31142
+ function exactPartsFromFloat(value) {
31143
+ if (Number.isNaN(value)) {
31144
+ throw new DecimalNonFiniteError("Cannot convert NaN to a decimal.");
31145
+ }
31146
+ if (!Number.isFinite(value)) {
31147
+ throw new DecimalNonFiniteError(
31148
+ `Cannot convert ${value > 0 ? "Infinity" : "-Infinity"} to a decimal.`
31149
+ );
31150
+ }
31151
+ const view = new DataView(new ArrayBuffer(8));
31152
+ view.setFloat64(0, value);
31153
+ const bits = view.getBigUint64(0);
31154
+ const negative = bits >> 63n === 1n;
31155
+ const exponentBits = Number(bits >> 52n & 0x7ffn);
31156
+ const mantissaBits = bits & 0xfffffffffffffn;
31157
+ let mantissa;
31158
+ let exponent;
31159
+ if (exponentBits === 0) {
31160
+ mantissa = mantissaBits;
31161
+ exponent = -1074;
31162
+ } else {
31163
+ mantissa = mantissaBits | 1n << 52n;
31164
+ exponent = exponentBits - 1075;
31165
+ }
31166
+ if (mantissa === 0n) return { coefficient: 0n, scale: 0 };
31167
+ if (negative) mantissa = -mantissa;
31168
+ let parts;
31169
+ if (exponent >= 0) {
31170
+ parts = { coefficient: mantissa * (1n << BigInt(exponent)), scale: 0 };
31171
+ } else {
31172
+ parts = {
31173
+ coefficient: mantissa * 5n ** BigInt(-exponent),
31174
+ scale: -exponent
31175
+ };
31176
+ }
31177
+ while (parts.scale > 0 && parts.coefficient % TEN === 0n) {
31178
+ parts = { coefficient: parts.coefficient / TEN, scale: parts.scale - 1 };
31179
+ }
31180
+ return parts;
31181
+ }
31182
+ function decimalStringFromFloat(value, digits) {
31183
+ assertDigitsInRange(digits, "float conversion");
31184
+ const rounded = roundDecimalParts(
31185
+ exactPartsFromFloat(value),
31186
+ digits,
31187
+ "toEven"
31188
+ );
31189
+ return formatDecimalParts(assertWithinEnvelope(rounded, "float conversion"));
31190
+ }
31191
+ function floatFromDecimalString(value) {
31192
+ assertCanonicalInput(value, "value");
31193
+ return Number(value);
31194
+ }
31195
+ var DecimalOverflowError, DecimalDivisionByZeroError, DecimalDigitsRangeError, DecimalNonFiniteError, DecimalClampRangeError, MATH_CLAMP_RANGE_MESSAGE, TEN;
31196
+ var init_decimal_math = __esm({
31197
+ "../packages/models/src/decimal/decimal-math.ts"() {
31198
+ "use strict";
31199
+ init_member_kinds();
31200
+ DecimalOverflowError = class extends Error {
31201
+ };
31202
+ DecimalDivisionByZeroError = class extends Error {
31203
+ };
31204
+ DecimalDigitsRangeError = class extends Error {
31205
+ };
31206
+ DecimalNonFiniteError = class extends Error {
31207
+ };
31208
+ DecimalClampRangeError = class extends Error {
31209
+ };
31210
+ MATH_CLAMP_RANGE_MESSAGE = "Math.Clamp requires min <= max.";
31211
+ TEN = 10n;
31212
+ }
31213
+ });
31214
+
31215
+ // ../packages/neoscript-runtime/src/neoscript/unity-value-format.ts
31216
+ function formatUnityFloat(value, digits) {
31217
+ const single = Math.fround(value);
31218
+ if (!Number.isFinite(single)) return String(single);
31219
+ const [mantissa, exponent] = single.toExponential(6).split("e");
31220
+ const coefficient = BigInt(mantissa.replace(".", ""));
31221
+ const scale = 6 - Number(exponent);
31222
+ const parts = scale < 0 ? { coefficient: coefficient * 10n ** BigInt(-scale), scale: 0 } : { coefficient, scale };
31223
+ const rounded = roundDecimalParts(parts, digits, "awayFromZero");
31224
+ return formatDecimalParts({
31225
+ coefficient: rounded.coefficient * 10n ** BigInt(digits - rounded.scale),
31226
+ scale: digits
31227
+ });
31228
+ }
31229
+ function formatUnityValue(value, kind) {
31230
+ if (typeof value !== "object" || value === null)
31231
+ throw new NSGetterRuntimeError(
31232
+ `Cannot interpolate an invalid ${MemberKind[kind]} value.`
31233
+ );
31234
+ const components2 = structuredLeafFields(kind).map((field) => {
31235
+ const component = Reflect.get(value, field.key);
31236
+ if (typeof component !== "number")
31237
+ throw new NSGetterRuntimeError(
31238
+ `${MemberKind[kind]}.${field.key} must be a number for interpolation.`
31239
+ );
31240
+ if (field.type === "int") {
31241
+ if (!Number.isInteger(component))
31242
+ throw new NSGetterRuntimeError(
31243
+ `${MemberKind[kind]}.${field.key} must be an integer for interpolation.`
31244
+ );
31245
+ return String(component);
31246
+ }
31247
+ return formatUnityFloat(component, kind === 19 /* Color */ ? 3 : 2);
31248
+ });
31249
+ return `${kind === 19 /* Color */ ? "RGBA" : ""}(${components2.join(", ")})`;
31250
+ }
31251
+ var init_unity_value_format = __esm({
31252
+ "../packages/neoscript-runtime/src/neoscript/unity-value-format.ts"() {
31253
+ "use strict";
31254
+ init_member_kind_enum();
31255
+ init_structured_leaf_fields();
31256
+ init_NSGetterRuntimeError();
31257
+ init_decimal_math();
31258
+ }
31259
+ });
31260
+
30883
31261
  // ../packages/neoscript-runtime/src/world-grid-query-reads.ts
30884
31262
  function worldGridQueryReadKey(read) {
30885
31263
  return read.kind === "placement" ? JSON.stringify([read.kind, read.valueId]) : JSON.stringify([read.kind, read.gridId, read.cell.x, read.cell.y]);
@@ -33871,6 +34249,8 @@ function tupleKeyFragment(entryMember, entry, graph) {
33871
34249
  ];
33872
34250
  case 30 /* Tuple */:
33873
34251
  return [member.kind, tupleKeyFragment(member, child2, graph)];
34252
+ case 3 /* String */:
34253
+ return [member.kind, requireString(child2.value, member)];
33874
34254
  default:
33875
34255
  return [member.kind, setEntryKey(member, child2, graph)];
33876
34256
  }
@@ -34864,291 +35244,6 @@ var init_cell_pattern2 = __esm({
34864
35244
  }
34865
35245
  });
34866
35246
 
34867
- // ../packages/models/src/decimal/decimal-math.ts
34868
- function pow10(exponent) {
34869
- return TEN ** BigInt(exponent);
34870
- }
34871
- function assertCanonicalInput(value, argName) {
34872
- const violation = getDecimalStringViolation(value);
34873
- if (violation !== null) {
34874
- throw new Error(
34875
- `Decimal argument "${argName}" (${JSON.stringify(value)}) ${violation}.`
34876
- );
34877
- }
34878
- }
34879
- function parseDecimalString(value) {
34880
- return parseDecimalArg(value, "value");
34881
- }
34882
- function parseDecimalArg(value, argName) {
34883
- assertCanonicalInput(value, argName);
34884
- const negative = value.startsWith("-");
34885
- const unsigned = negative ? value.slice(1) : value;
34886
- const pointIndex = unsigned.indexOf(".");
34887
- const digits = pointIndex === -1 ? unsigned : unsigned.slice(0, pointIndex) + unsigned.slice(pointIndex + 1);
34888
- const scale = pointIndex === -1 ? 0 : unsigned.length - pointIndex - 1;
34889
- const magnitude = BigInt(digits);
34890
- return { coefficient: negative ? -magnitude : magnitude, scale };
34891
- }
34892
- function formatDecimalParts(parts) {
34893
- const negative = parts.coefficient < 0n;
34894
- const digits = (negative ? -parts.coefficient : parts.coefficient).toString();
34895
- let unsigned;
34896
- if (parts.scale === 0) {
34897
- unsigned = digits;
34898
- } else {
34899
- const padded = digits.padStart(parts.scale + 1, "0");
34900
- const pointIndex = padded.length - parts.scale;
34901
- unsigned = `${padded.slice(0, pointIndex)}.${padded.slice(pointIndex)}`;
34902
- }
34903
- if (parts.coefficient === 0n) return unsigned;
34904
- return negative ? `-${unsigned}` : unsigned;
34905
- }
34906
- function significantDigitCount(coefficient) {
34907
- const magnitude = coefficient < 0n ? -coefficient : coefficient;
34908
- return magnitude.toString().length;
34909
- }
34910
- function assertWithinEnvelope(parts, operation) {
34911
- if (significantDigitCount(parts.coefficient) > DECIMAL_MAX_SIGNIFICANT_DIGITS) {
34912
- throw new DecimalOverflowError(
34913
- `Decimal overflow in ${operation}: the exact result exceeds ${DECIMAL_MAX_SIGNIFICANT_DIGITS} significant digits. Round explicitly (Round/Divide) to reduce precision.`
34914
- );
34915
- }
34916
- if (parts.scale > DECIMAL_MAX_SCALE) {
34917
- throw new DecimalOverflowError(
34918
- `Decimal overflow in ${operation}: the exact result exceeds scale ${DECIMAL_MAX_SCALE}. Round explicitly (Round/Divide) to reduce precision.`
34919
- );
34920
- }
34921
- return parts;
34922
- }
34923
- function alignScales(a, b) {
34924
- const scale = Math.max(a.scale, b.scale);
34925
- return {
34926
- a: a.coefficient * pow10(scale - a.scale),
34927
- b: b.coefficient * pow10(scale - b.scale),
34928
- scale
34929
- };
34930
- }
34931
- function compareDecimalStrings(a, b) {
34932
- const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
34933
- if (aligned.a < aligned.b) return -1;
34934
- if (aligned.a > aligned.b) return 1;
34935
- return 0;
34936
- }
34937
- function minDecimalStrings(a, b) {
34938
- return compareDecimalStrings(a, b) <= 0 ? a : b;
34939
- }
34940
- function maxDecimalStrings(a, b) {
34941
- return compareDecimalStrings(a, b) >= 0 ? a : b;
34942
- }
34943
- function clampDecimalStrings(value, min, max) {
34944
- if (compareDecimalStrings(min, max) > 0) {
34945
- throw new DecimalClampRangeError(MATH_CLAMP_RANGE_MESSAGE);
34946
- }
34947
- if (compareDecimalStrings(value, min) < 0) return min;
34948
- if (compareDecimalStrings(value, max) > 0) return max;
34949
- return value;
34950
- }
34951
- function absDecimalString(value) {
34952
- const parts = parseDecimalArg(value, "value");
34953
- const magnitude = parts.coefficient < 0n ? -parts.coefficient : parts.coefficient;
34954
- return formatDecimalParts({ coefficient: magnitude, scale: parts.scale });
34955
- }
34956
- function addDecimalStrings(a, b) {
34957
- const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
34958
- return formatDecimalParts(
34959
- assertWithinEnvelope(
34960
- { coefficient: aligned.a + aligned.b, scale: aligned.scale },
34961
- "addition"
34962
- )
34963
- );
34964
- }
34965
- function subtractDecimalStrings(a, b) {
34966
- const aligned = alignScales(parseDecimalArg(a, "a"), parseDecimalArg(b, "b"));
34967
- return formatDecimalParts(
34968
- assertWithinEnvelope(
34969
- { coefficient: aligned.a - aligned.b, scale: aligned.scale },
34970
- "subtraction"
34971
- )
34972
- );
34973
- }
34974
- function multiplyDecimalStrings(a, b) {
34975
- const left = parseDecimalArg(a, "a");
34976
- const right = parseDecimalArg(b, "b");
34977
- return formatDecimalParts(
34978
- assertWithinEnvelope(
34979
- {
34980
- coefficient: left.coefficient * right.coefficient,
34981
- scale: left.scale + right.scale
34982
- },
34983
- "multiplication"
34984
- )
34985
- );
34986
- }
34987
- function assertDigitsInRange(digits, operation) {
34988
- if (!Number.isInteger(digits)) {
34989
- throw new DecimalDigitsRangeError(
34990
- `Decimal ${operation} digits must be an integer (received ${digits}).`
34991
- );
34992
- }
34993
- if (digits < 0 || digits > DECIMAL_MAX_SCALE) {
34994
- throw new DecimalDigitsRangeError(
34995
- `Decimal ${operation} digits must be between 0 and ${DECIMAL_MAX_SCALE} (received ${digits}).`
34996
- );
34997
- }
34998
- }
34999
- function roundDecimalParts(parts, digits, midpoint) {
35000
- if (digits >= parts.scale) return parts;
35001
- const divisor = pow10(parts.scale - digits);
35002
- const negative = parts.coefficient < 0n;
35003
- const magnitude = negative ? -parts.coefficient : parts.coefficient;
35004
- let quotient = magnitude / divisor;
35005
- const doubled = magnitude % divisor * 2n;
35006
- const tieRoundsUp = midpoint === "awayFromZero" || quotient % 2n === 1n;
35007
- if (doubled > divisor || doubled === divisor && tieRoundsUp) {
35008
- quotient += 1n;
35009
- }
35010
- return { coefficient: negative ? -quotient : quotient, scale: digits };
35011
- }
35012
- function roundDecimalString(value, digits) {
35013
- assertDigitsInRange(digits, "round");
35014
- const rounded = roundDecimalParts(
35015
- parseDecimalArg(value, "value"),
35016
- digits,
35017
- "toEven"
35018
- );
35019
- return formatDecimalParts(assertWithinEnvelope(rounded, "round"));
35020
- }
35021
- function toIntegralParts(parts, direction) {
35022
- if (parts.scale === 0) return parts;
35023
- const divisor = pow10(parts.scale);
35024
- const quotient = parts.coefficient / divisor;
35025
- const remainder = parts.coefficient % divisor;
35026
- if (remainder === 0n) return { coefficient: quotient, scale: 0 };
35027
- if (direction === "floor" && remainder < 0n) {
35028
- return { coefficient: quotient - 1n, scale: 0 };
35029
- }
35030
- if (direction === "ceiling" && remainder > 0n) {
35031
- return { coefficient: quotient + 1n, scale: 0 };
35032
- }
35033
- return { coefficient: quotient, scale: 0 };
35034
- }
35035
- function floorDecimalString(value) {
35036
- const parts = toIntegralParts(parseDecimalArg(value, "value"), "floor");
35037
- return formatDecimalParts(assertWithinEnvelope(parts, "floor"));
35038
- }
35039
- function ceilingDecimalString(value) {
35040
- const parts = toIntegralParts(parseDecimalArg(value, "value"), "ceiling");
35041
- return formatDecimalParts(assertWithinEnvelope(parts, "ceiling"));
35042
- }
35043
- function truncateDecimalString(value) {
35044
- const parts = toIntegralParts(parseDecimalArg(value, "value"), "truncate");
35045
- return formatDecimalParts(assertWithinEnvelope(parts, "truncate"));
35046
- }
35047
- function divideDecimalStrings(a, b, digits) {
35048
- assertDigitsInRange(digits, "divide");
35049
- const dividend = parseDecimalArg(a, "a");
35050
- const divisor = parseDecimalArg(b, "b");
35051
- if (divisor.coefficient === 0n) {
35052
- throw new DecimalDivisionByZeroError(
35053
- `Decimal division by zero: ${JSON.stringify(a)} / ${JSON.stringify(b)}.`
35054
- );
35055
- }
35056
- const exponent = divisor.scale - dividend.scale + digits;
35057
- let numerator = dividend.coefficient;
35058
- let denominator = divisor.coefficient;
35059
- if (exponent >= 0) {
35060
- numerator *= pow10(exponent);
35061
- } else {
35062
- denominator *= pow10(-exponent);
35063
- }
35064
- const negative = numerator < 0n !== denominator < 0n;
35065
- const absNumerator = numerator < 0n ? -numerator : numerator;
35066
- const absDenominator = denominator < 0n ? -denominator : denominator;
35067
- let quotient = absNumerator / absDenominator;
35068
- const remainder = absNumerator % absDenominator;
35069
- const doubled = remainder * 2n;
35070
- if (doubled > absDenominator || doubled === absDenominator && quotient % 2n === 1n) {
35071
- quotient += 1n;
35072
- }
35073
- const parts = {
35074
- coefficient: negative ? -quotient : quotient,
35075
- scale: digits
35076
- };
35077
- return formatDecimalParts(assertWithinEnvelope(parts, "division"));
35078
- }
35079
- function exactPartsFromFloat(value) {
35080
- if (Number.isNaN(value)) {
35081
- throw new DecimalNonFiniteError("Cannot convert NaN to a decimal.");
35082
- }
35083
- if (!Number.isFinite(value)) {
35084
- throw new DecimalNonFiniteError(
35085
- `Cannot convert ${value > 0 ? "Infinity" : "-Infinity"} to a decimal.`
35086
- );
35087
- }
35088
- const view = new DataView(new ArrayBuffer(8));
35089
- view.setFloat64(0, value);
35090
- const bits = view.getBigUint64(0);
35091
- const negative = bits >> 63n === 1n;
35092
- const exponentBits = Number(bits >> 52n & 0x7ffn);
35093
- const mantissaBits = bits & 0xfffffffffffffn;
35094
- let mantissa;
35095
- let exponent;
35096
- if (exponentBits === 0) {
35097
- mantissa = mantissaBits;
35098
- exponent = -1074;
35099
- } else {
35100
- mantissa = mantissaBits | 1n << 52n;
35101
- exponent = exponentBits - 1075;
35102
- }
35103
- if (mantissa === 0n) return { coefficient: 0n, scale: 0 };
35104
- if (negative) mantissa = -mantissa;
35105
- let parts;
35106
- if (exponent >= 0) {
35107
- parts = { coefficient: mantissa * (1n << BigInt(exponent)), scale: 0 };
35108
- } else {
35109
- parts = {
35110
- coefficient: mantissa * 5n ** BigInt(-exponent),
35111
- scale: -exponent
35112
- };
35113
- }
35114
- while (parts.scale > 0 && parts.coefficient % TEN === 0n) {
35115
- parts = { coefficient: parts.coefficient / TEN, scale: parts.scale - 1 };
35116
- }
35117
- return parts;
35118
- }
35119
- function decimalStringFromFloat(value, digits) {
35120
- assertDigitsInRange(digits, "float conversion");
35121
- const rounded = roundDecimalParts(
35122
- exactPartsFromFloat(value),
35123
- digits,
35124
- "toEven"
35125
- );
35126
- return formatDecimalParts(assertWithinEnvelope(rounded, "float conversion"));
35127
- }
35128
- function floatFromDecimalString(value) {
35129
- assertCanonicalInput(value, "value");
35130
- return Number(value);
35131
- }
35132
- var DecimalOverflowError, DecimalDivisionByZeroError, DecimalDigitsRangeError, DecimalNonFiniteError, DecimalClampRangeError, MATH_CLAMP_RANGE_MESSAGE, TEN;
35133
- var init_decimal_math = __esm({
35134
- "../packages/models/src/decimal/decimal-math.ts"() {
35135
- "use strict";
35136
- init_member_kinds();
35137
- DecimalOverflowError = class extends Error {
35138
- };
35139
- DecimalDivisionByZeroError = class extends Error {
35140
- };
35141
- DecimalDigitsRangeError = class extends Error {
35142
- };
35143
- DecimalNonFiniteError = class extends Error {
35144
- };
35145
- DecimalClampRangeError = class extends Error {
35146
- };
35147
- MATH_CLAMP_RANGE_MESSAGE = "Math.Clamp requires min <= max.";
35148
- TEN = 10n;
35149
- }
35150
- });
35151
-
35152
35247
  // ../packages/neoscript-language/src/text-formats.ts
35153
35248
  function formatSpecifier(letter) {
35154
35249
  switch (letter) {
@@ -43212,13 +43307,6 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43212
43307
  } else if (ins.mutation === "Add" /* Add */ && !isArrayCollection(targetValue)) {
43213
43308
  overlayArgs[1] = findKnownRowIdByValueReference(args[1], ctx) ?? args[1];
43214
43309
  }
43215
- if (ins.mutation === "Add" /* Add */ && isArrayCollection(targetValue) && unorderedContainerValueId !== null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null) {
43216
- overlayArgs[0] = createUnorderedScalarProjectionEntry(
43217
- unorderedContainerValueId,
43218
- args[0] instanceof NSSlotReference ? [args[0].targetId] : args[0],
43219
- ctx
43220
- );
43221
- }
43222
43310
  const unorderedEntriesBeforeMutation = unorderedContainerValueId === null || !Array.isArray(targetValue) || ins.mutation === "Add" /* Add */ ? null : [...targetValue];
43223
43311
  const writesEntry = (ins.mutation === "Add" /* Add */ || ins.mutation === "Insert" /* Insert */) && !isLookupSet;
43224
43312
  let attachedValueId = null;
@@ -43253,6 +43341,13 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43253
43341
  );
43254
43342
  }
43255
43343
  }
43344
+ if (ins.mutation === "Add" /* Add */ && isArrayCollection(targetValue) && unorderedContainerValueId !== null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null) {
43345
+ overlayArgs[0] = createUnorderedScalarProjectionEntry(
43346
+ unorderedContainerValueId,
43347
+ args[0] instanceof NSSlotReference ? [args[0].targetId] : args[0],
43348
+ ctx
43349
+ );
43350
+ }
43256
43351
  const removableRowIds = isLookupSet || ins.reference === true ? null : removableEntryRowIds(targetValue, ins.mutation, overlayArgs, ctx);
43257
43352
  const removedIndex = applyLocalCollectionMutation(
43258
43353
  targetValue,
@@ -45970,9 +46065,16 @@ function formatDebugValue(value, type2, ctx) {
45970
46065
  }
45971
46066
  function formatForInterp(value, sourceType, ctx) {
45972
46067
  if (value === null || value === void 0) return "";
46068
+ sourceType = runtimeConcreteTypeInfo(sourceType, ctx);
45973
46069
  const sequenceType = inspectNeoScriptSequenceType(ctx, sourceType);
45974
- if (sequenceType !== null) return `(${sequenceType}, unenumerated)`;
46070
+ if (sequenceType !== null) return `<${sequenceType} unenumerated>`;
45975
46071
  switch (sourceType.type) {
46072
+ case 14 /* Vector2 */:
46073
+ case 16 /* Vector3 */:
46074
+ case 15 /* Vector2Int */:
46075
+ case 17 /* Vector3Int */:
46076
+ case 19 /* Color */:
46077
+ return formatUnityValue(value, sourceType.type);
45976
46078
  case 8 /* Enum */: {
45977
46079
  const cbId = sourceType.enumId;
45978
46080
  const cb = evaluatorSchemaIndex(ctx).enum(cbId);
@@ -53965,6 +54067,7 @@ var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, DELEGATE_LEXICAL_TYPE_ARGUMENT
53965
54067
  var init_evaluateNSGetter = __esm({
53966
54068
  "../packages/neoscript-runtime/src/neoscript/evaluateNSGetter.ts"() {
53967
54069
  "use strict";
54070
+ init_unity_value_format();
53968
54071
  init_sequence_dependencies();
53969
54072
  init_sequence_contract();
53970
54073
  init_type_info_compatibility();
@@ -55733,7 +55836,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
55733
55836
  Object.entries(declaredSlotArguments(resolved) ?? {}).flatMap(
55734
55837
  ([genericParamId, binding]) => {
55735
55838
  if (!isMemberGenericBinding(binding)) {
55736
- const forwarded = genericParamTypeInfo(
55839
+ const forwarded = genericParamTypeInfo2(
55737
55840
  ownerClass,
55738
55841
  binding.genericParamId,
55739
55842
  true
@@ -55881,7 +55984,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
55881
55984
  if (resolved.kind === 9 /* Lookup */) return null;
55882
55985
  if (!memberKindSupportsStorage(resolved.kind)) return null;
55883
55986
  if (isMemberGenericBase(resolved)) {
55884
- return genericParamTypeInfo(
55987
+ return genericParamTypeInfo2(
55885
55988
  ownerClass,
55886
55989
  resolved.genericParamId,
55887
55990
  isRequiredMember(resolved)
@@ -55892,7 +55995,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
55892
55995
  required: isRequiredMember(resolved)
55893
55996
  };
55894
55997
  }
55895
- function genericParamTypeInfo(ownerClass, genericParamId, required2) {
55998
+ function genericParamTypeInfo2(ownerClass, genericParamId, required2) {
55896
55999
  if (ownerClass === null) return null;
55897
56000
  const declaration = ownerClass.genericParams?.find(
55898
56001
  (parameter4) => parameter4.id === genericParamId
@@ -85597,6 +85700,20 @@ function substituteManifestType(type2, genericEnvironment, environment, seenPara
85597
85700
  )
85598
85701
  };
85599
85702
  }
85703
+ if (type2.kind === "tuple") {
85704
+ return {
85705
+ ...type2,
85706
+ elements: type2.elements.map((element) => ({
85707
+ ...element,
85708
+ type: substituteManifestType(
85709
+ element.type,
85710
+ genericEnvironment,
85711
+ environment,
85712
+ seenParameters
85713
+ )
85714
+ }))
85715
+ };
85716
+ }
85600
85717
  if (type2.kind === "dictionary") {
85601
85718
  return {
85602
85719
  ...type2,
@@ -87325,6 +87442,10 @@ function createNeoScriptDocumentContextInScope(context, projectOverride) {
87325
87442
  ...parameterDefaultDescriptor(argument2, context)
87326
87443
  }));
87327
87444
  const member = context.memberId ? analyzerMemberById(context, context.memberId) : void 0;
87445
+ const declaringClass2 = context.declaringClass ?? context.thisClass ?? (member && isStaticMember(member) ? context.vm.classes.find(
87446
+ (candidate) => Object.values(candidate.schema).includes(member.id)
87447
+ ) : void 0);
87448
+ const declaringType = declaringClass2 ? namedType(declaringClass2.id, true) : void 0;
87328
87449
  let functionName = context.functionName;
87329
87450
  if (functionName === void 0 && member) {
87330
87451
  const accessor = documentKind === "getter" || documentKind === "setter" ? documentKind : void 0;
@@ -87334,10 +87455,15 @@ function createNeoScriptDocumentContextInScope(context, projectOverride) {
87334
87455
  kind: documentKind,
87335
87456
  project,
87336
87457
  ...thisClass ? { thisClass } : {},
87458
+ ...declaringType ? {
87459
+ declaringType,
87460
+ implicitMemberAccess: true,
87461
+ staticMember: context.staticMember ?? isStaticMember(member) === true
87462
+ } : {},
87337
87463
  ...isExtensionMember(member) ? {
87338
87464
  declaringType: null,
87339
87465
  implicitMemberAccess: false,
87340
- staticMember: isStaticMember(member) === true,
87466
+ staticMember: context.staticMember ?? isStaticMember(member) === true,
87341
87467
  extensionReceiver: toLanguageType(
87342
87468
  member.extension.receiverType,
87343
87469
  context
@@ -88933,7 +89059,9 @@ function projectLanguageVersion(context) {
88933
89059
  context.vm.project.id,
88934
89060
  context.vm.project.updatedAt,
88935
89061
  ...projectRootMemberIds(context.vm.project),
88936
- ...records3.map((record7) => `${record7.id}:${record7.updatedAt}`).sort()
89062
+ ...records3.map((record7) => `${record7.id}:${record7.updatedAt}`).sort(),
89063
+ JSON.stringify(context.variants ?? []),
89064
+ JSON.stringify(context.variantFolders ?? [])
88937
89065
  ].join("|");
88938
89066
  }
88939
89067
  function virtualSourceUri(context, directory, fileName2) {
@@ -89428,6 +89556,8 @@ function createContext(ctx, options) {
89428
89556
  const analyzer = {
89429
89557
  vm: prepared ?? createAnalyzerProject(ctx),
89430
89558
  thisClass: ctx.thisClass,
89559
+ declaringClass: ctx.declaringClass,
89560
+ staticMember: ctx.staticMember,
89431
89561
  memberId: ctx.memberId,
89432
89562
  functionName: ctx.functionName,
89433
89563
  ...ctx.valueAliases ? { valueAliases: ctx.valueAliases } : {},
@@ -89447,6 +89577,8 @@ function createContext(ctx, options) {
89447
89577
  );
89448
89578
  const replayContext = ctx.storedConstructionReplay === true ? { ...adapted, storedConstructionReplay: true } : adapted;
89449
89579
  if (adapted.extensionReceiver) return replayContext;
89580
+ if (ctx.implicitMemberAccess === false)
89581
+ return { ...replayContext, implicitMemberAccess: false };
89450
89582
  if (ctx.implicitMemberAccess !== true) return replayContext;
89451
89583
  return {
89452
89584
  ...replayContext,
@@ -89570,6 +89702,48 @@ var init_compiler_adapter = __esm({
89570
89702
  }
89571
89703
  });
89572
89704
 
89705
+ // ../src/database/neoscript/initializer-context.ts
89706
+ function memberInitializerContext(code, declaringClass2, isStatic, constructors) {
89707
+ const instanceClass = isStatic ? null : declaringClass2;
89708
+ let lexicalThisClass = null;
89709
+ try {
89710
+ if (parseExpression(code).kind === "lambda")
89711
+ lexicalThisClass = instanceClass;
89712
+ } catch {
89713
+ }
89714
+ return {
89715
+ declaringClass: declaringClass2,
89716
+ lexicalThisClass,
89717
+ argumentTypes: initializerArgumentTypes(instanceClass, constructors)
89718
+ };
89719
+ }
89720
+ function initializerArgumentTypes(ownerClass, constructors) {
89721
+ if (ownerClass === null) return void 0;
89722
+ const requiredConstructorId2 = ownerClass.requiredConstructorId;
89723
+ if (requiredConstructorId2 === void 0) return void 0;
89724
+ if (requiredConstructorId2 === null) return void 0;
89725
+ const required2 = constructors.find(
89726
+ (constructor2) => constructor2.id === requiredConstructorId2
89727
+ );
89728
+ if (required2 === void 0) {
89729
+ throw new Error(
89730
+ `Class "${ownerClass.name}" names required constructor "${requiredConstructorId2}", but no such constructor record was loaded.`
89731
+ );
89732
+ }
89733
+ if (required2.classId !== ownerClass.id) {
89734
+ throw new Error(
89735
+ `Class "${ownerClass.name}" names required constructor "${requiredConstructorId2}", which is owned by class "${required2.classId}".`
89736
+ );
89737
+ }
89738
+ return required2.argumentTypes.map((argument2) => ({ ...argument2 }));
89739
+ }
89740
+ var init_initializer_context2 = __esm({
89741
+ "../src/database/neoscript/initializer-context.ts"() {
89742
+ "use strict";
89743
+ init_executable_parser();
89744
+ }
89745
+ });
89746
+
89573
89747
  // ../src/database/compile-ns-property.ts
89574
89748
  function compilationProjectContext(args, members2 = args.members) {
89575
89749
  return {
@@ -89764,7 +89938,6 @@ function compileMemberInitializerBody(args) {
89764
89938
  `Member "${args.member.name}" has an initializer but no resolvable declared type.`
89765
89939
  );
89766
89940
  }
89767
- const instanceClass = isStaticMember(args.member) ? null : args.thisClass;
89768
89941
  let compiled;
89769
89942
  try {
89770
89943
  compiled = compileUnit2(
@@ -89776,10 +89949,10 @@ function compileMemberInitializerBody(args) {
89776
89949
  variantFolders: args.variantFolders ?? [],
89777
89950
  returnTypeInfo,
89778
89951
  initializerName: args.member.name,
89779
- lexicalThisClass: parseExpression(defaultValue.init.code).kind === "lambda" ? instanceClass : null,
89780
- declaringClass: args.thisClass,
89781
- argumentTypes: initializerArgumentTypes(
89782
- instanceClass,
89952
+ ...memberInitializerContext(
89953
+ defaultValue.init.code,
89954
+ args.thisClass,
89955
+ isStaticMember(args.member) === true,
89783
89956
  args.constructors ?? []
89784
89957
  )
89785
89958
  })
@@ -89843,26 +90016,6 @@ function compileValueRowInitializerBody(args) {
89843
90016
  }
89844
90017
  Object.assign(container.init, { compiled });
89845
90018
  }
89846
- function initializerArgumentTypes(ownerClass, constructors) {
89847
- if (ownerClass === null) return void 0;
89848
- const requiredConstructorId2 = ownerClass.requiredConstructorId;
89849
- if (requiredConstructorId2 === void 0) return void 0;
89850
- if (requiredConstructorId2 === null) return void 0;
89851
- const required2 = constructors.find(
89852
- (constructor2) => constructor2.id === requiredConstructorId2
89853
- );
89854
- if (required2 === void 0) {
89855
- throw new Error(
89856
- `Class "${ownerClass.name}" names required constructor "${requiredConstructorId2}", but no such constructor record was loaded.`
89857
- );
89858
- }
89859
- if (required2.classId !== ownerClass.id) {
89860
- throw new Error(
89861
- `Class "${ownerClass.name}" names required constructor "${requiredConstructorId2}", which is owned by class "${required2.classId}".`
89862
- );
89863
- }
89864
- return required2.argumentTypes.map((argument2) => ({ ...argument2 }));
89865
- }
89866
90019
  function compileAuthoredMemberBodies(args) {
89867
90020
  compileNSPropertyBodies(args);
89868
90021
  compileNSFunctionBody(args);
@@ -90241,7 +90394,7 @@ var init_compile_ns_property = __esm({
90241
90394
  init_compile_delegate_closure();
90242
90395
  init_compiler_adapter();
90243
90396
  init_compiler_adapter();
90244
- init_executable_parser();
90397
+ init_initializer_context2();
90245
90398
  NeoScriptBodyCompileError = class extends Error {
90246
90399
  memberId;
90247
90400
  memberName;
@@ -100880,6 +101033,15 @@ function substituteInheritedSourceMember(member, baseInfo, resolvedBaseType) {
100880
101033
  if (type2.kind === "list" || type2.kind === "set") {
100881
101034
  return { ...type2, elementType: substitute2(type2.elementType) };
100882
101035
  }
101036
+ if (type2.kind === "tuple") {
101037
+ return {
101038
+ ...type2,
101039
+ elements: type2.elements.map((element) => ({
101040
+ ...element,
101041
+ type: substitute2(element.type)
101042
+ }))
101043
+ };
101044
+ }
100883
101045
  if (type2.kind === "dictionary") {
100884
101046
  return {
100885
101047
  ...type2,
@@ -119841,7 +120003,7 @@ function genericEnvironmentKey(env) {
119841
120003
  [...env].sort(([left], [right]) => left.localeCompare(right))
119842
120004
  );
119843
120005
  }
119844
- function createTypedValueNormalizer(reader, document, childrenByContainerId, parameterTypesForRow, memberById2, memberTypeInfo2, genericEnvironmentForRow, rowIdentities, readTracking, referenceTargets, localizedTexts) {
120006
+ function createTypedValueNormalizer(reader, document, childrenByContainerId, parameterTypesForRow, memberById2, memberTypeInfo2, genericEnvironmentForRow, rowIdentities, readTracking, referenceTargets, localizedTexts, classMemberIdentities) {
119845
120007
  const visiting = /* @__PURE__ */ new Set();
119846
120008
  const completed = /* @__PURE__ */ new Map();
119847
120009
  const compare2 = createEffectiveValueComparator();
@@ -120048,23 +120210,26 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
120048
120210
  document.members
120049
120211
  );
120050
120212
  const members2 = /* @__PURE__ */ new Map();
120051
- const keys = /* @__PURE__ */ new Set();
120213
+ const keys = /* @__PURE__ */ new Map();
120052
120214
  for (const entry of merged) {
120053
120215
  if (entry.memberId === null) continue;
120054
120216
  const member = memberById2(entry.memberId);
120055
120217
  if (member === void 0) continue;
120056
120218
  members2.set(entry.schemaKey, member);
120057
- keys.add(entry.schemaKey);
120219
+ keys.set(entry.schemaKey, `member:${entry.memberId}`);
120220
+ }
120221
+ for (const key of Object.keys(row.value)) {
120222
+ if (!keys.has(key)) keys.set(key, `key:${key}`);
120058
120223
  }
120059
- for (const key of Object.keys(row.value)) keys.add(key);
120060
120224
  const result = /* @__PURE__ */ Object.create(null);
120061
- for (const schemaKey of keys) {
120225
+ for (const [schemaKey, identity3] of keys) {
120226
+ const outputKey = classMemberIdentities ? identity3 : schemaKey;
120062
120227
  const rawMember = members2.get(schemaKey);
120063
120228
  const member = rawMember === void 0 ? void 0 : substituteMember(rawMember, env, document.members);
120064
120229
  if (member === void 0) {
120065
120230
  const childId2 = row.value[schemaKey];
120066
120231
  if (childId2 !== void 0)
120067
- result[schemaKey] = normalizeOpaqueOwnedRow(childId2);
120232
+ result[outputKey] = normalizeOpaqueOwnedRow(childId2);
120068
120233
  continue;
120069
120234
  }
120070
120235
  if (!memberKindOwnsStoredValue(member.kind)) continue;
@@ -120077,17 +120242,17 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
120077
120242
  });
120078
120243
  if (slot.kind === "missing") continue;
120079
120244
  if (slot.kind === "null") {
120080
- result[schemaKey] = { value: null };
120245
+ result[outputKey] = { value: null };
120081
120246
  continue;
120082
120247
  }
120083
120248
  const childId = slot.kind === "declaration" ? reader.declarationRow(member, env).id : slot.value;
120084
120249
  const type2 = memberTypeInfo2(member, env);
120085
120250
  if (typeof childId !== "string") {
120086
- result[schemaKey] = normalizeLiteral(childId);
120251
+ result[outputKey] = normalizeLiteral(childId);
120087
120252
  } else if (type2 === null) {
120088
- result[schemaKey] = normalizeOpaqueOwnedRow(childId);
120253
+ result[outputKey] = normalizeOpaqueOwnedRow(childId);
120089
120254
  } else {
120090
- result[schemaKey] = normalizeTypedRow(childId, type2, member, env);
120255
+ result[outputKey] = normalizeTypedRow(childId, type2, member, env);
120091
120256
  }
120092
120257
  }
120093
120258
  return result;
@@ -120197,7 +120362,8 @@ var init_effective_value_reader = __esm({
120197
120362
  materializedIndex;
120198
120363
  storedPlacements;
120199
120364
  graphCache;
120200
- createNormalizer(rowIdentities, referenceTargets) {
120365
+ constructorArgumentNormalizer;
120366
+ createNormalizer(rowIdentities, referenceTargets, classMemberIdentities = false) {
120201
120367
  return createTypedValueNormalizer(
120202
120368
  this,
120203
120369
  this.document,
@@ -120209,7 +120375,8 @@ var init_effective_value_reader = __esm({
120209
120375
  rowIdentities,
120210
120376
  this.context.readTracking,
120211
120377
  referenceTargets,
120212
- this.localizedTextsById()
120378
+ this.localizedTextsById(),
120379
+ classMemberIdentities
120213
120380
  );
120214
120381
  }
120215
120382
  localizedTextsById() {
@@ -120629,7 +120796,15 @@ var init_effective_value_reader = __esm({
120629
120796
  normalizeConstructorArguments(args, root, placement) {
120630
120797
  if (placement !== void 0) this.placements.set(root.id, placement);
120631
120798
  assertStoredConstructionStamp(root);
120632
- return this.normalizer.normalizeConstructorArgs(args, root);
120799
+ this.constructorArgumentNormalizer ??= this.createNormalizer(
120800
+ void 0,
120801
+ void 0,
120802
+ true
120803
+ );
120804
+ return this.constructorArgumentNormalizer.normalizeConstructorArgs(
120805
+ args,
120806
+ root
120807
+ );
120633
120808
  }
120634
120809
  normalizeTypedRow(valueId, typeInfo, placement, env, rowIdentities, referenceTargets) {
120635
120810
  if (placement !== void 0) this.placements.set(valueId, placement);
@@ -140536,22 +140711,23 @@ var init_project_commit_preparation_scoped_loader = __esm({
140536
140711
  // ../src/database/compiled-construction-types.ts
140537
140712
  function compiledConstructionTypeMembers(members2, bodies, projectId) {
140538
140713
  const created = [];
140714
+ const createdKeys = [];
140539
140715
  let existingIds;
140540
140716
  const byType = /* @__PURE__ */ new Map();
140541
140717
  const key = (type2) => canonicalJsonStringify(type2);
140542
- const intern = (type2) => {
140543
- const signature2 = key(type2);
140544
- const existing = byType.get(signature2);
140718
+ const intern = (type2, slot) => {
140719
+ const cacheKey = slot?.id ?? key(type2);
140720
+ const existing = byType.get(cacheKey);
140545
140721
  if (existing !== void 0) return existing;
140546
140722
  if (type2.type === 21 /* Generic */ || type2.type === NS_TYPE_UNKNOWN)
140547
140723
  return null;
140548
- const id2 = v5_default(
140549
- `neo:compiled-construction-type:${projectId}:${signature2}`,
140724
+ const id2 = slot?.id ?? v5_default(
140725
+ `neo:compiled-construction-type:${projectId}:${cacheKey}`,
140550
140726
  v5_default.URL
140551
140727
  );
140552
140728
  existingIds ??= new Set(members2.map((member) => member.id));
140553
140729
  if (existingIds.has(id2)) {
140554
- byType.set(signature2, id2);
140730
+ byType.set(cacheKey, id2);
140555
140731
  return id2;
140556
140732
  }
140557
140733
  const common = {
@@ -140559,11 +140735,24 @@ function compiledConstructionTypeMembers(members2, bodies, projectId) {
140559
140735
  projectId,
140560
140736
  createdAt: 0,
140561
140737
  updatedAt: 0,
140562
- name: "Type argument",
140738
+ name: slot?.name ?? "Type argument",
140563
140739
  kind: type2.type,
140564
140740
  requirement: type2.required ? 1 /* Required */ : 0 /* Optional */
140565
140741
  };
140742
+ const mark = created.length;
140566
140743
  const fields = (() => {
140744
+ if (type2.type === 30 /* Tuple */) {
140745
+ const elementMemberIds = [];
140746
+ for (const [index, element] of type2.elements.entries()) {
140747
+ const memberId = intern(element.typeInfo, {
140748
+ id: derivedTupleElementMemberId(id2, index),
140749
+ name: element.name ?? `Item${index + 1}`
140750
+ });
140751
+ if (memberId === null) return null;
140752
+ elementMemberIds.push(memberId);
140753
+ }
140754
+ return { elementMemberIds };
140755
+ }
140567
140756
  if (type2.type === 6 /* List */ || type2.type === 28 /* Set */ || type2.type === 5 /* Dictionary */) {
140568
140757
  const entryMemberId = intern(type2.entryTypeInfo);
140569
140758
  if (entryMemberId === null) return null;
@@ -140607,10 +140796,15 @@ function compiledConstructionTypeMembers(members2, bodies, projectId) {
140607
140796
  return {};
140608
140797
  }
140609
140798
  })();
140610
- if (fields === null) return null;
140799
+ if (fields === null) {
140800
+ for (const member of created.splice(mark)) existingIds.delete(member.id);
140801
+ for (const key2 of createdKeys.splice(mark)) byType.delete(key2);
140802
+ return null;
140803
+ }
140611
140804
  created.push({ ...common, ...fields });
140805
+ createdKeys.push(cacheKey);
140612
140806
  existingIds.add(id2);
140613
- byType.set(signature2, id2);
140807
+ byType.set(cacheKey, id2);
140614
140808
  return id2;
140615
140809
  };
140616
140810
  const visited = /* @__PURE__ */ new Set();
@@ -140664,6 +140858,7 @@ var init_compiled_construction_types = __esm({
140664
140858
  init_neoscript_guards();
140665
140859
  init_neoscript();
140666
140860
  init_project_content_hash();
140861
+ init_tuple_element_member_id();
140667
140862
  }
140668
140863
  });
140669
140864
 
@@ -141584,7 +141779,7 @@ var init_stored_closure_captures = __esm({
141584
141779
  });
141585
141780
 
141586
141781
  // ../src/database/construction-replay-equality.ts
141587
- function createConstructionReplayComparer(reader, ownedValueIds) {
141782
+ function createConstructionReplayComparer(reader, ownedValueIds, replayReader = reader) {
141588
141783
  let graph;
141589
141784
  return (args) => {
141590
141785
  if (!isLiteralValueContent(args.currentRoot)) return false;
@@ -141621,7 +141816,7 @@ function createConstructionReplayComparer(reader, ownedValueIds) {
141621
141816
  args.currentRoot,
141622
141817
  args.rootMember
141623
141818
  ),
141624
- reader.withRowOverrides(args.replayRows).normalizeConstructorArguments(
141819
+ replayReader.withRowOverrides(args.replayRows).normalizeConstructorArguments(
141625
141820
  replayed,
141626
141821
  args.replayRoot,
141627
141822
  args.rootMember
@@ -158664,6 +158859,12 @@ function compilePulledUncompiledConstructorsV4(document, compilationProject, rep
158664
158859
  }
158665
158860
  function compilePulledProjectDocumentForEvaluationV4(document, compilationProject, targets) {
158666
158861
  const compiled = [];
158862
+ for (let index = 0; index < document.values.length; index += 1) {
158863
+ const row = document.values[index];
158864
+ if (targets !== void 0 && !targets.valueIds?.has(row.id)) continue;
158865
+ if (!isInitValueContent(row) || row.init.compiled === void 0) continue;
158866
+ document.values[index] = { ...row, init: { code: row.init.code } };
158867
+ }
158667
158868
  const sharedCompilationProject = compilationProject ?? createNeoScriptCompilationProject({
158668
158869
  project: document.project,
158669
158870
  projectFiles: document.projectFiles,
@@ -171797,19 +171998,24 @@ function reconcileMaterializedInitializersV4(args) {
171797
171998
  continue;
171798
171999
  }
171799
172000
  assertPulledConstructorsCompiled(replayDocument, replayContext);
171800
- currentRows ??= storedRowsWithRenamedKeys(
171801
- currentState().document,
171802
- replayDocument
171803
- );
171804
- compareConstruction ??= createConstructionReplayComparer(
171805
- new EffectiveValueReader(storedRowsDocument(replayDocument, currentRows)),
171806
- (root, member) => {
171807
- return storedOwnedValues().collect({
171808
- rootIds: [root.id],
171809
- rootMembers: /* @__PURE__ */ new Map([[root.id, member]])
171810
- });
171811
- }
171812
- );
172001
+ currentRows ??= new Map(
172002
+ currentState().document.values.map((row) => [row.id, row])
172003
+ );
172004
+ if (compareConstruction === void 0) {
172005
+ const storedDocument = currentState().document;
172006
+ compilePulledUncompiledConstructorsV4(storedDocument);
172007
+ assertPulledConstructorsCompiled(storedDocument);
172008
+ compareConstruction = createConstructionReplayComparer(
172009
+ new EffectiveValueReader(storedDocument),
172010
+ (root, member) => {
172011
+ return storedOwnedValues().collect({
172012
+ rootIds: [root.id],
172013
+ rootMembers: /* @__PURE__ */ new Map([[root.id, member]])
172014
+ });
172015
+ },
172016
+ new EffectiveValueReader(replayDocument)
172017
+ );
172018
+ }
171813
172019
  const replay = replayRows.get(reconciliation.valueId);
171814
172020
  if (replay === void 0) {
171815
172021
  throw new Error(
@@ -171970,51 +172176,6 @@ function retainedLiteralFailure(args, records3, document, replayContext, compile
171970
172176
  );
171971
172177
  }
171972
172178
  }
171973
- function storedRowsDocument(document, rows) {
171974
- const values = [];
171975
- for (const row of document.values) {
171976
- if (rows.has(row.id)) continue;
171977
- if (row.containerId && rows.has(row.containerId)) continue;
171978
- values.push(row);
171979
- }
171980
- for (const row of rows.values()) values.push(row);
171981
- return { ...document, values: freezeJsonData(values) };
171982
- }
171983
- function storedRowsWithRenamedKeys(before, after) {
171984
- const renamesByClass = /* @__PURE__ */ new Map();
171985
- const rows = /* @__PURE__ */ new Map();
171986
- for (const row of before.values) {
171987
- let renamed = row;
171988
- if (typeof row.classId === "string" && isObjectRecord(row.value)) {
171989
- const classId = row.classId;
171990
- let renames = renamesByClass.get(classId);
171991
- if (renames === void 0) {
171992
- const entries = (document) => mergeInstanceSurfaceSchema(
171993
- classId,
171994
- document.classes,
171995
- document.members
171996
- ).map((entry) => [entry.schemaKey, entry.memberId]);
171997
- renames = schemaKeyRenamesByMemberId(entries(before), entries(after));
171998
- renamesByClass.set(row.classId, renames);
171999
- }
172000
- if (renames.size > 0) {
172001
- const value = {};
172002
- let collision = false;
172003
- for (const [key, child2] of Object.entries(row.value)) {
172004
- const target = renames.get(key) ?? key;
172005
- if (target !== key && Object.hasOwn(row.value, target) && !renames.has(target)) {
172006
- collision = true;
172007
- break;
172008
- }
172009
- value[target] = child2;
172010
- }
172011
- if (!collision) renamed = { ...row, value };
172012
- }
172013
- }
172014
- rows.set(row.id, renamed);
172015
- }
172016
- return rows;
172017
- }
172018
172179
  function pulledStateDocumentV4(workspace) {
172019
172180
  const state = workspace.state.records;
172020
172181
  const remembered = pulledStateDocuments.get(state);
@@ -172111,7 +172272,8 @@ function materializeInitializersLocallyV4(args) {
172111
172272
  const compilationProject = createNeoScriptCompilationProject(authoredDocument);
172112
172273
  const changedBodies = {
172113
172274
  memberIds: /* @__PURE__ */ new Set(),
172114
- constructorIds: /* @__PURE__ */ new Set()
172275
+ constructorIds: /* @__PURE__ */ new Set(),
172276
+ valueIds: new Set(valueBodyIds)
172115
172277
  };
172116
172278
  for (const change of args.changes) {
172117
172279
  if (change.operation === "delete") continue;
@@ -172140,6 +172302,7 @@ function materializeInitializersLocallyV4(args) {
172140
172302
  for (const id2 of dependentBodies.constructorIds) {
172141
172303
  changedBodies.constructorIds.add(id2);
172142
172304
  }
172305
+ for (const id2 of dependentBodies.valueIds) changedBodies.valueIds.add(id2);
172143
172306
  }
172144
172307
  const compiledBodies = compilePulledProjectDocumentForEvaluationV4(
172145
172308
  authoredDocument,
@@ -172501,7 +172664,6 @@ var init_local_initializer_materialization = __esm({
172501
172664
  init_variant_value_graph();
172502
172665
  init_members();
172503
172666
  init_member_value_id();
172504
- init_inheritance();
172505
172667
  init_effective_value_reader();
172506
172668
  init_virtual_instance_values();
172507
172669
  init_declared_binding_targets();
@@ -218796,10 +218958,21 @@ async function runExport(workspace, options, session) {
218796
218958
  console.log(
218797
218959
  result.localChanges === null ? " Clean: the export holds the pulled head." : ` Local: the export includes ${result.localChanges} local change(s). Player builds fail and saves stay local until \`neo push\` or a clean \`neo export\`.`
218798
218960
  );
218961
+ let csharp14Members = 0;
218799
218962
  for (const diagnostic of result.diagnostics) {
218800
218963
  if (diagnostic.severity === "error") continue;
218964
+ if (diagnostic.code === "extension-wrapper-target") {
218965
+ csharp14Members++;
218966
+ continue;
218967
+ }
218801
218968
  warn(formatDiagnostic(diagnostic));
218802
218969
  }
218970
+ if (csharp14Members > 0) {
218971
+ const members2 = csharp14Members === 1 ? "member that requires" : "members that require";
218972
+ warn(
218973
+ `Skipping codegen for ${csharp14Members} ${members2} C# 14. NeoScript execution is unaffected.`
218974
+ );
218975
+ }
218803
218976
  if (result.schemaSkew !== null) {
218804
218977
  warn(
218805
218978
  `Unity's project.json was written at schema ${result.schemaSkew}; this export writes schema ${PROJECT_UNITY_EXPORT_SCHEMA_VERSION}. Update the Neo Compose SDK in Unity to a version that reads schema ${PROJECT_UNITY_EXPORT_SCHEMA_VERSION}.`
@@ -238490,7 +238663,7 @@ var releaseWorkspaceLock = () => void 0;
238490
238663
  async function main() {
238491
238664
  const args = parseArgs(process.argv.slice(2));
238492
238665
  if (args.command === "--version") {
238493
- console.log("0.89.2");
238666
+ console.log("0.89.3");
238494
238667
  return;
238495
238668
  }
238496
238669
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {