@noy-db/hub 0.4.0-pre.6 → 0.4.0-pre.7

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 (454) hide show
  1. package/dist/api-3NKVNZPM.js +20 -0
  2. package/dist/attestation/index.js +18 -18
  3. package/dist/{backup-USYSNCYM.js → backup-PTSVXDDW.js} +13 -13
  4. package/dist/blobs/index.js +13 -13
  5. package/dist/blobs/index.js.map +1 -1
  6. package/dist/broker/index.js +12 -12
  7. package/dist/cargo/index.js +31 -29
  8. package/dist/{chunk-5WLDZZ6S.js → chunk-35NMVJ7I.js} +3 -3
  9. package/dist/{chunk-ZGEFBDPR.js → chunk-3HUYRN24.js} +3 -3
  10. package/dist/chunk-3HUYRN24.js.map +1 -0
  11. package/dist/{chunk-NA374QG7.js → chunk-3XKESW5E.js} +3 -3
  12. package/dist/{chunk-MUPZ6IZX.js → chunk-4JQK3L4V.js} +2 -2
  13. package/dist/{chunk-Z4D3YGAB.js → chunk-4ZKNC6A6.js} +2 -2
  14. package/dist/{chunk-ONB627HU.js → chunk-55LX6FSX.js} +2 -2
  15. package/dist/{chunk-M7W2KYTL.js → chunk-56IIVAEO.js} +2 -2
  16. package/dist/{chunk-FHHYCBBP.js → chunk-5DRROK5W.js} +2 -2
  17. package/dist/{chunk-GTNRMJYH.js → chunk-5GQEU4DN.js} +2 -2
  18. package/dist/{chunk-XSOGLHGY.js → chunk-6L3DKWRY.js} +6 -6
  19. package/dist/chunk-6LJY7X5A.js +18 -0
  20. package/dist/chunk-6LJY7X5A.js.map +1 -0
  21. package/dist/{chunk-44Y3P5U6.js → chunk-6M2I3DKF.js} +2 -2
  22. package/dist/{chunk-HDF5R2K6.js → chunk-6R6Q3MRN.js} +7 -7
  23. package/dist/{chunk-ZUDAK436.js → chunk-6UBZ6I5Z.js} +2 -2
  24. package/dist/{chunk-SEU6QHH4.js → chunk-6ZNSB3H6.js} +5 -17
  25. package/dist/chunk-6ZNSB3H6.js.map +1 -0
  26. package/dist/{chunk-7U6AB7DZ.js → chunk-AKKRXT23.js} +2 -2
  27. package/dist/{chunk-2PDBYF2O.js → chunk-AT2JJEKJ.js} +4 -4
  28. package/dist/chunk-AT2JJEKJ.js.map +1 -0
  29. package/dist/{chunk-OWLZONGX.js → chunk-BLBAQRBM.js} +2 -2
  30. package/dist/{chunk-XONZGK6J.js → chunk-BN4HRYAZ.js} +2 -2
  31. package/dist/{chunk-QVGEVZ5F.js → chunk-BQ6DHN4I.js} +3 -3
  32. package/dist/{chunk-LG2GUYRX.js → chunk-BYFXLDVV.js} +9 -9
  33. package/dist/{chunk-M4GO4ZJK.js → chunk-C25JXSOR.js} +137 -11
  34. package/dist/chunk-C25JXSOR.js.map +1 -0
  35. package/dist/{chunk-3TZUC4WS.js → chunk-CCDP6EPB.js} +13 -355
  36. package/dist/chunk-CCDP6EPB.js.map +1 -0
  37. package/dist/{chunk-QRHEAZ2Q.js → chunk-CUZLNGD5.js} +1 -1
  38. package/dist/{chunk-HXVRRJBD.js → chunk-DGBIHDVK.js} +5 -5
  39. package/dist/chunk-DSDXAKIP.js +50 -0
  40. package/dist/chunk-DSDXAKIP.js.map +1 -0
  41. package/dist/{chunk-JGOKAZNB.js → chunk-DZAF24PG.js} +5 -5
  42. package/dist/{chunk-NIKO2BBZ.js → chunk-DZFQVICS.js} +2 -2
  43. package/dist/chunk-DZFQVICS.js.map +1 -0
  44. package/dist/chunk-E23UGFVC.js +63 -0
  45. package/dist/chunk-E23UGFVC.js.map +1 -0
  46. package/dist/{chunk-YGMREQAK.js → chunk-EBKCYQ2D.js} +14 -14
  47. package/dist/chunk-EBKCYQ2D.js.map +1 -0
  48. package/dist/{chunk-TMR64XPL.js → chunk-EZNTORXE.js} +2 -2
  49. package/dist/{chunk-WCJJQV2D.js → chunk-FMNU7IUG.js} +3 -3
  50. package/dist/{chunk-H5GMROCB.js → chunk-FO6RNKKW.js} +8 -46
  51. package/dist/chunk-FO6RNKKW.js.map +1 -0
  52. package/dist/{chunk-YMUGBZN2.js → chunk-FQ5CHJR7.js} +1 -1
  53. package/dist/chunk-FQ5CHJR7.js.map +1 -0
  54. package/dist/{chunk-MQBFT2OT.js → chunk-FRMW23UK.js} +7 -7
  55. package/dist/chunk-FRMW23UK.js.map +1 -0
  56. package/dist/chunk-GJW4HX2O.js +1 -0
  57. package/dist/{chunk-JTIPVW4J.js → chunk-GP3UWP22.js} +4 -4
  58. package/dist/{chunk-DOZFU7OZ.js → chunk-GZACYEOB.js} +1 -1
  59. package/dist/chunk-GZACYEOB.js.map +1 -0
  60. package/dist/{chunk-XG7OZDOS.js → chunk-HFUAFR6B.js} +6 -6
  61. package/dist/{chunk-LN3MQFUE.js → chunk-IF6WNGAK.js} +9 -6
  62. package/dist/chunk-IF6WNGAK.js.map +1 -0
  63. package/dist/{chunk-ZX5FNWH7.js → chunk-IG6KUWBX.js} +2 -2
  64. package/dist/chunk-IG6KUWBX.js.map +1 -0
  65. package/dist/{chunk-VDTWFN2P.js → chunk-IMRB2C4O.js} +3 -3
  66. package/dist/{chunk-2BVW754E.js → chunk-ISRKW4YN.js} +3 -3
  67. package/dist/{chunk-P4NUJVWL.js → chunk-IXNCZTWA.js} +2 -2
  68. package/dist/{chunk-ZHZ4PET5.js → chunk-JIDLU57U.js} +3 -3
  69. package/dist/{chunk-PTT2NB46.js → chunk-JYJFGD2H.js} +2 -2
  70. package/dist/{chunk-XY6MNSAF.js → chunk-JYV4JJV2.js} +5 -5
  71. package/dist/{chunk-ZHMUFYZF.js → chunk-KBPU5M2E.js} +7 -7
  72. package/dist/{chunk-AZXEOEQK.js → chunk-KFRPNHWR.js} +4 -4
  73. package/dist/chunk-KFRPNHWR.js.map +1 -0
  74. package/dist/{chunk-ZDFU34XY.js → chunk-KPXM4WO6.js} +58 -54
  75. package/dist/chunk-KPXM4WO6.js.map +1 -0
  76. package/dist/{chunk-HA7P3BTB.js → chunk-KRCBZYTZ.js} +4 -4
  77. package/dist/{chunk-VNJMLOQS.js → chunk-KW42W6SV.js} +6 -6
  78. package/dist/{chunk-GQT6J4FJ.js → chunk-L3YYLT4E.js} +2 -2
  79. package/dist/chunk-L3YYLT4E.js.map +1 -0
  80. package/dist/{chunk-3GXDB3NQ.js → chunk-MANUDU7I.js} +6 -6
  81. package/dist/{chunk-YJ3TREAC.js → chunk-MHMLXJ3I.js} +2 -2
  82. package/dist/chunk-MHMLXJ3I.js.map +1 -0
  83. package/dist/{chunk-D4LAJ737.js → chunk-MSMJJB4J.js} +2 -2
  84. package/dist/chunk-MSMJJB4J.js.map +1 -0
  85. package/dist/{chunk-RM5EXCFF.js → chunk-MXUT7FTE.js} +2 -2
  86. package/dist/chunk-MXUT7FTE.js.map +1 -0
  87. package/dist/{chunk-IUATR5UE.js → chunk-N5PLUFH2.js} +5 -5
  88. package/dist/{chunk-C2V7AJO2.js → chunk-NEX7JCMO.js} +4 -4
  89. package/dist/{chunk-5HSSTOOG.js → chunk-NFZGZ4AK.js} +2 -2
  90. package/dist/{chunk-5ABOFAHN.js → chunk-NJ4DYYO5.js} +2 -2
  91. package/dist/chunk-NJ4DYYO5.js.map +1 -0
  92. package/dist/{chunk-2ZSC454H.js → chunk-NQSO4UAH.js} +8 -8
  93. package/dist/chunk-NQSO4UAH.js.map +1 -0
  94. package/dist/{chunk-GHEMAVTN.js → chunk-NYEFP7DY.js} +4 -4
  95. package/dist/chunk-NYEFP7DY.js.map +1 -0
  96. package/dist/{chunk-32467U5J.js → chunk-OBPVWOSQ.js} +4 -4
  97. package/dist/{chunk-6SSWOUUS.js → chunk-OLIWCCFM.js} +2 -5
  98. package/dist/{chunk-UNREYBZO.js → chunk-OLSARBZU.js} +2 -2
  99. package/dist/{chunk-V2R2VWER.js → chunk-PT4XLP6I.js} +12 -12
  100. package/dist/{chunk-V2R2VWER.js.map → chunk-PT4XLP6I.js.map} +1 -1
  101. package/dist/{chunk-LC7DSMHR.js → chunk-PTHKZWEH.js} +2 -14
  102. package/dist/{chunk-LC7DSMHR.js.map → chunk-PTHKZWEH.js.map} +1 -1
  103. package/dist/chunk-QADFHRQM.js +367 -0
  104. package/dist/chunk-QADFHRQM.js.map +1 -0
  105. package/dist/{chunk-7LP7FFJ2.js → chunk-QD46HPZG.js} +2 -2
  106. package/dist/{chunk-G4MFQXYX.js → chunk-QJNCB5SK.js} +2 -2
  107. package/dist/{chunk-6SYOHUHM.js → chunk-QZWTRENR.js} +2 -2
  108. package/dist/chunk-QZWTRENR.js.map +1 -0
  109. package/dist/{chunk-TSNRZSRC.js → chunk-RO5NM6UI.js} +2 -2
  110. package/dist/chunk-RO5NM6UI.js.map +1 -0
  111. package/dist/{chunk-MMVQ3SUO.js → chunk-RZPOZPZU.js} +8 -8
  112. package/dist/chunk-SGDPRCC4.js +1075 -0
  113. package/dist/chunk-SGDPRCC4.js.map +1 -0
  114. package/dist/{chunk-E7FSBI6I.js → chunk-SGQ4N5FS.js} +5 -5
  115. package/dist/{chunk-522MBPE5.js → chunk-SHEEBRZ4.js} +2 -2
  116. package/dist/{chunk-EPME33Y4.js → chunk-SHYIA73K.js} +6 -6
  117. package/dist/chunk-SKM35Y4Q.js +77 -0
  118. package/dist/chunk-SKM35Y4Q.js.map +1 -0
  119. package/dist/{chunk-MLCTPWSO.js → chunk-TE6LH6J2.js} +5 -5
  120. package/dist/chunk-TG634KCO.js +63 -0
  121. package/dist/chunk-TG634KCO.js.map +1 -0
  122. package/dist/{chunk-QVIZDLAR.js → chunk-TIVK6PRK.js} +9 -10
  123. package/dist/chunk-TIVK6PRK.js.map +1 -0
  124. package/dist/{chunk-JOCMXSR2.js → chunk-UADPR6F4.js} +3 -3
  125. package/dist/{chunk-SBOHNJUD.js → chunk-V6UQZA2H.js} +2 -2
  126. package/dist/chunk-VG2ZSFYD.js +32 -0
  127. package/dist/chunk-VG2ZSFYD.js.map +1 -0
  128. package/dist/{chunk-KCZAFDP5.js → chunk-VH6SOCXH.js} +2 -2
  129. package/dist/chunk-VSRSQ2CR.js +654 -0
  130. package/dist/chunk-VSRSQ2CR.js.map +1 -0
  131. package/dist/{chunk-4B3DL75F.js → chunk-W3G5REIU.js} +2 -2
  132. package/dist/{chunk-EGU4PWQW.js → chunk-W66AM5IB.js} +2 -2
  133. package/dist/chunk-W66AM5IB.js.map +1 -0
  134. package/dist/{chunk-MPPWL64H.js → chunk-WBKZUO5V.js} +3 -3
  135. package/dist/{chunk-WWBC4KLB.js → chunk-WO4T4OD5.js} +2 -2
  136. package/dist/{chunk-7IQWHYL2.js → chunk-WZ3NCMK6.js} +6 -5
  137. package/dist/{chunk-BAAUFCJK.js → chunk-X4MVWPHV.js} +3 -3
  138. package/dist/{chunk-HVPW6PCX.js → chunk-XIDQKFZF.js} +3 -3
  139. package/dist/{chunk-EWPS35AR.js → chunk-XOBHRD2M.js} +185 -333
  140. package/dist/chunk-XOBHRD2M.js.map +1 -0
  141. package/dist/chunk-Y2NBBT6K.js +18 -0
  142. package/dist/chunk-Y2NBBT6K.js.map +1 -0
  143. package/dist/{chunk-OWOT7CFC.js → chunk-Y6B6HVKC.js} +2 -2
  144. package/dist/{chunk-ICYC5YNI.js → chunk-Y6VZQGGH.js} +6 -6
  145. package/dist/{chunk-ZM72UO3Y.js → chunk-ZFUFAHZ3.js} +4 -4
  146. package/dist/{chunk-PWWWMRT7.js → chunk-ZTLOXFPB.js} +2 -2
  147. package/dist/chunk-ZTLOXFPB.js.map +1 -0
  148. package/dist/{walk-JXMWKKQW.js → chunk-ZWBKDKXC.js} +4 -13
  149. package/dist/{walk-JXMWKKQW.js.map → chunk-ZWBKDKXC.js.map} +1 -1
  150. package/dist/classified/index.js +5 -5
  151. package/dist/{classified-marker-SVDRXLD3.js → classified-marker-EOOSMWFC.js} +3 -3
  152. package/dist/collection-facade-TTRF5NFJ.js +45 -0
  153. package/dist/{computed-33DRJDOC.js → computed-AB45PS4V.js} +3 -3
  154. package/dist/consent/index.js +9 -9
  155. package/dist/{cover-ADBCTIKN.js → cover/index.js} +7 -6
  156. package/dist/custody/index.js +26 -0
  157. package/dist/{dead-filter-HKDMTMVY.js → dead-filter-6DYY7S64.js} +2 -2
  158. package/dist/{chunk-ZF572E2M.js → delegation-ONOZVPIP.js} +12 -6
  159. package/dist/{chunk-ZF572E2M.js.map → delegation-ONOZVPIP.js.map} +1 -1
  160. package/dist/derivations/index.js +12 -12
  161. package/dist/derive-IGGVSUPH.js +22 -0
  162. package/dist/directory/index.js +46 -0
  163. package/dist/{dispatch-SPMYNXNW.js → dispatch-7T45NN7C.js} +18 -18
  164. package/dist/{dispatch-V5MSMQYX.js → dispatch-RPTLK7LJ.js} +5 -5
  165. package/dist/{enclave-ZA7C3H2L.js → enclave-CLJVSDFG.js} +9 -9
  166. package/dist/executor-IEBLTBCW.js +9 -0
  167. package/dist/executor-RM7XWQDU.js +9 -0
  168. package/dist/executor-XZYM4KHT.js +28 -0
  169. package/dist/export-accessible-24XCCD3A.js +23 -0
  170. package/dist/extract-partition-H2TPEEOF.js +38 -0
  171. package/dist/{fanout-sidecar-HRMHC34B.js → fanout-sidecar-TV7CXAJ6.js} +9 -9
  172. package/dist/find-OZMTRIK3.js +11 -0
  173. package/dist/forget/index.js +11 -11
  174. package/dist/forget/index.js.map +1 -1
  175. package/dist/guards/index.js +4 -4
  176. package/dist/history/index.js +12 -12
  177. package/dist/i18n/index.js +14 -14
  178. package/dist/index.d.ts +14 -17
  179. package/dist/index.js +192 -1968
  180. package/dist/index.js.map +1 -1
  181. package/dist/indexing/index.js +2 -2
  182. package/dist/indexing/index.js.map +1 -1
  183. package/dist/introspection/index.js +28 -0
  184. package/dist/issue-55HJE7JF.js +19 -0
  185. package/dist/kernel/collection-config.d.ts +1 -1
  186. package/dist/kernel/collection.d.ts +2 -2
  187. package/dist/kernel/errors.d.ts +2 -2
  188. package/dist/kernel/noydb.d.ts +1 -1
  189. package/dist/kernel/types.d.ts +20 -20
  190. package/dist/kernel/vault.d.ts +10 -10
  191. package/dist/{ledger-K6JBFL3Z.js → ledger-XY6NP3J2.js} +11 -11
  192. package/dist/liberate-LXOJ2EMB.js +24 -0
  193. package/dist/{link-set-XVZY2ODC.js → link-set-POQB7BU5.js} +11 -11
  194. package/dist/materialized-views/index.js +19 -19
  195. package/dist/money/index.js +31 -0
  196. package/dist/noydb-KXS35UJS.js +82 -0
  197. package/dist/overlay-views/index.js +4 -4
  198. package/dist/periods/index.js +13 -13
  199. package/dist/pod/index.js +11 -11
  200. package/dist/{policy-QWGJB7P7.js → policy/index.js} +6 -6
  201. package/dist/port/with/blob-strategy.d.ts +15 -5
  202. package/dist/port/with/strategies.d.ts +9 -9
  203. package/dist/portability/index.js +8 -8
  204. package/dist/{post-register-5VHHVFJY.js → post-register-URQANI3B.js} +6 -6
  205. package/dist/query/index.js +3 -3
  206. package/dist/reduce/index.js +4 -4
  207. package/dist/register-5W6CG4RM.js +25 -0
  208. package/dist/registry-7Y5WF7GS.js +9 -0
  209. package/dist/{registry-VW6P6A3J.js → registry-BWD2ED52.js} +2 -2
  210. package/dist/registry-MCSGBZXI.js +18 -0
  211. package/dist/registry-UJFP3NWF.js +19 -0
  212. package/dist/request-withdrawal-IWYDM4SO.js +31 -0
  213. package/dist/{reveal-7OOT5XPD.js → reveal-BXZGWIOP.js} +6 -6
  214. package/dist/revoke-TINYPHYY.js +24 -0
  215. package/dist/satellites/index.js +1 -1
  216. package/dist/schema-update/index.js +26 -0
  217. package/dist/schema-update/index.js.map +1 -0
  218. package/dist/sealed-record/index.js +12 -12
  219. package/dist/search/index.js +36 -0
  220. package/dist/search/index.js.map +1 -0
  221. package/dist/{seed-GVOI6QP6.js → seed-F7YYQTRC.js} +11 -11
  222. package/dist/sequence/index.js +30 -0
  223. package/dist/sequence/index.js.map +1 -0
  224. package/dist/session/index.js +9 -9
  225. package/dist/shadow/index.js +2 -2
  226. package/dist/signer-WMZKCNKC.js +25 -0
  227. package/dist/signer-WMZKCNKC.js.map +1 -0
  228. package/dist/snapshots/index.js +11 -11
  229. package/dist/snapshots/index.js.map +1 -1
  230. package/dist/{stale-BJO2WIN7.js → stale-JOE7GBAE.js} +10 -10
  231. package/dist/stale-JOE7GBAE.js.map +1 -0
  232. package/dist/storage-B3WBKXKT.js +23 -0
  233. package/dist/storage-B3WBKXKT.js.map +1 -0
  234. package/dist/store/index.js +22 -0
  235. package/dist/store/index.js.map +1 -0
  236. package/dist/{store-coordination-provider-DX5HECK3.js → store-coordination-provider-5LX2UFU2.js} +3 -3
  237. package/dist/sync/index.js +10 -10
  238. package/dist/team/index.js +29 -20
  239. package/dist/tiers/index.js +10 -10
  240. package/dist/to/index.js +1 -1
  241. package/dist/{tx → transactions}/index.js +3 -3
  242. package/dist/{tx → transactions}/index.js.map +1 -1
  243. package/dist/util/index.js +1 -1
  244. package/dist/{verify-5X37OXRY.js → verify-7XWHJWUN.js} +5 -5
  245. package/dist/via/blob/active.d.ts +7 -18
  246. package/dist/via/blob/binding.d.ts +1 -1
  247. package/dist/via/blob/index.d.ts +2 -2
  248. package/dist/walk-6OHAWGBS.js +21 -0
  249. package/dist/walk-6OHAWGBS.js.map +1 -0
  250. package/dist/with-audit/forget/active.d.ts +3 -3
  251. package/dist/with-audit/forget/index.d.ts +4 -4
  252. package/dist/with-audit/forget/strategy.d.ts +3 -3
  253. package/dist/with-audit/guards/executor.d.ts +4 -4
  254. package/dist/with-audit/guards/immutable-guard.d.ts +3 -3
  255. package/dist/with-audit/guards/index.d.ts +1 -1
  256. package/dist/with-audit/guards/registry.d.ts +3 -3
  257. package/dist/with-audit/guards/transition-guard.d.ts +3 -3
  258. package/dist/with-audit/guards/types.d.ts +10 -10
  259. package/dist/with-audit/guards/with-guard.d.ts +2 -2
  260. package/dist/with-commit/numbering/descriptor.d.ts +16 -6
  261. package/dist/with-commit/tx/active.d.ts +5 -5
  262. package/dist/with-commit/tx/index.d.ts +2 -2
  263. package/dist/with-commit/tx/invariants.d.ts +1 -1
  264. package/dist/with-commit/tx/strategy.d.ts +3 -3
  265. package/dist/with-fork/snapshots/active.d.ts +2 -2
  266. package/dist/with-fork/snapshots/index.d.ts +1 -1
  267. package/dist/with-fork/snapshots/noydb-facade.d.ts +3 -3
  268. package/dist/with-fork/snapshots/strategy.d.ts +2 -2
  269. package/dist/with-formula/derivations/executor.d.ts +2 -2
  270. package/dist/with-formula/derivations/index.d.ts +2 -1
  271. package/dist/with-formula/derivations/registry.d.ts +3 -3
  272. package/dist/with-formula/derivations/stale.d.ts +2 -2
  273. package/dist/with-formula/derivations/types.d.ts +3 -3
  274. package/dist/with-formula/derivations/with-derivation.d.ts +2 -2
  275. package/dist/with-formula/derivations/with-rollup.d.ts +15 -8
  276. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +3 -3
  277. package/dist/with-formula/materialized-views/index.d.ts +1 -1
  278. package/dist/with-formula/materialized-views/registry.d.ts +4 -4
  279. package/dist/with-formula/materialized-views/types.d.ts +4 -4
  280. package/dist/with-formula/materialized-views/with-materialized-view.d.ts +2 -2
  281. package/dist/with-formula/overlay-views/index.d.ts +1 -1
  282. package/dist/with-formula/overlay-views/registry.d.ts +4 -4
  283. package/dist/with-formula/overlay-views/types.d.ts +3 -3
  284. package/dist/with-formula/overlay-views/virtual-collection.d.ts +2 -2
  285. package/dist/with-formula/overlay-views/with-overlayed-view.d.ts +2 -2
  286. package/dist/with-lookup/indexing/active.d.ts +5 -5
  287. package/dist/with-lookup/indexing/index.d.ts +1 -1
  288. package/dist/with-lookup/indexing/strategy.d.ts +3 -3
  289. package/dist/with-lookup/search/build-docs.d.ts +7 -2
  290. package/dist/with-lookup/search/index.d.ts +1 -1
  291. package/dist/with-party/directory/cover/index.d.ts +1 -0
  292. package/dist/with-party/directory/index.d.ts +2 -0
  293. package/dist/with-party/team/index.d.ts +2 -0
  294. package/dist/with-party/team/keyring.d.ts +49 -20
  295. package/dist/with-party/team/noydb-facade.d.ts +2 -2
  296. package/dist/with-shape/blobs/blob-set.d.ts +1 -1
  297. package/dist/with-shape/introspection/index.d.ts +6 -0
  298. package/dist/with-shape/schema-update/index.d.ts +1 -0
  299. package/dist/with-store/index.d.ts +3 -2
  300. package/dist/withdraw-accessible-DEUCOO4F.js +28 -0
  301. package/dist/withdraw-accessible-DEUCOO4F.js.map +1 -0
  302. package/package.json +45 -5
  303. package/dist/api-5QVQX4HG.js +0 -20
  304. package/dist/chunk-2PDBYF2O.js.map +0 -1
  305. package/dist/chunk-2ZSC454H.js.map +0 -1
  306. package/dist/chunk-3S2YNMUS.js +0 -134
  307. package/dist/chunk-3S2YNMUS.js.map +0 -1
  308. package/dist/chunk-3TZUC4WS.js.map +0 -1
  309. package/dist/chunk-5ABOFAHN.js.map +0 -1
  310. package/dist/chunk-6SYOHUHM.js.map +0 -1
  311. package/dist/chunk-AZXEOEQK.js.map +0 -1
  312. package/dist/chunk-D4LAJ737.js.map +0 -1
  313. package/dist/chunk-DOZFU7OZ.js.map +0 -1
  314. package/dist/chunk-EGU4PWQW.js.map +0 -1
  315. package/dist/chunk-EWPS35AR.js.map +0 -1
  316. package/dist/chunk-GHEMAVTN.js.map +0 -1
  317. package/dist/chunk-GQT6J4FJ.js.map +0 -1
  318. package/dist/chunk-H5GMROCB.js.map +0 -1
  319. package/dist/chunk-LN3MQFUE.js.map +0 -1
  320. package/dist/chunk-M4GO4ZJK.js.map +0 -1
  321. package/dist/chunk-MQBFT2OT.js.map +0 -1
  322. package/dist/chunk-NIKO2BBZ.js.map +0 -1
  323. package/dist/chunk-PWWWMRT7.js.map +0 -1
  324. package/dist/chunk-QVIZDLAR.js.map +0 -1
  325. package/dist/chunk-RM5EXCFF.js.map +0 -1
  326. package/dist/chunk-SEU6QHH4.js.map +0 -1
  327. package/dist/chunk-TSNRZSRC.js.map +0 -1
  328. package/dist/chunk-YGMREQAK.js.map +0 -1
  329. package/dist/chunk-YJ3TREAC.js.map +0 -1
  330. package/dist/chunk-YMUGBZN2.js.map +0 -1
  331. package/dist/chunk-ZDFU34XY.js.map +0 -1
  332. package/dist/chunk-ZGEFBDPR.js.map +0 -1
  333. package/dist/chunk-ZX5FNWH7.js.map +0 -1
  334. package/dist/collection-facade-S5PPKZD5.js +0 -44
  335. package/dist/delegation-EV7LKJPH.js +0 -25
  336. package/dist/derive-5LDJW76F.js +0 -21
  337. package/dist/executor-FCJEH3FU.js +0 -9
  338. package/dist/executor-OHET7TF7.js +0 -9
  339. package/dist/executor-SVHAJZ4A.js +0 -28
  340. package/dist/export-accessible-S35YKIBL.js +0 -23
  341. package/dist/extract-partition-UVHAM5WZ.js +0 -38
  342. package/dist/find-LEBUXVL7.js +0 -11
  343. package/dist/issue-5X3SMCF4.js +0 -19
  344. package/dist/liberate-NHTCKBU4.js +0 -24
  345. package/dist/noydb-TI3RFU6M.js +0 -78
  346. package/dist/register-CEX7R7NE.js +0 -23
  347. package/dist/registry-7CZWF3EQ.js +0 -9
  348. package/dist/registry-DIKMRXUC.js +0 -19
  349. package/dist/registry-EWIB5NTI.js +0 -18
  350. package/dist/request-withdrawal-AAG57QO4.js +0 -31
  351. package/dist/revoke-U5LCIJMF.js +0 -24
  352. package/dist/signer-NAA2OX7H.js +0 -25
  353. package/dist/storage-FL7XXZTN.js +0 -23
  354. package/dist/withdraw-accessible-GO6KQJVM.js +0 -28
  355. /package/dist/{api-5QVQX4HG.js.map → api-3NKVNZPM.js.map} +0 -0
  356. /package/dist/{backup-USYSNCYM.js.map → backup-PTSVXDDW.js.map} +0 -0
  357. /package/dist/{chunk-5WLDZZ6S.js.map → chunk-35NMVJ7I.js.map} +0 -0
  358. /package/dist/{chunk-NA374QG7.js.map → chunk-3XKESW5E.js.map} +0 -0
  359. /package/dist/{chunk-MUPZ6IZX.js.map → chunk-4JQK3L4V.js.map} +0 -0
  360. /package/dist/{chunk-Z4D3YGAB.js.map → chunk-4ZKNC6A6.js.map} +0 -0
  361. /package/dist/{chunk-ONB627HU.js.map → chunk-55LX6FSX.js.map} +0 -0
  362. /package/dist/{chunk-M7W2KYTL.js.map → chunk-56IIVAEO.js.map} +0 -0
  363. /package/dist/{chunk-FHHYCBBP.js.map → chunk-5DRROK5W.js.map} +0 -0
  364. /package/dist/{chunk-GTNRMJYH.js.map → chunk-5GQEU4DN.js.map} +0 -0
  365. /package/dist/{chunk-XSOGLHGY.js.map → chunk-6L3DKWRY.js.map} +0 -0
  366. /package/dist/{chunk-44Y3P5U6.js.map → chunk-6M2I3DKF.js.map} +0 -0
  367. /package/dist/{chunk-HDF5R2K6.js.map → chunk-6R6Q3MRN.js.map} +0 -0
  368. /package/dist/{chunk-ZUDAK436.js.map → chunk-6UBZ6I5Z.js.map} +0 -0
  369. /package/dist/{chunk-7U6AB7DZ.js.map → chunk-AKKRXT23.js.map} +0 -0
  370. /package/dist/{chunk-OWLZONGX.js.map → chunk-BLBAQRBM.js.map} +0 -0
  371. /package/dist/{chunk-XONZGK6J.js.map → chunk-BN4HRYAZ.js.map} +0 -0
  372. /package/dist/{chunk-QVGEVZ5F.js.map → chunk-BQ6DHN4I.js.map} +0 -0
  373. /package/dist/{chunk-LG2GUYRX.js.map → chunk-BYFXLDVV.js.map} +0 -0
  374. /package/dist/{chunk-QRHEAZ2Q.js.map → chunk-CUZLNGD5.js.map} +0 -0
  375. /package/dist/{chunk-HXVRRJBD.js.map → chunk-DGBIHDVK.js.map} +0 -0
  376. /package/dist/{chunk-JGOKAZNB.js.map → chunk-DZAF24PG.js.map} +0 -0
  377. /package/dist/{chunk-TMR64XPL.js.map → chunk-EZNTORXE.js.map} +0 -0
  378. /package/dist/{chunk-WCJJQV2D.js.map → chunk-FMNU7IUG.js.map} +0 -0
  379. /package/dist/{collection-facade-S5PPKZD5.js.map → chunk-GJW4HX2O.js.map} +0 -0
  380. /package/dist/{chunk-JTIPVW4J.js.map → chunk-GP3UWP22.js.map} +0 -0
  381. /package/dist/{chunk-XG7OZDOS.js.map → chunk-HFUAFR6B.js.map} +0 -0
  382. /package/dist/{chunk-VDTWFN2P.js.map → chunk-IMRB2C4O.js.map} +0 -0
  383. /package/dist/{chunk-2BVW754E.js.map → chunk-ISRKW4YN.js.map} +0 -0
  384. /package/dist/{chunk-P4NUJVWL.js.map → chunk-IXNCZTWA.js.map} +0 -0
  385. /package/dist/{chunk-ZHZ4PET5.js.map → chunk-JIDLU57U.js.map} +0 -0
  386. /package/dist/{chunk-PTT2NB46.js.map → chunk-JYJFGD2H.js.map} +0 -0
  387. /package/dist/{chunk-XY6MNSAF.js.map → chunk-JYV4JJV2.js.map} +0 -0
  388. /package/dist/{chunk-ZHMUFYZF.js.map → chunk-KBPU5M2E.js.map} +0 -0
  389. /package/dist/{chunk-HA7P3BTB.js.map → chunk-KRCBZYTZ.js.map} +0 -0
  390. /package/dist/{chunk-VNJMLOQS.js.map → chunk-KW42W6SV.js.map} +0 -0
  391. /package/dist/{chunk-3GXDB3NQ.js.map → chunk-MANUDU7I.js.map} +0 -0
  392. /package/dist/{chunk-IUATR5UE.js.map → chunk-N5PLUFH2.js.map} +0 -0
  393. /package/dist/{chunk-C2V7AJO2.js.map → chunk-NEX7JCMO.js.map} +0 -0
  394. /package/dist/{chunk-5HSSTOOG.js.map → chunk-NFZGZ4AK.js.map} +0 -0
  395. /package/dist/{chunk-32467U5J.js.map → chunk-OBPVWOSQ.js.map} +0 -0
  396. /package/dist/{chunk-6SSWOUUS.js.map → chunk-OLIWCCFM.js.map} +0 -0
  397. /package/dist/{chunk-UNREYBZO.js.map → chunk-OLSARBZU.js.map} +0 -0
  398. /package/dist/{chunk-7LP7FFJ2.js.map → chunk-QD46HPZG.js.map} +0 -0
  399. /package/dist/{chunk-G4MFQXYX.js.map → chunk-QJNCB5SK.js.map} +0 -0
  400. /package/dist/{chunk-MMVQ3SUO.js.map → chunk-RZPOZPZU.js.map} +0 -0
  401. /package/dist/{chunk-E7FSBI6I.js.map → chunk-SGQ4N5FS.js.map} +0 -0
  402. /package/dist/{chunk-522MBPE5.js.map → chunk-SHEEBRZ4.js.map} +0 -0
  403. /package/dist/{chunk-EPME33Y4.js.map → chunk-SHYIA73K.js.map} +0 -0
  404. /package/dist/{chunk-MLCTPWSO.js.map → chunk-TE6LH6J2.js.map} +0 -0
  405. /package/dist/{chunk-JOCMXSR2.js.map → chunk-UADPR6F4.js.map} +0 -0
  406. /package/dist/{chunk-SBOHNJUD.js.map → chunk-V6UQZA2H.js.map} +0 -0
  407. /package/dist/{chunk-KCZAFDP5.js.map → chunk-VH6SOCXH.js.map} +0 -0
  408. /package/dist/{chunk-4B3DL75F.js.map → chunk-W3G5REIU.js.map} +0 -0
  409. /package/dist/{chunk-MPPWL64H.js.map → chunk-WBKZUO5V.js.map} +0 -0
  410. /package/dist/{chunk-WWBC4KLB.js.map → chunk-WO4T4OD5.js.map} +0 -0
  411. /package/dist/{chunk-7IQWHYL2.js.map → chunk-WZ3NCMK6.js.map} +0 -0
  412. /package/dist/{chunk-BAAUFCJK.js.map → chunk-X4MVWPHV.js.map} +0 -0
  413. /package/dist/{chunk-HVPW6PCX.js.map → chunk-XIDQKFZF.js.map} +0 -0
  414. /package/dist/{chunk-OWOT7CFC.js.map → chunk-Y6B6HVKC.js.map} +0 -0
  415. /package/dist/{chunk-ICYC5YNI.js.map → chunk-Y6VZQGGH.js.map} +0 -0
  416. /package/dist/{chunk-ZM72UO3Y.js.map → chunk-ZFUFAHZ3.js.map} +0 -0
  417. /package/dist/{classified-marker-SVDRXLD3.js.map → classified-marker-EOOSMWFC.js.map} +0 -0
  418. /package/dist/{computed-33DRJDOC.js.map → collection-facade-TTRF5NFJ.js.map} +0 -0
  419. /package/dist/{cover-ADBCTIKN.js.map → computed-AB45PS4V.js.map} +0 -0
  420. /package/dist/{delegation-EV7LKJPH.js.map → cover/index.js.map} +0 -0
  421. /package/dist/{derive-5LDJW76F.js.map → custody/index.js.map} +0 -0
  422. /package/dist/{dead-filter-HKDMTMVY.js.map → dead-filter-6DYY7S64.js.map} +0 -0
  423. /package/dist/{enclave-ZA7C3H2L.js.map → derive-IGGVSUPH.js.map} +0 -0
  424. /package/dist/{executor-FCJEH3FU.js.map → directory/index.js.map} +0 -0
  425. /package/dist/{dispatch-SPMYNXNW.js.map → dispatch-7T45NN7C.js.map} +0 -0
  426. /package/dist/{dispatch-V5MSMQYX.js.map → dispatch-RPTLK7LJ.js.map} +0 -0
  427. /package/dist/{executor-OHET7TF7.js.map → enclave-CLJVSDFG.js.map} +0 -0
  428. /package/dist/{executor-SVHAJZ4A.js.map → executor-IEBLTBCW.js.map} +0 -0
  429. /package/dist/{export-accessible-S35YKIBL.js.map → executor-RM7XWQDU.js.map} +0 -0
  430. /package/dist/{extract-partition-UVHAM5WZ.js.map → executor-XZYM4KHT.js.map} +0 -0
  431. /package/dist/{find-LEBUXVL7.js.map → export-accessible-24XCCD3A.js.map} +0 -0
  432. /package/dist/{issue-5X3SMCF4.js.map → extract-partition-H2TPEEOF.js.map} +0 -0
  433. /package/dist/{fanout-sidecar-HRMHC34B.js.map → fanout-sidecar-TV7CXAJ6.js.map} +0 -0
  434. /package/dist/{ledger-K6JBFL3Z.js.map → find-OZMTRIK3.js.map} +0 -0
  435. /package/dist/{liberate-NHTCKBU4.js.map → introspection/index.js.map} +0 -0
  436. /package/dist/{link-set-XVZY2ODC.js.map → issue-55HJE7JF.js.map} +0 -0
  437. /package/dist/{noydb-TI3RFU6M.js.map → ledger-XY6NP3J2.js.map} +0 -0
  438. /package/dist/{policy-QWGJB7P7.js.map → liberate-LXOJ2EMB.js.map} +0 -0
  439. /package/dist/{register-CEX7R7NE.js.map → link-set-POQB7BU5.js.map} +0 -0
  440. /package/dist/{registry-7CZWF3EQ.js.map → money/index.js.map} +0 -0
  441. /package/dist/{registry-DIKMRXUC.js.map → noydb-KXS35UJS.js.map} +0 -0
  442. /package/dist/{registry-EWIB5NTI.js.map → policy/index.js.map} +0 -0
  443. /package/dist/{post-register-5VHHVFJY.js.map → post-register-URQANI3B.js.map} +0 -0
  444. /package/dist/{registry-VW6P6A3J.js.map → register-5W6CG4RM.js.map} +0 -0
  445. /package/dist/{request-withdrawal-AAG57QO4.js.map → registry-7Y5WF7GS.js.map} +0 -0
  446. /package/dist/{revoke-U5LCIJMF.js.map → registry-BWD2ED52.js.map} +0 -0
  447. /package/dist/{signer-NAA2OX7H.js.map → registry-MCSGBZXI.js.map} +0 -0
  448. /package/dist/{stale-BJO2WIN7.js.map → registry-UJFP3NWF.js.map} +0 -0
  449. /package/dist/{storage-FL7XXZTN.js.map → request-withdrawal-IWYDM4SO.js.map} +0 -0
  450. /package/dist/{reveal-7OOT5XPD.js.map → reveal-BXZGWIOP.js.map} +0 -0
  451. /package/dist/{withdraw-accessible-GO6KQJVM.js.map → revoke-TINYPHYY.js.map} +0 -0
  452. /package/dist/{seed-GVOI6QP6.js.map → seed-F7YYQTRC.js.map} +0 -0
  453. /package/dist/{store-coordination-provider-DX5HECK3.js.map → store-coordination-provider-5LX2UFU2.js.map} +0 -0
  454. /package/dist/{verify-5X37OXRY.js.map → verify-7XWHJWUN.js.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  FieldNotQueryableError,
7
7
  IndexRequiredError
8
- } from "./chunk-6SYOHUHM.js";
8
+ } from "./chunk-QZWTRENR.js";
9
9
 
