@noy-db/hub 0.2.0-pre.8 → 0.3.0-pre.1

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 (541) hide show
  1. package/README.md +129 -3
  2. package/dist/adapter/index.d.ts +5 -0
  3. package/dist/adapter/index.js +15 -0
  4. package/dist/aggregate/index.d.ts +6 -2
  5. package/dist/aggregate/index.js +24 -16
  6. package/dist/aggregate/index.js.map +1 -1
  7. package/dist/api-RW3KP7WU.js +14 -0
  8. package/dist/as/index.d.ts +7 -0
  9. package/dist/as/index.js +24 -0
  10. package/dist/at/index.d.ts +5 -0
  11. package/dist/at/index.js +1 -0
  12. package/dist/attestation/index.d.ts +15 -47
  13. package/dist/attestation/index.js +54 -10
  14. package/dist/attestation/index.js.map +1 -1
  15. package/dist/backup-XV3IOEGB.js +217 -0
  16. package/dist/backup-XV3IOEGB.js.map +1 -0
  17. package/dist/blobs/index.d.ts +6 -8
  18. package/dist/blobs/index.js +19 -12
  19. package/dist/blobs/index.js.map +1 -1
  20. package/dist/bundle/index.d.ts +16 -70
  21. package/dist/bundle/index.js +39 -476
  22. package/dist/bundle/index.js.map +1 -1
  23. package/dist/{ulid-BFJkYRRW.d.ts → bundle-CH-H06dp.d.ts} +31 -86
  24. package/dist/by/index.d.ts +1 -0
  25. package/dist/by/index.js +11 -0
  26. package/dist/cargo/index.d.ts +9 -0
  27. package/dist/cargo/index.js +89 -0
  28. package/dist/chunk-26LGBE4T.js +42 -0
  29. package/dist/chunk-26LGBE4T.js.map +1 -0
  30. package/dist/chunk-2P2HZEXU.js +233 -0
  31. package/dist/chunk-2P2HZEXU.js.map +1 -0
  32. package/dist/{chunk-K3DK3NU5.js → chunk-3YFXJ3ZP.js} +20 -5
  33. package/dist/chunk-3YFXJ3ZP.js.map +1 -0
  34. package/dist/chunk-4Q6HSHHL.js +90 -0
  35. package/dist/chunk-4Q6HSHHL.js.map +1 -0
  36. package/dist/chunk-5LUY7UTV.js +380 -0
  37. package/dist/chunk-5LUY7UTV.js.map +1 -0
  38. package/dist/chunk-5N6CZTCY.js +367 -0
  39. package/dist/chunk-5N6CZTCY.js.map +1 -0
  40. package/dist/chunk-5O3AOPDT.js +992 -0
  41. package/dist/chunk-5O3AOPDT.js.map +1 -0
  42. package/dist/chunk-5R3ERCDH.js +239 -0
  43. package/dist/chunk-5R3ERCDH.js.map +1 -0
  44. package/dist/{chunk-6774ZOQ7.js → chunk-5R5JW2JT.js} +7095 -4769
  45. package/dist/chunk-5R5JW2JT.js.map +1 -0
  46. package/dist/chunk-5TDJ56JE.js +32 -0
  47. package/dist/chunk-5TDJ56JE.js.map +1 -0
  48. package/dist/{chunk-T7JEBOGN.js → chunk-62QYRORB.js} +18 -11
  49. package/dist/chunk-62QYRORB.js.map +1 -0
  50. package/dist/{chunk-J66GRPNH.js → chunk-6S7T6WC4.js} +2 -2
  51. package/dist/chunk-6S7T6WC4.js.map +1 -0
  52. package/dist/chunk-76722EBH.js +451 -0
  53. package/dist/chunk-76722EBH.js.map +1 -0
  54. package/dist/{chunk-Z6FNBOTC.js → chunk-AIWULCUO.js} +13 -17
  55. package/dist/chunk-AIWULCUO.js.map +1 -0
  56. package/dist/{chunk-O3VZPBZG.js → chunk-AQTBSL7R.js} +47 -11
  57. package/dist/chunk-AQTBSL7R.js.map +1 -0
  58. package/dist/chunk-AURFOK3D.js +35 -0
  59. package/dist/chunk-AURFOK3D.js.map +1 -0
  60. package/dist/{chunk-53XBRIRT.js → chunk-AXRXJTE2.js} +9 -9
  61. package/dist/chunk-AXRXJTE2.js.map +1 -0
  62. package/dist/chunk-AZAOEIKW.js +155 -0
  63. package/dist/chunk-AZAOEIKW.js.map +1 -0
  64. package/dist/{chunk-HNRHLRDC.js → chunk-BG3SPSR4.js} +3 -3
  65. package/dist/chunk-BG3SPSR4.js.map +1 -0
  66. package/dist/chunk-BGIZAFY7.js +1 -0
  67. package/dist/chunk-CHFZDSE4.js +1 -0
  68. package/dist/{chunk-DJHHA6XH.js → chunk-CMGR4ZEW.js} +50 -20
  69. package/dist/chunk-CMGR4ZEW.js.map +1 -0
  70. package/dist/chunk-CWPPNPOH.js +23 -0
  71. package/dist/chunk-CWPPNPOH.js.map +1 -0
  72. package/dist/{chunk-QODLLGQ7.js → chunk-DFEMTNPJ.js} +371 -38
  73. package/dist/chunk-DFEMTNPJ.js.map +1 -0
  74. package/dist/{chunk-ZYWZWG6G.js → chunk-DGDI2D4M.js} +10 -10
  75. package/dist/chunk-DGDI2D4M.js.map +1 -0
  76. package/dist/{chunk-SYMWGEET.js → chunk-EIZUR2XW.js} +3 -3
  77. package/dist/chunk-EIZUR2XW.js.map +1 -0
  78. package/dist/{chunk-BVRYKATC.js → chunk-FISN7WE4.js} +36 -33
  79. package/dist/chunk-FISN7WE4.js.map +1 -0
  80. package/dist/chunk-GHVIKOHT.js +1 -0
  81. package/dist/chunk-GYGWYIOZ.js +200 -0
  82. package/dist/chunk-GYGWYIOZ.js.map +1 -0
  83. package/dist/chunk-HCIPRAGS.js +45 -0
  84. package/dist/chunk-HCIPRAGS.js.map +1 -0
  85. package/dist/{chunk-PX35GA7L.js → chunk-I2NOIW44.js} +10 -10
  86. package/dist/chunk-I2NOIW44.js.map +1 -0
  87. package/dist/{chunk-OIF6LZUR.js → chunk-I3TIKTJO.js} +3 -3
  88. package/dist/chunk-I3TIKTJO.js.map +1 -0
  89. package/dist/chunk-I7FD46FF.js +9 -0
  90. package/dist/chunk-I7FD46FF.js.map +1 -0
  91. package/dist/chunk-IAGBDSCS.js +40 -0
  92. package/dist/chunk-IAGBDSCS.js.map +1 -0
  93. package/dist/{chunk-JWRVQKRZ.js → chunk-IELYAOGG.js} +6 -18
  94. package/dist/chunk-IELYAOGG.js.map +1 -0
  95. package/dist/chunk-IGUYVGGI.js +205 -0
  96. package/dist/chunk-IGUYVGGI.js.map +1 -0
  97. package/dist/{chunk-U26HQ6KJ.js → chunk-IO6GRPT6.js} +4 -4
  98. package/dist/chunk-IO6GRPT6.js.map +1 -0
  99. package/dist/chunk-IPB7FTQX.js +273 -0
  100. package/dist/chunk-IPB7FTQX.js.map +1 -0
  101. package/dist/chunk-ITNUCOXM.js +148 -0
  102. package/dist/chunk-ITNUCOXM.js.map +1 -0
  103. package/dist/{chunk-WPLVTJ5D.js → chunk-IUEN57TV.js} +10 -10
  104. package/dist/chunk-IUEN57TV.js.map +1 -0
  105. package/dist/{chunk-DL3HWOQ5.js → chunk-JNUWZ6D3.js} +9 -9
  106. package/dist/chunk-JNUWZ6D3.js.map +1 -0
  107. package/dist/chunk-K2WCO3NX.js +1 -0
  108. package/dist/chunk-KVOXU4T5.js +30 -0
  109. package/dist/chunk-KVOXU4T5.js.map +1 -0
  110. package/dist/chunk-KXGNJJXB.js +135 -0
  111. package/dist/chunk-KXGNJJXB.js.map +1 -0
  112. package/dist/chunk-LB7FD65R.js +163 -0
  113. package/dist/chunk-LB7FD65R.js.map +1 -0
  114. package/dist/{chunk-22DWZL57.js → chunk-LFLXAY2W.js} +43 -218
  115. package/dist/chunk-LFLXAY2W.js.map +1 -0
  116. package/dist/chunk-LMTH2RM6.js +129 -0
  117. package/dist/chunk-LMTH2RM6.js.map +1 -0
  118. package/dist/{aggregate/index.cjs → chunk-LV7M27WM.js} +390 -219
  119. package/dist/chunk-LV7M27WM.js.map +1 -0
  120. package/dist/{chunk-PE2FR4J3.js → chunk-LXQT4WMP.js} +16 -18
  121. package/dist/chunk-LXQT4WMP.js.map +1 -0
  122. package/dist/chunk-M2YKN37S.js +524 -0
  123. package/dist/chunk-M2YKN37S.js.map +1 -0
  124. package/dist/chunk-M6OST55S.js +14 -0
  125. package/dist/chunk-M6OST55S.js.map +1 -0
  126. package/dist/{chunk-F3GDRNUT.js → chunk-MD3Y6J3L.js} +35 -69
  127. package/dist/chunk-MD3Y6J3L.js.map +1 -0
  128. package/dist/{chunk-XJFLDA7A.js → chunk-MTMJVJ5W.js} +8 -7
  129. package/dist/chunk-MTMJVJ5W.js.map +1 -0
  130. package/dist/{chunk-DFMLEQZB.js → chunk-NF5JWERG.js} +5 -10
  131. package/dist/chunk-NF5JWERG.js.map +1 -0
  132. package/dist/{chunk-DO7C2TOG.js → chunk-PKHL44ER.js} +3 -3
  133. package/dist/{chunk-DO7C2TOG.js.map → chunk-PKHL44ER.js.map} +1 -1
  134. package/dist/chunk-PSMV73A5.js +117 -0
  135. package/dist/chunk-PSMV73A5.js.map +1 -0
  136. package/dist/chunk-PY4KJPYU.js +9 -0
  137. package/dist/chunk-PY4KJPYU.js.map +1 -0
  138. package/dist/chunk-PZ5AY32C.js +10 -0
  139. package/dist/{chunk-DE6GKS6G.js → chunk-Q7SS3IME.js} +50 -9
  140. package/dist/chunk-Q7SS3IME.js.map +1 -0
  141. package/dist/chunk-QHJW5EXU.js +54 -0
  142. package/dist/chunk-QHJW5EXU.js.map +1 -0
  143. package/dist/{chunk-NONAAENK.js → chunk-RUEKROOS.js} +11 -4
  144. package/dist/chunk-RUEKROOS.js.map +1 -0
  145. package/dist/chunk-RUIMKQTA.js +23 -0
  146. package/dist/chunk-RUIMKQTA.js.map +1 -0
  147. package/dist/{chunk-TFBP23BX.js → chunk-SKF73JOP.js} +66 -7
  148. package/dist/chunk-SKF73JOP.js.map +1 -0
  149. package/dist/chunk-SM3AVUHC.js +42 -0
  150. package/dist/chunk-SM3AVUHC.js.map +1 -0
  151. package/dist/{chunk-ML236QKC.js → chunk-SMXWYP24.js} +5 -5
  152. package/dist/chunk-SMXWYP24.js.map +1 -0
  153. package/dist/chunk-SRB2XEWB.js +148 -0
  154. package/dist/chunk-SRB2XEWB.js.map +1 -0
  155. package/dist/chunk-SVLR4POP.js +64 -0
  156. package/dist/chunk-SVLR4POP.js.map +1 -0
  157. package/dist/chunk-TA66UMI4.js +123 -0
  158. package/dist/chunk-TA66UMI4.js.map +1 -0
  159. package/dist/chunk-TEILUWOI.js +664 -0
  160. package/dist/chunk-TEILUWOI.js.map +1 -0
  161. package/dist/chunk-TJYQIGAP.js +82 -0
  162. package/dist/chunk-TJYQIGAP.js.map +1 -0
  163. package/dist/{chunk-H2X3ISXG.js → chunk-UAG5KWVA.js} +7 -7
  164. package/dist/chunk-UAG5KWVA.js.map +1 -0
  165. package/dist/chunk-UDRIWL7A.js +382 -0
  166. package/dist/chunk-UDRIWL7A.js.map +1 -0
  167. package/dist/{chunk-2GLDA55J.js → chunk-UIU2THRG.js} +498 -133
  168. package/dist/chunk-UIU2THRG.js.map +1 -0
  169. package/dist/{chunk-3YPCK6JX.js → chunk-UPJNJGGA.js} +165 -423
  170. package/dist/chunk-UPJNJGGA.js.map +1 -0
  171. package/dist/chunk-UV5MFVO3.js +21 -0
  172. package/dist/chunk-UV5MFVO3.js.map +1 -0
  173. package/dist/{chunk-2WUSG3IT.js → chunk-V7RWQRG7.js} +5 -5
  174. package/dist/chunk-V7RWQRG7.js.map +1 -0
  175. package/dist/{chunk-VTKGMEPP.js → chunk-VCTFO5CO.js} +13 -3
  176. package/dist/chunk-VCTFO5CO.js.map +1 -0
  177. package/dist/{chunk-5T22KDPN.js → chunk-VFQGRQIH.js} +8 -8
  178. package/dist/chunk-VFQGRQIH.js.map +1 -0
  179. package/dist/{chunk-2QR2PQTT.js → chunk-VQNJ7UZL.js} +5 -3
  180. package/dist/chunk-VQNJ7UZL.js.map +1 -0
  181. package/dist/{chunk-DONMZAD2.js → chunk-WWGT2MDV.js} +43 -165
  182. package/dist/chunk-WWGT2MDV.js.map +1 -0
  183. package/dist/{chunk-EMIGCR7X.js → chunk-WXSYDNBT.js} +2 -2
  184. package/dist/chunk-WXSYDNBT.js.map +1 -0
  185. package/dist/chunk-WYSO2NIH.js +30 -0
  186. package/dist/chunk-WYSO2NIH.js.map +1 -0
  187. package/dist/chunk-XXYIOFUB.js +164 -0
  188. package/dist/chunk-XXYIOFUB.js.map +1 -0
  189. package/dist/{chunk-3BFJOWSU.js → chunk-Y22T3KQE.js} +35 -7
  190. package/dist/chunk-Y22T3KQE.js.map +1 -0
  191. package/dist/{chunk-A3JMGXPG.js → chunk-YMUGBZN2.js} +2 -2
  192. package/dist/chunk-YMUGBZN2.js.map +1 -0
  193. package/dist/{chunk-I5FOWO4J.js → chunk-ZCGAHGUS.js} +52 -73
  194. package/dist/chunk-ZCGAHGUS.js.map +1 -0
  195. package/dist/{chunk-FZU343FL.js → chunk-ZJADGNYF.js} +2 -2
  196. package/dist/chunk-ZJADGNYF.js.map +1 -0
  197. package/dist/{chunk-B6PB7JLN.js → chunk-ZYUC53LT.js} +427 -6
  198. package/dist/chunk-ZYUC53LT.js.map +1 -0
  199. package/dist/collection-facade-GQAOGJP2.js +33 -0
  200. package/dist/consent/index.d.ts +5 -7
  201. package/dist/consent/index.js +7 -5
  202. package/dist/consent/index.js.map +1 -1
  203. package/dist/crdt/index.d.ts +6 -2
  204. package/dist/crdt/index.js +3 -2
  205. package/dist/crdt/index.js.map +1 -1
  206. package/dist/decrypt-partition-IHtxEnTi.d.ts +21 -0
  207. package/dist/delegation-UL5HKLER.js +19 -0
  208. package/dist/derivations/index.d.ts +7 -9
  209. package/dist/derivations/index.js +11 -6
  210. package/dist/describe/index.d.ts +1 -0
  211. package/dist/describe/index.js +1 -0
  212. package/dist/describe-aBkJR2sd.d.ts +131 -0
  213. package/dist/{dev-unlock-p3ysikWP.d.ts → dev-unlock-C9Ro3v_O.d.ts} +1 -1
  214. package/dist/discriminant-BN9REW3o.d.ts +60 -0
  215. package/dist/enclave-UL5LW66V.js +88 -0
  216. package/dist/executor-2FWQRLMG.js +15 -0
  217. package/dist/executor-QZ7BXICW.js +9 -0
  218. package/dist/executor-Z5ZLJVTV.js +9 -0
  219. package/dist/export-accessible-KRV5W4GH.js +17 -0
  220. package/dist/extract-partition-GLKBOXFQ.js +30 -0
  221. package/dist/{fanout-sidecar-OKPMMPLG.js → fanout-sidecar-GF3DJ6KR.js} +34 -14
  222. package/dist/fanout-sidecar-GF3DJ6KR.js.map +1 -0
  223. package/dist/forget/index.d.ts +36 -0
  224. package/dist/forget/index.js +19 -0
  225. package/dist/forget/index.js.map +1 -0
  226. package/dist/guards/index.d.ts +13 -9
  227. package/dist/guards/index.js +12 -5
  228. package/dist/{hash-BPsYPcv_.d.cts → hash-Cp5uwiox.d.ts} +5 -1
  229. package/dist/history/index.d.ts +6 -8
  230. package/dist/history/index.js +19 -12
  231. package/dist/history/index.js.map +1 -1
  232. package/dist/i18n/index.d.ts +5 -7
  233. package/dist/i18n/index.js +104 -15
  234. package/dist/i18n/index.js.map +1 -1
  235. package/dist/in/index.d.ts +5 -0
  236. package/dist/in/index.js +1 -0
  237. package/dist/in/index.js.map +1 -0
  238. package/dist/index-B9QdHytu.d.ts +123 -0
  239. package/dist/index-BF9_96A5.d.ts +123 -0
  240. package/dist/{types-DGU60JDt.d.ts → index-BzUo1B6n.d.ts} +16306 -8352
  241. package/dist/index.d.ts +1088 -450
  242. package/dist/index.js +1165 -293
  243. package/dist/index.js.map +1 -1
  244. package/dist/indexing/index.d.ts +6 -3
  245. package/dist/indexing/index.js +6 -5
  246. package/dist/indexing/index.js.map +1 -1
  247. package/dist/issue-Y6UVIR43.js +13 -0
  248. package/dist/issue-Y6UVIR43.js.map +1 -0
  249. package/dist/kernel/index.d.ts +32 -0
  250. package/dist/kernel/index.js +53 -0
  251. package/dist/kernel/index.js.map +1 -0
  252. package/dist/{ledger-TMRZYNVJ.js → ledger-RYI35CDS.js} +12 -9
  253. package/dist/ledger-RYI35CDS.js.map +1 -0
  254. package/dist/liberate-CRPZEV7O.js +18 -0
  255. package/dist/liberate-CRPZEV7O.js.map +1 -0
  256. package/dist/materialized-views/index.d.ts +6 -19
  257. package/dist/materialized-views/index.js +16 -12
  258. package/dist/mime-magic-CGhw37_E.d.ts +103 -0
  259. package/dist/noydb-367AM4HT.js +50 -0
  260. package/dist/noydb-367AM4HT.js.map +1 -0
  261. package/dist/on/index.d.ts +5 -0
  262. package/dist/on/index.js +11 -0
  263. package/dist/on/index.js.map +1 -0
  264. package/dist/overlay-views/index.d.ts +27 -11
  265. package/dist/overlay-views/index.js +7 -6
  266. package/dist/periods/index.d.ts +5 -7
  267. package/dist/periods/index.js +13 -9
  268. package/dist/pod/index.d.ts +63 -0
  269. package/dist/pod/index.js +61 -0
  270. package/dist/pod/index.js.map +1 -0
  271. package/dist/policy-IXK4FVXP.js +41 -0
  272. package/dist/policy-IXK4FVXP.js.map +1 -0
  273. package/dist/portability/index.d.ts +20 -0
  274. package/dist/portability/index.js +43 -0
  275. package/dist/portability/index.js.map +1 -0
  276. package/dist/{public-envelope-BW6OXORV.js → public-envelope-JHDQCPSX.js} +6 -5
  277. package/dist/public-envelope-JHDQCPSX.js.map +1 -0
  278. package/dist/query/index.d.ts +5 -3
  279. package/dist/query/index.js +21 -13
  280. package/dist/read-only-facade-5ADRJVTM.js +8 -0
  281. package/dist/read-only-facade-5ADRJVTM.js.map +1 -0
  282. package/dist/registry-45RJNWGU.js +9 -0
  283. package/dist/registry-45RJNWGU.js.map +1 -0
  284. package/dist/registry-5GRV5VXI.js +13 -0
  285. package/dist/registry-5GRV5VXI.js.map +1 -0
  286. package/dist/registry-VW6P6A3J.js +8 -0
  287. package/dist/registry-VW6P6A3J.js.map +1 -0
  288. package/dist/registry-WEUCHBO4.js +11 -0
  289. package/dist/registry-WEUCHBO4.js.map +1 -0
  290. package/dist/request-withdrawal-GBPH2FDY.js +25 -0
  291. package/dist/request-withdrawal-GBPH2FDY.js.map +1 -0
  292. package/dist/revoke-TUFRGI6S.js +18 -0
  293. package/dist/revoke-TUFRGI6S.js.map +1 -0
  294. package/dist/sealed-record/index.d.ts +69 -0
  295. package/dist/sealed-record/index.js +65 -0
  296. package/dist/sealed-record/index.js.map +1 -0
  297. package/dist/session/index.d.ts +6 -8
  298. package/dist/session/index.js +7 -5
  299. package/dist/session/index.js.map +1 -1
  300. package/dist/shadow/index.d.ts +5 -7
  301. package/dist/shadow/index.js +4 -3
  302. package/dist/shadow/index.js.map +1 -1
  303. package/dist/{signer-72QAUSVW.js → signer-PNKTBVF7.js} +6 -5
  304. package/dist/signer-PNKTBVF7.js.map +1 -0
  305. package/dist/snapshots/index.d.ts +16 -11
  306. package/dist/snapshots/index.js +49 -13
  307. package/dist/snapshots/index.js.map +1 -1
  308. package/dist/{stale-6ZDBTQT7.js → stale-3JWHNDIY.js} +3 -2
  309. package/dist/stale-3JWHNDIY.js.map +1 -0
  310. package/dist/store-coordination-provider-3I7XWZZK.js +142 -0
  311. package/dist/store-coordination-provider-3I7XWZZK.js.map +1 -0
  312. package/dist/subject-index-O75wKshW.d.ts +362 -0
  313. package/dist/sync/index.d.ts +4 -6
  314. package/dist/sync/index.js +7 -6
  315. package/dist/sync/index.js.map +1 -1
  316. package/dist/team/index.d.ts +5 -7
  317. package/dist/team/index.js +20 -16
  318. package/dist/tiers/index.d.ts +5 -0
  319. package/dist/tiers/index.js +33 -0
  320. package/dist/tiers/index.js.map +1 -0
  321. package/dist/to/index.d.ts +5 -0
  322. package/dist/to/index.js +17 -0
  323. package/dist/to/index.js.map +1 -0
  324. package/dist/transition-guard-C7ol6oPw.d.ts +165 -0
  325. package/dist/tx/index.d.ts +23 -9
  326. package/dist/tx/index.js +13 -8
  327. package/dist/tx/index.js.map +1 -1
  328. package/dist/ui/index.d.ts +1 -0
  329. package/dist/ui/index.js +1 -0
  330. package/dist/ui/index.js.map +1 -0
  331. package/dist/ulid-DRH25k3y.d.ts +66 -0
  332. package/dist/ulid-PTAIMDG4.js +10 -0
  333. package/dist/ulid-PTAIMDG4.js.map +1 -0
  334. package/dist/util/index.d.ts +2 -0
  335. package/dist/util/index.js +7 -2
  336. package/dist/util/index.js.map +1 -1
  337. package/dist/vault-diff-B5fYNBL7.d.ts +147 -0
  338. package/dist/with/index.d.ts +38 -0
  339. package/dist/with/index.js +25 -0
  340. package/dist/with/index.js.map +1 -0
  341. package/dist/{with-materialized-view-BiasFcYx.d.ts → with-materialized-view-6p0Fk8bL.d.ts} +1 -1
  342. package/dist/{with-overlayed-view-CQViuko_.d.ts → with-overlayed-view-BJ6mXGMd.d.ts} +2 -3
  343. package/dist/with-rollup-BvQo3ROo.d.ts +47 -0
  344. package/dist/withdraw-accessible-FFS46EOD.js +22 -0
  345. package/dist/withdraw-accessible-FFS46EOD.js.map +1 -0
  346. package/dist/zod-HAJM7LMS.js +14763 -0
  347. package/dist/zod-HAJM7LMS.js.map +1 -0
  348. package/package.json +121 -201
  349. package/dist/aggregate/index.cjs.map +0 -1
  350. package/dist/aggregate/index.d.cts +0 -38
  351. package/dist/attestation/index.cjs +0 -305
  352. package/dist/attestation/index.cjs.map +0 -1
  353. package/dist/attestation/index.d.cts +0 -52
  354. package/dist/blobs/index.cjs +0 -1480
  355. package/dist/blobs/index.cjs.map +0 -1
  356. package/dist/blobs/index.d.cts +0 -46
  357. package/dist/bundle/index.cjs +0 -19104
  358. package/dist/bundle/index.cjs.map +0 -1
  359. package/dist/bundle/index.d.cts +0 -176
  360. package/dist/chunk-22DWZL57.js.map +0 -1
  361. package/dist/chunk-2GLDA55J.js.map +0 -1
  362. package/dist/chunk-2QR2PQTT.js.map +0 -1
  363. package/dist/chunk-2WUSG3IT.js.map +0 -1
  364. package/dist/chunk-3BFJOWSU.js.map +0 -1
  365. package/dist/chunk-3YPCK6JX.js.map +0 -1
  366. package/dist/chunk-53XBRIRT.js.map +0 -1
  367. package/dist/chunk-5T22KDPN.js.map +0 -1
  368. package/dist/chunk-5XHKQ56N.js +0 -340
  369. package/dist/chunk-5XHKQ56N.js.map +0 -1
  370. package/dist/chunk-6774ZOQ7.js.map +0 -1
  371. package/dist/chunk-6STK5TQP.js +0 -139
  372. package/dist/chunk-6STK5TQP.js.map +0 -1
  373. package/dist/chunk-A3JMGXPG.js.map +0 -1
  374. package/dist/chunk-B6PB7JLN.js.map +0 -1
  375. package/dist/chunk-BVRYKATC.js.map +0 -1
  376. package/dist/chunk-DE6GKS6G.js.map +0 -1
  377. package/dist/chunk-DFMLEQZB.js.map +0 -1
  378. package/dist/chunk-DJHHA6XH.js.map +0 -1
  379. package/dist/chunk-DL3HWOQ5.js.map +0 -1
  380. package/dist/chunk-DONMZAD2.js.map +0 -1
  381. package/dist/chunk-EMIGCR7X.js.map +0 -1
  382. package/dist/chunk-F3GDRNUT.js.map +0 -1
  383. package/dist/chunk-FZU343FL.js.map +0 -1
  384. package/dist/chunk-H2X3ISXG.js.map +0 -1
  385. package/dist/chunk-HNRHLRDC.js.map +0 -1
  386. package/dist/chunk-I5FOWO4J.js.map +0 -1
  387. package/dist/chunk-J66GRPNH.js.map +0 -1
  388. package/dist/chunk-JWRVQKRZ.js.map +0 -1
  389. package/dist/chunk-K3DK3NU5.js.map +0 -1
  390. package/dist/chunk-ML236QKC.js.map +0 -1
  391. package/dist/chunk-NONAAENK.js.map +0 -1
  392. package/dist/chunk-O3VZPBZG.js.map +0 -1
  393. package/dist/chunk-OIF6LZUR.js.map +0 -1
  394. package/dist/chunk-OQ6PIGHA.js +0 -19
  395. package/dist/chunk-OQ6PIGHA.js.map +0 -1
  396. package/dist/chunk-PE2FR4J3.js.map +0 -1
  397. package/dist/chunk-PP6W64Y3.js +0 -275
  398. package/dist/chunk-PP6W64Y3.js.map +0 -1
  399. package/dist/chunk-PX35GA7L.js.map +0 -1
  400. package/dist/chunk-QEILDE6R.js +0 -793
  401. package/dist/chunk-QEILDE6R.js.map +0 -1
  402. package/dist/chunk-QODLLGQ7.js.map +0 -1
  403. package/dist/chunk-RAZ4OVLL.js +0 -51
  404. package/dist/chunk-RAZ4OVLL.js.map +0 -1
  405. package/dist/chunk-SYMWGEET.js.map +0 -1
  406. package/dist/chunk-T7JEBOGN.js.map +0 -1
  407. package/dist/chunk-TFBP23BX.js.map +0 -1
  408. package/dist/chunk-TV3YZ35S.js +0 -90
  409. package/dist/chunk-TV3YZ35S.js.map +0 -1
  410. package/dist/chunk-U26HQ6KJ.js.map +0 -1
  411. package/dist/chunk-UF3BUNQZ.js +0 -1
  412. package/dist/chunk-UMLVJTYV.js +0 -20
  413. package/dist/chunk-UMLVJTYV.js.map +0 -1
  414. package/dist/chunk-VTKGMEPP.js.map +0 -1
  415. package/dist/chunk-W6EQLGMB.js +0 -100
  416. package/dist/chunk-W6EQLGMB.js.map +0 -1
  417. package/dist/chunk-WIRRPTFH.js +0 -17
  418. package/dist/chunk-WIRRPTFH.js.map +0 -1
  419. package/dist/chunk-WPLVTJ5D.js.map +0 -1
  420. package/dist/chunk-XJFLDA7A.js.map +0 -1
  421. package/dist/chunk-Z6FNBOTC.js.map +0 -1
  422. package/dist/chunk-ZYWZWG6G.js.map +0 -1
  423. package/dist/consent/index.cjs +0 -204
  424. package/dist/consent/index.cjs.map +0 -1
  425. package/dist/consent/index.d.cts +0 -25
  426. package/dist/crdt/index.cjs +0 -152
  427. package/dist/crdt/index.cjs.map +0 -1
  428. package/dist/crdt/index.d.cts +0 -30
  429. package/dist/crypto-HTZ4FJOP.js +0 -44
  430. package/dist/delegation-RI54P6I5.js +0 -17
  431. package/dist/derivations/index.cjs +0 -351
  432. package/dist/derivations/index.cjs.map +0 -1
  433. package/dist/derivations/index.d.cts +0 -72
  434. package/dist/dev-unlock-M4VAWNq_.d.cts +0 -263
  435. package/dist/executor-5PNY7LGW.js +0 -8
  436. package/dist/executor-B4QIYGZX.js +0 -8
  437. package/dist/executor-BWXXDQ7K.js +0 -11
  438. package/dist/fanout-sidecar-OKPMMPLG.js.map +0 -1
  439. package/dist/guards/index.cjs +0 -322
  440. package/dist/guards/index.cjs.map +0 -1
  441. package/dist/guards/index.d.cts +0 -31
  442. package/dist/hash-C1GtiOhR.d.ts +0 -63
  443. package/dist/history/index.cjs +0 -1222
  444. package/dist/history/index.cjs.map +0 -1
  445. package/dist/history/index.d.cts +0 -63
  446. package/dist/i18n/index.cjs +0 -1100
  447. package/dist/i18n/index.cjs.map +0 -1
  448. package/dist/i18n/index.d.cts +0 -39
  449. package/dist/index-4fBVt8j9.d.cts +0 -2387
  450. package/dist/index-D8I_pyJD.d.ts +0 -2387
  451. package/dist/index.cjs +0 -24334
  452. package/dist/index.cjs.map +0 -1
  453. package/dist/index.d.cts +0 -776
  454. package/dist/indexing/index.cjs +0 -742
  455. package/dist/indexing/index.cjs.map +0 -1
  456. package/dist/indexing/index.d.cts +0 -36
  457. package/dist/issue-VGDPP4B5.js +0 -12
  458. package/dist/lazy-builder-7tIpFyWN.d.ts +0 -304
  459. package/dist/lazy-builder-wY4pMCEe.d.cts +0 -304
  460. package/dist/materialized-views/index.cjs +0 -854
  461. package/dist/materialized-views/index.cjs.map +0 -1
  462. package/dist/materialized-views/index.d.cts +0 -186
  463. package/dist/mime-magic-CBBSOkjm.d.cts +0 -50
  464. package/dist/mime-magic-CBBSOkjm.d.ts +0 -50
  465. package/dist/noydb-LZBH3XDK.js +0 -34
  466. package/dist/overlay-views/index.cjs +0 -359
  467. package/dist/overlay-views/index.cjs.map +0 -1
  468. package/dist/overlay-views/index.d.cts +0 -82
  469. package/dist/periods/index.cjs +0 -1041
  470. package/dist/periods/index.cjs.map +0 -1
  471. package/dist/periods/index.d.cts +0 -22
  472. package/dist/predicate-BSAGEyu5.d.cts +0 -209
  473. package/dist/predicate-BSAGEyu5.d.ts +0 -209
  474. package/dist/query/index.cjs +0 -2375
  475. package/dist/query/index.cjs.map +0 -1
  476. package/dist/query/index.d.cts +0 -3
  477. package/dist/read-only-facade-ITU6L7BL.js +0 -7
  478. package/dist/registry-3QP3YKQS.js +0 -8
  479. package/dist/registry-DKEXOJVO.js +0 -7
  480. package/dist/registry-OJIOSBV6.js +0 -10
  481. package/dist/registry-USRVT6YF.js +0 -8
  482. package/dist/revoke-JCC7N56X.js +0 -17
  483. package/dist/session/index.cjs +0 -495
  484. package/dist/session/index.cjs.map +0 -1
  485. package/dist/session/index.d.cts +0 -46
  486. package/dist/shadow/index.cjs +0 -133
  487. package/dist/shadow/index.cjs.map +0 -1
  488. package/dist/shadow/index.d.cts +0 -17
  489. package/dist/snapshots/index.cjs +0 -903
  490. package/dist/snapshots/index.cjs.map +0 -1
  491. package/dist/snapshots/index.d.cts +0 -21
  492. package/dist/store/index.cjs +0 -1083
  493. package/dist/store/index.cjs.map +0 -1
  494. package/dist/store/index.d.cts +0 -492
  495. package/dist/store/index.d.ts +0 -492
  496. package/dist/store/index.js +0 -37
  497. package/dist/strategy-BSxFXGzb.d.cts +0 -110
  498. package/dist/strategy-BSxFXGzb.d.ts +0 -110
  499. package/dist/strategy-DSTrsZ8t.d.cts +0 -601
  500. package/dist/strategy-DSTrsZ8t.d.ts +0 -601
  501. package/dist/sync/index.cjs +0 -1062
  502. package/dist/sync/index.cjs.map +0 -1
  503. package/dist/sync/index.d.cts +0 -43
  504. package/dist/team/index.cjs +0 -2798
  505. package/dist/team/index.cjs.map +0 -1
  506. package/dist/team/index.d.cts +0 -118
  507. package/dist/tx/index.cjs +0 -544
  508. package/dist/tx/index.cjs.map +0 -1
  509. package/dist/tx/index.d.cts +0 -21
  510. package/dist/types-DjunxzJa.d.cts +0 -12776
  511. package/dist/ulid-COREQ2RQ.js +0 -9
  512. package/dist/ulid-DPeuPgi3.d.cts +0 -603
  513. package/dist/util/index.cjs +0 -230
  514. package/dist/util/index.cjs.map +0 -1
  515. package/dist/util/index.d.cts +0 -77
  516. package/dist/with-derivation-Df0kMlED.d.cts +0 -13
  517. package/dist/with-derivation-DfOpKjFw.d.ts +0 -13
  518. package/dist/with-guard-0KksDtSR.d.ts +0 -18
  519. package/dist/with-guard-C6W5RVrH.d.cts +0 -18
  520. package/dist/with-materialized-view-BmDKyHrm.d.cts +0 -27
  521. package/dist/with-overlayed-view-CA66vhHz.d.cts +0 -13
  522. /package/dist/{store → adapter}/index.js.map +0 -0
  523. /package/dist/{chunk-UF3BUNQZ.js.map → api-RW3KP7WU.js.map} +0 -0
  524. /package/dist/{crypto-HTZ4FJOP.js.map → as/index.js.map} +0 -0
  525. /package/dist/{delegation-RI54P6I5.js.map → at/index.js.map} +0 -0
  526. /package/dist/{executor-5PNY7LGW.js.map → by/index.js.map} +0 -0
  527. /package/dist/{executor-B4QIYGZX.js.map → cargo/index.js.map} +0 -0
  528. /package/dist/{executor-BWXXDQ7K.js.map → chunk-BGIZAFY7.js.map} +0 -0
  529. /package/dist/{issue-VGDPP4B5.js.map → chunk-CHFZDSE4.js.map} +0 -0
  530. /package/dist/{ledger-TMRZYNVJ.js.map → chunk-GHVIKOHT.js.map} +0 -0
  531. /package/dist/{noydb-LZBH3XDK.js.map → chunk-K2WCO3NX.js.map} +0 -0
  532. /package/dist/{public-envelope-BW6OXORV.js.map → chunk-PZ5AY32C.js.map} +0 -0
  533. /package/dist/{read-only-facade-ITU6L7BL.js.map → collection-facade-GQAOGJP2.js.map} +0 -0
  534. /package/dist/{registry-3QP3YKQS.js.map → delegation-UL5HKLER.js.map} +0 -0
  535. /package/dist/{registry-DKEXOJVO.js.map → describe/index.js.map} +0 -0
  536. /package/dist/{registry-OJIOSBV6.js.map → enclave-UL5LW66V.js.map} +0 -0
  537. /package/dist/{registry-USRVT6YF.js.map → executor-2FWQRLMG.js.map} +0 -0
  538. /package/dist/{revoke-JCC7N56X.js.map → executor-QZ7BXICW.js.map} +0 -0
  539. /package/dist/{signer-72QAUSVW.js.map → executor-Z5ZLJVTV.js.map} +0 -0
  540. /package/dist/{stale-6ZDBTQT7.js.map → export-accessible-KRV5W4GH.js.map} +0 -0
  541. /package/dist/{ulid-COREQ2RQ.js.map → extract-partition-GLKBOXFQ.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/sanitize-filename.ts"],"sourcesContent":["/**\n * Target-profile aware filename sanitizer.\n *\n * Pure string in / string out. No filesystem access, no I/O. Use this\n * at the boundary where a user-supplied filename meets a storage\n * destination — local FS, ZIP archive, S3 key, URL path, SMB share —\n * to defuse the canonical 14-class footgun before it reaches that\n * destination.\n *\n * ## Threat model\n *\n * 1. Path injection — `..`, NUL bytes, `\\` on POSIX, absolute paths.\n * 2. Windows reserved names — `CON`, `PRN`, `AUX`, `NUL`,\n * `COM1-9`, `LPT1-9`, with or without an extension.\n * 3. Windows reserved chars — `< > : \" / \\ | ? *` plus ASCII 0-31.\n * 4. Trailing `.` and ` ` on Windows / SMB.\n * 5. Unicode normalization drift — same display, different bytes →\n * \"two files with the same name\" sync ghosts.\n * 6. Bidi override spoofing — U+202E reversing `harmless.exe.txt`\n * into `harmless.txt.exe`.\n * 7. URL `+` ambiguity in S3 presigned URLs.\n * 8. ZIP general-purpose-flag bit 11 (UTF-8 filename) optional in\n * pre-2006 readers.\n * 9-14. Length caps, leading/trailing whitespace + controls,\n * `.DS_Store`-style hidden noise, etc.\n *\n * ## Always-on transforms (every profile)\n *\n * - NFC normalize (`String.prototype.normalize('NFC')`).\n * - Reject NUL — hard fail, not strip. Silent strip enables a\n * classic truncation bypass (`safe.txt\\0.exe` → `safe.txt`).\n * - Strip bidi overrides (`U+202A..U+202E`, `U+2066..U+2069`).\n * - Trim leading/trailing whitespace and ASCII control chars.\n *\n * ## Non-goals (i18n boundary policy, )\n *\n * - No transliteration.\n * - No locale-aware slugging.\n * - No script-specific segmentation.\n *\n * @module\n */\n\nimport { FilenameSanitizationError } from '../errors.js'\n\n/**\n * One of seven storage destinations the sanitizer knows how to defang\n * for. Pick the most restrictive that covers your write site:\n * `'macos-smb'` is the safe default for \"I don't know where these\n * files end up but they're going to a real filesystem somewhere.\"\n */\nexport type FilenameProfile =\n | 'posix'\n | 'windows'\n | 'macos-smb'\n | 'zip'\n | 'url-path'\n | 's3-key'\n | 'opaque'\n\nexport interface SanitizeFilenameOptions {\n /** Target-destination profile. */\n readonly profile: FilenameProfile\n /**\n * Override the per-profile length cap. Useful when leaving headroom\n * for a collision suffix — e.g. `maxBytes: 240` on a `posix` write\n * site that wants 15 bytes of slack for `-1`, `-2`, …\n */\n readonly maxBytes?: number\n /**\n * Required when `profile === 'opaque'`. The opaque profile replaces\n * the entire input with `${opaqueId}.${ext}` (extension preserved\n * from the input when present).\n */\n readonly opaqueId?: string\n}\n\nconst REPLACEMENT = '_'\n\n// Bidi overrides: U+202A LRE, U+202B RLE, U+202C PDF, U+202D LRO,\n// U+202E RLO, U+2066 LRI, U+2067 RLI, U+2068 FSI, U+2069 PDI.\nconst BIDI_OVERRIDES = /[‪-‮⁦-⁩]/g\n\n// Reserved by Windows / NTFS / FAT / SMB.\nconst WINDOWS_RESERVED_CHARS = /[<>:\"/\\\\|?*]/g\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n 'CON', 'PRN', 'AUX', 'NUL',\n 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',\n])\n\n// macOS legacy hidden-noise files. Match the full name.\nconst MAC_HIDDEN_NOISE = /^(?:\\.DS_Store|\\.localized|\\.fseventsd|\\._.+)$/i\n\n// RFC 3986 unreserved set.\nconst URL_UNRESERVED = /[A-Za-z0-9\\-._~]/\n\nconst utf8 = new TextEncoder()\n\nfunction isControlCode(cp: number): boolean {\n return (cp >= 0 && cp <= 0x1f) || cp === 0x7f\n}\n\nfunction stripControlChars(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i++) {\n out += isControlCode(s.charCodeAt(i)) ? REPLACEMENT : s[i]\n }\n return out\n}\n\nfunction trimWhitespaceAndControls(s: string): string {\n let start = 0\n let end = s.length\n while (start < end) {\n const ch = s[start]!\n if (!isControlCode(s.charCodeAt(start)) && ch.trim() !== '') break\n start++\n }\n while (end > start) {\n const ch = s[end - 1]!\n if (!isControlCode(s.charCodeAt(end - 1)) && ch.trim() !== '') break\n end--\n }\n return s.slice(start, end)\n}\n\n/**\n * Sanitize a filename for a target-destination profile. Pure: same\n * input + options always returns the same output, no I/O.\n *\n * Returns the sanitized name. Throws {@link FilenameSanitizationError}\n * when the input cannot be made safe at all (NUL byte, empty after\n * normalization, missing `opaqueId` for the opaque profile,\n * `..` segment that would fall out of any reasonable target).\n */\nexport function sanitizeFilename(name: string, opts: SanitizeFilenameOptions): string {\n if (typeof name !== 'string') {\n throw new FilenameSanitizationError('input must be a string')\n }\n if (name.includes('\\0')) {\n throw new FilenameSanitizationError('NUL byte in filename')\n }\n\n let s = name.normalize('NFC').replace(BIDI_OVERRIDES, '')\n\n if (opts.profile === 'opaque') {\n return applyOpaque(s, opts)\n }\n\n s = trimWhitespaceAndControls(s)\n\n switch (opts.profile) {\n case 'posix': return cap(applyPosix(s), opts.maxBytes ?? 255, 'utf8')\n case 'windows': return cap(applyWindows(s), opts.maxBytes ?? 255, 'utf16')\n case 'macos-smb': return cap(applyMacosSmb(s), opts.maxBytes ?? 240, 'utf8')\n case 'zip': return cap(applyZip(s), opts.maxBytes ?? 255, 'utf8')\n case 'url-path': return cap(applyUrlPath(s), opts.maxBytes ?? 1024, 'bytes-pre-encode')\n case 's3-key': return cap(applyS3Key(s), opts.maxBytes ?? 1024, 'utf8')\n }\n}\n\n// ─── Profile implementations ────────────────────────────────────────────\n\nfunction applyPosix(s: string): string {\n // POSIX is permissive; only `/` and NUL are off-limits.\n const cleaned = s.replace(/\\//g, REPLACEMENT)\n return rejectDotSegments(cleaned)\n}\n\nfunction applyWindows(s: string): string {\n let cleaned = s.replace(WINDOWS_RESERVED_CHARS, REPLACEMENT)\n cleaned = stripControlChars(cleaned)\n // Trailing space/dot are stripped by Win32 path resolution.\n cleaned = cleaned.replace(/[. ]+$/g, '')\n cleaned = rejectDotSegments(cleaned)\n return avoidWindowsReservedName(cleaned)\n}\n\nfunction applyMacosSmb(s: string): string {\n let cleaned = applyWindows(s)\n if (MAC_HIDDEN_NOISE.test(cleaned)) {\n cleaned = REPLACEMENT + cleaned\n }\n return cleaned\n}\n\nfunction applyZip(s: string): string {\n let cleaned = s.replace(/^\\/+/, '')\n cleaned = rejectDotSegments(cleaned)\n return stripControlChars(cleaned)\n}\n\nfunction applyUrlPath(s: string): string {\n // RFC 3986 percent-encoding for path segment. Keep `unreserved`,\n // encode everything else. `+` is encoded as `%2B` because S3 and\n // legacy servers treat raw `+` as space ambiguously.\n let out = ''\n for (const ch of s) {\n if (URL_UNRESERVED.test(ch)) { out += ch; continue }\n const bytes = utf8.encode(ch)\n for (const b of bytes) {\n out += '%' + b.toString(16).toUpperCase().padStart(2, '0')\n }\n }\n return out\n}\n\nfunction applyS3Key(s: string): string {\n // Strip leading slashes BEFORE percent-encoding — once `/` is\n // encoded to `%2F` the leading-slash regex no longer matches.\n return applyUrlPath(s.replace(/^\\/+/, ''))\n}\n\nfunction applyOpaque(s: string, opts: SanitizeFilenameOptions): string {\n if (!opts.opaqueId) {\n throw new FilenameSanitizationError('opaque profile requires opaqueId')\n }\n // Preserve a \"safe-looking\" extension only — alphanumeric, ≤16 bytes.\n const dot = s.lastIndexOf('.')\n if (dot > 0 && dot < s.length - 1) {\n const ext = s.slice(dot + 1)\n if (/^[A-Za-z0-9]{1,16}$/.test(ext)) {\n return `${opts.opaqueId}.${ext.toLowerCase()}`\n }\n }\n return opts.opaqueId\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\nfunction rejectDotSegments(s: string): string {\n if (s === '.' || s === '..' || s.split(/[/\\\\]/).some((seg) => seg === '..')) {\n throw new FilenameSanitizationError('path traversal segment in filename')\n }\n if (s.length === 0) {\n throw new FilenameSanitizationError('empty filename after sanitization')\n }\n return s\n}\n\nfunction avoidWindowsReservedName(s: string): string {\n const dot = s.indexOf('.')\n const base = dot === -1 ? s : s.slice(0, dot)\n if (WINDOWS_RESERVED_NAMES.has(base.toUpperCase())) {\n return REPLACEMENT + s\n }\n return s\n}\n\ntype LengthUnit = 'utf8' | 'utf16' | 'bytes-pre-encode'\n\nfunction cap(s: string, max: number, unit: LengthUnit): string {\n if (max <= 0) {\n throw new FilenameSanitizationError('maxBytes must be positive')\n }\n if (unit === 'utf16') {\n if (s.length <= max) return s\n return s.slice(0, max)\n }\n if (unit === 'bytes-pre-encode') {\n if (utf8.encode(s).byteLength <= max) return s\n return truncateToByteCap(s, max)\n }\n if (utf8.encode(s).byteLength <= max) return s\n return truncateToByteCap(s, max)\n}\n\nfunction truncateToByteCap(s: string, max: number): string {\n // Walk by code points so we never split a multi-byte sequence in\n // the middle. Whole-grapheme handling (ZWJ-joined emoji) is a\n // documented non-goal; we only protect against UTF-8 boundary\n // splits here.\n let out = ''\n let used = 0\n for (const cp of s) {\n const n = utf8.encode(cp).byteLength\n if (used + n > max) break\n out += cp\n used += n\n }\n if (out.length === 0) {\n throw new FilenameSanitizationError('maxBytes too small for a single code point')\n }\n return out\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/kernel/util/sanitize-filename.ts"],"sourcesContent":["/**\n * Target-profile aware filename sanitizer.\n *\n * Pure string in / string out. No filesystem access, no I/O. Use this\n * at the boundary where a user-supplied filename meets a storage\n * destination — local FS, ZIP archive, S3 key, URL path, SMB share —\n * to defuse the canonical 14-class footgun before it reaches that\n * destination.\n *\n * ## Threat model\n *\n * 1. Path injection — `..`, NUL bytes, `\\` on POSIX, absolute paths.\n * 2. Windows reserved names — `CON`, `PRN`, `AUX`, `NUL`,\n * `COM1-9`, `LPT1-9`, with or without an extension.\n * 3. Windows reserved chars — `< > : \" / \\ | ? *` plus ASCII 0-31.\n * 4. Trailing `.` and ` ` on Windows / SMB.\n * 5. Unicode normalization drift — same display, different bytes →\n * \"two files with the same name\" sync ghosts.\n * 6. Bidi override spoofing — U+202E reversing `harmless.exe.txt`\n * into `harmless.txt.exe`.\n * 7. URL `+` ambiguity in S3 presigned URLs.\n * 8. ZIP general-purpose-flag bit 11 (UTF-8 filename) optional in\n * pre-2006 readers.\n * 9-14. Length caps, leading/trailing whitespace + controls,\n * `.DS_Store`-style hidden noise, etc.\n *\n * ## Always-on transforms (every profile)\n *\n * - NFC normalize (`String.prototype.normalize('NFC')`).\n * - Reject NUL — hard fail, not strip. Silent strip enables a\n * classic truncation bypass (`safe.txt\\0.exe` → `safe.txt`).\n * - Strip bidi overrides (`U+202A..U+202E`, `U+2066..U+2069`).\n * - Trim leading/trailing whitespace and ASCII control chars.\n *\n * ## Non-goals (i18n boundary policy, )\n *\n * - No transliteration.\n * - No locale-aware slugging.\n * - No script-specific segmentation.\n *\n * @module\n */\n\nimport { FilenameSanitizationError } from '../errors.js'\n\n/**\n * One of seven storage destinations the sanitizer knows how to defang\n * for. Pick the most restrictive that covers your write site:\n * `'macos-smb'` is the safe default for \"I don't know where these\n * files end up but they're going to a real filesystem somewhere.\"\n */\nexport type FilenameProfile =\n | 'posix'\n | 'windows'\n | 'macos-smb'\n | 'zip'\n | 'url-path'\n | 's3-key'\n | 'opaque'\n\nexport interface SanitizeFilenameOptions {\n /** Target-destination profile. */\n readonly profile: FilenameProfile\n /**\n * Override the per-profile length cap. Useful when leaving headroom\n * for a collision suffix — e.g. `maxBytes: 240` on a `posix` write\n * site that wants 15 bytes of slack for `-1`, `-2`, …\n */\n readonly maxBytes?: number\n /**\n * Required when `profile === 'opaque'`. The opaque profile replaces\n * the entire input with `${opaqueId}.${ext}` (extension preserved\n * from the input when present).\n */\n readonly opaqueId?: string\n}\n\nconst REPLACEMENT = '_'\n\n// Bidi overrides: U+202A LRE, U+202B RLE, U+202C PDF, U+202D LRO,\n// U+202E RLO, U+2066 LRI, U+2067 RLI, U+2068 FSI, U+2069 PDI.\nconst BIDI_OVERRIDES = /[‪-‮⁦-⁩]/g\n\n// Reserved by Windows / NTFS / FAT / SMB.\nconst WINDOWS_RESERVED_CHARS = /[<>:\"/\\\\|?*]/g\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n 'CON', 'PRN', 'AUX', 'NUL',\n 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',\n])\n\n// macOS legacy hidden-noise files. Match the full name.\nconst MAC_HIDDEN_NOISE = /^(?:\\.DS_Store|\\.localized|\\.fseventsd|\\._.+)$/i\n\n// RFC 3986 unreserved set.\nconst URL_UNRESERVED = /[A-Za-z0-9\\-._~]/\n\nconst utf8 = new TextEncoder()\n\nfunction isControlCode(cp: number): boolean {\n return (cp >= 0 && cp <= 0x1f) || cp === 0x7f\n}\n\nfunction stripControlChars(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i++) {\n out += isControlCode(s.charCodeAt(i)) ? REPLACEMENT : s[i]\n }\n return out\n}\n\nfunction trimWhitespaceAndControls(s: string): string {\n let start = 0\n let end = s.length\n while (start < end) {\n const ch = s[start]!\n if (!isControlCode(s.charCodeAt(start)) && ch.trim() !== '') break\n start++\n }\n while (end > start) {\n const ch = s[end - 1]!\n if (!isControlCode(s.charCodeAt(end - 1)) && ch.trim() !== '') break\n end--\n }\n return s.slice(start, end)\n}\n\n/**\n * Sanitize a filename for a target-destination profile. Pure: same\n * input + options always returns the same output, no I/O.\n *\n * Returns the sanitized name. Throws {@link FilenameSanitizationError}\n * when the input cannot be made safe at all (NUL byte, empty after\n * normalization, missing `opaqueId` for the opaque profile,\n * `..` segment that would fall out of any reasonable target).\n */\nexport function sanitizeFilename(name: string, opts: SanitizeFilenameOptions): string {\n if (typeof name !== 'string') {\n throw new FilenameSanitizationError('input must be a string')\n }\n if (name.includes('\\0')) {\n throw new FilenameSanitizationError('NUL byte in filename')\n }\n\n let s = name.normalize('NFC').replace(BIDI_OVERRIDES, '')\n\n if (opts.profile === 'opaque') {\n return applyOpaque(s, opts)\n }\n\n s = trimWhitespaceAndControls(s)\n\n switch (opts.profile) {\n case 'posix': return cap(applyPosix(s), opts.maxBytes ?? 255, 'utf8')\n case 'windows': return cap(applyWindows(s), opts.maxBytes ?? 255, 'utf16')\n case 'macos-smb': return cap(applyMacosSmb(s), opts.maxBytes ?? 240, 'utf8')\n case 'zip': return cap(applyZip(s), opts.maxBytes ?? 255, 'utf8')\n case 'url-path': return cap(applyUrlPath(s), opts.maxBytes ?? 1024, 'bytes-pre-encode')\n case 's3-key': return cap(applyS3Key(s), opts.maxBytes ?? 1024, 'utf8')\n }\n}\n\n// ─── Profile implementations ────────────────────────────────────────────\n\nfunction applyPosix(s: string): string {\n // POSIX is permissive; only `/` and NUL are off-limits.\n const cleaned = s.replace(/\\//g, REPLACEMENT)\n return rejectDotSegments(cleaned)\n}\n\nfunction applyWindows(s: string): string {\n let cleaned = s.replace(WINDOWS_RESERVED_CHARS, REPLACEMENT)\n cleaned = stripControlChars(cleaned)\n // Trailing space/dot are stripped by Win32 path resolution.\n cleaned = cleaned.replace(/[. ]+$/g, '')\n cleaned = rejectDotSegments(cleaned)\n return avoidWindowsReservedName(cleaned)\n}\n\nfunction applyMacosSmb(s: string): string {\n let cleaned = applyWindows(s)\n if (MAC_HIDDEN_NOISE.test(cleaned)) {\n cleaned = REPLACEMENT + cleaned\n }\n return cleaned\n}\n\nfunction applyZip(s: string): string {\n let cleaned = s.replace(/^\\/+/, '')\n cleaned = rejectDotSegments(cleaned)\n return stripControlChars(cleaned)\n}\n\nfunction applyUrlPath(s: string): string {\n // RFC 3986 percent-encoding for path segment. Keep `unreserved`,\n // encode everything else. `+` is encoded as `%2B` because S3 and\n // legacy servers treat raw `+` as space ambiguously.\n let out = ''\n for (const ch of s) {\n if (URL_UNRESERVED.test(ch)) { out += ch; continue }\n const bytes = utf8.encode(ch)\n for (const b of bytes) {\n out += '%' + b.toString(16).toUpperCase().padStart(2, '0')\n }\n }\n return out\n}\n\nfunction applyS3Key(s: string): string {\n // Strip leading slashes BEFORE percent-encoding — once `/` is\n // encoded to `%2F` the leading-slash regex no longer matches.\n return applyUrlPath(s.replace(/^\\/+/, ''))\n}\n\nfunction applyOpaque(s: string, opts: SanitizeFilenameOptions): string {\n if (!opts.opaqueId) {\n throw new FilenameSanitizationError('opaque profile requires opaqueId')\n }\n // Preserve a \"safe-looking\" extension only — alphanumeric, ≤16 bytes.\n const dot = s.lastIndexOf('.')\n if (dot > 0 && dot < s.length - 1) {\n const ext = s.slice(dot + 1)\n if (/^[A-Za-z0-9]{1,16}$/.test(ext)) {\n return `${opts.opaqueId}.${ext.toLowerCase()}`\n }\n }\n return opts.opaqueId\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\nfunction rejectDotSegments(s: string): string {\n if (s === '.' || s === '..' || s.split(/[/\\\\]/).some((seg) => seg === '..')) {\n throw new FilenameSanitizationError('path traversal segment in filename')\n }\n if (s.length === 0) {\n throw new FilenameSanitizationError('empty filename after sanitization')\n }\n return s\n}\n\nfunction avoidWindowsReservedName(s: string): string {\n const dot = s.indexOf('.')\n const base = dot === -1 ? s : s.slice(0, dot)\n if (WINDOWS_RESERVED_NAMES.has(base.toUpperCase())) {\n return REPLACEMENT + s\n }\n return s\n}\n\ntype LengthUnit = 'utf8' | 'utf16' | 'bytes-pre-encode'\n\nfunction cap(s: string, max: number, unit: LengthUnit): string {\n if (max <= 0) {\n throw new FilenameSanitizationError('maxBytes must be positive')\n }\n if (unit === 'utf16') {\n if (s.length <= max) return s\n return s.slice(0, max)\n }\n if (unit === 'bytes-pre-encode') {\n if (utf8.encode(s).byteLength <= max) return s\n return truncateToByteCap(s, max)\n }\n if (utf8.encode(s).byteLength <= max) return s\n return truncateToByteCap(s, max)\n}\n\nfunction truncateToByteCap(s: string, max: number): string {\n // Walk by code points so we never split a multi-byte sequence in\n // the middle. Whole-grapheme handling (ZWJ-joined emoji) is a\n // documented non-goal; we only protect against UTF-8 boundary\n // splits here.\n let out = ''\n let used = 0\n for (const cp of s) {\n const n = utf8.encode(cp).byteLength\n if (used + n > max) break\n out += cp\n used += n\n }\n if (out.length === 0) {\n throw new FilenameSanitizationError('maxBytes too small for a single code point')\n }\n return out\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,147 @@
1
+ import { V as Vault, cE as DiffEntry } from './index-BzUo1B6n.js';
2
+
3
+ /**
4
+ * Vault-level diff orchestrator.
5
+ *
6
+ * Compares a live `Vault`'s plaintext state against a candidate state
7
+ * (another vault, a plain `{ collection: records[] }` map, or a vault
8
+ * dump JSON) and returns a structured `VaultDiff` plan listing the
9
+ * records that would be added, modified, or deleted to bring the live
10
+ * vault into the candidate's shape.
11
+ *
12
+ * Builds on two existing record-level helpers:
13
+ *
14
+ * 1. `diff(a, b)` from `./history/diff.ts` — emits dot-pathed
15
+ * `DiffEntry[]` with `type: 'added' | 'removed' | 'changed'` for
16
+ * each changed field of two records. Used here for the
17
+ * `fieldDiffs` of every `modified` entry, and (with empty result)
18
+ * as the default deep-equal check.
19
+ *
20
+ * 2. `Vault.exportStream()` from `./vault.ts` — the canonical
21
+ * decrypt-and-stream-records iterator. Used to walk both sides
22
+ * when the candidate is itself a `Vault`. ACL-scoped: collections
23
+ * the caller can't read silently drop out, the same way every
24
+ * other plaintext-emitting export pipeline filters them.
25
+ *
26
+ * The new orchestration is the **vault-level** enumeration: bucket
27
+ * each record id into added (only in candidate), deleted (only in
28
+ * vault), or modified (in both with field changes); leave the
29
+ * field-level granularity to the existing `diff()`.
30
+ *
31
+ * Use cases:
32
+ *
33
+ * - Import preview (`@noy-db/as-*` `fromString` returns a plan
34
+ * whose body is a `VaultDiff`).
35
+ * - Backup verification ("does this `.noydb` bundle from yesterday
36
+ * match the current vault?").
37
+ * - Two-vault reconciliation ("what's different between Office A
38
+ * and Office B before we sync?").
39
+ * - Test assertions (golden-file testing with one-liner
40
+ * `expect(plan.summary).toEqual(...)`).
41
+ *
42
+ * @module
43
+ */
44
+
45
+ /** Per-record entry shape — added and deleted records carry only the record value. */
46
+ interface VaultDiffEntry<T = unknown> {
47
+ readonly collection: string;
48
+ readonly id: string;
49
+ readonly record: T;
50
+ /**
51
+ * Unencrypted envelope metadata for the RECEIVER-side record.
52
+ * Populated only when `diffVault` is called with `{includeMetadata: true}`.
53
+ * Default: `undefined` (zero extra reads, no behavior change).
54
+ *
55
+ * Populated for `modified` (the CURRENT receiver state, before the candidate
56
+ * is applied) and `deleted` (the receiver envelope of the record being
57
+ * removed). `added` entries have no receiver envelope at diff time, so their
58
+ * `metadata` is always absent.
59
+ */
60
+ readonly metadata?: {
61
+ readonly version: number;
62
+ readonly timestamp: string;
63
+ readonly by?: string;
64
+ readonly source?: string;
65
+ readonly sourceTs?: string;
66
+ };
67
+ }
68
+ /** Modified records carry both halves of the diff plus the field-level breakdown. */
69
+ interface VaultDiffModifiedEntry<T = unknown> extends VaultDiffEntry<T> {
70
+ /** The record as it stands in the live vault. */
71
+ readonly before: T;
72
+ /** Top-level keys whose values differ between `before` and `record`. */
73
+ readonly fieldsChanged: readonly string[];
74
+ /**
75
+ * Field-level diff entries from `diff(before, record)`. Reuses the
76
+ * existing per-record diff helper so consumers can render git-style
77
+ * `path: from → to` rows without re-walking the records.
78
+ */
79
+ readonly fieldDiffs: readonly DiffEntry[];
80
+ }
81
+ interface VaultDiff<T = unknown> {
82
+ readonly added: readonly VaultDiffEntry<T>[];
83
+ readonly modified: readonly VaultDiffModifiedEntry<T>[];
84
+ readonly deleted: readonly VaultDiffEntry<T>[];
85
+ /** Only populated when `options.includeUnchanged: true`. */
86
+ readonly unchanged: readonly VaultDiffEntry<T>[] | undefined;
87
+ readonly summary: {
88
+ readonly add: number;
89
+ readonly modify: number;
90
+ readonly delete: number;
91
+ readonly total: number;
92
+ };
93
+ /**
94
+ * Format the diff as a human-readable string.
95
+ *
96
+ * - `'count'` — one line, just the numbers (`12 added · 3 modified · 0 deleted`)
97
+ * - `'one-line'` — count plus a single overview line
98
+ * - `'full'` — count + one row per added/modified/deleted record (default)
99
+ */
100
+ format(opts?: {
101
+ detail?: 'count' | 'one-line' | 'full';
102
+ }): string;
103
+ }
104
+ interface DiffOptions {
105
+ /** Restrict the diff to a subset of collections. */
106
+ readonly collections?: readonly string[];
107
+ /** Field on each record that carries its id. Defaults to `'id'`. */
108
+ readonly idKey?: string;
109
+ /** Override the default deep-equal check for "modified vs unchanged". */
110
+ readonly compareFn?: (a: unknown, b: unknown) => boolean;
111
+ /** If true, include unchanged records in the diff (off by default to save memory). */
112
+ readonly includeUnchanged?: boolean;
113
+ /**
114
+ * When `true`, each entry in `added`, `modified`, and `deleted` will carry a
115
+ * `metadata` field with the RECEIVER-side envelope metadata
116
+ * (`version`, `timestamp`, `by?`, `source?`, `sourceTs?`).
117
+ *
118
+ * Off by default — no extra adapter reads, no behavior change for existing callers.
119
+ */
120
+ readonly includeMetadata?: boolean;
121
+ }
122
+ /**
123
+ * Candidate state to diff the vault against:
124
+ *
125
+ * - A `Vault` instance — both sides are walked via `exportStream()`.
126
+ * - A `Record<collection, records[]>` map — same shape `as-json.toObject()`
127
+ * produces. Useful for diffing parsed file content against the live vault.
128
+ * - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the
129
+ * full vault state. Parsed and reduced to the map shape above.
130
+ */
131
+ type DiffCandidate<T = unknown> = Vault | Record<string, readonly T[]> | string;
132
+ /**
133
+ * Compute the diff between a live vault and a candidate state.
134
+ *
135
+ * Ungated shared import/merge infrastructure: the `as-*` exporters call this
136
+ * internally from their `fromString`/import merge logic, so it is always
137
+ * available (not behind `withCargo()`). Only `extractPartition` is a gated
138
+ * cargo capability.
139
+ *
140
+ * Returns a fully buffered `VaultDiff` — no streaming. Memory cost is
141
+ * O(n + m) in the row count of vault + candidate. For documented
142
+ * 1K-50K-record vaults this is fine; a streaming variant lands as a
143
+ * follow-up if a > 100K-record consumer arrives.
144
+ */
145
+ declare function diffVault<T = unknown>(vault: Vault, candidate: DiffCandidate<T>, options?: DiffOptions): Promise<VaultDiff<T>>;
146
+
147
+ export { type DiffCandidate as D, type VaultDiff as V, type DiffOptions as a, type VaultDiffEntry as b, type VaultDiffModifiedEntry as c, diffVault as d };
@@ -0,0 +1,38 @@
1
+ export { U as Unsubscribe, W as WriteEvent, a as WriteHook, b as WriteHookRegistry } from '../index-B9QdHytu.js';
2
+ import { cF as UnlockedKeyring, cG as ExportFormat } from '../index-BzUo1B6n.js';
3
+ export { cH as BusHandler, cI as GateDeleteEvent, cJ as GateEventMap, cK as GateHandler, cL as GatePoint, cM as GatePutEvent, cN as LifecycleEventMap, cO as LifecyclePoint, cP as ServiceBus, cQ as SubsystemBus } from '../index-BzUo1B6n.js';
4
+ import '../subject-index-O75wKshW.js';
5
+ import '../describe-aBkJR2sd.js';
6
+ import '@noy-db/attestation';
7
+
8
+ /**
9
+ * Authorize an `@noy-db/as-*` export against the keyring's `exportCapability`.
10
+ * Throws `ExportCapabilityError` if the keyring is not authorised.
11
+ *
12
+ * - plaintext tier requires a `format`; defaults to empty for every role.
13
+ * - bundle tier defaults to on for owner/admin, off for others.
14
+ */
15
+ declare function assertCanExport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): void;
16
+ /**
17
+ * Authorize an `@noy-db/as-*` import against the keyring's `importCapability`.
18
+ * Throws `ImportCapabilityError` if the keyring is not authorised.
19
+ *
20
+ * - plaintext tier requires a `format`; default-closed for every role.
21
+ * - bundle tier is default-closed for every role, including owner — import is
22
+ * more dangerous than export (corrupts vs leaks).
23
+ */
24
+ declare function assertCanImport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): void;
25
+ /**
26
+ * Read-only accessor for the keyring's export capability, with role-based
27
+ * defaults resolved. Useful for UI affordances (grey out the export button if
28
+ * no capability) without throwing.
29
+ */
30
+ declare function canExport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): boolean;
31
+ /**
32
+ * Read-only accessor for the keyring's import capability. UI affordance —
33
+ * returns false in every default-closed case (every role with no explicit
34
+ * `importCapability` grant).
35
+ */
36
+ declare function canImport(keyring: UnlockedKeyring, tier: 'plaintext' | 'bundle', format?: ExportFormat): boolean;
37
+
38
+ export { assertCanExport, assertCanImport, canExport, canImport };
@@ -0,0 +1,25 @@
1
+ import {
2
+ ServiceBus,
3
+ SubsystemBus,
4
+ WriteHookRegistry,
5
+ assertCanExport,
6
+ assertCanImport,
7
+ canExport,
8
+ canImport
9
+ } from "../chunk-5R3ERCDH.js";
10
+ import "../chunk-WWGT2MDV.js";
11
+ import "../chunk-ITNUCOXM.js";
12
+ import "../chunk-5O3AOPDT.js";
13
+ import "../chunk-5TDJ56JE.js";
14
+ import "../chunk-ZYUC53LT.js";
15
+ import "../chunk-PZ5AY32C.js";
16
+ export {
17
+ ServiceBus,
18
+ SubsystemBus,
19
+ WriteHookRegistry,
20
+ assertCanExport,
21
+ assertCanImport,
22
+ canExport,
23
+ canImport
24
+ };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,4 +1,4 @@
1
- import { aT as MaterializedViewStrategy, aU as MaterializedViewStrategyHandle } from './types-DGU60JDt.js';
1
+ import { cf as MaterializedViewStrategy, cg as MaterializedViewStrategyHandle } from './index-BzUo1B6n.js';
2
2
 
