@harperfast/harper 5.2.6 → 5.2.8

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 (304) hide show
  1. package/components/mcp/tools/application.ts +8 -4
  2. package/dist/components/mcp/tools/application.js +7 -4
  3. package/dist/components/mcp/tools/application.js.map +1 -1
  4. package/dist/resources/PrimaryRocksDatabase.js +2 -3
  5. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  6. package/dist/resources/RecordEncoder.d.ts +16 -0
  7. package/dist/resources/RecordEncoder.js +93 -3
  8. package/dist/resources/RecordEncoder.js.map +1 -1
  9. package/dist/resources/RocksTransactionLogStore.js +11 -1
  10. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  11. package/dist/resources/Table.js +55 -1
  12. package/dist/resources/Table.js.map +1 -1
  13. package/dist/resources/auditStore.d.ts +1 -0
  14. package/dist/resources/auditStore.js +1 -0
  15. package/dist/resources/auditStore.js.map +1 -1
  16. package/dist/resources/graphql.js +1 -1
  17. package/dist/resources/graphql.js.map +1 -1
  18. package/dist/resources/tracked.js +5 -0
  19. package/dist/resources/tracked.js.map +1 -1
  20. package/dist/resources/transactionBroadcast.js +5 -5
  21. package/dist/resources/transactionBroadcast.js.map +1 -1
  22. package/npm-shrinkwrap.json +47 -47
  23. package/package.json +4 -4
  24. package/resources/DESIGN.md +5 -0
  25. package/resources/PrimaryRocksDatabase.ts +3 -3
  26. package/resources/RecordEncoder.ts +85 -3
  27. package/resources/RocksTransactionLogStore.ts +11 -1
  28. package/resources/Table.ts +62 -2
  29. package/resources/auditStore.ts +3 -1
  30. package/resources/graphql.ts +1 -1
  31. package/resources/tracked.ts +4 -0
  32. package/resources/transactionBroadcast.ts +5 -5
  33. package/studio/web/assets/{Chat-BNHY84-Z.js → Chat-DDlysEi_.js} +71 -95
  34. package/studio/web/assets/FloatingChat-DdJ3DZJX.js +23 -0
  35. package/studio/web/assets/abnfDiagram-VCTEODGH-C0_BAZyO.js +1 -0
  36. package/studio/web/assets/{alertDialog-BaBrZQ4M.js → alertDialog-DIHt7Z0r.js} +1 -1
  37. package/studio/web/assets/apiToken-CrPb_98N.js +1 -0
  38. package/studio/web/assets/applications-C6Y4nL_X.js +296 -0
  39. package/studio/web/assets/arc-CVRByUzA.js +1 -0
  40. package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +1 -0
  41. package/studio/web/assets/architectureDiagram-5GKGNRK7-BWzrASgm.js +36 -0
  42. package/studio/web/assets/authStore-qKmCZcaf.js +3 -0
  43. package/studio/web/assets/blockDiagram-NRAW4CY4-BdJX9Khj.js +129 -0
  44. package/studio/web/assets/{button-DfBmT4rc.js → button-DhiX-njv.js} +1 -1
  45. package/studio/web/assets/c4Diagram-UCG6FXSJ-CI6MzGmQ.js +38 -0
  46. package/studio/web/assets/channel-DtCV8PTL.js +1 -0
  47. package/studio/web/assets/chevron-up-Df2c8uoU.js +1 -0
  48. package/studio/web/assets/chunk-75Z2AOVW-BT8tVmks.js +2 -0
  49. package/studio/web/assets/chunk-DU6HZSFF-9kAOOmI6.js +127 -0
  50. package/studio/web/assets/{chunk-2GRJ4B5K-DtwG__pv.js → chunk-F27PBJKO-BW7ao8AY.js} +1 -1
  51. package/studio/web/assets/{chunk-KEIR6QF5-BICK3FdT.js → chunk-FOHPRMQF-DHwB1DNv.js} +2 -2
  52. package/studio/web/assets/{chunk-5RXB4S5H-D3c7okHC.js → chunk-G27WJ6UU-COyLMcgK.js} +2 -2
  53. package/studio/web/assets/chunk-GMAD6QVW-BNyXpoQO.js +72 -0
  54. package/studio/web/assets/chunk-JQ64N6SF-Cyz1IeLf.js +1 -0
  55. package/studio/web/assets/{chunk-GF5L2VYU-DreJ7Snz.js → chunk-LCL6LL3I-HOzK_ppE.js} +3 -3
  56. package/studio/web/assets/chunk-OBVCFTLP-D4wWOqDQ.js +1 -0
  57. package/studio/web/assets/chunk-P2QGCYS3-DmIFY4d7.js +1 -0
  58. package/studio/web/assets/{chunk-KBJHAD2P-CLDPbAA-.js → chunk-POPQ4Y6H-BPrvMyKz.js} +1 -1
  59. package/studio/web/assets/{chunk-4I5QYGJK-D1FhvtQq.js → chunk-PWAF6VOD-2zB6IW9i.js} +1 -1
  60. package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +10 -0
  61. package/studio/web/assets/chunk-RHFEMEQ7-2FgyI8YU.js +168 -0
  62. package/studio/web/assets/{chunk-6Q2QTUOP-QviMM6bR.js → chunk-SVP7TREG-FwtbH2QC.js} +1 -1
  63. package/studio/web/assets/chunk-TEH6E4GO-P87k5mNi.js +62 -0
  64. package/studio/web/assets/{chunk-XXDRQBXY-CaP_jixK.js → chunk-XXDRQBXY-BoGZu3HH.js} +1 -1
  65. package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +1 -0
  66. package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +1 -0
  67. package/studio/web/assets/{cose-bilkent-JH36ORCC-BVTNhTKD.js → cose-bilkent-JH36ORCC-Cuuf67Bh.js} +1 -1
  68. package/studio/web/assets/{createLucideIcon-BMkDbMrz.js → createLucideIcon-BKGPfjm2.js} +1 -1
  69. package/studio/web/assets/cssMode-D8ceA4av.js +1 -0
  70. package/studio/web/assets/cynefin-OW5HDTMX-BRkpLFQV.js +1 -0
  71. package/studio/web/assets/cynefinDiagram-5FMLGOSQ-CHT1DaX6.js +62 -0
  72. package/studio/web/assets/cytoscape.esm-C2x7inlt.js +321 -0
  73. package/studio/web/assets/dagre-3AP2YEHR-DpUXBh63.js +4 -0
  74. package/studio/web/assets/dagre-PrKaheQc.js +1 -0
  75. package/studio/web/assets/diagram-S7CK7UJ4-BuymVFZT.js +30 -0
  76. package/studio/web/assets/diagram-UQ7AKVKN-CyP148RM.js +41 -0
  77. package/studio/web/assets/diagram-VSXAHHWV-CoCAg3M9.js +3 -0
  78. package/studio/web/assets/diagram-VX7I27RA-BpOqCFca.js +24 -0
  79. package/studio/web/assets/diagram-Z3DM3KII-Bfpw7Vbj.js +24 -0
  80. package/studio/web/assets/dialog-CBf0Mr1d.js +1 -0
  81. package/studio/web/assets/{dist-CeoU7cfW.js → dist-kYfyPZP9.js} +1 -1
  82. package/studio/web/assets/{dist-cY0BPcz0.js → dist-lkA3O3eM.js} +1 -1
  83. package/studio/web/assets/download-BtTOBem-.js +1 -0
  84. package/studio/web/assets/ebnfDiagram-PWID7BFC-DS_6aWqL.js +1 -0
  85. package/studio/web/assets/editor-C-jlLd1G.js +1 -0
  86. package/studio/web/assets/erDiagram-SSCWMZ5O-DJNk6Fgw.js +99 -0
  87. package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +1 -0
  88. package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +1 -0
  89. package/studio/web/assets/{ganttDiagram-PKOTCBZU-Cit41Zp3.js → ganttDiagram-EL5Y4UJY-2pOExxMY.js} +2 -2
  90. package/studio/web/assets/{getAnalytics-rTxZLIM5.js → getAnalytics-D4LKGeVy.js} +1 -1
  91. package/studio/web/assets/gitGraph-4MIJSDKK-CH5ZxwzF.js +1 -0
  92. package/studio/web/assets/gitGraphDiagram-WWUBYQGX-DVIsIhbO.js +106 -0
  93. package/studio/web/assets/html-BnuKFPjv.js +1 -0
  94. package/studio/web/assets/htmlMode-DXM6YYUw.js +1 -0
  95. package/studio/web/assets/index-BtTvoLf8.js +824 -0
  96. package/studio/web/assets/index-Cxj2_wsl.css +1 -0
  97. package/studio/web/assets/index.lazy-PVbC6xQh.js +2 -0
  98. package/studio/web/assets/info-A6RAGUB7-CPQfTnaG.js +1 -0
  99. package/studio/web/assets/infoDiagram-RXCK75RN-DlwLYlwm.js +2 -0
  100. package/studio/web/assets/{ishikawaDiagram-WSZJBQD7-BJYRB-hU.js → ishikawaDiagram-5VMMS53U-BRXRp29U.js} +2 -2
  101. package/studio/web/assets/{javascript-CGzSV8Sd.js → javascript-CAuAkYxc.js} +1 -1
  102. package/studio/web/assets/{journeyDiagram-NVQOT4AX-B8K4wuMz.js → journeyDiagram-EYS64GPL-B0ou8k0n.js} +1 -1
  103. package/studio/web/assets/jsonMode-Dny8hrU7.js +1 -0
  104. package/studio/web/assets/{kanban-definition-27J2QSJJ-DKFV1ovM.js → kanban-definition-3QL26DDD-uYg7iYzp.js} +11 -11
  105. package/studio/web/assets/languageServices-D1uNqC6s.js +1 -0
  106. package/studio/web/assets/linear-Cnt8506Q.js +1 -0
  107. package/studio/web/assets/lspLanguageFeatures-Bh-bvkyK.js +4 -0
  108. package/studio/web/assets/mermaid-parser.core-Ck-fC8b7.js +7 -0
  109. package/studio/web/assets/mermaid.core-CP8aNNYm.js +44 -0
  110. package/studio/web/assets/{mindmap-definition-FAOFIHXS-CKL4PdAv.js → mindmap-definition-FBJOCRG2-CgTZ-rit.js} +25 -25
  111. package/studio/web/assets/notifications-DPTOF-SX.js +1 -0
  112. package/studio/web/assets/notifications-DsE0S3zT.js +1 -0
  113. package/studio/web/assets/packet-AYTQ26CC-DEyoPtPb.js +1 -0
  114. package/studio/web/assets/pegDiagram-XKGWAZYB-DrD-7sD9.js +1 -0
  115. package/studio/web/assets/pie-WAS4IAKB-wjj-EI1d.js +1 -0
  116. package/studio/web/assets/pieDiagram-E7YTZNPT-GntqDCzv.js +39 -0
  117. package/studio/web/assets/profile-BIeCZr-w.js +1 -0
  118. package/studio/web/assets/{quadrantDiagram-CIZ2JOQS-CSbsuWtH.js → quadrantDiagram-AXDQQJYC-0UeqXQGd.js} +1 -1
  119. package/studio/web/assets/radar-RG4KPBEZ-DFSA5h7k.js +1 -0
  120. package/studio/web/assets/railroad-74A4TZTK-CaOUG9wR.js +1 -0
  121. package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +1 -0
  122. package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +1 -0
  123. package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +1 -0
  124. package/studio/web/assets/railroadDiagram-O6MQD6OU-yHUELZaV.js +1 -0
  125. package/studio/web/assets/regions-B5lGduv5.js +1 -0
  126. package/studio/web/assets/{editor.api-eUd8PqEu.js → register-Cvc1TpmQ.js} +139 -138
  127. package/studio/web/assets/{requirementDiagram-LRYGKXZP-ZIF0Wlho.js → requirementDiagram-EFPCY7ZU-DNEGFjuW.js} +2 -2
  128. package/studio/web/assets/rolldown-runtime-hePW80VL.js +1 -0
  129. package/studio/web/assets/safeParse-DeaoCCWH.js +1 -0
  130. package/studio/web/assets/{sankeyDiagram-W5VNT64P-BcRESt9x.js → sankeyDiagram-P5KCCOFB-DpyAmSVR.js} +1 -1
  131. package/studio/web/assets/{sequenceDiagram-SI44F4Z6-OpgTeJNU.js → sequenceDiagram-WJ2MYXX4-TyaT7xNk.js} +1 -1
  132. package/studio/web/assets/setComponentFile-D8ZLDWhU.js +1 -0
  133. package/studio/web/assets/setLocalStorage-D_kflv4U.js +1 -0
  134. package/studio/web/assets/setSessionStorage-B0bf71m4.js +1 -0
  135. package/studio/web/assets/setup-D2az-Ue_.js +2 -0
  136. package/studio/web/assets/src-CMc7m_Ut.js +1 -0
  137. package/studio/web/assets/stateDiagram-HBIQ2CUA-CeEdTArZ.js +1 -0
  138. package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +1 -0
  139. package/studio/web/assets/status-BJegPrWN.js +61 -0
  140. package/studio/web/assets/step-vX8bovaY.js +1 -0
  141. package/studio/web/assets/swimlanes-XN3QIQJK-B54FmF46.js +1 -0
  142. package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +8 -0
  143. package/studio/web/assets/tabs-B_G5zscN.js +1 -0
  144. package/studio/web/assets/{time-D55sDum-.js → time-Cclkb7kQ.js} +1 -1
  145. package/studio/web/assets/{timeline-definition-Z64GVDOM-Dy5A_tK2.js → timeline-definition-24CTP7MA-D-a9ujbo.js} +5 -5
  146. package/studio/web/assets/toggleHighContrast-BdIEw2rK.js +49 -0
  147. package/studio/web/assets/treeView-Q6P3EWNA-CrW_6JnS.js +1 -0
  148. package/studio/web/assets/treemap-WGGIJYW6-BxyYLdP_.js +1 -0
  149. package/studio/web/assets/tsMode-CulNMwI9.js +11 -0
  150. package/studio/web/assets/typescript-BpRqjmvQ.js +1 -0
  151. package/studio/web/assets/useEntityRestURL-C7x-Yz9r.js +1 -0
  152. package/studio/web/assets/useLocalStorage-Dtj1QS8_.js +1 -0
  153. package/studio/web/assets/{vendor-core-CddkYGh5.js → vendor-core-RCcadM3e.js} +1 -1
  154. package/studio/web/assets/vendor-datadog-BRv-mOv1.js +6 -0
  155. package/studio/web/assets/{vendor-react-BhazFIp8.js → vendor-react-Dyj4O3HE.js} +1 -1
  156. package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +1 -0
  157. package/studio/web/assets/{vendor-ui-BLIveqaL.js → vendor-ui-vhu-UHhF.js} +11 -11
  158. package/studio/web/assets/{vennDiagram-T6HMQDX7-DRvMIiSo.js → vennDiagram-4TSXK5OY-Cy7s7Mpy.js} +3 -3
  159. package/studio/web/assets/wardley-WFR3VGLG-BeBL35g2.js +1 -0
  160. package/studio/web/assets/{wardleyDiagram-T6FBY63Y-B04FSA0i.js → wardleyDiagram-VM6X3IG4-BylmIGSg.js} +3 -3
  161. package/studio/web/assets/workers-B2WpJDK9.js +3 -0
  162. package/studio/web/assets/x-B9o9hsep.js +1 -0
  163. package/studio/web/assets/xml-CZnimVSX.js +1 -0
  164. package/studio/web/assets/{xychartDiagram-ELKLHX3M-BE0X7RA7.js → xychartDiagram-S5SC5T6Z-CoKALMXr.js} +3 -3
  165. package/studio/web/assets/yaml-BwNuyZS-.js +1 -0
  166. package/studio/web/assets/{yaml.worker-Iyy2Pf1T.js → yaml.worker-BDL8_iuk.js} +153 -153
  167. package/studio/web/harper-studio_black.png +0 -0
  168. package/studio/web/index.html +18 -24
  169. package/studio/web/assets/FloatingChat-BbztUci0.js +0 -23
  170. package/studio/web/assets/abnfDiagram-N423BO3Z-BRuH0ywn.js +0 -1
  171. package/studio/web/assets/apiToken-D0x_S8Wq.js +0 -1
  172. package/studio/web/assets/applications-BU83fSEG.js +0 -296
  173. package/studio/web/assets/arc-3Xw6uabx.js +0 -1
  174. package/studio/web/assets/architecture-TIHT7OUA-CsHfPErM.js +0 -1
  175. package/studio/web/assets/architectureDiagram-T3A2C74G-DrwbS7Gp.js +0 -36
  176. package/studio/web/assets/array-BifhSqXX.js +0 -1
  177. package/studio/web/assets/authStore-B3IhXrn6.js +0 -3
  178. package/studio/web/assets/blockDiagram-VBNYF7ZC-DKN1mht5.js +0 -132
  179. package/studio/web/assets/c4Diagram-5PPSVZJV-CT9bmjm_.js +0 -10
  180. package/studio/web/assets/card-ByrPS_wa.js +0 -1
  181. package/studio/web/assets/channel-mnKBfsP-.js +0 -1
  182. package/studio/web/assets/chevron-right-CY-tr2sG.js +0 -1
  183. package/studio/web/assets/chunk-3NCLNEKW-BVj72ixc.js +0 -1
  184. package/studio/web/assets/chunk-5FCAYU7R-Dh5nylU8.js +0 -1
  185. package/studio/web/assets/chunk-5HE753X5-Bw-yg4kO.js +0 -1
  186. package/studio/web/assets/chunk-5JV3BV7I-Cy5pj3QY.js +0 -1
  187. package/studio/web/assets/chunk-5TONJI2A-DQOY3q1H.js +0 -2
  188. package/studio/web/assets/chunk-7BUUIJ7U-Bb538aSH.js +0 -1
  189. package/studio/web/assets/chunk-7Z6QIM7H-BJhESwQK.js +0 -10
  190. package/studio/web/assets/chunk-BIQX33UG-DZEsGuSn.js +0 -1
  191. package/studio/web/assets/chunk-CQNSW5MT-B8S09OIh.js +0 -1
  192. package/studio/web/assets/chunk-CYSBUYHQ-C1Rf4art.js +0 -1
  193. package/studio/web/assets/chunk-EMLP6XTP-RLD4nXpI.js +0 -1
  194. package/studio/web/assets/chunk-I66GZJ75-DHPYnKNr.js +0 -125
  195. package/studio/web/assets/chunk-J7OUQ5F2-DcY_kb6i.js +0 -2
  196. package/studio/web/assets/chunk-JG7HCLWE-BYfiSaVt.js +0 -2
  197. package/studio/web/assets/chunk-JQJVKLGR-DtEmbHZj.js +0 -156
  198. package/studio/web/assets/chunk-MOZMSUNE-XVucA-n6.js +0 -1
  199. package/studio/web/assets/chunk-NSK5VX7P-DDFNzCU_.js +0 -2
  200. package/studio/web/assets/chunk-OSBZ3O6U-CrKZOUOr.js +0 -1
  201. package/studio/web/assets/chunk-QBLGF6JB-CxAyS2mW.js +0 -1
  202. package/studio/web/assets/chunk-QR6OTTB3-Df7OCENk.js +0 -62
  203. package/studio/web/assets/chunk-R7FJI6CG-Cnn3gE-Y.js +0 -1
  204. package/studio/web/assets/chunk-RYQCIY6F-N0MDKk5G.js +0 -1
  205. package/studio/web/assets/chunk-U6XO7XAA-BFxjP5U3.js +0 -2
  206. package/studio/web/assets/chunk-UBXNYLIW-rn0yw1mp.js +0 -1
  207. package/studio/web/assets/chunk-W5SLKNZC-DKMlAWZk.js +0 -1
  208. package/studio/web/assets/chunk-WRU74C26-Dg10j8Pf.js +0 -70
  209. package/studio/web/assets/chunk-YOTPTUD7-D0vRKqYp.js +0 -1
  210. package/studio/web/assets/chunk-ZIRB5QZD-O39ZBUk3.js +0 -32
  211. package/studio/web/assets/classDiagram-JCYQIIEL-BrXNP4fl.js +0 -1
  212. package/studio/web/assets/classDiagram-v2-OCEON4UE-BrXNP4fl.js +0 -1
  213. package/studio/web/assets/cssMode-DipmMR_-.js +0 -1
  214. package/studio/web/assets/cynefin-VYW2F7L2-Ds2Fw2Y0.js +0 -1
  215. package/studio/web/assets/cynefinDiagram-MW4NZA55-DcTzrsC5.js +0 -62
  216. package/studio/web/assets/cytoscape.esm-B-NFISlW.js +0 -321
  217. package/studio/web/assets/dagre-Buvkdvvj.js +0 -1
  218. package/studio/web/assets/dagre-VZM6K2ZE-CMyJ9QPU.js +0 -4
  219. package/studio/web/assets/diagram-7IWD3JNH-jEGuzdp3.js +0 -30
  220. package/studio/web/assets/diagram-B4RE2ZJO-Ba7wC7iw.js +0 -3
  221. package/studio/web/assets/diagram-LBJQPF4R-Bm7Wj_dF.js +0 -24
  222. package/studio/web/assets/diagram-Q27KOJAE-C-gdktLC.js +0 -24
  223. package/studio/web/assets/diagram-UB23O5K3-COBVIEEk.js +0 -41
  224. package/studio/web/assets/ebnfDiagram-BXEA7PRR-G-t56mVV.js +0 -1
  225. package/studio/web/assets/editor-BDfNodZS.js +0 -1
  226. package/studio/web/assets/erDiagram-JOGREHBK-DpHzpqx1.js +0 -85
  227. package/studio/web/assets/eventmodeling-45OFAUF4-CLEiVx5s.js +0 -1
  228. package/studio/web/assets/flowDiagram-UKHOOZJN-CIxxUUxn.js +0 -1
  229. package/studio/web/assets/getRegistrationInfo--NLLrics.js +0 -1
  230. package/studio/web/assets/gitGraph-TEB2WS4Q-CZFBqwW-.js +0 -1
  231. package/studio/web/assets/gitGraphDiagram-DS77QQ5N-DuGnRv2R.js +0 -106
  232. package/studio/web/assets/html-DmSSmgE8.js +0 -1
  233. package/studio/web/assets/htmlMode-B2LqJw1z.js +0 -1
  234. package/studio/web/assets/index-BO3NaEw8.css +0 -1
  235. package/studio/web/assets/index-BQB9R8Ug.js +0 -810
  236. package/studio/web/assets/index-BnYZFLIB.css +0 -1
  237. package/studio/web/assets/index.lazy-CtErm5q7.js +0 -13
  238. package/studio/web/assets/info-DKCQHKI2--1InqQeT.js +0 -1
  239. package/studio/web/assets/infoDiagram-6WML65LV-DliK38kp.js +0 -2
  240. package/studio/web/assets/isArrayLikeObject-BHDnhloL.js +0 -1
  241. package/studio/web/assets/jsonMode-BVS6P5Xk.js +0 -1
  242. package/studio/web/assets/languageServices-Bl-BvoAb.js +0 -1
  243. package/studio/web/assets/line-Bom3IjHi.js +0 -1
  244. package/studio/web/assets/linear-DwB_ruUT.js +0 -1
  245. package/studio/web/assets/lspLanguageFeatures-C7XtZA_w.js +0 -4
  246. package/studio/web/assets/map-BaFkSB1l.js +0 -1
  247. package/studio/web/assets/math-Bi_r_ZWc.js +0 -1
  248. package/studio/web/assets/mermaid-parser.core-Dd4RYr9Q.js +0 -4
  249. package/studio/web/assets/mermaid.core-Bbo24DGo.js +0 -11
  250. package/studio/web/assets/notifications-B8rDagJM.js +0 -1
  251. package/studio/web/assets/notifications-CPwYKDDH.js +0 -1
  252. package/studio/web/assets/packet-7NZHBO7P-BGMXB0XL.js +0 -1
  253. package/studio/web/assets/path-fybaL0A-.js +0 -1
  254. package/studio/web/assets/pegDiagram-VL7TDLO6-CWEktcBB.js +0 -1
  255. package/studio/web/assets/pie-RZYD4A2V-DgYg3tCt.js +0 -1
  256. package/studio/web/assets/pieDiagram-7S7Q4E2Y-DEAmZOqY.js +0 -39
  257. package/studio/web/assets/pollUnlessForbidden-DIDXGBc5.js +0 -1
  258. package/studio/web/assets/profile-D0hB1xdm.js +0 -1
  259. package/studio/web/assets/purify.es-DrVcFY1Q.js +0 -3
  260. package/studio/web/assets/queryClient-BLhQvmWC.js +0 -1
  261. package/studio/web/assets/radar-I7S5WNFK-Ag-zp_Rq.js +0 -1
  262. package/studio/web/assets/railroad-3IZDKUUU-aibJDIDV.js +0 -1
  263. package/studio/web/assets/railroad-abnf-AHOZXSZD-BBMEuvIl.js +0 -1
  264. package/studio/web/assets/railroad-ebnf-EBAXGLYW-Be1nseej.js +0 -1
  265. package/studio/web/assets/railroad-peg-LSFZ7HO6-DIvD-Eyb.js +0 -1
  266. package/studio/web/assets/railroadDiagram-AXF67PYL-BJWrgR10.js +0 -1
  267. package/studio/web/assets/react-VeAY02s6.js +0 -1
  268. package/studio/web/assets/react-redux-Ds7wf7Ax.js +0 -5
  269. package/studio/web/assets/regions-y_jxsBpN.js +0 -1
  270. package/studio/web/assets/register-3F1Tje_F.js +0 -2
  271. package/studio/web/assets/register-S_PdXsoi.js +0 -2
  272. package/studio/web/assets/rolldown-runtime-B0Z9INg1.js +0 -1
  273. package/studio/web/assets/select-CKgJgpkn.js +0 -1
  274. package/studio/web/assets/setComponentFile-DSHbURTI.js +0 -1
  275. package/studio/web/assets/setLocalStorage-CD_L8p_D.js +0 -1
  276. package/studio/web/assets/setup-J5SrM1Kp.js +0 -2
  277. package/studio/web/assets/src-DUvBCJIr.js +0 -1
  278. package/studio/web/assets/stateDiagram-OKZ733FA-D9oPLTjO.js +0 -1
  279. package/studio/web/assets/stateDiagram-v2-UEYNNEHI-CSD1wbuZ.js +0 -1
  280. package/studio/web/assets/status-IoJkDzlx.js +0 -61
  281. package/studio/web/assets/string-f6JzSHaO.js +0 -1
  282. package/studio/web/assets/swagger-ui-react-BlgSS25O.js +0 -240
  283. package/studio/web/assets/swimlanes-SLNWSIFB-BpeoNE9k.js +0 -2
  284. package/studio/web/assets/swimlanesDiagram-ULZ7WXOC-DHxwzxpp.js +0 -8
  285. package/studio/web/assets/table-BvFflPWi.js +0 -1
  286. package/studio/web/assets/tabs-Dd_ElZ36.js +0 -1
  287. package/studio/web/assets/textarea-a3RnTY31.js +0 -9
  288. package/studio/web/assets/toggleHighContrast-CyNC3SCQ.js +0 -49
  289. package/studio/web/assets/tokenization-CWuvR2gh.js +0 -7
  290. package/studio/web/assets/treeView-QDETBFTQ-uHZ-3Fz8.js +0 -1
  291. package/studio/web/assets/treemap-6X3UGDF4-BnUKyy3l.js +0 -1
  292. package/studio/web/assets/tsMode-CslzhcVk.js +0 -11
  293. package/studio/web/assets/typescript-Dtnury3t.js +0 -1
  294. package/studio/web/assets/useAuth-DiJUZS1C.js +0 -1
  295. package/studio/web/assets/useEntityRestURL-qfahJnvr.js +0 -1
  296. package/studio/web/assets/useLocalStorage-DetQlhBe.js +0 -1
  297. package/studio/web/assets/vendor-datadog-XDrpA25D.js +0 -6
  298. package/studio/web/assets/vendor-tanstack-FsM5XZNE.js +0 -1
  299. package/studio/web/assets/wardley-OPB4EBWU-Da7TLC2F.js +0 -1
  300. package/studio/web/assets/workers-BtibQGyk.js +0 -3
  301. package/studio/web/assets/x-D39AGKMb.js +0 -1
  302. package/studio/web/assets/xml-D41zWqPl.js +0 -1
  303. package/studio/web/assets/yaml-BFQ3mF1U.js +0 -1
  304. /package/studio/web/assets/{editor-jjEx9u7D.css → register-jjEx9u7D.css} +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@harperfast/harper",
