@noy-db/hub 0.2.0-pre.23 → 0.2.0-pre.24

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 (285) hide show
  1. package/dist/aggregate/index.cjs.map +1 -1
  2. package/dist/aggregate/index.d.cts +3 -3
  3. package/dist/aggregate/index.d.ts +3 -3
  4. package/dist/aggregate/index.js +5 -5
  5. package/dist/attestation/index.cjs.map +1 -1
  6. package/dist/attestation/index.d.cts +4 -4
  7. package/dist/attestation/index.d.ts +4 -4
  8. package/dist/attestation/index.js +6 -6
  9. package/dist/blobs/index.cjs.map +1 -1
  10. package/dist/blobs/index.d.cts +6 -6
  11. package/dist/blobs/index.d.ts +6 -6
  12. package/dist/blobs/index.js +6 -6
  13. package/dist/bundle/index.cjs +617 -1202
  14. package/dist/bundle/index.cjs.map +1 -1
  15. package/dist/bundle/index.d.cts +15 -6
  16. package/dist/bundle/index.d.ts +15 -6
  17. package/dist/bundle/index.js +58 -193
  18. package/dist/bundle/index.js.map +1 -1
  19. package/dist/{chunk-CQYEDODS.js → chunk-35U5YNRR.js} +3 -3
  20. package/dist/{chunk-NV4IHBZS.js → chunk-3XJU3OHE.js} +5 -5
  21. package/dist/{chunk-OTWT6BAJ.js → chunk-4BB4T3O7.js} +12 -2
  22. package/dist/chunk-4BB4T3O7.js.map +1 -0
  23. package/dist/{chunk-IVZWHIEK.js → chunk-4HEGG5NJ.js} +5 -5
  24. package/dist/{chunk-WE2BUQD2.js → chunk-4TCMCCC3.js} +5 -3
  25. package/dist/{chunk-5YTXYPES.js → chunk-5A2FVGHT.js} +5 -5
  26. package/dist/{chunk-NSXNXLYM.js → chunk-5GZC2ZM3.js} +2 -2
  27. package/dist/{chunk-JYNH4FIM.js → chunk-77WF53XY.js} +4 -4
  28. package/dist/{chunk-O5XKZCUD.js → chunk-7X4EF35A.js} +5 -5
  29. package/dist/{chunk-SQKAECUL.js → chunk-7ZCTUI26.js} +2 -2
  30. package/dist/{chunk-J6RGRZOY.js → chunk-AO3QSMCU.js} +2 -2
  31. package/dist/{chunk-JDCPRJVS.js → chunk-AONK5GCC.js} +4 -4
  32. package/dist/{chunk-FRRJIUSI.js → chunk-B5CSNGSE.js} +17 -9
  33. package/dist/chunk-B5CSNGSE.js.map +1 -0
  34. package/dist/{chunk-IY24WS2P.js → chunk-BCMHJYVT.js} +4 -4
  35. package/dist/{chunk-IY24WS2P.js.map → chunk-BCMHJYVT.js.map} +1 -1
  36. package/dist/{chunk-TYMDCIQM.js → chunk-C472BRJ4.js} +4 -4
  37. package/dist/{chunk-MBXKRHSS.js → chunk-CCNRFAL3.js} +2 -2
  38. package/dist/{chunk-BZW5IL43.js → chunk-DCA2BDHA.js} +4 -4
  39. package/dist/{chunk-JBBWALNI.js → chunk-DCICHSRS.js} +2 -2
  40. package/dist/{chunk-2XA2ZML4.js → chunk-FG6IQ3ZL.js} +3 -3
  41. package/dist/{chunk-C2RJVZZL.js → chunk-G4GW5VOS.js} +2 -2
  42. package/dist/{chunk-U2XSUCDF.js → chunk-GEWIFM4J.js} +2 -2
  43. package/dist/{chunk-TNH5SLCD.js → chunk-HD4QCT2O.js} +2 -2
  44. package/dist/{chunk-I3IYTUUI.js → chunk-HHJ5DZCZ.js} +3 -3
  45. package/dist/{chunk-6QAZ5O6X.js → chunk-IEIADIPM.js} +2 -2
  46. package/dist/{chunk-YPIOFSN3.js → chunk-IHAISFXP.js} +2 -2
  47. package/dist/{chunk-GJTKMME7.js → chunk-JKM2AVVH.js} +2 -2
  48. package/dist/{chunk-EYK72OTL.js → chunk-JRMOSIH4.js} +5 -5
  49. package/dist/chunk-JRMOSIH4.js.map +1 -0
  50. package/dist/{chunk-S45MDEEF.js → chunk-LMWVNF6X.js} +2 -2
  51. package/dist/{chunk-TA6HPKWQ.js → chunk-LR7CODVN.js} +1 -1
  52. package/dist/chunk-LR7CODVN.js.map +1 -0
  53. package/dist/{chunk-TAMRU7A2.js → chunk-OKV7S356.js} +4 -4
  54. package/dist/{chunk-HYJMAV53.js → chunk-OWAMTSAI.js} +93 -93
  55. package/dist/chunk-OWAMTSAI.js.map +1 -0
  56. package/dist/{chunk-IW4L4X65.js → chunk-P5A4E53B.js} +2 -2
  57. package/dist/{chunk-JOK73NDT.js → chunk-P7OL22JP.js} +3 -3
  58. package/dist/{chunk-P65YMN5V.js → chunk-QOXZM3L2.js} +407 -162
  59. package/dist/chunk-QOXZM3L2.js.map +1 -0
  60. package/dist/chunk-R43KS34V.js +399 -0
  61. package/dist/chunk-R43KS34V.js.map +1 -0
  62. package/dist/{chunk-TGIJTNM3.js → chunk-R5ZECURV.js} +2 -2
  63. package/dist/{chunk-KOAJ3TZM.js → chunk-RFEXGW3L.js} +2 -2
  64. package/dist/{chunk-F5ILTHMU.js → chunk-RNQPDV75.js} +5 -5
  65. package/dist/{chunk-WWVJXBOT.js → chunk-SGM7CK7R.js} +5 -5
  66. package/dist/{chunk-7MRT7EPB.js → chunk-SOQE5DUV.js} +3 -3
  67. package/dist/{chunk-F5GWNSE2.js → chunk-TOMSCJRV.js} +3 -3
  68. package/dist/{chunk-F5GWNSE2.js.map → chunk-TOMSCJRV.js.map} +1 -1
  69. package/dist/{chunk-ZONKSLF2.js → chunk-TQMQZOMX.js} +2 -2
  70. package/dist/{chunk-3HNKR65T.js → chunk-U6LTLN7O.js} +3 -3
  71. package/dist/{chunk-UU6M64HI.js → chunk-UAK2AMO2.js} +4 -4
  72. package/dist/{chunk-37VGJM3T.js → chunk-WQ3KAGOV.js} +2 -2
  73. package/dist/{chunk-C6W5KVDV.js → chunk-XC32SZPW.js} +35 -35
  74. package/dist/chunk-XC32SZPW.js.map +1 -0
  75. package/dist/{chunk-AI4USDRI.js → chunk-XQO4TAJS.js} +4 -4
  76. package/dist/{chunk-SQOK5UM6.js → chunk-ZBENTRFS.js} +2 -2
  77. package/dist/{chunk-6QE4DUYC.js → chunk-ZDITTESU.js} +2 -2
  78. package/dist/consent/index.cjs.map +1 -1
  79. package/dist/consent/index.d.cts +5 -5
  80. package/dist/consent/index.d.ts +5 -5
  81. package/dist/consent/index.js +3 -3
  82. package/dist/{crypto-456N7UVX.js → crypto-2LU6XUFF.js} +3 -3
  83. package/dist/{delegation-DP4COTXB.js → delegation-6ABSJGXV.js} +5 -5
  84. package/dist/derivations/index.cjs.map +1 -1
  85. package/dist/derivations/index.d.cts +6 -6
  86. package/dist/derivations/index.d.ts +6 -6
  87. package/dist/derivations/index.js +4 -4
  88. package/dist/{dev-unlock-DzDzLTdZ.d.ts → dev-unlock-BlhRHr6p.d.ts} +1 -1
  89. package/dist/{dev-unlock-Bw7iBD1D.d.cts → dev-unlock-DURe4IvF.d.cts} +1 -1
  90. package/dist/{errors-Dkc_fi-S.d.cts → errors-B2tUcRPg.d.cts} +19 -5
  91. package/dist/{errors-Dkc_fi-S.d.ts → errors-B2tUcRPg.d.ts} +19 -5
  92. package/dist/executor-JKMSEB34.js +8 -0
  93. package/dist/executor-UYXSQB4D.js +12 -0
  94. package/dist/executor-VJSCTBWY.js +8 -0
  95. package/dist/{fanout-sidecar-YXNAEZ33.js → fanout-sidecar-ZQT4Y7PF.js} +2 -2
  96. package/dist/forget/index.js +4 -4
  97. package/dist/guards/index.cjs.map +1 -1
  98. package/dist/guards/index.d.cts +6 -6
  99. package/dist/guards/index.d.ts +6 -6
  100. package/dist/guards/index.js +6 -6
  101. package/dist/{hash-C52X_-m5.d.cts → hash-CqRZfDZH.d.cts} +1 -1
  102. package/dist/{hash-DepR-xVc.d.ts → hash-cF4iWaBV.d.ts} +1 -1
  103. package/dist/history/index.cjs.map +1 -1
  104. package/dist/history/index.d.cts +6 -6
  105. package/dist/history/index.d.ts +6 -6
  106. package/dist/history/index.js +5 -5
  107. package/dist/i18n/index.cjs.map +1 -1
  108. package/dist/i18n/index.d.cts +5 -5
  109. package/dist/i18n/index.d.ts +5 -5
  110. package/dist/i18n/index.js +6 -6
  111. package/dist/index-B8MoIS7B.d.ts +70 -0
  112. package/dist/{index-Bm9hIY7t.d.ts → index-BLff_E35.d.ts} +2 -2
  113. package/dist/{index-tZqVB9g5.d.cts → index-BthnP2MA.d.cts} +2 -2
  114. package/dist/index-da0M3NnR.d.cts +70 -0
  115. package/dist/index.cjs +25907 -25557
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.cts +135 -80
  118. package/dist/index.d.ts +135 -80
  119. package/dist/index.js +78 -51
  120. package/dist/index.js.map +1 -1
  121. package/dist/indexing/index.cjs.map +1 -1
  122. package/dist/indexing/index.js +4 -4
  123. package/dist/issue-KLRMW5DH.js +12 -0
  124. package/dist/kernel/index.cjs +657 -0
  125. package/dist/kernel/index.cjs.map +1 -0
  126. package/dist/kernel/index.d.cts +11 -0
  127. package/dist/kernel/index.d.ts +11 -0
  128. package/dist/kernel/index.js +40 -0
  129. package/dist/{ledger-I7JUYP4L.js → ledger-VOS2X3WJ.js} +5 -5
  130. package/dist/materialized-views/index.cjs.map +1 -1
  131. package/dist/materialized-views/index.d.cts +6 -6
  132. package/dist/materialized-views/index.d.ts +6 -6
  133. package/dist/materialized-views/index.js +8 -8
  134. package/dist/{mime-magic-Dejetix_.d.ts → mime-magic-BswIvWkR.d.ts} +1 -1
  135. package/dist/{mime-magic-Cxf9B_Dm.d.cts → mime-magic-CCrP-iXJ.d.cts} +1 -1
  136. package/dist/{ulid-Bg-IBJyA.d.cts → multi-bundle-6s5nKAZX.d.ts} +114 -58
  137. package/dist/{ulid-Dwt3JEcy.d.ts → multi-bundle-WhYiJEgV.d.cts} +114 -58
  138. package/dist/noydb-2PI2ZBX6.js +38 -0
  139. package/dist/overlay-views/index.cjs.map +1 -1
  140. package/dist/overlay-views/index.d.cts +6 -6
  141. package/dist/overlay-views/index.d.ts +6 -6
  142. package/dist/overlay-views/index.js +4 -4
  143. package/dist/periods/index.cjs.map +1 -1
  144. package/dist/periods/index.d.cts +5 -5
  145. package/dist/periods/index.d.ts +5 -5
  146. package/dist/periods/index.js +5 -5
  147. package/dist/{public-envelope-5XRTUNKF.js → public-envelope-IJJMWSTJ.js} +4 -4
  148. package/dist/query/index.cjs.map +1 -1
  149. package/dist/query/index.d.cts +3 -3
  150. package/dist/query/index.d.ts +3 -3
  151. package/dist/query/index.js +7 -7
  152. package/dist/registry-GAIFVWXF.js +8 -0
  153. package/dist/registry-J77ZUQ7G.js +8 -0
  154. package/dist/{registry-NWHOLD5M.js → registry-JGEVJ6YC.js} +3 -3
  155. package/dist/{revoke-5IEK22KT.js → revoke-WUY4AYRJ.js} +6 -6
  156. package/dist/sealed-record/index.cjs.map +1 -1
  157. package/dist/sealed-record/index.d.cts +1 -1
  158. package/dist/sealed-record/index.d.ts +1 -1
  159. package/dist/sealed-record/index.js +2 -2
  160. package/dist/session/index.cjs.map +1 -1
  161. package/dist/session/index.d.cts +6 -6
  162. package/dist/session/index.d.ts +6 -6
  163. package/dist/session/index.js +3 -3
  164. package/dist/shadow/index.cjs.map +1 -1
  165. package/dist/shadow/index.d.cts +5 -5
  166. package/dist/shadow/index.d.ts +5 -5
  167. package/dist/shadow/index.js +2 -2
  168. package/dist/{signer-I6YARZQA.js → signer-UJF3CFDC.js} +5 -5
  169. package/dist/snapshots/index.cjs.map +1 -1
  170. package/dist/snapshots/index.d.cts +5 -5
  171. package/dist/snapshots/index.d.ts +5 -5
  172. package/dist/snapshots/index.js +4 -4
  173. package/dist/{stale-CPESGAPL.js → stale-PW6VBGSP.js} +2 -2
  174. package/dist/store/index.cjs.map +1 -1
  175. package/dist/store/index.d.cts +5 -5
  176. package/dist/store/index.d.ts +5 -5
  177. package/dist/store/index.js +2 -2
  178. package/dist/{strategy-WtB-jXYv.d.cts → strategy-BWmgRPA2.d.cts} +1 -1
  179. package/dist/{strategy-54eIwox5.d.ts → strategy-D47TC5X6.d.ts} +1 -1
  180. package/dist/sync/index.cjs.map +1 -1
  181. package/dist/sync/index.d.cts +4 -4
  182. package/dist/sync/index.d.ts +4 -4
  183. package/dist/sync/index.js +4 -4
  184. package/dist/team/index.cjs +10 -3
  185. package/dist/team/index.cjs.map +1 -1
  186. package/dist/team/index.d.cts +5 -5
  187. package/dist/team/index.d.ts +5 -5
  188. package/dist/team/index.js +8 -8
  189. package/dist/{transition-guard-BcLyTGYq.d.cts → transition-guard-C3NxfVKk.d.cts} +1 -1
  190. package/dist/{transition-guard-Ctxapq1b.d.ts → transition-guard-CQH5263l.d.ts} +1 -1
  191. package/dist/tx/index.cjs +1 -1
  192. package/dist/tx/index.cjs.map +1 -1
  193. package/dist/tx/index.d.cts +5 -5
  194. package/dist/tx/index.d.ts +5 -5
  195. package/dist/tx/index.js +3 -3
  196. package/dist/{types-DONgts0n.d.ts → types-BGRX6sPT.d.ts} +288 -578
  197. package/dist/{types-Bhs2i_Ll.d.cts → types-COQ6qJZh.d.cts} +288 -578
  198. package/dist/ulid-DRH25k3y.d.cts +66 -0
  199. package/dist/ulid-DRH25k3y.d.ts +66 -0
  200. package/dist/util/index.cjs.map +1 -1
  201. package/dist/util/index.js +1 -1
  202. package/dist/{with-materialized-view-CyVLOr09.d.ts → with-materialized-view-Cj-6fuav.d.ts} +1 -1
  203. package/dist/{with-materialized-view-BYb3p9wT.d.cts → with-materialized-view-D4U-KrBH.d.cts} +1 -1
  204. package/dist/{with-overlayed-view-LGrQ984e.d.cts → with-overlayed-view-BKjdUPRx.d.cts} +1 -1
  205. package/dist/{with-overlayed-view-BhLRxqwI.d.ts → with-overlayed-view-COp_7EEy.d.ts} +1 -1
  206. package/dist/{with-rollup-CO8ibRcK.d.ts → with-rollup-B1_ZjG02.d.ts} +1 -1
  207. package/dist/{with-rollup-Bj8c7ttB.d.cts → with-rollup-C-Bok_o2.d.cts} +1 -1
  208. package/package.json +13 -3
  209. package/dist/chunk-C6W5KVDV.js.map +0 -1
  210. package/dist/chunk-EYK72OTL.js.map +0 -1
  211. package/dist/chunk-FRRJIUSI.js.map +0 -1
  212. package/dist/chunk-HYJMAV53.js.map +0 -1
  213. package/dist/chunk-JTI57WRT.js +0 -164
  214. package/dist/chunk-JTI57WRT.js.map +0 -1
  215. package/dist/chunk-OTWT6BAJ.js.map +0 -1
  216. package/dist/chunk-P65YMN5V.js.map +0 -1
  217. package/dist/chunk-TA6HPKWQ.js.map +0 -1
  218. package/dist/chunk-ZC7J6ZYV.js +0 -7
  219. package/dist/chunk-ZC7J6ZYV.js.map +0 -1
  220. package/dist/executor-4IEW4KG5.js +0 -8
  221. package/dist/executor-KYJCJCIN.js +0 -12
  222. package/dist/executor-W7VIBOBZ.js +0 -8
  223. package/dist/issue-JXC6T2QR.js +0 -12
  224. package/dist/noydb-VGR2HLDB.js +0 -39
  225. package/dist/registry-ATRHOG5B.js +0 -8
  226. package/dist/registry-LEHB26TY.js +0 -8
  227. package/dist/state-vault-JR3CFGNP.js +0 -14
  228. package/dist/vault-group-BB246VIM.js +0 -804
  229. package/dist/vault-group-BB246VIM.js.map +0 -1
  230. /package/dist/{chunk-CQYEDODS.js.map → chunk-35U5YNRR.js.map} +0 -0
  231. /package/dist/{chunk-NV4IHBZS.js.map → chunk-3XJU3OHE.js.map} +0 -0
  232. /package/dist/{chunk-IVZWHIEK.js.map → chunk-4HEGG5NJ.js.map} +0 -0
  233. /package/dist/{chunk-WE2BUQD2.js.map → chunk-4TCMCCC3.js.map} +0 -0
  234. /package/dist/{chunk-5YTXYPES.js.map → chunk-5A2FVGHT.js.map} +0 -0
  235. /package/dist/{chunk-NSXNXLYM.js.map → chunk-5GZC2ZM3.js.map} +0 -0
  236. /package/dist/{chunk-JYNH4FIM.js.map → chunk-77WF53XY.js.map} +0 -0
  237. /package/dist/{chunk-O5XKZCUD.js.map → chunk-7X4EF35A.js.map} +0 -0
  238. /package/dist/{chunk-SQKAECUL.js.map → chunk-7ZCTUI26.js.map} +0 -0
  239. /package/dist/{chunk-J6RGRZOY.js.map → chunk-AO3QSMCU.js.map} +0 -0
  240. /package/dist/{chunk-JDCPRJVS.js.map → chunk-AONK5GCC.js.map} +0 -0
  241. /package/dist/{chunk-TYMDCIQM.js.map → chunk-C472BRJ4.js.map} +0 -0
  242. /package/dist/{chunk-MBXKRHSS.js.map → chunk-CCNRFAL3.js.map} +0 -0
  243. /package/dist/{chunk-BZW5IL43.js.map → chunk-DCA2BDHA.js.map} +0 -0
  244. /package/dist/{chunk-JBBWALNI.js.map → chunk-DCICHSRS.js.map} +0 -0
  245. /package/dist/{chunk-2XA2ZML4.js.map → chunk-FG6IQ3ZL.js.map} +0 -0
  246. /package/dist/{chunk-C2RJVZZL.js.map → chunk-G4GW5VOS.js.map} +0 -0
  247. /package/dist/{chunk-U2XSUCDF.js.map → chunk-GEWIFM4J.js.map} +0 -0
  248. /package/dist/{chunk-TNH5SLCD.js.map → chunk-HD4QCT2O.js.map} +0 -0
  249. /package/dist/{chunk-I3IYTUUI.js.map → chunk-HHJ5DZCZ.js.map} +0 -0
  250. /package/dist/{chunk-6QAZ5O6X.js.map → chunk-IEIADIPM.js.map} +0 -0
  251. /package/dist/{chunk-YPIOFSN3.js.map → chunk-IHAISFXP.js.map} +0 -0
  252. /package/dist/{chunk-GJTKMME7.js.map → chunk-JKM2AVVH.js.map} +0 -0
  253. /package/dist/{chunk-S45MDEEF.js.map → chunk-LMWVNF6X.js.map} +0 -0
  254. /package/dist/{chunk-TAMRU7A2.js.map → chunk-OKV7S356.js.map} +0 -0
  255. /package/dist/{chunk-IW4L4X65.js.map → chunk-P5A4E53B.js.map} +0 -0
  256. /package/dist/{chunk-JOK73NDT.js.map → chunk-P7OL22JP.js.map} +0 -0
  257. /package/dist/{chunk-TGIJTNM3.js.map → chunk-R5ZECURV.js.map} +0 -0
  258. /package/dist/{chunk-KOAJ3TZM.js.map → chunk-RFEXGW3L.js.map} +0 -0
  259. /package/dist/{chunk-F5ILTHMU.js.map → chunk-RNQPDV75.js.map} +0 -0
  260. /package/dist/{chunk-WWVJXBOT.js.map → chunk-SGM7CK7R.js.map} +0 -0
  261. /package/dist/{chunk-7MRT7EPB.js.map → chunk-SOQE5DUV.js.map} +0 -0
  262. /package/dist/{chunk-ZONKSLF2.js.map → chunk-TQMQZOMX.js.map} +0 -0
  263. /package/dist/{chunk-3HNKR65T.js.map → chunk-U6LTLN7O.js.map} +0 -0
  264. /package/dist/{chunk-UU6M64HI.js.map → chunk-UAK2AMO2.js.map} +0 -0
  265. /package/dist/{chunk-37VGJM3T.js.map → chunk-WQ3KAGOV.js.map} +0 -0
  266. /package/dist/{chunk-AI4USDRI.js.map → chunk-XQO4TAJS.js.map} +0 -0
  267. /package/dist/{chunk-SQOK5UM6.js.map → chunk-ZBENTRFS.js.map} +0 -0
  268. /package/dist/{chunk-6QE4DUYC.js.map → chunk-ZDITTESU.js.map} +0 -0
  269. /package/dist/{crypto-456N7UVX.js.map → crypto-2LU6XUFF.js.map} +0 -0
  270. /package/dist/{delegation-DP4COTXB.js.map → delegation-6ABSJGXV.js.map} +0 -0
  271. /package/dist/{executor-4IEW4KG5.js.map → executor-JKMSEB34.js.map} +0 -0
  272. /package/dist/{executor-KYJCJCIN.js.map → executor-UYXSQB4D.js.map} +0 -0
  273. /package/dist/{executor-W7VIBOBZ.js.map → executor-VJSCTBWY.js.map} +0 -0
  274. /package/dist/{fanout-sidecar-YXNAEZ33.js.map → fanout-sidecar-ZQT4Y7PF.js.map} +0 -0
  275. /package/dist/{issue-JXC6T2QR.js.map → issue-KLRMW5DH.js.map} +0 -0
  276. /package/dist/{ledger-I7JUYP4L.js.map → kernel/index.js.map} +0 -0
  277. /package/dist/{noydb-VGR2HLDB.js.map → ledger-VOS2X3WJ.js.map} +0 -0
  278. /package/dist/{public-envelope-5XRTUNKF.js.map → noydb-2PI2ZBX6.js.map} +0 -0
  279. /package/dist/{registry-ATRHOG5B.js.map → public-envelope-IJJMWSTJ.js.map} +0 -0
  280. /package/dist/{registry-LEHB26TY.js.map → registry-GAIFVWXF.js.map} +0 -0
  281. /package/dist/{registry-NWHOLD5M.js.map → registry-J77ZUQ7G.js.map} +0 -0
  282. /package/dist/{revoke-5IEK22KT.js.map → registry-JGEVJ6YC.js.map} +0 -0
  283. /package/dist/{signer-I6YARZQA.js.map → revoke-WUY4AYRJ.js.map} +0 -0
  284. /package/dist/{stale-CPESGAPL.js.map → signer-UJF3CFDC.js.map} +0 -0
  285. /package/dist/{state-vault-JR3CFGNP.js.map → stale-PW6VBGSP.js.map} +0 -0
