@xnetjs/data 0.11.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/account-ZD3HMRY6.js +12 -0
  2. package/dist/{account-ledger-R2GAFJL6.js → account-ledger-ZHBNVREV.js} +3 -3
  3. package/dist/auth/index.d.ts +15 -5
  4. package/dist/auth/index.js +1 -1
  5. package/dist/budget-FTGZEXX6.js +12 -0
  6. package/dist/canvas-NQBTRNLS.js +10 -0
  7. package/dist/channel-474QAZGP.js +12 -0
  8. package/dist/chat-message-LGLCITLE.js +10 -0
  9. package/dist/{chunk-VQ7JHB67.js → chunk-22FKOLMX.js} +2 -2
  10. package/dist/{chunk-LYSWLCOI.js → chunk-26HTTVJN.js} +2 -2
  11. package/dist/{chunk-PH3PVAR6.js → chunk-3PV6QTKF.js} +2 -2
  12. package/dist/{chunk-KQUALW4O.js → chunk-4KJ4NAMC.js} +1 -1
  13. package/dist/{chunk-U64CW73O.js → chunk-52DR23IW.js} +2 -2
  14. package/dist/{chunk-SVNGSZZA.js → chunk-57UZYV3L.js} +2 -2
  15. package/dist/{chunk-3L73ZALR.js → chunk-5B47M2IG.js} +196 -201
  16. package/dist/{chunk-QVQVKZ3U.js → chunk-5UJMY3AH.js} +6 -5
  17. package/dist/{chunk-3J3HILXO.js → chunk-7PCMTV6J.js} +2 -2
  18. package/dist/{chunk-YSUIXD2Y.js → chunk-C4CQH7UD.js} +2 -2
  19. package/dist/{chunk-QN334DU7.js → chunk-CARPMPXV.js} +301 -245
  20. package/dist/{chunk-PNESGUH5.js → chunk-D4EVJN2P.js} +2 -2
  21. package/dist/{chunk-RL64OJJ5.js → chunk-D4LUUZYD.js} +36 -9
  22. package/dist/{chunk-W7EBL7ZU.js → chunk-DP4Q2HMO.js} +2 -2
  23. package/dist/{chunk-5EXHNXPL.js → chunk-DPJ4T2LQ.js} +2 -2
  24. package/dist/{chunk-BQLQSWKZ.js → chunk-EN6XTVLZ.js} +2 -2
  25. package/dist/{chunk-Q67VT5XL.js → chunk-ENA6NEFY.js} +5 -5
  26. package/dist/{chunk-TORDOOJ5.js → chunk-EYRZ6ZUB.js} +1 -1
  27. package/dist/{chunk-NI4FHG2K.js → chunk-EZTBWWMS.js} +2 -2
  28. package/dist/{chunk-UQM3G5A2.js → chunk-FWCM2TKJ.js} +2 -2
  29. package/dist/{chunk-OSAWNZVM.js → chunk-GCTONBF6.js} +1 -1
  30. package/dist/{chunk-2ZNJWIQG.js → chunk-HPUXHSKR.js} +2 -2
  31. package/dist/{chunk-ZPZ7XDA6.js → chunk-HTZTBXKL.js} +2 -2
  32. package/dist/{chunk-MCKP4F72.js → chunk-I7JMGCV6.js} +26 -5
  33. package/dist/{chunk-OGJCRNGE.js → chunk-IA23CLGV.js} +2 -2
  34. package/dist/{chunk-YEFKQYKA.js → chunk-IKGUBSZP.js} +2 -2
  35. package/dist/{chunk-XMSKJ5PV.js → chunk-IKI5FBNO.js} +2 -2
  36. package/dist/{chunk-OCMSAKWV.js → chunk-JA56EQJO.js} +15 -3
  37. package/dist/{chunk-TCTZW4A6.js → chunk-JLUFPUIL.js} +2 -2
  38. package/dist/{chunk-WEPK7SZF.js → chunk-KTPSQJ5L.js} +2 -2
  39. package/dist/{chunk-T5AZAOG5.js → chunk-LK5ZIAIE.js} +1 -1
  40. package/dist/{chunk-XROI44ZP.js → chunk-M4KGY2PC.js} +2 -2
  41. package/dist/{chunk-QJW5LDP4.js → chunk-NSMSOIEW.js} +2 -2
  42. package/dist/{chunk-FB63TZVI.js → chunk-OF6455OV.js} +2 -2
  43. package/dist/{chunk-6OMG4I7M.js → chunk-OIWW5TG3.js} +2 -2
  44. package/dist/{chunk-6KLGA6IR.js → chunk-Q6VTTPG4.js} +2 -2
  45. package/dist/{chunk-J4ANIXIV.js → chunk-QDLWTOII.js} +2 -2
  46. package/dist/{chunk-EBNMV2VO.js → chunk-RRXJNZX5.js} +1 -1
  47. package/dist/{chunk-FVEACSKE.js → chunk-RXBLWQQI.js} +2 -2
  48. package/dist/{chunk-L7NRPLE5.js → chunk-S6JWYPVW.js} +2 -2
  49. package/dist/{chunk-JDFNMFOZ.js → chunk-SOXXBQ4P.js} +2 -2
  50. package/dist/{chunk-4EYKGTSQ.js → chunk-T45PWXNA.js} +2 -2
  51. package/dist/{chunk-MD553LDL.js → chunk-TRPXLCND.js} +2 -2
  52. package/dist/{chunk-ZCOFZY5M.js → chunk-UUQVNDBG.js} +2 -2
  53. package/dist/{chunk-53F4PRNC.js → chunk-W3QOEPUN.js} +2 -2
  54. package/dist/{chunk-S6U6TCMN.js → chunk-WC7EDJHC.js} +2 -2
  55. package/dist/{chunk-KQAT4XBL.js → chunk-WWQO7QKV.js} +2 -2
  56. package/dist/{chunk-BY5O6LNC.js → chunk-XJBDESCX.js} +1 -1
  57. package/dist/{chunk-ZZ6TWKGS.js → chunk-XQDXQ7WG.js} +2 -2
  58. package/dist/{chunk-MBTUO3ZL.js → chunk-YD2ZPFT7.js} +2 -2
  59. package/dist/{chunk-ZLU4Y3O2.js → chunk-YHO7GNZK.js} +2 -2
  60. package/dist/{chunk-Y3S5SRVM.js → chunk-YSD4NSCE.js} +2 -2
  61. package/dist/{chunk-IJ44LR7N.js → chunk-ZKJXGQCR.js} +2 -2
  62. package/dist/{chunk-GU6THOAB.js → chunk-ZKMWJNDQ.js} +2 -2
  63. package/dist/{chunk-OPPHF3TF.js → chunk-ZKVRGKLM.js} +3 -3
  64. package/dist/{clone-CbmoWwu4.d.ts → clone-Bj0nQyMc.d.ts} +2 -2
  65. package/dist/comment-IAZJHG6G.js +10 -0
  66. package/dist/{crm-L5RYAAF3.js → crm-AFJSSPHK.js} +5 -5
  67. package/dist/dashboard-2DLFZM2J.js +10 -0
  68. package/dist/database/index.d.ts +3 -3
  69. package/dist/database/index.js +10 -10
  70. package/dist/database-5M7ZA33U.js +10 -0
  71. package/dist/database-field-IFUWOK7X.js +10 -0
  72. package/dist/database-row-C52KCOPB.js +10 -0
  73. package/dist/database-select-option-AEAPKXEE.js +10 -0
  74. package/dist/database-view-GUGJHS7J.js +10 -0
  75. package/dist/experiment-JXHENWXV.js +10 -0
  76. package/dist/{external-item-P2E5X7BZ.js → external-item-ZVD33IXV.js} +5 -5
  77. package/dist/external-reference-LGFNVEKC.js +8 -0
  78. package/dist/feed-CLEHVA6Q.js +12 -0
  79. package/dist/feed-item-QXRIE6FU.js +12 -0
  80. package/dist/{folder-6KM3KYD5.js → folder-NU5TJFOT.js} +3 -3
  81. package/dist/{game-5AK5XWBR.js → game-7WW2JX6O.js} +5 -5
  82. package/dist/grant-W772T6FE.js +8 -0
  83. package/dist/{grant-expiration-cleaner-Bm1fSG42.d.ts → grant-expiration-cleaner-BrMW0ffX.d.ts} +7 -2
  84. package/dist/import-batch-ZRU4FY6Y.js +12 -0
  85. package/dist/{inbox-state-E5NSVOGP.js → inbox-state-IO5C7HVE.js} +3 -3
  86. package/dist/index.d.ts +7 -6
  87. package/dist/index.js +316 -314
  88. package/dist/map-BZAVGCR6.js +10 -0
  89. package/dist/media-asset-VHFL65HI.js +8 -0
  90. package/dist/{meeting-LMUYTZBF.js → meeting-PVNKBGTI.js} +5 -5
  91. package/dist/{memory-PNRTMBZO.js → memory-5PD3XCKB.js} +3 -3
  92. package/dist/metric-6IGGFJMB.js +10 -0
  93. package/dist/milestone-MZAZCWGR.js +12 -0
  94. package/dist/{moderation-FFHETMRB.js → moderation-CXQB77CP.js} +3 -3
  95. package/dist/observation-O3DLKVIH.js +10 -0
  96. package/dist/page-UE5NPYEF.js +10 -0
  97. package/dist/posting-5VZZMOKS.js +12 -0
  98. package/dist/{profile-XBPZQA3C.js → profile-USKJ6PN7.js} +3 -3
  99. package/dist/project-UHGGEFLP.js +10 -0
  100. package/dist/{query-ast-Bvg0Wolx.d.ts → query-ast-ESRn8U2H.d.ts} +1 -1
  101. package/dist/reaction-KD3G75UH.js +10 -0
  102. package/dist/{registry-_49rC6IG.d.ts → registry-BGD80QCd.d.ts} +1 -1
  103. package/dist/saved-view-AZTUINZA.js +10 -0
  104. package/dist/schema/index.d.ts +5 -5
  105. package/dist/schema/index.js +70 -70
  106. package/dist/{schema-extension-LNRF2YRD.js → schema-extension-DV5D7JCQ.js} +5 -5
  107. package/dist/{space-IJU24PBH.js → space-THD2MWHR.js} +6 -6
  108. package/dist/{space-membership-DEUMM7NV.js → space-membership-M3QFMONE.js} +3 -3
  109. package/dist/store/index.d.ts +16 -6
  110. package/dist/store/index.js +4 -4
  111. package/dist/{store-DEWnip2G.d.ts → store-B0fb6WdJ.d.ts} +1 -1
  112. package/dist/{system-ILHCZOVO.js → system-LFIMY3QQ.js} +3 -3
  113. package/dist/{tag-SKCHM3U5.js → tag-W7ZYPXHK.js} +3 -3
  114. package/dist/{task-7AOBP7WC.js → task-DHTPD66H.js} +5 -5
  115. package/dist/task-view-J2WRE62C.js +10 -0
  116. package/dist/transaction-ANNDXCJM.js +12 -0
  117. package/dist/transcription-DFTQ4FQ4.js +12 -0
  118. package/dist/{types-BB8-SLEa.d.ts → types-B5rrBwRI.d.ts} +17 -0
  119. package/dist/user-widget-5IRVORF3.js +8 -0
  120. package/dist/workspace-RC4V4IF3.js +8 -0
  121. package/package.json +7 -7
  122. package/dist/account-MWNCH4GJ.js +0 -12
  123. package/dist/budget-NN7P35XP.js +0 -12
  124. package/dist/canvas-6WYBNH53.js +0 -10
  125. package/dist/channel-AT3LQF4A.js +0 -12
  126. package/dist/chat-message-47LETTYF.js +0 -10
  127. package/dist/comment-NIMFL4XB.js +0 -10
  128. package/dist/dashboard-JMKTTRA7.js +0 -10
  129. package/dist/database-GIXSPZJW.js +0 -10
  130. package/dist/database-field-3EPAMZUR.js +0 -10
  131. package/dist/database-row-5MEIOJ52.js +0 -10
  132. package/dist/database-select-option-BBBJFLLH.js +0 -10
  133. package/dist/database-view-DM7YCTZT.js +0 -10
  134. package/dist/experiment-DOVOZ34Y.js +0 -10
  135. package/dist/external-reference-7BSFF6SA.js +0 -8
  136. package/dist/feed-2IXHHP6O.js +0 -12
  137. package/dist/feed-item-DPE6LN7I.js +0 -12
  138. package/dist/grant-WTQSNT5A.js +0 -8
  139. package/dist/import-batch-IXBJLQPJ.js +0 -12
  140. package/dist/map-RG5Y3CPC.js +0 -10
  141. package/dist/media-asset-QTCGLIZA.js +0 -8
  142. package/dist/metric-65SVOX5C.js +0 -10
  143. package/dist/milestone-XEO6ZGDG.js +0 -12
  144. package/dist/observation-2Y3QKUXM.js +0 -10
  145. package/dist/page-2V27JGKJ.js +0 -10
  146. package/dist/posting-GBOSZCMZ.js +0 -12
  147. package/dist/project-CQL5LN26.js +0 -10
  148. package/dist/reaction-T2DTJBBV.js +0 -10
  149. package/dist/saved-view-4R2DBCL3.js +0 -10
  150. package/dist/task-view-NUGKELJP.js +0 -10
  151. package/dist/transaction-ZDSEGDIR.js +0 -12
  152. package/dist/transcription-PSCLDAGX.js +0 -12
  153. package/dist/user-widget-RLY2N46A.js +0 -8
  154. package/dist/workspace-WDKSQMOK.js +0 -8