3
3
  "description": "Harper is an open-source Node.js performance platform that unifies database, cache, application, and messaging layers into one in-memory process.",
4
- "version": "5.2.6",
4
+ "version": "5.2.8",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://harper.fast",
7
7
  "bugs": {
@@ -179,7 +179,7 @@
179
179
  "@fastify/cors": "^11.2.0",
180
180
  "@fastify/static": "^9.1.3",
181
181
  "@harperfast/extended-iterable": "1.0.3",
182
- "@harperfast/rocksdb-js": "2.7.1",
182
+ "@harperfast/rocksdb-js": "2.8.0",
183
183
  "@harperfast/skills": "^1.10.8",
184
184
  "@turf/area": "6.5.0",
185
185
  "@turf/boolean-contains": "6.5.0",
@@ -223,7 +223,7 @@
223
223
  "minimist": "1.2.8",
224
224
  "moment": "2.30.1",
225
225
  "mqtt-packet": "~9.0.1",
226
- "msgpackr": "2.0.5",
226
+ "msgpackr": "2.0.6",
227
227
  "needle": "3.5.0",
228
228
  "node-forge": "^1.3.1",
229
229
  "node-stream-zip": "1.16.0",
@@ -244,7 +244,7 @@
244
244
  "ses": "^1.15.0",
245
245
  "stream-chain": "2.2.5",
246
246
  "stream-json": "1.9.1",
247
- "structon": "1.0.8",
247
+ "structon": "1.1.0",
248
248
  "systeminformation": "^5.31.4",
249
249
  "tar-fs": "^3.1.2",
250
250
  "tar-stream": "^3.1.8",
@@ -166,6 +166,11 @@ Tests: `../unitTests/resources/defineResource.test.js`, `../unitTests/resources/
166
166
 
167
167
  ## Conventions
168
168
 
169
+ - A record's `toJSON` is a response projection, not durable state. `recordUpdater` (and the cache-fill
170
+ and audit paths feeding it) projects records to stored fields via `storedFieldsOnly`, so no durable
171
+ form carries a resolver-owned (`@computed`/`@relationship`) name; materialization skips such names
172
+ when promoting a decoded record (`assignStoredFields`), which is what keeps rows written by affected
173
+ releases readable. See harper#2359 and `integrationTests/resources/cachedComputedAttribute.test.ts`.
169
174
  - **Never** remove `transactional()` from a static method on `Resource` — it owns transaction context lifetime.
170
175
  - New `Resource` subclasses should override **instance** methods (`get`, `put`, ...) for behavior; static methods are the protocol entry points and stay generic.
171
176
  - **Overriding a static entry point takes over its whole contract.** Assigning `static post`/`put`/`patch` on a subclass shadows the `transactional()`-wrapped static, so none of that wrapper runs — including the `when(data, ...)` that resolves `data` and the `allowCreate`/`allowUpdate` gate. That is by design (it is how `login.ts` implements a deliberately pre-authentication endpoint), and it means an override owns two obligations the wrapper would otherwise have met:
@@ -3,7 +3,7 @@ import { RocksDatabase, type RocksDatabaseOptions, constants, type Store } from
3
3
  const FRESH_VERSION_FLAG = constants.FRESH_VERSION_FLAG;
4
4
  import { WeakLRUCache } from 'weak-lru-cache';
5
5
  import { when } from '../utility/when.ts';
6
- import { entryMap, METADATA, type Entry } from './RecordEncoder.ts';
6
+ import { assignStoredFields, entryMap, METADATA, type Entry } from './RecordEncoder.ts';
7
7
 
8
8
  /**
9
9
  * RocksDatabase subclass that owns all primary-store behaviour for Harper tables:
@@ -60,7 +60,7 @@ export class PrimaryRocksDatabase extends RocksDatabase {
60
60
  if (entry.value.constructor === Object && this.#enc.structPrototype) {
61
61
  const originalValue = entry.value;
62
62
  entry.value = new this.#enc.structPrototype.constructor();
63
- Object.assign(entry.value, originalValue);
63
+ assignStoredFields(entry.value, originalValue, this.#enc);
64
64
  }
65
65
  if (typeof entry.value === 'object' && entry.value !== null) {
66
66
  entryMap.set(entry.value, entry);
@@ -164,7 +164,7 @@ export class PrimaryRocksDatabase extends RocksDatabase {
164
164
  if (entry.value?.constructor === Object && enc.structPrototype) {
165
165
  const originalValue = entry.value;
166
166
  entry.value = new enc.structPrototype.constructor();
167
- for (const key in originalValue) entry.value[key] = originalValue[key];
167
+ assignStoredFields(entry.value, originalValue, enc);
168
168
  }
169
169
  return entry;
170
170
  });
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { Encoder } from 'msgpackr';
9
- import { createStructon } from 'structon';
9
+ import { createStructon, SOURCE_SYMBOL } from 'structon';
10
10
  import {
11
11
  HAS_PREVIOUS_RESIDENCY_ID,
12
12
  HAS_CURRENT_RESIDENCY_ID,
@@ -123,12 +123,86 @@ let timestampNextEncoding = 0,
123
123
  additionalAuditRefsNextEncoding: Array<{ version: number; nodeId: number }> | undefined;
124
124
  // tracking metadata with a singleton works better than trying to alter response of getEntry/get and coordinating that across caching layers
125
125
  export let lastMetadata: Entry | null = null;
126
+ /**
127
+ * A resolver owns its attribute's name, so no durable form of a record may carry a value under it.
128
+ * A value gets there either through the response `toJSON` the table installs on the record prototype
129
+ * (msgpackr consults an instance's toJSON when it encodes one) or as an own key from a source or
130
+ * peer payload.
131
+ */
132
+ export function storedFieldsOnly(encoder: any, record: any) {
133
+ if (record === null || typeof record !== 'object') return record;
134
+ // Optional: this also runs for a store whose encode hook was grafted onto a foreign encoder
135
+ // (copyDb's migration target), which carries no table schema.
136
+ const resolved = encoder?.resolvedAttributeNames;
137
+ if (resolved === undefined) return record;
138
+ const resolvedList = encoder.resolvedAttributeNamesList ?? Array.from(resolved);
139
+ // A typed-struct instance keeps its stored fields as accessors on a structon-generated child
140
+ // prototype carrying structon's own toJSON, so it never reaches the response projection — and
141
+ // copying its own keys would encode an empty record.
142
+ let project =
143
+ encoder.surfacedToJSON !== undefined &&
144
+ record.toJSON === encoder.surfacedToJSON &&
145
+ record[SOURCE_SYMBOL] === undefined;
146
+ if (!project && typeof record.toJSON === 'function' && record[SOURCE_SYMBOL] === undefined) {
147
+ // A class instance with its own serialization: the encoder will consult that toJSON, so the
148
+ // projection has to run on its OUTPUT, or the serialized form smuggles resolver-owned keys past
149
+ // a check that only saw the instance. A non-object (or self) result is left for the encoder,
150
+ // which invokes toJSON again — serializers are assumed pure.
151
+ const json = record.toJSON();
152
+ if (json !== record && json !== null && typeof json === 'object') record = json;
153
+ }
154
+ if (!project) {
155
+ for (let i = 0; i < resolvedList.length; i++) {
156
+ if (Object.hasOwn(record, resolvedList[i])) {
157
+ project = true;
158
+ break;
159
+ }
160
+ }
161
+ }
162
+ if (!project) return record;
163
+ const stored = {};
164
+ for (const key of Object.keys(record)) {
165
+ if (resolved.has(key)) continue;
166
+ // '__proto__' as an own key must stay a data property: plain assignment would run the inherited
167
+ // setter, dropping the field from the durable write and swapping the temporary's prototype.
168
+ if (key === '__proto__')
169
+ Object.defineProperty(stored, key, { value: record[key], enumerable: true, writable: true, configurable: true });
170
+ else stored[key] = record[key];
171
+ }
172
+ return stored;
173
+ }
174
+
175
+ /**
176
+ * A resolver-owned name is skipped rather than assigned during record-instance promotion: through a
177
+ * read-only resolver the assignment throws, and through a writable one (a many-to-one
178
+ * `@relationship`) it would derive a foreign key from the stale stored value.
179
+ */
180
+ export function assignStoredFields(target: any, source: any, encoder: any) {
181
+ const resolved = encoder?.resolvedAttributeNames;
182
+ if (resolved === undefined) return Object.assign(target, source);
183
+ // Own keys, matching the Object.assign fallback above and storedFieldsOnly: a decoded plain
184
+ // object has no inherited enumerables of its own, so walking the chain could only ever pick up
185
+ // somebody else's (a polluted Object.prototype included).
186
+ for (const key of Object.keys(source)) {
187
+ if (resolved.has(key)) continue;
188
+ if (key === '__proto__')
189
+ Object.defineProperty(target, key, { value: source[key], enumerable: true, writable: true, configurable: true });
190
+ else target[key] = source[key];
191
+ }
192
+ return target;
193
+ }
194
+
126
195
  export class RecordEncoder extends StructonEncoder {
127
196
  rootStore: any;
128
197
  declare saveStructures: any;
129
198
  declare getStructures: any;
130
199
  declare _writeStruct: any;
131
200
  structureUpdate?: any;
201
+ // Set by TableResource.updatedAttributes. Undefined for a store with no resolved attributes, which
202
+ // is what keeps the projection off that store's writes entirely.
203
+ resolvedAttributeNames?: Set<string>;
204
+ resolvedAttributeNamesList?: string[];
205
+ surfacedToJSON?: () => any;
132
206
  isRocksDB: boolean;
133
207
  name: string;
134
208
  useVersions: boolean;
@@ -539,7 +613,7 @@ export function handleLocalTimeForGets(store, rootStore) {
539
613
  // if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
540
614
  const originalValue = entry.value;
541
615
  entry.value = new store.encoder.structPrototype.constructor();
542
- Object.assign(entry.value, originalValue);
616
+ assignStoredFields(entry.value, originalValue, store.encoder);
543
617
  }
544
618
  entryMap.set(entry.value, entry); // allow the record to access the entry
545
619
  }
@@ -591,7 +665,7 @@ export function handleLocalTimeForGets(store, rootStore) {
591
665
  // if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
592
666
  const originalValue = entry.value;
593
667
  entry.value = new store.encoder.structPrototype.constructor();
594
- for (const key in originalValue) entry.value[key] = originalValue[key];
668
+ assignStoredFields(entry.value, originalValue, store.encoder);
595
669
  }
596
670
  }
597
671
  return entry;
@@ -708,6 +782,10 @@ export function recordUpdater(store, tableId, auditStore) {
708
782
  // harper#1309: reset so a record===undefined call (delete/no-op) cannot carry stale bytes
709
783
  // into the audit encodedRecord or write-size analytics of this call.
710
784
  lastValueEncoding = undefined;
785
+ // Every durable form of the record — the stored value, the audit entry's encodedRecord and so the
786
+ // transaction log and replication payload — comes from this record, so projecting it here covers
787
+ // them all; nested values keep their own toJSON serialization.
788
+ record = storedFieldsOnly(store.encoder, record);
711
789
  const isRocksDB = store instanceof RocksDatabase;
712
790
  // determine if and how we apply the local timestamp
713
791
  if (isRocksDB) {
@@ -809,6 +887,10 @@ export function recordUpdater(store, tableId, auditStore) {
809
887
  if (audit) {
810
888
  const username = typeof options?.user === 'string' ? options.user : options?.user?.username;
811
889
  if (auditRecord) {
890
+ // The audit encodedRecord is durable record state too (it is the transaction log and the
891
+ // replication payload), so it takes the same projection — except for message/publish
892
+ // entries, whose auditRecord IS the published payload and must reach subscribers verbatim.
893
+ if (type !== 'message' && type !== 'publish') auditRecord = storedFieldsOnly(store.encoder, auditRecord);
812
894
  encodeBlobsWithFilePath(() => store.encoder.encode(auditRecord), id, store.rootStore);
813
895
  if (blobsWereEncoded) {
814
896
  extendedType |= HAS_BLOBS;
@@ -117,7 +117,14 @@ export class RocksTransactionLogStore extends EventEmitter {
117
117
  }
118
118
  entryBinary = createAuditEntry(auditRecord, position);
119
119
  }
120
- if (this.listenerCount('aftercommit')) (options.transaction.logEntries ??= []).push(auditRecord);
120
+ if (this.listenerCount('aftercommit')) {
121
+ if (!(auditRecord instanceof Uint8Array)) {
122
+ const txnTimestamp = options.transaction.getTimestamp?.();
123
+ if (txnTimestamp != null) auditRecord.localTime = txnTimestamp;
124
+ auditRecord.recordVersion = auditRecord.version;
125
+ }
126
+ (options.transaction.logEntries ??= []).push(auditRecord);
127
+ }
121
128
  // One commit hook per transaction handles both deferred side effects — the `aftercommit` emit and the
122
129
  // per-(log, table) structureVersion watermark advances — so they apply only after a durable commit (never
123
130
  // on an aborted/discarded transaction). This store is the sole setter of transaction.onCommit.
@@ -414,7 +421,10 @@ export class RocksTransactionLogStore extends EventEmitter {
414
421
  position += 8;
415
422
  }
416
423
  const auditRecord = readAuditEntry(data, position, undefined);
424
+ // version stays the log key (replication resume relies on version === log key);
425
+ // the record's own version survives as recordVersion
417
426
  auditRecord.version = timestamp;
427
+ auditRecord.localTime = timestamp;
418
428
  auditRecord.endTxn = endTxn;
419
429
  auditRecord.previousResidencyId = previousResidencyId;
420
430
  auditRecord.previousVersion = previousVersion;
@@ -72,7 +72,15 @@ import { getWorkerIndex, getWorkerCount } from '../server/threads/manageThreads.
72
72
  import { HAS_BLOBS, auditRetention, removeAuditEntry } from './auditStore.ts';
73
73
  import { buildEmbedBefore, createDefaultEmbedder, type EmbedAttribute, type Embedder } from './models/embedHook.ts';
74
74
  import { autoCast, autoCastBooleanStrict } from '../utility/common_utils.ts';
75
- import { recordUpdater, removeEntry, PENDING_LOCAL_TIME, RecordObject, type Entry, entryMap } from './RecordEncoder.ts';
75
+ import {
76
+ recordUpdater,
77
+ removeEntry,
78
+ PENDING_LOCAL_TIME,
79
+ RecordObject,
80
+ type Entry,
81
+ entryMap,
82
+ storedFieldsOnly,
83
+ } from './RecordEncoder.ts';
76
84
  import { recordAction, recordActionBinary } from './analytics/write.ts';
77
85
  import { rebuildUpdateBefore } from './crdt.ts';
78
86
  import { appendHeader } from '../server/serverHelpers/Headers.ts';
@@ -453,6 +461,18 @@ export function makeTable(options) {
453
461
  // it, so such a table takes the guarded serialization path rather than the raw fast path.
454
462
  let hasSurfacedComputed = false;
455
463
  let runningRecordExpiration: boolean;
464
+ const reportedResolverCollisions = new Set<string>();
465
+ // Reached from record materialization, so it can never be the reason a record fails to load: the
466
+ // name is marked before the log call, and a throwing log sink is swallowed.
467
+ function reportResolverCollision(name: string) {
468
+ if (reportedResolverCollisions.has(name)) return;
469
+ reportedResolverCollisions.add(name);
470
+ try {
471
+ logger.warn?.(
472
+ `Table "${tableName}" has a stored value under "${name}", which is a computed attribute; the stored value is being discarded and the computed value used instead`
473
+ );
474
+ } catch {}
475
+ }
456
476
  const isRocksDB = primaryStore instanceof RocksDatabase;
457
477
  type BigInt64ArrayAndMaxSafeId = BigInt64Array & { maxSafeId: number };
458
478
  let idIncrementer: BigInt64ArrayAndMaxSafeId;
@@ -4113,7 +4133,8 @@ export function makeTable(options) {
4113
4133
  // been written, so are fresh in memory.
4114
4134
  const entry: Entry = primaryStore.getEntry(id);
4115
4135
  if (entry) {
4116
- if (entry.version !== auditRecord.version) return; // out of order event, with old update, don't send anything
4136
+ // staleness is a record-version comparison; auditRecord.version is the log key on RocksDB
4137
+ if (entry.version !== (auditRecord.recordVersion ?? auditRecord.version)) return; // out of order event, with old update, don't send anything
4117
4138
  value = entry.value;
4118
4139
  type = entry.metadataFlags & INVALIDATED ? 'invalidate' : value ? 'put' : 'delete';
4119
4140
  } else {
@@ -4990,6 +5011,9 @@ export function makeTable(options) {
4990
5011
  for (const attribute of this.attributes) {
4991
5012
  if (attribute.isPrimaryKey) primaryKeyAttribute = attribute;
4992
5013
  attribute.resolve = null; // reset this
5014
+ // Also the setter, or a reload that turns a @relationship into a @computed keeps the
5015
+ // relationship's setter and writes a foreign key from a computed assignment.
5016
+ attribute.set = null;
4993
5017
  const relationship = attribute.relationship;
4994
5018
  const computed = attribute.computed;
4995
5019
  // Register the default embedder unless an author override is set. Sits outside
@@ -5151,14 +5175,19 @@ export function makeTable(options) {
5151
5175
  enumerableAttributeNames = [];
5152
5176
  enumerableRelationDefs.clear();
5153
5177
  hasSurfacedComputed = false;
5178
+ const resolvedAttributeNames: string[] = [];
5154
5179
  for (const attribute of attributes) {
5155
5180
  const name = attribute.name;
5156
5181
  if (attribute.resolve) {
5182
+ resolvedAttributeNames.push(name);
5157
5183
  Object.defineProperty(primaryStore.encoder.structPrototype, name, {
5158
5184
  get() {
5159
5185
  return attribute.resolve(this, contextStorage.getStore()); // it is only possible to get the context from ALS, we don't have a direct reference to the current context
5160
5186
  },
5161
5187
  set(related) {
5188
+ // A read-only resolver must never be the reason a record fails to materialize — the
5189
+ // same reason the one-to-many branch above installs a no-op.
5190
+ if (!attribute.set) return reportResolverCollision(name);
5162
5191
  return attribute.set(this, related);
5163
5192
  },
5164
5193
  configurable: true,
@@ -5184,6 +5213,12 @@ export function makeTable(options) {
5184
5213
  if (enumerableAttributeNames.length > 0)
5185
5214
  installEnumerableToJSON(primaryStore.encoder.structPrototype, this, hasSurfacedComputed);
5186
5215
  else if (primaryStore.encoder.structPrototype.toJSON) delete primaryStore.encoder.structPrototype.toJSON;
5216
+ // Undefined rather than an empty set for a table with no resolved attributes: that is the
5217
+ // check which keeps the projection off an unaffected store's write path.
5218
+ primaryStore.encoder.resolvedAttributeNames =
5219
+ resolvedAttributeNames.length > 0 ? new Set(resolvedAttributeNames) : undefined;
5220
+ primaryStore.encoder.resolvedAttributeNamesList = resolvedAttributeNames;
5221
+ primaryStore.encoder.surfacedToJSON = primaryStore.encoder.structPrototype.toJSON;
5187
5222
  }
5188
5223
  // #section: computed-history
5189
5224
  static setComputedAttribute(attribute_name, resolver) {
@@ -5997,6 +6032,31 @@ export function makeTable(options) {
5997
6032
  // before stamping the primary key and created/updated times below (records are immutable —
5998
6033
  // 5.2 record caching relies on it — so we must not write through the frozen object).
5999
6034
  if (isFrozenRecordObject(updatedRecord)) updatedRecord = { ...updatedRecord };
6035
+ // A writable resolver (a relationship) keeps its meaning for source payloads: a source
6036
+ // returning the related object instead of the foreign key gets the key derived, the way
6037
+ // the promotion setter used to. Derivation runs against a probe first — a malformed
6038
+ // value (a scalar, an object without the related primary key) derives undefined, and
6039
+ // applying that would durably wipe the foreign key. The projection then drops the
6040
+ // resolver-owned key itself, so the cache-fill response cannot be the one read
6041
+ // reporting the source's value.
6042
+ const resolvedNames = primaryStore.encoder.resolvedAttributeNamesList;
6043
+ if (resolvedNames) {
6044
+ for (const name of resolvedNames) {
6045
+ if (Object.hasOwn(updatedRecord, name)) {
6046
+ const resolvedAttribute = findAttribute(attributes, name);
6047
+ if (resolvedAttribute?.set && updatedRecord[name] != null) {
6048
+ const probe = {};
6049
+ resolvedAttribute.set(probe, updatedRecord[name]);
6050
+ for (const key in probe) {
6051
+ const derived = probe[key];
6052
+ const usable = Array.isArray(derived) ? derived.every((one) => one != null) : derived != null;
6053
+ if (usable) updatedRecord[key] = derived;
6054
+ }
6055
+ }
6056
+ }
6057
+ }
6058
+ }
6059
+ updatedRecord = storedFieldsOnly(primaryStore.encoder, updatedRecord);
6000
6060
  if (primaryKey && updatedRecord[primaryKey] !== id) updatedRecord[primaryKey] = id;
6001
6061
  }
6002
6062
  resolved = true;
@@ -34,7 +34,8 @@ initSync();
34
34
 
35
35
  export type AuditRecord = {
36
36
  version: number;
37
- localTime: number; // only to be used by LMDB (from the key)
37
+ recordVersion?: number; // the record's own version; on RocksDB reads `version` becomes the log key, so record identity uses this
38
+ localTime: number; // log position: LMDB audit-store key; RocksDB transaction-log timestamp
38
39
  type: string;
39
40
  encodedRecord?: Buffer;
40
41
  extendedType?: number;
@@ -620,6 +621,7 @@ export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined):
620
621
  return buffer.subarray(recordIdStart, recordIdEnd);
621
622
  },
622
623
  version,
624
+ recordVersion: version,
623
625
  previousVersion,
624
626
  get user() {
625
627
  try {
@@ -351,4 +351,4 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
351
351
  }
352
352
 
353
353
  // useful for testing
354
- export const loadGQLSchema = (content) => processGraphQLSchema(content, null, null, new Resources());
354
+ export const loadGQLSchema = (content) => processGraphQLSchema(content, null, '<inline-schema>', new Resources());
@@ -45,6 +45,10 @@ export function assignTrackedAccessors(Target, typeDef, useFullPropertyProxy = f
45
45
  return attribute.resolve(this, this.getContext?.());
46
46
  },
47
47
  set(related) {
48
+ // Unlike the struct-prototype accessor (which tolerates a stored collision so a record can
49
+ // still load), this is a user assignment to a resolved attribute, and a read-only resolver
50
+ // (a scalar @computed has no attribute.set) has nowhere to put it (harper#2359).
51
+ if (!attribute.set) throw new ClientError(`${name} is a computed attribute and can not be assigned`);
48
52
  return attribute.set(this, related);
49
53
  },
50
54
  configurable: true,
@@ -180,6 +180,9 @@ function notifyFromTransactionData(subscriptions, auditLogIterable?, allowYield
180
180
  const auditRecord = result.value;
181
181
  const timestamp: number = auditRecord.localTime ?? auditRecord.version;
182
182
  subscriptions.lastTxnTime = timestamp;
183
+ // the transaction extent: RocksDB entries committed together share the log key (record
184
+ // versions may differ); LMDB's localTime is a per-entry audit key, so version delimits there
185
+ const txnKey = auditStore.reusableIterable ? timestamp : auditRecord.version;
183
186
  if (ACTIONS_OF_INTEREST.includes(auditRecord.type)) {
184
187
  const tableSubscriptions = subscriptions[auditRecord.tableId];
185
188
  if (tableSubscriptions) {
@@ -204,7 +207,7 @@ function notifyFromTransactionData(subscriptions, auditLogIterable?, allowYield
204
207
  }
205
208
  try {
206
209
  let beginTxn;
207
- if (subscription.supportsTransactions && subscription.txnInProgress !== auditRecord.version) {
210
+ if (subscription.supportsTransactions && subscription.txnInProgress !== txnKey) {
208
211
  // if the subscriber supports transactions, we mark this as the beginning of a new transaction
209
212
  // tracking the subscription so that we can delimit the transaction on next transaction
210
213
  // (with a beginTxn flag, which may be on an endTxn event)
@@ -214,10 +217,7 @@ function notifyFromTransactionData(subscriptions, auditLogIterable?, allowYield
214
217
  if (!subscribersWithTxns) subscribersWithTxns = [subscription];
215
218
  else subscribersWithTxns.push(subscription);
216
219
  }
217
- // the version defines the extent of a transaction, all audit records with the same version
218
- // are part of the same transaction, and when the version changes, we know it is a new
219
- // transaction
220
- subscription.txnInProgress = auditRecord.version;
220
+ subscription.txnInProgress = txnKey;
221
221
  }
222
222
  subscription.listener(recordId, auditRecord, timestamp, beginTxn);
223
223
  } catch (error) {