@@ -0,0 +1,399 @@
1
+ import {
2
+ resolveManagedSecret
3
+ } from "./chunk-XC32SZPW.js";
4
+ import {
5
+ hasNoydbBundleMagic,
6
+ parseExtractedPartitionBody,
7
+ readNoydbBundle,
8
+ readNoydbBundleHeader,
9
+ readNoydbBundlePublicEnvelope,
10
+ readUint32BE,
11
+ writeNoydbBundle,
12
+ writeUint32BE
13
+ } from "./chunk-4TCMCCC3.js";
14
+ import {
15
+ createOwnerKeyring
16
+ } from "./chunk-B5CSNGSE.js";
17
+ import {
18
+ generateULID
19
+ } from "./chunk-FZU343FL.js";
20
+ import {
21
+ LEDGER_COLLECTION,
22
+ LedgerStore
23
+ } from "./chunk-AONK5GCC.js";
24
+ import {
25
+ base64ToBuffer,
26
+ decrypt,
27
+ sha256Hex,
28
+ unwrapCek,
29
+ wrapKey
30
+ } from "./chunk-WQ3KAGOV.js";
31
+ import {
32
+ AdoptionStateError,
33
+ TransferSealError,
34
+ ValidationError
35
+ } from "./chunk-4BB4T3O7.js";
36
+
37
+ // src/bundle/adopt-partition.ts
38
+ async function unsealDeks(seal, transferKey) {
39
+ if (transferKey.byteLength !== 32) {
40
+ throw new TransferSealError(
41
+ `transfer key must be 32 bytes, got ${transferKey.byteLength}.`
42
+ );
43
+ }
44
+ const key = await crypto.subtle.importKey("raw", transferKey, "AES-GCM", false, ["decrypt"]);
45
+ const raw = base64ToBuffer(seal.payload);
46
+ let plaintext;
47
+ try {
48
+ plaintext = await crypto.subtle.decrypt(
49
+ { name: "AES-GCM", iv: raw.slice(0, 12) },
50
+ key,
51
+ raw.slice(12)
52
+ );
53
+ } catch {
54
+ throw new TransferSealError(
55
+ "transfer seal could not be opened \u2014 wrong transfer key (AES-GCM authentication failed)."
56
+ );
57
+ }
58
+ let dekMap;
59
+ try {
60
+ dekMap = JSON.parse(new TextDecoder().decode(plaintext));
61
+ } catch {
62
+ throw new TransferSealError("transfer seal payload is not valid JSON after decryption.");
63
+ }
64
+ const deks = /* @__PURE__ */ new Map();
65
+ for (const [collection, b64] of Object.entries(dekMap)) {
66
+ const dek = await crypto.subtle.importKey("raw", base64ToBuffer(b64), "AES-GCM", true, ["encrypt", "decrypt"]);
67
+ deks.set(collection, dek);
68
+ }
69
+ return deks;
70
+ }
71
+ async function adoptPartition(bundleBytes, opts) {
72
+ const { transferKey, destinationStore, vaultName } = opts;
73
+ const header = readNoydbBundleHeader(bundleBytes);
74
+ if (header.bundleKind !== "extracted-partition" || header.transferSeal === void 0) {
75
+ throw new ValidationError(
76
+ "adoptPartition requires an extracted-partition bundle with a transfer seal. For ordinary backups use readNoydbBundle + vault.load."
77
+ );
78
+ }
79
+ const { dumpJson } = await readNoydbBundle(bundleBytes);
80
+ const { dump, seal } = parseExtractedPartitionBody(dumpJson);
81
+ await unsealDeks(seal, transferKey);
82
+ const existing = await destinationStore.get(vaultName, "_meta", "adoption");
83
+ if (existing) {
84
+ const prior = JSON.parse(existing._data);
85
+ if (prior.sealId === seal.sealId) {
86
+ throw new AdoptionStateError(
87
+ `partition (sealId ${seal.sealId}) is already adopted into vault "${vaultName}".`
88
+ );
89
+ }
90
+ throw new AdoptionStateError(
91
+ `vault "${vaultName}" already holds an adopted partition (sealId ${prior.sealId}); adopting a different partition (sealId ${seal.sealId}) here would overwrite it. Adopt into a fresh vaultName instead.`
92
+ );
93
+ }
94
+ const existingKeyring = await destinationStore.list(vaultName, "_keyring");
95
+ if (existingKeyring.length > 0) {
96
+ throw new AdoptionStateError(
97
+ `vault "${vaultName}" already holds a keyring (an unrelated owner exists at this slot); adoptPartition requires a fresh vaultName to avoid destructive saveAll on SQL adapters.`
98
+ );
99
+ }
100
+ const backup = JSON.parse(dump);
101
+ await destinationStore.saveAll(vaultName, backup.collections);
102
+ if (backup._internal) {
103
+ for (const [collection, records] of Object.entries(backup._internal)) {
104
+ for (const [id, envelope] of Object.entries(records)) {
105
+ await destinationStore.put(vaultName, collection, id, envelope);
106
+ }
107
+ }
108
+ }
109
+ const adoptedAt = (/* @__PURE__ */ new Date()).toISOString();
110
+ const adoption = { sealId: seal.sealId, adoptedAt, needsOwner: true, transferSeal: seal };
111
+ await destinationStore.put(vaultName, "_meta", "adoption", {
112
+ _noydb: 1,
113
+ _v: 1,
114
+ _ts: adoptedAt,
115
+ _iv: "",
116
+ _data: JSON.stringify(adoption)
117
+ });
118
+ return { vaultName, needsOwner: true, sealId: seal.sealId };
119
+ }
120
+ function isManaged(o) {
121
+ return "passphraseMode" in o && o.passphraseMode === "managed";
122
+ }
123
+ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
124
+ const { userId, transferKey } = opts;
125
+ if (isManaged(opts) && !opts.recovery.some((r) => r.profile === "shamir")) {
126
+ throw new AdoptionStateError(
127
+ "managed-mode adoption requires at least one strong (shamir) recovery profile in `recovery` \u2014 paper alone is not strong when there is no user passphrase to fall back on."
128
+ );
129
+ }
130
+ const adoptionEnv = await store.get(vaultName, "_meta", "adoption");
131
+ if (!adoptionEnv) {
132
+ throw new AdoptionStateError(
133
+ `vault "${vaultName}" is not an adopted partition (no _meta/adoption). createOwnerOnAdoptedPartition only applies to vaults created via adoptPartition.`
134
+ );
135
+ }
136
+ const adoption = JSON.parse(adoptionEnv._data);
137
+ if (adoption.consumedAt !== void 0 || adoption.transferSeal === void 0) {
138
+ throw new AdoptionStateError(
139
+ `vault "${vaultName}" already has an owner (transfer seal consumed at ${adoption.consumedAt}).`
140
+ );
141
+ }
142
+ const partitionDeks = await unsealDeks(adoption.transferSeal, transferKey);
143
+ const existingKeyring = await store.get(vaultName, "_keyring", userId);
144
+ const otherOwners = (await store.list(vaultName, "_keyring")).filter((u) => u !== userId);
145
+ if (otherOwners.length > 0) {
146
+ throw new AdoptionStateError(
147
+ `vault "${vaultName}" already has a keyring for a different owner; cannot create owner "${userId}".`
148
+ );
149
+ }
150
+ const partitionCollections = [...partitionDeks.keys()];
151
+ const priorDeks = existingKeyring ? JSON.parse(existingKeyring._data).deks : {};
152
+ const ownerMinted = existingKeyring !== null && partitionCollections.every((c) => c in priorDeks);
153
+ if (!ownerMinted) {
154
+ const passphrase = isManaged(opts) ? await resolveManagedSecret(store, vaultName, opts.sealingKey) : opts.passphrase;
155
+ const unlocked = await createOwnerKeyring(store, vaultName, userId, passphrase);
156
+ const env = await store.get(vaultName, "_keyring", userId);
157
+ if (!env) throw new AdoptionStateError(`keyring write for "${userId}" did not persist`);
158
+ const keyringFile = JSON.parse(env._data);
159
+ const kek = unlocked.kek;
160
+ if (!kek) throw new AdoptionStateError(`owner keyring for "${userId}" has no KEK to wrap partition DEKs under`);
161
+ const mergedDeks = { ...keyringFile.deks };
162
+ for (const [collection, dek] of partitionDeks) {
163
+ mergedDeks[collection] = await wrapKey(dek, kek);
164
+ }
165
+ const mergedFile = { ...keyringFile, deks: mergedDeks };
166
+ await store.put(vaultName, "_keyring", userId, { ...env, _data: JSON.stringify(mergedFile) });
167
+ }
168
+ const ledgerDek = partitionDeks.get(LEDGER_COLLECTION);
169
+ if (ledgerDek) {
170
+ const ledger = new LedgerStore({
171
+ adapter: store,
172
+ vault: vaultName,
173
+ encrypted: true,
174
+ getDEK: async () => ledgerDek,
175
+ actor: userId
176
+ });
177
+ const creationReason = `creation-of-new-owner:${userId}`;
178
+ const consumedReason = `transfer-seal-consumed:${adoption.sealId}`;
179
+ const recordedReasons = new Set((await ledger.loadAllEntries()).map((e) => e.reason));
180
+ if (!recordedReasons.has(creationReason)) {
181
+ await ledger.append({ op: "lifecycle", collection: "", id: "", version: 0, actor: "", payloadHash: "", reason: creationReason });
182
+ }
183
+ if (!recordedReasons.has(consumedReason)) {
184
+ await ledger.append({ op: "lifecycle", collection: "", id: "", version: 0, actor: "", payloadHash: "", reason: consumedReason });
185
+ }
186
+ }
187
+ if (isManaged(opts)) {
188
+ const { createNoydb } = await import("./noydb-2PI2ZBX6.js");
189
+ const db = await createNoydb({
190
+ store,
191
+ user: userId,
192
+ passphraseMode: "managed",
193
+ sealingKey: opts.sealingKey,
194
+ shamirRecovery: opts.shamirRecovery
195
+ });
196
+ await db.openVaultAndEnrollRecovery(vaultName, { recovery: opts.recovery });
197
+ }
198
+ const consumed = { sealId: adoption.sealId, adoptedAt: adoption.adoptedAt, consumedAt: (/* @__PURE__ */ new Date()).toISOString() };
199
+ await store.put(vaultName, "_meta", "adoption", { ...adoptionEnv, _data: JSON.stringify(consumed) });
200
+ return { vaultName, userId };
201
+ }
202
+
203
+ // src/bundle/decrypt-partition.ts
204
+ async function decryptExtractedPartition(bundleBytes, transferKey) {
205
+ const header = readNoydbBundleHeader(bundleBytes);
206
+ if (header.bundleKind !== "extracted-partition" || header.transferSeal === void 0) {
207
+ throw new Error("decryptExtractedPartition: bundle is not an extracted-partition.");
208
+ }
209
+ const { dumpJson } = await readNoydbBundle(bundleBytes);
210
+ const { dump, seal } = parseExtractedPartitionBody(dumpJson);
211
+ const deks = await unsealDeks(seal, transferKey);
212
+ const backup = JSON.parse(dump);
213
+ const out = {};
214
+ for (const [collection, byId] of Object.entries(backup.collections)) {
215
+ const dek = deks.get(collection);
216
+ if (dek === void 0) continue;
217
+ const recs = [];
218
+ for (const [id, env] of Object.entries(byId)) {
219
+ const plaintext = env._cek !== void 0 ? await decrypt(env._iv, env._data, await unwrapCek(env._cek, dek)) : await decrypt(env._iv, env._data, dek);
220
+ const body = JSON.parse(plaintext);
221
+ recs.push({
222
+ id,
223
+ record: { ...body, id },
224
+ ts: env._ts,
225
+ version: env._v,
226
+ ...env._source !== void 0 ? { source: env._source } : {},
227
+ ...env._sourceTs !== void 0 ? { sourceTs: env._sourceTs } : {}
228
+ });
229
+ }
230
+ out[collection] = recs;
231
+ }
232
+ return out;
233
+ }
234
+
235
+ // src/bundle/multi-bundle.ts
236
+ var NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([78, 68, 66, 77]);
237
+ var NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10;
238
+ var NOYDB_MULTI_BUNDLE_VERSION = 1;
239
+ function encodeMultiBundle(manifest, inner) {
240
+ validateManifest(manifest);
241
+ if (manifest.compartments.length !== inner.length) {
242
+ throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`);
243
+ }
244
+ for (let i = 0; i < inner.length; i++) {
245
+ if (manifest.compartments[i].innerBytes !== inner[i].length) {
246
+ throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i].innerBytes} but ${inner[i].length} bytes were provided.`);
247
+ }
248
+ }
249
+ const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest));
250
+ const bodyLen = inner.reduce((n, b) => n + b.length, 0);
251
+ const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen);
252
+ out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0);
253
+ out[4] = NOYDB_MULTI_BUNDLE_VERSION;
254
+ out[5] = 0;
255
+ writeUint32BE(out, 6, manifestBytes.length);
256
+ out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES);
257
+ let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length;
258
+ for (const b of inner) {
259
+ out.set(b, off);
260
+ off += b.length;
261
+ }
262
+ return out;
263
+ }
264
+ function hasMultiMagic(bytes) {
265
+ if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false;
266
+ for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false;
267
+ return true;
268
+ }
269
+ function validateManifest(parsed) {
270
+ if (parsed === null || typeof parsed !== "object") throw new Error("multi-bundle manifest must be a JSON object.");
271
+ const m = parsed;
272
+ if (m["multiFormatVersion"] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m["multiFormatVersion"])}.`);
273
+ if (typeof m["handle"] !== "string" || m["handle"].length === 0) throw new Error("multi-bundle manifest.handle must be a non-empty string.");
274
+ if (!Array.isArray(m["compartments"])) throw new Error("multi-bundle manifest.compartments must be an array.");
275
+ const seenHandles = /* @__PURE__ */ new Set();
276
+ for (const c of m["compartments"]) {
277
+ if (c === null || typeof c !== "object") throw new Error("multi-bundle compartment must be an object.");
278
+ const e = c;
279
+ if (typeof e["handle"] !== "string" || e["handle"].length === 0) throw new Error("multi-bundle compartment.handle must be a non-empty string.");
280
+ if (seenHandles.has(e["handle"])) {
281
+ throw new Error(`multi-bundle manifest has a duplicate compartment handle "${e["handle"]}".`);
282
+ }
283
+ seenHandles.add(e["handle"]);
284
+ if (typeof e["innerBytes"] !== "number" || !Number.isInteger(e["innerBytes"]) || e["innerBytes"] < 0) throw new Error("multi-bundle compartment.innerBytes must be a non-negative integer.");
285
+ if (typeof e["innerSha256"] !== "string" || !/^[0-9a-f]{64}$/.test(e["innerSha256"])) throw new Error("multi-bundle compartment.innerSha256 must be 64-char lowercase hex.");
286
+ }
287
+ }
288
+ function decodeMultiBundle(bytes) {
289
+ if (!hasMultiMagic(bytes)) throw new Error("not a NOYDB multi-bundle: missing NDBM magic.");
290
+ if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error("multi-bundle truncated: shorter than the fixed prefix.");
291
+ if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`);
292
+ const manifestLen = readUint32BE(bytes, 6);
293
+ const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen;
294
+ if (manifestEnd > bytes.length) throw new Error("multi-bundle truncated: manifest length overruns the buffer.");
295
+ const manifestJson = new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd));
296
+ let parsed;
297
+ try {
298
+ parsed = JSON.parse(manifestJson);
299
+ } catch (err) {
300
+ throw new Error(`multi-bundle manifest is not valid JSON: ${err.message}`);
301
+ }
302
+ validateManifest(parsed);
303
+ const inner = [];
304
+ let off = manifestEnd;
305
+ for (const c of parsed.compartments) {
306
+ const end = off + c.innerBytes;
307
+ if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment "${c.handle}" innerBytes overruns the buffer.`);
308
+ inner.push(bytes.subarray(off, end));
309
+ off = end;
310
+ }
311
+ if (off !== bytes.length) {
312
+ throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment \u2014 buffer may be corrupt.`);
313
+ }
314
+ return { manifest: parsed, inner };
315
+ }
316
+ async function writeMultiVaultBundle(compartments, opts = {}) {
317
+ if (compartments.length === 0) throw new Error("writeMultiVaultBundle: at least one compartment is required.");
318
+ const inner = [];
319
+ const entries = [];
320
+ for (const c of compartments) {
321
+ const innerBytes = await writeNoydbBundle(c.vault, c.bundleOptions ?? {});
322
+ const header = readNoydbBundleHeader(innerBytes);
323
+ const entry = {
324
+ handle: header.handle,
325
+ exportedAt: c.exportedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
326
+ innerBytes: innerBytes.length,
327
+ innerSha256: await sha256Hex(innerBytes)
328
+ };
329
+ if (c.roleTag !== void 0) entry.roleTag = c.roleTag;
330
+ if (c.disclose?.name !== void 0 && c.disclose.name !== false) {
331
+ entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name;
332
+ }
333
+ if (c.disclose?.collections === true) {
334
+ const names = await c.vault.collections();
335
+ entry.collections = await Promise.all(
336
+ names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() }))
337
+ );
338
+ }
339
+ if (c.disclose?.publicEnvelope === true) {
340
+ const env = readNoydbBundlePublicEnvelope(innerBytes);
341
+ if (env !== void 0) entry.publicEnvelope = env;
342
+ }
343
+ const fence = await c.vault.schemaFenceState();
344
+ entry.schemaVersion = fence.currentSchemaVersion;
345
+ inner.push(innerBytes);
346
+ entries.push(entry);
347
+ }
348
+ const manifest = {
349
+ multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,
350
+ handle: opts.handle ?? generateULID(),
351
+ compartments: entries
352
+ };
353
+ return encodeMultiBundle(manifest, inner);
354
+ }
355
+ async function readNoydbBundleManifest(bytes) {
356
+ if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments];
357
+ if (hasNoydbBundleMagic(bytes)) {
358
+ const header = readNoydbBundleHeader(bytes);
359
+ const env = readNoydbBundlePublicEnvelope(bytes);
360
+ const entry = {
361
+ handle: header.handle,
362
+ innerBytes: bytes.length,
363
+ innerSha256: await sha256Hex(bytes)
364
+ };
365
+ if (env !== void 0) entry.publicEnvelope = env;
366
+ return [entry];
367
+ }
368
+ throw new Error("readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).");
369
+ }
370
+ function readMultiVaultBundleCompartment(bytes, selector) {
371
+ if (typeof selector === "number" && !Number.isInteger(selector)) {
372
+ throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`);
373
+ }
374
+ if (hasNoydbBundleMagic(bytes) && !hasMultiMagic(bytes)) {
375
+ const header = readNoydbBundleHeader(bytes);
376
+ if (selector === 0 || selector === header.handle) return bytes;
377
+ throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment "${header.handle}".`);
378
+ }
379
+ const { manifest, inner } = decodeMultiBundle(bytes);
380
+ const idx = typeof selector === "number" ? selector : manifest.compartments.findIndex((c) => c.handle === selector);
381
+ if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === "number" ? `at index ${selector}` : `"${selector}"`}.`);
382
+ return inner[idx];
383
+ }
384
+
385
+ export {
386
+ unsealDeks,
387
+ adoptPartition,
388
+ createOwnerOnAdoptedPartition,
389
+ decryptExtractedPartition,
390
+ NOYDB_MULTI_BUNDLE_MAGIC,
391
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES,
392
+ NOYDB_MULTI_BUNDLE_VERSION,
393
+ encodeMultiBundle,
394
+ decodeMultiBundle,
395
+ writeMultiVaultBundle,
396
+ readNoydbBundleManifest,
397
+ readMultiVaultBundleCompartment
398
+ };
399
+ //# sourceMappingURL=chunk-R43KS34V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bundle/adopt-partition.ts","../src/bundle/decrypt-partition.ts","../src/bundle/multi-bundle.ts"],"sourcesContent":["/**\n * Partition adoption. Recipient side: verify an extracted bundle,\n * validate the transfer key, import the re-keyed collections into a\n * destination store, and record an `_meta/adoption` marker. The bundle\n * stays UNOWNED after adoption — `createOwnerOnAdoptedPartition`\n * mints the owner; the transfer seal is then destroyed.\n *\n * @module\n */\nimport { base64ToBuffer, wrapKey } from '../crypto.js'\nimport { TransferSealError, AdoptionStateError, ValidationError } from '../errors.js'\nimport type { NoydbStore, VaultSnapshot, KeyringFile } from '../types.js'\nimport { createOwnerKeyring } from '../team/keyring.js'\nimport { resolveManagedSecret } from '../team/managed-passphrase.js'\nimport type { SealingKeyProvider } from '../team/managed-passphrase.js'\nimport type { ShamirRecoveryProvider } from '../team/shamir-recovery-provider.js'\nimport type { RecoveryEnrollmentInput } from '../team/rotate-recover.js'\nimport { LedgerStore } from '../history/ledger/store.js'\nimport { LEDGER_COLLECTION } from '../history/ledger/constants.js'\nimport type { TransferSealPayload } from './bundle.js'\nimport { readNoydbBundleHeader, readNoydbBundle, parseExtractedPartitionBody } from './bundle.js'\n\n/**\n * Reverse of `sealDeks`. Imports the transfer key, decrypts the\n * sealed `{ collection: base64(rawDEK) }` map (layout iv(12)‖ct‖tag), and\n * re-imports each DEK as an AES-GCM key. Throws `TransferSealError` on a\n * wrong key (AES-GCM auth-tag failure) or malformed payload.\n */\nexport async function unsealDeks(\n seal: TransferSealPayload,\n transferKey: Uint8Array,\n): Promise<Map<string, CryptoKey>> {\n if (transferKey.byteLength !== 32) {\n throw new TransferSealError(\n `transfer key must be 32 bytes, got ${transferKey.byteLength}.`,\n )\n }\n const key = await crypto.subtle.importKey('raw', transferKey as BufferSource, 'AES-GCM', false, ['decrypt'])\n const raw = base64ToBuffer(seal.payload)\n let plaintext: ArrayBuffer\n try {\n plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: raw.slice(0, 12) as BufferSource },\n key,\n raw.slice(12) as BufferSource,\n )\n } catch {\n throw new TransferSealError(\n 'transfer seal could not be opened — wrong transfer key (AES-GCM authentication failed).',\n )\n }\n let dekMap: Record<string, string>\n try {\n dekMap = JSON.parse(new TextDecoder().decode(plaintext)) as Record<string, string>\n } catch {\n throw new TransferSealError('transfer seal payload is not valid JSON after decryption.')\n }\n const deks = new Map<string, CryptoKey>()\n for (const [collection, b64] of Object.entries(dekMap)) {\n // Extractable: the recipient must be able to re-wrap these under their\n // own KEK (AES-KW) at owner-creation. Matches generateDEK.\n const dek = await crypto.subtle.importKey('raw', base64ToBuffer(b64) as BufferSource, 'AES-GCM', true, ['encrypt', 'decrypt'])\n deks.set(collection, dek)\n }\n return deks\n}\n\nexport interface AdoptPartitionOptions {\n readonly transferKey: Uint8Array\n readonly destinationStore: NoydbStore\n readonly vaultName: string\n}\n\nexport interface AdoptPartitionResult {\n readonly vaultName: string\n readonly needsOwner: true\n readonly sealId: string\n}\n\nexport async function adoptPartition(\n bundleBytes: Uint8Array,\n opts: AdoptPartitionOptions,\n): Promise<AdoptPartitionResult> {\n const { transferKey, destinationStore, vaultName } = opts\n\n const header = readNoydbBundleHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new ValidationError(\n 'adoptPartition requires an extracted-partition bundle with a transfer seal. '\n + 'For ordinary backups use readNoydbBundle + vault.load.',\n )\n }\n\n const { dumpJson } = await readNoydbBundle(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n\n // Validate the transfer key by unsealing in memory; throws\n // TransferSealError on mismatch. DEKs are discarded here — they stay\n // sealed at rest (in _meta/adoption) until owner-creation wraps them under the\n // recipient's KEK.\n await unsealDeks(seal, transferKey)\n\n // Single-occupancy per vaultName: an `_meta/adoption` marker already present\n // means this slot holds a partition (adopted-and-unowned, or already owned).\n // saveAll below would overwrite its data and replace the marker, stranding the\n // prior adoption's transfer seal. Refuse regardless of sealId — re-adopting the\n // SAME bundle is a redundant call, and adopting a DIFFERENT bundle here would\n // clobber the existing partition. Either way, pick a fresh vaultName.\n const existing = await destinationStore.get(vaultName, '_meta', 'adoption')\n if (existing) {\n const prior = JSON.parse(existing._data) as { sealId?: string }\n if (prior.sealId === seal.sealId) {\n throw new AdoptionStateError(\n `partition (sealId ${seal.sealId}) is already adopted into vault \"${vaultName}\".`,\n )\n }\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds an adopted partition (sealId ${prior.sealId}); `\n + `adopting a different partition (sealId ${seal.sealId}) here would overwrite it. `\n + `Adopt into a fresh vaultName instead.`,\n )\n }\n\n // The marker-only check above misses a worse case: a vaultName already in use\n // by an ORDINARY vault (createNoydb + openVault) carries no `_meta/adoption`,\n // yet `saveAll` below is destructive on SQL adapters (`DELETE FROM ... WHERE\n // vault = ?` followed by upsert) and would wipe the legitimate keyring +\n // data. Refuse adoption into ANY occupied slot — a fresh vaultName is the\n // documented precondition.\n const existingKeyring = await destinationStore.list(vaultName, '_keyring')\n if (existingKeyring.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds a keyring (an unrelated owner exists at this slot); `\n + `adoptPartition requires a fresh vaultName to avoid destructive saveAll on SQL adapters.`,\n )\n }\n\n const backup = JSON.parse(dump) as { collections: VaultSnapshot; _internal?: VaultSnapshot }\n await destinationStore.saveAll(vaultName, backup.collections)\n\n // Import carried internal collections (e.g. _schemas from carrySchemas).\n // saveAll only writes data collections; _internal is written per-record.\n if (backup._internal) {\n for (const [collection, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await destinationStore.put(vaultName, collection, id, envelope)\n }\n }\n }\n\n const adoptedAt = new Date().toISOString()\n const adoption = { sealId: seal.sealId, adoptedAt, needsOwner: true as const, transferSeal: seal }\n await destinationStore.put(vaultName, '_meta', 'adoption', {\n _noydb: 1, _v: 1, _ts: adoptedAt, _iv: '', _data: JSON.stringify(adoption),\n })\n\n return { vaultName, needsOwner: true, sealId: seal.sealId }\n}\n\nexport interface CreateOwnerResult {\n readonly vaultName: string\n readonly userId: string\n}\n\n/** Standard-mode owner: recipient supplies the passphrase. */\nexport interface CreateOwnerStandardOptions {\n readonly userId: string\n readonly passphrase: string\n readonly transferKey: Uint8Array\n}\n\n/**\n * Managed-mode owner: the passphrase is minted + sealed under\n * a `SealingKeyProvider` (e.g. an `at-*` OS keychain) so the partition\n * auto-unlocks on the recipient's device. Managed mode mandates a strong\n * (Shamir) recovery profile at creation, which needs the\n * `shamirRecovery` provider injected.\n */\nexport interface CreateOwnerManagedOptions {\n readonly userId: string\n readonly passphraseMode: 'managed'\n readonly sealingKey: SealingKeyProvider\n readonly recovery: ReadonlyArray<RecoveryEnrollmentInput>\n readonly shamirRecovery: ShamirRecoveryProvider\n readonly transferKey: Uint8Array\n}\n\nexport type CreateOwnerOptions = CreateOwnerStandardOptions | CreateOwnerManagedOptions\n\nfunction isManaged(o: CreateOwnerOptions): o is CreateOwnerManagedOptions {\n return 'passphraseMode' in o && o.passphraseMode === 'managed'\n}\n\n/**\n * Mint the first owner keyring on an adopted-but-unowned partition,\n * then destroy the transfer seal.\n *\n * Standard mode: the recipient supplies a passphrase. Managed mode: the\n * passphrase is minted + sealed under a `SealingKeyProvider` and a strong\n * (Shamir) recovery profile is enrolled — orchestrated via the existing\n * `openVaultAndEnrollRecovery` ceremony.\n *\n * Either way, reuses `createOwnerKeyring` to derive the KEK + write the base\n * keyring, then wraps the partition's DEKs (recovered from the seal) under that\n * KEK and re-persists the merged keyring file.\n *\n * Idempotent under retry: the seal is destroyed LAST (Stage D), after the\n * keyring (Stage A), the ledger transition (Stage B), and — in managed mode —\n * strong-recovery enrollment (Stage C). A failure in the fallible enrollment\n * step leaves the seal intact, and re-running with the same `userId` +\n * `transferKey` resumes from the first incomplete stage. (Multi-profile recovery\n * arrays may re-enroll an already-enrolled profile on retry; managed mode's\n * mandated single Shamir profile does not.)\n */\nexport async function createOwnerOnAdoptedPartition(\n store: NoydbStore,\n vaultName: string,\n opts: CreateOwnerOptions,\n): Promise<CreateOwnerResult> {\n const { userId, transferKey } = opts\n\n // Managed mode requires a strong (Shamir) recovery profile, validated BEFORE\n // any disk write — same gate as createNoydb.\n if (isManaged(opts) && !opts.recovery.some((r) => r.profile === 'shamir')) {\n throw new AdoptionStateError(\n 'managed-mode adoption requires at least one strong (shamir) recovery profile in '\n + '`recovery` — paper alone is not strong when there is no user passphrase to fall back on.',\n )\n }\n\n // 1. Verify adopted-unowned state.\n const adoptionEnv = await store.get(vaultName, '_meta', 'adoption')\n if (!adoptionEnv) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" is not an adopted partition (no _meta/adoption). `\n + `createOwnerOnAdoptedPartition only applies to vaults created via adoptPartition.`,\n )\n }\n const adoption = JSON.parse(adoptionEnv._data) as {\n sealId: string; adoptedAt: string; needsOwner?: boolean\n consumedAt?: string; transferSeal?: TransferSealPayload\n }\n if (adoption.consumedAt !== undefined || adoption.transferSeal === undefined) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has an owner (transfer seal consumed at ${adoption.consumedAt}).`,\n )\n }\n\n // 2. Recover the partition DEKs from the seal (throws on wrong key) BEFORE\n // writing any keyring, so a bad transfer key leaves no trace. Always\n // validated, including when resuming a partial prior call.\n const partitionDeks = await unsealDeks(adoption.transferSeal, transferKey)\n\n // The ceremony below is split into stages so a failure in the fallible\n // managed-enrollment step (network/provider outage) leaves the call RETRYABLE\n // — the seal is destroyed only once everything durable is in place. Each stage\n // detects its own prior completion rather than relying on a single resume bit.\n\n // A keyring present for a DIFFERENT user (with the seal still unconsumed) is a\n // genuine second-owner attempt — refuse it. A same-user keyring is a resumed\n // partial call and is handled by the stage checks below.\n const existingKeyring = await store.get(vaultName, '_keyring', userId)\n const otherOwners = (await store.list(vaultName, '_keyring')).filter((u) => u !== userId)\n if (otherOwners.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has a keyring for a different owner; cannot create owner \"${userId}\".`,\n )\n }\n\n // Stage A — mint the owner keyring + merge the partition DEKs. Considered done\n // only when the keyring already holds every partition DEK. createOwnerKeyring\n // overwrites (fresh KEK + fresh _users DEK), so re-running is safe ONLY while\n // no recovery has been enrolled yet — guaranteed here because enrollment\n // (Stage C) runs strictly after Stage A completes.\n const partitionCollections = [...partitionDeks.keys()]\n const priorDeks = existingKeyring ? (JSON.parse(existingKeyring._data) as KeyringFile).deks : {}\n const ownerMinted = existingKeyring !== null && partitionCollections.every((c) => c in priorDeks)\n if (!ownerMinted) {\n // Resolve the owner passphrase. Managed mode mints a random passphrase, seals\n // it under the provider, and persists _meta/sealed-passphrase (so the\n // partition auto-unlocks on the recipient's device); standard mode uses the\n // caller's passphrase. Idempotent under retry — resolveManagedSecret's reopen\n // arm reuses an already-sealed passphrase.\n const passphrase = isManaged(opts)\n ? await resolveManagedSecret(store, vaultName, opts.sealingKey)\n : opts.passphrase\n\n // Mint the owner keyring (KEK + _users DEK + canary, written to disk).\n const unlocked = await createOwnerKeyring(store, vaultName, userId, passphrase)\n\n // Merge the partition DEKs (wrapped under the new KEK) into the keyring.\n const env = await store.get(vaultName, '_keyring', userId)\n if (!env) throw new AdoptionStateError(`keyring write for \"${userId}\" did not persist`)\n const keyringFile = JSON.parse(env._data) as KeyringFile\n const kek = unlocked.kek\n if (!kek) throw new AdoptionStateError(`owner keyring for \"${userId}\" has no KEK to wrap partition DEKs under`)\n const mergedDeks: Record<string, string> = { ...keyringFile.deks }\n for (const [collection, dek] of partitionDeks) {\n mergedDeks[collection] = await wrapKey(dek, kek)\n }\n const mergedFile: KeyringFile = { ...keyringFile, deks: mergedDeks }\n await store.put(vaultName, '_keyring', userId, { ...env, _data: JSON.stringify(mergedFile) })\n }\n\n // Stage B — record the ownership transition on the carried\n // audit chain (carryLedger sealed the _ledger DEK). No-op without that DEK.\n // Idempotent: appended only if the closing `transfer-seal-consumed` entry is\n // absent, so a retry does not duplicate the pair.\n const ledgerDek = partitionDeks.get(LEDGER_COLLECTION)\n if (ledgerDek) {\n const ledger = new LedgerStore({\n adapter: store,\n vault: vaultName,\n encrypted: true,\n getDEK: async () => ledgerDek,\n actor: userId,\n })\n const creationReason = `creation-of-new-owner:${userId}`\n const consumedReason = `transfer-seal-consumed:${adoption.sealId}`\n // Gate each append on its own presence — a crash or store error strictly\n // between the two adjacent puts would otherwise re-append the first one\n // on retry. The pair is the audit record, not a single transaction.\n const recordedReasons = new Set((await ledger.loadAllEntries()).map((e) => e.reason))\n if (!recordedReasons.has(creationReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: creationReason })\n }\n if (!recordedReasons.has(consumedReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: consumedReason })\n }\n }\n\n // Stage C — Managed mode: enroll the mandatory strong recovery\n // by orchestrating the existing public ceremony. The partition is\n // now a managed-mode vault on disk (sealed passphrase + keyring), so we\n // open it as a normal client and let openVaultAndEnrollRecovery do the\n // gate-bypass + enroll + re-assert. Dynamic import keeps the Noydb class\n // out of the @noy-db/hub/bundle static graph. Runs BEFORE seal destruction\n // so a failure here leaves the seal intact and the call retryable.\n if (isManaged(opts)) {\n const { createNoydb } = await import('../noydb.js')\n const db = await createNoydb({\n store,\n user: userId,\n passphraseMode: 'managed',\n sealingKey: opts.sealingKey,\n shamirRecovery: opts.shamirRecovery,\n })\n await db.openVaultAndEnrollRecovery(vaultName, { recovery: opts.recovery })\n }\n\n // Stage D — Destroy the transfer seal LAST — the commit point. Everything\n // above is either idempotent or resumable, so the seal is only consumed\n // once the owner keyring (and, in managed mode, strong recovery) is\n // durably in place. Retain sealId + consumedAt for audit.\n const consumed = { sealId: adoption.sealId, adoptedAt: adoption.adoptedAt, consumedAt: new Date().toISOString() }\n await store.put(vaultName, '_meta', 'adoption', { ...adoptionEnv, _data: JSON.stringify(consumed) })\n\n return { vaultName, userId }\n}\n","/**\n * Read-side counterpart to `extractPartition`: decrypt an\n * extracted-partition bundle's records to plaintext using its transfer\n * key, WITHOUT adopting it into a vault. Used by reconcile/merge\n * (@klum-db/lobby FR-3) and field-authority (FR-4) to compare incoming\n * records against a receiver. The transfer key validates the bundle\n * (wrong key throws).\n * @module\n */\nimport type { EncryptedEnvelope } from '../types.js'\nimport { decrypt } from '../crypto.js'\nimport { unwrapCek } from '../record-keys/index.js'\nimport { readNoydbBundleHeader, readNoydbBundle, parseExtractedPartitionBody } from './bundle.js'\nimport { unsealDeks } from './adopt-partition.js'\n\n/** One decrypted record from an extracted-partition compartment. */\nexport interface DecryptedRecord {\n readonly id: string\n readonly record: Record<string, unknown>\n /** Source envelope write timestamp (ISO) — for last-write-wins merges. */\n readonly ts: string\n /** Source envelope version. */\n readonly version: number\n /** Provenance source id (FR-5). Present only when the source collection had provenance:true and a source was supplied on put. */\n readonly source?: string\n /** ISO-8601 timestamp the provenance source was recorded (FR-5). */\n readonly sourceTs?: string\n}\n\n/**\n * Decrypt every record of an extracted-partition bundle to plaintext,\n * grouped by collection. Throws if the bundle isn't an\n * extracted-partition or the transfer key is wrong.\n */\nexport async function decryptExtractedPartition(\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n): Promise<Record<string, DecryptedRecord[]>> {\n const header = readNoydbBundleHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new Error('decryptExtractedPartition: bundle is not an extracted-partition.')\n }\n const { dumpJson } = await readNoydbBundle(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n const deks = await unsealDeks(seal, transferKey) // throws TransferSealError on wrong key\n const backup = JSON.parse(dump) as { collections: Record<string, Record<string, EncryptedEnvelope>> }\n const out: Record<string, DecryptedRecord[]> = {}\n for (const [collection, byId] of Object.entries(backup.collections)) {\n const dek = deks.get(collection)\n if (dek === undefined) continue // no DEK sealed for this collection — skip\n const recs: DecryptedRecord[] = []\n for (const [id, env] of Object.entries(byId)) {\n const plaintext = env._cek !== undefined\n ? await decrypt(env._iv, env._data, await unwrapCek(env._cek, dek))\n : await decrypt(env._iv, env._data, dek)\n const body = JSON.parse(plaintext) as Record<string, unknown>\n recs.push({\n id,\n record: { ...body, id },\n ts: env._ts,\n version: env._v,\n ...(env._source !== undefined ? { source: env._source } : {}),\n ...(env._sourceTs !== undefined ? { sourceTs: env._sourceTs } : {}),\n })\n }\n out[collection] = recs\n }\n return out\n}\n","/**\n * Multi-compartment `.noydb` bundle (`NDBM`). A thin outer container\n * that embeds N standard single-vault `.noydb` bundles plus an\n * unencrypted, owner-curated **manifest**. The v1 single-vault format\n * is untouched; each compartment is a complete v1 bundle, produced by\n * `writeNoydbBundle` and read by `readNoydbBundle`.\n *\n * Layout: magic 'NDBM'(4) · version(1) · reserved(1) · manifestLen(4 BE)\n * · manifest JSON · concat(inner v1 bundles, in manifest order).\n *\n * @packageDocumentation\n */\nimport type { Vault } from '../vault.js'\nimport type { PublicEnvelope } from '../meta/public-envelope/types.js'\nimport { sha256Hex } from '../crypto.js'\nimport { generateULID } from './ulid.js'\nimport { readUint32BE, writeUint32BE, hasNoydbBundleMagic } from './format.js'\nimport {\n writeNoydbBundle,\n readNoydbBundleHeader,\n readNoydbBundlePublicEnvelope,\n type WriteNoydbBundleOptions,\n} from './bundle.js'\n\n/** Magic bytes 'NDBM' — NOYDB Multi-compartment bundle. */\nexport const NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([0x4e, 0x44, 0x42, 0x4d])\n/** Fixed prefix: magic(4) + version(1) + reserved(1) + manifestLen(4). */\nexport const NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10\n/** Current multi-bundle layout version. */\nexport const NOYDB_MULTI_BUNDLE_VERSION = 1\n\n/** One compartment's entry in the pre-decrypt manifest. */\nexport interface CompartmentManifest {\n /** The inner v1 bundle's stable ULID handle. */\n readonly handle: string\n /** Owner-curated classification (e.g. 'shard', 'pool'). Opt-in. */\n readonly roleTag?: string\n /** ISO export timestamp. Always set by the writer; absent for a v1 bundle read as a 1-entry manifest. */\n readonly exportedAt?: string\n /** Compartment (vault) name. Opt-in disclosure. */\n readonly name?: string\n /** Collection names + record counts. Opt-in disclosure. */\n readonly collections?: readonly { readonly name: string; readonly count: number }[]\n /** Inner bundle's owner-curated public envelope, surfaced. Opt-in. */\n readonly publicEnvelope?: PublicEnvelope\n /** Byte length of the inner v1 bundle (drives framing). */\n readonly innerBytes: number\n /** SHA-256 (lowercase hex) of the inner v1 bundle bytes — pre-decrypt integrity. */\n readonly innerSha256: string\n /** Source vault's schema fence version at extract time (FR-8). Opt-in; absent on older bundles. */\n readonly schemaVersion?: number\n}\n\n/** The unencrypted manifest of a multi-compartment bundle. */\nexport interface MultiBundleManifest {\n readonly multiFormatVersion: number\n /** Opaque ULID for the outer container. */\n readonly handle: string\n readonly compartments: readonly CompartmentManifest[]\n}\n\n/** Assemble the `NDBM` container from a manifest + inner bundle bytes (in manifest order). */\nexport function encodeMultiBundle(\n manifest: MultiBundleManifest,\n inner: readonly Uint8Array[],\n): Uint8Array {\n validateManifest(manifest)\n if (manifest.compartments.length !== inner.length) {\n throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`)\n }\n for (let i = 0; i < inner.length; i++) {\n if (manifest.compartments[i]!.innerBytes !== inner[i]!.length) {\n throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i]!.innerBytes} but ${inner[i]!.length} bytes were provided.`)\n }\n }\n const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest))\n const bodyLen = inner.reduce((n, b) => n + b.length, 0)\n const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen)\n out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0)\n out[4] = NOYDB_MULTI_BUNDLE_VERSION\n out[5] = 0\n writeUint32BE(out, 6, manifestBytes.length)\n out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES)\n let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length\n for (const b of inner) { out.set(b, off); off += b.length }\n return out\n}\n\nfunction hasMultiMagic(bytes: Uint8Array): boolean {\n if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false\n for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false\n return true\n}\n\nfunction validateManifest(parsed: unknown): asserts parsed is MultiBundleManifest {\n if (parsed === null || typeof parsed !== 'object') throw new Error('multi-bundle manifest must be a JSON object.')\n const m = parsed as Record<string, unknown>\n if (m['multiFormatVersion'] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m['multiFormatVersion'])}.`)\n if (typeof m['handle'] !== 'string' || m['handle'].length === 0) throw new Error('multi-bundle manifest.handle must be a non-empty string.')\n if (!Array.isArray(m['compartments'])) throw new Error('multi-bundle manifest.compartments must be an array.')\n const seenHandles = new Set<string>()\n for (const c of m['compartments'] as unknown[]) {\n if (c === null || typeof c !== 'object') throw new Error('multi-bundle compartment must be an object.')\n const e = c as Record<string, unknown>\n if (typeof e['handle'] !== 'string' || e['handle'].length === 0) throw new Error('multi-bundle compartment.handle must be a non-empty string.')\n if (seenHandles.has(e['handle'])) {\n throw new Error(`multi-bundle manifest has a duplicate compartment handle \"${e['handle']}\".`)\n }\n seenHandles.add(e['handle'])\n if (typeof e['innerBytes'] !== 'number' || !Number.isInteger(e['innerBytes']) || e['innerBytes'] < 0) throw new Error('multi-bundle compartment.innerBytes must be a non-negative integer.')\n if (typeof e['innerSha256'] !== 'string' || !/^[0-9a-f]{64}$/.test(e['innerSha256'])) throw new Error('multi-bundle compartment.innerSha256 must be 64-char lowercase hex.')\n }\n}\n\n/** Parse the `NDBM` container into its manifest + raw inner bundle byte slices. */\nexport function decodeMultiBundle(bytes: Uint8Array): { manifest: MultiBundleManifest; inner: Uint8Array[] } {\n if (!hasMultiMagic(bytes)) throw new Error('not a NOYDB multi-bundle: missing NDBM magic.')\n if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error('multi-bundle truncated: shorter than the fixed prefix.')\n if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`)\n const manifestLen = readUint32BE(bytes, 6)\n const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen\n if (manifestEnd > bytes.length) throw new Error('multi-bundle truncated: manifest length overruns the buffer.')\n const manifestJson = new TextDecoder('utf-8', { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd))\n let parsed: unknown\n try { parsed = JSON.parse(manifestJson) } catch (err) { throw new Error(`multi-bundle manifest is not valid JSON: ${(err as Error).message}`) }\n validateManifest(parsed)\n const inner: Uint8Array[] = []\n let off = manifestEnd\n for (const c of parsed.compartments) {\n const end = off + c.innerBytes\n if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment \"${c.handle}\" innerBytes overruns the buffer.`)\n inner.push(bytes.subarray(off, end))\n off = end\n }\n if (off !== bytes.length) {\n throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment — buffer may be corrupt.`)\n }\n return { manifest: parsed, inner }\n}\n\n/** Per-compartment input to {@link writeMultiVaultBundle}. */\nexport interface MultiVaultCompartmentInput {\n readonly vault: Vault\n /** Owner-curated classification surfaced in the manifest (e.g. 'shard', 'pool'). */\n readonly roleTag?: string\n /** ISO timestamp for the manifest; defaults to now. */\n readonly exportedAt?: string\n /** Opt-in pre-decrypt disclosure for this compartment. */\n readonly disclose?: {\n /** `true` → use `vault.name`; a string → that explicit name. */\n readonly name?: boolean | string\n /** `true` → include collection names + record counts. */\n readonly collections?: boolean\n /** `true` → surface the inner bundle's public envelope into the manifest. */\n readonly publicEnvelope?: boolean\n }\n /** Options forwarded to `writeNoydbBundle` for this compartment's inner bundle. */\n readonly bundleOptions?: WriteNoydbBundleOptions\n}\n\n/** Write N vaults into one `NDBM` multi-compartment bundle. */\nexport async function writeMultiVaultBundle(\n compartments: readonly MultiVaultCompartmentInput[],\n opts: { readonly handle?: string } = {},\n): Promise<Uint8Array> {\n if (compartments.length === 0) throw new Error('writeMultiVaultBundle: at least one compartment is required.')\n const inner: Uint8Array[] = []\n const entries: CompartmentManifest[] = []\n for (const c of compartments) {\n const innerBytes = await writeNoydbBundle(c.vault, c.bundleOptions ?? {})\n const header = readNoydbBundleHeader(innerBytes)\n const entry: {\n -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K]\n } = {\n handle: header.handle,\n exportedAt: c.exportedAt ?? new Date().toISOString(),\n innerBytes: innerBytes.length,\n innerSha256: await sha256Hex(innerBytes),\n }\n if (c.roleTag !== undefined) entry.roleTag = c.roleTag\n if (c.disclose?.name !== undefined && c.disclose.name !== false) {\n entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name\n }\n if (c.disclose?.collections === true) {\n const names = await c.vault.collections()\n entry.collections = await Promise.all(\n names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() })),\n )\n }\n if (c.disclose?.publicEnvelope === true) {\n const env = readNoydbBundlePublicEnvelope(innerBytes)\n if (env !== undefined) entry.publicEnvelope = env\n }\n // FR-8: stamp schema fence version so the bundle self-describes its version.\n const fence = await c.vault.schemaFenceState()\n entry.schemaVersion = fence.currentSchemaVersion\n inner.push(innerBytes)\n entries.push(entry)\n }\n const manifest: MultiBundleManifest = {\n multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,\n handle: opts.handle ?? generateULID(),\n compartments: entries,\n }\n return encodeMultiBundle(manifest, inner)\n}\n\n/**\n * Read the pre-decrypt manifest of a bundle WITHOUT decrypting any\n * compartment. Accepts a multi-compartment `NDBM` bundle (returns its\n * N entries) OR a single v1 `NDB1` bundle (returns a 1-entry manifest,\n * for uniform handling). Throws on anything else.\n */\nexport async function readNoydbBundleManifest(bytes: Uint8Array): Promise<CompartmentManifest[]> {\n if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments]\n if (hasNoydbBundleMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n const env = readNoydbBundlePublicEnvelope(bytes)\n const entry: { -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K] } = {\n handle: header.handle,\n innerBytes: bytes.length,\n innerSha256: await sha256Hex(bytes),\n }\n if (env !== undefined) entry.publicEnvelope = env\n return [entry]\n }\n throw new Error('readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).')\n}\n\n/**\n * Extract one compartment's inner v1 `.noydb` bundle bytes, ready to\n * pass to `readNoydbBundle`. `selector` is a compartment `handle` or a\n * zero-based index. For a single v1 bundle, the bundle itself is the\n * only compartment.\n *\n * Does NOT verify the manifest `innerSha256` — it returns the raw\n * slice. Integrity is enforced downstream: `readNoydbBundle` verifies\n * the inner bundle's own `bodySha256`. Callers wanting an early,\n * pre-decrypt check can hash the returned bytes against the\n * compartment's `innerSha256`.\n */\nexport function readMultiVaultBundleCompartment(bytes: Uint8Array, selector: string | number): Uint8Array {\n if (typeof selector === 'number' && !Number.isInteger(selector)) {\n throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`)\n }\n if (hasNoydbBundleMagic(bytes) && !hasMultiMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n if (selector === 0 || selector === header.handle) return bytes\n throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment \"${header.handle}\".`)\n }\n const { manifest, inner } = decodeMultiBundle(bytes)\n const idx = typeof selector === 'number'\n ? selector\n : manifest.compartments.findIndex((c) => c.handle === selector)\n if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === 'number' ? `at index ${selector}` : `\"${selector}\"`}.`)\n return inner[idx]!\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ReadOnlyFrameError
3
- } from "./chunk-OTWT6BAJ.js";
3
+ } from "./chunk-4BB4T3O7.js";
4
4
 