10
10
  // src/with-lookup/indexing/strategy.ts
11
11
  var NO_INDEXING = {
@@ -534,4 +534,4 @@ export {
534
534
  PersistedCollectionIndex,
535
535
  LazyQuery
536
536
  };
537
- //# sourceMappingURL=chunk-GQT6J4FJ.js.map
537
+ //# sourceMappingURL=chunk-L3YYLT4E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-lookup/indexing/strategy.ts","../src/with-lookup/indexing/persisted-indexes.ts","../src/with-lookup/indexing/lazy-builder.ts"],"sourcesContent":["/**\n * Strategy seam between core Collection and the optional indexing\n * service. Core imports `IndexingStrategy` and `IndexState` as\n * TYPE-ONLY symbols and `NO_INDEXING` as a tiny runtime stub.\n *\n * The heavy classes — `CollectionIndexes`, `PersistedCollectionIndex`,\n * `LazyQuery` — are only instantiated inside the `withIndexing()`\n * factory under `./active.ts`, which in turn is only reachable through\n * the `@noy-db/hub/indexing` subpath export. A consumer that never\n * imports the subpath ships none of those classes in their bundle\n * (ESM tree-shaking + hub's `\"sideEffects\": false`).\n *\n * @internal\n */\n\nimport type { CollectionIndexes, IndexDef } from './eager-indexes.js'\nimport type { PersistedCollectionIndex } from './persisted-indexes.js'\n\n/**\n * Per-collection container for whatever mirrors the active strategy\n * decided to materialize. Both accessors may return `null` — they do\n * for `NO_INDEXING`, and `getEagerIndexes` returns null in a\n * lazy-mode collection even when indexing is active (lazy uses the\n * persisted mirror instead).\n *\n * `isEnabled` is a cheap guard so collection code can short-circuit\n * the full indexing path without inspecting either mirror.\n *\n * @internal\n */\nexport interface IndexState {\n readonly isEnabled: boolean\n getEagerIndexes(): CollectionIndexes | null\n getPersistedIndexes(): PersistedCollectionIndex | null\n}\n\n/**\n * Factory that builds one `IndexState` per Collection. Called exactly\n * once inside each Collection constructor with the declared\n * `IndexDef[]` and the lazy-mode flag (so lazy collections get the\n * persisted mirror and eager collections get the in-memory one).\n *\n * @internal\n */\nexport interface IndexingStrategy {\n createState(args: {\n readonly defs: readonly IndexDef[]\n readonly lazy: boolean\n }): IndexState\n}\n\n/**\n * No-indexing stub. Every Collection defaults to this; it returns a\n * cheap `IndexState` whose mirrors are both `null`. Collection code\n * null-checks both accessors and short-circuits, so no indexing code\n * path runs and the heavy classes never arrive in the bundle.\n *\n * @internal\n */\nexport const NO_INDEXING: IndexingStrategy = {\n createState() {\n return DISABLED_STATE\n },\n}\n\nconst DISABLED_STATE: IndexState = {\n isEnabled: false,\n getEagerIndexes: () => null,\n getPersistedIndexes: () => null,\n}\n","/**\n * Persistent, encrypted secondary indexes for lazy-mode collections.\n *\n * Parallel to the in-memory `CollectionIndexes` used by eager mode (see\n * `packages/hub/src/query/indexes.ts`): same logical surface, but entries\n * are materialised as encrypted side-car records (`_idx/<field>/<recordId>`)\n * and bulk-loaded into an in-memory mirror on first query.\n *\n * This module only owns the id-namespace convention, the in-memory mirror,\n * and the typed errors. Write-path integration (PR 2 / ), query-planner\n * dispatch (PR 3 / , PR 4 / ), and the rebuild/reconcile utilities\n * (PR 5 / ) live in other files.\n *\n * See the design spec for the full architecture + threat model.\n */\n\n/**\n * Reserved id prefix for encrypted index side-car records.\n * Matches the existing `_keyring`, `_ledger_deltas/…`, `_meta/handle`\n * conventions inside a collection's id namespace.\n */\nexport const IDX_PREFIX = '_idx/' as const\n\n/**\n * Encode the side-car record id for a (field, recordId) pair.\n *\n * Format: `_idx/<field>/<recordId>` — no escaping. Field names may contain\n * dots (for dotted-path access consistent with eager-mode `readPath`);\n * record ids may contain slashes. The first two slash-separated segments\n * are `_idx` and the field; everything after the *second* slash is the\n * record id verbatim.\n */\nexport function encodeIdxId(field: string, recordId: string): string {\n return `${IDX_PREFIX}${field}/${recordId}`\n}\n\n/**\n * Decode a side-car id back into `{ field, recordId }`, or `null` if the\n * input is not a well-formed idx id. A well-formed id is:\n * - prefixed with `_idx/`\n * - contains a field segment (non-empty, no slashes)\n * - contains a record-id segment (non-empty, may contain slashes)\n */\nexport function decodeIdxId(id: string): { field: string; recordId: string } | null {\n if (!id.startsWith(IDX_PREFIX)) return null\n const rest = id.slice(IDX_PREFIX.length)\n const firstSlash = rest.indexOf('/')\n if (firstSlash <= 0) return null\n const field = rest.slice(0, firstSlash)\n const recordId = rest.slice(firstSlash + 1)\n if (recordId.length === 0) return null\n return { field, recordId }\n}\n\n/**\n * Fast-path predicate for discriminating side-car ids from regular record\n * ids and other reserved namespaces. Used by the hub to filter `list()`\n * results during bulk-load of the in-memory mirror.\n */\nexport function isIdxId(id: string): boolean {\n return decodeIdxId(id) !== null\n}\n\n/**\n * Sorted-value entry returned by `orderedBy()`. Mirrors the body shape\n * used by the write path — but `orderedBy` emits them already sorted by\n * `value` in the requested direction. Consumers (PR 4 / ) treat the\n * array as immutable and paginate via a numeric offset.\n *\n * **Note on `value`:** as of, this is the ORIGINAL TYPED\n * value (number, Date, boolean, etc.), not the stringified bucket key.\n * That's what lets range predicates and `orderedBy` compare numerically\n * instead of stumbling into `'10' < '2'` on `String(n)`.\n */\nexport interface OrderedEntry {\n readonly recordId: string\n readonly value: unknown\n}\n\n/**\n * Bulk-load row shape accepted by `ingest()`. The `value` field is the\n * decrypted index body's `value` field verbatim.\n */\nexport interface IngestRow {\n readonly recordId: string\n readonly value: unknown\n}\n\n/**\n * In-memory mirror of the persisted index side-car records for a single\n * collection. Populated by bulk-loading `_idx/<field>/*` ids on first\n * query and maintained incrementally by `Collection.put()` / `.delete()`\n * via `upsert()` / `remove()`.\n *\n * API surface is deliberately parallel to `CollectionIndexes` (eager mode)\n * so the query planner in PR 3/4 can dispatch to either polymorphically.\n *\n * Lifecycle:\n * - `declare(field)` — accept the field as indexable (idempotent)\n * - `ingest(field, rows[])` — bulk-load from decrypted index bodies\n * - `upsert(recordId, field, newValue, previousValue)` — incremental update\n * - `remove(recordId, field, value)` — incremental remove\n * - `lookupEqual(field, value)` / `lookupIn(field, values)` — equality reads\n * - `orderedBy(field, dir)` — sorted iteration for orderBy\n * - `clear()` — drop all buckets (invalidation / rotation)\n */\n/**\n * Per-field storage: the equality bucket map AND a parallel table of typed\n * values keyed by recordId. The typed table exists so range predicates\n * and `orderedBy` can compare on the original typed value rather\n * than the stringified bucket key — String(10) < String(2) is the classic\n * landmine `stringifyKey` introduces for numeric fields.\n */\ninterface PersistedFieldState {\n readonly buckets: Map<string, Set<string>>\n readonly values: Map<string, unknown>\n}\n\n/**\n * Structured index definition. Single-field indexes carry just a field\n * name; composite indexes carry the ordered list of fields and\n * the synthetic `key` (= fields joined by `COMPOSITE_DELIMITER`) used\n * as the bucket-map key and side-car envelope id segment.\n */\nexport type PersistedIndexDef =\n | { readonly kind: 'single'; readonly field: string; readonly key: string }\n | { readonly kind: 'composite'; readonly fields: readonly string[]; readonly key: string }\n\n/**\n * Delimiter used to synthesize a composite-index key from an ordered\n * field list. Intentionally a character that is extremely unusual in\n * JavaScript object keys (`|`) so collision with a literal field name\n * is vanishingly rare in practice. Composite declarations whose field\n * names contain `|` are rejected at declare-time with an explicit\n * error.\n */\nexport const COMPOSITE_DELIMITER = '|'\n\nexport function compositeKey(fields: readonly string[]): string {\n return fields.join(COMPOSITE_DELIMITER)\n}\n\nexport class PersistedCollectionIndex {\n private readonly indexes = new Map<string, PersistedFieldState>()\n private readonly defs = new Map<string, PersistedIndexDef>()\n\n /**\n * Per-field bucket-key canonicalizer (#677 — lazy twin of #672's\n * `CollectionIndexes.setCanonicalizer`), registered ONCE via\n * {@link setCanonicalizer} when the collection wires indexing up\n * (money-aware via `ViaPipeline.canonicalizeIndexKey`). Consulted by\n * EVERY bucket-mutation site — `ingest`/`upsert`/`remove` — so bucket\n * membership is symmetric: a legacy non-canonical stored value (e.g.\n * `'0100'`) and a canonical one (`'100'`) land in the SAME bucket,\n * mirroring `eager-indexes.ts`'s `addToIndex`/`removeFromIndex`.\n */\n private canonicalize?: (field: string, value: unknown) => string | undefined\n\n /**\n * Register the bucket-key canonicalizer. Called once, where the\n * collection constructs its indexing state — safe to call again (the\n * closure is simply replaced) but there is normally only one caller.\n */\n setCanonicalizer(fn: (field: string, value: unknown) => string | undefined): void {\n this.canonicalize = fn\n }\n\n /**\n * Declare a single-field index. Subsequent `upsert` / `ingest` calls\n * populate the in-memory mirror; calls before `declare` are no-ops\n * (tolerant bulk-load ordering). Idempotent.\n */\n declare(field: string): void {\n if (this.indexes.has(field)) return\n this.indexes.set(field, { buckets: new Map(), values: new Map() })\n this.defs.set(field, { kind: 'single', field, key: field })\n }\n\n /**\n * Declare a composite (multi-field) index. The synthetic\n * key is `fields.join('|')`; it doubles as the in-memory map key and\n * the `_idx/<key>/<recordId>` side-car field segment. Callers upsert\n * and lookup via the same `key` as single-field indexes, just with a\n * tuple value (JSON-stringified for bucketing).\n */\n declareComposite(fields: readonly string[]): void {\n if (fields.length === 0) {\n throw new Error('declareComposite: fields array must be non-empty')\n }\n for (const f of fields) {\n if (f.includes(COMPOSITE_DELIMITER)) {\n throw new Error(\n `declareComposite: field \"${f}\" contains the composite delimiter ` +\n `\"${COMPOSITE_DELIMITER}\" — pick a different field name or open an ` +\n `issue to add hash-based composite keys.`,\n )\n }\n }\n const key = compositeKey(fields)\n if (this.indexes.has(key)) return\n this.indexes.set(key, { buckets: new Map(), values: new Map() })\n this.defs.set(key, { kind: 'composite', fields: [...fields], key })\n }\n\n /**\n * Every declared index's structured definition. Collection walks this\n * when materialising side-cars on put/delete so it can extract a\n * single-field value or a composite tuple appropriately.\n */\n definitions(): PersistedIndexDef[] {\n return [...this.defs.values()]\n }\n\n /** True if `field` has been declared as indexable on this mirror. */\n has(field: string): boolean {\n return this.indexes.has(field)\n }\n\n /** All declared field names, in declaration order. */\n fields(): string[] {\n return [...this.indexes.keys()]\n }\n\n /**\n * Bulk-load the mirror from decrypted index bodies. Intended to be\n * called once per field after reading the collection's `_idx/<field>/*`\n * side-cars. Safe to call twice with the same rows — bucket Sets\n * deduplicate recordIds. If `field` is not declared, this is a no-op\n * (tolerates the case where bulk-load runs before `declare()` lands).\n */\n ingest(field: string, rows: readonly IngestRow[]): void {\n const state = this.indexes.get(field)\n if (!state) return\n for (const row of rows) {\n addToState(state, row.recordId, row.value, field, this.canonicalize)\n }\n }\n\n /**\n * Incrementally update a record's index entry for one field. Called by\n * `Collection.put()` after the main write succeeds. If\n * `previousValue` is non-null, the record is removed from the old\n * bucket first — this is the update path. Pass `null` for fresh adds.\n * No-op if the field is not declared.\n */\n upsert(recordId: string, field: string, newValue: unknown, previousValue: unknown): void {\n const state = this.indexes.get(field)\n if (!state) return\n if (previousValue !== null && previousValue !== undefined) {\n removeFromState(state, recordId, previousValue, field, this.canonicalize)\n }\n addToState(state, recordId, newValue, field, this.canonicalize)\n }\n\n /**\n * Remove a record from the index for one field. Called by\n * `Collection.delete()`. No-op if the field is not declared or\n * the record isn't in the bucket. Empty buckets are dropped to keep\n * the Map clean.\n */\n remove(recordId: string, field: string, value: unknown): void {\n const state = this.indexes.get(field)\n if (!state) return\n removeFromState(state, recordId, value, field, this.canonicalize)\n }\n\n /**\n * Drop all bucket data while preserving field declarations. Called on\n * invalidation (incoming sync changes, keyring rotation) — the next\n * query re-populates via `ingest`.\n */\n clear(): void {\n for (const state of this.indexes.values()) {\n state.buckets.clear()\n state.values.clear()\n }\n }\n\n /**\n * Equality lookup — return the set of record ids whose `field` matches\n * `value`. Returns `null` if the field is not declared (caller falls\n * back to scan or throws `IndexRequiredError`). Returns a shared empty\n * set if the field is declared but no record matches — that set MUST\n * NOT be mutated by the caller.\n *\n * `value` is bucketed via the plain {@link stringifyKey} — it is NOT\n * canonicalized here. Callers on a Via-covered field (money) canonicalize\n * `value` themselves BEFORE calling (see `lazy-builder.ts`'s\n * `resolveCandidateIds()`, #677) — the SAME caller-canonicalizes split\n * `eager-indexes.ts`'s `lookupEqual`/`lookupIn` use (see `kernel/query/\n * builder.ts`'s `candidateRecords()`), so probing here twice never\n * double-canonicalizes.\n */\n lookupEqual(field: string, value: unknown): ReadonlySet<string> | null {\n const state = this.indexes.get(field)\n if (!state) return null\n const key = stringifyKey(value)\n return state.buckets.get(key) ?? EMPTY_SET\n }\n\n /**\n * Set lookup — return the union of record ids whose `field` matches any\n * of `values`. Returns `null` if the field is not declared. Returns a\n * fresh (non-shared) Set — safe for the caller to mutate. Same\n * caller-canonicalizes contract as {@link lookupEqual} (#677).\n */\n lookupIn(field: string, values: readonly unknown[]): ReadonlySet<string> | null {\n const state = this.indexes.get(field)\n if (!state) return null\n const out = new Set<string>()\n for (const value of values) {\n const bucket = state.buckets.get(stringifyKey(value))\n if (bucket) for (const id of bucket) out.add(id)\n }\n return out\n }\n\n /**\n * Range lookup. Return record ids whose indexed value\n * satisfies the predicate. Comparison happens on the ORIGINAL TYPED\n * value carried in `state.values` — so numeric `<` sorts numerically,\n * not lexicographically on `String(n)`. Returns `null` if the field\n * is not declared.\n *\n * Supported ops: `'<'`, `'<='`, `'>'`, `'>='`, `'between'`. For\n * `'between'`, `value` is `[lo, hi]` and both bounds are inclusive\n * (matches the eager-mode operator contract in `predicate.ts`).\n *\n * NOT canonicalized (#677): this method compares `value` against the\n * ORIGINAL TYPED `state.values`, not a stringified bucket key, so a\n * `canonicalizeIndexKey`-shaped (`string | undefined`) result would not\n * even type-check as a bound here. This does NOT mirror eager mode the\n * way `lookupEqual`/`lookupIn` do: `moneyIndexProbe` (`via/money/\n * where.ts`) never emits a range probe, so EAGER mode's `candidateRecords`\n * never calls an index for a range clause and always scans.\n *\n * LAZY mode's `resolveCandidateIds()` (`lazy-builder.ts`) no longer\n * dispatches a Via-covered (e.g. money) range clause through THIS method\n * at all (#684) — it enumerates the field's indexed ids via `orderedBy()`\n * instead and leaves the raw/typed comparison here for the (now\n * Via-aware) post-filter to redo correctly in scaled-int space. A\n * NON-via range clause still dispatches through this method exactly as\n * before — the raw/typed comparison here is correct and sufficient for\n * fields with no decode-transforming Via binding.\n */\n lookupRange(\n field: string,\n op: '<' | '<=' | '>' | '>=' | 'between',\n value: unknown,\n ): ReadonlySet<string> | null {\n const state = this.indexes.get(field)\n if (!state) return null\n const out = new Set<string>()\n for (const [recordId, live] of state.values) {\n if (live === undefined || live === null) continue\n if (matchesRange(live, op, value)) out.add(recordId)\n }\n return out\n }\n\n /**\n * Sorted iteration — return every entry on `field` as an\n * `OrderedEntry[]`, sorted by the ORIGINAL TYPED value (no more\n * `'10' < '2'` surprises on numeric fields). Consumers paginate with\n * a numeric offset. `OrderedEntry.value` is the typed value.\n */\n orderedBy(field: string, dir: 'asc' | 'desc'): readonly OrderedEntry[] | null {\n const state = this.indexes.get(field)\n if (!state) return null\n const entries: OrderedEntry[] = []\n for (const [recordId, value] of state.values) {\n entries.push({ recordId, value })\n }\n entries.sort((a, b) => compareTyped(a.value, b.value))\n if (dir === 'desc') entries.reverse()\n return entries\n }\n}\n\nconst EMPTY_SET: ReadonlySet<string> = new Set()\n\n/**\n * Canonicalize a value into a bucket key. Deliberately identical to the\n * eager-mode `stringifyKey` in `query/indexes.ts` so semantics match. When\n * `query/indexes.ts` changes its coercion rules, update this in lockstep.\n *\n * null / undefined values are NOT indexed — callers who pass them to\n * `upsert` / `remove` short-circuit before reaching this function; the\n * sentinel here exists only to make `lookupEqual(field, null)` return\n * an empty bucket (rather than matching some arbitrary record).\n */\nfunction stringifyKey(value: unknown): string {\n if (value === null || value === undefined) return '\\0NULL\\0'\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n if (value instanceof Date) return value.toISOString()\n // composite index values are tuple arrays. JSON.stringify\n // gives a delimiter-safe, order-preserving canonical form so buckets\n // for `['c-A', '2026-Q1']` and `['c-A', '2026-Q2']` never collide.\n if (Array.isArray(value)) {\n const parts: string[] = []\n for (const el of value) parts.push(stringifyKey(el))\n return JSON.stringify(parts)\n }\n return '\\0OBJECT\\0'\n}\n\nfunction addToState(\n state: PersistedFieldState,\n recordId: string,\n value: unknown,\n field: string,\n canonicalize?: (field: string, value: unknown) => string | undefined,\n): void {\n if (value === null || value === undefined) return\n const key = canonicalize?.(field, value) ?? stringifyKey(value)\n let bucket = state.buckets.get(key)\n if (!bucket) {\n bucket = new Set()\n state.buckets.set(key, bucket)\n }\n bucket.add(recordId)\n state.values.set(recordId, value)\n}\n\nfunction removeFromState(\n state: PersistedFieldState,\n recordId: string,\n value: unknown,\n field: string,\n canonicalize?: (field: string, value: unknown) => string | undefined,\n): void {\n if (value === null || value === undefined) return\n const key = canonicalize?.(field, value) ?? stringifyKey(value)\n const bucket = state.buckets.get(key)\n if (bucket) {\n bucket.delete(recordId)\n if (bucket.size === 0) state.buckets.delete(key)\n }\n state.values.delete(recordId)\n}\n\n/**\n * Range-predicate comparator. Runs on the ORIGINAL TYPED value so numeric\n * fields sort numerically (not lexicographically on `String(n)`). ISO-8601\n * date strings already sort correctly lexicographically; Date instances\n * compare via `getTime()` before the string branch to keep the contract\n * honest regardless of which form survived serialization.\n */\nfunction matchesRange(\n live: unknown,\n op: '<' | '<=' | '>' | '>=' | 'between',\n bound: unknown,\n): boolean {\n if (op === 'between') {\n if (!Array.isArray(bound) || bound.length !== 2) return false\n return compareTyped(live, bound[0]) >= 0 && compareTyped(live, bound[1]) <= 0\n }\n const cmp = compareTyped(live, bound)\n switch (op) {\n case '<': return cmp < 0\n case '<=': return cmp <= 0\n case '>': return cmp > 0\n case '>=': return cmp >= 0\n }\n}\n\nfunction compareTyped(a: unknown, b: unknown): number {\n if (a === undefined || a === null) return b === undefined || b === null ? 0 : 1\n if (b === undefined || b === null) return -1\n if (typeof a === 'number' && typeof b === 'number') return a - b\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime()\n if (typeof a === 'string' && typeof b === 'string') return a < b ? -1 : a > b ? 1 : 0\n if (typeof a === 'boolean' && typeof b === 'boolean') {\n return a === b ? 0 : a ? 1 : -1\n }\n // Mixed/unsupported types: deliberately treat as equal so sort stays\n // stable. Matches the eager-mode `compareValues` contract in\n // builder.ts — we don't silently coerce arbitrary objects to strings\n // (which would be meaningless) nor throw (which would be hostile).\n return 0\n}\n","/**\n * Lazy-mode query builder.\n *\n * Companion to `Query<T>` in `builder.ts`, but built for collections in lazy\n * mode where `snapshot()` is unavailable — records live in the adapter and\n * are pulled on demand. Dispatches through `PersistedCollectionIndex` to\n * resolve a candidate record-id set, then decrypts only those records.\n *\n * Scope:\n * - `.where(field, '==' | 'in', value)` — dispatched through the index\n * - `.where(field, other-op, value)` — evaluated against the decrypted\n * candidate set (non-indexed ops still require the field to be indexed\n * — we need SOMETHING to scope the candidate set)\n * - `.orderBy(field, dir?)` — dispatched through `orderedBy` when no\n * `==`/`in` clause is present; otherwise applied as an in-memory sort\n * over the candidate set\n * - `.limit(n)` / `.offset(n)` — page slice after filtering\n * - `.toArray()` / `.first()` / `.count()` — terminals\n *\n * Every field referenced by a where or orderBy clause MUST be indexed;\n * otherwise `toArray()` throws `IndexRequiredError`. This is deliberate:\n * silent scan-fallback would hide the very performance cliff that lazy-mode\n * indexes exist to prevent (see `docs/architecture.md` §indexes).\n */\n\nimport type { Clause, FieldClause, Operator } from '../../kernel/query/predicate.js'\nimport { evaluateClause, readPath } from '../../kernel/query/predicate.js'\nimport type { PersistedCollectionIndex } from './persisted-indexes.js'\nimport { IndexRequiredError, FieldNotQueryableError } from '../../kernel/errors.js'\nimport type { QueryField } from '../../kernel/types.js'\nimport type { ViaPipeline } from '../../kernel/via/pipeline.js'\n\nexport interface LazyOrderBy {\n readonly field: string\n readonly direction: 'asc' | 'desc'\n}\n\n/**\n * Source abstraction the LazyQuery runs against. Collection implements it.\n * Kept minimal so the builder stays test-friendly.\n */\nexport interface LazyQuerySource<T> {\n readonly collectionName: string\n readonly persistedIndexes: PersistedCollectionIndex\n /**\n * Per-field bucket-key canonicalizer (#677 — lazy twin of the eager\n * `candidateRecords()` probe-resolution in `kernel/query/builder.ts`).\n * Consulted in `resolveCandidateIds()` for `==`/`in` clause values\n * BEFORE calling `lookupEqual`/`lookupIn`, so a mixed-era stored value\n * (money) probes the SAME canonical bucket the write path now\n * populates. A narrow closure — not the whole `ViaPipeline` — keeps\n * the with-lookup/kernel seam thin. `undefined` (no via, or no binding\n * covers the field) is the common case: falls back to the raw value,\n * unchanged from today.\n */\n canonicalizeIndexKey?(field: string, value: unknown): string | undefined\n /** Ensure `_idx/<field>/*` side-cars have been bulk-loaded into the mirror. */\n ensurePersistedIndexesLoaded(): Promise<void>\n /**\n * Decrypt one record by id in RAW (pre-`present()`, stored-form) shape,\n * or return null if it's gone (#684 — the raw-fetch seam). Used by the\n * post-filter (`toArray()`) so a `clause.via.evaluate` (e.g. money) sees\n * the same operand/actual-value space as eager's `filterRecords` — the\n * DECODED form (e.g. money's canonical decimal) is only materialized\n * for survivors, via {@link decodeRecord}.\n */\n getRawRecord(id: string): Promise<unknown>\n /**\n * Apply this collection's locale/virtual-field decode (`present()`) to a\n * RAW record already known to match — the output-side twin of\n * {@link getRawRecord}. Mirrors eager's `Query.decodeVia`.\n */\n decodeRecord(record: unknown): Promise<T>\n /**\n * This collection's compiled Via pipeline (money, i18n, …), read lazily\n * (a method, not a captured value) so a late `_setVia` (#666) is honored\n * — same closure discipline as {@link canonicalizeIndexKey}. `undefined`\n * when the collection has no Via-covered fields.\n */\n via(): ViaPipeline | undefined\n}\n\ninterface LazyPlan {\n readonly clauses: readonly FieldClause[]\n readonly orderBy: readonly LazyOrderBy[]\n readonly limit: number | undefined\n readonly offset: number\n}\n\nconst EMPTY_PLAN: LazyPlan = {\n clauses: [],\n orderBy: [],\n limit: undefined,\n offset: 0,\n}\n\nexport class LazyQuery<T, S extends keyof T = never, Q extends keyof T & string = never> {\n private readonly source: LazyQuerySource<T>\n private readonly plan: LazyPlan\n\n constructor(source: LazyQuerySource<T>, plan: LazyPlan = EMPTY_PLAN) {\n this.source = source\n this.plan = plan\n }\n\n where<V>(field: QueryField<T, S, Q>, op: Operator, value: V): LazyQuery<T, S, Q> {\n // A Via-covered field (e.g. money) compares in major units, BigInt-exact\n // in scaled space — same build-time operand rewrite + `clause.via`\n // attachment as `Query.where()` (`kernel/query/builder.ts`) and\n // `ScanBuilder.where()` (`kernel/query/scan-builder.ts`). Before #684\n // this method built a bare clause with no `clause.via` at all, so the\n // post-filter fell through to the generic (non-Via-aware) comparison —\n // see `toArray()` below for the raw-record post-filter this feeds.\n const via = this.source.via()\n // Consults the Via pipeline's posture BEFORE building a clause — same\n // gate as `Query.where()` (builder.ts) / `ScanBuilder.where()`\n // (scan-builder.ts): a field whose posture is `queryable: 'none'`\n // (e.g. a `blobFields` slot) throws `FieldNotQueryableError` here, at\n // the call site, instead of building a bare clause that later surfaces\n // as a deferred `IndexRequiredError` from `toArray()`.\n if (via?.postureFor(field)?.queryable === 'none') throw new FieldNotQueryableError(field)\n const viaClause = via?.buildClause(field, op, value)\n const clause: FieldClause = viaClause\n ? {\n type: 'field',\n field,\n op,\n value,\n via: {\n brand: viaClause.brand,\n payload: viaClause.payload,\n evaluate: (actual: unknown, evalOp: string) => via!.evaluateClause(viaClause, actual, evalOp),\n indexValue: via!.indexProbe(viaClause, op),\n },\n }\n : { type: 'field', field, op, value }\n return new LazyQuery<T, S, Q>(this.source, {\n ...this.plan,\n clauses: [...this.plan.clauses, clause],\n })\n }\n\n orderBy(field: QueryField<T, S>, direction: 'asc' | 'desc' = 'asc'): LazyQuery<T, S, Q> {\n return new LazyQuery<T, S, Q>(this.source, {\n ...this.plan,\n orderBy: [...this.plan.orderBy, { field, direction }],\n })\n }\n\n limit(n: number): LazyQuery<T, S, Q> {\n return new LazyQuery<T, S, Q>(this.source, { ...this.plan, limit: n })\n }\n\n offset(n: number): LazyQuery<T, S, Q> {\n return new LazyQuery<T, S, Q>(this.source, { ...this.plan, offset: n })\n }\n\n async toArray(): Promise<T[]> {\n await this.source.ensurePersistedIndexesLoaded()\n\n const touchedFields = collectTouchedFields(this.plan)\n const missingFields = touchedFields.filter(f => !isFieldIndexed(f, this.source.persistedIndexes))\n if (missingFields.length > 0) {\n throw new IndexRequiredError({\n collection: this.source.collectionName,\n touchedFields,\n missingFields,\n })\n }\n\n const candidateIds = this.resolveCandidateIds()\n if (candidateIds === null) {\n // No usable driver — every touched field is indexed but no clause\n // pins the candidate set. This happens when a query only uses\n // operators other than `==`/`in` and no `orderBy` clause is\n // present — we refuse to enumerate the whole index, because that\n // defeats the purpose of lazy mode.\n throw new IndexRequiredError({\n collection: this.source.collectionName,\n touchedFields,\n missingFields: touchedFields,\n })\n }\n\n // #684: post-filter the RAW record (mirrors eager's filterRecords on the\n // raw snapshot) so `clause.via.evaluate` sees the same stored-form\n // operand/actual-value space `buildClause` quantized into at where()\n // time. Survivors stay RAW here — #695 sorts them via-aware in that\n // same stored-form space (mirroring eager's `sortRecords(result, ...,\n // source.via, ...)` in `kernel/query/builder.ts`) before anything is\n // decoded (`present()`).\n const survivors: T[] = []\n for (const id of candidateIds) {\n const raw = await this.source.getRawRecord(id)\n if (raw === null) continue\n if (!matchesAll(raw, this.plan.clauses)) continue\n survivors.push(raw as T)\n }\n\n // #695: sort the RAW survivors via-aware — a money field's stored form\n // (scaled-integer string) sorts lexicographically wrong under the\n // generic comparator ('10.00' < '2.00' once decoded); `via.compareForOrder`\n // compares in the correct (BigInt-exact scaled) space, same as eager.\n const sorted = this.plan.orderBy.length > 0\n ? sortRecords(survivors, this.plan.orderBy, this.source.via())\n : survivors\n\n const offset = this.plan.offset > 0 ? this.plan.offset : 0\n const page = this.plan.limit === undefined\n ? sorted.slice(offset)\n : sorted.slice(offset, offset + this.plan.limit)\n\n // Decode only the final page — fewer decodes than the pre-#695 code,\n // which decoded every survivor before sorting/slicing.\n return Promise.all(page.map(r => this.source.decodeRecord(r)))\n }\n\n async first(): Promise<T | null> {\n const out = await this.limit(1).toArray()\n return out.length > 0 ? out[0]! : null\n }\n\n async count(): Promise<number> {\n const out = await this.toArray()\n return out.length\n }\n\n /**\n * Resolve the candidate record-id set to decrypt. Returns null when the\n * query has no usable driver — no `==`/`in` clause and no `orderBy`\n * clause that can scope the scan. Callers interpret null as\n * IndexRequiredError (see `toArray`).\n */\n private resolveCandidateIds(): readonly string[] | null {\n const idx = this.source.persistedIndexes\n\n // prefer a composite index when the query's `==`\n // clauses cover every field of one declared composite. The\n // composite mirror lookup is O(matches) vs single-field +\n // post-filter on the decrypted candidate set.\n const eqMap = new Map<string, unknown>()\n const viaFields = new Set<string>()\n for (const clause of this.plan.clauses) {\n if (clause.op === '==') {\n eqMap.set(clause.field, clause.value)\n // #696: the composite mirror buckets on `stringifyKey(tuple)` built\n // from the RAW clause values — the per-field money canonicalizer\n // (`canonicalizeIndexKey`) only ever keys off a single field name,\n // never the joined composite key, so a Via-covered field's tuple\n // slot never lands in the same bucket a canonical write produced.\n // Track which `==` fields are Via-covered so the composite branch\n // below can skip them and fall through to the single-field\n // Via-aware path (already correct for money) instead.\n if (clause.via) viaFields.add(clause.field)\n }\n }\n if (eqMap.size >= 2) {\n for (const def of idx.definitions()) {\n if (def.kind !== 'composite') continue\n if (def.fields.some(f => viaFields.has(f))) continue\n if (def.fields.every(f => eqMap.has(f))) {\n const tuple = def.fields.map(f => eqMap.get(f))\n const ids = idx.lookupEqual(def.key, tuple)\n if (ids) return [...ids]\n }\n }\n }\n\n for (const clause of this.plan.clauses) {\n if (clause.op === '==') {\n if (clause.via) {\n // #684: prefer `clause.via.indexValue` — the same STORED-form\n // probe operand eager's `candidateRecords()` resolves first\n // (`kernel/query/builder.ts`). `undefined` means the binding\n // declined to probe this op/payload (e.g. money multi-mode) — no\n // sound equality bucket exists. Eager's `candidateRecords()`\n // handles this by skipping the index-eligibility check for the\n // clause and falling back to a full scan (`builder.ts:1176`); the\n // lazy equivalent (#684 review-fix 2) is the same move the RANGE branch\n // below already makes — enumerate the field's full indexed id\n // set via `orderedBy` and let the (now via-aware) post-filter in\n // `toArray()` decide, instead of throwing `IndexRequiredError`.\n if (clause.via.indexValue === undefined) {\n const entries = idx.orderedBy(clause.field, 'asc')\n if (entries) return entries.map(e => e.recordId)\n continue\n }\n const ids = idx.lookupEqual(clause.field, clause.via.indexValue)\n if (ids) return [...ids]\n continue\n }\n // #677: canonicalize the probe value BEFORE the lookup — same\n // \"resolve before lookupEqual\" shape as eager's `candidateRecords()`,\n // but through the narrower `canonicalizeIndexKey` seam, used only on\n // this NON-via path. `undefined` (no via coverage) falls back to the\n // raw clause value, unchanged from today.\n const probe = this.source.canonicalizeIndexKey?.(clause.field, clause.value) ?? clause.value\n const ids = idx.lookupEqual(clause.field, probe)\n if (ids) return [...ids]\n } else if (clause.op === 'in' && Array.isArray(clause.value)) {\n if (clause.via) {\n // Same #684 review-fix 2 fallback as the `==` branch above — a via\n // payload that declines to probe (e.g. money multi-mode) still\n // has a sound candidate superset via `orderedBy`.\n if (clause.via.indexValue === undefined) {\n const entries = idx.orderedBy(clause.field, 'asc')\n if (entries) return entries.map(e => e.recordId)\n continue\n }\n if (!Array.isArray(clause.via.indexValue)) continue\n const ids = idx.lookupIn(clause.field, clause.via.indexValue)\n if (ids) return [...ids]\n continue\n }\n const probes = clause.value.map(v => this.source.canonicalizeIndexKey?.(clause.field, v) ?? v)\n const ids = idx.lookupIn(clause.field, probes)\n if (ids) return [...ids]\n } else if (isRangeOp(clause.op)) {\n if (clause.via) {\n // #684: a Via-covered range clause (e.g. money) cannot trust\n // `lookupRange` — it compares the ORIGINAL TYPED stored value,\n // wrong space for a binding whose stored form isn't directly\n // orderable that way (money: BigInt-exact scaled-int compare).\n // No binding emits a range `indexProbe` either (see\n // `moneyIndexProbe`), so there's no sound bucket lookup at all.\n // Enumerate the field's full indexed id set via `orderedBy` — the\n // same superset a scan would consider, just scoped to indexed ids\n // — and let the (now via-aware) post-filter in `toArray()` apply\n // the correct scaled-space comparison. Replaces the old\n // \"always trust lookupRange, no scan fallback\" gap.\n const entries = idx.orderedBy(clause.field, 'asc')\n if (entries) return entries.map(e => e.recordId)\n continue\n }\n // range predicates on a NON-via indexed field dispatch through\n // `lookupRange`, which compares on the original typed value (no\n // numeric-lexicographic landmines).\n const ids = idx.lookupRange(clause.field, clause.op, clause.value)\n if (ids) return [...ids]\n }\n }\n\n // No equality/range driver — try to scope via orderBy.\n if (this.plan.orderBy.length > 0) {\n const primary = this.plan.orderBy[0]!\n const entries = idx.orderedBy(primary.field, primary.direction)\n if (entries) return entries.map(e => e.recordId)\n }\n\n return null\n }\n}\n\n/**\n * True if the given field name is covered by either a single-field\n * index or appears as a component of a declared composite index.\n * Composite coverage is sufficient for the missing-field check because\n * composite writes also maintain the in-memory mirror — the range /\n * orderBy / single-equality lookup paths fall through to decrypted\n * candidates that still get post-filtered by the composite clause.\n */\nfunction isFieldIndexed(field: string, idx: PersistedCollectionIndex): boolean {\n if (idx.has(field)) return true\n for (const def of idx.definitions()) {\n if (def.kind === 'composite' && def.fields.includes(field)) return true\n }\n return false\n}\n\nfunction isRangeOp(op: Operator): op is '<' | '<=' | '>' | '>=' | 'between' {\n return op === '<' || op === '<=' || op === '>' || op === '>=' || op === 'between'\n}\n\nfunction collectTouchedFields(plan: LazyPlan): string[] {\n const seen = new Set<string>()\n for (const c of plan.clauses) seen.add(c.field)\n for (const o of plan.orderBy) seen.add(o.field)\n return [...seen]\n}\n\nfunction matchesAll(record: unknown, clauses: readonly Clause[]): boolean {\n for (const c of clauses) {\n if (!evaluateClause(record, c)) return false\n }\n return true\n}\n\nfunction sortRecords<T>(records: T[], orderBy: readonly LazyOrderBy[], via?: ViaPipeline): T[] {\n return [...records].sort((a, b) => {\n for (const { field, direction } of orderBy) {\n const av = readPath(a, field)\n const bv = readPath(b, field)\n // #695: a Via-covered field (e.g. money) may store a representation\n // the generic comparator would order wrong — ask the pipeline for an\n // exact ordering first, same as eager's `sortRecords` in\n // `kernel/query/builder.ts`. `undefined` (no via, or the field isn't\n // covered) falls back to the generic comparator, unchanged from today.\n const viaCmp = via?.compareForOrder(field, av, bv)\n const cmp = viaCmp !== undefined ? viaCmp : compareValues(av, bv)\n if (cmp !== 0) return direction === 'asc' ? cmp : -cmp\n }\n return 0\n })\n}\n\nfunction compareValues(a: unknown, b: unknown): number {\n if (a === undefined || a === null) return b === undefined || b === null ? 0 : 1\n if (b === undefined || b === null) return -1\n if (typeof a === 'number' && typeof b === 'number') return a - b\n if (typeof a === 'string' && typeof b === 'string') return a < b ? -1 : a > b ? 1 : 0\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime()\n return 0\n}\n"],"mappings":"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","names":["ids"]}
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  liveRecordIsElevated
3
- } from "./chunk-PTT2NB46.js";
3
+ } from "./chunk-JYJFGD2H.js";
4
4
  import {
5
5
  isRewrappedUnder,
6
6
  openEnvelopeJson,
7
7
  rewrapEnvelope
8
- } from "./chunk-MMVQ3SUO.js";
8
+ } from "./chunk-RZPOZPZU.js";
9
9
  import {
10
10
  isTombstone,
11
11
  isTombstoneShape
12
- } from "./chunk-KCZAFDP5.js";
12
+ } from "./chunk-VH6SOCXH.js";
13
13
  import {
14
14
  NOYDB_FORMAT_VERSION
15
- } from "./chunk-DOZFU7OZ.js";
15
+ } from "./chunk-GZACYEOB.js";
16
16
  import {
17
17
  ReadOnlyAtInstantError
18
- } from "./chunk-6SYOHUHM.js";
18
+ } from "./chunk-QZWTRENR.js";
19
19
 