3
3
  /**
4
4
  * Register a materialized view: a declared query whose result is
@@ -1,10 +1,9 @@
1
- import { aV as OverlayedViewStrategy, aY as OverlayedViewStrategyHandle } from './types-DGU60JDt.js';
1
+ import { ch as OverlayedViewStrategy, cq as OverlayedViewStrategyHandle } from './index-BzUo1B6n.js';
2
2
 
3
3
  /**
4
4
  * Register a read-shadow overlay: bind an MV-owned base collection to
5
5
  * a user-writable overlay so consumers can express operator-editable
6
- * lifecycles as one declarative block (MV v2 spec § Composition
7
- * with operator-editable lifecycle).
6
+ * lifecycles as one declarative block.
8
7
  *
9
8
  * See docs/superpowers/specs/2026-05-20-dim14-mv-v2-design.md.
10
9
  */
@@ -0,0 +1,47 @@
1
+ import { c2 as DerivationStrategy, cb as DerivationStrategyHandle } from './index-BzUo1B6n.js';
2
+
3
+ /**
4
+ * Register a deterministic derivation: one source collection → one or
5
+ * more typed outputs, computed by the user's `derive` function on
6
+ * plaintext after DEK unwrap. Outputs are encrypted with the same DEK
7
+ * as the source and written via the standard `Collection.put` path.
8
+ *
9
+ * See docs/superpowers/specs/2026-05-01-dim14-derivation-v1-design.md.
10
+ */
11
+ declare function withDerivation<TSource extends Record<string, unknown>, TOutputs extends Record<string, Record<string, unknown> | ReadonlyArray<Record<string, unknown>>>>(spec: DerivationStrategy<TSource, TOutputs>): DerivationStrategyHandle;
12
+
13
+ /**
14
+ * `withRollup` — aggregate many child records onto a single field of their
15
+ * parent. The reverse of a join: instead of reading children
16
+ * on demand, the parent carries a maintained summary.
17
+ *
18
+ * ```ts
19
+ * withRollup<Sale, Buyer>({
20
+ * from: 'sales', // child collection (the trigger)
21
+ * key: 'buyerId', // FK on the child → parent id
22
+ * into: 'buyers', // parent collection
23
+ * field: 'revenueByYear', // field on the parent to maintain
24
+ * compute: (sales) => groupSumByYear(sales, 'total'),
25
+ * })
26
+ * ```
27
+ *
28
+ * On every write OR delete of a `from` record, the parent at id `child[key]`
29
+ * is recomputed: `compute(allChildren where child[key] === parentId)` is
30
+ * patched onto `parent[field]`. A parent write also recomputes its own
31
+ * aggregate (so a parent created after its children still fills in). Only the
32
+ * `field` is touched — the rest of the parent record is never clobbered — and
33
+ * a value-equality guard suppresses no-op writes. The aggregate is gap-free
34
+ * with respect to child inserts, updates, and deletes.
35
+ *
36
+ * Desugars to a `withDerivation` strategy carrying a `rollup` marker; dispatch
37
+ * handles it without invoking the executor. Eager-only in this slice.
38
+ */
39
+ declare function withRollup<TChild extends Record<string, unknown> = Record<string, unknown>, TParent extends Record<string, unknown> = Record<string, unknown>>(config: {
40
+ from: string;
41
+ key: keyof TChild & string;
42
+ into: string;
43
+ field: keyof TParent & string;
44
+ compute: (children: TChild[]) => unknown;
45
+ }): DerivationStrategyHandle;
46
+
47
+ export { withRollup as a, withDerivation as w };
@@ -0,0 +1,22 @@
1
+ import {
2
+ FROZEN_SNAPSHOTS_COLLECTION,
3
+ freezeAndDeleteClosure,
4
+ freezeSnapshotOnly,
5
+ randomId,
6
+ withdrawAccessibleData
7
+ } from "./chunk-PSMV73A5.js";
8
+ import "./chunk-HCIPRAGS.js";
9
+ import "./chunk-FISN7WE4.js";
10
+ import "./chunk-SMXWYP24.js";
11
+ import "./chunk-5O3AOPDT.js";
12
+ import "./chunk-5TDJ56JE.js";
13
+ import "./chunk-ZYUC53LT.js";
14
+ import "./chunk-PZ5AY32C.js";
15
+ export {
16
+ FROZEN_SNAPSHOTS_COLLECTION,
17
+ freezeAndDeleteClosure,
18
+ freezeSnapshotOnly,
19
+ randomId,
20
+ withdrawAccessibleData
21
+ };
22
+ //# sourceMappingURL=withdraw-accessible-FFS46EOD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}