5
5
  // src/shadow/vault-frame.ts
6
6
  var VaultFrame = class {
@@ -76,4 +76,4 @@ export {
76
76
  VaultFrame,
77
77
  CollectionFrame
78
78
  };
79
- //# sourceMappingURL=chunk-TGIJTNM3.js.map
79
+ //# sourceMappingURL=chunk-R5ZECURV.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MaterializedViewCycleError,
3
3
  MaterializedViewSourceUnknownError
4
- } from "./chunk-OTWT6BAJ.js";
4
+ } from "./chunk-4BB4T3O7.js";
5
5
 
6
6
  // src/materialized-views/dependency-analyzer.ts
7
7
  function analyzeDependencies(query) {
@@ -315,4 +315,4 @@ export {
315
315
  MaterializedViewRegistry,
316
316
  wrapDbWithPredicates
317
317
  };
318
- //# sourceMappingURL=chunk-KOAJ3TZM.js.map
318
+ //# sourceMappingURL=chunk-RFEXGW3L.js.map
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  ATTESTATIONS_COLLECTION,
3
3
  loadOrCreateSigner
4
- } from "./chunk-TAMRU7A2.js";
4
+ } from "./chunk-OKV7S356.js";
5
5
  import {
6
6
  generateULID
7
7
  } from "./chunk-FZU343FL.js";