20
20
  // src/with-commit/history/history.ts
21
21
  var HISTORY_COLLECTION = "_history";
@@ -330,4 +330,4 @@ export {
330
330
  VaultInstant,
331
331
  CollectionInstant
332
332
  };
333
- //# sourceMappingURL=chunk-3GXDB3NQ.js.map
333
+ //# sourceMappingURL=chunk-MANUDU7I.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DerivationCapExceededError,
3
3
  DerivationOutputShapeError
4
- } from "./chunk-6SYOHUHM.js";
4
+ } from "./chunk-QZWTRENR.js";
5
5
 
6
6
  // src/with-formula/derivations/executor.ts
7
7
  var DerivationExecutor = {
@@ -121,4 +121,4 @@ var DerivationExecutor = {
121
121
  export {
122
122
  DerivationExecutor
123
123
  };
124
- //# sourceMappingURL=chunk-YJ3TREAC.js.map
124
+ //# sourceMappingURL=chunk-MHMLXJ3I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/derivations/executor.ts"],"sourcesContent":["import { DerivationCapExceededError, DerivationOutputShapeError } from '../../kernel/errors.js'\nimport type { DerivationContext, DerivationSpec, DerivedFromMeta } from './types.js'\n\nexport interface RunResult {\n outputs: Record<string, OutputResult>\n failed: boolean\n}\n\n/**\n * Per-output result of a strategy invocation. Discriminated by\n * `kind`:\n *\n * - `record` — the existing v1 shape: one value (or a \"skipped\"\n * marker if the output was optional and `derive` returned null).\n * - `array` — a list of `(key, value)` entries.\n * The caller diffs these against the previously-emitted key set\n * (loaded from the fanout sidecar) to compute deletes + upserts.\n */\nexport type OutputResult =\n | RecordOutputResult\n | ArrayOutputResult\n | FailedOutputResult\n\nexport interface RecordOutputResult {\n kind: 'record'\n value: Record<string, unknown>\n ok: true\n /**\n * `true` when an optional output returned `null` /\n * `undefined`. The caller deletes any previously-emitted output at\n * the same id (mirrors \"tombstone for derived data\"); a never-emitted\n * output is a silent no-op. `ok: true` because skipping is a\n * successful outcome, not a failure.\n */\n skipped?: boolean\n}\n\nexport interface ArrayOutputResult {\n kind: 'array'\n ok: true\n /** One `(key, value)` per derived row. Empty array means \"all prior outputs for this source go.\" */\n entries: ReadonlyArray<{ readonly key: string; readonly value: Record<string, unknown> }>\n}\n\nexport interface FailedOutputResult {\n kind: 'failed'\n ok: false\n error: Error\n /** Always empty on failure; present so consumers don't have to narrow. */\n value: Record<string, unknown>\n}\n\n/**\n * Stateless functions that execute a derivation strategy. Persistence\n * (encrypt + store.put) is the caller's job — typically\n * `DerivationRegistry.onSourceWrite` which iterates run() results and\n * writes each output via `Collection.put`.\n */\nexport const DerivationExecutor = {\n /**\n * Run `derive` once, validate output shape against the spec, stamp\n * `_derivedFrom` onto every output. Returns per-output success or\n * failure; throws only for shape mismatches (a contract violation).\n */\n async run<\n TSource extends Record<string, unknown>,\n TOutputs extends Record<string, Record<string, unknown> | ReadonlyArray<Record<string, unknown>>>,\n >(\n strategy: DerivationSpec<TSource, TOutputs>,\n source: TSource & { id: string },\n sourceVersion: number,\n strategyHash: string,\n ctx: DerivationContext,\n ): Promise<RunResult> {\n const outputs: Record<string, OutputResult> = {}\n let derived: Partial<TOutputs>\n\n try {\n derived = await Promise.resolve(strategy.derive(source as TSource, ctx))\n } catch (err) {\n for (const key of Object.keys(strategy.outputs)) {\n outputs[key] = {\n kind: 'failed',\n value: {},\n ok: false,\n error: err instanceof Error ? err : new Error(String(err)),\n }\n }\n return { outputs, failed: true }\n }\n\n const meta: DerivedFromMeta = {\n source: strategy.source,\n sourceId: source.id,\n sourceVersion,\n derivedAt: new Date().toISOString(),\n strategyHash,\n }\n\n for (const key of Object.keys(strategy.outputs)) {\n const outSpec = strategy.outputs[key]\n if (!outSpec) continue\n const value = (derived as Record<string, unknown>)[key]\n\n // ── Array-shape branch ─────────────────────────────────────\n if (outSpec.shape === 'array') {\n if (value === undefined || value === null) {\n // Treat null/undefined as \"empty array\" — clears all prior\n // outputs for this (source, output) pair. The caller's\n // diff turns that into deletes.\n outputs[key] = { kind: 'array', ok: true, entries: [] }\n continue\n }\n if (!Array.isArray(value)) {\n throw new DerivationOutputShapeError(\n key,\n `shape 'array' expects an array, got ${typeof value}`,\n )\n }\n const maxFanout = outSpec.maxFanout ?? 64\n if (value.length > maxFanout) {\n throw new DerivationCapExceededError(key, value.length, maxFanout)\n }\n const entries: Array<{ key: string; value: Record<string, unknown> }> = []\n const seenKeys = new Set<string>()\n for (let i = 0; i < value.length; i++) {\n const row = value[i] as unknown\n if (row === null || typeof row !== 'object') {\n throw new DerivationOutputShapeError(\n key,\n `array member at index ${i} must be a non-null object (got ${row === null ? 'null' : typeof row})`,\n )\n }\n let derivedKey: string\n try {\n derivedKey = outSpec.key(row as Record<string, unknown>)\n } catch (err) {\n throw new DerivationOutputShapeError(\n key,\n `key extractor threw on array member at index ${i}: `\n + (err instanceof Error ? err.message : String(err)),\n )\n }\n if (typeof derivedKey !== 'string' || derivedKey.length === 0) {\n throw new DerivationOutputShapeError(\n key,\n `key extractor returned ${typeof derivedKey === 'string' ? 'empty string' : typeof derivedKey} at index ${i}; expected non-empty string`,\n )\n }\n if (seenKeys.has(derivedKey)) {\n throw new DerivationOutputShapeError(\n key,\n `duplicate key \"${derivedKey}\" in array output (index ${i}); each derived row must have a unique key within a single derive() invocation`,\n )\n }\n seenKeys.add(derivedKey)\n entries.push({\n key: derivedKey,\n value: { ...(row as Record<string, unknown>), _derivedFrom: meta },\n })\n }\n outputs[key] = { kind: 'array', ok: true, entries }\n continue\n }\n\n // ── Record-shape branch (existing v1 behavior) ─────────────\n if (value === undefined || value === null) {\n if (outSpec.optional === true) {\n // Optional output explicitly skipped. Mark for caller\n // so any prior-emitted output at this id can be deleted.\n outputs[key] = { kind: 'record', value: {}, ok: true, skipped: true }\n continue\n }\n throw new DerivationOutputShapeError(\n key,\n `expected object, got ${value === undefined ? 'undefined' : 'null'}`,\n )\n }\n if (typeof value !== 'object') {\n throw new DerivationOutputShapeError(\n key,\n `expected object, got ${typeof value}`,\n )\n }\n outputs[key] = {\n kind: 'record',\n value: { ...(value as Record<string, unknown>), _derivedFrom: meta },\n ok: true,\n }\n }\n return { outputs, failed: false }\n },\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-6SYOHUHM.js";
3
+ } from "./chunk-QZWTRENR.js";
4
4
 
5
5
  // src/with-formula/overlay-views/with-overlayed-view.ts
6
6
  function withOverlayedView(spec) {
@@ -33,4 +33,4 @@ function withOverlayedView(spec) {
33
33
  export {
34
34
  withOverlayedView
35
35
  };
36
- //# sourceMappingURL=chunk-D4LAJ737.js.map
36
+ //# sourceMappingURL=chunk-MSMJJB4J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/overlay-views/with-overlayed-view.ts"],"sourcesContent":["import { ValidationError } from '../../kernel/errors.js'\nimport type { OverlayedViewSpec, OverlayedViewStrategy } from './types.js'\n\n/**\n * Register a read-shadow overlay: bind an MV-owned base collection to\n * a user-writable overlay so consumers can express operator-editable\n * lifecycles as one declarative block.\n *\n * See docs/superpowers/specs/2026-05-20-dim14-mv-v2-design.md.\n */\nexport function withOverlayedView(\n spec: OverlayedViewSpec,\n): OverlayedViewStrategy {\n if (!spec.name || spec.name.length === 0) {\n throw new ValidationError('withOverlayedView: name is required')\n }\n if (!spec.base || spec.base.length === 0) {\n throw new ValidationError('withOverlayedView: base is required')\n }\n if (!spec.overlay || spec.overlay.length === 0) {\n throw new ValidationError('withOverlayedView: overlay is required')\n }\n if (spec.base === spec.overlay) {\n throw new ValidationError('withOverlayedView: base and overlay must be different collections')\n }\n if (spec.base === spec.name || spec.overlay === spec.name) {\n throw new ValidationError(\n 'withOverlayedView: virtual name must differ from both base and overlay collection names',\n )\n }\n if (!spec.shadowField || spec.shadowField.length === 0) {\n throw new ValidationError('withOverlayedView: shadowField is required')\n }\n return {\n __noydb_strategy: 'overlayed-view',\n spec,\n }\n}\n"],"mappings":";;;;;AAUO,SAAS,kBACd,MACuB;AACvB,MAAI,CAAC,KAAK,QAAQ,KAAK,KAAK,WAAW,GAAG;AACxC,UAAM,IAAI,gBAAgB,qCAAqC;AAAA,EACjE;AACA,MAAI,CAAC,KAAK,QAAQ,KAAK,KAAK,WAAW,GAAG;AACxC,UAAM,IAAI,gBAAgB,qCAAqC;AAAA,EACjE;AACA,MAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,WAAW,GAAG;AAC9C,UAAM,IAAI,gBAAgB,wCAAwC;AAAA,EACpE;AACA,MAAI,KAAK,SAAS,KAAK,SAAS;AAC9B,UAAM,IAAI,gBAAgB,mEAAmE;AAAA,EAC/F;AACA,MAAI,KAAK,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,MAAM;AACzD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,KAAK,eAAe,KAAK,YAAY,WAAW,GAAG;AACtD,UAAM,IAAI,gBAAgB,4CAA4C;AAAA,EACxE;AACA,SAAO;AAAA,IACL,kBAAkB;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MaterializedViewConfigError,
3
3
  ValidationError
4
- } from "./chunk-6SYOHUHM.js";
4
+ } from "./chunk-QZWTRENR.js";
5
5
 
6
6
  // src/with-formula/materialized-views/with-materialized-view.ts
7
7
  function withMaterializedView(spec) {
@@ -177,4 +177,4 @@ function withMaterializedView(spec) {
177
177
  export {
178
178
  withMaterializedView
179
179
  };
180
- //# sourceMappingURL=chunk-RM5EXCFF.js.map
180
+ //# sourceMappingURL=chunk-MXUT7FTE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/materialized-views/with-materialized-view.ts"],"sourcesContent":["import { MaterializedViewConfigError, ValidationError } from '../../kernel/errors.js'\nimport type { MaterializedViewSpec, MaterializedViewStrategy } from './types.js'\n\n/**\n * Register a materialized view: a declared query whose result is\n * persisted as a queryable collection and kept fresh as sources\n * change. Writes go through the standard `Collection.put` pipeline;\n * refresh-driven deletes route through `Collection._internalDelete` so\n * user `onDelete` guards on the output collection aren't tripped by\n * housekeeping.\n *\n * Three registration modes:\n * - **single-source** — declare `query: (db) => Query<TRow>`; the\n * dependency analyzer derives source collections from the plan.\n * - **UNION** — declare `unionSources: [{ collection, map }, ...]`\n * plus optional `groupBy` + `aggregate`; the executor reads each\n * arm, maps to the unified row shape, concatenates, then groups\n * and aggregates.\n * - **projection** (#810) — declare `projection: { source, joins,\n * map }`; one output row per primary record, enriched with\n * forward FK legs and reverse \"collect\" legs before `map` runs.\n *\n * The three modes are mutually exclusive — exactly one of `query` /\n * `unionSources` / `projection` must be set at registration time.\n *\n * See docs/superpowers/specs/2026-05-20-dim14-mv-v2-design.md (single-source v2),\n * docs/superpowers/specs/2026-05-21-dim14-mv-multikey-and-union.md (UNION),\n * and docs/superpowers/specs/2026-07-25-join-projection-mv-design.md (projection).\n */\nexport function withMaterializedView<TRow extends Record<string, unknown>>(\n spec: MaterializedViewSpec<TRow>,\n): MaterializedViewStrategy {\n if (!spec.name || spec.name.length === 0) {\n throw new ValidationError('withMaterializedView: name is required')\n }\n // Mutual exclusion: exactly one of the three forms must be declared.\n const declaredForms = [spec.query, spec.unionSources, spec.projection]\n .filter((f) => f !== undefined).length\n if (declaredForms > 1) {\n throw new MaterializedViewConfigError(\n 'query, unionSources, and projection are mutually exclusive — pick one',\n )\n }\n if (declaredForms === 0) {\n throw new MaterializedViewConfigError(\n 'strategy must declare exactly one of query, unionSources, or projection',\n )\n }\n if (spec.query !== undefined && typeof spec.query !== 'function') {\n throw new ValidationError('withMaterializedView: query must be a function returning a Query<T>')\n }\n // UNION-form invariants.\n if (spec.unionSources) {\n // A single arm is a deliberate shape: map→group→aggregate over\n // ONE collection with a COMPUTED bucket key (e.g. month sliced from a\n // date field) — something the query form's stored-field groupBy cannot\n // express. The executor and dependency analyzer are arm-count-agnostic.\n if (spec.unionSources.length < 1) {\n throw new MaterializedViewConfigError(\n 'unionSources requires at least 1 source collection',\n )\n }\n const seen = new Set<string>()\n for (const s of spec.unionSources) {\n if (typeof s?.collection !== 'string' || s.collection.length === 0) {\n throw new MaterializedViewConfigError(\n 'each unionSources entry must declare a non-empty `collection` string',\n )\n }\n if (typeof s.map !== 'function') {\n throw new MaterializedViewConfigError(\n `unionSources entry for \"${s.collection}\" is missing a \\`map\\` function`,\n )\n }\n if (seen.has(s.collection)) {\n throw new MaterializedViewConfigError(\n `unionSources must reference distinct collections (duplicate: \"${s.collection}\")`,\n )\n }\n seen.add(s.collection)\n }\n if (Array.isArray(spec.groupBy) && spec.groupBy.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": groupBy must not be an empty array — omit it or provide at least one field name`,\n )\n }\n if (spec.aggregate && !spec.groupBy) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": UNION strategy with aggregate requires groupBy — `\n + `use groupBy to declare the bucketing keys, or remove aggregate for a pure dedup MV`,\n )\n }\n // `moneyFields` only has meaning when there's an aggregate to\n // money-rewrite — it keys reducer outputs, so declaring it without\n // `aggregate` is a no-op config mistake.\n if (spec.moneyFields && !spec.aggregate) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": moneyFields requires aggregate — `\n + `moneyFields rewrites sum/min/max reducers over money output fields, `\n + `so it is meaningless without an aggregate spec`,\n )\n }\n // Per-arm joins resolve right-side collections that the union\n // dependency set (built from arm `collection`s alone) does NOT\n // include. The consumer must list those right-side collections in\n // `sources` so writes to them trigger MV refresh.\n if (spec.unionSources.some(s => s.join && s.join.length > 0) && (!spec.sources || spec.sources.length === 0)) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": a unionSources arm declares join(s) but `\n + `no \\`sources\\` are listed — declare sources: [...] with the right-side `\n + `(join-target) collection names so writes to them trigger MV refresh`,\n )\n }\n if (spec.predicates) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": predicates are not supported on UNION strategies — `\n + `UNION mode does not use a Query<T> chain, so .wherePredicate() cannot fire. `\n + `Use the query() form, or open an issue if per-arm predicates are needed`,\n )\n }\n }\n // Projection-form invariants (#810). Shape checks only — the\n // semantic ref() check on collect legs (the `on` field must carry a\n // ref() targeting the projection source) runs at first\n // materialization, parity with join-time ref errors.\n if (spec.projection) {\n const projection = spec.projection\n if (typeof projection.source !== 'string' || projection.source.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": projection.source must be a non-empty collection name`,\n )\n }\n if (typeof projection.map !== 'function') {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": projection is missing a \\`map\\` function`,\n )\n }\n if (!Array.isArray(projection.joins) || projection.joins.length < 1) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": projection.joins must declare at least 1 leg — `\n + `a leg-less single-source MV is the query() form's job`,\n )\n }\n const seenAs = new Set<string>()\n for (const leg of projection.joins) {\n const l = leg as { field?: unknown; collect?: unknown; on?: unknown; as?: unknown }\n const isForward = l.field !== undefined\n const isCollect = l.collect !== undefined\n if (isForward && isCollect) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": a projection leg cannot declare both \\`field\\` `\n + `(forward) and \\`collect\\` (reverse) — split it into two legs`,\n )\n }\n if (!isForward && !isCollect) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": each projection leg must declare either \\`field\\` `\n + `(forward FK) or \\`collect\\` (reverse one-to-many)`,\n )\n }\n if (isForward && (typeof l.field !== 'string' || l.field.length === 0)) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": a forward projection leg must declare a non-empty \\`field\\``,\n )\n }\n if (isCollect) {\n if (typeof l.collect !== 'string' || l.collect.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": a collect projection leg must declare a non-empty \\`collect\\` collection name`,\n )\n }\n if (typeof l.on !== 'string' || l.on.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": collect leg for \"${l.collect}\" must declare a non-empty \\`on\\` FK field`,\n )\n }\n }\n if (typeof l.as !== 'string' || l.as.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": each projection leg must declare a non-empty \\`as\\` alias`,\n )\n }\n if (seenAs.has(l.as)) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": projection legs must attach under distinct \\`as\\` aliases (duplicate: \"${l.as}\")`,\n )\n }\n seenAs.add(l.as)\n }\n // Post-map grouping invariants — same rules as UNION (the mapped\n // stream feeds the same shared groupAndReduce tail).\n if (Array.isArray(spec.groupBy) && spec.groupBy.length === 0) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": groupBy must not be an empty array — omit it or provide at least one field name`,\n )\n }\n if (spec.aggregate && !spec.groupBy) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": projection strategy with aggregate requires groupBy — `\n + `use groupBy to declare the bucketing keys, or remove aggregate for a row-per-primary-record MV`,\n )\n }\n if (spec.moneyFields && !spec.aggregate) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": moneyFields requires aggregate — `\n + `moneyFields rewrites sum/min/max reducers over money output fields, `\n + `so it is meaningless without an aggregate spec`,\n )\n }\n if (spec.predicates) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": predicates are not supported on projection strategies — `\n + `projection mode does not use a Query<T> chain, so .wherePredicate() cannot fire. `\n + `Filter inside projection.map (return null to omit) instead`,\n )\n }\n }\n // i18nLocale + i18nFields drive compute-time i18n resolution of group-key\n // i18nText fields before bucketing — UNION mode (resolved on the unified rows)\n // AND query mode (resolved in GroupedReduction.run before groupAndReduce).\n // i18nLocale without i18nFields cannot resolve anything, so reject it early.\n if (spec.i18nLocale !== undefined && spec.i18nFields === undefined) {\n throw new MaterializedViewConfigError(\n `withMaterializedView \"${spec.name}\": i18nLocale requires i18nFields — `\n + `declare the i18nText descriptors of the group-key fields so they can be `\n + `resolved at the mv layer before bucketing.`,\n )\n }\n if (typeof spec.rowKey !== 'function') {\n throw new ValidationError('withMaterializedView: rowKey is required (no default; see spec § Type surface)')\n }\n if (spec.refresh !== 'eager' && spec.refresh !== 'lazy' && spec.refresh !== 'manual') {\n throw new ValidationError(\n `withMaterializedView: refresh must be 'eager' | 'lazy' | 'manual', got \"${String(spec.refresh)}\"`,\n )\n }\n return {\n __noydb_strategy: 'materialized-view',\n spec,\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  PERIODS_COLLECTION
3
- } from "./chunk-TMR64XPL.js";
3
+ } from "./chunk-EZNTORXE.js";
4
4
  import {
5
5
  canonicalJson,
6
6
  sha256Hex
7
- } from "./chunk-2BVW754E.js";
7
+ } from "./chunk-ISRKW4YN.js";
8
8
  import {
9
9
  PeriodClosedError,
10
10
  ValidationError
11
- } from "./chunk-6SYOHUHM.js";
11
+ } from "./chunk-QZWTRENR.js";
12
12
 