@@ -1,18 +1,18 @@
1
+ import {
2
+ SYSTEM_SCHEMA_BASE_IRIS,
3
+ isSystemNamespaceResource,
4
+ isSystemSchemaIri
5
+ } from "./chunk-XJBDESCX.js";
1
6
  import {
2
7
  applyNodeQueryDescriptor,
3
8
  getNodeQuerySearchTokens,
4
9
  withoutNodeQueryMaterializedView,
5
10
  withoutNodeQueryPagination
6
11
  } from "./chunk-S5RP5RKY.js";
7
- import {
8
- SYSTEM_SCHEMA_BASE_IRIS,
9
- isSystemNamespaceResource,
10
- isSystemSchemaIri
11
- } from "./chunk-BY5O6LNC.js";
12
12
  import {
13
13
  createNodeId,
14
14
  getBaseSchemaIRI
15
- } from "./chunk-EBNMV2VO.js";
15
+ } from "./chunk-RRXJNZX5.js";
16
16
 
17
17
  // src/store/query-ast.ts
18
18
  var QUERY_AST_VERSION = 1;
@@ -887,187 +887,23 @@ function evaluateQueryASTPlannerGate(value) {
887
887
  }
888
888
 
889
889
  // src/store/store.ts
890
- import { compareChangeApplicationOrder, lwwWins } from "@xnetjs/core";
891
-
892
- // src/store/transaction-executor.ts
893
- async function executeTransactionOperations(host, input) {
894
- const results = [];
895
- const changes = [];
896
- const events = [];
897
- for (let i = 0; i < input.operations.length; i++) {
898
- const op = input.operations[i];
899
- let change;
900
- let result = null;
901
- let previousNode = null;
902
- switch (op.type) {
903
- case "create": {
904
- const id = op.options.id ?? createNodeId();
905
- const payload = {
906
- nodeId: id,
907
- schemaId: op.options.schemaId,
908
- properties: op.options.properties
909
- };
910
- change = await host.createBatchedChange(
911
- "node-change",
912
- payload,
913
- input.lamport,
914
- input.now,
915
- input.batchId,
916
- i,
917
- input.batchSize,
918
- input.storage
919
- );
920
- await host.applyChange(change, input.storage);
921
- result = await input.storage.getNode(id);
922
- await host.persistEncryptedNodeSnapshot(result, input.storage);
923
- break;
924
- }
925
- case "update": {
926
- const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
927
- if (!existing) {
928
- throw new Error(`Node not found: ${op.nodeId}`);
929
- }
930
- previousNode = existing;
931
- const payload = {
932
- nodeId: op.nodeId,
933
- properties: op.options.properties
934
- };
935
- change = await host.createBatchedChange(
936
- "node-change",
937
- payload,
938
- input.lamport,
939
- input.now,
940
- input.batchId,
941
- i,
942
- input.batchSize,
943
- input.storage
944
- );
945
- await host.applyChange(change, input.storage);
946
- result = await input.storage.getNode(op.nodeId);
947
- await host.persistEncryptedNodeSnapshot(result, input.storage);
948
- break;
949
- }
950
- case "delete": {
951
- const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
952
- if (!existing) {
953
- throw new Error(`Node not found: ${op.nodeId}`);
954
- }
955
- previousNode = existing;
956
- const payload = {
957
- nodeId: op.nodeId,
958
- properties: {},
959
- deleted: true
960
- };
961
- change = await host.createBatchedChange(
962
- "node-change",
963
- payload,
964
- input.lamport,
965
- input.now,
966
- input.batchId,
967
- i,
968
- input.batchSize,
969
- input.storage
970
- );
971
- await host.applyChange(change, input.storage);
972
- result = null;
973
- break;
974
- }
975
- case "restore": {
976
- const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
977
- if (!existing) {
978
- throw new Error(`Node not found: ${op.nodeId}`);
979
- }
980
- previousNode = existing;
981
- const payload = {
982
- nodeId: op.nodeId,
983
- properties: {},
984
- deleted: false
985
- };
986
- change = await host.createBatchedChange(
987
- "node-change",
988
- payload,
989
- input.lamport,
990
- input.now,
991
- input.batchId,
992
- i,
993
- input.batchSize,
994
- input.storage
995
- );
996
- await host.applyChange(change, input.storage);
997
- result = await input.storage.getNode(op.nodeId);
998
- await host.persistEncryptedNodeSnapshot(result, input.storage);
999
- break;
1000
- }
1001
- }
1002
- changes.push(change);
1003
- results.push(result);
1004
- events.push({ change, result, previousNode });
1005
- }
1006
- return { results, changes, events };
1007
- }
1008
- async function executeTransactionOperationsFast(host, input) {
1009
- const planned = input.operations.map((op) => ({
1010
- op,
1011
- id: op.type === "create" ? op.options.id ?? createNodeId() : op.nodeId
1012
- }));
1013
- const preflight = await host.getBatchPreflight(
1014
- planned.map((entry) => entry.id),
1015
- host.storage
1016
- );
1017
- const nodesById = host.cloneNodeMap(preflight.nodesById);
1018
- const lastChanges = new Map(preflight.lastChangesByNodeId);
1019
- const results = [];
1020
- const changes = [];
1021
- const events = [];
1022
- const affectedSchemaIds = /* @__PURE__ */ new Set();
1023
- for (let i = 0; i < planned.length; i++) {
1024
- const { op, id } = planned[i];
1025
- const existing = nodesById.get(id) ?? null;
1026
- if (op.type !== "create" && !existing) {
1027
- throw new Error(`Node not found: ${id}`);
1028
- }
1029
- const payload = op.type === "create" ? { nodeId: id, schemaId: op.options.schemaId, properties: op.options.properties } : op.type === "update" ? { nodeId: id, properties: op.options.properties } : { nodeId: id, properties: {}, deleted: op.type === "delete" };
1030
- const change = await host.createBatchedChangeWithParentHash(
1031
- "node-change",
1032
- payload,
1033
- lastChanges.get(id)?.hash ?? null,
1034
- input.lamport,
1035
- input.now,
1036
- input.batchId,
1037
- i,
1038
- input.batchSize
1039
- );
1040
- const schemaId = existing?.schemaId ?? (op.type === "create" ? op.options.schemaId : null);
1041
- if (!schemaId) {
1042
- throw new Error(`First change for node ${id} must include schemaId`);
1043
- }
1044
- const node = host.materializeNodeChange(
1045
- change,
1046
- existing ?? host.createInitialNodeFromChange(change, schemaId)
1047
- );
1048
- nodesById.set(id, node);
1049
- lastChanges.set(id, change);
1050
- affectedSchemaIds.add(schemaId);
1051
- changes.push(change);
1052
- const result = op.type === "delete" ? null : node;
1053
- results.push(result);
1054
- events.push({ change, result, previousNode: existing });
1055
- }
1056
- const touchedIds = Array.from(new Set(planned.map((entry) => entry.id)));
1057
- await host.storage.applyNodeBatch({
1058
- batchId: input.batchId,
1059
- nodes: touchedIds.flatMap((id) => {
1060
- const node = nodesById.get(id);
1061
- return node ? [node] : [];
1062
- }),
1063
- changes,
1064
- lastLamportTime: host.clockTime(),
1065
- affectedSchemaIds: Array.from(affectedSchemaIds),
1066
- indexMode: "touched",
1067
- indexProperties: true
1068
- });
1069
- return { results, changes, events };
1070
- }
890
+ import {
891
+ LWW_TIEBREAK_KEY_VERSION,
892
+ compareChangeApplicationOrder,
893
+ computeLwwTiebreakKey,
894
+ lwwWins
895
+ } from "@xnetjs/core";
896
+ import { base64ToBytes, bytesToBase64 } from "@xnetjs/crypto";
897
+ import { parseDID } from "@xnetjs/identity";
898
+ import {
899
+ createLamportClock,
900
+ tick,
901
+ receive,
902
+ signChange,
903
+ createUnsignedChange,
904
+ createBatchId
905
+ } from "@xnetjs/sync";
906
+ import { verifyChange, verifyChangeHash } from "@xnetjs/sync";
1071
907
 