8
8
  import {
9
9
  NOYDB_FORMAT_VERSION
10
- } from "./chunk-TA6HPKWQ.js";
10
+ } from "./chunk-LR7CODVN.js";
11
11
  import {
12
12
  encrypt
13
- } from "./chunk-37VGJM3T.js";
13
+ } from "./chunk-WQ3KAGOV.js";
14
14
  import {
15
15
  AttestationError
16
- } from "./chunk-OTWT6BAJ.js";
16
+ } from "./chunk-4BB4T3O7.js";
17
17
 
18
18
  // src/attestation/issue.ts
19
19
  import {
@@ -56,4 +56,4 @@ async function issueAttestationCore(ctx, args) {
56
56
  export {
57
57
  issueAttestationCore
58
58
  };
59
- //# sourceMappingURL=chunk-F5ILTHMU.js.map
59
+ //# sourceMappingURL=chunk-RNQPDV75.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NOYDB_FORMAT_VERSION
3
- } from "./chunk-TA6HPKWQ.js";
3
+ } from "./chunk-LR7CODVN.js";
4
4
  import {
5
5
  base64ToBuffer,
6
6
  bufferToBase64,
@@ -13,11 +13,11 @@ import {
13
13
  sha256Hex,
14
14
  unwrapCek,
15
15
  wrapCek
16
- } from "./chunk-37VGJM3T.js";
16
+ } from "./chunk-WQ3KAGOV.js";
17
17
  import {
18
18
  ConflictError,
19
19
  NotFoundError
20
- } from "./chunk-OTWT6BAJ.js";
20
+ } from "./chunk-4BB4T3O7.js";
21
21
 