13
13
  // src/with-audit/periods/strategy.ts
14
14
  var NOT_ENABLED = new Error(
@@ -79,7 +79,7 @@ function validatePeriodName(name, existing) {
79
79
  }
80
80
  async function appendPeriodLedgerEntry(ledger, actor, envelope, name, collection = PERIODS_COLLECTION) {
81
81
  if (!ledger) return;
82
- const { envelopePayloadHash } = await import("./ledger-K6JBFL3Z.js");
82
+ const { envelopePayloadHash } = await import("./ledger-XY6NP3J2.js");
83
83
  await ledger.append({
84
84
  op: "put",
85
85
  collection,
@@ -98,4 +98,4 @@ export {
98
98
  validatePeriodName,
99
99
  appendPeriodLedgerEntry
100
100
  };
101
- //# sourceMappingURL=chunk-IUATR5UE.js.map
101
+ //# sourceMappingURL=chunk-N5PLUFH2.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  envelopePayloadHash
3
- } from "./chunk-2BVW754E.js";
3
+ } from "./chunk-ISRKW4YN.js";
4
4
  import {
5
5
  NOYDB_FORMAT_VERSION
6
- } from "./chunk-DOZFU7OZ.js";
6
+ } from "./chunk-GZACYEOB.js";
7
7
  import {
8
8
  DictKeyMissingError,
9
9
  PermissionDeniedError
10
- } from "./chunk-6SYOHUHM.js";
10
+ } from "./chunk-QZWTRENR.js";
11
11
 
