@noy-db/hub 0.2.0-pre.12 → 0.2.0-pre.14

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 (249) hide show
  1. package/dist/aggregate/index.cjs.map +1 -1
  2. package/dist/aggregate/index.d.cts +2 -2
  3. package/dist/aggregate/index.d.ts +2 -2
  4. package/dist/aggregate/index.js +2 -2
  5. package/dist/attestation/index.cjs.map +1 -1
  6. package/dist/attestation/index.d.cts +3 -3
  7. package/dist/attestation/index.d.ts +3 -3
  8. package/dist/attestation/index.js +6 -6
  9. package/dist/blobs/index.cjs.map +1 -1
  10. package/dist/blobs/index.d.cts +4 -4
  11. package/dist/blobs/index.d.ts +4 -4
  12. package/dist/blobs/index.js +5 -5
  13. package/dist/bundle/index.cjs +683 -39
  14. package/dist/bundle/index.cjs.map +1 -1
  15. package/dist/bundle/index.d.cts +5 -5
  16. package/dist/bundle/index.d.ts +5 -5
  17. package/dist/bundle/index.js +9 -9
  18. package/dist/{chunk-OPDTLHFA.js → chunk-3EWA37FV.js} +2 -2
  19. package/dist/{chunk-ZCFS7U4J.js → chunk-4PEFEETV.js} +2 -2
  20. package/dist/{chunk-ZC7MNVYN.js → chunk-4TBBMHVC.js} +2 -2
  21. package/dist/{chunk-AGRC7NQQ.js → chunk-535SSHBS.js} +33 -1
  22. package/dist/chunk-535SSHBS.js.map +1 -0
  23. package/dist/{chunk-SJJQKNMP.js → chunk-56DJ7JVK.js} +4 -4
  24. package/dist/{chunk-C2CIIQRG.js → chunk-5LQG6ZO2.js} +2 -2
  25. package/dist/{chunk-6AD5TBF2.js → chunk-6AJBSQU4.js} +3 -3
  26. package/dist/{chunk-LWSD4QPT.js → chunk-6RR3MNMG.js} +3 -3
  27. package/dist/{chunk-O53RIZCC.js → chunk-7HT2MEZ5.js} +5 -5
  28. package/dist/{chunk-7LVRIW4G.js → chunk-7PS7EOCF.js} +4 -4
  29. package/dist/{chunk-GFPR7VJS.js → chunk-A5ZOOZFB.js} +4 -4
  30. package/dist/{chunk-B7GGYNKQ.js → chunk-AAVWKNZW.js} +2 -2
  31. package/dist/{chunk-TMHJEYW7.js → chunk-ACKFRSAH.js} +302 -137
  32. package/dist/chunk-ACKFRSAH.js.map +1 -0
  33. package/dist/{chunk-SZ4N3IL5.js → chunk-BIYRQQV6.js} +5 -5
  34. package/dist/{chunk-CILT6V3V.js → chunk-BQ65SS5A.js} +2 -2
  35. package/dist/{chunk-DLTU4M2I.js → chunk-COFPAMX6.js} +6 -6
  36. package/dist/{chunk-UA6G45ME.js → chunk-DKO2QFSA.js} +3 -3
  37. package/dist/{chunk-L6BYRCYB.js → chunk-DQU36Q7I.js} +2 -2
  38. package/dist/{chunk-VOXMU6LB.js → chunk-EGD5DXFT.js} +2 -2
  39. package/dist/{chunk-BXOUVUES.js → chunk-F4OJZIWQ.js} +4 -4
  40. package/dist/{chunk-P3Z5Y2TS.js → chunk-FWPKCXTN.js} +2 -2
  41. package/dist/{chunk-LYNNZEQD.js → chunk-GC4V7RU7.js} +1 -1
  42. package/dist/chunk-GC4V7RU7.js.map +1 -0
  43. package/dist/{chunk-6BYBVRZU.js → chunk-HOR4R722.js} +3 -3
  44. package/dist/{chunk-XSIFXX54.js → chunk-JD3OZAI4.js} +2 -2
  45. package/dist/{chunk-UOC7JMZO.js → chunk-KGCORI4L.js} +135 -10
  46. package/dist/chunk-KGCORI4L.js.map +1 -0
  47. package/dist/{chunk-RRDWXNBQ.js → chunk-KI6HAJWL.js} +3 -3
  48. package/dist/{chunk-LSEW3ZZ2.js → chunk-L2FE64BU.js} +3 -3
  49. package/dist/{chunk-HBAJDI2N.js → chunk-LX3CB26H.js} +5 -5
  50. package/dist/{chunk-LOA2VCMS.js → chunk-NSCVNK5K.js} +5 -5
  51. package/dist/{chunk-4BHFNKTP.js → chunk-OHVFWCJP.js} +2 -2
  52. package/dist/{chunk-7JJE3OMJ.js → chunk-PE4AQGFH.js} +5 -5
  53. package/dist/{chunk-RHQYVHFH.js → chunk-TS26M2SB.js} +2 -2
  54. package/dist/{chunk-EKNUBIIQ.js → chunk-UWNYBOOO.js} +4 -4
  55. package/dist/{chunk-WNRGOVLG.js → chunk-VU7SWWT5.js} +2 -2
  56. package/dist/{chunk-WUG3E423.js → chunk-WBAYSNUQ.js} +4 -4
  57. package/dist/{chunk-XHM2SARW.js → chunk-WGHU7BLI.js} +3 -3
  58. package/dist/{chunk-5ARRXIVR.js → chunk-X73VS74Y.js} +2 -2
  59. package/dist/{chunk-M45IRXDM.js → chunk-YHPM5D7Y.js} +3 -3
  60. package/dist/{chunk-P4EDT5ZP.js → chunk-YNTBADIY.js} +2 -2
  61. package/dist/{chunk-IUBHXEPJ.js → chunk-YULZKK4F.js} +2 -2
  62. package/dist/{chunk-IEPT7HVP.js → chunk-Z4DO7YSI.js} +2 -2
  63. package/dist/chunk-ZC7J6ZYV.js +7 -0
  64. package/dist/chunk-ZC7J6ZYV.js.map +1 -0
  65. package/dist/{chunk-HLGDYFWR.js → chunk-ZNQYHJXX.js} +2 -2
  66. package/dist/{chunk-CHBXWJZQ.js → chunk-ZWTNWAO4.js} +2 -2
  67. package/dist/consent/index.cjs.map +1 -1
  68. package/dist/consent/index.d.cts +4 -4
  69. package/dist/consent/index.d.ts +4 -4
  70. package/dist/consent/index.js +3 -3
  71. package/dist/{crypto-AJB72OKN.js → crypto-QXQOHMHF.js} +3 -3
  72. package/dist/{delegation-6FCWDRUS.js → delegation-NIQ43IPU.js} +5 -5
  73. package/dist/derivations/index.cjs.map +1 -1
  74. package/dist/derivations/index.d.cts +5 -5
  75. package/dist/derivations/index.d.ts +5 -5
  76. package/dist/derivations/index.js +4 -4
  77. package/dist/{dev-unlock-ckqa_Nso.d.cts → dev-unlock-BF4OSxRv.d.cts} +1 -1
  78. package/dist/{dev-unlock-D3mpVFRc.d.ts → dev-unlock-DV7ujTCI.d.ts} +1 -1
  79. package/dist/executor-6ZDSDZ6V.js +8 -0
  80. package/dist/executor-723ZP6TH.js +11 -0
  81. package/dist/executor-IDZDAFNH.js +8 -0
  82. package/dist/{fanout-sidecar-ZSKEQ6NI.js → fanout-sidecar-N6OJX6QR.js} +2 -2
  83. package/dist/guards/index.cjs.map +1 -1
  84. package/dist/guards/index.d.cts +5 -5
  85. package/dist/guards/index.d.ts +5 -5
  86. package/dist/guards/index.js +3 -3
  87. package/dist/{hash-rDSSd_oW.d.cts → hash-BcF5WQXl.d.cts} +1 -1
  88. package/dist/{hash-CTZVkXLx.d.ts → hash-DswxkLtW.d.ts} +1 -1
  89. package/dist/history/index.cjs.map +1 -1
  90. package/dist/history/index.d.cts +5 -5
  91. package/dist/history/index.d.ts +5 -5
  92. package/dist/history/index.js +5 -5
  93. package/dist/i18n/index.cjs.map +1 -1
  94. package/dist/i18n/index.d.cts +4 -4
  95. package/dist/i18n/index.d.ts +4 -4
  96. package/dist/i18n/index.js +6 -6
  97. package/dist/{immutable-guard-C51vAHuh.d.cts → immutable-guard-7KqslW2K.d.cts} +1 -1
  98. package/dist/{immutable-guard-DyD0qg2k.d.ts → immutable-guard-C8IYdzfu.d.ts} +1 -1
  99. package/dist/{index-Cmop06zJ.d.cts → index-CUVOMtgg.d.cts} +28 -2
  100. package/dist/{index-CkFHr4OP.d.ts → index-Cqzp4tt9.d.ts} +28 -2
  101. package/dist/index.cjs +699 -42
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.d.cts +22 -13
  104. package/dist/index.d.ts +22 -13
  105. package/dist/index.js +59 -40
  106. package/dist/index.js.map +1 -1
  107. package/dist/indexing/index.cjs.map +1 -1
  108. package/dist/indexing/index.js +2 -2
  109. package/dist/issue-ADVS4OVP.js +12 -0
  110. package/dist/{ledger-5JMVF7PY.js → ledger-CWSE3BLF.js} +5 -5
  111. package/dist/materialized-views/index.cjs.map +1 -1
  112. package/dist/materialized-views/index.d.cts +5 -5
  113. package/dist/materialized-views/index.d.ts +5 -5
  114. package/dist/materialized-views/index.js +6 -6
  115. package/dist/noydb-VZ4JVW55.js +35 -0
  116. package/dist/overlay-views/index.cjs.map +1 -1
  117. package/dist/overlay-views/index.d.cts +5 -5
  118. package/dist/overlay-views/index.d.ts +5 -5
  119. package/dist/overlay-views/index.js +4 -4
  120. package/dist/periods/index.cjs.map +1 -1
  121. package/dist/periods/index.d.cts +4 -4
  122. package/dist/periods/index.d.ts +4 -4
  123. package/dist/periods/index.js +5 -5
  124. package/dist/{public-envelope-PFLZI5MO.js → public-envelope-SYHEYQ3X.js} +4 -4
  125. package/dist/query/index.cjs +89 -7
  126. package/dist/query/index.cjs.map +1 -1
  127. package/dist/query/index.d.cts +2 -2
  128. package/dist/query/index.d.ts +2 -2
  129. package/dist/query/index.js +3 -3
  130. package/dist/{registry-NCY445U5.js → registry-DK5YWAAA.js} +3 -3
  131. package/dist/registry-IUZQVVBB.js +8 -0
  132. package/dist/registry-XGLNADIE.js +8 -0
  133. package/dist/{revoke-7RLGQWZ7.js → revoke-ZDFKMR5E.js} +6 -6
  134. package/dist/session/index.cjs.map +1 -1
  135. package/dist/session/index.d.cts +5 -5
  136. package/dist/session/index.d.ts +5 -5
  137. package/dist/session/index.js +3 -3
  138. package/dist/shadow/index.cjs.map +1 -1
  139. package/dist/shadow/index.d.cts +4 -4
  140. package/dist/shadow/index.d.ts +4 -4
  141. package/dist/shadow/index.js +2 -2
  142. package/dist/{signer-6JF44I4A.js → signer-P5D7Y72U.js} +5 -5
  143. package/dist/snapshots/index.cjs.map +1 -1
  144. package/dist/snapshots/index.d.cts +4 -4
  145. package/dist/snapshots/index.d.ts +4 -4
  146. package/dist/snapshots/index.js +4 -4
  147. package/dist/{stale-UBLP3RJ3.js → stale-7FRJVHN6.js} +2 -2
  148. package/dist/state-vault-TMXZRTY5.js +147 -0
  149. package/dist/state-vault-TMXZRTY5.js.map +1 -0
  150. package/dist/store/index.cjs.map +1 -1
  151. package/dist/store/index.d.cts +4 -4
  152. package/dist/store/index.d.ts +4 -4
  153. package/dist/store/index.js +2 -2
  154. package/dist/{strategy-rtpKDfTC.d.ts → strategy-CrS7PnbE.d.cts} +20 -1
  155. package/dist/{strategy-rtpKDfTC.d.cts → strategy-CrS7PnbE.d.ts} +20 -1
  156. package/dist/sync/index.cjs.map +1 -1
  157. package/dist/sync/index.d.cts +3 -3
  158. package/dist/sync/index.d.ts +3 -3
  159. package/dist/sync/index.js +4 -4
  160. package/dist/team/index.cjs.map +1 -1
  161. package/dist/team/index.d.cts +4 -4
  162. package/dist/team/index.d.ts +4 -4
  163. package/dist/team/index.js +8 -8
  164. package/dist/tx/index.cjs.map +1 -1
  165. package/dist/tx/index.d.cts +4 -4
  166. package/dist/tx/index.d.ts +4 -4
  167. package/dist/tx/index.js +3 -3
  168. package/dist/{types-DRdfwgTG.d.ts → types-BFHQUjdy.d.ts} +341 -90
  169. package/dist/{types-BGwjsDef.d.cts → types-V5R2-pd4.d.cts} +341 -90
  170. package/dist/{ulid-D4d0Xto3.d.cts → ulid-CwNf9e6-.d.cts} +1 -1
  171. package/dist/{ulid-DOTPZ5_h.d.ts → ulid-p2nKiiKg.d.ts} +1 -1
  172. package/dist/util/index.cjs.map +1 -1
  173. package/dist/util/index.js +1 -1
  174. package/dist/{vault-group-Z4KB75ZH.js → vault-group-W7QC4UYW.js} +175 -18
  175. package/dist/vault-group-W7QC4UYW.js.map +1 -0
  176. package/dist/{with-derivation-CB1EdcFF.d.cts → with-derivation-C9K43BOB.d.cts} +1 -1
  177. package/dist/{with-derivation-B082Y_WQ.d.ts → with-derivation-Ds9yZgCj.d.ts} +1 -1
  178. package/dist/{with-materialized-view-CzRg1Dpr.d.cts → with-materialized-view-DgQcAjYv.d.cts} +1 -1
  179. package/dist/{with-materialized-view-Dw4SwjKl.d.ts → with-materialized-view-DwR4jkV5.d.ts} +1 -1
  180. package/dist/{with-overlayed-view-C9YFKXzn.d.cts → with-overlayed-view-7-rUB3vD.d.cts} +1 -1
  181. package/dist/{with-overlayed-view-CaCXeW26.d.ts → with-overlayed-view-ByyhHdVr.d.ts} +1 -1
  182. package/package.json +3 -3
  183. package/dist/chunk-AGRC7NQQ.js.map +0 -1
  184. package/dist/chunk-LYNNZEQD.js.map +0 -1
  185. package/dist/chunk-TMHJEYW7.js.map +0 -1
  186. package/dist/chunk-UOC7JMZO.js.map +0 -1
  187. package/dist/executor-7KSCEIFA.js +0 -8
  188. package/dist/executor-D2QMNGRJ.js +0 -8
  189. package/dist/executor-O5AZK7UW.js +0 -11
  190. package/dist/issue-YIYG4OW5.js +0 -12
  191. package/dist/noydb-D5SLAJ6V.js +0 -34
  192. package/dist/registry-BVQ5ITMF.js +0 -8
  193. package/dist/registry-JLP3QOLD.js +0 -8
  194. package/dist/vault-group-Z4KB75ZH.js.map +0 -1
  195. /package/dist/{chunk-OPDTLHFA.js.map → chunk-3EWA37FV.js.map} +0 -0
  196. /package/dist/{chunk-ZCFS7U4J.js.map → chunk-4PEFEETV.js.map} +0 -0
  197. /package/dist/{chunk-ZC7MNVYN.js.map → chunk-4TBBMHVC.js.map} +0 -0
  198. /package/dist/{chunk-SJJQKNMP.js.map → chunk-56DJ7JVK.js.map} +0 -0
  199. /package/dist/{chunk-C2CIIQRG.js.map → chunk-5LQG6ZO2.js.map} +0 -0
  200. /package/dist/{chunk-6AD5TBF2.js.map → chunk-6AJBSQU4.js.map} +0 -0
  201. /package/dist/{chunk-LWSD4QPT.js.map → chunk-6RR3MNMG.js.map} +0 -0
  202. /package/dist/{chunk-O53RIZCC.js.map → chunk-7HT2MEZ5.js.map} +0 -0
  203. /package/dist/{chunk-7LVRIW4G.js.map → chunk-7PS7EOCF.js.map} +0 -0
  204. /package/dist/{chunk-GFPR7VJS.js.map → chunk-A5ZOOZFB.js.map} +0 -0
  205. /package/dist/{chunk-B7GGYNKQ.js.map → chunk-AAVWKNZW.js.map} +0 -0
  206. /package/dist/{chunk-SZ4N3IL5.js.map → chunk-BIYRQQV6.js.map} +0 -0
  207. /package/dist/{chunk-CILT6V3V.js.map → chunk-BQ65SS5A.js.map} +0 -0
  208. /package/dist/{chunk-DLTU4M2I.js.map → chunk-COFPAMX6.js.map} +0 -0
  209. /package/dist/{chunk-UA6G45ME.js.map → chunk-DKO2QFSA.js.map} +0 -0
  210. /package/dist/{chunk-L6BYRCYB.js.map → chunk-DQU36Q7I.js.map} +0 -0
  211. /package/dist/{chunk-VOXMU6LB.js.map → chunk-EGD5DXFT.js.map} +0 -0
  212. /package/dist/{chunk-BXOUVUES.js.map → chunk-F4OJZIWQ.js.map} +0 -0
  213. /package/dist/{chunk-P3Z5Y2TS.js.map → chunk-FWPKCXTN.js.map} +0 -0
  214. /package/dist/{chunk-6BYBVRZU.js.map → chunk-HOR4R722.js.map} +0 -0
  215. /package/dist/{chunk-XSIFXX54.js.map → chunk-JD3OZAI4.js.map} +0 -0
  216. /package/dist/{chunk-RRDWXNBQ.js.map → chunk-KI6HAJWL.js.map} +0 -0
  217. /package/dist/{chunk-LSEW3ZZ2.js.map → chunk-L2FE64BU.js.map} +0 -0
  218. /package/dist/{chunk-HBAJDI2N.js.map → chunk-LX3CB26H.js.map} +0 -0
  219. /package/dist/{chunk-LOA2VCMS.js.map → chunk-NSCVNK5K.js.map} +0 -0
  220. /package/dist/{chunk-4BHFNKTP.js.map → chunk-OHVFWCJP.js.map} +0 -0
  221. /package/dist/{chunk-7JJE3OMJ.js.map → chunk-PE4AQGFH.js.map} +0 -0
  222. /package/dist/{chunk-RHQYVHFH.js.map → chunk-TS26M2SB.js.map} +0 -0
  223. /package/dist/{chunk-EKNUBIIQ.js.map → chunk-UWNYBOOO.js.map} +0 -0
  224. /package/dist/{chunk-WNRGOVLG.js.map → chunk-VU7SWWT5.js.map} +0 -0
  225. /package/dist/{chunk-WUG3E423.js.map → chunk-WBAYSNUQ.js.map} +0 -0
  226. /package/dist/{chunk-XHM2SARW.js.map → chunk-WGHU7BLI.js.map} +0 -0
  227. /package/dist/{chunk-5ARRXIVR.js.map → chunk-X73VS74Y.js.map} +0 -0
  228. /package/dist/{chunk-M45IRXDM.js.map → chunk-YHPM5D7Y.js.map} +0 -0
  229. /package/dist/{chunk-P4EDT5ZP.js.map → chunk-YNTBADIY.js.map} +0 -0
  230. /package/dist/{chunk-IUBHXEPJ.js.map → chunk-YULZKK4F.js.map} +0 -0
  231. /package/dist/{chunk-IEPT7HVP.js.map → chunk-Z4DO7YSI.js.map} +0 -0
  232. /package/dist/{chunk-HLGDYFWR.js.map → chunk-ZNQYHJXX.js.map} +0 -0
  233. /package/dist/{chunk-CHBXWJZQ.js.map → chunk-ZWTNWAO4.js.map} +0 -0
  234. /package/dist/{crypto-AJB72OKN.js.map → crypto-QXQOHMHF.js.map} +0 -0
  235. /package/dist/{delegation-6FCWDRUS.js.map → delegation-NIQ43IPU.js.map} +0 -0
  236. /package/dist/{executor-7KSCEIFA.js.map → executor-6ZDSDZ6V.js.map} +0 -0
  237. /package/dist/{executor-D2QMNGRJ.js.map → executor-723ZP6TH.js.map} +0 -0
  238. /package/dist/{executor-O5AZK7UW.js.map → executor-IDZDAFNH.js.map} +0 -0
  239. /package/dist/{fanout-sidecar-ZSKEQ6NI.js.map → fanout-sidecar-N6OJX6QR.js.map} +0 -0
  240. /package/dist/{issue-YIYG4OW5.js.map → issue-ADVS4OVP.js.map} +0 -0
  241. /package/dist/{ledger-5JMVF7PY.js.map → ledger-CWSE3BLF.js.map} +0 -0
  242. /package/dist/{noydb-D5SLAJ6V.js.map → noydb-VZ4JVW55.js.map} +0 -0
  243. /package/dist/{public-envelope-PFLZI5MO.js.map → public-envelope-SYHEYQ3X.js.map} +0 -0
  244. /package/dist/{registry-BVQ5ITMF.js.map → registry-DK5YWAAA.js.map} +0 -0
  245. /package/dist/{registry-JLP3QOLD.js.map → registry-IUZQVVBB.js.map} +0 -0
  246. /package/dist/{registry-NCY445U5.js.map → registry-XGLNADIE.js.map} +0 -0
  247. /package/dist/{revoke-7RLGQWZ7.js.map → revoke-ZDFKMR5E.js.map} +0 -0
  248. /package/dist/{signer-6JF44I4A.js.map → signer-P5D7Y72U.js.map} +0 -0
  249. /package/dist/{stale-UBLP3RJ3.js.map → stale-7FRJVHN6.js.map} +0 -0