22
22
  // src/blobs/mime-magic.ts
23
23
  function hex(s) {
@@ -1153,7 +1153,7 @@ var BlobSet = class {
1153
1153
  return this.buildResponse(slot, result.blob, { inline: true });
1154
1154
  }
1155
1155
  const aad = chunkAAD(slot.eTag, 0, result.blob.chunkCount);
1156
- const { decryptBytesWithAAD: decryptAAD } = await import("./crypto-456N7UVX.js");
1156
+ const { decryptBytesWithAAD: decryptAAD } = await import("./crypto-2LU6XUFF.js");
1157
1157
  const decrypted = await decryptAAD(envelope._iv, envelope._data, blobDEK, aad);
1158
1158
  const plaintext = result.blob.compression === "gzip" ? await decompressBytes(decrypted) : decrypted;
1159
1159
  const body = new ReadableStream({
@@ -1303,4 +1303,4 @@ export {
1303
1303
  memoryObjectProjection,
1304
1304
  importExternalObjects
1305
1305
  };
1306
- //# sourceMappingURL=chunk-WWVJXBOT.js.map
1306
+ //# sourceMappingURL=chunk-SGM7CK7R.js.map
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  base64ToBuffer,
6
6
  bufferToBase64
7
- } from "./chunk-37VGJM3T.js";
7
+ } from "./chunk-WQ3KAGOV.js";
8
8
  import {
9
9
  SessionExpiredError,
10
10
  SessionNotFoundError,
11
11
  SessionPolicyError,
12
12
  ValidationError
13
- } from "./chunk-OTWT6BAJ.js";
13
+ } from "./chunk-4BB4T3O7.js";
14
14
 