12
12
  // src/via/lookup/handle.ts
13
13
  function isDeleteMarker(envelope) {
@@ -389,4 +389,4 @@ export {
389
389
  dictCollectionName,
390
390
  LookupHandle
391
391
  };
392
- //# sourceMappingURL=chunk-C2V7AJO2.js.map
392
+ //# sourceMappingURL=chunk-NEX7JCMO.js.map
@@ -2,7 +2,7 @@ import {
2
2
  decrypt,
3
3
  deriveSealedFieldKey,
4
4
  deriveSealedFieldKeyFromCek
5
- } from "./chunk-7U6AB7DZ.js";
5
+ } from "./chunk-AKKRXT23.js";
6
6
 
7
7
  // src/kernel/enclave/record-keys/sealed-slot.ts
8
8
  function parseSealedSlot(blob) {
@@ -26,4 +26,4 @@ export {
26
26
  parseSealedSlot,
27
27
  dualReadSealedSlot
28
28
  };
29
- //# sourceMappingURL=chunk-5HSSTOOG.js.map
29
+ //# sourceMappingURL=chunk-NFZGZ4AK.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5D2ALSM5.js";
4
4
 
5
5
  // src/with-formula/derivations/stale.ts
6
- var loadDerivationExecutor = lazy(() => import("./executor-FCJEH3FU.js"));
6
+ var loadDerivationExecutor = lazy(() => import("./executor-IEBLTBCW.js"));
7
7
  var _staleByRegistry = /* @__PURE__ */ new WeakMap();
8
8
  var keyFor = (source, sourceId) => `${source}/${sourceId}`;
9
9
  async function markStale(registry, strategy, sourceId) {
@@ -78,4 +78,4 @@ export {
78
78
  markStale,
79
79
  resolveStaleOnRead
80
80
  };
81
- //# sourceMappingURL=chunk-5ABOFAHN.js.map
81
+ //# sourceMappingURL=chunk-NJ4DYYO5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/derivations/stale.ts"],"sourcesContent":["import type { Collection } from '../../kernel/collection.js'\nimport type { DerivationExecutor as DerivationExecutorType } from './executor.js'\nimport type { ReadOnlyVaultFacade } from '../../with-audit/guards/types.js'\nimport type { TxContext } from '../../with-commit/tx/transaction.js'\nimport type { DerivationRegistry } from './registry.js'\n// Type-only — runtime class loaded via dynamic import in\n// `resolveStaleOnRead` only when a stale flag actually fires. Keeps\n// the executor chunk out of the floor bundle.\nimport type { DerivationSpec } from './types.js'\n\nimport { lazy } from '../../kernel/lazy.js'\n\n/** #846c — one memoized binding instead of a cast at the call site. */\nconst loadDerivationExecutor = lazy(() => import('./executor.js'))\n\n/**\n * Accessor shape passed through from the owning Vault. Provides the\n * registry (used to look up strategies and as the WeakMap key) and a\n * resolver from collection name to the live `Collection` instance.\n * Same shape as `Collection.derivationSource` so callers can pass it\n * through directly.\n */\nexport interface DerivationStaleAccessor {\n registry(): DerivationRegistry\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getCollection(name: string): Collection<any>\n /**\n * Read-only vault facade handed to `derive(source, ctx)` on the lazy\n * resolve-on-read path. Same instance/shape as the eager path uses.\n */\n getReadOnlyFacade(): ReadOnlyVaultFacade\n /**\n * Active multi-record TxContext or `null`. The lazy resolve-on-read\n * path uses this to register tombstone deletes on `_executed` so a\n * later rollback restores the prior emission. Mirrors the eager\n * path's rollback tracking; the lazy `put` was historically\n * unregistered but the tombstone delete (a NEW write path)\n * matches the eager registration for symmetry.\n */\n getActiveTxContext(): TxContext | null\n}\n\n/**\n * In-memory stale map keyed by `DerivationRegistry` instance (stable\n * per vault). Maps `${source}/${sourceId}` → set of pending strategies.\n *\n * Persistence across vault close is NOT implemented in v1 (concern\n * flagged in the dim14 spec). On vault re-open, derived records'\n * `_derivedFrom.strategyHash` will still match the registered\n * strategies' hash, so an unset stale flag is interpreted as \"fresh.\"\n * `vault.deriveAll()` (Task D13) is the explicit recompute escape\n * hatch.\n *\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst _staleByRegistry = new WeakMap<DerivationRegistry, Map<string, Set<DerivationSpec<any, any>>>>()\n\nconst keyFor = (source: string, sourceId: string): string => `${source}/${sourceId}`\n\n/** Mark every output of (strategy, sourceId) as stale. */\nexport async function markStale(\n registry: DerivationRegistry,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n strategy: DerivationSpec<any, any>,\n sourceId: string,\n): Promise<void> {\n let map = _staleByRegistry.get(registry)\n if (!map) {\n map = new Map()\n _staleByRegistry.set(registry, map)\n }\n const k = keyFor(strategy.source, sourceId)\n let set = map.get(k)\n if (!set) {\n set = new Set()\n map.set(k, set)\n }\n set.add(strategy)\n}\n\n/**\n * Called from `Collection.get` on lazy-mode output collections. If the\n * id has a pending stale flag for any strategy producing this output\n * collection, re-derive before returning the record. No-op when there\n * is no pending work — keeps the read fast path negligible.\n */\nexport async function resolveStaleOnRead(\n accessor: DerivationStaleAccessor,\n outputCollection: string,\n id: string,\n): Promise<void> {\n const registry = accessor.registry()\n const producers = registry.strategiesProducingOutput(outputCollection)\n if (producers.length === 0) return\n\n const map = _staleByRegistry.get(registry)\n if (!map) return\n\n // Dynamic-import the executor only when at least one stale flag\n // actually fires. Vaults with no derivation strategies never call\n // this function (gated on `derivationSource` in `Collection.get`);\n // vaults with strategies but no pending stale ids reach the\n // `pending.has(spec)` short-circuit below without ever touching\n // the executor chunk.\n let DerivationExecutor: typeof DerivationExecutorType | null = null\n\n for (const { spec, strategyHash } of producers) {\n const k = keyFor(spec.source, id)\n const pending = map.get(k)\n if (!pending || !pending.has(spec)) continue\n\n // Read the source record from the source collection and re-derive.\n // We use the same getCollection accessor that eager dispatch uses\n // — it returns the live `Collection<any>` instance with full\n // crypto / keyring wiring.\n const sourceColl = accessor.getCollection(spec.source)\n const source = await sourceColl.get(id)\n if (!source) {\n pending.delete(spec)\n continue\n }\n const sourceWithId = { ...(source as Record<string, unknown>), id } as Record<string, unknown> & { id: string }\n // sourceVersion: not tracked in v1 stale map; pass 0 — matches the\n // forthcoming v0 semantics, `_derivedFrom.sourceVersion` is\n // informational, not load-bearing for correctness.\n DerivationExecutor ??= (await loadDerivationExecutor()).DerivationExecutor\n const ctx = { vault: accessor.getReadOnlyFacade() }\n const result = await DerivationExecutor.run(spec, sourceWithId, 0, strategyHash, ctx)\n for (const key of Object.keys(spec.outputs)) {\n const out = result.outputs[key]\n if (!out) continue\n if (out.kind === 'failed') {\n const err = out.error\n if (spec.strict) {\n // Leave the stale flag set so a future read retries.\n throw err\n }\n console.warn(\n `[derivation] lazy output \"${key}\" for source \"${spec.source}\" id=\"${id}\" failed:`,\n err,\n )\n continue\n }\n if (out.kind === 'array') {\n // Defensive — array-shape requires `lifecycle: 'eager'`\n // (validated at withDerivation registration).\n // Reaching the lazy-resolve path for array-shape would mean\n // a registration check was bypassed. Log and skip.\n console.warn(\n `[derivation] unexpected array-shape output \"${key}\" in lazy resolve path; `\n + 'array-shape derivations require lifecycle: \"eager\".',\n )\n continue\n }\n const outSpec = spec.outputs[key]\n if (!outSpec) continue\n const outputColl = accessor.getCollection(outSpec.collection)\n if (out.skipped === true) {\n // Optional output skipped on lazy resolve — delete any\n // prior emission so the read returns null (matches eager-path\n // tombstone semantics). Routed through `_internalDelete` so a\n // user-registered `onDelete` on the output collection\n // does NOT fire. The active TxContext (if any) is forwarded:\n // `resolveStaleOnRead` is reachable from `Collection.get()`\n // which can be called from inside a transaction, so the\n // tombstone must be observable to `revertExecuted` on\n // rollback.\n await outputColl._internalDelete(id, accessor.getActiveTxContext())\n continue\n }\n await outputColl.put(id, out.value)\n }\n pending.delete(spec)\n }\n}\n"],"mappings":";;;;;AAaA,IAAM,yBAAyB,KAAK,MAAM,OAAO,wBAAe,CAAC;AA2CjE,IAAM,mBAAmB,oBAAI,QAAwE;AAErG,IAAM,SAAS,CAAC,QAAgB,aAA6B,GAAG,MAAM,IAAI,QAAQ;AAGlF,eAAsB,UACpB,UAEA,UACA,UACe;AACf,MAAI,MAAM,iBAAiB,IAAI,QAAQ;AACvC,MAAI,CAAC,KAAK;AACR,UAAM,oBAAI,IAAI;AACd,qBAAiB,IAAI,UAAU,GAAG;AAAA,EACpC;AACA,QAAM,IAAI,OAAO,SAAS,QAAQ,QAAQ;AAC1C,MAAI,MAAM,IAAI,IAAI,CAAC;AACnB,MAAI,CAAC,KAAK;AACR,UAAM,oBAAI,IAAI;AACd,QAAI,IAAI,GAAG,GAAG;AAAA,EAChB;AACA,MAAI,IAAI,QAAQ;AAClB;AAQA,eAAsB,mBACpB,UACA,kBACA,IACe;AACf,QAAM,WAAW,SAAS,SAAS;AACnC,QAAM,YAAY,SAAS,0BAA0B,gBAAgB;AACrE,MAAI,UAAU,WAAW,EAAG;AAE5B,QAAM,MAAM,iBAAiB,IAAI,QAAQ;AACzC,MAAI,CAAC,IAAK;AAQV,MAAI,qBAA2D;AAE/D,aAAW,EAAE,MAAM,aAAa,KAAK,WAAW;AAC9C,UAAM,IAAI,OAAO,KAAK,QAAQ,EAAE;AAChC,UAAM,UAAU,IAAI,IAAI,CAAC;AACzB,QAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,IAAI,EAAG;AAMpC,UAAM,aAAa,SAAS,cAAc,KAAK,MAAM;AACrD,UAAM,SAAS,MAAM,WAAW,IAAI,EAAE;AACtC,QAAI,CAAC,QAAQ;AACX,cAAQ,OAAO,IAAI;AACnB;AAAA,IACF;AACA,UAAM,eAAe,EAAE,GAAI,QAAoC,GAAG;AAIlE,4BAAwB,MAAM,uBAAuB,GAAG;AACxD,UAAM,MAAM,EAAE,OAAO,SAAS,kBAAkB,EAAE;AAClD,UAAM,SAAS,MAAM,mBAAmB,IAAI,MAAM,cAAc,GAAG,cAAc,GAAG;AACpF,eAAW,OAAO,OAAO,KAAK,KAAK,OAAO,GAAG;AAC3C,YAAM,MAAM,OAAO,QAAQ,GAAG;AAC9B,UAAI,CAAC,IAAK;AACV,UAAI,IAAI,SAAS,UAAU;AACzB,cAAM,MAAM,IAAI;AAChB,YAAI,KAAK,QAAQ;AAEf,gBAAM;AAAA,QACR;AACA,gBAAQ;AAAA,UACN,6BAA6B,GAAG,iBAAiB,KAAK,MAAM,SAAS,EAAE;AAAA,UACvE;AAAA,QACF;AACA;AAAA,MACF;AACA,UAAI,IAAI,SAAS,SAAS;AAKxB,gBAAQ;AAAA,UACN,+CAA+C,GAAG;AAAA,QAEpD;AACA;AAAA,MACF;AACA,YAAM,UAAU,KAAK,QAAQ,GAAG;AAChC,UAAI,CAAC,QAAS;AACd,YAAM,aAAa,SAAS,cAAc,QAAQ,UAAU;AAC5D,UAAI,IAAI,YAAY,MAAM;AAUxB,cAAM,WAAW,gBAAgB,IAAI,SAAS,mBAAmB,CAAC;AAClE;AAAA,MACF;AACA,YAAM,WAAW,IAAI,IAAI,IAAI,KAAK;AAAA,IACpC;AACA,YAAQ,OAAO,IAAI;AAAA,EACrB;AACF;","names":[]}
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  assertTierAccess,
3
3
  dekKey
4
- } from "./chunk-LC7DSMHR.js";
4
+ } from "./chunk-PTHKZWEH.js";
5
5
  import {
6
6
  liveRecordIsElevated,
7
7
  liveRecordTier
8
- } from "./chunk-PTT2NB46.js";
8
+ } from "./chunk-JYJFGD2H.js";
9
9
  import {
10
10
  openEnvelopeJson,
11
11
  writeEnvelopeBody
12
- } from "./chunk-MMVQ3SUO.js";
12
+ } from "./chunk-RZPOZPZU.js";
13
13
  import {
14
14
  base64ToBuffer,
15
15
  bufferToBase64,
@@ -21,10 +21,10 @@ import {
21
21
  sha256Hex,
22
22
  unwrapCek,
23
23
  wrapCek
24
- } from "./chunk-7U6AB7DZ.js";
24
+ } from "./chunk-AKKRXT23.js";
25
25
  import {
26
26
  NOYDB_FORMAT_VERSION
27
- } from "./chunk-DOZFU7OZ.js";
27
+ } from "./chunk-GZACYEOB.js";
28
28
  import {
29
29
  BlobIntentPendingError,
30
30
  BlobOfflineError,
@@ -34,7 +34,7 @@ import {
34
34
  TierNotGrantedError,
35
35
  UnsupportedTierCompositionError,
36
36
  ValidationError
37
- } from "./chunk-6SYOHUHM.js";
37
+ } from "./chunk-QZWTRENR.js";
38
38
 
39
39
  // src/with-shape/blobs/blob-pinning.ts
40
40
  function memoryBlobPinStore() {
@@ -476,7 +476,7 @@ var BlobSet = class _BlobSet {
476
476
  * DECLARED; a collection with an undeclared field (or no `blobFields` at
477
477
  * all) constructs fine and reaches this write path unguarded. Refuse the
478
478
  * write itself instead of broadening the construction mandate, which
479
- * would over-refuse blobless tiered collections (`blobStrategy` is
479
+ * would over-refuse blobless tiered collections (`blobsStrategy` is
480
480
  * vault-wide, not per-collection). Called from every content-write entry
481
481
  * (`put()`, `publish()`) — never from a read path, so a pre-existing
482
482
  * legacy blob stays readable (back-compat).
@@ -3069,4 +3069,4 @@ export {
3069
3069
  DEFAULT_CHUNK_SIZE,
3070
3070
  BlobSet
3071
3071
  };
3072
- //# sourceMappingURL=chunk-2ZSC454H.js.map
3072
+ //# sourceMappingURL=chunk-NQSO4UAH.js.map