@neocompose/cli 0.53.0 → 0.53.2

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
@@ -31783,9 +31783,9 @@ function assertDialogue(value, path) {
31783
31783
  (entry, index) => assertMember(entry, `${path}.functions[${index}]`)
31784
31784
  );
31785
31785
  array(dialogue.members, `${path}.members`).forEach((entry, index) => {
31786
- const memberPath2 = `${path}.members[${index}]`;
31787
- const member = record(entry, memberPath2);
31788
- exactKeys(member, memberPath2, [
31786
+ const memberPath3 = `${path}.members[${index}]`;
31787
+ const member = record(entry, memberPath3);
31788
+ exactKeys(member, memberPath3, [
31789
31789
  "id",
31790
31790
  "state",
31791
31791
  "source",
@@ -31796,16 +31796,16 @@ function assertDialogue(value, path) {
31796
31796
  "arguments",
31797
31797
  "content"
31798
31798
  ]);
31799
- assertIdentity(member, memberPath2);
31800
- string(member.name, `${memberPath2}.name`);
31801
- string(member.graphType, `${memberPath2}.graphType`);
31799
+ assertIdentity(member, memberPath3);
31800
+ string(member.name, `${memberPath3}.name`);
31801
+ string(member.graphType, `${memberPath3}.graphType`);
31802
31802
  if (member.destination !== null) {
31803
- string(member.destination, `${memberPath2}.destination`);
31803
+ string(member.destination, `${memberPath3}.destination`);
31804
31804
  }
31805
- string(member.initializer, `${memberPath2}.initializer`);
31806
- assertFlowArguments(member.arguments, `${memberPath2}.arguments`);
31805
+ string(member.initializer, `${memberPath3}.initializer`);
31806
+ assertFlowArguments(member.arguments, `${memberPath3}.arguments`);
31807
31807
  if (member.content !== null) {
31808
- assertDialogueContent(member.content, `${memberPath2}.content`);
31808
+ assertDialogueContent(member.content, `${memberPath3}.content`);
31809
31809
  }
31810
31810
  });
31811
31811
  }
@@ -34796,6 +34796,111 @@ var init_src = __esm({
34796
34796
  }
34797
34797
  });
34798
34798
 
34799
+ // src/project-source/lower-support.ts
34800
+ function identityMap(declarations, kind) {
34801
+ return new Map(
34802
+ declarations.map((declaration) => [
34803
+ declaration.name,
34804
+ materializedId(declaration, kind, declaration.name)
34805
+ ])
34806
+ );
34807
+ }
34808
+ function sourceIdentity2(identity2, kind, name) {
34809
+ const sourceSpan = span(identity2);
34810
+ return {
34811
+ symbolId: `${kind}:${materializedIdentityId(identity2, kind, name)}`,
34812
+ kind,
34813
+ span: sourceSpan,
34814
+ selectionSpan: sourceSpan
34815
+ };
34816
+ }
34817
+ function span(identity2) {
34818
+ return {
34819
+ path: identity2.source.uri,
34820
+ start: { ...identity2.source.range.start },
34821
+ end: { ...identity2.source.range.end }
34822
+ };
34823
+ }
34824
+ function materializedId(identity2, kind, name) {
34825
+ return materializedIdentityId(identity2, kind, name);
34826
+ }
34827
+ function materializedIdentityId(identity2, kind, name) {
34828
+ return identity2.id ?? `__pending__:${kind}:${encodeURIComponent(identity2.source.uri)}:${identity2.source.range.start.line}:${identity2.source.range.start.character}:${encodeURIComponent(name)}`;
34829
+ }
34830
+ function expressionArguments(expression) {
34831
+ const result = /* @__PURE__ */ new Map();
34832
+ expression.args.forEach((entry, index) => {
34833
+ const name = expression.argumentNames?.[index] ?? null;
34834
+ if (name === null) {
34835
+ throw new Error(
34836
+ "Project configuration constructors require named arguments."
34837
+ );
34838
+ }
34839
+ if (result.has(name)) {
34840
+ throw new Error(
34841
+ `Constructor argument ${JSON.stringify(name)} is duplicated.`
34842
+ );
34843
+ }
34844
+ result.set(name, entry);
34845
+ });
34846
+ return result;
34847
+ }
34848
+ function annotation(annotations, name) {
34849
+ return annotations.find((entry) => entry.name === name);
34850
+ }
34851
+ function argument(value, name) {
34852
+ return value?.arguments.find((entry) => entry.name === name)?.expression ?? null;
34853
+ }
34854
+ function parseAnnotationExpression(value) {
34855
+ return parseExpression(value);
34856
+ }
34857
+ function stringArgument(value, name) {
34858
+ const raw = argument(value, name);
34859
+ if (raw === null) return null;
34860
+ const expression = parseAnnotationExpression(raw);
34861
+ return expression.kind === "litString" ? expression.value : null;
34862
+ }
34863
+ function contextualEnumArgument(value, name) {
34864
+ const raw = argument(value, name);
34865
+ if (raw === null) return null;
34866
+ const expression = parseAnnotationExpression(raw);
34867
+ return expression.kind === "contextualEnum" ? expression.name : null;
34868
+ }
34869
+ function systemMetadata(annotations) {
34870
+ const system = annotation(annotations, "system");
34871
+ if (!system) return null;
34872
+ const kind = contextualEnumArgument(system, "kind");
34873
+ if (kind === null) {
34874
+ throw new Error("@system requires a kind inferred enum argument.");
34875
+ }
34876
+ const worldKind = contextualEnumArgument(system, "worldKind");
34877
+ return {
34878
+ kind: lowerFirst2(kind),
34879
+ worldKind: worldKind ? lowerFirst2(worldKind) : null
34880
+ };
34881
+ }
34882
+ function requiredName(values, name, kind) {
34883
+ const value = values.get(name);
34884
+ if (!value) throw new Error(`Unknown ${kind} ${JSON.stringify(name)}.`);
34885
+ return value;
34886
+ }
34887
+ function lowerFirst2(value) {
34888
+ return value.length ? `${value[0].toLowerCase()}${value.slice(1)}` : value;
34889
+ }
34890
+ function indexFirstById(values) {
34891
+ const result = /* @__PURE__ */ new Map();
34892
+ for (const value of values) {
34893
+ if (!result.has(value.id)) result.set(value.id, value);
34894
+ }
34895
+ return result;
34896
+ }
34897
+ var init_lower_support = __esm({
34898
+ "src/project-source/lower-support.ts"() {
34899
+ "use strict";
34900
+ init_src();
34901
+ }
34902
+ });
34903
+
34799
34904
  // src/project-source/local-values.ts
34800
34905
  function validateLocalValuePlacementsV4(value) {
34801
34906
  if (!Array.isArray(value))
@@ -34870,6 +34975,23 @@ function validateLocalValuePlacementsV4(value) {
34870
34975
  for (const entry of active) visited.add(entry);
34871
34976
  }
34872
34977
  }
34978
+ function* staticMembersInitializedByName(analysis) {
34979
+ for (const sourceClass of analysis.schema.classes) {
34980
+ for (const declaration of sourceClass.members) {
34981
+ if (!declaration.modifiers.includes("static")) continue;
34982
+ if (declaration.kind !== "field" || declaration.initializer === null)
34983
+ continue;
34984
+ const name = declaration.initializer.trim();
34985
+ if (!/^[A-Za-z_]\w*$/u.test(name)) continue;
34986
+ const path = `${sourceClass.name}.${declaration.name}`;
34987
+ yield {
34988
+ name,
34989
+ memberId: materializedId(declaration, "member", path),
34990
+ path
34991
+ };
34992
+ }
34993
+ }
34994
+ }
34873
34995
  function typeText2(type) {
34874
34996
  return type.name + (type.arguments.length === 0 ? "" : `<${type.arguments.map(typeText2).join(", ")}>`) + (type.nullable ? "?" : "");
34875
34997
  }
@@ -34879,12 +35001,15 @@ var init_local_values = __esm({
34879
35001
  "use strict";
34880
35002
  init_workspace_source_path();
34881
35003
  init_src();
35004
+ init_lower_support();
34882
35005
  LocalValueBindingsV4 = class {
34883
35006
  definitions = /* @__PURE__ */ new Map();
34884
35007
  expressions = /* @__PURE__ */ new Map();
34885
35008
  owners = /* @__PURE__ */ new Map();
35009
+ /** Static members whose initializer is a bare local name, by that name. */
35010
+ ownerMembers = /* @__PURE__ */ new Map();
34886
35011
  scalarTypes;
34887
- constructor(globals, enumNames = []) {
35012
+ constructor(globals, enumNames = [], ownerMembers = []) {
34888
35013
  const scalarTypes = /* @__PURE__ */ new Set(["string", "int", "float", "decimal", "bool"]);
34889
35014
  for (const name of enumNames) scalarTypes.add(name);
34890
35015
  this.scalarTypes = scalarTypes;
@@ -34893,6 +35018,12 @@ var init_local_values = __esm({
34893
35018
  throw new Error(`Duplicate local value ${global.name}.`);
34894
35019
  this.definitions.set(global.name, global);
34895
35020
  }
35021
+ for (const owner of ownerMembers) {
35022
+ if (!this.definitions.has(owner.name)) continue;
35023
+ const members = this.ownerMembers.get(owner.name) ?? [];
35024
+ members.push({ memberId: owner.memberId, path: owner.path });
35025
+ this.ownerMembers.set(owner.name, members);
35026
+ }
34896
35027
  }
34897
35028
  resolve(expression, source, valueId) {
34898
35029
  if (expression.kind !== "ident") return { expression, source };
@@ -34931,6 +35062,44 @@ var init_local_values = __esm({
34931
35062
  has(name) {
34932
35063
  return this.definitions.has(name);
34933
35064
  }
35065
+ /**
35066
+ * The row a local names, answered without its owning assignment having
35067
+ * lowered, so the answer does not depend on which file lowered first: the
35068
+ * `@id` its declaration carries (through any alias chain), else the static
35069
+ * member whose initializer is the local, whose row derives from the member.
35070
+ * `null` for a local no push has identified yet.
35071
+ */
35072
+ declaredTarget(name) {
35073
+ const definition2 = this.definitions.get(name);
35074
+ if (definition2 === void 0) return null;
35075
+ const chain = /* @__PURE__ */ new Set();
35076
+ let global = definition2;
35077
+ let expression;
35078
+ for (; ; ) {
35079
+ if (chain.has(global.name))
35080
+ throw new Error(`Local initializer cycle reaches ${global.name}.`);
35081
+ chain.add(global.name);
35082
+ expression = this.expressions.get(global.name) ?? parseExpression(global.initializer);
35083
+ this.expressions.set(global.name, expression);
35084
+ const alias = expression.kind === "ident" ? this.definitions.get(expression.name) : void 0;
35085
+ if (alias === void 0) break;
35086
+ global = alias;
35087
+ }
35088
+ const typeName = definition2.type.name;
35089
+ const id2 = expression.kind === "annotated" ? expression.annotations.find((entry) => entry.name === "id")?.args[0] : void 0;
35090
+ if (id2 !== void 0 && id2.kind === "litString" && id2.value.length > 0) {
35091
+ return { id: id2.value, typeName };
35092
+ }
35093
+ const owners = this.ownerMembers.get(name);
35094
+ if (owners === void 0) return null;
35095
+ if (owners.length !== 1) {
35096
+ throw new Error(
35097
+ `Reference(${name}) requires exactly one owning assignment.`
35098
+ );
35099
+ }
35100
+ const owner = owners[0];
35101
+ return { ownerMemberId: owner.memberId, ownerPath: owner.path, typeName };
35102
+ }
34934
35103
  target(name) {
34935
35104
  const owners = this.owners.get(name);
34936
35105
  if (owners?.size !== 1)
@@ -59609,7 +59778,7 @@ function emitSupplementalProjectSourcesV4(records2, binaryPaths) {
59609
59778
  (candidate) => candidate.recordKind === "priority-group"
59610
59779
  )) {
59611
59780
  const data = recordData(record6);
59612
- const name = requiredName(data, record6);
59781
+ const name = requiredName2(data, record6);
59613
59782
  files.push({
59614
59783
  path: defaultDeclarationPathV4("PriorityGroups", name, record6.recordId),
59615
59784
  content: emitPriorityGroup(data, record6.recordId, name),
@@ -59620,7 +59789,7 @@ function emitSupplementalProjectSourcesV4(records2, binaryPaths) {
59620
59789
  (candidate) => candidate.recordKind === "dialogue-group"
59621
59790
  )) {
59622
59791
  const data = recordData(record6);
59623
- const name = requiredName(data, record6);
59792
+ const name = requiredName2(data, record6);
59624
59793
  files.push({
59625
59794
  path: defaultDeclarationPathV4("DialogueGroups", name, record6.recordId),
59626
59795
  content: emitDialogueGroup(
@@ -60380,7 +60549,7 @@ function recordData(record6) {
60380
60549
  }
60381
60550
  return record6.data;
60382
60551
  }
60383
- function requiredName(data, record6) {
60552
+ function requiredName2(data, record6) {
60384
60553
  if (typeof data.name !== "string") {
60385
60554
  throw new Error(`${record6.recordKind}:${record6.recordId} has no name.`);
60386
60555
  }
@@ -60391,7 +60560,7 @@ function namesById(records2, kind) {
60391
60560
  return new Map(
60392
60561
  records2.filter((record6) => record6.recordKind === kind).map((record6) => [
60393
60562
  record6.recordId,
60394
- requiredName(recordData(record6), record6)
60563
+ requiredName2(recordData(record6), record6)
60395
60564
  ])
60396
60565
  );
60397
60566
  }
@@ -60512,9 +60681,9 @@ function lowerSystemMetadata(annotations) {
60512
60681
  throw new Error("@system worldKind must be an inferred enum or null.");
60513
60682
  }
60514
60683
  return {
60515
- kind: lowerFirst2(kindExpression.name),
60684
+ kind: lowerFirst3(kindExpression.name),
60516
60685
  ...worldKindExpression === void 0 ? {} : {
60517
- worldKind: worldKindExpression.kind === "contextualEnum" ? lowerFirst2(worldKindExpression.name) : null
60686
+ worldKind: worldKindExpression.kind === "contextualEnum" ? lowerFirst3(worldKindExpression.name) : null
60518
60687
  }
60519
60688
  };
60520
60689
  }
@@ -60524,7 +60693,7 @@ function hasAnnotation(annotations, name) {
60524
60693
  function enumCase2(value) {
60525
60694
  return value.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join("");
60526
60695
  }
60527
- function lowerFirst2(value) {
60696
+ function lowerFirst3(value) {
60528
60697
  return `${value[0]?.toLowerCase() ?? ""}${value.slice(1)}`;
60529
60698
  }
60530
60699
  function assertProjectIdentifier2(value, kind) {
@@ -76851,8 +77020,8 @@ function applyConstructorFields(args) {
76851
77020
  storageKeyDeclarations,
76852
77021
  ctx
76853
77022
  } = args;
76854
- for (const { validated, value } of args.supplied) {
76855
- if (value === null) {
77023
+ for (const { validated, value: supplied } of args.supplied) {
77024
+ if (supplied === null) {
76856
77025
  if (args.nullMeansOmit) continue;
76857
77026
  applyExplicitNullConstructorField({
76858
77027
  validated,
@@ -76867,6 +77036,7 @@ function applyConstructorFields(args) {
76867
77036
  continue;
76868
77037
  }
76869
77038
  const { schemaKey, member } = validated;
77039
+ const value = isMemberLookupBase(member) ? encodeLookupInitializerSelection(member, supplied, createdValues, ctx) : supplied;
76870
77040
  const trackedValueId = findKnownRowIdByValueReference(value, ctx);
76871
77041
  if (trackedValueId !== null && isMemberClassBase(member)) {
76872
77042
  const source = evalValueById(
@@ -90449,9 +90619,24 @@ function addPackedChildEdges(source, record6, add) {
90449
90619
  childId: position.valueId
90450
90620
  })
90451
90621
  });
90622
+ if (packedEntryOwnsSparseRows(position.entry)) {
90623
+ add({
90624
+ edgeKind: "containment-child",
90625
+ targetKey: position.valueId,
90626
+ targetAddressing: "record",
90627
+ payloadJson: canonicalJsonStringify({
90628
+ relation: "packed-parent",
90629
+ path: position.path
90630
+ })
90631
+ });
90632
+ }
90452
90633
  addStampBindingEdges(position.entry.genericBindings, add);
90453
90634
  }
90454
90635
  }
90636
+ function packedEntryOwnsSparseRows(entry) {
90637
+ if (collectDirectBodyChildIds(entry.value).length > 0) return true;
90638
+ return isLiteralValueContent(entry) && collectDirectBodyChildIds(entry.constructorArgs).length > 0;
90639
+ }
90455
90640
  function projectSnapshotDerivedPathTargetKey(args) {
90456
90641
  return canonicalJsonStringify({ recordId: args.recordId, path: args.path });
90457
90642
  }
@@ -96040,176 +96225,6 @@ function orderLocalizedTextWritesBesideLinks(prepared) {
96040
96225
  });
96041
96226
  return ordered;
96042
96227
  }
96043
- function planProjectVersionTransaction(changes, atomicGroups, options = {}) {
96044
- if (changes.length === 0) {
96045
- throw new Error("A project-version transaction plan requires changes.");
96046
- }
96047
- if (options.basePayloadBytes !== void 0 && options.basePayloadBytes.length !== changes.length)
96048
- throw new Error("Transaction base payload sizes must cover every change.");
96049
- const changeCosts = changes.map(
96050
- (change, index) => estimateProjectVersionChangeCost(change, options.basePayloadBytes?.[index])
96051
- );
96052
- const groups = normalizeAtomicGroups(changes.length, atomicGroups);
96053
- let totalEstimatedCost = changeCosts.reduce(
96054
- addProjectVersionTransactionBudgets,
96055
- IMMEDIATE_FIXED_COST
96056
- );
96057
- if (changes.some(projectVersionChangeCanTriggerWholeGraphValidation)) {
96058
- totalEstimatedCost = addProjectVersionTransactionBudgets(
96059
- totalEstimatedCost,
96060
- WHOLE_GRAPH_VALIDATION_SURCHARGE
96061
- );
96062
- }
96063
- const limitingResource = firstExceededResource(
96064
- totalEstimatedCost,
96065
- PROJECT_TRANSACTION_IMMEDIATE_BUDGET
96066
- );
96067
- if (limitingResource === null && options.forceAsync !== true) {
96068
- return {
96069
- path: "immediate",
96070
- limitingResource: null,
96071
- totalEstimatedCost,
96072
- chunks: [
96073
- {
96074
- firstChangeIndex: 0,
96075
- changeCount: changes.length,
96076
- estimatedCost: totalEstimatedCost
96077
- }
96078
- ]
96079
- };
96080
- }
96081
- const stagedChangeCosts = changes.map((change, index) => {
96082
- const cost = changeCosts[index];
96083
- const receiptBytes = 2 * KIB + new TextEncoder().encode(change.recordId).byteLength;
96084
- return addProjectVersionTransactionBudgets(cost, {
96085
- ...EMPTY_BUDGET,
96086
- bytesRead: receiptBytes,
96087
- bytesWritten: receiptBytes,
96088
- documentsRead: 1,
96089
- documentsWritten: 1,
96090
- databaseQueries: 1,
96091
- indexRanges: 1
96092
- });
96093
- });
96094
- const chunks = [];
96095
- let firstChangeIndex = 0;
96096
- let chunkCost = CHUNK_FIXED_COST;
96097
- let changeCount = 0;
96098
- for (const group of groups) {
96099
- const groupCost = stagedChangeCosts.slice(group.firstChangeIndex, group.firstChangeIndex + group.changeCount).reduce(addProjectVersionTransactionBudgets, EMPTY_BUDGET);
96100
- const nativeExceeded = firstExceededResource(
96101
- addProjectVersionTransactionBudgets(CHUNK_FIXED_COST, groupCost),
96102
- PROJECT_TRANSACTION_SINGLE_CHANGE_NATIVE_BUDGET
96103
- );
96104
- if (nativeExceeded !== null) {
96105
- throw new Error(
96106
- `Project-version atomic group starting at change ${group.firstChangeIndex} (${group.changeCount} changes) exceeds the native worker budget for ${nativeExceeded}.`
96107
- );
96108
- }
96109
- const nextCost = addProjectVersionTransactionBudgets(chunkCost, groupCost);
96110
- const exceeded = firstExceededResource(
96111
- nextCost,
96112
- PROJECT_TRANSACTION_WORKER_BUDGET
96113
- );
96114
- if (exceeded !== null && changeCount > 0) {
96115
- chunks.push({ firstChangeIndex, changeCount, estimatedCost: chunkCost });
96116
- firstChangeIndex = group.firstChangeIndex;
96117
- changeCount = 0;
96118
- chunkCost = CHUNK_FIXED_COST;
96119
- }
96120
- chunkCost = addProjectVersionTransactionBudgets(chunkCost, groupCost);
96121
- changeCount += group.changeCount;
96122
- }
96123
- if (changeCount > 0) {
96124
- chunks.push({ firstChangeIndex, changeCount, estimatedCost: chunkCost });
96125
- }
96126
- return {
96127
- path: "asynchronous",
96128
- limitingResource,
96129
- totalEstimatedCost,
96130
- chunks
96131
- };
96132
- }
96133
- function projectVersionChangeCanTriggerWholeGraphValidation(change) {
96134
- if (change.recordKind === "enum" || change.recordKind === "member" || change.recordKind === "project" || change.recordKind === "internal-record-relation") {
96135
- return true;
96136
- }
96137
- if (change.recordKind === "class") return change.operation !== "create";
96138
- if (change.recordKind !== "value") return false;
96139
- if (change.operation === "delete") return true;
96140
- return valueChangeCarriesWorldLayerOverride(change);
96141
- }
96142
- function valueChangeCarriesWorldLayerOverride(change) {
96143
- const nextData = change.nextData;
96144
- if (nextData === null || typeof nextData !== "object") return false;
96145
- if (Array.isArray(nextData)) return false;
96146
- const value = nextData.value;
96147
- if (value === null || typeof value !== "object") return false;
96148
- if (Array.isArray(value)) return false;
96149
- return typeof value.layerOverrideValueId === "string";
96150
- }
96151
- function normalizeAtomicGroups(changeCount, groups) {
96152
- if (groups === void 0) {
96153
- return Array.from({ length: changeCount }, (_, firstChangeIndex) => ({
96154
- firstChangeIndex,
96155
- changeCount: 1
96156
- }));
96157
- }
96158
- let nextChangeIndex = 0;
96159
- for (const group of groups) {
96160
- if (!Number.isSafeInteger(group.firstChangeIndex) || !Number.isSafeInteger(group.changeCount) || group.firstChangeIndex !== nextChangeIndex || group.changeCount < 1) {
96161
- throw new Error(
96162
- "Project-version atomic groups must be positive, ordered, and contiguous."
96163
- );
96164
- }
96165
- nextChangeIndex += group.changeCount;
96166
- }
96167
- if (nextChangeIndex !== changeCount) {
96168
- throw new Error(
96169
- `Project-version atomic groups cover ${nextChangeIndex}/${changeCount} changes.`
96170
- );
96171
- }
96172
- return [...groups];
96173
- }
96174
- function estimateProjectVersionChangeCost(change, basePayloadBytes) {
96175
- const encoded = canonicalJsonStringify(change);
96176
- const payloadBytes = new TextEncoder().encode(encoded).byteLength;
96177
- const hasBase = change.operation !== "create";
96178
- if (basePayloadBytes !== void 0 && (!Number.isSafeInteger(basePayloadBytes) || basePayloadBytes < 0))
96179
- throw new Error(
96180
- "Transaction base payload size must be a nonnegative byte count."
96181
- );
96182
- const baseBytes = hasBase ? basePayloadBytes ?? payloadBytes : 0;
96183
- const nextStoredBytes = change.operation === "delete" ? baseBytes : payloadBytes;
96184
- const counts = changeCountCost(change);
96185
- return {
96186
- argumentBytes: payloadBytes + 128,
96187
- bytesRead: payloadBytes + 2 * baseBytes + CHANGE_BYTES_READ_OVERHEAD,
96188
- // Live records appear in the snapshot, result data, result snapshot and diff.
96189
- bytesWritten: (change.operation === "delete" ? 2 * baseBytes + payloadBytes : 4 * nextStoredBytes) + CHANGE_BYTES_WRITTEN_OVERHEAD,
96190
- documentsRead: counts.documentsRead,
96191
- documentsWritten: counts.documentsWritten,
96192
- databaseQueries: counts.databaseQueries,
96193
- // Not metered by Convex: `TransactionMetrics` reports seven dimensions and
96194
- // this is not one of them, so it cannot be measured the way the others
96195
- // were. Every index range a change opens is also a database query, so the
96196
- // measured query count is a strict upper bound on it. Charging exactly
96197
- // that keeps the dimension a true bound instead of an invented number,
96198
- // and keeps it dominated by `databaseQueries` rather than silently
96199
- // becoming the binding constraint on a well-measured plan.
96200
- indexRanges: counts.databaseQueries,
96201
- functionsScheduled: 0,
96202
- scheduledFunctionArgsBytes: 0,
96203
- // Deleted result rows still carry the complete tombstone snapshot.
96204
- returnBytes: (change.operation === "delete" ? baseBytes : 2 * nextStoredBytes) + 512
96205
- };
96206
- }
96207
- function changeCountCost(change) {
96208
- if (change.recordKind === "value") {
96209
- return VALUE_CHANGE_COUNT_COSTS[change.operation];
96210
- }
96211
- return SCHEMA_CHANGE_COUNT_COSTS[change.operation];
96212
- }
96213
96228
  function addProjectVersionTransactionBudgets(left, right) {
96214
96229
  return {
96215
96230
  argumentBytes: left.argumentBytes + right.argumentBytes,
@@ -96224,15 +96239,7 @@ function addProjectVersionTransactionBudgets(left, right) {
96224
96239
  returnBytes: left.returnBytes + right.returnBytes
96225
96240
  };
96226
96241
  }
96227
- function firstExceededResource(cost, target) {
96228
- for (const resource of Object.keys(
96229
- EMPTY_BUDGET
96230
- )) {
96231
- if (cost[resource] > target[resource]) return resource;
96232
- }
96233
- return null;
96234
- }
96235
- var KIB, MIB, PROJECT_TRANSACTION_CHUNK_PAYLOAD_TARGET_BYTES, PROJECT_TRANSACTION_IMMEDIATE_BUDGET, PROJECT_TRANSACTION_WORKER_BUDGET, PROJECT_TRANSACTION_SINGLE_CHANGE_NATIVE_BUDGET, EMPTY_BUDGET, CHUNK_GRAPH_VALIDATION_RESERVE, CHUNK_FIXED_COST, IMMEDIATE_FIXED_COST, WHOLE_GRAPH_VALIDATION_SURCHARGE, VALUE_CHANGE_COUNT_COSTS, SCHEMA_CHANGE_COUNT_COSTS, CHANGE_BYTES_READ_OVERHEAD, CHANGE_BYTES_WRITTEN_OVERHEAD;
96242
+ var KIB, MIB, PROJECT_TRANSACTION_CHUNK_PAYLOAD_TARGET_BYTES, PROJECT_TRANSACTION_IMMEDIATE_BUDGET, PROJECT_TRANSACTION_WORKER_BUDGET, PROJECT_TRANSACTION_SINGLE_CHANGE_NATIVE_BUDGET, EMPTY_BUDGET, CHUNK_GRAPH_VALIDATION_RESERVE, CHUNK_FIXED_COST, IMMEDIATE_FIXED_COST, WHOLE_GRAPH_VALIDATION_SURCHARGE, CHANGE_BYTES_READ_OVERHEAD, CHANGE_BYTES_WRITTEN_OVERHEAD;
96236
96243
  var init_project_version_transaction_planning = __esm({
96237
96244
  "../src/database/project-version-transaction-planning.ts"() {
96238
96245
  "use strict";
@@ -96324,16 +96331,6 @@ var init_project_version_transaction_planning = __esm({
96324
96331
  databaseQueries: 410,
96325
96332
  indexRanges: 410
96326
96333
  };
96327
- VALUE_CHANGE_COUNT_COSTS = {
96328
- create: { documentsRead: 3, documentsWritten: 3, databaseQueries: 8 },
96329
- update: { documentsRead: 6, documentsWritten: 3, databaseQueries: 9 },
96330
- delete: { documentsRead: 6, documentsWritten: 3, databaseQueries: 14 }
96331
- };
96332
- SCHEMA_CHANGE_COUNT_COSTS = {
96333
- create: { documentsRead: 9, documentsWritten: 7, databaseQueries: 9 },
96334
- update: { documentsRead: 6, documentsWritten: 5, databaseQueries: 22 },
96335
- delete: { documentsRead: 6, documentsWritten: 5, databaseQueries: 22 }
96336
- };
96337
96334
  CHANGE_BYTES_READ_OVERHEAD = 4 * KIB;
96338
96335
  CHANGE_BYTES_WRITTEN_OVERHEAD = 4 * KIB;
96339
96336
  }
@@ -101587,12 +101584,12 @@ var init_animation_clips = __esm({
101587
101584
  * fix.
101588
101585
  */
101589
101586
  validateStructuredLeafPartial(args) {
101590
- const memberPath2 = args.path.join(".");
101587
+ const memberPath3 = args.path.join(".");
101591
101588
  const prefix = `Animation clip "${args.clipName}" frame ${args.frameIndex}`;
101592
101589
  const kind = args.member.kind;
101593
101590
  if (!isStructuredLeafKind(kind)) {
101594
101591
  throw new Error(
101595
- `${prefix} member "${memberPath2}" is of kind ${MemberKind[kind]}, which has no addressable fields, so it cannot take a "${STRUCTURED_LEAF_PARTIAL_KEY}" field override.`
101592
+ `${prefix} member "${memberPath3}" is of kind ${MemberKind[kind]}, which has no addressable fields, so it cannot take a "${STRUCTURED_LEAF_PARTIAL_KEY}" field override.`
101596
101593
  );
101597
101594
  }
101598
101595
  const kindLabel = MemberKind[kind];
@@ -101601,7 +101598,7 @@ var init_animation_clips = __esm({
101601
101598
  args.member.id
101602
101599
  ])) {
101603
101600
  throw new Error(
101604
- `${prefix} ${kindLabel} member "${memberPath2}" cannot take a "${STRUCTURED_LEAF_PARTIAL_KEY}" field override; member "${args.member.name}" is not a writable Save/Session override leaf.`
101601
+ `${prefix} ${kindLabel} member "${memberPath3}" cannot take a "${STRUCTURED_LEAF_PARTIAL_KEY}" field override; member "${args.member.name}" is not a writable Save/Session override leaf.`
101605
101602
  );
101606
101603
  }
101607
101604
  const violation = structuredLeafPartialViolation(
@@ -101610,14 +101607,14 @@ var init_animation_clips = __esm({
101610
101607
  kindLabel
101611
101608
  );
101612
101609
  if (violation !== null) {
101613
- throw new Error(`${prefix} member "${memberPath2}" ${violation}.`);
101610
+ throw new Error(`${prefix} member "${memberPath3}" ${violation}.`);
101614
101611
  }
101615
101612
  const resolution = this.resolveDefinitionChildResolution(
101616
101613
  args.definitionNode,
101617
101614
  args.schemaKey,
101618
101615
  args.member
101619
101616
  );
101620
- const descent = `${prefix} cannot descend into ${kindLabel} member "${memberPath2}"`;
101617
+ const descent = `${prefix} cannot descend into ${kindLabel} member "${memberPath3}"`;
101621
101618
  if (resolution.node === null) {
101622
101619
  if (resolution.absence.reason === "nullDefault") {
101623
101620
  throw new Error(
@@ -106906,111 +106903,6 @@ var init_value_record_comparison = __esm({
106906
106903
  }
106907
106904
  });
106908
106905
 
106909
- // src/project-source/lower-support.ts
106910
- function identityMap(declarations, kind) {
106911
- return new Map(
106912
- declarations.map((declaration) => [
106913
- declaration.name,
106914
- materializedId(declaration, kind, declaration.name)
106915
- ])
106916
- );
106917
- }
106918
- function sourceIdentity2(identity2, kind, name) {
106919
- const sourceSpan = span(identity2);
106920
- return {
106921
- symbolId: `${kind}:${materializedIdentityId(identity2, kind, name)}`,
106922
- kind,
106923
- span: sourceSpan,
106924
- selectionSpan: sourceSpan
106925
- };
106926
- }
106927
- function span(identity2) {
106928
- return {
106929
- path: identity2.source.uri,
106930
- start: { ...identity2.source.range.start },
106931
- end: { ...identity2.source.range.end }
106932
- };
106933
- }
106934
- function materializedId(identity2, kind, name) {
106935
- return materializedIdentityId(identity2, kind, name);
106936
- }
106937
- function materializedIdentityId(identity2, kind, name) {
106938
- return identity2.id ?? `__pending__:${kind}:${encodeURIComponent(identity2.source.uri)}:${identity2.source.range.start.line}:${identity2.source.range.start.character}:${encodeURIComponent(name)}`;
106939
- }
106940
- function expressionArguments(expression) {
106941
- const result = /* @__PURE__ */ new Map();
106942
- expression.args.forEach((entry, index) => {
106943
- const name = expression.argumentNames?.[index] ?? null;
106944
- if (name === null) {
106945
- throw new Error(
106946
- "Project configuration constructors require named arguments."
106947
- );
106948
- }
106949
- if (result.has(name)) {
106950
- throw new Error(
106951
- `Constructor argument ${JSON.stringify(name)} is duplicated.`
106952
- );
106953
- }
106954
- result.set(name, entry);
106955
- });
106956
- return result;
106957
- }
106958
- function annotation(annotations, name) {
106959
- return annotations.find((entry) => entry.name === name);
106960
- }
106961
- function argument(value, name) {
106962
- return value?.arguments.find((entry) => entry.name === name)?.expression ?? null;
106963
- }
106964
- function parseAnnotationExpression(value) {
106965
- return parseExpression(value);
106966
- }
106967
- function stringArgument(value, name) {
106968
- const raw = argument(value, name);
106969
- if (raw === null) return null;
106970
- const expression = parseAnnotationExpression(raw);
106971
- return expression.kind === "litString" ? expression.value : null;
106972
- }
106973
- function contextualEnumArgument(value, name) {
106974
- const raw = argument(value, name);
106975
- if (raw === null) return null;
106976
- const expression = parseAnnotationExpression(raw);
106977
- return expression.kind === "contextualEnum" ? expression.name : null;
106978
- }
106979
- function systemMetadata(annotations) {
106980
- const system = annotation(annotations, "system");
106981
- if (!system) return null;
106982
- const kind = contextualEnumArgument(system, "kind");
106983
- if (kind === null) {
106984
- throw new Error("@system requires a kind inferred enum argument.");
106985
- }
106986
- const worldKind = contextualEnumArgument(system, "worldKind");
106987
- return {
106988
- kind: lowerFirst3(kind),
106989
- worldKind: worldKind ? lowerFirst3(worldKind) : null
106990
- };
106991
- }
106992
- function requiredName2(values, name, kind) {
106993
- const value = values.get(name);
106994
- if (!value) throw new Error(`Unknown ${kind} ${JSON.stringify(name)}.`);
106995
- return value;
106996
- }
106997
- function lowerFirst3(value) {
106998
- return value.length ? `${value[0].toLowerCase()}${value.slice(1)}` : value;
106999
- }
107000
- function indexFirstById(values) {
107001
- const result = /* @__PURE__ */ new Map();
107002
- for (const value of values) {
107003
- if (!result.has(value.id)) result.set(value.id, value);
107004
- }
107005
- return result;
107006
- }
107007
- var init_lower_support = __esm({
107008
- "src/project-source/lower-support.ts"() {
107009
- "use strict";
107010
- init_src();
107011
- }
107012
- });
107013
-
107014
106906
  // src/project-source/lower-configuration.ts
107015
106907
  function lowerConfiguration(base, analysis) {
107016
106908
  const globals = analysis.configuration.globals;
@@ -107962,7 +107854,7 @@ function nullableStatusConstructorArgument(argumentsValue, name, fallback, statu
107962
107854
  }
107963
107855
  function resolveStatusExpression(expression, statusIdsByName) {
107964
107856
  if (expression.kind === "ident") {
107965
- return requiredName2(
107857
+ return requiredName(
107966
107858
  statusIdsByName,
107967
107859
  expression.name,
107968
107860
  "localization status"
@@ -108038,6 +107930,200 @@ var init_lower_configuration = __esm({
108038
107930
  }
108039
107931
  });
108040
107932
 
107933
+ // src/project-source/initializer-reference-spellings.ts
107934
+ function sourceOffsetAt(source, pos) {
107935
+ let offset = 0;
107936
+ for (let line = 1; line < pos.line; line += 1) {
107937
+ const next = source.indexOf("\n", offset);
107938
+ if (next < 0) return null;
107939
+ offset = next + 1;
107940
+ }
107941
+ return Math.min(offset + pos.column - 1, source.length);
107942
+ }
107943
+ function settleInitializerReferenceSpellings(code, settle) {
107944
+ const splices = [];
107945
+ const pending = [parseExpression(code)];
107946
+ while (pending.length > 0) {
107947
+ const node = pending.pop();
107948
+ switch (node.kind) {
107949
+ case "call": {
107950
+ const target = settle(node);
107951
+ if (target === null) {
107952
+ pending.push(node.callee, ...node.args);
107953
+ break;
107954
+ }
107955
+ const start = sourceOffsetAt(code, node.callee.pos);
107956
+ const end = start === null ? null : referenceCallEnd(code, start);
107957
+ if (start === null || end === null) break;
107958
+ splices.push({
107959
+ start,
107960
+ end,
107961
+ text: `Reference<${target.typeName}>(id: ${JSON.stringify(target.id)})`
107962
+ });
107963
+ break;
107964
+ }
107965
+ case "annotated":
107966
+ pending.push(node.expression);
107967
+ break;
107968
+ case "new":
107969
+ pending.push(...node.args);
107970
+ for (const entry of node.initializer ?? []) pending.push(entry.value);
107971
+ break;
107972
+ case "litList":
107973
+ pending.push(...node.elements);
107974
+ break;
107975
+ case "litDict":
107976
+ for (const entry of node.entries) pending.push(entry.value);
107977
+ break;
107978
+ case "member":
107979
+ pending.push(node.receiver);
107980
+ break;
107981
+ case "index":
107982
+ pending.push(node.receiver, node.index);
107983
+ break;
107984
+ case "binary":
107985
+ case "coalesce":
107986
+ pending.push(node.left, node.right);
107987
+ break;
107988
+ case "conditional":
107989
+ pending.push(node.condition, node.whenTrue, node.whenFalse);
107990
+ break;
107991
+ case "unary":
107992
+ case "force":
107993
+ case "is":
107994
+ pending.push(node.operand);
107995
+ break;
107996
+ }
107997
+ }
107998
+ if (splices.length === 0) return code;
107999
+ splices.sort((left, right) => right.start - left.start);
108000
+ let settled = code;
108001
+ for (const splice of splices) {
108002
+ settled = settled.slice(0, splice.start) + splice.text + settled.slice(splice.end);
108003
+ }
108004
+ return settled;
108005
+ }
108006
+ function referenceCallEnd(code, start) {
108007
+ const open = code.indexOf("(", start);
108008
+ if (open < 0) return null;
108009
+ let depth = 0;
108010
+ let quoted = null;
108011
+ for (let index = open; index < code.length; index += 1) {
108012
+ const character = code[index];
108013
+ if (quoted !== null) {
108014
+ if (character === "\\") index += 1;
108015
+ else if (character === quoted) quoted = null;
108016
+ continue;
108017
+ }
108018
+ if (character === '"' || character === "'") quoted = character;
108019
+ else if (character === "(") depth += 1;
108020
+ else if (character === ")") {
108021
+ depth -= 1;
108022
+ if (depth === 0) return index + 1;
108023
+ }
108024
+ }
108025
+ return null;
108026
+ }
108027
+ function memberValueIdV4(memberId) {
108028
+ return isPendingId(memberId) ? pendingMemberValueId(memberId) : derivedMemberValueId(memberId);
108029
+ }
108030
+ function referencedSymbolPath(call) {
108031
+ if (call.callee.kind !== "ident" || call.callee.name !== "Reference") {
108032
+ return null;
108033
+ }
108034
+ if ((call.typeArguments?.length ?? 0) > 1) return null;
108035
+ if (call.args.length !== 1) return null;
108036
+ if (typeof call.argumentNames?.[0] === "string") return null;
108037
+ const path = memberPath(call.args[0]);
108038
+ if (path === null) return null;
108039
+ const typeArgument = call.typeArguments?.[0];
108040
+ return {
108041
+ path,
108042
+ genericTypeName: typeArgument === void 0 ? null : astTypeNameV4(typeArgument)
108043
+ };
108044
+ }
108045
+ function memberPath(expression) {
108046
+ if (expression.kind === "ident") return expression.name;
108047
+ if (expression.kind !== "member") return null;
108048
+ const receiver = memberPath(expression.receiver);
108049
+ return receiver === null ? null : `${receiver}.${expression.name}`;
108050
+ }
108051
+ function unidentifiedLocalReferenceError(name) {
108052
+ return new Error(
108053
+ `Reference(${name}) inside a constructed initializer needs ${name} to carry an @id. Push the declaration of ${name} first, then reference it.`
108054
+ );
108055
+ }
108056
+ function createSchemaInitializerReferenceSettlerV4(args) {
108057
+ let sourceStatics = null;
108058
+ const readSourceStatics = () => {
108059
+ if (sourceStatics !== null) return sourceStatics;
108060
+ const statics = /* @__PURE__ */ new Map();
108061
+ for (const sourceClass of args.analysis.schema.classes) {
108062
+ for (const declaration of sourceClass.members) {
108063
+ if (!declaration.modifiers.includes("static")) continue;
108064
+ if (declaration.kind !== "field") continue;
108065
+ const path = `${sourceClass.name}.${declaration.name}`;
108066
+ statics.set(path, {
108067
+ memberId: materializedId(declaration, "member", path),
108068
+ typeName: declaration.type.name
108069
+ });
108070
+ }
108071
+ }
108072
+ sourceStatics = statics;
108073
+ return statics;
108074
+ };
108075
+ const staticValueId = (path, memberId) => args.staticValueIdsBySymbol.get(path) ?? memberValueIdV4(memberId);
108076
+ const settle = (call) => {
108077
+ const spelled = referencedSymbolPath(call);
108078
+ if (spelled === null) return null;
108079
+ if (args.localValues.has(spelled.path)) {
108080
+ const declared = args.localValues.declaredTarget(spelled.path);
108081
+ if (declared === null)
108082
+ throw unidentifiedLocalReferenceError(spelled.path);
108083
+ const typeName2 = spelled.genericTypeName ?? declared.typeName;
108084
+ if ("id" in declared) return { id: declared.id, typeName: typeName2 };
108085
+ return {
108086
+ id: staticValueId(declared.ownerPath, declared.ownerMemberId),
108087
+ typeName: typeName2
108088
+ };
108089
+ }
108090
+ const source = readSourceStatics().get(spelled.path);
108091
+ if (source !== void 0) {
108092
+ return {
108093
+ id: staticValueId(spelled.path, source.memberId),
108094
+ typeName: spelled.genericTypeName ?? source.typeName
108095
+ };
108096
+ }
108097
+ const stored = args.staticValueIdsBySymbol.get(spelled.path);
108098
+ if (stored === void 0) return null;
108099
+ const typeName = spelled.genericTypeName ?? storedStaticTypeName(args.manifest, spelled.path);
108100
+ return typeName === null ? null : { id: stored, typeName };
108101
+ };
108102
+ return (code) => settleInitializerReferenceSpellings(code, settle);
108103
+ }
108104
+ function storedStaticTypeName(manifest, path) {
108105
+ const separator = path.lastIndexOf(".");
108106
+ if (separator < 0) return null;
108107
+ const className = path.slice(0, separator);
108108
+ const memberName = path.slice(separator + 1);
108109
+ const schemaClass2 = manifest.classes.find(
108110
+ (entry) => entry.name === className
108111
+ );
108112
+ const memberId = schemaClass2?.schema[memberName];
108113
+ const member = manifest.members.find((entry) => entry.id === memberId);
108114
+ if (member?.kind !== "class") return null;
108115
+ return manifest.classes.find((entry) => entry.id === member.classId)?.name ?? null;
108116
+ }
108117
+ var init_initializer_reference_spellings = __esm({
108118
+ "src/project-source/initializer-reference-spellings.ts"() {
108119
+ "use strict";
108120
+ init_member_value_id();
108121
+ init_src();
108122
+ init_key_reference_spelling();
108123
+ init_lower_support();
108124
+ }
108125
+ });
108126
+
108041
108127
  // ../src/models/members/required-constructor-id.ts
108042
108128
  function derivedRequiredConstructorId(classId) {
108043
108129
  return inSystemRecordNamespaceOf(
@@ -108490,9 +108576,9 @@ function lowerClass(context, declaration) {
108490
108576
  if (classBases.length > 1) {
108491
108577
  throw new Error(`Class ${declaration.name} has more than one Class base.`);
108492
108578
  }
108493
- const extendsClassId = classBases[0] ? requiredName2(context.classIdsByName, classBases[0].name, "class") : null;
108579
+ const extendsClassId = classBases[0] ? requiredName(context.classIdsByName, classBases[0].name, "class") : null;
108494
108580
  const implementsInterfaceIds = declaration.baseTypes.filter((type) => context.interfaceIdsByName.has(type.name)).map(
108495
- (type) => requiredName2(context.interfaceIdsByName, type.name, "interface")
108581
+ (type) => requiredName(context.interfaceIdsByName, type.name, "interface")
108496
108582
  );
108497
108583
  const schema = {};
108498
108584
  const schemaKeyOrder = [];
@@ -109125,7 +109211,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
109125
109211
  entryMemberId: entryId,
109126
109212
  key: keyType.name === "string" ? { kind: "string" } : {
109127
109213
  kind: "enum",
109128
- enumId: requiredName2(context.enumIdsByName, keyType.name, "enum")
109214
+ enumId: requiredName(context.enumIdsByName, keyType.name, "enum")
109129
109215
  }
109130
109216
  };
109131
109217
  }
@@ -109482,7 +109568,7 @@ function lowerInterface(context, declaration) {
109482
109568
  ...declaration.docsText === void 0 ? {} : { docsText: declaration.docsText },
109483
109569
  members,
109484
109570
  extendsInterfaceIds: declaration.baseTypes.map(
109485
- (type) => requiredName2(context.interfaceIdsByName, type.name, "interface")
109571
+ (type) => requiredName(context.interfaceIdsByName, type.name, "interface")
109486
109572
  ),
109487
109573
  system: systemMetadata(declaration.annotations) ?? base?.system ?? null
109488
109574
  };
@@ -109579,7 +109665,7 @@ function lowerType(context, type, ownerClass) {
109579
109665
  kind: "dictionary",
109580
109666
  nullable: nullable2,
109581
109667
  entryType: lowerType(context, requiredTypeArgument(type, 1), ownerClass),
109582
- keyEnumId: key.name === "string" ? null : requiredName2(context.enumIdsByName, key.name, "enum"),
109668
+ keyEnumId: key.name === "string" ? null : requiredName(context.enumIdsByName, key.name, "enum"),
109583
109669
  readOnly: false
109584
109670
  };
109585
109671
  }
@@ -109659,7 +109745,13 @@ function lowerDefault(context, initializer, type, ownerClass, base, memberId, st
109659
109745
  }
109660
109746
  const expression = parseExpression(initializer);
109661
109747
  if (positionRequiresEvaluation(context, expression, type, ownerClass)) {
109662
- return { init: { code: normalizeInitializerSource(initializer) } };
109748
+ return {
109749
+ init: {
109750
+ code: context.settleInitializerReferences(
109751
+ normalizeInitializerSource(initializer)
109752
+ )
109753
+ }
109754
+ };
109663
109755
  }
109664
109756
  if (context.rowBackedDefaultMemberIds.has(memberId) && base?.defaultValue && !("serverValueId" in base.defaultValue)) {
109665
109757
  return base.defaultValue;
@@ -109984,7 +110076,7 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
109984
110076
  );
109985
110077
  }
109986
110078
  const className = explicitPartial ? expectedType.name : expression.className ?? expectedType.name;
109987
- const classId = requiredName2(context.classIdsByName, className, "class");
110079
+ const classId = requiredName(context.classIdsByName, className, "class");
109988
110080
  const innerEnvironment = constructedGenericEnvironment(
109989
110081
  context,
109990
110082
  classId,
@@ -110164,15 +110256,6 @@ function isStoredActionLiteral(type, expression) {
110164
110256
  while (current.kind === "annotated") current = current.expression;
110165
110257
  return current.kind === "litList";
110166
110258
  }
110167
- function sourceOffsetAt(source, pos) {
110168
- let offset = 0;
110169
- for (let line = 1; line < pos.line; line += 1) {
110170
- const next = source.indexOf("\n", offset);
110171
- if (next < 0) return null;
110172
- offset = next + 1;
110173
- }
110174
- return Math.min(offset + pos.column - 1, source.length);
110175
- }
110176
110259
  function lambdaExpressionSource(source, lambda) {
110177
110260
  const start = sourceOffsetAt(source, lambda.pos);
110178
110261
  if (start === null) return null;
@@ -110652,14 +110735,14 @@ function genericConstraint(context, ownerClass, parameterId, type, baseConstrain
110652
110735
  }
110653
110736
  return {
110654
110737
  kind: "enum",
110655
- enumId: requiredName2(context.enumIdsByName, type.name, "enum")
110738
+ enumId: requiredName(context.enumIdsByName, type.name, "enum")
110656
110739
  };
110657
110740
  }
110658
110741
  function inheritedMemberId(context, ownerClass, name) {
110659
110742
  const directBase = ownerClass.baseTypes.find(
110660
110743
  (entry) => context.classIdsByName.has(entry.name)
110661
110744
  );
110662
- const classId = directBase ? requiredName2(context.classIdsByName, directBase.name, "class") : null;
110745
+ const classId = directBase ? requiredName(context.classIdsByName, directBase.name, "class") : null;
110663
110746
  return effectiveMemberIdByName(context, classId, name);
110664
110747
  }
110665
110748
  function effectiveMemberIdByName(context, startClassId, name) {
@@ -110682,7 +110765,7 @@ function effectiveMemberIdByName(context, startClassId, name) {
110682
110765
  const sourceBase = sourceClass.baseTypes.find(
110683
110766
  (entry) => context.classIdsByName.has(entry.name)
110684
110767
  );
110685
- classId = sourceBase ? requiredName2(context.classIdsByName, sourceBase.name, "class") : null;
110768
+ classId = sourceBase ? requiredName(context.classIdsByName, sourceBase.name, "class") : null;
110686
110769
  continue;
110687
110770
  }
110688
110771
  const pulledClass = context.baseClasses.get(classId);
@@ -110998,6 +111081,7 @@ var UNSET_LIST_COLUMN_WIDTH, EMPTY_GENERIC_TYPE_ENVIRONMENT, DICTIONARY_KEY_TYPE
110998
111081
  var init_lower_members = __esm({
110999
111082
  "src/project-source/lower-members.ts"() {
111000
111083
  "use strict";
111084
+ init_initializer_reference_spellings();
111001
111085
  init_src();
111002
111086
  init_src2();
111003
111087
  init_lower_support();
@@ -111202,7 +111286,7 @@ function genericRelationEndpoint(context, expression, relationKind, side, prior)
111202
111286
  }
111203
111287
  return {
111204
111288
  recordKind: "class",
111205
- recordId: requiredName2(context.classIdsByName, expression.name, "class")
111289
+ recordId: requiredName(context.classIdsByName, expression.name, "class")
111206
111290
  };
111207
111291
  }
111208
111292
  if (expression.kind === "member" && expression.receiver.kind === "ident" && expected === "value") {
@@ -111310,7 +111394,7 @@ function relationExpressionIdentity(expression) {
111310
111394
  }
111311
111395
  function relationTargetClassId(context, expression) {
111312
111396
  if (expression.kind === "ident") {
111313
- return requiredName2(context.classIdsByName, expression.name, "class");
111397
+ return requiredName(context.classIdsByName, expression.name, "class");
111314
111398
  }
111315
111399
  if (expression.kind === "call" && expression.callee.kind === "ident" && expression.callee.name === "Reference") {
111316
111400
  const index = expression.argumentNames?.findIndex((name) => name === "id") ?? -1;
@@ -111358,7 +111442,7 @@ function lowerVariants(context, analysis) {
111358
111442
  );
111359
111443
  const variants = variantGlobals(analysis).map((global) => {
111360
111444
  const className = owningClassName(global);
111361
- const classId = requiredName2(context.classIdsByName, className, "class");
111445
+ const classId = requiredName(context.classIdsByName, className, "class");
111362
111446
  const variantId = variantRecordId(global, global.type.name);
111363
111447
  return {
111364
111448
  id: variantId,
@@ -111390,7 +111474,7 @@ function variantValueBindingsV4(manifest, analysis) {
111390
111474
  targetClassId: variant2.classId,
111391
111475
  targetClassName: requiredClassName2(classNames, variant2.classId),
111392
111476
  variantTypeName: global.type.name,
111393
- valueClassId: global.type.name === NEO_LOOKUP_VARIANT_TYPE_NAME ? requiredName2(
111477
+ valueClassId: global.type.name === NEO_LOOKUP_VARIANT_TYPE_NAME ? requiredName(
111394
111478
  new Map(
111395
111479
  manifest.classes.map((entry) => [entry.name, entry.id])
111396
111480
  ),
@@ -111425,7 +111509,7 @@ function lowerVariantFolders(context, analysis) {
111425
111509
  return {
111426
111510
  id: variantRecordId(global, NEO_VARIANT_FOLDER_TYPE_NAME),
111427
111511
  source: sourceIdentity2(global, "variantFolder", global.name),
111428
- classId: requiredName2(context.classIdsByName, className, "class"),
111512
+ classId: requiredName(context.classIdsByName, className, "class"),
111429
111513
  path: folderPath2(global),
111430
111514
  binding: folderBinding(context, global)
111431
111515
  };
@@ -111625,6 +111709,7 @@ var init_lower_variants = __esm({
111625
111709
  // src/project-source/lower-schema.ts
111626
111710
  function lowerProjectSchemaV4(base, analysis, options = {}) {
111627
111711
  const classIdsByName = identityMap(analysis.schema.classes, "class");
111712
+ const staticValueIdsBySymbol3 = options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map();
111628
111713
  const interfaceIdsByName = identityMap(
111629
111714
  analysis.schema.interfaces,
111630
111715
  "interface"
@@ -111700,7 +111785,17 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
111700
111785
  loweredMembers: /* @__PURE__ */ new Map(),
111701
111786
  entryTypesByEntryId: /* @__PURE__ */ new Map(),
111702
111787
  placements: /* @__PURE__ */ new Map(),
111703
- staticValueIdsBySymbol: options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map(),
111788
+ staticValueIdsBySymbol: staticValueIdsBySymbol3,
111789
+ settleInitializerReferences: createSchemaInitializerReferenceSettlerV4({
111790
+ analysis,
111791
+ manifest: base,
111792
+ staticValueIdsBySymbol: staticValueIdsBySymbol3,
111793
+ localValues: new LocalValueBindingsV4(
111794
+ analysis.values.globals,
111795
+ analysis.schema.enums.map((declaration) => declaration.name),
111796
+ staticMembersInitializedByName(analysis)
111797
+ )
111798
+ }),
111704
111799
  templateIdsByName: new Map(
111705
111800
  analysis.configuration.globals.flatMap(
111706
111801
  (global) => global.type.name === "TextureTemplate" ? [
@@ -111833,6 +111928,8 @@ var init_lower_schema = __esm({
111833
111928
  init_lower_relations();
111834
111929
  init_lower_variants();
111835
111930
  init_lower_support();
111931
+ init_initializer_reference_spellings();
111932
+ init_local_values();
111836
111933
  }
111837
111934
  });
111838
111935
 
@@ -115305,7 +115402,7 @@ function materializedInitializerReconciliationFailuresV4(args) {
115305
115402
  `Cannot reconcile stored construction for value "${valueId}": its canonical pulled constructor expression is unavailable.`
115306
115403
  );
115307
115404
  }
115308
- const authoredConstructionChanged = args.manifest !== void 0 && canonicalExpression !== constructorExpressionSlice(reconciliation.code);
115405
+ const authoredConstructionChanged = args.manifest !== void 0 && canonicalExpression !== reconciliation.construction;
115309
115406
  authoredConstructionChangedByValueId.set(
115310
115407
  valueId,
115311
115408
  authoredConstructionChanged
@@ -115694,7 +115791,6 @@ var init_local_initializer_materialization = __esm({
115694
115791
  init_src();
115695
115792
  init_projection();
115696
115793
  init_source_diagnostics();
115697
- init_init_source();
115698
115794
  init_initializer_replay();
115699
115795
  init_materialized_construction_cache();
115700
115796
  init_neoscript_build_cache();
@@ -119943,7 +120039,8 @@ function buildValueLowerContext(state, manifest, options = {}) {
119943
120039
  return {
119944
120040
  localValues: registry.localValues ??= new LocalValueBindingsV4(
119945
120041
  options.analysis?.values.globals ?? [],
119946
- manifest.enums.values().map((entry) => entry.name)
120042
+ manifest.enums.values().map((entry) => entry.name),
120043
+ options.analysis === void 0 ? [] : staticMembersInitializedByName(options.analysis)
119947
120044
  ),
119948
120045
  state,
119949
120046
  members,
@@ -121045,7 +121142,7 @@ function memberInitializerRequiresEvaluation(context, member, expression, source
121045
121142
  return requiresEvaluation;
121046
121143
  }
121047
121144
  function isSchemaMemberValueRead(context, expression, source) {
121048
- const path = memberPath(annotatedValue(expression).expression);
121145
+ const path = memberPath2(annotatedValue(expression).expression);
121049
121146
  if (path === null) return false;
121050
121147
  const parts = path.split(".");
121051
121148
  const name = parts.at(-1);
@@ -121708,7 +121805,10 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
121708
121805
  nodeType: "initializer",
121709
121806
  id: valueId,
121710
121807
  memberId: member.id,
121711
- code,
121808
+ code: settleInitializerReferenceSpellings(
121809
+ code,
121810
+ (call) => settledReferenceTarget(context, call)
121811
+ ),
121712
121812
  ...containerId === void 0 ? {} : { containerId }
121713
121813
  };
121714
121814
  registerSeedRow(context, rows, initRow, source, sourceExpression);
@@ -122353,6 +122453,10 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
122353
122453
  );
122354
122454
  }
122355
122455
  indexInitAuthoredRowIds(context, code, source.label);
122456
+ const compiledCode = settleInitializerReferenceSpellings(
122457
+ code,
122458
+ (call) => settledReferenceTarget(context, call)
122459
+ );
122356
122460
  const storedConstructorArgs = isObjectRecord2(base.constructorArgs) ? base.constructorArgs : null;
122357
122461
  if (resolvedMember.kind !== "class" && isLiteralValueContent(base)) {
122358
122462
  addReconstructed(
@@ -122387,7 +122491,8 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
122387
122491
  if (source.purpose === "stored" || requiresCanonicalConstruction) {
122388
122492
  context.initializerReconciliations.set(expectedValueId, {
122389
122493
  valueId: expectedValueId,
122390
- code,
122494
+ code: compiledCode,
122495
+ construction: authoredConstruction,
122391
122496
  storedConstructorArgs: storedConstructorArgs === null ? null : structuredClone(storedConstructorArgs),
122392
122497
  // Only a construction this pass could not apply is a conflict. A
122393
122498
  // re-projected one landed on the rows the canonical expression is
@@ -122419,7 +122524,7 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
122419
122524
  context,
122420
122525
  "value",
122421
122526
  expectedValueId,
122422
- { ...literalFields, init: { code } },
122527
+ { ...literalFields, init: { code: compiledCode } },
122423
122528
  source.source
122424
122529
  );
122425
122530
  return expectedValueId;
@@ -123799,7 +123904,7 @@ function requiredDecimal(expression) {
123799
123904
  }
123800
123905
  function sourceValueSymbol(context, expression) {
123801
123906
  const unwrapped = annotatedValue(expression).expression;
123802
- const path = memberPath(unwrapped);
123907
+ const path = memberPath2(unwrapped);
123803
123908
  return path === null ? null : context.staticValueIdsBySymbol.get(path) ?? null;
123804
123909
  }
123805
123910
  function resolveKeyReferenceMemberDefaultsV4(args) {
@@ -123883,12 +123988,12 @@ function referenceTargetSpelling(context, expression) {
123883
123988
  };
123884
123989
  }
123885
123990
  const resolved = referenceTargetBySymbol(context, argument2, genericTypeName);
123886
- const path = memberPath(argument2);
123991
+ const path = memberPath2(argument2);
123887
123992
  if (resolved === null || path === null) return null;
123888
123993
  return { spelling: "symbol", path, resolved };
123889
123994
  }
123890
123995
  function referenceTargetBySymbol(context, argument2, genericTypeName) {
123891
- const path = memberPath(argument2);
123996
+ const path = memberPath2(argument2);
123892
123997
  if (path === null) return null;
123893
123998
  const valueId = context.staticValueIdsBySymbol.get(path);
123894
123999
  if (valueId) {
@@ -123908,6 +124013,22 @@ function referenceTargetBySymbol(context, argument2, genericTypeName) {
123908
124013
  genericTypeName
123909
124014
  } : null;
123910
124015
  }
124016
+ function settledReferenceTarget(context, call) {
124017
+ const target = referenceTargetSpelling(context, call);
124018
+ if (target?.spelling === "symbol") {
124019
+ const typeName2 = target.resolved.genericTypeName ?? target.resolved.typeName;
124020
+ return typeName2 === null ? null : { id: target.resolved.id, typeName: typeName2 };
124021
+ }
124022
+ if (target?.spelling !== "local") return null;
124023
+ const declared = context.localValues.declaredTarget(target.name);
124024
+ if (declared === null) throw unidentifiedLocalReferenceError(target.name);
124025
+ const typeName = target.typeName ?? declared.typeName;
124026
+ if ("id" in declared) return { id: declared.id, typeName };
124027
+ return {
124028
+ id: context.staticValueIdsBySymbol.get(declared.ownerPath) ?? memberValueId(declared.ownerMemberId),
124029
+ typeName
124030
+ };
124031
+ }
123911
124032
  function referenceTargetById(context, id2, genericTypeName) {
123912
124033
  const pendingValue = context.pendingValues.get(id2);
123913
124034
  if (pendingValue !== void 0) {
@@ -124403,7 +124524,7 @@ function indexSourceStaticTargets(targets, state, analysis, manifest, parsedInit
124403
124524
  }
124404
124525
  }
124405
124526
  function sourceValueSymbolFromMap(targets, expression) {
124406
- const path = memberPath(annotatedValue(expression).expression);
124527
+ const path = memberPath2(annotatedValue(expression).expression);
124407
124528
  return path === null ? null : targets.get(path) ?? null;
124408
124529
  }
124409
124530
  function returnedSymbol(body) {
@@ -124421,7 +124542,7 @@ function returnedSymbol(body) {
124421
124542
  function firstReturnedMemberPath(statements) {
124422
124543
  for (const statement of statements) {
124423
124544
  if (statement.kind === "return") {
124424
- const path = statement.expr === null ? null : memberPath(statement.expr);
124545
+ const path = statement.expr === null ? null : memberPath2(statement.expr);
124425
124546
  if (path !== null) return path;
124426
124547
  continue;
124427
124548
  }
@@ -124544,7 +124665,7 @@ function classMemberByName(context, classId, name) {
124544
124665
  );
124545
124666
  }
124546
124667
  function lowerFunctionReference(context, expression, ownerClassId) {
124547
- const symbol = memberPath(expression);
124668
+ const symbol = memberPath2(expression);
124548
124669
  if (symbol === null || symbol.includes(".")) {
124549
124670
  throw new Error("FunctionRef values require a bare function symbol.");
124550
124671
  }
@@ -124593,7 +124714,7 @@ function lowerActionListener2(context, element, ownerClassId, index) {
124593
124714
  `NeoAction listener ${index} is a lambda. A listener must be a member reference: extract the body to an NSFunction member and subscribe that member instead.`
124594
124715
  );
124595
124716
  }
124596
- const path = memberPath(expression);
124717
+ const path = memberPath2(expression);
124597
124718
  if (path === null) {
124598
124719
  throw new Error(
124599
124720
  `NeoAction listener ${index} must name a function, NSFunction, NSDelegate, or NeoAction member on the current Class or a receiver reachable through root.`
@@ -124650,7 +124771,7 @@ function lowerDelegateValue(context, expression, ownerClassId, authoredSlice) {
124650
124771
  }
124651
124772
  return { code };
124652
124773
  }
124653
- const path = memberPath(expression);
124774
+ const path = memberPath2(expression);
124654
124775
  const symbol = path?.startsWith("this.") ? path.slice("this.".length) : path;
124655
124776
  if (symbol === null || symbol === void 0 || symbol.includes(".")) {
124656
124777
  throw new Error(
@@ -124671,7 +124792,7 @@ function lowerDelegateValue(context, expression, ownerClassId, authoredSlice) {
124671
124792
  return { memberId: target.id, valueId: null };
124672
124793
  }
124673
124794
  function fileTargetId(context, expression, registry) {
124674
- const path = memberPath(expression);
124795
+ const path = memberPath2(expression);
124675
124796
  if (path !== null) {
124676
124797
  if (!path.startsWith(`${registry}.`)) return null;
124677
124798
  return context.projectFileIdsBySymbol.get(path) ?? null;
@@ -124683,10 +124804,10 @@ function fileTargetId(context, expression, registry) {
124683
124804
  }
124684
124805
  return null;
124685
124806
  }
124686
- function memberPath(expression) {
124807
+ function memberPath2(expression) {
124687
124808
  if (expression.kind === "ident") return expression.name;
124688
124809
  if (expression.kind !== "member") return null;
124689
- const receiver = memberPath(expression.receiver);
124810
+ const receiver = memberPath2(expression.receiver);
124690
124811
  return receiver === null ? null : `${receiver}.${expression.name}`;
124691
124812
  }
124692
124813
  function annotatedValue(expression) {
@@ -126732,6 +126853,7 @@ var init_value_sources = __esm({
126732
126853
  init_initializer_replay();
126733
126854
  init_key_reference_spelling();
126734
126855
  init_local_values();
126856
+ init_initializer_reference_spellings();
126735
126857
  init_lower_members();
126736
126858
  init_lower_variants();
126737
126859
  init_member_kind_type_names();
@@ -128129,16 +128251,6 @@ var init_api = __esm({
128129
128251
  });
128130
128252
 
128131
128253
  // src/convex.ts
128132
- var convex_exports = {};
128133
- __export(convex_exports, {
128134
- api: () => api2,
128135
- convexHttpActionUrl: () => convexHttpActionUrl,
128136
- createConvexClient: () => createConvexClient,
128137
- createConvexClientForApi: () => createConvexClientForApi,
128138
- createConvexPushConnection: () => createConvexPushConnection,
128139
- mintConvexJwt: () => mintConvexJwt,
128140
- resolveConvexUrl: () => resolveConvexUrl
128141
- });
128142
128254
  import { gzipSync } from "node:zlib";
128143
128255
  import { ConvexClient, ConvexHttpClient } from "convex/browser";
128144
128256
  import { Buffer as Buffer2 } from "node:buffer";
@@ -129827,6 +129939,7 @@ __export(push_exports, {
129827
129939
  applyPushResult: () => applyPushResult,
129828
129940
  assignPendingIds: () => assignPendingIds,
129829
129941
  buildPostPushCompileSchema: () => buildPostPushCompileSchema,
129942
+ commitProjectVersionChanges: () => commitProjectVersionChanges,
129830
129943
  createPendingProjectSourceIdentityV4: () => createPendingProjectSourceIdentityV4,
129831
129944
  prepareCompleteNeoScriptBodyChanges: () => prepareCompleteNeoScriptBodyChanges,
129832
129945
  prepareLocalCandidateV4: () => prepareLocalCandidateV4,
@@ -130058,6 +130171,81 @@ function pendingInterfaceMemberSymbolOwner(value) {
130058
130171
  if (!/^\d+$/u.test(parts[4] ?? "")) return null;
130059
130172
  return owner;
130060
130173
  }
130174
+ async function commitProjectVersionChanges(args) {
130175
+ const { workspace } = args;
130176
+ const body = {
130177
+ operation: args.operation,
130178
+ changes: args.changes,
130179
+ authoredValueSeeds: [],
130180
+ initializerMaterialization: { roots: [] },
130181
+ stagedFiles: [],
130182
+ stagedUploadSessionId: null,
130183
+ // The asynchronous path keys reconnects on this identity; the rows name
130184
+ // the commit, so the same repair resubmitted is the same transaction.
130185
+ sourceHash: createHash10("sha256").update(
130186
+ JSON.stringify(
130187
+ args.changes.map((change) => `${change.recordKind}:${change.recordId}`).sort()
130188
+ )
130189
+ ).digest("hex"),
130190
+ pendingIdAssignments: {},
130191
+ summary: args.summary,
130192
+ headTransactionHash: workspace.state.headTransactionHash ?? null,
130193
+ derivedEdgeExtractorVersion: PROJECT_SNAPSHOT_DERIVED_EDGE_EXTRACTOR_VERSION,
130194
+ forceRecompile: false
130195
+ };
130196
+ const reporter = createPushProgressReporter(args.json, args.progressLabel);
130197
+ reporter.report({
130198
+ type: "project-transaction-progress",
130199
+ transactionId: null,
130200
+ phase: "submitting",
130201
+ totalChangeCount: args.changes.length,
130202
+ appliedChangeCount: 0,
130203
+ totalChunkCount: null,
130204
+ appliedChunkCount: 0,
130205
+ errorCode: null,
130206
+ errorMessage: null
130207
+ });
130208
+ try {
130209
+ const connection = await createConvexPushConnection(workspace);
130210
+ let response;
130211
+ try {
130212
+ response = await connection.submit(body, false);
130213
+ } catch (error) {
130214
+ if (!(error instanceof NeoApiError) || error.status !== 413 || !isObjectRecord2(error.body) || error.body.error !== "schema-commit-route-required")
130215
+ throw error;
130216
+ response = await NeoApiClient.forBaseUrl(
130217
+ workspace.config.apiBaseUrl
130218
+ ).post(
130219
+ `/api/projects/${workspace.config.projectId}/versions/${workspace.config.versionId}/schema/commit`,
130220
+ body
130221
+ );
130222
+ }
130223
+ const accepted = readAcceptedProjectVersionCommitResponse(response);
130224
+ if (accepted === null) {
130225
+ if (!isObjectRecord2(response) || typeof response.kind !== "string") {
130226
+ throw new Error(
130227
+ "Project transaction response is neither accepted nor an immediate commit result."
130228
+ );
130229
+ }
130230
+ return {
130231
+ kind: response.kind === "noop" ? "noop" : "committed",
130232
+ transactionId: immediateTransactionId(response)
130233
+ };
130234
+ }
130235
+ const completed = await waitForAcceptedProjectVersionTransaction({
130236
+ workspace,
130237
+ accepted,
130238
+ reporter,
130239
+ connection
130240
+ });
130241
+ return {
130242
+ kind: completed.totalChangeCount === 0 ? "noop" : "committed",
130243
+ transactionId: completed.transactionId
130244
+ };
130245
+ } finally {
130246
+ reporter.stop();
130247
+ }
130248
+ }
130061
130249
  function readAcceptedProjectVersionCommitResponse(value) {
130062
130250
  if (!isObjectRecord2(value) || value.kind !== "accepted") return null;
130063
130251
  if (typeof value.transactionId !== "string") {
@@ -130239,9 +130427,9 @@ function readNullableString(value, field) {
130239
130427
  function isProjectVersionTransactionCommitStatus(value) {
130240
130428
  return value === "preparing" || value === "waiting" || value === "queued" || value === "applying" || value === "reverting" || value === "noop" || value === "committed" || value === "failed";
130241
130429
  }
130242
- function createPushProgressReporter(json) {
130430
+ function createPushProgressReporter(json, label = "Pushing\u2026") {
130243
130431
  const animated = process.stdout.isTTY === true && !json;
130244
- const indicator = animated ? spinner("Pushing\u2026") : null;
130432
+ const indicator = animated ? spinner(label) : null;
130245
130433
  let lastStructuredEvent = "";
130246
130434
  return {
130247
130435
  report(event) {
@@ -138377,7 +138565,7 @@ var init_registry2 = __esm({
138377
138565
  "schema-contract/registry.mjs"() {
138378
138566
  "use strict";
138379
138567
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
138380
- cliVersion: "0.53.0",
138568
+ cliVersion: "0.53.2",
138381
138569
  projectFileUploadBatchSize: 32,
138382
138570
  documentRecords: {
138383
138571
  member: {
@@ -141869,8 +142057,7 @@ async function repairUnprojectedValueRows(workspace, findings, yes) {
141869
142057
  return;
141870
142058
  }
141871
142059
  const rows = plan.roots.flatMap((root) => root.rows);
141872
- const pulledHeadTransactionHash = workspace.state.headTransactionHash;
141873
- if (typeof pulledHeadTransactionHash !== "string") {
142060
+ if (typeof workspace.state.headTransactionHash !== "string") {
141874
142061
  throw new Error(
141875
142062
  'This workspace has no recorded project head, so `neo doctor --fix` cannot prove its deletions land on the state the audit read. Run "neo pull", then rerun.'
141876
142063
  );
@@ -141904,7 +142091,7 @@ async function repairUnprojectedValueRows(workspace, findings, yes) {
141904
142091
  console.log("Cancelled. No records were deleted.");
141905
142092
  return;
141906
142093
  }
141907
- const { api: api3, createConvexClient: createConvexClient2 } = await Promise.resolve().then(() => (init_convex(), convex_exports));
142094
+ const { commitProjectVersionChanges: commitProjectVersionChanges2 } = await Promise.resolve().then(() => (init_push(), push_exports));
141908
142095
  const { createProjectVersionIntent: createProjectVersionIntent2 } = await Promise.resolve().then(() => (init_project_version_intents(), project_version_intents_exports));
141909
142096
  const changes = rows.map((row) => ({
141910
142097
  recordKind: "value",
@@ -141916,95 +142103,44 @@ async function repairUnprojectedValueRows(workspace, findings, yes) {
141916
142103
  source: "neo-cli-doctor"
141917
142104
  })
141918
142105
  }));
141919
- const batchSize = immediateCommitBatchSize(changes);
141920
- const convex = await createConvexClient2(workspace);
141921
- const progress = spinner(`Deleting ${rowLabel(rows.length)}\u2026`);
141922
- let deleted = 0;
141923
- let expectedHeadTransactionHash = pulledHeadTransactionHash;
141924
- for (let index = 0; index < changes.length; index += batchSize) {
141925
- const batch = changes.slice(index, index + batchSize);
141926
- let transactionHash;
141927
- try {
141928
- const result = await convex.mutation(
141929
- api3.serverProjectRecordOperations.commitFromSession,
141930
- {
141931
- projectId: workspace.config.projectId,
141932
- versionId: workspace.config.versionId,
141933
- operation: "delete",
141934
- changes: batch,
141935
- summary: `neo doctor --fix (${rowLabel(batch.length)})`,
141936
- expectedHeadTransactionHash
141937
- }
141938
- );
141939
- transactionHash = committedTransactionHash(result);
141940
- } catch (error) {
141941
- progress.fail(
141942
- deleted === 0 ? `Failed to delete ${rowLabel(batch.length)}.` : `Failed after deleting ${rowLabel(deleted)}.`
141943
- );
141944
- throw repairFailure(error, deleted);
141945
- }
141946
- if (transactionHash === null) continue;
141947
- expectedHeadTransactionHash = transactionHash;
141948
- deleted += batch.length;
141949
- progress.update(
141950
- `Deleting ${rowLabel(rows.length)}\u2026 ${String(deleted)} done`
141951
- );
141952
- }
141953
- progress.succeed(`Deleted ${rowLabel(deleted)} across ${rootLabel}.`);
141954
- console.log('Run "neo pull" to refresh the working copy.');
141955
- }
141956
- function immediateCommitBatchSize(changes) {
141957
- let fits = 0;
141958
- let low = 1;
141959
- let high = changes.length;
141960
- while (low <= high) {
141961
- const size = Math.floor((low + high) / 2);
141962
- if (planProjectVersionTransaction(changes.slice(0, size)).path === "immediate") {
141963
- fits = size;
141964
- low = size + 1;
141965
- } else {
141966
- high = size - 1;
141967
- }
141968
- }
141969
- if (fits === 0) {
141970
- throw new Error(
141971
- "Deleting a single value row exceeds the immediate transaction budget, so `neo doctor --fix` cannot commit anything. The transaction cost model needs to change before this repair can run."
141972
- );
141973
- }
141974
- return fits;
141975
- }
141976
- function committedTransactionHash(result) {
141977
- if (!isObjectRecord2(result)) {
141978
- throw new Error(
141979
- "Doctor repair committed a deletion but the server returned no transaction envelope."
141980
- );
142106
+ let committed;
142107
+ try {
142108
+ committed = await commitProjectVersionChanges2({
142109
+ workspace,
142110
+ operation: "delete",
142111
+ changes,
142112
+ summary: `neo doctor --fix (${rowLabel(rows.length)})`,
142113
+ progressLabel: `Deleting ${rowLabel(rows.length)}\u2026`,
142114
+ json: false
142115
+ });
142116
+ } catch (error) {
142117
+ throw repairFailure(error);
141981
142118
  }
141982
- if (result.transaction === null) return null;
141983
- const transactionHash = isObjectRecord2(result.transaction) ? result.transaction.transactionHash : void 0;
141984
- if (typeof transactionHash !== "string") {
141985
- throw new Error(
141986
- "Doctor repair committed a transaction that carries no hash, so the remaining deletions have no fast-forward base."
142119
+ if (committed.kind === "noop") {
142120
+ console.log(
142121
+ `${sym.info} Nothing to delete: the ${rowLabel(rows.length)} were already gone.`
141987
142122
  );
142123
+ } else {
142124
+ success(`Deleted ${rowLabel(rows.length)} across ${rootLabel}.`);
141988
142125
  }
141989
- return transactionHash;
142126
+ console.log('Run "neo pull" to refresh the working copy.');
141990
142127
  }
141991
- function repairFailure(error, deleted) {
141992
- const applied = deleted === 0 ? "" : ` ${rowLabel(deleted)} were already deleted.`;
141993
- const code = convexErrorCode(error);
142128
+ function repairFailure(error) {
142129
+ const code = writeRefusalCode(error);
141994
142130
  if (code === "non-fast-forward" || code === "base-hash-conflict") {
141995
142131
  return new Error(
141996
- `neo doctor --fix was refused: the project moved on since this workspace pulled, so the audit is stale.${applied} Run \`neo pull\` to re-derive it, then rerun.`,
142132
+ "neo doctor --fix was refused: the project moved on since this workspace pulled, so the audit is stale. Run `neo pull` to re-derive it, then rerun.",
141997
142133
  { cause: error }
141998
142134
  );
141999
142135
  }
142000
142136
  return new Error(
142001
- `neo doctor --fix could not delete the audited rows: ${errorMessage3(error)}${applied}`,
142137
+ `neo doctor --fix could not delete the audited rows: ${errorMessage3(error)}`,
142002
142138
  { cause: error }
142003
142139
  );
142004
142140
  }
142005
- function convexErrorCode(error) {
142141
+ function writeRefusalCode(error) {
142006
142142
  if (!isObjectRecord2(error)) return null;
142007
- const data = error.data;
142143
+ const data = error instanceof NeoApiError ? error.body : error.data;
142008
142144
  if (!isObjectRecord2(data)) return null;
142009
142145
  return typeof data.error === "string" ? data.error : null;
142010
142146
  }
@@ -142019,8 +142155,8 @@ var init_doctor = __esm({
142019
142155
  init_source_diagnostics();
142020
142156
  init_project_documents();
142021
142157
  init_project_integrity();
142022
- init_project_version_transaction_planning();
142023
142158
  init_projection();
142159
+ init_http();
142024
142160
  NEO_COMPILER_CONTRACT = "ProjectSourceAnalysisV4";
142025
142161
  NEO_VSCODE_EXTENSION_ID = "neocompose.neo-compose-neoscript";
142026
142162
  NEO_VSCODE_EXTENSION_CONTRACT_VERSION = "0.3.0";
@@ -144979,16 +145115,16 @@ function dryrunOwnership(document, valueById, saveBindings = /* @__PURE__ */ new
144979
145115
  return memberById2.get(memberId)?.valueId;
144980
145116
  };
144981
145117
  const visitedPlacements = /* @__PURE__ */ new Set();
144982
- const walkOwnedGraph = (memberPath2, valueId) => {
144983
- const memberId = memberPath2.at(-1);
145118
+ const walkOwnedGraph = (memberPath3, valueId) => {
145119
+ const memberId = memberPath3.at(-1);
144984
145120
  if (memberId === void 0) return;
144985
- const visitKey = `${memberPath2.join("/")}\0${valueId}`;
145121
+ const visitKey = `${memberPath3.join("/")}\0${valueId}`;
144986
145122
  if (visitedPlacements.has(visitKey)) return;
144987
145123
  visitedPlacements.add(visitKey);
144988
145124
  const value = valueById.get(valueId);
144989
145125
  const member = memberById2.get(memberId);
144990
145126
  if (value === void 0 || member === void 0) return;
144991
- const storage = storageResolver.effectiveStorageForPath(memberPath2);
145127
+ const storage = storageResolver.effectiveStorageForPath(memberPath3);
144992
145128
  if (storage === 2 /* Save */) saveOwned.add(valueId);
144993
145129
  if (storage === 3 /* Session */) sessionOwned.add(valueId);
144994
145130
  if (member.kind === 7 /* Class */ && isObjectRecord2(value.value)) {
@@ -145000,7 +145136,7 @@ function dryrunOwnership(document, valueById, saveBindings = /* @__PURE__ */ new
145000
145136
  for (const [key, childValueId] of Object.entries(value.value)) {
145001
145137
  const childMemberId = childMemberByKey.get(key);
145002
145138
  if (childMemberId !== void 0 && typeof childValueId === "string") {
145003
- walkOwnedGraph([...memberPath2, childMemberId], childValueId);
145139
+ walkOwnedGraph([...memberPath3, childMemberId], childValueId);
145004
145140
  }
145005
145141
  }
145006
145142
  return;
@@ -145011,7 +145147,7 @@ function dryrunOwnership(document, valueById, saveBindings = /* @__PURE__ */ new
145011
145147
  if (entryMemberId === void 0) return;
145012
145148
  for (const childValueId of membership.get(valueId) ?? []) {
145013
145149
  if (typeof childValueId === "string") {
145014
- walkOwnedGraph([...memberPath2, entryMemberId], childValueId);
145150
+ walkOwnedGraph([...memberPath3, entryMemberId], childValueId);
145015
145151
  }
145016
145152
  }
145017
145153
  return;
@@ -145022,7 +145158,7 @@ function dryrunOwnership(document, valueById, saveBindings = /* @__PURE__ */ new
145022
145158
  const childIds = Array.isArray(value.value) ? value.value : Object.values(value.value);
145023
145159
  for (const childValueId of childIds) {
145024
145160
  if (typeof childValueId === "string") {
145025
- walkOwnedGraph([...memberPath2, entryMemberId], childValueId);
145161
+ walkOwnedGraph([...memberPath3, entryMemberId], childValueId);
145026
145162
  }
145027
145163
  }
145028
145164
  }
@@ -146250,7 +146386,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
146250
146386
  async function main() {
146251
146387
  const args = parseArgs(process.argv.slice(2));
146252
146388
  if (args.command === "--version") {
146253
- console.log("0.53.0");
146389
+ console.log("0.53.2");
146254
146390
  return;
146255
146391
  }
146256
146392
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {