@noy-db/hub 0.4.0-pre.1 → 0.4.0-pre.11

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 (605) hide show
  1. package/README.md +3 -4
  2. package/dist/api-ZDKTWNBB.js +20 -0
  3. package/dist/attestation/index.js +18 -18
  4. package/dist/{backup-LU2DTZTI.js → backup-2UX7PRM5.js} +13 -13
  5. package/dist/blobs/index.js +30 -15
  6. package/dist/blobs/index.js.map +1 -1
  7. package/dist/broker/index.js +12 -12
  8. package/dist/broker/index.js.map +1 -1
  9. package/dist/cargo/index.js +53 -43
  10. package/dist/{chunk-YTGDPCPW.js → chunk-2J6UEN2V.js} +42 -18
  11. package/dist/chunk-2J6UEN2V.js.map +1 -0
  12. package/dist/{chunk-IY23KFNZ.js → chunk-35NMVJ7I.js} +3 -3
  13. package/dist/{chunk-S3BFKGET.js → chunk-3HUYRN24.js} +4 -4
  14. package/dist/chunk-3HUYRN24.js.map +1 -0
  15. package/dist/{walk-XS3PKM6I.js → chunk-3V3XR4S4.js} +4 -13
  16. package/dist/{walk-XS3PKM6I.js.map → chunk-3V3XR4S4.js.map} +1 -1
  17. package/dist/{chunk-RTEK4C4I.js → chunk-4JQK3L4V.js} +2 -2
  18. package/dist/{chunk-3ELCWU56.js → chunk-4ZKNC6A6.js} +2 -2
  19. package/dist/{chunk-VQNJ7UZL.js → chunk-55LKVALY.js} +106 -10
  20. package/dist/chunk-55LKVALY.js.map +1 -0
  21. package/dist/{chunk-VAIS3SOM.js → chunk-55LX6FSX.js} +2 -2
  22. package/dist/chunk-5D2ALSM5.js +19 -0
  23. package/dist/chunk-5D2ALSM5.js.map +1 -0
  24. package/dist/{chunk-6HPG2YNX.js → chunk-5DRROK5W.js} +2 -2
  25. package/dist/{chunk-S6Q37VGE.js → chunk-5GQEU4DN.js} +2 -2
  26. package/dist/chunk-5JOFWL4G.js +25 -0
  27. package/dist/chunk-5JOFWL4G.js.map +1 -0
  28. package/dist/{chunk-TOPYT5U5.js → chunk-63FE525P.js} +6 -6
  29. package/dist/chunk-6LJY7X5A.js +18 -0
  30. package/dist/chunk-6LJY7X5A.js.map +1 -0
  31. package/dist/{chunk-JVBO4SZL.js → chunk-6UBZ6I5Z.js} +2 -2
  32. package/dist/{chunk-BOKIKJJB.js → chunk-6ZNSB3H6.js} +5 -17
  33. package/dist/chunk-6ZNSB3H6.js.map +1 -0
  34. package/dist/{chunk-BMQWTQZ4.js → chunk-7YVBQJ7K.js} +13 -355
  35. package/dist/chunk-7YVBQJ7K.js.map +1 -0
  36. package/dist/{chunk-UFEVO57O.js → chunk-ABS7FMMD.js} +6 -6
  37. package/dist/chunk-AFHQATY4.js +47 -0
  38. package/dist/chunk-AFHQATY4.js.map +1 -0
  39. package/dist/{chunk-HOONYZY2.js → chunk-AKKRXT23.js} +7 -7
  40. package/dist/chunk-AKKRXT23.js.map +1 -0
  41. package/dist/{chunk-DDHM2TLX.js → chunk-AT2JJEKJ.js} +4 -4
  42. package/dist/chunk-AT2JJEKJ.js.map +1 -0
  43. package/dist/{chunk-M75ZZHSR.js → chunk-BLBAQRBM.js} +2 -2
  44. package/dist/{chunk-3SV2EPMN.js → chunk-BLCWSJLN.js} +88 -81
  45. package/dist/chunk-BLCWSJLN.js.map +1 -0
  46. package/dist/chunk-CADUYBQD.js +151 -0
  47. package/dist/chunk-CADUYBQD.js.map +1 -0
  48. package/dist/{chunk-G6EQYAL6.js → chunk-CI32CAFS.js} +5 -5
  49. package/dist/{chunk-FH52K7EG.js → chunk-CUZLNGD5.js} +2 -6
  50. package/dist/{chunk-FH52K7EG.js.map → chunk-CUZLNGD5.js.map} +1 -1
  51. package/dist/{chunk-2P7EGNKF.js → chunk-CXQW2NWO.js} +145 -3
  52. package/dist/chunk-CXQW2NWO.js.map +1 -0
  53. package/dist/{chunk-6B4DYGWO.js → chunk-DABACXEF.js} +3 -3
  54. package/dist/{chunk-F6T6L2UK.js → chunk-DMH3VZU5.js} +4 -4
  55. package/dist/chunk-DSDXAKIP.js +50 -0
  56. package/dist/chunk-DSDXAKIP.js.map +1 -0
  57. package/dist/{chunk-MQ6WOPSY.js → chunk-DZ2JXHWK.js} +5 -5
  58. package/dist/chunk-DZFQVICS.js +23 -0
  59. package/dist/chunk-DZFQVICS.js.map +1 -0
  60. package/dist/chunk-E23UGFVC.js +63 -0
  61. package/dist/chunk-E23UGFVC.js.map +1 -0
  62. package/dist/{chunk-UBNCR3YK.js → chunk-EE7UHLKH.js} +4 -4
  63. package/dist/chunk-EIPVYUEP.js +654 -0
  64. package/dist/chunk-EIPVYUEP.js.map +1 -0
  65. package/dist/{chunk-EGCRBCNA.js → chunk-EKRSCRNM.js} +3 -3
  66. package/dist/{chunk-YMUGBZN2.js → chunk-FQ5CHJR7.js} +1 -1
  67. package/dist/chunk-FQ5CHJR7.js.map +1 -0
  68. package/dist/{chunk-LB6OH6K2.js → chunk-FQZ6XTQ7.js} +17 -20
  69. package/dist/chunk-FQZ6XTQ7.js.map +1 -0
  70. package/dist/{chunk-IRQY7IR5.js → chunk-FRMPM7WG.js} +4 -4
  71. package/dist/{chunk-DVUZMT2W.js → chunk-G2JUIDFA.js} +9 -9
  72. package/dist/{chunk-DVUZMT2W.js.map → chunk-G2JUIDFA.js.map} +1 -1
  73. package/dist/{chunk-RND5ZPNP.js → chunk-G6WWZNJP.js} +13 -13
  74. package/dist/chunk-G6WWZNJP.js.map +1 -0
  75. package/dist/chunk-GJW4HX2O.js +1 -0
  76. package/dist/{chunk-T6GU5PPZ.js → chunk-GU3IP74F.js} +6 -6
  77. package/dist/{chunk-5OI6BR4H.js → chunk-GWWOGNBK.js} +308 -18
  78. package/dist/chunk-GWWOGNBK.js.map +1 -0
  79. package/dist/{chunk-UNCOC7QH.js → chunk-H2GPHUZD.js} +12 -13
  80. package/dist/chunk-H2GPHUZD.js.map +1 -0
  81. package/dist/{chunk-7CI6CP7Z.js → chunk-HMU5P6RL.js} +5 -5
  82. package/dist/chunk-HMU5P6RL.js.map +1 -0
  83. package/dist/{chunk-YJV2UZ7H.js → chunk-I5GEJX3R.js} +5 -5
  84. package/dist/chunk-I5GEJX3R.js.map +1 -0
  85. package/dist/{chunk-GWKAVKHI.js → chunk-IG6KUWBX.js} +2 -2
  86. package/dist/chunk-IG6KUWBX.js.map +1 -0
  87. package/dist/{chunk-MTQPRQHB.js → chunk-IPUG56GJ.js} +15 -5
  88. package/dist/{chunk-MTQPRQHB.js.map → chunk-IPUG56GJ.js.map} +1 -1
  89. package/dist/{chunk-SMIRGMS7.js → chunk-IXNCZTWA.js} +2 -2
  90. package/dist/{chunk-RM2XV574.js → chunk-IXTSNGYY.js} +3 -3
  91. package/dist/{chunk-KUPKLSX5.js → chunk-IYZISPGD.js} +7 -5
  92. package/dist/chunk-IYZISPGD.js.map +1 -0
  93. package/dist/{chunk-SMGEYW6G.js → chunk-JDOMW53O.js} +26 -16
  94. package/dist/chunk-JDOMW53O.js.map +1 -0
  95. package/dist/{chunk-PK6QCH2C.js → chunk-JJZGIE4U.js} +6 -5
  96. package/dist/{chunk-DRWBEDYO.js → chunk-JYJFGD2H.js} +2 -2
  97. package/dist/{chunk-TAGR72IR.js → chunk-KRCBZYTZ.js} +26 -177
  98. package/dist/chunk-KRCBZYTZ.js.map +1 -0
  99. package/dist/{chunk-HPUWOVR7.js → chunk-L2DGWBCT.js} +14 -14
  100. package/dist/chunk-L2DGWBCT.js.map +1 -0
  101. package/dist/{chunk-VEALDPHW.js → chunk-L3YYLT4E.js} +15 -2
  102. package/dist/chunk-L3YYLT4E.js.map +1 -0
  103. package/dist/{chunk-A7JJLVGH.js → chunk-LNPUSMZL.js} +29 -31
  104. package/dist/chunk-LNPUSMZL.js.map +1 -0
  105. package/dist/{chunk-KUIB4B5Q.js → chunk-LNZKOUJR.js} +2 -2
  106. package/dist/{chunk-IM3QVF53.js → chunk-MBKVNOJS.js} +6 -6
  107. package/dist/chunk-MCHBCNCE.js +367 -0
  108. package/dist/chunk-MCHBCNCE.js.map +1 -0
  109. package/dist/{chunk-VCBHAE4R.js → chunk-MHMLXJ3I.js} +2 -2
  110. package/dist/chunk-MHMLXJ3I.js.map +1 -0
  111. package/dist/{chunk-WNGGJWF7.js → chunk-MSMJJB4J.js} +2 -2
  112. package/dist/chunk-MSMJJB4J.js.map +1 -0
  113. package/dist/{chunk-T36RFODW.js → chunk-MXUT7FTE.js} +2 -2
  114. package/dist/chunk-MXUT7FTE.js.map +1 -0
  115. package/dist/{chunk-BGK233EA.js → chunk-N4BBNYIB.js} +11 -9
  116. package/dist/chunk-N4BBNYIB.js.map +1 -0
  117. package/dist/{chunk-3PF6CRDT.js → chunk-NFIBXF4V.js} +1082 -1583
  118. package/dist/chunk-NFIBXF4V.js.map +1 -0
  119. package/dist/{chunk-LOF2W3JU.js → chunk-NFNJLRY7.js} +368 -52
  120. package/dist/chunk-NFNJLRY7.js.map +1 -0
  121. package/dist/{chunk-N6WF5PKC.js → chunk-NFZGZ4AK.js} +2 -2
  122. package/dist/{chunk-JRBNCUNT.js → chunk-NGSJZFGL.js} +21 -4
  123. package/dist/chunk-NGSJZFGL.js.map +1 -0
  124. package/dist/chunk-NJ4DYYO5.js +81 -0
  125. package/dist/chunk-NJ4DYYO5.js.map +1 -0
  126. package/dist/{chunk-2IALOXZS.js → chunk-NM5UYF6Q.js} +2 -2
  127. package/dist/chunk-NM5UYF6Q.js.map +1 -0
  128. package/dist/{chunk-JBBSYJHP.js → chunk-NYEFP7DY.js} +4 -4
  129. package/dist/chunk-NYEFP7DY.js.map +1 -0
  130. package/dist/{chunk-CCOP5XDW.js → chunk-NZ24MX4J.js} +8 -46
  131. package/dist/chunk-NZ24MX4J.js.map +1 -0
  132. package/dist/{chunk-KWVJAOIN.js → chunk-OLEPKFTW.js} +4 -4
  133. package/dist/chunk-OLEPKFTW.js.map +1 -0
  134. package/dist/{chunk-OF75ACKS.js → chunk-PEATRIYJ.js} +9 -9
  135. package/dist/chunk-PEOZ34EM.js +13 -0
  136. package/dist/chunk-PEOZ34EM.js.map +1 -0
  137. package/dist/{chunk-UC2ETWF3.js → chunk-PTHKZWEH.js} +2 -14
  138. package/dist/{chunk-UC2ETWF3.js.map → chunk-PTHKZWEH.js.map} +1 -1
  139. package/dist/chunk-PVEWA2DU.js +23 -0
  140. package/dist/chunk-PVEWA2DU.js.map +1 -0
  141. package/dist/{chunk-LSASLXGC.js → chunk-QBAC3GXA.js} +1 -1
  142. package/dist/chunk-QBAC3GXA.js.map +1 -0
  143. package/dist/{chunk-RDXW3OBQ.js → chunk-QD46HPZG.js} +2 -2
  144. package/dist/chunk-QD46HPZG.js.map +1 -0
  145. package/dist/{chunk-N55W7KUL.js → chunk-QDIH2744.js} +2 -2
  146. package/dist/{chunk-6HY2X62D.js → chunk-QJNCB5SK.js} +2 -2
  147. package/dist/{chunk-4BRCIYFG.js → chunk-QX76XVQH.js} +6 -6
  148. package/dist/chunk-QX76XVQH.js.map +1 -0
  149. package/dist/{chunk-W2OG6JOL.js → chunk-QZWTRENR.js} +24 -7
  150. package/dist/chunk-QZWTRENR.js.map +1 -0
  151. package/dist/{chunk-6NQMXTYC.js → chunk-RO5NM6UI.js} +2 -2
  152. package/dist/chunk-RO5NM6UI.js.map +1 -0
  153. package/dist/chunk-SGDPRCC4.js +1075 -0
  154. package/dist/chunk-SGDPRCC4.js.map +1 -0
  155. package/dist/{chunk-2PCAVW2I.js → chunk-SHEEBRZ4.js} +2 -2
  156. package/dist/chunk-SMY5X46Z.js +14 -0
  157. package/dist/chunk-SMY5X46Z.js.map +1 -0
  158. package/dist/{chunk-ISMV2QVG.js → chunk-TG634KCO.js} +11 -2
  159. package/dist/chunk-TG634KCO.js.map +1 -0
  160. package/dist/{chunk-J6Q7UVQE.js → chunk-TUXQSFHZ.js} +4 -16
  161. package/dist/{chunk-J6Q7UVQE.js.map → chunk-TUXQSFHZ.js.map} +1 -1
  162. package/dist/{chunk-GULTLPFB.js → chunk-UADPR6F4.js} +3 -3
  163. package/dist/{chunk-GULTLPFB.js.map → chunk-UADPR6F4.js.map} +1 -1
  164. package/dist/{chunk-ZEQWCBCM.js → chunk-UDHBXYGG.js} +27 -5
  165. package/dist/chunk-UDHBXYGG.js.map +1 -0
  166. package/dist/{chunk-RA5VTXXG.js → chunk-V6UQZA2H.js} +2 -2
  167. package/dist/chunk-VG2ZSFYD.js +32 -0
  168. package/dist/chunk-VG2ZSFYD.js.map +1 -0
  169. package/dist/chunk-VKQCVU2Z.js +21 -0
  170. package/dist/chunk-VKQCVU2Z.js.map +1 -0
  171. package/dist/{chunk-QDPZWTN2.js → chunk-W3G5REIU.js} +2 -2
  172. package/dist/{chunk-WEYZTLXN.js → chunk-W3L64Y3J.js} +2 -2
  173. package/dist/{chunk-ONTBCHCP.js → chunk-W66AM5IB.js} +2 -2
  174. package/dist/chunk-W66AM5IB.js.map +1 -0
  175. package/dist/{chunk-A5BDDEXK.js → chunk-WBKZUO5V.js} +26 -43
  176. package/dist/chunk-WBKZUO5V.js.map +1 -0
  177. package/dist/{chunk-CBSY2N76.js → chunk-WLXMTYGO.js} +2 -2
  178. package/dist/{chunk-3U3FBR7O.js → chunk-X3F5YJG2.js} +2 -2
  179. package/dist/{chunk-GQNGCEP5.js → chunk-X45JYIAY.js} +3 -3
  180. package/dist/chunk-X45JYIAY.js.map +1 -0
  181. package/dist/{chunk-6XE5TMPR.js → chunk-X4MVWPHV.js} +3 -3
  182. package/dist/chunk-X4MVWPHV.js.map +1 -0
  183. package/dist/chunk-XZHEOSQ2.js +16 -0
  184. package/dist/chunk-XZHEOSQ2.js.map +1 -0
  185. package/dist/chunk-Y2NBBT6K.js +18 -0
  186. package/dist/chunk-Y2NBBT6K.js.map +1 -0
  187. package/dist/{chunk-DDATL6PU.js → chunk-Y2NJBNX3.js} +8 -8
  188. package/dist/{chunk-DDATL6PU.js.map → chunk-Y2NJBNX3.js.map} +1 -1
  189. package/dist/chunk-YMUFFJCO.js +23 -0
  190. package/dist/chunk-YMUFFJCO.js.map +1 -0
  191. package/dist/{chunk-O7WJ47EF.js → chunk-YWWQM7KP.js} +5 -14
  192. package/dist/chunk-YWWQM7KP.js.map +1 -0
  193. package/dist/{chunk-7O3AYBC7.js → chunk-YZJSJOUI.js} +235 -65
  194. package/dist/chunk-YZJSJOUI.js.map +1 -0
  195. package/dist/{chunk-5WZXVULX.js → chunk-ZTLOXFPB.js} +2 -2
  196. package/dist/chunk-ZTLOXFPB.js.map +1 -0
  197. package/dist/classified/index.js +5 -5
  198. package/dist/{classified-marker-WQVIJAW2.js → classified-marker-7PKJBFCG.js} +3 -3
  199. package/dist/collection-facade-6I5K5IOD.js +45 -0
  200. package/dist/{computed-DSMPXG2Y.js → computed-AB45PS4V.js} +3 -3
  201. package/dist/consent/index.js +13 -9
  202. package/dist/consent/index.js.map +1 -1
  203. package/dist/cover/index.js +37 -0
  204. package/dist/crdt/index.js +4 -0
  205. package/dist/crdt/index.js.map +1 -1
  206. package/dist/custody/index.js +26 -0
  207. package/dist/{dead-filter-2A7IAJ3D.js → dead-filter-FL3WIUZS.js} +2 -2
  208. package/dist/{chunk-GYYCX5K6.js → delegation-QXZ4MPPH.js} +12 -6
  209. package/dist/{chunk-GYYCX5K6.js.map → delegation-QXZ4MPPH.js.map} +1 -1
  210. package/dist/derivations/index.js +12 -12
  211. package/dist/derive-VGS7FKE3.js +22 -0
  212. package/dist/directory/index.js +46 -0
  213. package/dist/dispatch-EGGC7UD7.js +72 -0
  214. package/dist/dispatch-EGGC7UD7.js.map +1 -0
  215. package/dist/dispatch-GDSTUTVP.js +194 -0
  216. package/dist/dispatch-GDSTUTVP.js.map +1 -0
  217. package/dist/{enclave-7MW6ZGXW.js → enclave-SPEEDYZ4.js} +11 -11
  218. package/dist/executor-IEBLTBCW.js +9 -0
  219. package/dist/executor-OTF556PL.js +28 -0
  220. package/dist/executor-RM7XWQDU.js +9 -0
  221. package/dist/export-accessible-P42BQ4PB.js +23 -0
  222. package/dist/extract-partition-TCYXRWBN.js +38 -0
  223. package/dist/{fanout-sidecar-WDYQ77VB.js → fanout-sidecar-SSMRSC2L.js} +9 -9
  224. package/dist/find-OZMTRIK3.js +11 -0
  225. package/dist/forget/index.js +11 -11
  226. package/dist/forget/index.js.map +1 -1
  227. package/dist/guards/index.js +6 -6
  228. package/dist/history/index.js +16 -12
  229. package/dist/history/index.js.map +1 -1
  230. package/dist/i18n/index.js +16 -14
  231. package/dist/i18n/index.js.map +1 -1
  232. package/dist/index.d.ts +42 -42
  233. package/dist/index.js +330 -2106
  234. package/dist/index.js.map +1 -1
  235. package/dist/indexing/index.js +4 -2
  236. package/dist/indexing/index.js.map +1 -1
  237. package/dist/introspection/index.js +28 -0
  238. package/dist/issue-FCKN5O6C.js +19 -0
  239. package/dist/kernel/best-effort-revert.d.ts +9 -1
  240. package/dist/kernel/collection-config.d.ts +12 -70
  241. package/dist/kernel/collection.d.ts +11 -23
  242. package/dist/kernel/enclave/crypto.d.ts +8 -8
  243. package/dist/kernel/enclave/index.d.ts +3 -3
  244. package/dist/kernel/errors.d.ts +41 -22
  245. package/dist/kernel/lazy.d.ts +30 -0
  246. package/dist/kernel/noydb.d.ts +81 -124
  247. package/dist/kernel/query/builder.d.ts +10 -10
  248. package/dist/kernel/query/index.d.ts +0 -6
  249. package/dist/kernel/query/scan-builder.d.ts +4 -4
  250. package/dist/kernel/sync-policy.d.ts +76 -4
  251. package/dist/kernel/types.d.ts +146 -86
  252. package/dist/kernel/validation.d.ts +33 -33
  253. package/dist/kernel/vault.d.ts +41 -229
  254. package/dist/kernel/via/dispatch.d.ts +7 -0
  255. package/dist/{ledger-33BC4TR7.js → ledger-6XBEVWYP.js} +11 -11
  256. package/dist/liberate-CYUOS4NC.js +24 -0
  257. package/dist/{link-set-QK22TDEX.js → link-set-NK6L2A5S.js} +11 -11
  258. package/dist/materialized-views/index.js +22 -19
  259. package/dist/money/index.js +31 -0
  260. package/dist/noydb-FZZIMLCI.js +81 -0
  261. package/dist/overlay-views/index.js +4 -4
  262. package/dist/periods/index.js +15 -13
  263. package/dist/pod/index.js +26 -12
  264. package/dist/{policy-NAHB2TUT.js → policy/index.js} +6 -6
  265. package/dist/port/with/archive-strategy.d.ts +31 -0
  266. package/dist/port/with/blob-strategy.d.ts +15 -5
  267. package/dist/port/with/collection-options.d.ts +171 -0
  268. package/dist/port/with/collection-registries.d.ts +62 -0
  269. package/dist/port/with/strategies.d.ts +134 -0
  270. package/dist/port/with/team-strategy.d.ts +3 -2
  271. package/dist/portability/index.js +8 -8
  272. package/dist/{post-register-JVTMJ6OW.js → post-register-VFIYISUK.js} +6 -6
  273. package/dist/query/index.js +6 -46
  274. package/dist/{aggregate → reduce}/index.js +24 -17
  275. package/dist/reduce/index.js.map +1 -0
  276. package/dist/register-UKU2J6MN.js +25 -0
  277. package/dist/registry-2VCWVHZS.js +19 -0
  278. package/dist/registry-7Y5WF7GS.js +9 -0
  279. package/dist/{registry-VW6P6A3J.js → registry-BWD2ED52.js} +2 -2
  280. package/dist/registry-DTWRJLSF.js +18 -0
  281. package/dist/request-withdrawal-JYDZ5XY2.js +31 -0
  282. package/dist/{reveal-LGBOM2BO.js → reveal-CL2BCW6A.js} +6 -6
  283. package/dist/revoke-2TSAD2T4.js +24 -0
  284. package/dist/satellites/index.js +1 -1
  285. package/dist/schema-update/index.js +26 -0
  286. package/dist/sealed-record/index.js +12 -12
  287. package/dist/search/index.js +36 -0
  288. package/dist/{seed-PWK45HDF.js → seed-NUVJEL7T.js} +12 -12
  289. package/dist/seed-NUVJEL7T.js.map +1 -0
  290. package/dist/sequence/index.js +30 -0
  291. package/dist/session/index.js +13 -9
  292. package/dist/session/index.js.map +1 -1
  293. package/dist/shadow/index.js +6 -2
  294. package/dist/shadow/index.js.map +1 -1
  295. package/dist/signer-K7Z2EOMG.js +25 -0
  296. package/dist/snapshots/index.js +14 -10
  297. package/dist/snapshots/index.js.map +1 -1
  298. package/dist/{stale-FJED42DM.js → stale-A4J26OIC.js} +11 -10
  299. package/dist/storage-YVHZUISN.js +23 -0
  300. package/dist/store/index.js +22 -0
  301. package/dist/{store-coordination-provider-APODTV4W.js → store-coordination-provider-EWRZL7XF.js} +3 -3
  302. package/dist/sync/index.js +15 -12
  303. package/dist/sync/index.js.map +1 -1
  304. package/dist/team/index.js +33 -48
  305. package/dist/tiers/index.js +10 -10
  306. package/dist/to/index.js +1 -1
  307. package/dist/{tx → transactions}/index.js +7 -3
  308. package/dist/transactions/index.js.map +1 -0
  309. package/dist/util/index.js +1 -1
  310. package/dist/{verify-26Y5GNMK.js → verify-7XWHJWUN.js} +5 -5
  311. package/dist/via/blob/active.d.ts +23 -7
  312. package/dist/via/blob/binding.d.ts +1 -1
  313. package/dist/via/blob/index.d.ts +7 -1
  314. package/dist/via/i18n/core.d.ts +1 -1
  315. package/dist/via/i18n/index.d.ts +2 -0
  316. package/dist/via/money/money-reducer.d.ts +2 -2
  317. package/dist/walk-P5D6CF4V.js +21 -0
  318. package/dist/with-audit/consent/index.d.ts +2 -0
  319. package/dist/with-audit/forget/active.d.ts +3 -3
  320. package/dist/with-audit/forget/index.d.ts +6 -5
  321. package/dist/with-audit/forget/strategy.d.ts +3 -3
  322. package/dist/with-audit/guards/executor.d.ts +4 -4
  323. package/dist/with-audit/guards/immutable-guard.d.ts +3 -3
  324. package/dist/with-audit/guards/index.d.ts +1 -1
  325. package/dist/with-audit/guards/registry.d.ts +3 -3
  326. package/dist/with-audit/guards/transition-guard.d.ts +3 -3
  327. package/dist/with-audit/guards/types.d.ts +10 -10
  328. package/dist/with-audit/guards/with-guard.d.ts +2 -2
  329. package/dist/with-audit/periods/index.d.ts +2 -0
  330. package/dist/with-audit/periods/vault-facade.d.ts +6 -0
  331. package/dist/with-audit/portability/export-accessible.d.ts +4 -4
  332. package/dist/with-audit/portability/request-withdrawal.d.ts +3 -3
  333. package/dist/with-audit/portability/withdraw-accessible.d.ts +2 -2
  334. package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
  335. package/dist/with-audit/tiers/index.d.ts +1 -0
  336. package/dist/with-cargo/adopt-partition.d.ts +7 -7
  337. package/dist/{legacy/kernel.d.ts → with-cargo/floor.d.ts} +4 -4
  338. package/dist/with-cargo/index.d.ts +9 -2
  339. package/dist/with-commit/crdt/index.d.ts +2 -0
  340. package/dist/with-commit/history/index.d.ts +2 -0
  341. package/dist/with-commit/history/time-machine.d.ts +2 -2
  342. package/dist/with-commit/numbering/descriptor.d.ts +16 -6
  343. package/dist/with-commit/tx/active.d.ts +5 -5
  344. package/dist/with-commit/tx/index.d.ts +2 -2
  345. package/dist/with-commit/tx/invariants.d.ts +1 -1
  346. package/dist/with-commit/tx/strategy.d.ts +3 -3
  347. package/dist/with-fork/shadow/index.d.ts +2 -0
  348. package/dist/with-fork/snapshots/active.d.ts +2 -2
  349. package/dist/with-fork/snapshots/index.d.ts +3 -1
  350. package/dist/with-fork/snapshots/noydb-facade.d.ts +3 -3
  351. package/dist/with-fork/snapshots/strategy.d.ts +2 -2
  352. package/dist/with-formula/derivations/dispatch.d.ts +98 -0
  353. package/dist/with-formula/derivations/executor.d.ts +2 -2
  354. package/dist/with-formula/derivations/index.d.ts +4 -1
  355. package/dist/with-formula/derivations/registry.d.ts +3 -3
  356. package/dist/with-formula/derivations/stale.d.ts +2 -2
  357. package/dist/with-formula/derivations/types.d.ts +3 -3
  358. package/dist/with-formula/derivations/with-derivation.d.ts +2 -2
  359. package/dist/with-formula/derivations/with-rollup.d.ts +15 -8
  360. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +3 -3
  361. package/dist/with-formula/materialized-views/dispatch.d.ts +75 -0
  362. package/dist/with-formula/materialized-views/index.d.ts +2 -1
  363. package/dist/with-formula/materialized-views/registry.d.ts +4 -4
  364. package/dist/with-formula/materialized-views/types.d.ts +11 -11
  365. package/dist/with-formula/materialized-views/with-materialized-view.d.ts +2 -2
  366. package/dist/with-formula/overlay-views/index.d.ts +1 -1
  367. package/dist/with-formula/overlay-views/registry.d.ts +4 -4
  368. package/dist/with-formula/overlay-views/types.d.ts +3 -3
  369. package/dist/with-formula/overlay-views/virtual-collection.d.ts +2 -2
  370. package/dist/with-formula/overlay-views/with-overlayed-view.d.ts +2 -2
  371. package/dist/with-lookup/indexing/active.d.ts +5 -5
  372. package/dist/with-lookup/indexing/index.d.ts +3 -1
  373. package/dist/with-lookup/indexing/strategy.d.ts +3 -3
  374. package/dist/with-lookup/{aggregate → reduce}/active.d.ts +8 -8
  375. package/dist/with-lookup/{aggregate → reduce}/groupby.d.ts +21 -21
  376. package/dist/with-lookup/reduce/index.d.ts +34 -0
  377. package/dist/with-lookup/{aggregate → reduce}/reducers.d.ts +11 -12
  378. package/dist/with-lookup/{aggregate/aggregation.d.ts → reduce/reduction.d.ts} +21 -21
  379. package/dist/with-lookup/{aggregate → reduce}/strategy.d.ts +15 -15
  380. package/dist/with-lookup/search/build-docs.d.ts +7 -2
  381. package/dist/with-lookup/search/index.d.ts +1 -1
  382. package/dist/with-party/broker/index.d.ts +1 -0
  383. package/dist/with-party/broker/seed.d.ts +1 -1
  384. package/dist/with-party/custody/liberate.d.ts +3 -3
  385. package/dist/with-party/directory/cover/index.d.ts +1 -5
  386. package/dist/with-party/directory/cover/schema.d.ts +0 -6
  387. package/dist/with-party/directory/cover/storage.d.ts +0 -8
  388. package/dist/with-party/directory/cover/types.d.ts +0 -21
  389. package/dist/with-party/directory/index.d.ts +2 -0
  390. package/dist/with-party/session/dev-unlock.d.ts +2 -2
  391. package/dist/with-party/session/index.d.ts +2 -0
  392. package/dist/with-party/session/session.d.ts +2 -2
  393. package/dist/with-party/team/deed.d.ts +8 -8
  394. package/dist/with-party/team/index.d.ts +4 -7
  395. package/dist/with-party/team/keyring.d.ts +83 -35
  396. package/dist/with-party/team/{managed-passphrase.d.ts → managed-secret.d.ts} +27 -27
  397. package/dist/with-party/team/noydb-facade.d.ts +43 -42
  398. package/dist/with-party/team/peer-recover.d.ts +13 -13
  399. package/dist/with-party/team/recovery.d.ts +5 -5
  400. package/dist/with-party/team/rotate-recover.d.ts +30 -30
  401. package/dist/with-pod/bundle.d.ts +30 -32
  402. package/dist/with-pod/format.d.ts +2 -2
  403. package/dist/with-pod/index.d.ts +2 -1
  404. package/dist/with-shape/blobs/blob-compaction.d.ts +43 -3
  405. package/dist/with-shape/blobs/blob-pinning.d.ts +112 -0
  406. package/dist/with-shape/blobs/blob-set.d.ts +86 -2
  407. package/dist/with-shape/introspection/index.d.ts +6 -0
  408. package/dist/with-shape/schema-update/index.d.ts +1 -0
  409. package/dist/with-store/index.d.ts +3 -2
  410. package/dist/with-store/route-store.d.ts +1 -1
  411. package/dist/{with-party/team/sync-active.d.ts → with-sync/active.d.ts} +1 -1
  412. package/dist/{with-party/team/sync-credentials.d.ts → with-sync/credentials.d.ts} +3 -3
  413. package/dist/{with-party/team/sync.d.ts → with-sync/engine.d.ts} +5 -5
  414. package/dist/{with-party/sync → with-sync}/index.d.ts +4 -2
  415. package/dist/{with-party/team/sync-period-scope.d.ts → with-sync/period-scope.d.ts} +2 -2
  416. package/dist/{with-party/team → with-sync}/presence.d.ts +2 -2
  417. package/dist/{with-party/team/sync-strategy.d.ts → with-sync/strategy.d.ts} +6 -6
  418. package/dist/{with-party/team/sync-transaction.d.ts → with-sync/transaction.d.ts} +3 -3
  419. package/dist/withdraw-accessible-A2PWF5MZ.js +28 -0
  420. package/package.json +45 -36
  421. package/dist/aggregate/index.js.map +0 -1
  422. package/dist/api-IQFZJSQO.js +0 -20
  423. package/dist/as/index.js +0 -30
  424. package/dist/at/index.js +0 -1
  425. package/dist/bundle/index.js +0 -105
  426. package/dist/by/index.js +0 -11
  427. package/dist/chunk-2IALOXZS.js.map +0 -1
  428. package/dist/chunk-2MUZ3LY6.js +0 -205
  429. package/dist/chunk-2MUZ3LY6.js.map +0 -1
  430. package/dist/chunk-2P7EGNKF.js.map +0 -1
  431. package/dist/chunk-3PF6CRDT.js.map +0 -1
  432. package/dist/chunk-3SV2EPMN.js.map +0 -1
  433. package/dist/chunk-4BRCIYFG.js.map +0 -1
  434. package/dist/chunk-5OI6BR4H.js.map +0 -1
  435. package/dist/chunk-5WZXVULX.js.map +0 -1
  436. package/dist/chunk-6NQMXTYC.js.map +0 -1
  437. package/dist/chunk-6XE5TMPR.js.map +0 -1
  438. package/dist/chunk-7CI6CP7Z.js.map +0 -1
  439. package/dist/chunk-7O3AYBC7.js.map +0 -1
  440. package/dist/chunk-A5BDDEXK.js.map +0 -1
  441. package/dist/chunk-A7JJLVGH.js.map +0 -1
  442. package/dist/chunk-BGK233EA.js.map +0 -1
  443. package/dist/chunk-BMQWTQZ4.js.map +0 -1
  444. package/dist/chunk-BOKIKJJB.js.map +0 -1
  445. package/dist/chunk-CCOP5XDW.js.map +0 -1
  446. package/dist/chunk-CHFZDSE4.js +0 -1
  447. package/dist/chunk-DDHM2TLX.js.map +0 -1
  448. package/dist/chunk-GQNGCEP5.js.map +0 -1
  449. package/dist/chunk-GVZQ4NAM.js +0 -14
  450. package/dist/chunk-GVZQ4NAM.js.map +0 -1
  451. package/dist/chunk-GWKAVKHI.js.map +0 -1
  452. package/dist/chunk-HOONYZY2.js.map +0 -1
  453. package/dist/chunk-HPUWOVR7.js.map +0 -1
  454. package/dist/chunk-ISMV2QVG.js.map +0 -1
  455. package/dist/chunk-JBBSYJHP.js.map +0 -1
  456. package/dist/chunk-JRBNCUNT.js.map +0 -1
  457. package/dist/chunk-JZWWLLVY.js +0 -99
  458. package/dist/chunk-JZWWLLVY.js.map +0 -1
  459. package/dist/chunk-KUPKLSX5.js.map +0 -1
  460. package/dist/chunk-KWVJAOIN.js.map +0 -1
  461. package/dist/chunk-LB6OH6K2.js.map +0 -1
  462. package/dist/chunk-LB7FD65R.js +0 -163
  463. package/dist/chunk-LB7FD65R.js.map +0 -1
  464. package/dist/chunk-LOF2W3JU.js.map +0 -1
  465. package/dist/chunk-LSASLXGC.js.map +0 -1
  466. package/dist/chunk-O7WJ47EF.js.map +0 -1
  467. package/dist/chunk-ONTBCHCP.js.map +0 -1
  468. package/dist/chunk-PT37L5DV.js +0 -255
  469. package/dist/chunk-PT37L5DV.js.map +0 -1
  470. package/dist/chunk-RDXW3OBQ.js.map +0 -1
  471. package/dist/chunk-RND5ZPNP.js.map +0 -1
  472. package/dist/chunk-S3BFKGET.js.map +0 -1
  473. package/dist/chunk-SMGEYW6G.js.map +0 -1
  474. package/dist/chunk-T36RFODW.js.map +0 -1
  475. package/dist/chunk-TAGR72IR.js.map +0 -1
  476. package/dist/chunk-UNCOC7QH.js.map +0 -1
  477. package/dist/chunk-VCBHAE4R.js.map +0 -1
  478. package/dist/chunk-VEALDPHW.js.map +0 -1
  479. package/dist/chunk-VQNJ7UZL.js.map +0 -1
  480. package/dist/chunk-W2OG6JOL.js.map +0 -1
  481. package/dist/chunk-WNGGJWF7.js.map +0 -1
  482. package/dist/chunk-YJV2UZ7H.js.map +0 -1
  483. package/dist/chunk-YMUGBZN2.js.map +0 -1
  484. package/dist/chunk-YTGDPCPW.js.map +0 -1
  485. package/dist/chunk-ZEQWCBCM.js.map +0 -1
  486. package/dist/collection-facade-MJXSC3Q6.js +0 -44
  487. package/dist/cover-B5SJDHR3.js +0 -52
  488. package/dist/delegation-A5A75KQO.js +0 -25
  489. package/dist/derive-HJSMH7RA.js +0 -21
  490. package/dist/executor-AXE4XMLT.js +0 -26
  491. package/dist/executor-KGNLJD6M.js +0 -9
  492. package/dist/executor-XGIS6CR7.js +0 -9
  493. package/dist/export-accessible-VVBJM3MM.js +0 -23
  494. package/dist/extract-partition-LGGBTQET.js +0 -38
  495. package/dist/find-YS6XWB46.js +0 -11
  496. package/dist/in/index.js +0 -1
  497. package/dist/issue-LSR5PS6H.js +0 -19
  498. package/dist/legacy/bundle.d.ts +0 -30
  499. package/dist/liberate-GBSAYLPJ.js +0 -24
  500. package/dist/noydb-MTUBMWFE.js +0 -70
  501. package/dist/on/index.js +0 -17
  502. package/dist/port/as/index.d.ts +0 -26
  503. package/dist/port/at/index.d.ts +0 -18
  504. package/dist/port/in/index.d.ts +0 -21
  505. package/dist/port/on/index.d.ts +0 -27
  506. package/dist/port/ui/index.d.ts +0 -21
  507. package/dist/port/with/index.d.ts +0 -18
  508. package/dist/register-X462DNDM.js +0 -23
  509. package/dist/registry-3XMCT7MQ.js +0 -18
  510. package/dist/registry-KHD2I3M2.js +0 -19
  511. package/dist/registry-NPOWJHC4.js +0 -9
  512. package/dist/request-withdrawal-U7K3JTMY.js +0 -31
  513. package/dist/revoke-OCWDSWRQ.js +0 -24
  514. package/dist/seed-PWK45HDF.js.map +0 -1
  515. package/dist/signer-3YFBLZRN.js +0 -25
  516. package/dist/storage-W3GURVFU.js +0 -23
  517. package/dist/tx/index.js.map +0 -1
  518. package/dist/ui/index.js +0 -1
  519. package/dist/with/index.js +0 -31
  520. package/dist/with-lookup/aggregate/index.d.ts +0 -23
  521. package/dist/withdraw-accessible-Y3B2535F.js +0 -28
  522. /package/dist/{api-IQFZJSQO.js.map → api-ZDKTWNBB.js.map} +0 -0
  523. /package/dist/{backup-LU2DTZTI.js.map → backup-2UX7PRM5.js.map} +0 -0
  524. /package/dist/{chunk-IY23KFNZ.js.map → chunk-35NMVJ7I.js.map} +0 -0
  525. /package/dist/{chunk-RTEK4C4I.js.map → chunk-4JQK3L4V.js.map} +0 -0
  526. /package/dist/{chunk-3ELCWU56.js.map → chunk-4ZKNC6A6.js.map} +0 -0
  527. /package/dist/{chunk-VAIS3SOM.js.map → chunk-55LX6FSX.js.map} +0 -0
  528. /package/dist/{chunk-6HPG2YNX.js.map → chunk-5DRROK5W.js.map} +0 -0
  529. /package/dist/{chunk-S6Q37VGE.js.map → chunk-5GQEU4DN.js.map} +0 -0
  530. /package/dist/{chunk-TOPYT5U5.js.map → chunk-63FE525P.js.map} +0 -0
  531. /package/dist/{chunk-JVBO4SZL.js.map → chunk-6UBZ6I5Z.js.map} +0 -0
  532. /package/dist/{chunk-UFEVO57O.js.map → chunk-ABS7FMMD.js.map} +0 -0
  533. /package/dist/{chunk-M75ZZHSR.js.map → chunk-BLBAQRBM.js.map} +0 -0
  534. /package/dist/{chunk-G6EQYAL6.js.map → chunk-CI32CAFS.js.map} +0 -0
  535. /package/dist/{chunk-6B4DYGWO.js.map → chunk-DABACXEF.js.map} +0 -0
  536. /package/dist/{chunk-F6T6L2UK.js.map → chunk-DMH3VZU5.js.map} +0 -0
  537. /package/dist/{chunk-MQ6WOPSY.js.map → chunk-DZ2JXHWK.js.map} +0 -0
  538. /package/dist/{chunk-UBNCR3YK.js.map → chunk-EE7UHLKH.js.map} +0 -0
  539. /package/dist/{chunk-EGCRBCNA.js.map → chunk-EKRSCRNM.js.map} +0 -0
  540. /package/dist/{chunk-IRQY7IR5.js.map → chunk-FRMPM7WG.js.map} +0 -0
  541. /package/dist/{as/index.js.map → chunk-GJW4HX2O.js.map} +0 -0
  542. /package/dist/{chunk-T6GU5PPZ.js.map → chunk-GU3IP74F.js.map} +0 -0
  543. /package/dist/{chunk-SMIRGMS7.js.map → chunk-IXNCZTWA.js.map} +0 -0
  544. /package/dist/{chunk-RM2XV574.js.map → chunk-IXTSNGYY.js.map} +0 -0
  545. /package/dist/{chunk-PK6QCH2C.js.map → chunk-JJZGIE4U.js.map} +0 -0
  546. /package/dist/{chunk-DRWBEDYO.js.map → chunk-JYJFGD2H.js.map} +0 -0
  547. /package/dist/{chunk-KUIB4B5Q.js.map → chunk-LNZKOUJR.js.map} +0 -0
  548. /package/dist/{chunk-IM3QVF53.js.map → chunk-MBKVNOJS.js.map} +0 -0
  549. /package/dist/{chunk-N6WF5PKC.js.map → chunk-NFZGZ4AK.js.map} +0 -0
  550. /package/dist/{chunk-OF75ACKS.js.map → chunk-PEATRIYJ.js.map} +0 -0
  551. /package/dist/{chunk-N55W7KUL.js.map → chunk-QDIH2744.js.map} +0 -0
  552. /package/dist/{chunk-6HY2X62D.js.map → chunk-QJNCB5SK.js.map} +0 -0
  553. /package/dist/{chunk-2PCAVW2I.js.map → chunk-SHEEBRZ4.js.map} +0 -0
  554. /package/dist/{chunk-RA5VTXXG.js.map → chunk-V6UQZA2H.js.map} +0 -0
  555. /package/dist/{chunk-QDPZWTN2.js.map → chunk-W3G5REIU.js.map} +0 -0
  556. /package/dist/{chunk-WEYZTLXN.js.map → chunk-W3L64Y3J.js.map} +0 -0
  557. /package/dist/{chunk-CBSY2N76.js.map → chunk-WLXMTYGO.js.map} +0 -0
  558. /package/dist/{chunk-3U3FBR7O.js.map → chunk-X3F5YJG2.js.map} +0 -0
  559. /package/dist/{classified-marker-WQVIJAW2.js.map → classified-marker-7PKJBFCG.js.map} +0 -0
  560. /package/dist/{at/index.js.map → collection-facade-6I5K5IOD.js.map} +0 -0
  561. /package/dist/{bundle/index.js.map → computed-AB45PS4V.js.map} +0 -0
  562. /package/dist/{by → cover}/index.js.map +0 -0
  563. /package/dist/{in → custody}/index.js.map +0 -0
  564. /package/dist/{dead-filter-2A7IAJ3D.js.map → dead-filter-FL3WIUZS.js.map} +0 -0
  565. /package/dist/{chunk-CHFZDSE4.js.map → derive-VGS7FKE3.js.map} +0 -0
  566. /package/dist/{on → directory}/index.js.map +0 -0
  567. /package/dist/{collection-facade-MJXSC3Q6.js.map → enclave-SPEEDYZ4.js.map} +0 -0
  568. /package/dist/{computed-DSMPXG2Y.js.map → executor-IEBLTBCW.js.map} +0 -0
  569. /package/dist/{cover-B5SJDHR3.js.map → executor-OTF556PL.js.map} +0 -0
  570. /package/dist/{delegation-A5A75KQO.js.map → executor-RM7XWQDU.js.map} +0 -0
  571. /package/dist/{derive-HJSMH7RA.js.map → export-accessible-P42BQ4PB.js.map} +0 -0
  572. /package/dist/{enclave-7MW6ZGXW.js.map → extract-partition-TCYXRWBN.js.map} +0 -0
  573. /package/dist/{fanout-sidecar-WDYQ77VB.js.map → fanout-sidecar-SSMRSC2L.js.map} +0 -0
  574. /package/dist/{executor-AXE4XMLT.js.map → find-OZMTRIK3.js.map} +0 -0
  575. /package/dist/{ui → introspection}/index.js.map +0 -0
  576. /package/dist/{executor-KGNLJD6M.js.map → issue-FCKN5O6C.js.map} +0 -0
  577. /package/dist/{executor-XGIS6CR7.js.map → ledger-6XBEVWYP.js.map} +0 -0
  578. /package/dist/{export-accessible-VVBJM3MM.js.map → liberate-CYUOS4NC.js.map} +0 -0
  579. /package/dist/{extract-partition-LGGBTQET.js.map → link-set-NK6L2A5S.js.map} +0 -0
  580. /package/dist/{with → money}/index.js.map +0 -0
  581. /package/dist/{find-YS6XWB46.js.map → noydb-FZZIMLCI.js.map} +0 -0
  582. /package/dist/{issue-LSR5PS6H.js.map → policy/index.js.map} +0 -0
  583. /package/dist/{post-register-JVTMJ6OW.js.map → post-register-VFIYISUK.js.map} +0 -0
  584. /package/dist/{ledger-33BC4TR7.js.map → register-UKU2J6MN.js.map} +0 -0
  585. /package/dist/{liberate-GBSAYLPJ.js.map → registry-2VCWVHZS.js.map} +0 -0
  586. /package/dist/{link-set-QK22TDEX.js.map → registry-7Y5WF7GS.js.map} +0 -0
  587. /package/dist/{noydb-MTUBMWFE.js.map → registry-BWD2ED52.js.map} +0 -0
  588. /package/dist/{policy-NAHB2TUT.js.map → registry-DTWRJLSF.js.map} +0 -0
  589. /package/dist/{register-X462DNDM.js.map → request-withdrawal-JYDZ5XY2.js.map} +0 -0
  590. /package/dist/{reveal-LGBOM2BO.js.map → reveal-CL2BCW6A.js.map} +0 -0
  591. /package/dist/{registry-3XMCT7MQ.js.map → revoke-2TSAD2T4.js.map} +0 -0
  592. /package/dist/{registry-KHD2I3M2.js.map → schema-update/index.js.map} +0 -0
  593. /package/dist/{registry-NPOWJHC4.js.map → search/index.js.map} +0 -0
  594. /package/dist/{registry-VW6P6A3J.js.map → sequence/index.js.map} +0 -0
  595. /package/dist/{request-withdrawal-U7K3JTMY.js.map → signer-K7Z2EOMG.js.map} +0 -0
  596. /package/dist/{revoke-OCWDSWRQ.js.map → stale-A4J26OIC.js.map} +0 -0
  597. /package/dist/{signer-3YFBLZRN.js.map → storage-YVHZUISN.js.map} +0 -0
  598. /package/dist/{stale-FJED42DM.js.map → store/index.js.map} +0 -0
  599. /package/dist/{store-coordination-provider-APODTV4W.js.map → store-coordination-provider-EWRZL7XF.js.map} +0 -0
  600. /package/dist/{verify-26Y5GNMK.js.map → verify-7XWHJWUN.js.map} +0 -0
  601. /package/dist/{storage-W3GURVFU.js.map → walk-P5D6CF4V.js.map} +0 -0
  602. /package/dist/with-lookup/{aggregate → reduce}/canonical-key.d.ts +0 -0
  603. /package/dist/{with-party → with-sync}/tab-coordination.d.ts +0 -0
  604. /package/dist/{with-party → with-sync}/tab-write-relay.d.ts +0 -0
  605. /package/dist/{withdraw-accessible-Y3B2535F.js.map → withdraw-accessible-A2PWF5MZ.js.map} +0 -0
@@ -1,255 +0,0 @@
1
- import {
2
- hasExportCapability,
3
- hasImportCapability
4
- } from "./chunk-3SV2EPMN.js";
5
- import {
6
- ExportCapabilityError,
7
- ImportCapabilityError
8
- } from "./chunk-W2OG6JOL.js";
9
-
10
- // src/port/with/capabilities.ts
11
- function assertCanExport(keyring, tier, format) {
12
- if (tier === "plaintext") {
13
- if (format === void 0) {
14
- throw new Error("vault.assertCanExport: plaintext tier requires a format");
15
- }
16
- if (!hasExportCapability(keyring, "plaintext", format)) {
17
- throw new ExportCapabilityError({
18
- tier: "plaintext",
19
- userId: keyring.userId,
20
- format
21
- });
22
- }
23
- return;
24
- }
25
- if (!hasExportCapability(keyring, "bundle")) {
26
- throw new ExportCapabilityError({
27
- tier: "bundle",
28
- userId: keyring.userId
29
- });
30
- }
31
- }
32
- function assertCanImport(keyring, tier, format) {
33
- if (tier === "plaintext") {
34
- if (format === void 0) {
35
- throw new Error("vault.assertCanImport: plaintext tier requires a format");
36
- }
37
- if (!hasImportCapability(keyring, "plaintext", format)) {
38
- throw new ImportCapabilityError({
39
- tier: "plaintext",
40
- userId: keyring.userId,
41
- format
42
- });
43
- }
44
- return;
45
- }
46
- if (!hasImportCapability(keyring, "bundle")) {
47
- throw new ImportCapabilityError({
48
- tier: "bundle",
49
- userId: keyring.userId
50
- });
51
- }
52
- }
53
- function canExport(keyring, tier, format) {
54
- if (tier === "plaintext") {
55
- if (format === void 0) return false;
56
- return hasExportCapability(keyring, "plaintext", format);
57
- }
58
- return hasExportCapability(keyring, "bundle");
59
- }
60
- function canImport(keyring, tier, format) {
61
- if (tier === "plaintext") {
62
- if (format === void 0) return false;
63
- return hasImportCapability(keyring, "plaintext", format);
64
- }
65
- return hasImportCapability(keyring, "bundle");
66
- }
67
-
68
- // src/port/with/write-hooks.ts
69
- var WriteHookRegistry = class {
70
- #before = [];
71
- #after = [];
72
- #suppressed = false;
73
- /** True while handlers are running — used by the write path to skip nested firing. */
74
- get suppressed() {
75
- return this.#suppressed;
76
- }
77
- /** True when any hook is registered (cheap gate for the write path). */
78
- get hasHandlers() {
79
- return this.#before.length > 0 || this.#after.length > 0;
80
- }
81
- onBeforeWrite(handler) {
82
- this.#before.push(handler);
83
- return () => {
84
- const i = this.#before.indexOf(handler);
85
- if (i >= 0) this.#before.splice(i, 1);
86
- };
87
- }
88
- onAfterWrite(handler) {
89
- this.#after.push(handler);
90
- return () => {
91
- const i = this.#after.indexOf(handler);
92
- if (i >= 0) this.#after.splice(i, 1);
93
- };
94
- }
95
- /** Run before-hooks (awaited, in order). A throw propagates and aborts the write. */
96
- async runBefore(event) {
97
- if (this.#before.length === 0) return;
98
- this.#suppressed = true;
99
- try {
100
- for (const h of this.#before.slice()) await h(event);
101
- } finally {
102
- this.#suppressed = false;
103
- }
104
- }
105
- /** Run after-hooks (awaited, in order). Per-handler errors are warned, not thrown. */
106
- async runAfter(event) {
107
- if (this.#after.length === 0) return;
108
- this.#suppressed = true;
109
- try {
110
- for (const h of this.#after.slice()) {
111
- try {
112
- await h(event);
113
- } catch (err) {
114
- console.warn(
115
- `[noy-db] onAfterWrite handler failed for ${event.collection}/${event.docId}: ` + (err instanceof Error ? err.message : String(err))
116
- );
117
- }
118
- }
119
- } finally {
120
- this.#suppressed = false;
121
- }
122
- }
123
- };
124
-
125
- // src/port/with/service-bus.ts
126
- var ServiceBus = class {
127
- #handlers = /* @__PURE__ */ new Map();
128
- #gateHandlers = /* @__PURE__ */ new Map();
129
- #depth = 0;
130
- /** Register a handler for an observe point. Returns an unsubscribe fn. */
131
- register(point, handler) {
132
- let arr = this.#handlers.get(point);
133
- if (!arr) {
134
- arr = [];
135
- this.#handlers.set(point, arr);
136
- }
137
- arr.push(handler);
138
- return () => {
139
- const a = this.#handlers.get(point);
140
- if (!a) return;
141
- const i = a.indexOf(handler);
142
- if (i >= 0) a.splice(i, 1);
143
- };
144
- }
145
- /** Cheap gate for the write path — true when any handler is registered for the point. */
146
- hasHandlers(point) {
147
- const a = this.#handlers.get(point);
148
- return a !== void 0 && a.length > 0;
149
- }
150
- /**
151
- * True while one or more dispatches are in flight. Backed by a depth counter
152
- * so that two concurrent async dispatches (`Promise.all([put('a'), put('b')])`
153
- * each captured `busAfterPut=true` at their respective put() tops while depth
154
- * was 0) both proceed independently — the counter stays > 0 until BOTH finish,
155
- * so any nested write attempted by a handler still sees `dispatching === true`
156
- * and is suppressed by the write-path gate in `collection.ts`
157
- * (`busAfterPut = hasHandlers('afterPut') && !dispatching`). Re-entrancy
158
- * suppression lives exclusively on that write-path gate; concurrent independent
159
- * dispatches must not drop each other's events.
160
- */
161
- get dispatching() {
162
- return this.#depth > 0;
163
- }
164
- /**
165
- * Dispatch in registration order, awaited. Per-handler errors are warned, not
166
- * thrown — an observe handler must never abort a completed write. A
167
- * re-entrancy guard suppresses nested firing so a handler that itself writes
168
- * cannot loop (same rationale as WriteHookRegistry.#suppressed).
169
- */
170
- async dispatch(point, event) {
171
- const a = this.#handlers.get(point);
172
- if (!a || a.length === 0) return;
173
- this.#depth++;
174
- try {
175
- for (const h of a.slice()) {
176
- try {
177
- await h(event);
178
- } catch (err) {
179
- console.warn(
180
- `[noy-db] service observe handler failed at ${point}: ` + (err instanceof Error ? err.message : String(err))
181
- );
182
- }
183
- }
184
- } finally {
185
- this.#depth--;
186
- }
187
- }
188
- /**
189
- * Register a write-gating handler. A throw from the handler ABORTS the
190
- * write. Returns an unsubscribe fn. See {@link GateRegisterOptions} for
191
- * the `needsPrior` prior-read declaration (#267).
192
- */
193
- registerGate(point, handler, opts) {
194
- let arr = this.#gateHandlers.get(point);
195
- if (!arr) {
196
- arr = [];
197
- this.#gateHandlers.set(point, arr);
198
- }
199
- const entry = { fn: handler, needsPrior: opts?.needsPrior !== false };
200
- arr.push(entry);
201
- return () => {
202
- const a = this.#gateHandlers.get(point);
203
- if (!a) return;
204
- const i = a.indexOf(entry);
205
- if (i >= 0) a.splice(i, 1);
206
- };
207
- }
208
- /** Cheap gate for the write path — true when any gate handler is registered for the point. */
209
- hasGateHandlers(point) {
210
- const a = this.#gateHandlers.get(point);
211
- return a !== void 0 && a.length > 0;
212
- }
213
- /**
214
- * True when at least one gate handler at `point` needs the prior record
215
- * (the default). False when the point has no handlers or every handler
216
- * registered with `needsPrior: false` — the write path then skips the
217
- * prior-read before dispatching (#267 prior-read elision).
218
- */
219
- gateNeedsPrior(point) {
220
- const a = this.#gateHandlers.get(point);
221
- if (!a) return false;
222
- return a.some((e) => e.needsPrior);
223
- }
224
- /**
225
- * Run gate handlers in registration order, awaited. Unlike `dispatch`
226
- * (observe), a handler throw is NOT swallowed — it PROPAGATES, aborting the
227
- * write before it reaches the store. The first throw stops the remaining
228
- * handlers (fail-fast). This is the seam guards/periods migrate onto.
229
- *
230
- * Note: gate handlers are validators that read, not write. A gate handler
231
- * that writes back into the same collection would re-enter the write path
232
- * and re-dispatch this point; loop-suppression for that case is deferred to
233
- * the migration slice (contract: gate handlers must not perform writes that
234
- * re-trigger their own point).
235
- */
236
- async dispatchGate(point, event) {
237
- const a = this.#gateHandlers.get(point);
238
- if (!a || a.length === 0) return;
239
- for (const e of a.slice()) {
240
- await e.fn(event);
241
- }
242
- }
243
- };
244
- var SubsystemBus = ServiceBus;
245
-
246
- export {
247
- assertCanExport,
248
- assertCanImport,
249
- canExport,
250
- canImport,
251
- WriteHookRegistry,
252
- ServiceBus,
253
- SubsystemBus
254
- };
255
- //# sourceMappingURL=chunk-PT37L5DV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/port/with/capabilities.ts","../src/port/with/write-hooks.ts","../src/port/with/service-bus.ts"],"sourcesContent":["/**\n * Export/import capability gating.\n *\n * Pure predicates over a keyring's `exportCapability` / `importCapability`: the\n * `assert*` variants throw {@link ExportCapabilityError} / {@link ImportCapabilityError}\n * when the invoking keyring is not authorised; the `can*` variants return a\n * boolean for UI affordances. They wrap the role-default resolution in\n * {@link hasExportCapability} / {@link hasImportCapability}. Behaviour is\n * byte-identical to the inline `Vault` methods they replaced — every dependency\n * is the unlocked keyring, passed in. `Vault` keeps the typed (overloaded)\n * public methods and delegates here.\n *\n * Internal — reached through `vault.assertCanExport(...)` etc.\n */\nimport { ExportCapabilityError, ImportCapabilityError } from '../../kernel/errors.js'\nimport { hasExportCapability, hasImportCapability } from '../../with-party/team/keyring.js'\nimport type { UnlockedKeyring } from '../../with-party/team/keyring.js'\nimport type { ExportFormat } from '../../kernel/types.js'\n\n/**\n * Authorize an `@noy-db/as-*` export against the keyring's `exportCapability`.\n * Throws `ExportCapabilityError` if the keyring is not authorised.\n *\n * - plaintext tier requires a `format`; defaults to empty for every role.\n * - bundle tier defaults to on for owner/admin, off for others.\n */\nexport function assertCanExport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): void {\n if (tier === 'plaintext') {\n if (format === undefined) {\n throw new Error('vault.assertCanExport: plaintext tier requires a format')\n }\n if (!hasExportCapability(keyring, 'plaintext', format)) {\n throw new ExportCapabilityError({\n tier: 'plaintext',\n userId: keyring.userId,\n format,\n })\n }\n return\n }\n if (!hasExportCapability(keyring, 'bundle')) {\n throw new ExportCapabilityError({\n tier: 'bundle',\n userId: keyring.userId,\n })\n }\n}\n\n/**\n * Authorize an `@noy-db/as-*` import against the keyring's `importCapability`.\n * Throws `ImportCapabilityError` if the keyring is not authorised.\n *\n * - plaintext tier requires a `format`; default-closed for every role.\n * - bundle tier is default-closed for every role, including owner — import is\n * more dangerous than export (corrupts vs leaks).\n */\nexport function assertCanImport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): void {\n if (tier === 'plaintext') {\n if (format === undefined) {\n throw new Error('vault.assertCanImport: plaintext tier requires a format')\n }\n if (!hasImportCapability(keyring, 'plaintext', format)) {\n throw new ImportCapabilityError({\n tier: 'plaintext',\n userId: keyring.userId,\n format,\n })\n }\n return\n }\n if (!hasImportCapability(keyring, 'bundle')) {\n throw new ImportCapabilityError({\n tier: 'bundle',\n userId: keyring.userId,\n })\n }\n}\n\n/**\n * Read-only accessor for the keyring's export capability, with role-based\n * defaults resolved. Useful for UI affordances (grey out the export button if\n * no capability) without throwing.\n */\nexport function canExport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): boolean {\n if (tier === 'plaintext') {\n if (format === undefined) return false\n return hasExportCapability(keyring, 'plaintext', format)\n }\n return hasExportCapability(keyring, 'bundle')\n}\n\n/**\n * Read-only accessor for the keyring's import capability. UI affordance —\n * returns false in every default-closed case (every role with no explicit\n * `importCapability` grant).\n */\nexport function canImport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): boolean {\n if (tier === 'plaintext') {\n if (format === undefined) return false\n return hasImportCapability(keyring, 'plaintext', format)\n }\n return hasImportCapability(keyring, 'bundle')\n}\n","/**\n * Hub-level write lifecycle hooks. `onBeforeWrite` may abort (throw);\n * `onAfterWrite` is awaited and its errors are warned, not thrown. A\n * re-entrancy flag suppresses nested firing so a handler that writes can't\n * loop. Held on the Noydb instance, threaded into every Collection.\n */\nexport interface WriteEvent {\n readonly op: 'create' | 'update' | 'delete'\n readonly vault: string\n readonly collection: string\n readonly docId: string\n readonly before: unknown // decrypted prior record; null on 'create'\n readonly after: unknown // the record written; null on 'delete'\n readonly baseVersion: number // version the writer started from (0 on create)\n readonly version: number // version the writer wrote (baseVersion + 1)\n readonly userId: string\n readonly timestamp: number\n readonly txId: string\n}\n\nexport type WriteHook = (event: WriteEvent) => void | Promise<void>\nexport type Unsubscribe = () => void\n\nexport class WriteHookRegistry {\n readonly #before: WriteHook[] = []\n readonly #after: WriteHook[] = []\n #suppressed = false\n\n /** True while handlers are running — used by the write path to skip nested firing. */\n get suppressed(): boolean { return this.#suppressed }\n\n /** True when any hook is registered (cheap gate for the write path). */\n get hasHandlers(): boolean { return this.#before.length > 0 || this.#after.length > 0 }\n\n onBeforeWrite(handler: WriteHook): Unsubscribe {\n this.#before.push(handler)\n return () => { const i = this.#before.indexOf(handler); if (i >= 0) this.#before.splice(i, 1) }\n }\n\n onAfterWrite(handler: WriteHook): Unsubscribe {\n this.#after.push(handler)\n return () => { const i = this.#after.indexOf(handler); if (i >= 0) this.#after.splice(i, 1) }\n }\n\n /** Run before-hooks (awaited, in order). A throw propagates and aborts the write. */\n async runBefore(event: WriteEvent): Promise<void> {\n if (this.#before.length === 0) return\n this.#suppressed = true\n try {\n for (const h of this.#before.slice()) await h(event)\n } finally {\n this.#suppressed = false\n }\n }\n\n /** Run after-hooks (awaited, in order). Per-handler errors are warned, not thrown. */\n async runAfter(event: WriteEvent): Promise<void> {\n if (this.#after.length === 0) return\n this.#suppressed = true\n try {\n for (const h of this.#after.slice()) {\n try {\n await h(event)\n } catch (err) {\n console.warn(\n `[noy-db] onAfterWrite handler failed for ${event.collection}/${event.docId}: ` +\n (err instanceof Error ? err.message : String(err)),\n )\n }\n }\n } finally {\n this.#suppressed = false\n }\n }\n}\n","/**\n * Generic per-instance **observe** bus. Observe-class\n * services (devtools inspector, audit, sync-dirty notification) register\n * handlers against named lifecycle points instead of the kernel naming each\n * service. Mirrors the registry pattern of {@link WriteHookRegistry} but is\n * internal and keyed by lifecycle point.\n *\n * OBSERVE SEMANTICS: handlers react to a write that already happened. A\n * handler throw is warned, not propagated — it can never abort a write. Write-\n * *gating* services (guards, periods) need a throw-propagating gate bus.\n * Add observe points by extending {@link LifecycleEventMap}. Write-*gating*\n * services use the sibling gate API on this same class\n * (`registerGate`/`dispatchGate`, throw-propagating); see {@link GateEventMap}.\n *\n * @module\n */\nimport type { WriteEvent } from './write-hooks.js'\nimport type { Role } from '../../kernel/types.js'\n\n/** Typed map of OBSERVE lifecycle point → event payload. Extend by adding keys. */\nexport interface LifecycleEventMap {\n afterPut: WriteEvent\n afterDelete: WriteEvent\n}\n\nexport type LifecyclePoint = keyof LifecycleEventMap\nexport type BusHandler<P extends LifecyclePoint> = (event: LifecycleEventMap[P]) => void | Promise<void>\nexport type Unsubscribe = () => void\n\ntype AnyHandler = (event: unknown) => void | Promise<void>\n\n/** Payload for a `beforePut` gate — carries the data guards and periods need to validate or reject a write. */\nexport interface GatePutEvent {\n readonly op: 'create' | 'update'\n readonly vault: string\n readonly collection: string\n readonly docId: string\n /**\n * The record about to be written (pre schema-validation). Money fields\n * are presented in their canonical decoded form — equal on both\n * sides for an unchanged value, regardless of how the caller wrote them.\n */\n readonly incoming: unknown\n /**\n * Decrypted prior record, or null on create / when prior is unreadable.\n * Money fields are decoded to the canonical decimal `get()` shape, NOT\n * the stored scaled-int — `incoming[f] === existing[f]` holds\n * for an unchanged money field.\n */\n readonly existing: unknown\n /** Prior envelope version, or 0 when none. */\n readonly existingVersion: number\n /** Prior envelope timestamp (`_ts` ISO string), or undefined when none — periods compares against this. */\n readonly existingTs: string | undefined\n readonly userId: string\n readonly role: Role\n /**\n * Names of fields whose values are schema-owned computed fields for this\n * collection. Gate handlers (e.g. `frozenFields`) must skip these: the\n * incoming record is the raw user input (computed fields not yet evaluated),\n * so comparing `existing[computedField]` vs `incoming[computedField]`\n * would always see a change even when the computed result is unchanged.\n */\n readonly computedFieldNames?: ReadonlySet<string>\n}\n\n/** Payload for a `beforeDelete` gate. Like {@link GatePutEvent} without `incoming`. */\nexport interface GateDeleteEvent {\n readonly vault: string\n readonly collection: string\n readonly docId: string\n /** True for system-internal (housekeeping) deletes — handlers branch on this. */\n readonly internal: boolean\n /** Decrypted prior record; money fields decoded to the canonical `get()` shape. */\n readonly existing: unknown\n readonly existingVersion: number\n readonly existingTs: string | undefined\n readonly userId: string\n readonly role: Role\n}\n\n/** Typed map of GATE lifecycle point → event payload. Extend by adding keys. */\nexport interface GateEventMap {\n beforePut: GatePutEvent\n beforeDelete: GateDeleteEvent\n}\n\nexport type GatePoint = keyof GateEventMap\nexport type GateHandler<P extends GatePoint> = (event: GateEventMap[P]) => void | Promise<void>\n\n/**\n * Registration options for a gate handler.\n *\n * `needsPrior` (default `true`) declares whether the handler reads the\n * prior-derived event fields — `existing`, `existingVersion`, `existingTs`,\n * and (on `beforePut`) `op`. When EVERY handler registered at a point set\n * `needsPrior: false`, the write path skips the prior-read (store get +\n * decrypt) entirely and dispatches the event with `existing: null`,\n * `existingVersion: 0`, `existingTs: undefined` (and `op: 'create'` on\n * `beforePut`; a `beforeDelete` gate then also fires for delete-of-absent).\n * A handler that opts out MUST NOT rely on those fields. (#267 prior-read\n * elision — pure perf; one prior-needing handler restores the old behavior\n * for the whole point.)\n */\nexport interface GateRegisterOptions {\n readonly needsPrior?: boolean\n}\n\ntype GateEntry = { readonly fn: AnyHandler; readonly needsPrior: boolean }\n\nexport class ServiceBus {\n readonly #handlers = new Map<LifecyclePoint, AnyHandler[]>()\n readonly #gateHandlers = new Map<GatePoint, GateEntry[]>()\n #depth = 0\n\n /** Register a handler for an observe point. Returns an unsubscribe fn. */\n register<P extends LifecyclePoint>(point: P, handler: BusHandler<P>): Unsubscribe {\n let arr = this.#handlers.get(point)\n if (!arr) { arr = []; this.#handlers.set(point, arr) }\n arr.push(handler as AnyHandler)\n return () => {\n const a = this.#handlers.get(point)\n if (!a) return\n const i = a.indexOf(handler as AnyHandler)\n if (i >= 0) a.splice(i, 1)\n }\n }\n\n /** Cheap gate for the write path — true when any handler is registered for the point. */\n hasHandlers(point: LifecyclePoint): boolean {\n const a = this.#handlers.get(point)\n return a !== undefined && a.length > 0\n }\n\n /**\n * True while one or more dispatches are in flight. Backed by a depth counter\n * so that two concurrent async dispatches (`Promise.all([put('a'), put('b')])`\n * each captured `busAfterPut=true` at their respective put() tops while depth\n * was 0) both proceed independently — the counter stays > 0 until BOTH finish,\n * so any nested write attempted by a handler still sees `dispatching === true`\n * and is suppressed by the write-path gate in `collection.ts`\n * (`busAfterPut = hasHandlers('afterPut') && !dispatching`). Re-entrancy\n * suppression lives exclusively on that write-path gate; concurrent independent\n * dispatches must not drop each other's events.\n */\n get dispatching(): boolean { return this.#depth > 0 }\n\n /**\n * Dispatch in registration order, awaited. Per-handler errors are warned, not\n * thrown — an observe handler must never abort a completed write. A\n * re-entrancy guard suppresses nested firing so a handler that itself writes\n * cannot loop (same rationale as WriteHookRegistry.#suppressed).\n */\n async dispatch<P extends LifecyclePoint>(point: P, event: LifecycleEventMap[P]): Promise<void> {\n const a = this.#handlers.get(point)\n if (!a || a.length === 0) return\n this.#depth++\n try {\n for (const h of a.slice()) {\n try {\n await h(event)\n } catch (err) {\n console.warn(\n `[noy-db] service observe handler failed at ${point}: ` +\n (err instanceof Error ? err.message : String(err)),\n )\n }\n }\n } finally {\n this.#depth--\n }\n }\n\n /**\n * Register a write-gating handler. A throw from the handler ABORTS the\n * write. Returns an unsubscribe fn. See {@link GateRegisterOptions} for\n * the `needsPrior` prior-read declaration (#267).\n */\n registerGate<P extends GatePoint>(point: P, handler: GateHandler<P>, opts?: GateRegisterOptions): Unsubscribe {\n let arr = this.#gateHandlers.get(point)\n if (!arr) { arr = []; this.#gateHandlers.set(point, arr) }\n const entry: GateEntry = { fn: handler as AnyHandler, needsPrior: opts?.needsPrior !== false }\n arr.push(entry)\n return () => {\n const a = this.#gateHandlers.get(point)\n if (!a) return\n const i = a.indexOf(entry)\n if (i >= 0) a.splice(i, 1)\n }\n }\n\n /** Cheap gate for the write path — true when any gate handler is registered for the point. */\n hasGateHandlers(point: GatePoint): boolean {\n const a = this.#gateHandlers.get(point)\n return a !== undefined && a.length > 0\n }\n\n /**\n * True when at least one gate handler at `point` needs the prior record\n * (the default). False when the point has no handlers or every handler\n * registered with `needsPrior: false` — the write path then skips the\n * prior-read before dispatching (#267 prior-read elision).\n */\n gateNeedsPrior(point: GatePoint): boolean {\n const a = this.#gateHandlers.get(point)\n if (!a) return false\n return a.some((e) => e.needsPrior)\n }\n\n /**\n * Run gate handlers in registration order, awaited. Unlike `dispatch`\n * (observe), a handler throw is NOT swallowed — it PROPAGATES, aborting the\n * write before it reaches the store. The first throw stops the remaining\n * handlers (fail-fast). This is the seam guards/periods migrate onto.\n *\n * Note: gate handlers are validators that read, not write. A gate handler\n * that writes back into the same collection would re-enter the write path\n * and re-dispatch this point; loop-suppression for that case is deferred to\n * the migration slice (contract: gate handlers must not perform writes that\n * re-trigger their own point).\n */\n async dispatchGate<P extends GatePoint>(point: P, event: GateEventMap[P]): Promise<void> {\n const a = this.#gateHandlers.get(point)\n if (!a || a.length === 0) return\n for (const e of a.slice()) {\n await e.fn(event) // throw propagates → aborts the write\n }\n }\n}\n\n/** @deprecated Use ServiceBus. */\nexport const SubsystemBus = ServiceBus\n/** @deprecated Use ServiceBus. */\nexport type SubsystemBus = ServiceBus\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-audit/sealed-record/strategy.ts"],"sourcesContent":["/**\n * Sealed-record (grantor-side) capability strategy — the three on-demand vault\n * methods the record-scoped CEK sealing surface routes through. The active\n * engine ({@link withSealedRecord}) dynamically imports the `record-keys`\n * grantor cores (keeping them reachable only via opt-in); {@link NO_SEALED_RECORD}\n * throws. The vault always assembles the per-call {@link SealingContext} and\n * delegates here, so an un-opted-in caller hits `NO_SEALED_RECORD`'s throw.\n *\n * Note: the recipient-host opener (`openSealedRecord`) is a pure decrypt\n * function exported from this subpath and is NOT gated — it runs on a remote\n * host with no `createNoydb` instance (the same way the attestation verifier\n * stays ungated). Only the vault-side grantor operations are the capability.\n * @internal\n */\nimport type { SealingContext } from '../../kernel/enclave/index.js'\nimport type { RecipientSealer } from '../../with-party/team/managed-passphrase.js'\nimport { SealedRecordNotEnabledError } from '../../kernel/errors.js'\n\nexport interface SealedRecordStrategy {\n sealRecordToHost(\n ctx: SealingContext,\n collection: string,\n id: string,\n hostSealer: RecipientSealer,\n opts: { expiresAt: string },\n ): Promise<{ pid: string; envelopeKey: string }>\n revokeSealedRecord(\n ctx: SealingContext,\n collection: string,\n id: string,\n pid: string,\n opts?: { hard?: boolean },\n ): Promise<void>\n rotateRecordCek(ctx: SealingContext, collection: string, id: string): Promise<void>\n}\n\n/**\n * No-op stub — the floor default. Every grantor method throws\n * {@link SealedRecordNotEnabledError}; opt in with\n * `sealedRecordStrategy: withSealedRecord()` in createNoydb. @internal\n */\nexport const NO_SEALED_RECORD: SealedRecordStrategy = {\n async sealRecordToHost() { throw new SealedRecordNotEnabledError() },\n async revokeSealedRecord() { throw new SealedRecordNotEnabledError() },\n async rotateRecordCek() { throw new SealedRecordNotEnabledError() },\n}\n"],"mappings":";;;;;AAyCO,IAAM,mBAAyC;AAAA,EACpD,MAAM,mBAAmB;AAAE,UAAM,IAAI,4BAA4B;AAAA,EAAE;AAAA,EACnE,MAAM,qBAAqB;AAAE,UAAM,IAAI,4BAA4B;AAAA,EAAE;AAAA,EACrE,MAAM,kBAAkB;AAAE,UAAM,IAAI,4BAA4B;AAAA,EAAE;AACpE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-party/policy/presets.ts","../src/with-party/policy/engine.ts","../src/with-party/policy/noydb-facade.ts"],"sourcesContent":["import type { VaultPolicy } from '../../kernel/types.js'\n\n/**\n * Default policy for personal vaults and SMB deployments — the gates\n * that need an off-device factor get one (TOTP / email-OTP / paper\n * recovery), the rest take a tier-1 unlock alone. Tier-3 (PIN) is the\n * floor only for `rotate-unlock` because that's the\n * \"change my PIN\" flow.\n *\n * The unspecified gates (e.g. `view-user-auth`) inherit the engine\n * default of `{ enabled: false, minTier: 1 }` — they fail closed.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → Built-in gates\n */\nexport const PERSONAL_POLICY: VaultPolicy = Object.freeze({\n passphrase: {\n minWords: 6,\n minWordLength: 3,\n rejectRepeatedAdjacent: true,\n },\n gates: {\n 'rotate-passphrase': {\n minTier: 1,\n // Any second factor satisfies the gate — off-device kinds (TOTP,\n // email-OTP, paper recovery, roaming WebAuthn) are the strongest;\n // platform-bound kinds (platform WebAuthn, password, PIN) are\n // accepted because requiring \"something off-device\" is overkill\n // for personal/SMB threat models. Consumers needing the off-device\n // guarantee should use STRICT_POLICY or override this gate.\n factors: [{\n anyOf: [\n 'totp', 'email-otp', 'recovery',\n 'webauthn-roaming', 'webauthn-platform',\n 'password', 'pin',\n ],\n }],\n },\n 'recover-passphrase': {\n minTier: 1,\n enabled: true,\n },\n // rotate-recovery: deliberate paper-sheet regeneration\n // when the user remembers their passphrase. PERSONAL allows tier-1 —\n // knowing the passphrase is enough.\n 'rotate-recovery': { minTier: 1 },\n 'enroll-authenticator': { minTier: 1 },\n 'remove-authenticator': { minTier: 1 },\n // update-authenticator: meta-only mutation (slot rename, label\n // changes). Symmetric with enroll/remove under PERSONAL — tier-1\n // unlock alone. The structural anti-slot-swap guard inside the\n // implementation enforces wrap-material/id/method immutability\n // regardless of this gate's settings.\n 'update-authenticator': { minTier: 1 },\n 'rotate-unlock': { minTier: 2 },\n 'enroll-user': { minTier: 1 },\n 'revoke-user': { minTier: 1 },\n // Peer-recovery is a high-trust intentional op — co-owners\n // recovering each other should not need an off-device factor in\n // the personal/SMB threat model (the partner is already vetted by\n // virtue of being a co-owner). Tier-1 unlock is the floor; the\n // STRICT preset adds a recovery/email-OTP requirement.\n 'peer-recover-user': { minTier: 1 },\n // update-user: post-grant identity mutation (role/displayName/\n // permissions). PERSONAL_POLICY treats this on par with enroll-user\n // / revoke-user — tier-1 unlock alone. The role-elevation guard\n // inside the implementation is the structural backstop that this\n // gate's settings cannot weaken.\n 'update-user': { minTier: 1 },\n 'export-bundle': { minTier: 1 },\n 'export-plaintext': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'view-user-auth': {\n minTier: 1,\n enabled: false,\n },\n // ─── User envelope gates ──────────────────────────────────────────\n // edit-own-profile: tier 3 floor — any active session can edit their\n // own profile/preferences. Tightening to require a TOTP for\n // profile changes is a one-line override.\n // view-team-profiles: tier 2 floor — an authenticated session can\n // read teammates' profiles (display names, avatars, locales).\n // Setting `enabled: false` makes vault.user.list() return only\n // self (privacy-strict opt-out).\n 'edit-own-profile': { minTier: 3 },\n 'view-team-profiles': { minTier: 2 },\n // client-unilateral-withdraw: a non-owner's self-service DESTRUCTIVE\n // withdrawal (export-and-delete/freeze). Fail-closed by default —\n // the firm opts in per jurisdiction/contract (e.g. GDPR Art. 17).\n // Listed explicitly (not just relying on the built-in default) so it is\n // discoverable in describeGate / policy dumps.\n 'client-unilateral-withdraw': { minTier: 1, enabled: false },\n // Two-party withdrawal: filing a request is non-destructive\n // (tier-1, enabled so a read-only client can ask); deciding it is the\n // destructive step (tier-2 floor + owner/admin role, enforced in code).\n 'user-request-withdrawal': { minTier: 1 },\n 'approve-user-withdrawal': { minTier: 2 },\n },\n}) as VaultPolicy\n\n/**\n * Strict policy for regulated deployments and shared workstations —\n * raises the phrase floor to 8 words, demands two distinct factors for\n * exports, and blocks export-on-shared-device. Use as a base for\n * `policy: { ...STRICT_POLICY, gates: { ...STRICT_POLICY.gates, ... } }`\n * tweaks.\n */\nexport const STRICT_POLICY: VaultPolicy = Object.freeze({\n passphrase: {\n minWords: 8,\n minWordLength: 3,\n rejectRepeatedAdjacent: true,\n },\n gates: {\n 'rotate-passphrase': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp', 'recovery'], count: 2 }],\n },\n 'recover-passphrase': {\n minTier: 1,\n enabled: true,\n },\n // rotate-recovery: STRICT requires an off-device factor —\n // rotating recovery is an off-site-trust event; a stolen unlocked\n // laptop must not be able to silently mint a new sheet for the\n // attacker. Matches the `peer-recover-user` STRICT default.\n 'rotate-recovery': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp', 'webauthn-roaming'] }],\n },\n 'enroll-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'remove-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n // STRICT update-authenticator: same factor floor as enroll/remove.\n // Even though meta changes don't touch wrap material, a malicious\n // rename could mislead the user about which device a slot\n // corresponds to (\"MacBook Touch ID\" → \"iPhone Touch ID\" on a\n // shared workstation). STRICT requires a fresh factor proof.\n 'update-authenticator': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'rotate-unlock': { minTier: 1 },\n 'enroll-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'revoke-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n // STRICT peer-recovery: the issuer must present a recovery code\n // OR a fresh off-device second factor at the moment of recovery.\n // This binds the high-trust operation to a verifiable proof\n // (recovery sheet photographed by an attacker won't suffice —\n // they'd also need tier-1 unlock first; this gate is the freshness\n // binding on top). Roaming WebAuthn (YubiKey-class hardware key)\n // accepted; platform-bound kinds (Touch ID, password, PIN)\n // intentionally excluded under STRICT because they don't survive\n // device theft — the off-device requirement is the whole point.\n 'peer-recover-user': {\n minTier: 1,\n factors: [{ anyOf: ['recovery', 'totp', 'email-otp', 'webauthn-roaming'] }],\n },\n // STRICT update-user: matches the enroll-user / revoke-user shape\n // (off-device factor required). Update-user is admin-shaped — it\n // mutates someone else's role/permissions; STRICT requires a fresh\n // off-device factor proof so the operator affirmatively re-asserts\n // identity at the moment of mutation. Platform-bound factors\n // (Touch ID / password / PIN) intentionally excluded: same logic as\n // peer-recover-user — the off-device requirement is the whole\n // point under STRICT.\n 'update-user': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'export-bundle': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n warn: { sharedDevice: 'block' },\n },\n 'export-plaintext': {\n minTier: 1,\n factors: [{ anyOf: ['totp', 'email-otp'], count: 2 }],\n warn: { sharedDevice: 'block' },\n },\n 'view-user-auth': {\n minTier: 1,\n enabled: false,\n },\n // ─── User envelope gates ──────────────────────────────────────────\n // STRICT: profile edits require a TOTP/email-OTP factor (typical\n // shared-workstation hardening — your name/avatar shouldn't change\n // without a fresh second-factor proof).\n 'edit-own-profile': {\n minTier: 2,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n },\n 'view-team-profiles': { minTier: 2 },\n // STRICT: still fail-closed, but if a regulated firm flips enabled:true\n // they inherit a two-factor proof + shared-device block for the\n // destructive withdrawal (mirrors export-plaintext's hardening).\n 'client-unilateral-withdraw': {\n minTier: 1,\n enabled: false,\n factors: [{ anyOf: ['totp', 'email-otp'], count: 2 }],\n warn: { sharedDevice: 'block' },\n },\n // STRICT: filing stays tier-1; the destructive APPROVE demands an\n // off-device factor + shared-device block (mirrors export-bundle).\n 'user-request-withdrawal': { minTier: 1 },\n 'approve-user-withdrawal': {\n minTier: 2,\n factors: [{ anyOf: ['totp', 'email-otp'] }],\n warn: { sharedDevice: 'block' },\n },\n },\n}) as VaultPolicy\n\n/**\n * Merge a developer override onto a preset. Unspecified gates inherit;\n * specified gates fully replace the preset's entry for that gate.\n *\n * Example:\n *\n * ```ts\n * mergePolicy(PERSONAL_POLICY, {\n * gates: {\n * 'app:approve-large-payment': { minTier: 2, factors: [{ anyOf: ['totp'] }] },\n * },\n * })\n * // → PERSONAL_POLICY plus the new app gate; existing gates intact.\n * ```\n */\nexport function mergePolicy(\n base: VaultPolicy,\n override?: Partial<VaultPolicy>,\n): VaultPolicy {\n if (!override) return base\n const passphrase = override.passphrase ?? base.passphrase\n return {\n ...(passphrase !== undefined ? { passphrase } : {}),\n gates: {\n ...base.gates,\n ...(override.gates ?? {}),\n },\n }\n}\n","/**\n * Policy gate engine — the {@link checkGate} entry point.\n *\n * Given a configured {@link VaultPolicy}, an active session tier, and\n * the factor proofs an actor is presenting, decide whether the gate\n * permits the action. On denial, throws {@link PolicyDeniedError} with\n * a stable {@link PolicyDenyReason} so consumers can branch in error\n * UIs.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/session-tiers.md → checkGate() API\n *\n * @module\n */\nimport { PolicyDeniedError, type PolicyDenyReason } from '../../kernel/errors.js'\nimport type {\n ActiveTier,\n FactorProof,\n GateName,\n GatePolicy,\n VaultPolicy,\n FactorRequirement,\n} from '../../kernel/types.js'\n\n/** Default freshness window — 5 minutes. */\nexport const DEFAULT_FRESHNESS_MS = 5 * 60 * 1000\n\n/** Caller-supplied context for one `checkGate` invocation. */\nexport interface CheckGateContext {\n /** Tier the active session currently holds. */\n readonly activeTier: ActiveTier\n /** Proofs the actor is presenting for this gate. */\n readonly factors?: ReadonlyArray<FactorProof>\n /**\n * If the host knows the actor is on a shared device, set this to\n * `true` so the engine can apply `warn.sharedDevice` rules. Defaults\n * to `false`.\n */\n readonly sharedDevice?: boolean\n /**\n * Override `now()` for tests. Defaults to `Date.now()`.\n * @internal\n */\n readonly now?: number\n}\n\n/**\n * Decide whether `gate` permits the action under `context`. Throws\n * {@link PolicyDeniedError} on denial; resolves with `void` on success.\n *\n * Lookup rules:\n * - **Built-in gates** without a configured policy fail closed\n * (`enabled: false`).\n * - **App-defined gates** (`app:*`) without a configured policy are\n * treated as no-op (allow). The developer registered the policy if\n * they wanted enforcement; absence means the gate is informational.\n */\nexport async function checkGate(\n policy: VaultPolicy,\n gate: GateName,\n context: CheckGateContext,\n): Promise<void> {\n const configured = policy.gates[gate]\n if (!configured) {\n if (gate.startsWith('app:')) {\n // Custom app gate without a policy — the developer hasn't\n // registered one; engine treats it as an unenforced label.\n return\n }\n // Built-in gate without a policy — fail closed.\n throw deny(gate, 'disabled', { minTier: 1, enabled: false })\n }\n\n if (configured.enabled === false) {\n throw deny(gate, 'disabled', configured)\n }\n\n // Tier check first — cheap and a hard prerequisite.\n if (context.activeTier > configured.minTier) {\n // Higher number is a LOWER tier in this model (1 is most privileged).\n throw deny(gate, 'insufficient-tier', configured)\n }\n\n // Factor checks — every requirement entry must be satisfied.\n if (configured.factors && configured.factors.length > 0) {\n const presented = context.factors ?? []\n const now = context.now ?? Date.now()\n for (const requirement of configured.factors) {\n const matches = countMatchingFactors(presented, requirement, now)\n const need = requirement.count ?? 1\n if (matches.fresh < need) {\n if (matches.totalKindMatches < need) {\n throw deny(gate, 'missing-factor', configured)\n }\n // Some matched the kind list but not the freshness window.\n throw deny(gate, 'stale-proof', configured)\n }\n }\n }\n\n // Soft signals — only `'block'` raises here.\n if (configured.warn?.sharedDevice === 'block' && context.sharedDevice === true) {\n throw deny(gate, 'shared-device-blocked', configured)\n }\n}\n\n/**\n * Same as {@link checkGate} but returns a structured verdict instead\n * of throwing. Useful when an error UI wants to show the user\n * \"you'll need TOTP plus a recovery code to do that\" without first\n * triggering the action.\n */\nexport async function describeGate(\n policy: VaultPolicy,\n gate: GateName,\n context: CheckGateContext,\n): Promise<{ ok: true } | { ok: false; reason: PolicyDenyReason; required: GatePolicy }> {\n try {\n await checkGate(policy, gate, context)\n return { ok: true }\n } catch (err) {\n if (err instanceof PolicyDeniedError) {\n return { ok: false, reason: err.reason, required: err.required }\n }\n throw err\n }\n}\n\nfunction countMatchingFactors(\n presented: ReadonlyArray<FactorProof>,\n requirement: FactorRequirement,\n now: number,\n): { totalKindMatches: number; fresh: number } {\n const freshnessMs = requirement.freshnessMs ?? DEFAULT_FRESHNESS_MS\n let totalKindMatches = 0\n let fresh = 0\n for (const proof of presented) {\n if (!requirement.anyOf.includes(proof.kind)) continue\n totalKindMatches += 1\n const minted = proof.mintedAt ? Date.parse(proof.mintedAt) : now\n if (Number.isFinite(minted) && now - minted <= freshnessMs) {\n fresh += 1\n }\n }\n return { totalKindMatches, fresh }\n}\n\nfunction deny(gate: GateName, reason: PolicyDenyReason, required: GatePolicy): PolicyDeniedError {\n return new PolicyDeniedError(gate, reason, required)\n}\n","/**\n * Noydb-side policy / session-policy facade.\n *\n * Holds the vault-policy read/update/bootstrap logic (`getPolicy`,\n * `updatePolicy`, `bootstrapPolicy`) and the per-vault session-policy\n * enforcer wiring (`touchPolicy`, `checkPolicyOperation`). The session\n * *timer* and the managed-recovery enrolment check stay kernel-resident on\n * `Noydb` (interleaved with the instance lifecycle) and arrive here as the\n * `resetSessionTimer` / `assertRecoveryEnrolled` callbacks. The policy cache\n * and the enforcer map stay `Noydb`-resident too (touched by\n * `openVault`/`close`) and arrive by reference; behaviour is byte-identical\n * to the inline `Noydb` methods it replaced — every other dependency the\n * moving code touched on `this.*` arrives via {@link NoydbPolicyDeps}.\n *\n * Internal service — reached through `noydb.getPolicy(...)` etc. Public\n * contract ({@link NoydbPolicyApi} / {@link NoydbPolicyDeps} /\n * {@link NoydbPolicyFactory}) lives in the kernel spine; `createNoydb()`\n * wires this file's {@link createNoydbPolicy} in via a pre-resolved dynamic\n * import (the S4 gate recipe).\n */\nimport { ValidationError } from '../../kernel/errors.js'\nimport { PERSONAL_POLICY, mergePolicy } from './presets.js'\nimport { loadVaultPolicy, saveVaultPolicy } from './storage.js'\nimport type { VaultPolicy, ReAuthOperation, NoydbPolicyApi, NoydbPolicyDeps, NoydbPolicyFactory } from '../../kernel/types.js'\n\nexport class NoydbPolicy implements NoydbPolicyApi {\n constructor(private readonly deps: NoydbPolicyDeps) {}\n\n /**\n * Touch the policy enforcer for a vault (records activity, resets\n * idle timer). Also touches the legacy session timer. No-op if no enforcer.\n */\n touchPolicy(vault?: string): void {\n this.deps.resetSessionTimer()\n if (vault) {\n this.deps.policyEnforcers.get(vault)?.touch()\n }\n }\n\n /**\n * Check that a policy-guarded operation is permitted.\n * Throws `SessionPolicyError` if re-auth is required.\n */\n checkPolicyOperation(vault: string, op: ReAuthOperation): void {\n this.deps.policyEnforcers.get(vault)?.checkOperation(op)\n }\n\n /**\n * Read the active policy for a vault. Loads from `_meta/policy` on\n * first call; subsequent calls hit the in-memory cache. Throws\n * `ValidationError` if the vault has not been opened.\n */\n async getPolicy(vault: string): Promise<VaultPolicy> {\n if (this.deps.isClosed()) throw new ValidationError('Instance is closed')\n const cached = this.deps.policyCache.get(vault)\n if (cached) return cached\n await this.bootstrapPolicy(vault)\n return this.deps.policyCache.get(vault) ?? PERSONAL_POLICY\n }\n\n /**\n * Replace the policy document at `_meta/policy` and update the\n * in-memory cache. Gated by the `enroll-user` policy (a policy\n * change is fundamentally a privilege-management action).\n */\n async updatePolicy(vault: string, override: Partial<VaultPolicy>): Promise<VaultPolicy> {\n if (this.deps.isClosed()) throw new ValidationError('Instance is closed')\n const current = await this.getPolicy(vault)\n const merged = mergePolicy(current, override)\n if (this.deps.encrypted) {\n await saveVaultPolicy(this.deps.store, vault, merged)\n }\n this.deps.policyCache.set(vault, merged)\n return merged\n }\n\n /** Read or persist the vault policy at `_meta/policy` on first open. */\n async bootstrapPolicy(\n vault: string,\n opts?: { skipManagedCheck?: boolean },\n ): Promise<void> {\n const onDisk = await loadVaultPolicy(this.deps.store, vault)\n if (onDisk) {\n // Honour the on-disk document; developer overrides cannot\n // weaken what the vault committed to at creation time.\n this.deps.policyCache.set(vault, onDisk)\n await this.deps.assertRecoveryEnrolled(vault, onDisk, opts)\n return\n }\n // First time — persist the developer's policy (or default preset).\n const initial = this.deps.policyOption\n ? mergePolicy(PERSONAL_POLICY, this.deps.policyOption)\n : PERSONAL_POLICY\n await saveVaultPolicy(this.deps.store, vault, initial)\n this.deps.policyCache.set(vault, initial)\n await this.deps.assertRecoveryEnrolled(vault, initial, opts)\n }\n}\n\n/**\n * Factory that builds the `NoydbPolicy` service. `createNoydb()`\n * pre-resolves this via a dynamic import (mirrors\n * `with-party/directory/user-envelope/api.js#createUserApi`) and threads\n * it through `NoydbOptions.policyFactory` so `Noydb`'s constructor can\n * build `this.policyManager` synchronously.\n */\nexport const createNoydbPolicy: NoydbPolicyFactory = (deps) => new NoydbPolicy(deps)\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-formula/materialized-views/dependency-analyzer.ts","../src/with-formula/materialized-views/query-hash.ts","../src/with-formula/materialized-views/registry.ts"],"sourcesContent":["import type { Query, QueryPlan } from '../../kernel/query/builder.js'\nimport type { JoinContext } from '../../kernel/query/join.js'\nimport type { MaterializedViewStrategy } from './types.js'\n\n/**\n * Walks a `Query<T>` plan and returns the set of source collection\n * names that any source-write should trigger a refresh on.\n *\n * Handles:\n * - root collection (the one the query was built from)\n * - FK join targets (`.join(field, { as })`)\n *\n * Also handles:\n * - cross-join targets (`.crossJoin(target, { as })`) — v3\n *\n * Deferred:\n * - `.wherePredicate(name)` — v2 predicate primitive\n * - Overlay-name expansion to {base, overlay}\n *\n * The set is materialized at MV registration time. The MV registry\n * uses it to (a) dispatch `onSourceWrite` only to MVs that actually\n * care, and (b) contribute edges to the shared cycle-detection graph.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function analyzeDependencies(query: Query<any>): Set<string> {\n const deps = new Set<string>()\n const plan = query._plan()\n const ctx = query._joinContext()\n\n // The root collection is always a dependency.\n if (ctx?.leftCollection) {\n deps.add(ctx.leftCollection)\n }\n\n // FK join targets contribute additional sources.\n for (const leg of plan.joins) {\n deps.add(leg.target)\n }\n\n // Cross-join targets are also dependency sources — writes to either side\n // must trigger MV refresh. Symmetric with FK-join target handling above.\n for (const clause of plan.clauses) {\n if (clause.type === 'crossJoin') {\n deps.add(clause.target)\n }\n }\n\n // Sub-plans inside OR clauses can carry nested joins. Walk them.\n // (Today only top-level `.join()` populates `plan.joins`, but the\n // OR-group machinery permits sub-plans, so we recurse defensively.)\n walkClausesForJoins(plan, deps, ctx)\n\n return deps\n}\n\nfunction walkClausesForJoins(\n plan: QueryPlan,\n deps: Set<string>,\n ctx: JoinContext | undefined,\n): void {\n void ctx\n // Today `plan.joins` carries all join legs at top level. Sub-plans\n // inside OR groups don't currently support nested joins, so the loop\n // below is a no-op safety net for future builder extensions.\n for (const clause of plan.clauses) {\n if (clause.type === 'group') {\n // Group clauses don't (yet) carry their own joins; this is a\n // forward-compat anchor for when OR-groups support nested\n // sources.\n }\n }\n}\n\n/**\n * Convenience: produce a stable string summary of the query plan\n * suitable for `queryHash` derivation. Captures everything the\n * dependency analyzer reads + the where/orderBy/limit/offset\n * structure that affects materialized rows.\n *\n * `joinContext` is intentionally NOT included — the join-resolution\n * function references would defeat hash determinism. The set of join\n * TARGETS (collection names) IS included via the plan.joins legs.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function summarizeQueryPlan(query: Query<any>): string {\n const plan = query._plan()\n const ctx = query._joinContext()\n return JSON.stringify({\n root: ctx?.leftCollection ?? null,\n clauses: plan.clauses.map(c => {\n if (c.type === 'crossJoin') {\n return {\n type: 'crossJoin',\n target: c.target,\n as: c.as,\n // Inline on: callback: use sentinel — drift detection disabled for this MV\n onPredicateName: c.onPredicateName ?? (c.on ? '[inline]' : null),\n maxRows: c.maxRows ?? null,\n }\n }\n return c\n }),\n orderBy: plan.orderBy,\n limit: plan.limit ?? null,\n offset: plan.offset,\n joins: plan.joins.map(j => ({ field: j.field, as: j.as, target: j.target, mode: j.mode })),\n })\n}\n\n/**\n * Canonical string description of a UNION MV's plan, used as input to\n * `computeQueryHash`.\n *\n * Asymmetry note:\n * - Arm collection names are NOT sorted. Declaration order is\n * semantically meaningful for the dedup-only UNION path —\n * `materializeUnionResult` iterates `spec.unionSources` in\n * declaration order and keeps the first-seen row per composite key\n * (tie-break precedence). If we sorted arms here, a consumer who\n * reordered `unionSources` to change precedence would compute the\n * same `queryHash`, refresh would be a no-op, and stale MV rows\n * would persist. Hashing in declaration order makes any reorder\n * trigger a refresh.\n * - `groupBy` fields ARE sorted. Multi-key groupBy buckets are\n * commutative (`canonicalGroupKey` produces the same composite key\n * regardless of field order in the input spec).\n * - `aggregate` keys ARE sorted. Reducer-spec keys are independent\n * of each other — order of declaration doesn't change output.\n *\n * Per-arm `map` functions are NOT fingerprinted; consumers must bump\n * the MV's `name` (or rely on application-level cache busting) when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeUnionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewStrategy<T>,\n): string {\n return `union(${summarizeUnionArms(spec)})${summarizeGroupingTail(spec)}`\n}\n\n/**\n * Canonical string description of a projection MV's plan (#810), used\n * as input to `computeQueryHash`.\n *\n * Leg descriptors ARE sorted (contrast with UNION arm order): every\n * leg attaches under a distinct `as` alias, forward legs are\n * one-to-one attachments and collect legs are independent\n * hash-grouped passes, so declaration order never changes the\n * materialized rows — a pure reorder must NOT force a refresh.\n *\n * The projection `map` is NOT fingerprinted (identical limitation as\n * the UNION arm `map`); consumers must bump the MV's `name` when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeProjectionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewStrategy<T>,\n): string {\n const projection = spec.projection!\n const legs = projection.joins\n .map(leg =>\n 'collect' in leg\n ? `collect:${leg.collect}.${leg.on}→${leg.as}`\n : `field:${leg.field}→${leg.as}`,\n )\n .sort()\n const body = JSON.stringify({ source: projection.source, legs })\n return `projection(${body})${summarizeGroupingTail(spec)}`\n}\n\n/** Arm descriptors for `summarizeUnionPlan` — declaration order preserved (see its doc). */\nfunction summarizeUnionArms<T extends Record<string, unknown>>(\n spec: MaterializedViewStrategy<T>,\n): string {\n return (spec.unionSources ?? [])\n .map(s => {\n // Fold each arm's join legs into the summary so adding or\n // reordering joins (which changes the materialized rows) bumps\n // queryHash. Leg order is declaration-significant (legs chain), so\n // it is NOT sorted — same rationale as arm declaration order.\n const joins = s.join?.length\n ? `[${s.join.map(j => `${j.field}→${j.as}`).join(';')}]`\n : ''\n return `${s.collection}${joins}`\n })\n .join(',')\n}\n\n/**\n * Shared `|groupBy(…)|aggregate(…)|money(…)` tail for the UNION and\n * projection summaries — both feed the same post-map grouping pipeline,\n * so the same spec fields fold into both hashes with the same rules.\n */\nfunction summarizeGroupingTail<T extends Record<string, unknown>>(\n spec: MaterializedViewStrategy<T>,\n): string {\n const groupBy: string = Array.isArray(spec.groupBy)\n ? [...spec.groupBy].sort().join(',')\n : typeof spec.groupBy === 'string'\n ? spec.groupBy\n : ''\n const aggKeys = spec.aggregate ? Object.keys(spec.aggregate).sort().join(',') : ''\n // `moneyFields` changes reducer semantics (float → exact BigInt), so\n // declaring / removing / re-keying it must bump queryHash. Keys are\n // sorted — they're independent of each other (one descriptor per\n // output field), same rationale as aggregate keys.\n const moneyKeys = spec.moneyFields ? Object.keys(spec.moneyFields).sort().join(',') : ''\n return `|groupBy(${groupBy})|aggregate(${aggKeys})|money(${moneyKeys})`\n}\n","/**\n * Deterministic hash of a materialized view strategy's \"shape\": MV\n * name + canonical query-plan summary + sorted dependency-set.\n *\n * Used to detect strategy drift: a row whose `_materializedFrom.queryHash`\n * doesn't match the current strategy is considered stale.\n *\n * Web Crypto SHA-256 — no extra deps. Mirrors the v1\n * `computeStrategyHash` pattern.\n */\nimport { sha256Hex } from '../../kernel/enclave/index.js'\n\nexport async function computeQueryHash(\n mvName: string,\n /**\n * Source-collection set the query depends on. Sorted before\n * canonicalization so set iteration order doesn't affect the hash.\n */\n dependencies: ReadonlySet<string>,\n /**\n * Stringified query-plan summary. The caller produces this from the\n * `Query<T>` builder — concretely: a JSON serialization of clauses +\n * orderBy + limit + offset + joins. Function bodies inside\n * `wherePredicate` are NOT included here (those carry their own\n * `predicateHash` to be folded in by a later sub-issue).\n */\n queryPlanSummary: string,\n): Promise<string> {\n const canonical = JSON.stringify({\n mvName,\n dependencies: [...dependencies].sort(),\n queryPlanSummary,\n })\n const bytes = new TextEncoder().encode(canonical)\n return sha256Hex(bytes)\n}\n\n/**\n * Canonicalize a query plan for hashing. Walks the plan structure\n * with sorted keys so insertion order doesn't perturb the result.\n * Lives here rather than in `query/builder.ts` to keep that module\n * stable across MV-specific evolutions.\n *\n * @internal exported for testing\n */\nexport function canonicalizeQueryPlan(plan: unknown): string {\n return JSON.stringify(plan, (_key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n })\n}\n","import { MaterializedViewSourceUnknownError } from '../../kernel/errors.js'\nimport type { ViaGraph, FieldRef, EdgeKind, Grain } from '../../kernel/via/graph.js'\nimport type { Clause, FieldClause } from '../../kernel/query/predicate.js'\nimport type { DeclaredPredicate } from '../../kernel/query/builder.js'\nimport { analyzeDependencies, summarizeQueryPlan, summarizeUnionPlan, summarizeProjectionPlan } from './dependency-analyzer.js'\nimport { computeQueryHash } from './query-hash.js'\nimport type { MaterializedViewStrategy, MVQueryContext } from './types.js'\n\n/**\n * Whole-record artifact-grain field marker (#638 Task 2) — MUST match\n * `derivations/registry.ts`'s and `vault.ts`'s overlay-edge marker so\n * cross-registry edges (a derivation feeding an MV, or vice versa) resolve\n * to the SAME graph node. See that file's `WHOLE_RECORD` doc comment.\n */\nconst WHOLE_RECORD = '*'\n\n/**\n * One registered MV strategy alongside its derived metadata. Stored\n * type-erased on `TRow` so the registry can hold heterogeneous MVs.\n */\nexport interface RegisteredMV {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly spec: MaterializedViewStrategy<any>\n /** Output collection name (`spec.output?.collection ?? spec.name`). */\n readonly outputCollection: string\n /** Set of source collections; populated at registration via the analyzer. */\n readonly dependencies: ReadonlySet<string>\n /** Canonical `queryHash` — `_materializedFrom.queryHash` for every emitted row. */\n readonly queryHash: string\n /**\n * Top-level FieldClauses on the partition field, captured at\n * registration time. Used by the cycle detector to resolve\n * same-collection-as-source edges via the partition-discriminator\n * check. Empty when `spec.output?.partition` is undefined.\n */\n readonly partitionClauses: readonly FieldClause[]\n /**\n * #638 Task 2 — `'record'` for a row-per-source-row Query<T> or\n * `unionSources` MV, `'aggregate'` for a `.groupBy().aggregate()` MV\n * (the shape that requires explicit `sources`, since the dependency\n * analyzer can't walk an aggregate plan). Feeds `edges()`'s grain.\n */\n readonly grain: Grain\n}\n\n/**\n * Vault-internal registry of MV strategies. Owned by `Vault`; not\n * exported. Parallel to v1's `DerivationRegistry`; the two graphs share\n * a single cycle-detection pass at vault open (see `validate`).\n *\n * @internal\n */\nexport class MaterializedViewRegistry {\n /** Keyed by `spec.name`. */\n private readonly _byName = new Map<string, RegisteredMV>()\n /** Keyed by dependency source-collection → MVs that depend on it. */\n private readonly _bySource = new Map<string, RegisteredMV[]>()\n /**\n * Projection MVs (#810) whose forward-leg ref() targets could not be\n * resolved at registration time. A forward leg names only the FK\n * FIELD; its dependency is the field's ref() TARGET, declared on the\n * source collection — but registration runs at vault open, BEFORE\n * user code declares collections (and their refs). Constructing the\n * source collection here to look them up would be worse: a later\n * `vault.collection(source, { refs })` call only registers refs on a\n * cache miss, so an early construction would silently drop them.\n * Instead each entry carries a non-constructive ref-registry probe;\n * `mvsForSource` retries on every dispatch until every forward\n * target has resolved (see `_resolvePendingForwardDeps`).\n */\n private readonly _pendingForwardDeps: Array<{\n reg: RegisteredMV\n fields: Set<string>\n resolveTarget: (field: string) => string | null\n }> = []\n\n /**\n * Register an MV. Invokes `spec.query()` once at registration time to\n * read the plan + join context; the resulting `Query<T>` is discarded\n * after dependency extraction. `vault.collection(...)` must therefore\n * be functional by the time this runs — typically wired from\n * `Vault._initMaterializedViews` after collection bootstrap.\n *\n * Throws `MaterializedViewSourceUnknownError` if the analyzer\n * surfaces a dependency the vault doesn't know about (when a\n * `knownCollections` checker is supplied).\n */\n async register(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n spec: MaterializedViewStrategy<any>,\n db: MVQueryContext,\n options?: { knownCollections?: (name: string) => boolean },\n ): Promise<void> {\n // Build a predicate-aware db wrapper. If `spec.predicates` is\n // declared, the wrapper intercepts `.collection().query()` and\n // attaches the predicates map to the resulting Query<T>. With no\n // predicates declared, the wrapper is the original db unchanged.\n const dbForQuery = spec.predicates ? wrapDbWithPredicates(db, spec.predicates) : db\n\n // Invoke the query callback once to inspect its plan / dependencies.\n // For Query<T> shapes the analyzer extracts deps + plan summary\n // automatically. Aggregation / GroupedAggregation shapes don't\n // expose the underlying Query, so the spec must declare `sources`\n // explicitly. `partitionClauses` are only populated for Query<T>\n // since same-collection-partition is a non-aggregate concern.\n // UNION-form strategies: dependencies and plan summary come\n // straight off the strategy — no `query` callback to introspect.\n // The dependency-analyzer + summarizer are bypassed entirely; the\n // executor handles materialization via `materializeUnionResult`.\n let dependencies: Set<string>\n let queryPlanSummary: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let qAny: any = null\n let isQuery = false\n // Projection-form (#810): forward legs whose ref() target wasn't\n // resolvable at registration time — folded in lazily, see\n // `_pendingForwardDeps`.\n const pendingForwardFields: string[] = []\n if (spec.unionSources) {\n dependencies = new Set(spec.unionSources.map(s => s.collection))\n // Per-arm joins resolve right-side collections that aren't among\n // the arm `collection`s. The consumer lists those in `sources`;\n // fold them into the dependency set so a write to a join-target\n // collection triggers MV refresh (and contributes a cycle edge).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeUnionPlan(spec)\n } else if (spec.projection) {\n // Projection-form (#810): dependencies are all AUTO — the primary\n // source, every collect leg's collection (both literal names), and\n // every forward leg's ref() target. Forward targets usually can't\n // resolve yet (refs are declared after vault open) — those go\n // through the pending-resolution path below. Explicit `sources`\n // remains additive, same as the other two forms.\n const projection = spec.projection\n dependencies = new Set([projection.source])\n for (const leg of projection.joins) {\n if ('collect' in leg) dependencies.add(leg.collect)\n else pendingForwardFields.push(leg.field)\n }\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeProjectionPlan(spec)\n } else {\n const q = spec.query!(dbForQuery)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n qAny = q as any\n isQuery = typeof qAny._plan === 'function'\n if (isQuery) {\n // `q` is the `Query` arm of the union here (runtime-confirmed via\n // `qAny._plan` above); reuse the already-`any` `qAny` the block uses\n // for `_plan()` rather than re-narrowing.\n dependencies = analyzeDependencies(qAny)\n queryPlanSummary = summarizeQueryPlan(qAny)\n // Fold `.wherePredicate(name, ctx)` references into the plan\n // summary so predicate function or ctx changes (signalled by\n // bumping `hash` or supplying a different ctx) propagate into\n // `queryHash` and force refresh on next visit.\n const predicateRefs = extractPredicateRefs(qAny._plan())\n if (predicateRefs.length > 0) {\n queryPlanSummary = JSON.stringify({ plan: queryPlanSummary, predicates: predicateRefs })\n }\n // If `sources` is ALSO declared, take the union (consumer's\n // explicit list extends the auto-analyzed set).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n } else {\n // Aggregate shape: require explicit `sources`.\n if (!spec.sources || spec.sources.length === 0) {\n throw new Error(\n `withMaterializedView \"${spec.name}\": query() returned an aggregate ` +\n `(Aggregation or GroupedAggregation) but no \\`sources\\` field is declared. ` +\n `The dependency analyzer cannot walk through groupBy().aggregate() ` +\n `back to the source — declare sources: [...] explicitly.`,\n )\n }\n dependencies = new Set(spec.sources)\n // Aggregate plans don't carry a chainable query plan for summary\n // purposes; the dep-set + spec.name serve as the queryHash inputs.\n queryPlanSummary = JSON.stringify({ aggregate: true, sources: [...spec.sources].sort() })\n }\n }\n\n // Sanity-check declared dependencies against the vault's known\n // collections. Optional — when the checker isn't supplied (test\n // wiring, in-process composition) the registration succeeds and\n // any typo surfaces at first onSourceWrite as a no-op.\n if (options?.knownCollections) {\n for (const dep of dependencies) {\n if (!options.knownCollections(dep)) {\n throw new MaterializedViewSourceUnknownError(spec.name, dep)\n }\n }\n }\n\n const outputCollection = spec.output?.collection ?? spec.name\n const queryHash = await computeQueryHash(spec.name, dependencies, queryPlanSummary)\n // For same-collection-as-source MVs, capture the where-clauses on\n // the partition field so cycle detection can prove disjointness.\n // Only applicable to Query<T> shapes — aggregate MVs don't carry\n // a chainable plan to inspect (and same-collection aggregation\n // doesn't make sense for same-collection aggregation).\n const partitionClauses: FieldClause[] = []\n const partitionField = spec.output?.partition?.field\n if (partitionField !== undefined && isQuery) {\n const plan = qAny._plan()\n for (const clause of plan.clauses) {\n if (isFieldClauseOnField(clause, partitionField)) partitionClauses.push(clause)\n }\n }\n // #638 Task 2 — 'aggregate' only for the explicit-sources aggregate shape\n // (groupBy().aggregate() with no chainable plan); a row-per-source-row\n // Query<T>, unionSources, or projection MV is 'record'.\n const grain: Grain = spec.unionSources || spec.projection || isQuery ? 'record' : 'aggregate'\n const reg: RegisteredMV = { spec, outputCollection, dependencies, queryHash, partitionClauses, grain }\n\n this._byName.set(spec.name, reg)\n for (const dep of dependencies) {\n const arr = this._bySource.get(dep)\n if (arr) arr.push(reg)\n else this._bySource.set(dep, [reg])\n }\n if (pendingForwardFields.length > 0) {\n // Non-constructive ref-registry probe: the Vault (the real\n // MVQueryContext) carries its RefRegistry as a private field,\n // reachable structurally at runtime. Test stubs without one simply\n // never resolve — forward deps then come only from explicit `sources`.\n const refRegistry = (db as unknown as {\n refRegistry?: { getOutbound(collection: string): Record<string, { target: string }> }\n }).refRegistry\n const source = spec.projection!.source\n this._pendingForwardDeps.push({\n reg,\n fields: new Set(pendingForwardFields),\n resolveTarget: (field) => refRegistry?.getOutbound(source)[field]?.target ?? null,\n })\n // Immediate attempt — covers refs already declared by the time\n // this MV registers (re-registration flows, test wiring).\n this._resolvePendingForwardDeps()\n }\n }\n\n /** All MVs that depend on `source`, in registration order. */\n mvsForSource(source: string): ReadonlyArray<RegisteredMV> {\n if (this._pendingForwardDeps.length > 0) this._resolvePendingForwardDeps()\n return this._bySource.get(source) ?? []\n }\n\n /**\n * Retry ref() resolution for every pending projection forward leg\n * (#810). A field resolves once its source collection's refs have\n * been declared; the target then folds into the owning MV's\n * dependency set and `_bySource`, so subsequent writes to it\n * dispatch a refresh. Idempotent and cheap — the pending list\n * empties as fields resolve, and `mvsForSource` skips the call\n * entirely once it's empty.\n *\n * Late-resolved targets do NOT retro-feed `edges()` — the cycle\n * pass runs once at vault open, before refs exist. A cycle routed\n * exclusively through a forward leg is therefore not detected at\n * open (collect + source edges, the literal names, are).\n */\n private _resolvePendingForwardDeps(): void {\n for (let i = this._pendingForwardDeps.length - 1; i >= 0; i--) {\n const entry = this._pendingForwardDeps[i]!\n for (const field of [...entry.fields]) {\n const target = entry.resolveTarget(field)\n if (target === null) continue\n entry.fields.delete(field)\n if (entry.reg.dependencies.has(target)) continue\n // `dependencies` is declared ReadonlySet for consumers; the\n // registry owns the underlying Set and is the one writer.\n ;(entry.reg.dependencies as Set<string>).add(target)\n const arr = this._bySource.get(target)\n if (arr) arr.push(entry.reg)\n else this._bySource.set(target, [entry.reg])\n }\n if (entry.fields.size === 0) this._pendingForwardDeps.splice(i, 1)\n }\n }\n\n /** Single MV by name, or `undefined`. */\n byName(name: string): RegisteredMV | undefined {\n return this._byName.get(name)\n }\n\n /** Iterate over every registered MV. */\n all(): ReadonlyArray<RegisteredMV> {\n return [...this._byName.values()]\n }\n\n /**\n * Graph edges for #638 Task 2: one `'mv'` edge per registered MV — target\n * = the output collection (a `WHOLE_RECORD` artifact node), sources =\n * every dependency (also `WHOLE_RECORD` nodes). Same-collection edges\n * (`dep === outputCollection`) are skipped IFF the MV declares an\n * `output.partition` discriminator AND the query has a where-clause that\n * provably excludes the partition value (`partitionDisjoint`) — the SAME\n * condition the old local DFS used. Grain comes from the registration-time\n * `RegisteredMV.grain`.\n */\n edges(): ReadonlyArray<{ readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly kind: EdgeKind; readonly grain: Grain }> {\n const out: Array<{ target: FieldRef; sources: FieldRef[]; kind: EdgeKind; grain: Grain }> = []\n for (const reg of this._byName.values()) {\n const sources: FieldRef[] = []\n for (const dep of reg.dependencies) {\n if (dep === reg.outputCollection && partitionDisjoint(reg)) continue\n sources.push({ collection: dep, field: WHOLE_RECORD })\n }\n if (sources.length === 0) continue\n out.push({ target: { collection: reg.outputCollection, field: WHOLE_RECORD }, sources, kind: 'mv', grain: reg.grain })\n }\n return out\n }\n\n /**\n * Cycle detection, delegated to `ViaGraph.assertAcyclic()` (#638 Task 2 —\n * retires the local DFS). `graph` is the caller's shared per-vault graph,\n * ALREADY carrying this registry's `edges()` AND `DerivationRegistry`'s\n * (registered by the caller — see `Vault._initMaterializedViews`, which\n * runs after `_initDerivations`, so a pure-derivation cycle already threw\n * `DerivationCycleError` there; any cycle surfacing here necessarily\n * touches an MV edge). Throws `MaterializedViewCycleError` — SAME class as\n * before.\n */\n validate(graph: ViaGraph): void {\n graph.assertAcyclic()\n }\n}\n\n/**\n * Type guard: is the clause a top-level `FieldClause` on the given\n * field? Used by the partition-disjoint check.\n *\n * @internal\n */\nfunction isFieldClauseOnField(clause: Clause, field: string): clause is FieldClause {\n return clause.type === 'field' && clause.field === field\n}\n\n/**\n * Wrap an `MVQueryContext` so its `.collection().query()` returns a\n * Query<T> with the MV's declared predicates attached. Bare Queries\n * (outside of any MV) don't gain `.wherePredicate()` — only Queries\n * obtained through this wrapped db do.\n *\n * @internal\n */\nexport function wrapDbWithPredicates(\n db: MVQueryContext,\n predicates: NonNullable<MaterializedViewStrategy<Record<string, unknown>>['predicates']>,\n): MVQueryContext {\n // Build the predicate map once — the fn signature in the MV spec\n // is row-typed but the QueryBuilder casts to unknown, so we widen\n // here for the Map.\n const map = new Map<string, DeclaredPredicate>()\n for (const [name, decl] of Object.entries(predicates)) {\n map.set(name, {\n hash: decl.hash,\n fn: decl.fn as (record: unknown, ctx?: unknown) => boolean,\n })\n }\n return {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n collection<T extends Record<string, unknown>>(name: string): any {\n const c = db.collection<T>(name)\n // Return an object that delegates everything to `c` but\n // overrides `.query()` to attach predicates via the new\n // `Query._withPredicates()` accessor.\n return new Proxy(c, {\n get(target, prop, receiver) {\n if (prop === 'query') {\n return (...args: unknown[]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const q = (target.query as any)(...args)\n // For non-aggregate Query<T>, attach predicates. For\n // legacy predicate-arg overload that returns T[] (sync\n // filter), pass through unchanged.\n \n if (q && typeof q._withPredicates === 'function') {\n return q._withPredicates(map)\n }\n return q\n }\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n },\n }\n}\n\n/**\n * Walk a QueryPlan's clauses and collect predicate-reference markers\n * for `queryHash` derivation. Returns a sorted array (deterministic\n * order) of `{ name, predicateHash, ctxHash }` tuples — these are the\n * hashable identity of each `.wherePredicate()` call site.\n *\n * @internal\n */\nfunction extractPredicateRefs(\n plan: { clauses: readonly Clause[] },\n): Array<{ name: string; predicateHash: string; ctxHash: string }> {\n const refs: Array<{ name: string; predicateHash: string; ctxHash: string }> = []\n const walk = (clauses: readonly Clause[]): void => {\n for (const c of clauses) {\n if (c.type === 'wherePredicate') {\n refs.push({ name: c.name, predicateHash: c.predicateHash, ctxHash: c.ctxHash })\n } else if (c.type === 'group') {\n walk(c.clauses)\n }\n }\n }\n walk(plan.clauses)\n // Stable-sort by (name, predicateHash, ctxHash) — same predicate\n // appearing twice with different ctx hashes both flow through.\n refs.sort((a, b) => {\n if (a.name !== b.name) return a.name < b.name ? -1 : 1\n if (a.predicateHash !== b.predicateHash) return a.predicateHash < b.predicateHash ? -1 : 1\n return a.ctxHash < b.ctxHash ? -1 : a.ctxHash > b.ctxHash ? 1 : 0\n })\n return refs\n}\n\n/**\n * Provability check for the same-collection partition-discriminator.\n * Returns `true` when\n * the captured partition clauses on the MV's query provably exclude\n * the partition's value — meaning the input filter and the output\n * partition are disjoint and the same-collection edge isn't really a\n * cycle.\n *\n * Supported provability shapes (narrow on purpose — DERIV-PP30-001\n * is the load-bearing case):\n *\n * - `.where(field, '==', X)` where X !== partition.value → disjoint\n * - `.where(field, '!=', partition.value)` → disjoint\n * - `.where(field, 'in', [...])` where partition.value NOT in list → disjoint\n *\n * Anything else (no clause on the partition field, an 'in' list that\n * contains partition.value, unsupported operators) → not disjoint,\n * the cycle detector surfaces `MaterializedViewCycleError`.\n *\n * @internal\n */\nfunction partitionDisjoint(reg: RegisteredMV): boolean {\n const partition = reg.spec.output?.partition\n if (partition === undefined) return false\n const value = partition.value\n // The OR-semantics of multiple where-clauses on the same field\n // would muddy this check. v2 only treats AND-chained clauses;\n // any clause that proves disjoint is sufficient.\n for (const c of reg.partitionClauses) {\n if (c.op === '==' && c.value !== value) return true\n if (c.op === '!=' && c.value === value) return true\n if (c.op === 'in' && Array.isArray(c.value)) {\n const list = c.value as readonly unknown[]\n if (!list.includes(value)) return true\n }\n }\n return false\n}\n"],"mappings":"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","names":[]}