15
15
  // src/session/session.ts
16
16
  var subtle = globalThis.crypto.subtle;
@@ -364,4 +364,4 @@ export {
364
364
  clearDevUnlock,
365
365
  isDevUnlockActive
366
366
  };
367
- //# sourceMappingURL=chunk-7MRT7EPB.js.map
367
+ //# sourceMappingURL=chunk-SOQE5DUV.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TierNotGrantedError
3
- } from "./chunk-OTWT6BAJ.js";
3
+ } from "./chunk-4BB4T3O7.js";
4
4
 
5
5
  // src/team/tiers.ts
6
6
  function dekKey(collection, tier) {
@@ -20,7 +20,7 @@ function effectiveClearance(keyring, collection) {
20
20
  }
21
21
  function assertTierAccess(keyring, collection, tier) {
22
22
  if (tier <= 0) return;
23
- if (keyring.role === "owner" || keyring.role === "admin") return;
23
+ if (keyring.role === "owner" || keyring.role === "admin" || keyring.role === "custodian") return;
24
24
  if (!keyring.deks.has(dekKey(collection, tier))) {
25
25
  throw new TierNotGrantedError(collection, tier);
26
26
  }
@@ -31,4 +31,4 @@ export {
31
31
  effectiveClearance,
32
32
  assertTierAccess
33
33
  };
34
- //# sourceMappingURL=chunk-F5GWNSE2.js.map
34
+ //# sourceMappingURL=chunk-TOMSCJRV.js.map