1072
908
  // src/store/batch-write-orchestrator.ts
1073
909
  var elapsedMs = (startedAt) => Math.max(0, Date.now() - startedAt);
@@ -1159,21 +995,10 @@ async function executeDeterministicNodeImport(host, input) {
1159
995
  };
1160
996
  }
1161
997
 
1162
- // src/store/store.ts
1163
- import { base64ToBytes, bytesToBase64 } from "@xnetjs/crypto";
1164
- import { parseDID } from "@xnetjs/identity";
1165
- import {
1166
- createLamportClock,
1167
- tick,
1168
- receive,
1169
- signChange,
1170
- createUnsignedChange,
1171
- createBatchId
1172
- } from "@xnetjs/sync";
1173
- import { verifyChange, verifyChangeHash } from "@xnetjs/sync";
1174
-
1175
998
  // src/store/permission-error.ts
1176
- var PermissionError = class extends Error {
999
+ import { TaggedError } from "@xnetjs/core";
1000
+ var PermissionError = class extends TaggedError {
1001
+ _tag = "PermissionError";
1177
1002
  code = "PERMISSION_DENIED";
1178
1003
  action;
1179
1004
  nodeId;
@@ -1186,7 +1011,6 @@ var PermissionError = class extends Error {
1186
1011
  super(
1187
1012
  `Permission denied: ${roleInfo} but action '${decision.action}' is not permitted. Reasons: ${decision.reasons.join(", ")}`
1188
1013
  );
1189
- this.name = "PermissionError";
1190
1014
  this.action = decision.action;
1191
1015
  this.nodeId = decision.resource;
1192
1016
  this.subject = decision.subject;
@@ -1363,6 +1187,186 @@ function findSchemaIdForNode(operations, nodeId, tempIds) {
1363
1187
  return void 0;
1364
1188
  }
1365
1189
 
1190
+ // src/store/transaction-executor.ts
1191
+ async function executeTransactionOperations(host, input) {
1192
+ const results = [];
1193
+ const changes = [];
1194
+ const events = [];
1195
+ for (let i = 0; i < input.operations.length; i++) {
1196
+ const op = input.operations[i];
1197
+ let change;
1198
+ let result = null;
1199
+ let previousNode = null;
1200
+ switch (op.type) {
1201
+ case "create": {
1202
+ const id = op.options.id ?? createNodeId();
1203
+ const payload = {
1204
+ nodeId: id,
1205
+ schemaId: op.options.schemaId,
1206
+ properties: op.options.properties
1207
+ };
1208
+ change = await host.createBatchedChange(
1209
+ "node-change",
1210
+ payload,
1211
+ input.lamport,
1212
+ input.now,
1213
+ input.batchId,
1214
+ i,
1215
+ input.batchSize,
1216
+ input.storage
1217
+ );
1218
+ await host.applyChange(change, input.storage);
1219
+ result = await input.storage.getNode(id);
1220
+ await host.persistEncryptedNodeSnapshot(result, input.storage);
1221
+ break;
1222
+ }
1223
+ case "update": {
1224
+ const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
1225
+ if (!existing) {
1226
+ throw new Error(`Node not found: ${op.nodeId}`);
1227
+ }
1228
+ previousNode = existing;
1229
+ const payload = {
1230
+ nodeId: op.nodeId,
1231
+ properties: op.options.properties
1232
+ };
1233
+ change = await host.createBatchedChange(
1234
+ "node-change",
1235
+ payload,
1236
+ input.lamport,
1237
+ input.now,
1238
+ input.batchId,
1239
+ i,
1240
+ input.batchSize,
1241
+ input.storage
1242
+ );
1243
+ await host.applyChange(change, input.storage);
1244
+ result = await input.storage.getNode(op.nodeId);
1245
+ await host.persistEncryptedNodeSnapshot(result, input.storage);
1246
+ break;
1247
+ }
1248
+ case "delete": {
1249
+ const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
1250
+ if (!existing) {
1251
+ throw new Error(`Node not found: ${op.nodeId}`);
1252
+ }
1253
+ previousNode = existing;
1254
+ const payload = {
1255
+ nodeId: op.nodeId,
1256
+ properties: {},
1257
+ deleted: true
1258
+ };
1259
+ change = await host.createBatchedChange(
1260
+ "node-change",
1261
+ payload,
1262
+ input.lamport,
1263
+ input.now,
1264
+ input.batchId,
1265
+ i,
1266
+ input.batchSize,
1267
+ input.storage
1268
+ );
1269
+ await host.applyChange(change, input.storage);
1270
+ result = null;
1271
+ break;
1272
+ }
1273
+ case "restore": {
1274
+ const existing = host.cloneNodeState(await input.storage.getNode(op.nodeId));
1275
+ if (!existing) {
1276
+ throw new Error(`Node not found: ${op.nodeId}`);
1277
+ }
1278
+ previousNode = existing;
1279
+ const payload = {
1280
+ nodeId: op.nodeId,
1281
+ properties: {},
1282
+ deleted: false
1283
+ };
1284
+ change = await host.createBatchedChange(
1285
+ "node-change",
1286
+ payload,
1287
+ input.lamport,
1288
+ input.now,
1289
+ input.batchId,
1290
+ i,
1291
+ input.batchSize,
1292
+ input.storage
1293
+ );
1294
+ await host.applyChange(change, input.storage);
1295
+ result = await input.storage.getNode(op.nodeId);
1296
+ await host.persistEncryptedNodeSnapshot(result, input.storage);
1297
+ break;
1298
+ }
1299
+ }
1300
+ changes.push(change);
1301
+ results.push(result);
1302
+ events.push({ change, result, previousNode });
1303
+ }
1304
+ return { results, changes, events };
1305
+ }
1306
+ async function executeTransactionOperationsFast(host, input) {
1307
+ const planned = input.operations.map((op) => ({
1308
+ op,
1309
+ id: op.type === "create" ? op.options.id ?? createNodeId() : op.nodeId
1310
+ }));
1311
+ const preflight = await host.getBatchPreflight(
1312
+ planned.map((entry) => entry.id),
1313
+ host.storage
1314
+ );
1315
+ const nodesById = host.cloneNodeMap(preflight.nodesById);
1316
+ const lastChanges = new Map(preflight.lastChangesByNodeId);
1317
+ const results = [];
1318
+ const changes = [];
1319
+ const events = [];
1320
+ const affectedSchemaIds = /* @__PURE__ */ new Set();
1321
+ for (let i = 0; i < planned.length; i++) {
1322
+ const { op, id } = planned[i];
1323
+ const existing = nodesById.get(id) ?? null;
1324
+ if (op.type !== "create" && !existing) {
1325
+ throw new Error(`Node not found: ${id}`);
1326
+ }
1327
+ const payload = op.type === "create" ? { nodeId: id, schemaId: op.options.schemaId, properties: op.options.properties } : op.type === "update" ? { nodeId: id, properties: op.options.properties } : { nodeId: id, properties: {}, deleted: op.type === "delete" };
1328
+ const change = await host.createBatchedChangeWithParentHash(
1329
+ "node-change",
1330
+ payload,
1331
+ lastChanges.get(id)?.hash ?? null,
1332
+ input.lamport,
1333
+ input.now,
1334
+ input.batchId,
1335
+ i,
1336
+ input.batchSize
1337
+ );
1338
+ const schemaId = existing?.schemaId ?? (op.type === "create" ? op.options.schemaId : null);
1339
+ if (!schemaId) {
1340
+ throw new Error(`First change for node ${id} must include schemaId`);
1341
+ }
1342
+ const node = host.materializeNodeChange(
1343
+ change,
1344
+ existing ?? host.createInitialNodeFromChange(change, schemaId)
1345
+ );
1346
+ nodesById.set(id, node);
1347
+ lastChanges.set(id, change);
1348
+ affectedSchemaIds.add(schemaId);
1349
+ changes.push(change);
1350
+ const result = op.type === "delete" ? null : node;
1351
+ results.push(result);
1352
+ events.push({ change, result, previousNode: existing });
1353
+ }
1354
+ const touchedIds = Array.from(new Set(planned.map((entry) => entry.id)));
1355
+ await host.storage.applyNodeBatch({
1356
+ batchId: input.batchId,
1357
+ nodes: touchedIds.flatMap((id) => {
1358
+ const node = nodesById.get(id);
1359
+ return node ? [node] : [];
1360
+ }),
1361
+ changes,
1362
+ lastLamportTime: host.clockTime(),
1363
+ affectedSchemaIds: Array.from(affectedSchemaIds),
1364
+ indexMode: "touched",
1365
+ indexProperties: true
1366
+ });
1367
+ return { results, changes, events };
1368
+ }
1369
+
1366
1370
  // src/store/store.ts
1367
1371
  var MAX_CONFLICTS = 200;
1368
1372
  var ENCRYPTED_NODE_MARKER = "xnet:node-encrypted:v1";
@@ -1462,7 +1466,7 @@ var NodeStore = class {
1462
1466
  schemaId: options.schemaId,
1463
1467
  properties: options.properties
1464
1468
  },
1465
- authAction: "write",
1469
+ authAction: "create",
1466
1470
  requireExisting: false,
1467
1471
  createSchemaId: options.schemaId
1468
1472
  });
@@ -1476,7 +1480,7 @@ var NodeStore = class {
1476
1480
  }
1477
1481
  await this.assertAuthorized({
1478
1482
  subject: this.authorDID,
1479
- action: "write",
1483
+ action: "create",
1480
1484
  nodeId: id,
1481
1485
  patch: options.properties,
1482
1486
  node: {
@@ -1610,7 +1614,7 @@ var NodeStore = class {
1610
1614
  nodeId: id,
1611
1615
  properties: options.properties
1612
1616
  },
1613
- authAction: "write",
1617
+ authAction: "update",
1614
1618
  requireExisting: true
1615
1619
  });
1616
1620
  this.emit(change2, node2, previousNode, false);
@@ -1634,7 +1638,7 @@ var NodeStore = class {
1634
1638
  }
1635
1639
  await this.assertAuthorized({
1636
1640
  subject: this.authorDID,
1637
- action: "write",
1641
+ action: "update",
1638
1642
  nodeId: id,
1639
1643
  patch: options.properties,
1640
1644
  node: {
@@ -1757,7 +1761,7 @@ var NodeStore = class {
1757
1761
  properties: {},
1758
1762
  deleted: false
1759
1763
  },
1760
- authAction: "write",
1764
+ authAction: "update",
1761
1765
  requireExisting: true
1762
1766
  });
1763
1767
  this.emit(change2, node2, previousNode, false);
@@ -1770,7 +1774,7 @@ var NodeStore = class {
1770
1774
  }
1771
1775
  await this.assertAuthorized({
1772
1776
  subject: this.authorDID,
1773
- action: "write",
1777
+ action: "update",
1774
1778
  nodeId: id,
1775
1779
  node: {
1776
1780
  schemaId: existing.schemaId,
@@ -2471,12 +2475,21 @@ var NodeStore = class {
2471
2475
  );
2472
2476
  }
2473
2477
  if (this.authEvaluator) {
2474
- const action = this.inferActionFromChange(change);
2478
+ const stored = await this.storage.getNode(change.payload.nodeId);
2479
+ const action = this.inferActionFromChange(change, stored);
2475
2480
  const decision = await this.authEvaluator.can({
2476
2481
  subject: change.authorDID,
2477
2482
  action,
2478
2483
  nodeId: change.payload.nodeId,
2479
- patch: action === "write" ? change.payload.properties : void 0
2484
+ patch: action === "create" || action === "update" ? change.payload.properties : void 0,
2485
+ // A remote create has no stored node to evaluate against — build the
2486
+ // draft from the payload so container-relation roles resolve
2487
+ // (exploration 0304). Update/delete load the stored node as before.
2488
+ node: action === "create" && change.payload.schemaId ? {
2489
+ schemaId: change.payload.schemaId,
2490
+ createdBy: change.authorDID,
2491
+ properties: change.payload.properties
2492
+ } : void 0
2480
2493
  });
2481
2494
  if (!decision.allowed) {
2482
2495
  this.telemetry?.reportSecurityEvent("data.unauthorized_remote_change", "medium");
@@ -2921,7 +2934,11 @@ var NodeStore = class {
2921
2934
  const newTs = {
2922
2935
  lamport: change.lamport,
2923
2936
  author: change.authorDID,
2924
- wallTime: change.wallTime
2937
+ wallTime: change.wallTime,
2938
+ // Grinding-resistant final tiebreak (exploration 0305): only v4+ changes
2939
+ // carry a key, so a v4-vs-legacy comparison degrades to the author DID
2940
+ // and mixed fleets still agree.
2941
+ ...(change.protocolVersion ?? 0) >= LWW_TIEBREAK_KEY_VERSION ? { tiebreakKey: computeLwwTiebreakKey(change.authorDID, key, value) } : {}
2925
2942
  };
2926
2943
  const incomingWins = !existingTs || this.shouldReplace(existingTs, newTs);
2927
2944
  const target = isUnknownProperty ? node._unknown ??= {} : node.properties;
@@ -3056,7 +3073,7 @@ var NodeStore = class {
3056
3073
  if (operation.type === "create") {
3057
3074
  await this.assertAuthorized({
3058
3075
  subject: this.authorDID,
3059
- action: "write",
3076
+ action: "create",
3060
3077
  nodeId: operation.options.id ?? "",
3061
3078
  node: {
3062
3079
  schemaId: operation.options.schemaId,
@@ -3076,17 +3093,20 @@ var NodeStore = class {
3076
3093
  }
3077
3094
  await this.assertAuthorized({
3078
3095
  subject: this.authorDID,
3079
- action: "write",
3096
+ action: "update",
3080
3097
  nodeId: operation.nodeId,
3081
3098
  patch: operation.type === "update" ? operation.options.properties : void 0
3082
3099
  });
3083
3100
  }
3084
3101
  }
3085
- inferActionFromChange(change) {
3102
+ inferActionFromChange(change, stored) {
3086
3103
  if (change.payload.deleted === true) {
3087
3104
  return "delete";
3088
3105
  }
3089
- return "write";
3106
+ if (!stored && change.payload.schemaId) {
3107
+ return "create";
3108
+ }
3109
+ return "update";
3090
3110
  }
3091
3111
  shouldRecomputeRecipients(schemaId, patch) {
3092
3112
  const authRelevant = this.authRelevantPropertyLookup?.(schemaId);
@@ -3459,7 +3479,7 @@ var MemoryNodeStorageAdapter = class {
3459
3479
  };
3460
3480
 
3461
3481
  // src/store/sqlite-adapter.ts
3462
- import { lwwUpdateGuardSql } from "@xnetjs/core";
3482
+ import { lwwUpdateGuardSql, singleFlight } from "@xnetjs/core";
3463
3483
  import {
3464
3484
  extractSearchableContent as extractSearchableContent2,
3465
3485
  analyzeQuery,
@@ -3519,7 +3539,10 @@ function hydrateJoinedRows(rows) {
3519
3539
  node.timestamps[row.property_key] = {
3520
3540
  lamport: row.lamport_time ?? 0,
3521
3541
  author: row.updated_by ?? "",
3522
- wallTime: row.prop_updated_at ?? 0
3542
+ wallTime: row.prop_updated_at ?? 0,
3543
+ // Round-trip the stored key so the in-memory LWW comparison matches the
3544
+ // SQL guard exactly (0305); NULL legacy rows keep the author tiebreak.
3545
+ ...row.tiebreak_key != null ? { tiebreakKey: row.tiebreak_key } : {}
3523
3546
  };
3524
3547
  if ((row.prop_updated_at ?? 0) >= node.updatedAt) {
3525
3548
  node.updatedBy = row.updated_by ?? node.createdBy;
@@ -3539,7 +3562,10 @@ function hydrateAggregatedRows(rows) {
3539
3562
  timestamps[key] = {
3540
3563
  lamport: entry.l ?? 0,
3541
3564
  author: entry.b ?? "",
3542
- wallTime: entry.w ?? 0
3565
+ wallTime: entry.w ?? 0,
3566
+ // Round-trip the stored tiebreak key (0305) so aggregated hydrate
3567
+ // matches the SQL guard; NULL/absent → author tiebreak.
3568
+ ...entry.k != null ? { tiebreakKey: entry.k } : {}
3543
3569
  };
3544
3570
  if ((entry.w ?? 0) >= row.updated_at) {
3545
3571
  node.updatedBy = entry.b ?? row.created_by;
@@ -3570,6 +3596,7 @@ function buildHydrateChunkQuery(ids) {
3570
3596
  p.lamport_time,
3571
3597
  p.updated_by,
3572
3598
  p.updated_at AS prop_updated_at,
3599
+ p.tiebreak_key,
3573
3600
  wanted.ordinal
3574
3601
  FROM wanted
3575
3602
  JOIN nodes n ON n.id = wanted.id
@@ -3598,7 +3625,7 @@ function buildAggregatedHydrateChunkQuery(ids) {
3598
3625
  FILTER (WHERE p.property_key IS NOT NULL) AS props_json,
3599
3626
  json_group_object(
3600
3627
  p.property_key,
3601
- json_object('l', p.lamport_time, 'b', p.updated_by, 'w', p.updated_at)
3628
+ json_object('l', p.lamport_time, 'b', p.updated_by, 'w', p.updated_at, 'k', p.tiebreak_key)
3602
3629
  ) FILTER (WHERE p.property_key IS NOT NULL) AS meta_json
3603
3630
  FROM wanted
3604
3631
  JOIN nodes n ON n.id = wanted.id
@@ -4521,7 +4548,12 @@ var NODE_PROPERTIES_LWW_GUARD = lwwUpdateGuardSql({
4521
4548
  table: "node_properties",
4522
4549
  lamportColumn: "lamport_time",
4523
4550
  wallTimeColumn: "updated_at",
4524
- authorColumn: "updated_by"
4551
+ authorColumn: "updated_by",
4552
+ // Grinding-resistant final tiebreak (exploration 0305): larger key wins when
4553
+ // both rows carry one (v4+), else the author DID. The key is precomputed in
4554
+ // application code and stored, so SQL only compares the opaque hex — byte
4555
+ // identical to `shouldReplace` in ./store.ts, no user-defined function.
4556
+ tiebreakKeyColumn: "tiebreak_key"
4525
4557
  });
4526
4558
  var DEFAULT_ADAPTIVE_INDEXING = {
4527
4559
  enabled: false,
@@ -4621,6 +4653,7 @@ var SQLiteNodeStorageAdapter = class {
4621
4653
  nodeReadAuthorizer;
4622
4654
  /** One-time guard: ensure the `auth_fingerprint` column exists on upgraded DBs. */
4623
4655
  materializationColumnsReady = false;
4656
+ nodePropertyColumnsReady = false;
4624
4657
  /**
4625
4658
  * Descriptor→SQL compilation lives in `query-compiler.ts` (exploration
4626
4659
  * 0276). Flags are read per-compile so the compiler never captures stale
@@ -4965,6 +4998,7 @@ var SQLiteNodeStorageAdapter = class {
4965
4998
  * Used by importNodes to avoid nested transactions.
4966
4999
  */
4967
5000
  async _setNodeInternal(node, options) {
5001
+ await this.ensureNodePropertyColumns();
4968
5002
  await this.db.run(
4969
5003
  `INSERT INTO nodes (id, schema_id, created_at, updated_at, created_by, deleted_at)
4970
5004
  VALUES (?, ?, ?, ?, ?, ?)
@@ -4986,13 +5020,14 @@ var SQLiteNodeStorageAdapter = class {
4986
5020
  const timestamp = node.timestamps[key];
4987
5021
  if (!timestamp) continue;
4988
5022
  await this.db.run(
4989
- `INSERT INTO node_properties (node_id, property_key, value, lamport_time, updated_by, updated_at)
4990
- VALUES (?, ?, ?, ?, ?, ?)
5023
+ `INSERT INTO node_properties (node_id, property_key, value, lamport_time, updated_by, updated_at, tiebreak_key)
5024
+ VALUES (?, ?, ?, ?, ?, ?, ?)
4991
5025
  ON CONFLICT(node_id, property_key) DO UPDATE SET
4992
5026
  value = excluded.value,
4993
5027
  lamport_time = excluded.lamport_time,
4994
5028
  updated_by = excluded.updated_by,
4995
- updated_at = excluded.updated_at
5029
+ updated_at = excluded.updated_at,
5030
+ tiebreak_key = excluded.tiebreak_key
4996
5031
  WHERE ${NODE_PROPERTIES_LWW_GUARD}`,
4997
5032
  [
4998
5033
  node.id,
@@ -5000,7 +5035,8 @@ var SQLiteNodeStorageAdapter = class {
5000
5035
  this.serializeValue(value),
5001
5036
  timestamp.lamport,
5002
5037
  timestamp.author,
5003
- timestamp.wallTime
5038
+ timestamp.wallTime,
5039
+ timestamp.tiebreakKey ?? null
5004
5040
  ]
5005
5041
  );
5006
5042
  }
@@ -5062,7 +5098,7 @@ var SQLiteNodeStorageAdapter = class {
5062
5098
  )
5063
5099
  SELECT
5064
5100
  ln.id, ln.schema_id, ln.created_at, ln.updated_at, ln.created_by, ln.deleted_at,
5065
- p.property_key, p.value, p.lamport_time, p.updated_by, p.updated_at as prop_updated_at,
5101
+ p.property_key, p.value, p.lamport_time, p.updated_by, p.updated_at as prop_updated_at, p.tiebreak_key,
5066
5102
  NULL as ordinal
5067
5103
  FROM limited_nodes ln
5068
5104
  LEFT JOIN node_properties p ON ln.id = p.node_id
@@ -5074,7 +5110,7 @@ var SQLiteNodeStorageAdapter = class {
5074
5110
  sql = `
5075
5111
  SELECT
5076
5112
  n.id, n.schema_id, n.created_at, n.updated_at, n.created_by, n.deleted_at,
5077
- p.property_key, p.value, p.lamport_time, p.updated_by, p.updated_at as prop_updated_at,
5113
+ p.property_key, p.value, p.lamport_time, p.updated_by, p.updated_at as prop_updated_at, p.tiebreak_key,
5078
5114
  NULL as ordinal
5079
5115
  FROM nodes n
5080
5116
  LEFT JOIN node_properties p ON n.id = p.node_id
@@ -5587,6 +5623,7 @@ var SQLiteNodeStorageAdapter = class {
5587
5623
  if (!this.db.transactionBatch) {
5588
5624
  throw new Error("SQLite transactionBatch is not available.");
5589
5625
  }
5626
+ await this.ensureNodePropertyColumns();
5590
5627
  const operations = [];
5591
5628
  const indexProperties = options?.indexProperties ?? true;
5592
5629
  const hasFullTextSearch = await this.fullTextIndexing.hasTable();
@@ -5637,16 +5674,17 @@ var SQLiteNodeStorageAdapter = class {
5637
5674
  const timestamp = node.timestamps[key];
5638
5675
  if (!timestamp) continue;
5639
5676
  operations.push({
5640
- // Full LWW ordering triple — keep in lockstep with the setNode
5641
- // upsert above and `shouldReplace` in ./store.ts (0272).
5677
+ // Full LWW ordering chain — keep in lockstep with the setNode
5678
+ // upsert above and `shouldReplace` in ./store.ts (0272/0305).
5642
5679
  sql: `INSERT INTO node_properties
5643
- (node_id, property_key, value, lamport_time, updated_by, updated_at)
5644
- VALUES (?, ?, ?, ?, ?, ?)
5680
+ (node_id, property_key, value, lamport_time, updated_by, updated_at, tiebreak_key)
5681
+ VALUES (?, ?, ?, ?, ?, ?, ?)
5645
5682
  ON CONFLICT(node_id, property_key) DO UPDATE SET
5646
5683
  value = excluded.value,
5647
5684
  lamport_time = excluded.lamport_time,
5648
5685
  updated_by = excluded.updated_by,
5649
- updated_at = excluded.updated_at
5686
+ updated_at = excluded.updated_at,
5687
+ tiebreak_key = excluded.tiebreak_key
5650
5688
  WHERE ${NODE_PROPERTIES_LWW_GUARD}`,
5651
5689
  params: [
5652
5690
  node.id,
@@ -5654,7 +5692,8 @@ var SQLiteNodeStorageAdapter = class {
5654
5692
  this.serializeValue(value),
5655
5693
  timestamp.lamport,
5656
5694
  timestamp.author,
5657
- timestamp.wallTime
5695
+ timestamp.wallTime,
5696
+ timestamp.tiebreakKey ?? null
5658
5697
  ]
5659
5698
  });
5660
5699
  }
@@ -5906,6 +5945,24 @@ var SQLiteNodeStorageAdapter = class {
5906
5945
  }
5907
5946
  this.materializationColumnsReady = true;
5908
5947
  }
5948
+ /**
5949
+ * Ensure the `node_properties.tiebreak_key` column exists (exploration 0305).
5950
+ * Fresh databases get it from the DDL; databases created before schema v8 need
5951
+ * this in-place add so the grinding-resistant LWW guard has a column to
5952
+ * compare. Idempotent, memoized, and non-fatal on races — a legacy NULL key
5953
+ * just falls back to the author-DID tiebreak.
5954
+ */
5955
+ async ensureNodePropertyColumns() {
5956
+ if (this.nodePropertyColumnsReady) return;
5957
+ try {
5958
+ const columns = await this.db.query(`PRAGMA table_info(node_properties)`);
5959
+ if (!columns.some((column) => column.name === "tiebreak_key")) {
5960
+ await this.db.run("ALTER TABLE node_properties ADD COLUMN tiebreak_key TEXT");
5961
+ }
5962
+ } catch {
5963
+ }
5964
+ this.nodePropertyColumnsReady = true;
5965
+ }
5909
5966
  setNodeReadAuthorizer(authorizer) {
5910
5967
  this.nodeReadAuthorizer = authorizer;
5911
5968
  }
@@ -6185,24 +6242,23 @@ var SQLiteNodeStorageAdapter = class {
6185
6242
  */
6186
6243
  collectCompiledQueryDiagnostics(compiled) {
6187
6244
  const memoKey = compiled.sql;
6188
- const memoized = this.compiledQueryDiagnosticsMemo.get(memoKey);
6189
- if (memoized) {
6190
- return memoized;
6191
- }
6192
- const pending = this.computeCompiledQueryDiagnostics(compiled).then((diagnostics) => {
6193
- if (diagnostics.diagnosticsError) {
6194
- this.compiledQueryDiagnosticsMemo.delete(memoKey);
6195
- }
6196
- return diagnostics;
6197
- });
6198
- if (this.compiledQueryDiagnosticsMemo.size >= COMPILED_QUERY_DIAGNOSTICS_MEMO_LIMIT) {
6245
+ if (!this.compiledQueryDiagnosticsMemo.has(memoKey) && this.compiledQueryDiagnosticsMemo.size >= COMPILED_QUERY_DIAGNOSTICS_MEMO_LIMIT) {
6199
6246
  const oldest = this.compiledQueryDiagnosticsMemo.keys().next().value;
6200
6247
  if (oldest !== void 0) {
6201
6248
  this.compiledQueryDiagnosticsMemo.delete(oldest);
6202
6249
  }
6203
6250
  }
6204
- this.compiledQueryDiagnosticsMemo.set(memoKey, pending);
6205
- return pending;
6251
+ return singleFlight(
6252
+ this.compiledQueryDiagnosticsMemo,
6253
+ memoKey,
6254
+ () => this.computeCompiledQueryDiagnostics(compiled).then((diagnostics) => {
6255
+ if (diagnostics.diagnosticsError) {
6256
+ this.compiledQueryDiagnosticsMemo.delete(memoKey);
6257
+ }
6258
+ return diagnostics;
6259
+ }),
6260
+ { retain: "keep" }
6261
+ );
6206
6262
  }
6207
6263
  async computeCompiledQueryDiagnostics(compiled) {
6208
6264
  try {