@@ -31,7 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
33
  // src/errors.ts
34
- var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, FieldFrozenError, InvariantError, AmendmentForbiddenError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, BundleVersionConflictError, ValidationError, SchemaValidationError, SchemaUpdateError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, LocaleNotSpecifiedError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, PartitionExtractionError, TransferSealError, AdoptionStateError, AttestationError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, DerivationCycleError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, UnknownShardError, ShardProvisioningError, VaultTemplateNotFoundError;
34
+ var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, FieldFrozenError, InvariantError, AmendmentForbiddenError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, ValidationError, SchemaValidationError, SchemaUpdateError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, LocaleNotSpecifiedError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, PartitionExtractionError, TransferSealError, AdoptionStateError, AttestationError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, DerivationCycleError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, UnknownShardError, ShardProvisioningError, CrossShardJoinError, VaultTemplateNotFoundError;
35
35
  var init_errors = __esm({
36
36
  "src/errors.ts"() {
37
37
  "use strict";
@@ -155,6 +155,18 @@ var init_errors = __esm({
155
155
  this.offendingCollection = offendingCollection;
156
156
  }
157
157
  };
158
+ ReservedVaultNameError = class extends NoydbError {
159
+ /** The rejected vault name. */
160
+ vaultName;
161
+ constructor(vaultName) {
162
+ super(
163
+ "RESERVED_VAULT_NAME",
164
+ `"${vaultName}" is a reserved internal vault name and cannot be used as a group name or partition key`
165
+ );
166
+ this.name = "ReservedVaultNameError";
167
+ this.vaultName = vaultName;
168
+ }
169
+ };
158
170
  FieldFrozenError = class extends NoydbError {
159
171
  collection;
160
172
  id;
@@ -288,6 +300,17 @@ var init_errors = __esm({
288
300
  this.name = "SequenceOfflineError";
289
301
  }
290
302
  };
303
+ NumberingUncertaintyError = class extends NoydbError {
304
+ series;
305
+ constructor(series) {
306
+ super(
307
+ "NUMBERING_UNCERTAINTY",
308
+ `Deferred numbering for series "${series}" cannot run: the store does not expose getStoreTime() (capabilities.serverWriteTime). Use a CAS sequence or a store with serverWriteTime.`
309
+ );
310
+ this.name = "NumberingUncertaintyError";
311
+ this.series = series;
312
+ }
313
+ };
291
314
  BundleVersionConflictError = class extends NoydbError {
292
315
  /** The bundle handle of the newer remote version that rejected the push. */
293
316
  remoteVersion;
@@ -723,6 +746,12 @@ Resolutions:
723
746
  this.vaultId = vaultId;
724
747
  }
725
748
  };
749
+ CrossShardJoinError = class extends NoydbError {
750
+ constructor(message) {
751
+ super("CROSS_SHARD_JOIN", message);
752
+ this.name = "CrossShardJoinError";
753
+ }
754
+ };
726
755
  VaultTemplateNotFoundError = class extends NoydbError {
727
756
  templateName;
728
757
  constructor(templateName) {
@@ -2716,6 +2745,15 @@ var init_store = __esm({
2716
2745
  }
2717
2746
  });
2718
2747
 
2748
+ // src/federation/constants.ts
2749
+ var STATE_VAULT_NAME;
2750
+ var init_constants2 = __esm({
2751
+ "src/federation/constants.ts"() {
2752
+ "use strict";
2753
+ STATE_VAULT_NAME = "__noydb_state__";
2754
+ }
2755
+ });
2756
+
2719
2757
  // src/policy/errors.ts
2720
2758
  var PolicyDeniedError, RecoveryNotEnrolledError, ManagedRecoveryNotEnrolledError, RecoveryProfileNotImplementedError;
2721
2759
  var init_errors2 = __esm({
@@ -3712,10 +3750,10 @@ function shouldRoundUp(negative, lastKeptDigit, firstDiscarded, hasMoreNonZeroAf
3712
3750
  }
3713
3751
  }
3714
3752
  function parseToScaledInt(input, scale, rounding) {
3715
- const canonical = toCanonicalDecimalString(input);
3716
- if (canonical === null) return { ok: false, reason: "nonfinite" };
3717
- const negative = canonical.startsWith("-");
3718
- const unsigned = negative ? canonical.slice(1) : canonical;
3753
+ const canonical2 = toCanonicalDecimalString(input);
3754
+ if (canonical2 === null) return { ok: false, reason: "nonfinite" };
3755
+ const negative = canonical2.startsWith("-");
3756
+ const unsigned = negative ? canonical2.slice(1) : canonical2;
3719
3757
  const dot = unsigned.indexOf(".");
3720
3758
  const intPart = dot === -1 ? unsigned : unsigned.slice(0, dot);
3721
3759
  const fracPart = dot === -1 ? "" : unsigned.slice(dot + 1);
@@ -4869,7 +4907,7 @@ function serializeClause(clause) {
4869
4907
  }
4870
4908
  function canonicalCtxHash(ctx) {
4871
4909
  if (ctx === void 0) return "";
4872
- const canonical = JSON.stringify(ctx, (_key, value) => {
4910
+ const canonical2 = JSON.stringify(ctx, (_key, value) => {
4873
4911
  if (value && typeof value === "object" && !Array.isArray(value)) {
4874
4912
  const sorted = {};
4875
4913
  for (const k of Object.keys(value).sort()) {
@@ -4880,8 +4918,8 @@ function canonicalCtxHash(ctx) {
4880
4918
  return value;
4881
4919
  });
4882
4920
  let h = 5381;
4883
- for (let i = 0; i < canonical.length; i++) {
4884
- h = (h << 5) + h ^ canonical.charCodeAt(i);
4921
+ for (let i = 0; i < canonical2.length; i++) {
4922
+ h = (h << 5) + h ^ canonical2.charCodeAt(i);
4885
4923
  }
4886
4924
  return (h >>> 0).toString(16).padStart(8, "0");
4887
4925
  }
@@ -4924,6 +4962,7 @@ var init_builder = __esm({
4924
4962
  init_live();
4925
4963
  init_strategy4();
4926
4964
  init_money_reducer();
4965
+ init_normalize();
4927
4966
  EMPTY_PLAN = {
4928
4967
  clauses: [],
4929
4968
  orderBy: [],
@@ -5292,7 +5331,7 @@ var init_builder = __esm({
5292
5331
  * for the ordering rationale.
5293
5332
  */
5294
5333
  toArray() {
5295
- const base = executePlanWithSource(this.source, this.plan, this.joinContext);
5334
+ const base = this.decodeMoney(executePlanWithSource(this.source, this.plan, this.joinContext));
5296
5335
  if (this.plan.joins.length === 0) return base;
5297
5336
  if (!this.joinContext) {
5298
5337
  throw new Error(
@@ -5301,6 +5340,23 @@ var init_builder = __esm({
5301
5340
  }
5302
5341
  return applyJoins(base, this.plan.joins, this.joinContext);
5303
5342
  }
5343
+ /**
5344
+ * Decode this source's money fields on read (stored scaled-int → canonical
5345
+ * decimal), so `query().toArray()` agrees with `get()`/`sum()` on the value.
5346
+ * No-op when the source declares no money fields.
5347
+ *
5348
+ * The query layer carries no locale context, so we decode with `'raw'` —
5349
+ * canonical decimal, WITHOUT fabricating locale-formatted `<field>Formatted`
5350
+ * / `<field>Number` virtuals. Producing a guessed-locale string here would
5351
+ * just reintroduce #322's "two read paths disagree" failure on the virtual
5352
+ * field (e.g. it-IT via `get()` vs en-US here). Consumers who need formatted
5353
+ * money read through `get()`/`list()` with a locale.
5354
+ */
5355
+ decodeMoney(records) {
5356
+ const moneyFields = this.source.moneyFields;
5357
+ if (!moneyFields || Object.keys(moneyFields).length === 0) return records;
5358
+ return records.map((r) => decodeMoneyFields(r, moneyFields, "raw"));
5359
+ }
5304
5360
  /** Return the first matching record, or null. Joins are applied. */
5305
5361
  first() {
5306
5362
  const arr = this.limit(1).toArray();
@@ -5678,6 +5734,7 @@ var init_scan_builder = __esm({
5678
5734
  "use strict";
5679
5735
  init_predicate();
5680
5736
  init_errors();
5737
+ init_normalize();
5681
5738
  DEFAULT_SCAN_PAGE_SIZE = 100;
5682
5739
  ScanBuilder = class _ScanBuilder {
5683
5740
  pageProvider;
@@ -5703,12 +5760,29 @@ var init_scan_builder = __esm({
5703
5760
  * context throws with an actionable error.
5704
5761
  */
5705
5762
  joinContext;
5706
- constructor(pageProvider, pageSize = DEFAULT_SCAN_PAGE_SIZE, clauses = [], joins = [], joinContext) {
5763
+ /**
5764
+ * Money field descriptors for the backing collection. When present, yielded
5765
+ * records are decoded (stored scaled-int → canonical decimal) so `scan()`
5766
+ * agrees with `get()`/`list()`/`query().toArray()` — #322. Decoded with
5767
+ * `'raw'` (canonical decimal, no locale-formatted virtuals) since the scan
5768
+ * stream carries no locale context, mirroring `Query.toArray()`.
5769
+ */
5770
+ moneyFields;
5771
+ constructor(pageProvider, pageSize = DEFAULT_SCAN_PAGE_SIZE, clauses = [], joins = [], joinContext, moneyFields) {
5707
5772
  this.pageProvider = pageProvider;
5708
5773
  this.pageSize = pageSize;
5709
5774
  this.clauses = clauses;
5710
5775
  this.joins = joins;
5711
5776
  this.joinContext = joinContext;
5777
+ this.moneyFields = moneyFields;
5778
+ }
5779
+ /**
5780
+ * Decode this scan's money fields on a record (stored scaled-int → canonical
5781
+ * decimal). No-op when no money fields are declared. See {@link moneyFields}.
5782
+ */
5783
+ decodeMoney(record) {
5784
+ if (!this.moneyFields || Object.keys(this.moneyFields).length === 0) return record;
5785
+ return decodeMoneyFields(record, this.moneyFields, "raw");
5712
5786
  }
5713
5787
  /**
5714
5788
  * Add a field comparison. Runs per record as the scan stream
@@ -5730,7 +5804,8 @@ var init_scan_builder = __esm({
5730
5804
  this.pageSize,
5731
5805
  [...this.clauses, clause],
5732
5806
  this.joins,
5733
- this.joinContext
5807
+ this.joinContext,
5808
+ this.moneyFields
5734
5809
  );
5735
5810
  }
5736
5811
  /**
@@ -5749,7 +5824,8 @@ var init_scan_builder = __esm({
5749
5824
  this.pageSize,
5750
5825
  [...this.clauses, clause],
5751
5826
  this.joins,
5752
- this.joinContext
5827
+ this.joinContext,
5828
+ this.moneyFields
5753
5829
  );
5754
5830
  }
5755
5831
  /**
@@ -5860,7 +5936,8 @@ var init_scan_builder = __esm({
5860
5936
  this.pageSize,
5861
5937
  this.clauses,
5862
5938
  [...this.joins, leg],
5863
- this.joinContext
5939
+ this.joinContext,
5940
+ this.moneyFields
5864
5941
  );
5865
5942
  }
5866
5943
  /**
@@ -5877,10 +5954,11 @@ var init_scan_builder = __esm({
5877
5954
  while (true) {
5878
5955
  for (const record of page.items) {
5879
5956
  if (!this.recordMatches(record)) continue;
5957
+ const decoded = this.decodeMoney(record);
5880
5958
  if (joinResolvers === null) {
5881
- yield record;
5959
+ yield decoded;
5882
5960
  } else {
5883
- let attached = record;
5961
+ let attached = decoded;
5884
5962
  for (const resolver of joinResolvers) {
5885
5963
  attached = this.applyOneJoinStreaming(attached, resolver);
5886
5964
  }
@@ -7048,12 +7126,12 @@ var init_dependency_analyzer = __esm({
7048
7126
 
7049
7127
  // src/materialized-views/query-hash.ts
7050
7128
  async function computeQueryHash(mvName, dependencies, queryPlanSummary) {
7051
- const canonical = JSON.stringify({
7129
+ const canonical2 = JSON.stringify({
7052
7130
  mvName,
7053
7131
  dependencies: [...dependencies].sort(),
7054
7132
  queryPlanSummary
7055
7133
  });
7056
- const bytes = new TextEncoder().encode(canonical);
7134
+ const bytes = new TextEncoder().encode(canonical2);
7057
7135
  const digest = await crypto.subtle.digest("SHA-256", bytes);
7058
7136
  return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
7059
7137
  }
@@ -8914,9 +8992,17 @@ var init_collection = __esm({
8914
8992
  }
8915
8993
  await this.ensureHydrated();
8916
8994
  const records = [...this.cache.values()].map((e) => e.record);
8917
- if (!locale) return records;
8995
+ if (!this.hasReadTransforms()) return records;
8918
8996
  return Promise.all(records.map((r) => this.applyLocaleToRecord(r, locale)));
8919
8997
  }
8998
+ /**
8999
+ * @internal — whether any read-side record transform is registered
9000
+ * (money decode, i18nText resolution, dictKey labels). Gates the
9001
+ * no-transform fast path in {@link list}.
9002
+ */
9003
+ hasReadTransforms() {
9004
+ return this.moneyFields !== void 0 && Object.keys(this.moneyFields).length > 0 || this.i18nFields !== void 0 && Object.keys(this.i18nFields).length > 0 || this.dictKeyFields !== void 0 && Object.keys(this.dictKeyFields).length > 0;
9005
+ }
8920
9006
  // ─── Bulk operations ─────────────────────────────────────
8921
9007
  /**
8922
9008
  * Put many records in one call. Each item is processed sequentially
@@ -9422,7 +9508,8 @@ var init_collection = __esm({
9422
9508
  pageSize,
9423
9509
  [],
9424
9510
  [],
9425
- joinContext
9511
+ joinContext,
9512
+ this.moneyFields
9426
9513
  );
9427
9514
  }
9428
9515
  /** Decrypt a page of envelopes returned by `adapter.listPage`. */
@@ -10790,6 +10877,168 @@ var init_sequence = __esm({
10790
10877
  }
10791
10878
  });
10792
10879
 
10880
+ // src/numbering/index.ts
10881
+ var NUMBERING_HEAD_COLLECTION, NUMBERING_PENDING_COLLECTION, DeferredNumberingStore;
10882
+ var init_numbering = __esm({
10883
+ "src/numbering/index.ts"() {
10884
+ "use strict";
10885
+ init_types();
10886
+ init_crypto();
10887
+ init_errors();
10888
+ NUMBERING_HEAD_COLLECTION = "_numbering_head";
10889
+ NUMBERING_PENDING_COLLECTION = "_numbering_pending";
10890
+ DeferredNumberingStore = class {
10891
+ adapter;
10892
+ vault;
10893
+ encrypted;
10894
+ getDEK;
10895
+ actor;
10896
+ configs;
10897
+ /**
10898
+ * Stamp a serial onto a USER record THROUGH the Collection layer (so the
10899
+ * cache, indexes, and MVs stay coherent — the engine must NOT write user
10900
+ * collections at the raw adapter level). Returns false if the record is
10901
+ * gone (the engine then skips it without burning a serial). Provided by the
10902
+ * vault; unit tests pass a Map-backed double.
10903
+ */
10904
+ stamp;
10905
+ /** In-process registry: `${series}::${recordId}` → resolver for the live next() Promise. */
10906
+ waiters = /* @__PURE__ */ new Map();
10907
+ dekCache = /* @__PURE__ */ new Map();
10908
+ constructor(opts) {
10909
+ this.adapter = opts.adapter;
10910
+ this.vault = opts.vault;
10911
+ this.encrypted = opts.encrypted;
10912
+ this.getDEK = opts.getDEK;
10913
+ this.actor = opts.actor;
10914
+ this.configs = opts.configs;
10915
+ this.stamp = opts.stamp;
10916
+ }
10917
+ has(series) {
10918
+ return this.configs.has(series);
10919
+ }
10920
+ dek(collection) {
10921
+ let p = this.dekCache.get(collection);
10922
+ if (!p) {
10923
+ p = this.getDEK(collection);
10924
+ this.dekCache.set(collection, p);
10925
+ }
10926
+ return p;
10927
+ }
10928
+ async readJson(collection, id) {
10929
+ const env = await this.adapter.get(this.vault, collection, id);
10930
+ if (!env) return { env: null, value: null };
10931
+ const json = this.encrypted ? await decrypt(env._iv, env._data, await this.dek(collection)) : env._data;
10932
+ return { env, value: JSON.parse(json) };
10933
+ }
10934
+ async writeJson(collection, id, value, expectedVersion) {
10935
+ const json = JSON.stringify(value);
10936
+ let env;
10937
+ if (!this.encrypted) {
10938
+ env = { _noydb: NOYDB_FORMAT_VERSION, _v: expectedVersion + 1, _ts: (/* @__PURE__ */ new Date()).toISOString(), _iv: "", _data: json, _by: this.actor };
10939
+ } else {
10940
+ const { iv, data } = await encrypt(json, await this.dek(collection));
10941
+ env = { _noydb: NOYDB_FORMAT_VERSION, _v: expectedVersion + 1, _ts: (/* @__PURE__ */ new Date()).toISOString(), _iv: iv, _data: data, _by: this.actor };
10942
+ }
10943
+ await this.adapter.put(this.vault, collection, id, env, expectedVersion);
10944
+ }
10945
+ pendingId(series, recordId2) {
10946
+ return `${series}::${recordId2}`;
10947
+ }
10948
+ /** Current last-assigned serial for a series (0 if none). */
10949
+ async peek(series) {
10950
+ const { value } = await this.readJson(NUMBERING_HEAD_COLLECTION, series);
10951
+ return value?.lastSerial ?? 0;
10952
+ }
10953
+ /**
10954
+ * Enqueue a record for numbering: stamp it with the current store clock and
10955
+ * durably write a pending entry. The returned Promise resolves once the
10956
+ * record is durably enqueued; its `assigned` field resolves with the serial
10957
+ * at the next pass (the record's `field` is the durable source of truth —
10958
+ * `assigned` is an in-process convenience that a crash may drop).
10959
+ */
10960
+ async enqueue(series, recordId2) {
10961
+ const cfg = this.configs.get(series);
10962
+ if (!cfg) throw new NumberingUncertaintyError(series);
10963
+ if (typeof this.adapter.getStoreTime !== "function") throw new NumberingUncertaintyError(series);
10964
+ const st = await this.adapter.getStoreTime();
10965
+ const id = this.pendingId(series, recordId2);
10966
+ const { env } = await this.readJson(NUMBERING_PENDING_COLLECTION, id);
10967
+ const entry = {
10968
+ series,
10969
+ recordId: recordId2,
10970
+ collection: cfg.collection,
10971
+ field: cfg.field,
10972
+ storeEarliest: st.earliest,
10973
+ storeLatest: st.latest,
10974
+ enqueuedAt: Date.now()
10975
+ };
10976
+ await this.writeJson(NUMBERING_PENDING_COLLECTION, id, entry, env?._v ?? 0);
10977
+ const assigned = new Promise((resolve, reject) => {
10978
+ this.waiters.set(id, { resolve, reject });
10979
+ });
10980
+ return { assigned };
10981
+ }
10982
+ async listPending(series) {
10983
+ const ids = await this.adapter.list(this.vault, NUMBERING_PENDING_COLLECTION);
10984
+ const prefix = `${series}::`;
10985
+ const out = [];
10986
+ for (const id of ids) {
10987
+ if (!id.startsWith(prefix)) continue;
10988
+ const { value } = await this.readJson(NUMBERING_PENDING_COLLECTION, id);
10989
+ if (value) out.push({ id, entry: value });
10990
+ }
10991
+ return out;
10992
+ }
10993
+ /**
10994
+ * Run a numbering pass for `series`: select entries provably settled
10995
+ * (`storeLatest ≤ now.earliest` — commit-wait), order by
10996
+ * `(storeEarliest, recordId)`, assign serials after the head, stamp each
10997
+ * record's field, advance the head with one CAS, and consume the entries.
10998
+ * Idempotent/convergent: a losing concurrent pass returns `[]` and the next
10999
+ * pass reconciles. Resolves any in-process enqueue() `assigned` Promises.
11000
+ */
11001
+ async runPass(series) {
11002
+ const cfg = this.configs.get(series);
11003
+ if (!cfg) throw new NumberingUncertaintyError(series);
11004
+ if (typeof this.adapter.getStoreTime !== "function") throw new NumberingUncertaintyError(series);
11005
+ const now = await this.adapter.getStoreTime();
11006
+ const settled = (await this.listPending(series)).filter((p) => p.entry.storeLatest <= now.earliest).sort(
11007
+ (a, b) => a.entry.storeEarliest - b.entry.storeEarliest || (a.entry.recordId < b.entry.recordId ? -1 : a.entry.recordId > b.entry.recordId ? 1 : 0)
11008
+ );
11009
+ if (settled.length === 0) return [];
11010
+ const { env: headEnv, value: head } = await this.readJson(NUMBERING_HEAD_COLLECTION, series);
11011
+ let serial = head?.lastSerial ?? 0;
11012
+ const assignments = [];
11013
+ for (const { entry } of settled) {
11014
+ serial += 1;
11015
+ const ok = await this.stamp(entry.collection, entry.recordId, entry.field, serial);
11016
+ if (!ok) {
11017
+ serial -= 1;
11018
+ continue;
11019
+ }
11020
+ assignments.push({ recordId: entry.recordId, serial });
11021
+ }
11022
+ try {
11023
+ await this.writeJson(NUMBERING_HEAD_COLLECTION, series, { series, lastSerial: serial, watermark: now.earliest }, headEnv?._v ?? 0);
11024
+ } catch (err) {
11025
+ if (err instanceof ConflictError) return [];
11026
+ throw err;
11027
+ }
11028
+ for (const { id, entry } of settled) {
11029
+ await this.adapter.delete(this.vault, NUMBERING_PENDING_COLLECTION, id);
11030
+ const a = assignments.find((x) => x.recordId === entry.recordId);
11031
+ if (a) {
11032
+ this.waiters.get(id)?.resolve(a.serial);
11033
+ this.waiters.delete(id);
11034
+ }
11035
+ }
11036
+ return assignments;
11037
+ }
11038
+ };
11039
+ }
11040
+ });
11041
+
10793
11042
  // src/shadow/strategy.ts
10794
11043
  var NOT_ENABLED3, NO_SHADOW;
10795
11044
  var init_strategy7 = __esm({
@@ -11598,8 +11847,8 @@ async function derivePersistedSchema(validator) {
11598
11847
  if (kind === "Zod") {
11599
11848
  const convert = await loadZodConverter();
11600
11849
  const jsonSchema = convert(validator);
11601
- const canonical = canonicalize(jsonSchema);
11602
- const hash = await sha256Hex2(new TextEncoder().encode(canonical));
11850
+ const canonical2 = canonicalize(jsonSchema);
11851
+ const hash = await sha256Hex2(new TextEncoder().encode(canonical2));
11603
11852
  return { _noydb_schema: 1, kind, jsonSchema, hash, derivedAt };
11604
11853
  }
11605
11854
  return {
@@ -12639,12 +12888,12 @@ var init_read_only_facade = __esm({
12639
12888
 
12640
12889
  // src/derivations/strategy-hash.ts
12641
12890
  async function computeStrategyHash(source, outputKeys, derive) {
12642
- const canonical = JSON.stringify({
12891
+ const canonical2 = JSON.stringify({
12643
12892
  source,
12644
12893
  outputs: [...outputKeys].sort(),
12645
12894
  derive: derive.toString()
12646
12895
  });
12647
- const bytes = new TextEncoder().encode(canonical);
12896
+ const bytes = new TextEncoder().encode(canonical2);
12648
12897
  const digest = await crypto.subtle.digest("SHA-256", bytes);
12649
12898
  return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
12650
12899
  }
@@ -12919,6 +13168,7 @@ var init_vault = __esm({
12919
13168
  init_errors();
12920
13169
  init_archive();
12921
13170
  init_sequence();
13171
+ init_numbering();
12922
13172
  init_constants();
12923
13173
  init_entry();
12924
13174
  init_strategy3();
@@ -13086,6 +13336,10 @@ var init_vault = __esm({
13086
13336
  ledgerStore = null;
13087
13337
  /** Lazily-built atomic-sequence store. See {@link sequence}. */
13088
13338
  sequenceStore = null;
13339
+ /** Lazily-built deferred-numbering engine. See {@link runNumberingPass}. */
13340
+ deferredNumbering = null;
13341
+ /** Registered deferred-numbering series, keyed by series name. */
13342
+ numberingConfigs;
13089
13343
  /**
13090
13344
  * Background writes for persisted-schema envelopes (#schema-dump v0
13091
13345
  * slice 1). One promise per `collection({ persistJsonSchema: true })`
@@ -13172,6 +13426,7 @@ var init_vault = __esm({
13172
13426
  constructor(opts) {
13173
13427
  this.adapter = opts.adapter;
13174
13428
  this.name = opts.name;
13429
+ this.numberingConfigs = new Map((opts.numberingConfigs ?? []).map((c) => [c.series, c]));
13175
13430
  this.noydb = opts.noydb;
13176
13431
  this.keyring = opts.keyring;
13177
13432
  this.encrypted = opts.encrypted;
@@ -13846,6 +14101,18 @@ var init_vault = __esm({
13846
14101
  * ```
13847
14102
  */
13848
14103
  sequence(name) {
14104
+ if (this.numberingConfigs.has(name)) {
14105
+ const eng = this.deferred();
14106
+ return {
14107
+ next: async (opts) => {
14108
+ if (!opts?.for) {
14109
+ throw new ValidationError(`sequence("${name}") is a deferred-numbering series; call next({ for: recordId }).`);
14110
+ }
14111
+ return (await eng.enqueue(name, opts.for)).assigned;
14112
+ },
14113
+ peek: () => eng.peek(name)
14114
+ };
14115
+ }
13849
14116
  if (!this.sequenceStore) {
13850
14117
  this.sequenceStore = new SequenceStore({
13851
14118
  adapter: this.adapter,
@@ -13857,6 +14124,38 @@ var init_vault = __esm({
13857
14124
  }
13858
14125
  return this.sequenceStore.handle(name);
13859
14126
  }
14127
+ /** @internal — lazily build the deferred-numbering engine with a cache-coherent stamp. */
14128
+ deferred() {
14129
+ if (!this.deferredNumbering) {
14130
+ this.deferredNumbering = new DeferredNumberingStore({
14131
+ adapter: this.adapter,
14132
+ vault: this.name,
14133
+ encrypted: this.encrypted,
14134
+ getDEK: this.getDEK,
14135
+ actor: this.keyring.userId,
14136
+ configs: this.numberingConfigs,
14137
+ // Stamp THROUGH the Collection layer so cache/indexes/MVs stay coherent —
14138
+ // `this.collection(name)` returns the shared cached instance, so a
14139
+ // subsequent user `collection.get(id)` sees the assigned serial.
14140
+ stamp: async (collection, recordId2, field, serial) => {
14141
+ const coll = this.collection(collection);
14142
+ const rec = await coll.get(recordId2);
14143
+ if (!rec) return false;
14144
+ await coll.put(recordId2, { ...rec, [field]: serial });
14145
+ return true;
14146
+ }
14147
+ });
14148
+ }
14149
+ return this.deferredNumbering;
14150
+ }
14151
+ /**
14152
+ * Run a deferred-numbering pass for `series`: assign gap-free serials to all
14153
+ * records whose store-commit-time interval has settled, in store-time order.
14154
+ * Returns the assignments made. See {@link sequence} / `withDeferredNumbering`.
14155
+ */
14156
+ async runNumberingPass(series) {
14157
+ return this.deferred().runPass(series);
14158
+ }
13860
14159
  async compact(options = {}) {
13861
14160
  return runCompaction({
13862
14161
  adapter: this.adapter,
@@ -16910,6 +17209,54 @@ var init_classify_skip = __esm({
16910
17209
  }
16911
17210
  });
16912
17211
 
17212
+ // src/federation/cross-shard-join.ts
17213
+ function coerceKey(value) {
17214
+ if (value === null || value === void 0) return null;
17215
+ if (typeof value === "string") return value;
17216
+ if (typeof value === "number" || typeof value === "bigint") return String(value);
17217
+ return null;
17218
+ }
17219
+ function warnOnceBroadcastMiss(field, as, key) {
17220
+ const dedup = `${field}\u2192${as}:${key}`;
17221
+ if (warnedBroadcastKeys.has(dedup)) return;
17222
+ warnedBroadcastKeys.add(dedup);
17223
+ console.warn(
17224
+ `[noy-db] broadcastJoin: no "${as}" dimension row for ${field}="${key}". Attaching null. Use mode: 'cascade' to silence.`
17225
+ );
17226
+ }
17227
+ async function applyBroadcastLegs(rows, legs) {
17228
+ if (legs.length === 0) return [...rows];
17229
+ const indexes = [];
17230
+ for (const leg of legs) {
17231
+ const map = /* @__PURE__ */ new Map();
17232
+ for (const rec of await leg.from.list()) {
17233
+ const k = coerceKey(readPath(rec, leg.on));
17234
+ if (k !== null && !map.has(k)) map.set(k, rec);
17235
+ }
17236
+ indexes.push({ leg, map });
17237
+ }
17238
+ return rows.map((row) => {
17239
+ const out = { ...row };
17240
+ for (const { leg, map } of indexes) {
17241
+ const key = coerceKey(readPath(row, leg.field));
17242
+ const match = key === null ? null : map.get(key) ?? null;
17243
+ if (match === null && leg.mode === "warn") {
17244
+ warnOnceBroadcastMiss(leg.field, leg.as, key ?? "<null>");
17245
+ }
17246
+ out[leg.as] = match;
17247
+ }
17248
+ return out;
17249
+ });
17250
+ }
17251
+ var warnedBroadcastKeys;
17252
+ var init_cross_shard_join = __esm({
17253
+ "src/federation/cross-shard-join.ts"() {
17254
+ "use strict";
17255
+ init_predicate();
17256
+ warnedBroadcastKeys = /* @__PURE__ */ new Set();
17257
+ }
17258
+ });
17259
+
16913
17260
  // src/federation/cross-vault-live.ts
16914
17261
  var CrossVaultLive;
16915
17262
  var init_cross_vault_live = __esm({
@@ -17117,6 +17464,9 @@ function assertSafePartitionKey(partitionKey) {
17117
17464
  if (partitionKey.length === 0) {
17118
17465
  throw new ValidationError("partitionKey must be a non-empty string");
17119
17466
  }
17467
+ if (partitionKey === STATE_VAULT_NAME) {
17468
+ throw new ReservedVaultNameError(partitionKey);
17469
+ }
17120
17470
  if (!SAFE_PARTITION_KEY.test(partitionKey)) {
17121
17471
  throw new ValidationError(
17122
17472
  `partitionKey "${partitionKey}" contains characters outside [A-Za-z0-9._-]. Map your records to a store-safe key in sharding.keyOf.`
@@ -17133,7 +17483,9 @@ var init_vault_group = __esm({
17133
17483
  "src/federation/vault-group.ts"() {
17134
17484
  "use strict";
17135
17485
  init_errors();
17486
+ init_constants2();
17136
17487
  init_classify_skip();
17488
+ init_cross_shard_join();
17137
17489
  init_cross_vault_live();
17138
17490
  init_aggregate_across();
17139
17491
  SHARD_SEPARATOR = "--";
@@ -17156,15 +17508,38 @@ var init_vault_group = __esm({
17156
17508
  registry;
17157
17509
  sharding;
17158
17510
  template;
17511
+ /** @internal — set when the group is managed (no explicit registry). */
17512
+ stateVault;
17513
+ /** @internal */
17514
+ _attachStateVault(sv) {
17515
+ this.stateVault = sv;
17516
+ }
17159
17517
  /** Deterministic vault name for a partition key, namespaced by the group. */
17160
17518
  shardVaultId(partitionKey) {
17161
17519
  assertSafePartitionKey(partitionKey);
17162
17520
  return `${this.name}${SHARD_SEPARATOR}${partitionKey}`;
17163
17521
  }
17164
- /** All registry rows (hydrates the registry collection first). */
17522
+ /**
17523
+ * @internal — group-qualified registry record key (avoids cross-group key
17524
+ * collisions). Identical to the shard vault id by design — the registry row
17525
+ * for a shard is keyed by that shard's vault id — so it delegates to
17526
+ * `shardVaultId`, reusing its partition-key validation.
17527
+ */
17528
+ registryId(partitionKey) {
17529
+ return this.shardVaultId(partitionKey);
17530
+ }
17531
+ /**
17532
+ * Registry rows for THIS group (hydrates the registry collection first).
17533
+ * The registry may be shared across groups (the auto-wired StateManagement
17534
+ * vault holds one `vaultRegistry` for the whole instance), so rows are
17535
+ * filtered by `group` — without this, a group's fan-out reads would leak
17536
+ * across into other groups' shards. Mirrors the `${group}--` scoping that
17537
+ * `liveBinding().isRelevant` already applies to the reactive path.
17538
+ */
17165
17539
  async allRows() {
17166
17540
  await this.registry.list();
17167
- return this.registry.query().toArray();
17541
+ const rows = this.registry.query().toArray();
17542
+ return rows.filter((r) => r.group === this.name);
17168
17543
  }
17169
17544
  /** Open an existing shard and apply the template. */
17170
17545
  async openShard(partitionKey) {
@@ -17182,19 +17557,32 @@ var init_vault_group = __esm({
17182
17557
  */
17183
17558
  async createShard(partitionKey) {
17184
17559
  const vaultId = this.shardVaultId(partitionKey);
17185
- const row = await this.registry.get(partitionKey);
17560
+ const row = await this.registry.get(this.registryId(partitionKey));
17186
17561
  const provisioned = await this.db._shardVaultProvisioned(vaultId);
17187
17562
  if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
17188
17563
  if (row && provisioned) return this.openShard(partitionKey);
17189
17564
  const vault = await this.db.openVault(vaultId);
17190
17565
  this.template.configure(vault);
17191
- await this.registry.put(partitionKey, {
17566
+ await this.registry.put(this.registryId(partitionKey), {
17192
17567
  vaultId,
17193
17568
  partitionKey,
17194
17569
  templateName: this.sharding.vaultTemplate,
17195
17570
  schemaVersion: this.template.version,
17196
- createdAt: Date.now()
17571
+ createdAt: Date.now(),
17572
+ group: this.name
17197
17573
  });
17574
+ if (this.stateVault) {
17575
+ try {
17576
+ await this.stateVault.appendEvent({
17577
+ type: "shard-created",
17578
+ group: this.name,
17579
+ vaultId,
17580
+ templateName: this.sharding.vaultTemplate,
17581
+ version: this.template.version
17582
+ });
17583
+ } catch {
17584
+ }
17585
+ }
17198
17586
  return vault;
17199
17587
  }
17200
17588
  /**
@@ -17204,7 +17592,7 @@ var init_vault_group = __esm({
17204
17592
  */
17205
17593
  async shard(partitionKey) {
17206
17594
  const vaultId = this.shardVaultId(partitionKey);
17207
- const row = await this.registry.get(partitionKey);
17595
+ const row = await this.registry.get(this.registryId(partitionKey));
17208
17596
  if (!row) throw new UnknownShardError(partitionKey, this.name);
17209
17597
  const provisioned = await this.db._shardVaultProvisioned(vaultId);
17210
17598
  if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
@@ -17243,7 +17631,7 @@ var init_vault_group = __esm({
17243
17631
  /** Route a write to the shard owning `keyOf(record)`. */
17244
17632
  async put(id, record) {
17245
17633
  const key = this.group.sharding.keyOf(record);
17246
- const row = await this.group.registry.get(key);
17634
+ const row = await this.group.registry.get(this.group.registryId(key));
17247
17635
  let vault;
17248
17636
  if (!row) {
17249
17637
  if (this.group.sharding.autoCreate === false) {
@@ -17261,31 +17649,89 @@ var init_vault_group = __esm({
17261
17649
  }
17262
17650
  };
17263
17651
  ShardedQuery = class _ShardedQuery {
17264
- constructor(group, collectionName, clauses) {
17652
+ constructor(group, collectionName, clauses, coPartitionedLegs = [], broadcastLegs = []) {
17265
17653
  this.group = group;
17266
17654
  this.collectionName = collectionName;
17267
17655
  this.clauses = clauses;
17656
+ this.coPartitionedLegs = coPartitionedLegs;
17657
+ this.broadcastLegs = broadcastLegs;
17268
17658
  }
17269
17659
  group;
17270
17660
  collectionName;
17271
17661
  clauses;
17662
+ coPartitionedLegs;
17663
+ broadcastLegs;
17272
17664
  where(field, op, value) {
17273
- return new _ShardedQuery(this.group, this.collectionName, [
17274
- ...this.clauses,
17275
- { field, op, value }
17276
- ]);
17665
+ return new _ShardedQuery(
17666
+ this.group,
17667
+ this.collectionName,
17668
+ [...this.clauses, { field, op, value }],
17669
+ this.coPartitionedLegs,
17670
+ this.broadcastLegs
17671
+ );
17672
+ }
17673
+ /** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */
17674
+ crossShardJoin(field, opts) {
17675
+ const leg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy };
17676
+ return new _ShardedQuery(
17677
+ this.group,
17678
+ this.collectionName,
17679
+ this.clauses,
17680
+ [...this.coPartitionedLegs, leg],
17681
+ this.broadcastLegs
17682
+ );
17683
+ }
17684
+ /** Broadcast dimension join: enrich every merged row from a single shared collection. */
17685
+ broadcastJoin(field, opts) {
17686
+ const leg = {
17687
+ field,
17688
+ as: opts.as,
17689
+ from: opts.from,
17690
+ on: opts.on ?? "id",
17691
+ mode: opts.mode ?? "warn"
17692
+ };
17693
+ return new _ShardedQuery(
17694
+ this.group,
17695
+ this.collectionName,
17696
+ this.clauses,
17697
+ this.coPartitionedLegs,
17698
+ [...this.broadcastLegs, leg]
17699
+ );
17277
17700
  }
17278
17701
  /** @internal — fan out the where-filtered records across eligible shards. */
17279
17702
  async fanoutRecords(options = {}) {
17280
17703
  const { eligible, skipped } = await this.group.resolveEligible(options);
17704
+ const probeRow = eligible[0];
17705
+ if (this.coPartitionedLegs.length > 0 && probeRow) {
17706
+ const probe = await this.group.openShard(probeRow.partitionKey);
17707
+ this.group.template.configure(probe);
17708
+ for (const leg of this.coPartitionedLegs) {
17709
+ if (!probe.resolveRef(this.collectionName, leg.field)) {
17710
+ throw new CrossShardJoinError(
17711
+ `crossShardJoin("${leg.field}"): no ref() declared for "${leg.field}" on collection "${this.collectionName}" in template "${this.group.sharding.vaultTemplate}". Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`
17712
+ );
17713
+ }
17714
+ }
17715
+ }
17281
17716
  const across = await this.group.db.queryAcross(
17282
17717
  eligible.map((r) => r.vaultId),
17283
17718
  async (vault) => {
17284
17719
  this.group.template.configure(vault);
17285
17720
  const coll = vault.collection(this.collectionName);
17286
17721
  await coll.list();
17722
+ for (const leg of this.coPartitionedLegs) {
17723
+ const desc = vault.resolveRef(this.collectionName, leg.field);
17724
+ if (desc) await vault.collection(desc.target).list();
17725
+ }
17287
17726
  let q = coll.query();
17288
17727
  for (const c of this.clauses) q = q.where(c.field, c.op, c.value);
17728
+ for (const leg of this.coPartitionedLegs) {
17729
+ q = q.join(leg.field, {
17730
+ as: leg.as,
17731
+ ...leg.maxRows !== void 0 ? { maxRows: leg.maxRows } : {},
17732
+ ...leg.strategy ? { strategy: leg.strategy } : {}
17733
+ });
17734
+ }
17289
17735
  return q.toArray();
17290
17736
  },
17291
17737
  { concurrency: options.concurrency ?? 1, create: false }
@@ -17297,10 +17743,11 @@ var init_vault_group = __esm({
17297
17743
  }
17298
17744
  return { records: results, skippedVaults: skipped };
17299
17745
  }
17300
- /** Fan out across eligible shards and merge results. */
17746
+ /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
17301
17747
  async toArray(options = {}) {
17302
17748
  const { records, skippedVaults } = await this.fanoutRecords(options);
17303
- return { results: records, skippedVaults };
17749
+ const results = await applyBroadcastLegs(records, this.broadcastLegs);
17750
+ return { results, skippedVaults };
17304
17751
  }
17305
17752
  /** @internal — build the change-subscription + relevance binding for this query's group+collection. */
17306
17753
  liveBinding() {
@@ -17314,8 +17761,17 @@ var init_vault_group = __esm({
17314
17761
  isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`)
17315
17762
  };
17316
17763
  }
17764
+ /** @internal — joined queries don't support reactive/aggregate surfaces in v1. */
17765
+ assertNoJoinLegs(surface) {
17766
+ if (this.coPartitionedLegs.length || this.broadcastLegs.length) {
17767
+ throw new CrossShardJoinError(
17768
+ `${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin legs in v1. Use toArray() for joined cross-shard queries.`
17769
+ );
17770
+ }
17771
+ }
17317
17772
  /** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */
17318
17773
  live(options = {}) {
17774
+ this.assertNoJoinLegs("live");
17319
17775
  const bind = this.liveBinding();
17320
17776
  const core = new CrossVaultLive({
17321
17777
  ...bind,
@@ -17343,10 +17799,12 @@ var init_vault_group = __esm({
17343
17799
  }
17344
17800
  /** One-shot distributed aggregate — central reduce over all shard records. */
17345
17801
  aggregate(spec) {
17802
+ this.assertNoJoinLegs("aggregate");
17346
17803
  return new CrossVaultAggregation(this, spec, this.liveBinding());
17347
17804
  }
17348
17805
  /** Begin a grouped cross-shard aggregate. */
17349
17806
  groupBy(field) {
17807
+ this.assertNoJoinLegs("groupBy");
17350
17808
  return new ShardedGroupedQuery(this, field);
17351
17809
  }
17352
17810
  };
@@ -17369,6 +17827,159 @@ var init_vault_group = __esm({
17369
17827
  }
17370
17828
  });
17371
17829
 
17830
+ // src/federation/schema-manifest.ts
17831
+ function captureBlueprint(configure) {
17832
+ const recorded = [];
17833
+ const collectionStub = new Proxy(
17834
+ {},
17835
+ {
17836
+ get: () => () => collectionStub
17837
+ }
17838
+ );
17839
+ const proxy = new Proxy(
17840
+ {},
17841
+ {
17842
+ get: (_t, prop) => {
17843
+ if (prop === "collection") {
17844
+ return (name, opts) => {
17845
+ recorded.push({
17846
+ name,
17847
+ indexes: opts?.indexes ?? [],
17848
+ persistJsonSchema: !!opts?.persistJsonSchema
17849
+ });
17850
+ return collectionStub;
17851
+ };
17852
+ }
17853
+ return () => proxy;
17854
+ }
17855
+ }
17856
+ );
17857
+ configure(proxy);
17858
+ const sorted = [...recorded].sort((a, b) => a.name.localeCompare(b.name));
17859
+ const indexes = {};
17860
+ const persistJsonSchema = [];
17861
+ for (const c of sorted) {
17862
+ indexes[c.name] = c.indexes;
17863
+ if (c.persistJsonSchema) persistJsonSchema.push(c.name);
17864
+ }
17865
+ return {
17866
+ // `persistJsonSchema` is already name-sorted: it is populated while
17867
+ // iterating `sorted` (collections in name order).
17868
+ collections: sorted.map((c) => c.name),
17869
+ indexes,
17870
+ persistJsonSchema
17871
+ };
17872
+ }
17873
+ function canonical(value) {
17874
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
17875
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
17876
+ const obj = value;
17877
+ const keys = Object.keys(obj).sort();
17878
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(obj[k])}`).join(",")}}`;
17879
+ }
17880
+ async function fingerprintBlueprint(bp) {
17881
+ return sha256Hex2(new TextEncoder().encode(canonical(bp)));
17882
+ }
17883
+ var init_schema_manifest = __esm({
17884
+ "src/federation/schema-manifest.ts"() {
17885
+ "use strict";
17886
+ init_crypto();
17887
+ }
17888
+ });
17889
+
17890
+ // src/federation/state-vault.ts
17891
+ var state_vault_exports = {};
17892
+ __export(state_vault_exports, {
17893
+ STATE_VAULT_NAME: () => STATE_VAULT_NAME,
17894
+ StateManagementVault: () => StateManagementVault
17895
+ });
17896
+ var REGISTRY, MANIFEST, EVENTS, StateManagementVault;
17897
+ var init_state_vault = __esm({
17898
+ "src/federation/state-vault.ts"() {
17899
+ "use strict";
17900
+ init_schema_manifest();
17901
+ init_constants2();
17902
+ init_ulid();
17903
+ init_constants2();
17904
+ REGISTRY = "vaultRegistry";
17905
+ MANIFEST = "schemaManifest";
17906
+ EVENTS = "deploymentEvents";
17907
+ StateManagementVault = class _StateManagementVault {
17908
+ constructor(registry, schemaManifest, events) {
17909
+ this.registry = registry;
17910
+ this.schemaManifest = schemaManifest;
17911
+ this.#events = events;
17912
+ }
17913
+ registry;
17914
+ schemaManifest;
17915
+ /**
17916
+ * The append-only deployment-events log is kept truly private so the raw
17917
+ * mutable Collection is never surfaced — events may only be written via
17918
+ * `appendEvent` and read via `queryEvents`. (`registry` and
17919
+ * `schemaManifest` are deliberately public: consumers read and write them.)
17920
+ */
17921
+ #events;
17922
+ /** Idempotently open the reserved state vault and bind the three control-plane collections. */
17923
+ static async open(db) {
17924
+ const vault = await db.openVault(STATE_VAULT_NAME);
17925
+ return new _StateManagementVault(
17926
+ vault.collection(REGISTRY),
17927
+ vault.collection(MANIFEST),
17928
+ vault.collection(EVENTS)
17929
+ );
17930
+ }
17931
+ /** Read-only query over the append-only deployment-events log. */
17932
+ queryEvents() {
17933
+ return this.#events.query();
17934
+ }
17935
+ /**
17936
+ * Append a deployment event with a fresh unique (ULID) id. This is the
17937
+ * only write path to the events log; no update/delete is exposed.
17938
+ * Callers should treat failures as non-fatal — this method does not
17939
+ * swallow errors, so wrap the call site in try/catch where appropriate.
17940
+ */
17941
+ async appendEvent(event) {
17942
+ const ts = event.ts ?? Date.now();
17943
+ const id = generateULID();
17944
+ await this.#events.put(id, { ...event, id, ts });
17945
+ }
17946
+ /**
17947
+ * Ensure a manifest row exists for `(templateName, template.version)`.
17948
+ * Safe to call repeatedly: the `fingerprint` is a deterministic hash of
17949
+ * the template's declared shape (stable across calls), though each call
17950
+ * refreshes `recordedAt`.
17951
+ */
17952
+ async recordManifest(templateName, template) {
17953
+ const bp = captureBlueprint(template.configure);
17954
+ const fingerprint = await fingerprintBlueprint(bp);
17955
+ await this.schemaManifest.put(`${templateName}:${template.version}`, {
17956
+ templateName,
17957
+ version: template.version,
17958
+ collections: bp.collections,
17959
+ indexes: bp.indexes,
17960
+ persistJsonSchema: bp.persistJsonSchema,
17961
+ fingerprint,
17962
+ recordedAt: Date.now()
17963
+ });
17964
+ return fingerprint;
17965
+ }
17966
+ /**
17967
+ * True when `template`'s current declared shape does not match the recorded
17968
+ * manifest for `(templateName, template.version)`. Because shards carry no
17969
+ * schema state independent of their template, this catches "a template's
17970
+ * shape changed without bumping `version`" — not independent per-shard drift.
17971
+ * A missing manifest is treated as drift (nothing to verify against).
17972
+ */
17973
+ async detectDrift(templateName, template) {
17974
+ const row = await this.schemaManifest.get(`${templateName}:${template.version}`);
17975
+ if (!row) return true;
17976
+ const current = await fingerprintBlueprint(captureBlueprint(template.configure));
17977
+ return current !== row.fingerprint;
17978
+ }
17979
+ };
17980
+ }
17981
+ });
17982
+
17372
17983
  // src/noydb.ts
17373
17984
  var noydb_exports = {};
17374
17985
  __export(noydb_exports, {
@@ -17428,6 +18039,7 @@ var init_noydb = __esm({
17428
18039
  "src/noydb.ts"() {
17429
18040
  "use strict";
17430
18041
  init_errors();
18042
+ init_constants2();
17431
18043
  init_storage3();
17432
18044
  init_rotate_recover();
17433
18045
  init_peer_recover();
@@ -17767,6 +18379,7 @@ var init_noydb = __esm({
17767
18379
  ...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
17768
18380
  ...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
17769
18381
  ...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
18382
+ ...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
17770
18383
  locale: opts?.locale,
17771
18384
  // Thread the translator hook so Collection.put() can invoke it
17772
18385
  plaintextTranslator: this.options.plaintextTranslator ? (text, from, to, field, collection) => this.invokeTranslator(text, from, to, field, collection) : void 0,
@@ -17820,7 +18433,8 @@ var init_noydb = __esm({
17820
18433
  ...this.options.historyStrategy !== void 0 ? { historyStrategy: this.options.historyStrategy } : {},
17821
18434
  ...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
17822
18435
  ...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
17823
- ...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {}
18436
+ ...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
18437
+ ...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {}
17824
18438
  });
17825
18439
  this.vaultCache.set(name, comp2);
17826
18440
  return comp2;
@@ -17850,6 +18464,7 @@ var init_noydb = __esm({
17850
18464
  ...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
17851
18465
  ...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
17852
18466
  ...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
18467
+ ...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
17853
18468
  emitter: this.emitter
17854
18469
  });
17855
18470
  this.vaultCache.set(name, comp);
@@ -18168,10 +18783,39 @@ var init_noydb = __esm({
18168
18783
  */
18169
18784
  async openVaultGroup(name, opts) {
18170
18785
  if (this.closed) throw new ValidationError("Instance is closed");
18786
+ if (name === STATE_VAULT_NAME) throw new ReservedVaultNameError(name);
18171
18787
  const template = this.vaultTemplates.get(opts.sharding.vaultTemplate);
18172
18788
  if (!template) throw new VaultTemplateNotFoundError(opts.sharding.vaultTemplate);
18173
18789
  const { VaultGroup: VaultGroup2 } = await Promise.resolve().then(() => (init_vault_group(), vault_group_exports));
18174
- return new VaultGroup2(this, name, opts.registry, opts.sharding, template);
18790
+ const { StateManagementVault: StateManagementVault2 } = await Promise.resolve().then(() => (init_state_vault(), state_vault_exports));
18791
+ const stateVault = opts.registry ? void 0 : await StateManagementVault2.open(this);
18792
+ const registry = opts.registry ?? stateVault.registry;
18793
+ const group = new VaultGroup2(this, name, registry, opts.sharding, template);
18794
+ if (stateVault) {
18795
+ group._attachStateVault(stateVault);
18796
+ await stateVault.recordManifest(opts.sharding.vaultTemplate, template);
18797
+ try {
18798
+ await stateVault.appendEvent({
18799
+ type: "manifest-recorded",
18800
+ group: name,
18801
+ templateName: opts.sharding.vaultTemplate,
18802
+ version: template.version
18803
+ });
18804
+ await stateVault.appendEvent({ type: "group-opened", group: name });
18805
+ } catch {
18806
+ }
18807
+ }
18808
+ return group;
18809
+ }
18810
+ /**
18811
+ * Open the reserved StateManagement control-plane vault (registry +
18812
+ * schema-manifest + deployment-events). Lazy-loaded so the federation
18813
+ * chunk stays out of the core graph until used.
18814
+ */
18815
+ async openStateManagementVault() {
18816
+ if (this.closed) throw new ValidationError("Instance is closed");
18817
+ const { StateManagementVault: StateManagementVault2 } = await Promise.resolve().then(() => (init_state_vault(), state_vault_exports));
18818
+ return StateManagementVault2.open(this);
18175
18819
  }
18176
18820
  /**
18177
18821
  * @internal — true when an encrypted shard vault is provisioned