@noy-db/hub 0.1.0-pre.9 → 0.2.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/aggregate/index.cjs +91 -36
  2. package/dist/aggregate/index.cjs.map +1 -1
  3. package/dist/aggregate/index.d.cts +2 -2
  4. package/dist/aggregate/index.d.ts +2 -2
  5. package/dist/aggregate/index.js +16 -9
  6. package/dist/aggregate/index.js.map +1 -1
  7. package/dist/blobs/index.cjs.map +1 -1
  8. package/dist/blobs/index.d.cts +6 -6
  9. package/dist/blobs/index.d.ts +6 -6
  10. package/dist/blobs/index.js +4 -4
  11. package/dist/bundle/index.cjs +298 -7
  12. package/dist/bundle/index.cjs.map +1 -1
  13. package/dist/bundle/index.d.cts +6 -6
  14. package/dist/bundle/index.d.ts +6 -6
  15. package/dist/bundle/index.js +15 -4
  16. package/dist/{chunk-GOUT6DND.js → chunk-23TTQXVO.js} +173 -91
  17. package/dist/chunk-23TTQXVO.js.map +1 -0
  18. package/dist/{chunk-CIMZBAZB.js → chunk-2AXFIYHT.js} +1 -1
  19. package/dist/chunk-2AXFIYHT.js.map +1 -0
  20. package/dist/chunk-34YSDCDP.js +73 -0
  21. package/dist/chunk-34YSDCDP.js.map +1 -0
  22. package/dist/{chunk-AVVPZ4BC.js → chunk-4TFSM22V.js} +4 -4
  23. package/dist/{chunk-QGZRWRSL.js → chunk-537VFZTR.js} +4 -4
  24. package/dist/{chunk-M62XNWRA.js → chunk-5DWL3JBF.js} +2 -2
  25. package/dist/{chunk-PTVMYYON.js → chunk-5SCJ5UEF.js} +3 -3
  26. package/dist/chunk-5ZGZ6HIZ.js +100 -0
  27. package/dist/chunk-5ZGZ6HIZ.js.map +1 -0
  28. package/dist/chunk-6HPZY4ON.js +291 -0
  29. package/dist/chunk-6HPZY4ON.js.map +1 -0
  30. package/dist/{chunk-EXHNQEV4.js → chunk-7H6DOO3E.js} +239 -11
  31. package/dist/chunk-7H6DOO3E.js.map +1 -0
  32. package/dist/{chunk-ACLDOTNQ.js → chunk-ADQ5MQ54.js} +275 -3
  33. package/dist/chunk-ADQ5MQ54.js.map +1 -0
  34. package/dist/chunk-CBAHB2BF.js +893 -0
  35. package/dist/chunk-CBAHB2BF.js.map +1 -0
  36. package/dist/chunk-DPMFBCV6.js +296 -0
  37. package/dist/chunk-DPMFBCV6.js.map +1 -0
  38. package/dist/chunk-DYBQG5PQ.js +34 -0
  39. package/dist/chunk-DYBQG5PQ.js.map +1 -0
  40. package/dist/{chunk-ZFKD4QMV.js → chunk-DYECX3IX.js} +3 -3
  41. package/dist/chunk-EGQYGYIU.js +51 -0
  42. package/dist/chunk-EGQYGYIU.js.map +1 -0
  43. package/dist/chunk-FCXOFQAJ.js +79 -0
  44. package/dist/chunk-FCXOFQAJ.js.map +1 -0
  45. package/dist/chunk-HB3Z2GCR.js +124 -0
  46. package/dist/chunk-HB3Z2GCR.js.map +1 -0
  47. package/dist/{chunk-SCZXXXU4.js → chunk-I6MX32UC.js} +7 -32
  48. package/dist/chunk-I6MX32UC.js.map +1 -0
  49. package/dist/{chunk-VQBTTTUN.js → chunk-KESP7GOK.js} +4 -4
  50. package/dist/{chunk-VQBTTTUN.js.map → chunk-KESP7GOK.js.map} +1 -1
  51. package/dist/{chunk-NXFEYLVG.js → chunk-MIQHZESA.js} +4 -3
  52. package/dist/{chunk-NXFEYLVG.js.map → chunk-MIQHZESA.js.map} +1 -1
  53. package/dist/chunk-MKSA2V7A.js +19 -0
  54. package/dist/chunk-MKSA2V7A.js.map +1 -0
  55. package/dist/{chunk-M5INGEFC.js → chunk-MRIBLZL3.js} +3 -1
  56. package/dist/chunk-MRIBLZL3.js.map +1 -0
  57. package/dist/{chunk-MDDTIZUO.js → chunk-NIOHFJPJ.js} +6 -6
  58. package/dist/chunk-OMLIZL2P.js +61 -0
  59. package/dist/chunk-OMLIZL2P.js.map +1 -0
  60. package/dist/{chunk-USKYUS74.js → chunk-P7EQ2S5O.js} +2 -2
  61. package/dist/{chunk-WDM5XGGS.js → chunk-PA6R5ZCI.js} +181 -11
  62. package/dist/chunk-PA6R5ZCI.js.map +1 -0
  63. package/dist/chunk-PEULZC6M.js +118 -0
  64. package/dist/chunk-PEULZC6M.js.map +1 -0
  65. package/dist/chunk-RD5LYKD6.js +82 -0
  66. package/dist/chunk-RD5LYKD6.js.map +1 -0
  67. package/dist/chunk-SIZWEV2Y.js +145 -0
  68. package/dist/chunk-SIZWEV2Y.js.map +1 -0
  69. package/dist/{chunk-QAVUREFT.js → chunk-UA4RI7OT.js} +12 -6
  70. package/dist/chunk-UA4RI7OT.js.map +1 -0
  71. package/dist/chunk-UMLVJTYV.js +20 -0
  72. package/dist/chunk-UMLVJTYV.js.map +1 -0
  73. package/dist/chunk-UZXLQCHP.js +53 -0
  74. package/dist/chunk-UZXLQCHP.js.map +1 -0
  75. package/dist/{chunk-2CSJGFCB.js → chunk-VMIO4IXG.js} +5 -5
  76. package/dist/{chunk-MR4424N3.js → chunk-WCA2NROQ.js} +2 -2
  77. package/dist/{chunk-TDR6T5CJ.js → chunk-XGSOTWYX.js} +91 -132
  78. package/dist/chunk-XGSOTWYX.js.map +1 -0
  79. package/dist/{chunk-NPC4LFV5.js → chunk-YMYK7US4.js} +2 -2
  80. package/dist/{chunk-RKJ6OL7K.js → chunk-YS3POABP.js} +1 -1
  81. package/dist/chunk-YS3POABP.js.map +1 -0
  82. package/dist/chunk-Z72JH4KG.js +209 -0
  83. package/dist/chunk-Z72JH4KG.js.map +1 -0
  84. package/dist/{chunk-R36SIKES.js → chunk-ZNOEIM6Y.js} +2 -2
  85. package/dist/consent/index.cjs.map +1 -1
  86. package/dist/consent/index.d.cts +6 -6
  87. package/dist/consent/index.d.ts +6 -6
  88. package/dist/consent/index.js +3 -3
  89. package/dist/{crypto-IVKU7YTT.js → crypto-A7FRXYHC.js} +3 -3
  90. package/dist/{delegation-2DBS2EOH.js → delegation-YBA4X4JN.js} +5 -4
  91. package/dist/derivations/index.cjs +351 -0
  92. package/dist/derivations/index.cjs.map +1 -0
  93. package/dist/derivations/index.d.cts +71 -0
  94. package/dist/derivations/index.d.ts +71 -0
  95. package/dist/derivations/index.js +27 -0
  96. package/dist/{dev-unlock-BdPp68qn.d.ts → dev-unlock-D9s-loPr.d.ts} +1 -1
  97. package/dist/{dev-unlock-Da1B0TIK.d.cts → dev-unlock-DRwVSy2S.d.cts} +1 -1
  98. package/dist/executor-7E3VFGW7.js +11 -0
  99. package/dist/executor-CEWX2FQI.js +8 -0
  100. package/dist/executor-CEWX2FQI.js.map +1 -0
  101. package/dist/executor-X4SQ3ZLC.js +8 -0
  102. package/dist/executor-X4SQ3ZLC.js.map +1 -0
  103. package/dist/fanout-sidecar-VJ52RIEY.js +51 -0
  104. package/dist/fanout-sidecar-VJ52RIEY.js.map +1 -0
  105. package/dist/guards/index.cjs +315 -0
  106. package/dist/guards/index.cjs.map +1 -0
  107. package/dist/guards/index.d.cts +30 -0
  108. package/dist/guards/index.d.ts +30 -0
  109. package/dist/guards/index.js +29 -0
  110. package/dist/guards/index.js.map +1 -0
  111. package/dist/{hash-lsoL3eEW.d.ts → hash-DXXXusyk.d.ts} +1 -1
  112. package/dist/{hash-BEfzPKwo.d.cts → hash-DtRih9MQ.d.cts} +1 -1
  113. package/dist/history/index.cjs +8 -1
  114. package/dist/history/index.cjs.map +1 -1
  115. package/dist/history/index.d.cts +7 -7
  116. package/dist/history/index.d.ts +7 -7
  117. package/dist/history/index.js +6 -6
  118. package/dist/i18n/index.cjs +81 -0
  119. package/dist/i18n/index.cjs.map +1 -1
  120. package/dist/i18n/index.d.cts +6 -6
  121. package/dist/i18n/index.d.ts +6 -6
  122. package/dist/i18n/index.js +19 -6
  123. package/dist/i18n/index.js.map +1 -1
  124. package/dist/{index-8QDuznDr.d.ts → index-4agOpzqd.d.ts} +174 -3
  125. package/dist/{index-6xNpPsxR.d.cts → index-CNwA-B6-.d.ts} +303 -5
  126. package/dist/{index-DJTf9yxn.d.ts → index-CmVgTkqk.d.cts} +303 -5
  127. package/dist/{index-CywCC1qZ.d.cts → index-hdFvZkBP.d.cts} +174 -3
  128. package/dist/index.cjs +5615 -979
  129. package/dist/index.cjs.map +1 -1
  130. package/dist/index.d.cts +207 -16
  131. package/dist/index.d.ts +207 -16
  132. package/dist/index.js +2302 -741
  133. package/dist/index.js.map +1 -1
  134. package/dist/indexing/index.cjs +2 -0
  135. package/dist/indexing/index.cjs.map +1 -1
  136. package/dist/indexing/index.d.cts +3 -3
  137. package/dist/indexing/index.d.ts +3 -3
  138. package/dist/indexing/index.js +4 -4
  139. package/dist/{lazy-builder-CZVLKh0Z.d.cts → lazy-builder-C-rPfWG0.d.cts} +1 -1
  140. package/dist/{lazy-builder-BwEoBQZ9.d.ts → lazy-builder-Rpd-V3jP.d.ts} +1 -1
  141. package/dist/{ledger-QZTTHQAQ.js → ledger-3TXNP47J.js} +6 -6
  142. package/dist/ledger-3TXNP47J.js.map +1 -0
  143. package/dist/materialized-views/index.cjs +837 -0
  144. package/dist/materialized-views/index.cjs.map +1 -0
  145. package/dist/materialized-views/index.d.cts +183 -0
  146. package/dist/materialized-views/index.d.ts +183 -0
  147. package/dist/materialized-views/index.js +45 -0
  148. package/dist/materialized-views/index.js.map +1 -0
  149. package/dist/overlay-views/index.cjs +359 -0
  150. package/dist/overlay-views/index.cjs.map +1 -0
  151. package/dist/overlay-views/index.d.cts +81 -0
  152. package/dist/overlay-views/index.d.ts +81 -0
  153. package/dist/overlay-views/index.js +23 -0
  154. package/dist/overlay-views/index.js.map +1 -0
  155. package/dist/periods/index.cjs +7 -1
  156. package/dist/periods/index.cjs.map +1 -1
  157. package/dist/periods/index.d.cts +6 -6
  158. package/dist/periods/index.d.ts +6 -6
  159. package/dist/periods/index.js +6 -6
  160. package/dist/{predicate-SBHmi6D0.d.cts → predicate-Dnu81tsS.d.cts} +25 -1
  161. package/dist/{predicate-SBHmi6D0.d.ts → predicate-Dnu81tsS.d.ts} +25 -1
  162. package/dist/{public-envelope-6JTACYJV.js → public-envelope-PY6NKFLI.js} +4 -4
  163. package/dist/public-envelope-PY6NKFLI.js.map +1 -0
  164. package/dist/query/index.cjs +302 -124
  165. package/dist/query/index.cjs.map +1 -1
  166. package/dist/query/index.d.cts +3 -3
  167. package/dist/query/index.d.ts +3 -3
  168. package/dist/query/index.js +26 -11
  169. package/dist/read-only-facade-ITU6L7BL.js +7 -0
  170. package/dist/read-only-facade-ITU6L7BL.js.map +1 -0
  171. package/dist/registry-3L3N3PTG.js +10 -0
  172. package/dist/registry-3L3N3PTG.js.map +1 -0
  173. package/dist/registry-O47PUPSY.js +8 -0
  174. package/dist/registry-O47PUPSY.js.map +1 -0
  175. package/dist/registry-RFGGMVNJ.js +7 -0
  176. package/dist/registry-RFGGMVNJ.js.map +1 -0
  177. package/dist/registry-WLLMODKN.js +8 -0
  178. package/dist/registry-WLLMODKN.js.map +1 -0
  179. package/dist/session/index.cjs +7 -1
  180. package/dist/session/index.cjs.map +1 -1
  181. package/dist/session/index.d.cts +7 -7
  182. package/dist/session/index.d.ts +7 -7
  183. package/dist/session/index.js +10 -3
  184. package/dist/session/index.js.map +1 -1
  185. package/dist/shadow/index.cjs.map +1 -1
  186. package/dist/shadow/index.d.cts +6 -6
  187. package/dist/shadow/index.d.ts +6 -6
  188. package/dist/shadow/index.js +2 -2
  189. package/dist/stale-HSC5YO2O.js +13 -0
  190. package/dist/stale-HSC5YO2O.js.map +1 -0
  191. package/dist/store/index.cjs +14 -0
  192. package/dist/store/index.cjs.map +1 -1
  193. package/dist/store/index.d.cts +6 -6
  194. package/dist/store/index.d.ts +6 -6
  195. package/dist/store/index.js +5 -2
  196. package/dist/{strategy-D-SrOLCl.d.cts → strategy-DSTrsZ8t.d.cts} +72 -19
  197. package/dist/{strategy-D-SrOLCl.d.ts → strategy-DSTrsZ8t.d.ts} +72 -19
  198. package/dist/sync/index.cjs.map +1 -1
  199. package/dist/sync/index.d.cts +5 -5
  200. package/dist/sync/index.d.ts +5 -5
  201. package/dist/sync/index.js +4 -4
  202. package/dist/team/index.cjs +1554 -2
  203. package/dist/team/index.cjs.map +1 -1
  204. package/dist/team/index.d.cts +6 -6
  205. package/dist/team/index.d.ts +6 -6
  206. package/dist/team/index.js +76 -9
  207. package/dist/tx/index.cjs +296 -44
  208. package/dist/tx/index.cjs.map +1 -1
  209. package/dist/tx/index.d.cts +6 -6
  210. package/dist/tx/index.d.ts +6 -6
  211. package/dist/tx/index.js +2 -2
  212. package/dist/{types-Bnb82f5R.d.cts → types-C4lwMKKF.d.cts} +2605 -328
  213. package/dist/{types-Bo7NSXJr.d.ts → types-DW9RGSSs.d.ts} +2605 -328
  214. package/dist/util/index.cjs.map +1 -1
  215. package/dist/util/index.js +1 -1
  216. package/dist/with-derivation-C8LDlV7t.d.cts +13 -0
  217. package/dist/with-derivation-g-pGoMzL.d.ts +13 -0
  218. package/dist/with-guard-DWOCK4Ca.d.ts +18 -0
  219. package/dist/with-guard-jI1x9Z3k.d.cts +18 -0
  220. package/dist/with-materialized-view-DaKR-N6J.d.ts +27 -0
  221. package/dist/with-materialized-view-DcTx4H3j.d.cts +27 -0
  222. package/dist/with-overlayed-view-D-6oWAgM.d.cts +13 -0
  223. package/dist/with-overlayed-view-N7jYuNOS.d.ts +13 -0
  224. package/package.json +53 -2
  225. package/dist/chunk-4PWAI7Q4.js +0 -79
  226. package/dist/chunk-4PWAI7Q4.js.map +0 -1
  227. package/dist/chunk-ACLDOTNQ.js.map +0 -1
  228. package/dist/chunk-BTDCBVJW.js +0 -160
  229. package/dist/chunk-BTDCBVJW.js.map +0 -1
  230. package/dist/chunk-CIMZBAZB.js.map +0 -1
  231. package/dist/chunk-EXHNQEV4.js.map +0 -1
  232. package/dist/chunk-GOUT6DND.js.map +0 -1
  233. package/dist/chunk-M5INGEFC.js.map +0 -1
  234. package/dist/chunk-QAVUREFT.js.map +0 -1
  235. package/dist/chunk-RKJ6OL7K.js.map +0 -1
  236. package/dist/chunk-SCZXXXU4.js.map +0 -1
  237. package/dist/chunk-TDR6T5CJ.js.map +0 -1
  238. package/dist/chunk-WDM5XGGS.js.map +0 -1
  239. /package/dist/{chunk-AVVPZ4BC.js.map → chunk-4TFSM22V.js.map} +0 -0
  240. /package/dist/{chunk-QGZRWRSL.js.map → chunk-537VFZTR.js.map} +0 -0
  241. /package/dist/{chunk-M62XNWRA.js.map → chunk-5DWL3JBF.js.map} +0 -0
  242. /package/dist/{chunk-PTVMYYON.js.map → chunk-5SCJ5UEF.js.map} +0 -0
  243. /package/dist/{chunk-ZFKD4QMV.js.map → chunk-DYECX3IX.js.map} +0 -0
  244. /package/dist/{chunk-MDDTIZUO.js.map → chunk-NIOHFJPJ.js.map} +0 -0
  245. /package/dist/{chunk-USKYUS74.js.map → chunk-P7EQ2S5O.js.map} +0 -0
  246. /package/dist/{chunk-2CSJGFCB.js.map → chunk-VMIO4IXG.js.map} +0 -0
  247. /package/dist/{chunk-MR4424N3.js.map → chunk-WCA2NROQ.js.map} +0 -0
  248. /package/dist/{chunk-NPC4LFV5.js.map → chunk-YMYK7US4.js.map} +0 -0
  249. /package/dist/{chunk-R36SIKES.js.map → chunk-ZNOEIM6Y.js.map} +0 -0
  250. /package/dist/{crypto-IVKU7YTT.js.map → crypto-A7FRXYHC.js.map} +0 -0
  251. /package/dist/{delegation-2DBS2EOH.js.map → delegation-YBA4X4JN.js.map} +0 -0
  252. /package/dist/{ledger-QZTTHQAQ.js.map → derivations/index.js.map} +0 -0
  253. /package/dist/{public-envelope-6JTACYJV.js.map → executor-7E3VFGW7.js.map} +0 -0
@@ -0,0 +1,183 @@
1
+ export { w as withMaterializedView } from '../with-materialized-view-DaKR-N6J.js';
2
+ import { aH as Collection, at as TxContext, ba as MVQueryContext, bb as RegisteredMV, bc as MaterializedViewRegistry } from '../types-DW9RGSSs.js';
3
+ export { bd as MaterializedFromMeta, be as MaterializedViewOutput, aE as MaterializedViewStrategy, aF as MaterializedViewStrategyHandle, bf as UnionSource } from '../types-DW9RGSSs.js';
4
+ import { Q as Query } from '../index-CNwA-B6-.js';
5
+ export { m as MaterializedViewConfigError, n as MaterializedViewCycleError, o as MaterializedViewSourceUnknownError, p as MaterializedViewTooLargeError } from '../index-CNwA-B6-.js';
6
+ import '../lazy-builder-Rpd-V3jP.js';
7
+ import '../predicate-Dnu81tsS.js';
8
+ import '../strategy-DSTrsZ8t.js';
9
+ import '../strategy-BSxFXGzb.js';
10
+
11
+ /**
12
+ * Accessor shape passed in from the owning Vault. Mirrors v1's
13
+ * `DerivationStaleAccessor` — provides the per-collection resolver
14
+ * and the active TxContext so refresh writes/tombstones register on
15
+ * `_executed` for #133-style rollback symmetry.
16
+ */
17
+ interface MVExecutorAccessor {
18
+ getCollection(name: string): Collection<any>;
19
+ getActiveTxContext(): TxContext | null;
20
+ /**
21
+ * Vault-shaped accessor passed to the MV's `query()` callback at
22
+ * each refresh. Same instance the registry used at registration
23
+ * time; threading through the executor lets the refresh path
24
+ * re-evaluate the closure against the live vault state.
25
+ */
26
+ getQueryContext(): MVQueryContext;
27
+ }
28
+ interface RefreshResult {
29
+ /** Rows newly written / overwritten. */
30
+ written: number;
31
+ /** Rows tombstoned via `_internalDelete` (only when `onEmpty: 'delete'`). */
32
+ deleted: number;
33
+ /** Failed row writes (non-strict mode). */
34
+ failed: number;
35
+ }
36
+ /**
37
+ * Run an MV's `query()` and write the result rows to the output
38
+ * collection. Same-DEK encryption: routes through the standard
39
+ * `Collection.put` pipeline, so the output collection's DEK is what
40
+ * gets used (matches the v2 spec's "same DEK as the left-most source"
41
+ * invariant — `Collection.put` looks up the DEK by collection name,
42
+ * and the output collection IS the MV's owned collection).
43
+ *
44
+ * Stamps `_materializedFrom` onto every emitted row.
45
+ *
46
+ * **Tombstoning** (#152): when `spec.onEmpty: 'delete'` (default), rows
47
+ * that existed in a prior refresh but no longer appear in the new
48
+ * materialized result are deleted via `Collection._internalDelete` —
49
+ * the housekeeping bypass primitive added in PR #148 prevents user
50
+ * `onDelete` guards on the output collection from firing on these
51
+ * system-internal deletes. `onEmpty: 'keep'` opts out (rows from
52
+ * prior refreshes linger even when the new result lacks them).
53
+ *
54
+ * **Cost ceiling** (#152): if the materialized row count exceeds
55
+ * `spec.maxRows` (default 100k), throws `MaterializedViewTooLargeError`
56
+ * before any writes hit the store — so strict-mode rollback is
57
+ * clean.
58
+ *
59
+ * **Strict mode** (#152): `spec.strict === true` re-throws on any
60
+ * row-write failure; the active TxContext registration means the
61
+ * source-write rolls back atomically via `revertExecuted` (#133).
62
+ *
63
+ * @internal
64
+ */
65
+ declare const MaterializedViewExecutor: {
66
+ refresh(reg: RegisteredMV, accessor: MVExecutorAccessor): Promise<RefreshResult>;
67
+ };
68
+
69
+ /**
70
+ * Walks a `Query<T>` plan and returns the set of source collection
71
+ * names that any source-write should trigger a refresh on.
72
+ *
73
+ * Foundation sub-issue (#150) handles:
74
+ * - root collection (the one the query was built from)
75
+ * - FK join targets (`.join(field, { as })`)
76
+ *
77
+ * Deferred to later sub-issues:
78
+ * - `.crossJoin()` — v3 cross-join spec (separate primitive)
79
+ * - `.wherePredicate(name)` — v2 predicate primitive, sub-issue #153
80
+ * - Overlay-name expansion to {base, overlay} — sub-issue #154
81
+ *
82
+ * The set is materialized at MV registration time. The MV registry
83
+ * uses it to (a) dispatch `onSourceWrite` only to MVs that actually
84
+ * care, and (b) contribute edges to the shared cycle-detection graph.
85
+ */
86
+ declare function analyzeDependencies(query: Query<any>): Set<string>;
87
+ /**
88
+ * Convenience: produce a stable string summary of the query plan
89
+ * suitable for `queryHash` derivation. Captures everything the
90
+ * dependency analyzer reads + the where/orderBy/limit/offset
91
+ * structure that affects materialized rows.
92
+ *
93
+ * `joinContext` is intentionally NOT included — the join-resolution
94
+ * function references would defeat hash determinism. The set of join
95
+ * TARGETS (collection names) IS included via the plan.joins legs.
96
+ */
97
+ declare function summarizeQueryPlan(query: Query<any>): string;
98
+
99
+ /**
100
+ * Deterministic hash of a materialized view strategy's "shape": MV
101
+ * name + canonical query-plan summary + sorted dependency-set.
102
+ *
103
+ * Used to detect strategy drift: a row whose `_materializedFrom.queryHash`
104
+ * doesn't match the current strategy is considered stale.
105
+ *
106
+ * Web Crypto SHA-256 — no extra deps. Mirrors the v1
107
+ * `computeStrategyHash` pattern.
108
+ */
109
+ declare function computeQueryHash(mvName: string,
110
+ /**
111
+ * Source-collection set the query depends on. Sorted before
112
+ * canonicalization so set iteration order doesn't affect the hash.
113
+ */
114
+ dependencies: ReadonlySet<string>,
115
+ /**
116
+ * Stringified query-plan summary. The caller produces this from the
117
+ * `Query<T>` builder — concretely: a JSON serialization of clauses +
118
+ * orderBy + limit + offset + joins. Function bodies inside
119
+ * `wherePredicate` are NOT included here (those carry their own
120
+ * `predicateHash` to be folded in by a later sub-issue).
121
+ */
122
+ queryPlanSummary: string): Promise<string>;
123
+ /**
124
+ * Canonicalize a query plan for hashing. Walks the plan structure
125
+ * with sorted keys so insertion order doesn't perturb the result.
126
+ * Lives here rather than in `query/builder.ts` to keep that module
127
+ * stable across MV-specific evolutions.
128
+ *
129
+ * @internal exported for testing
130
+ */
131
+ declare function canonicalizeQueryPlan(plan: unknown): string;
132
+
133
+ /**
134
+ * Accessor shape passed in from the owning Vault. Provides the
135
+ * registry (used as a stable WeakMap key + to look up MVs by output
136
+ * collection) and the runtime context the lazy refresh needs.
137
+ * Mirrors v1's `DerivationStaleAccessor`.
138
+ */
139
+ interface MVStaleAccessor {
140
+ registry(): MaterializedViewRegistry;
141
+ getCollection(name: string): Collection<any>;
142
+ getActiveTxContext(): TxContext | null;
143
+ getQueryContext(): MVQueryContext;
144
+ }
145
+ /**
146
+ * Mark an MV as stale. Called from `Collection.dispatchMaterializedViews`
147
+ * when a source-write fires for a `refresh: 'lazy'` MV.
148
+ *
149
+ * @internal
150
+ */
151
+ declare function markMVStale(registry: MaterializedViewRegistry, mvName: string): void;
152
+ /**
153
+ * Test-only: check whether a given MV name is currently flagged stale
154
+ * against a registry. Exported so the regression suite can pin the
155
+ * stale-bit lifecycle without touching the internal `WeakMap`.
156
+ *
157
+ * @internal
158
+ */
159
+ declare function isMVStale(registry: MaterializedViewRegistry, mvName: string): boolean;
160
+ /**
161
+ * Called from `Collection.get` (and any reader that materializes the
162
+ * MV's output collection). If any MV producing `outputCollection` is
163
+ * flagged stale, runs the executor against the live source state
164
+ * before returning. No-op when there is no pending work — keeps the
165
+ * read fast path negligible.
166
+ *
167
+ * Dynamic-imports the executor only when a stale flag actually fires
168
+ * (the floor-bundle isolation pattern v1 derivations established in
169
+ * #130).
170
+ */
171
+ declare function resolveStaleMVOnRead(accessor: MVStaleAccessor, outputCollection: string): Promise<void>;
172
+ /**
173
+ * Drop every stale flag for a registry. Used after a manual
174
+ * `vault.refreshView(name)` runs the executor explicitly — the
175
+ * post-refresh state matches the registered strategies, so
176
+ * lingering stale bits would force a redundant refresh on the next
177
+ * read.
178
+ *
179
+ * @internal
180
+ */
181
+ declare function clearMVStale(registry: MaterializedViewRegistry, mvName: string): void;
182
+
183
+ export { type MVExecutorAccessor, type MVStaleAccessor, MaterializedViewExecutor, MaterializedViewRegistry, type RefreshResult, RegisteredMV, analyzeDependencies, canonicalizeQueryPlan, clearMVStale, computeQueryHash, isMVStale, markMVStale, resolveStaleMVOnRead, summarizeQueryPlan };
@@ -0,0 +1,45 @@
1
+ import {
2
+ withMaterializedView
3
+ } from "../chunk-RD5LYKD6.js";
4
+ import {
5
+ MaterializedViewExecutor
6
+ } from "../chunk-SIZWEV2Y.js";
7
+ import {
8
+ MaterializedViewRegistry,
9
+ analyzeDependencies,
10
+ canonicalizeQueryPlan,
11
+ computeQueryHash,
12
+ summarizeQueryPlan
13
+ } from "../chunk-DPMFBCV6.js";
14
+ import {
15
+ clearMVStale,
16
+ isMVStale,
17
+ markMVStale,
18
+ resolveStaleMVOnRead
19
+ } from "../chunk-UZXLQCHP.js";
20
+ import "../chunk-XGSOTWYX.js";
21
+ import "../chunk-MRIBLZL3.js";
22
+ import {
23
+ MaterializedViewConfigError,
24
+ MaterializedViewCycleError,
25
+ MaterializedViewSourceUnknownError,
26
+ MaterializedViewTooLargeError
27
+ } from "../chunk-ADQ5MQ54.js";
28
+ export {
29
+ MaterializedViewConfigError,
30
+ MaterializedViewCycleError,
31
+ MaterializedViewExecutor,
32
+ MaterializedViewRegistry,
33
+ MaterializedViewSourceUnknownError,
34
+ MaterializedViewTooLargeError,
35
+ analyzeDependencies,
36
+ canonicalizeQueryPlan,
37
+ clearMVStale,
38
+ computeQueryHash,
39
+ isMVStale,
40
+ markMVStale,
41
+ resolveStaleMVOnRead,
42
+ summarizeQueryPlan,
43
+ withMaterializedView
44
+ };
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/overlay-views/index.ts
21
+ var overlay_views_exports = {};
22
+ __export(overlay_views_exports, {
23
+ OverlayBaseIsVirtualError: () => OverlayBaseIsVirtualError,
24
+ OverlayCollectionUnavailableError: () => OverlayCollectionUnavailableError,
25
+ OverlayIdMismatchError: () => OverlayIdMismatchError,
26
+ OverlayNameCollisionError: () => OverlayNameCollisionError,
27
+ OverlayedCollection: () => OverlayedCollection,
28
+ OverlayedViewRegistry: () => OverlayedViewRegistry,
29
+ withOverlayedView: () => withOverlayedView
30
+ });
31
+ module.exports = __toCommonJS(overlay_views_exports);
32
+
33
+ // src/errors.ts
34
+ var NoydbError = class extends Error {
35
+ /** Machine-readable error code. Stable across library versions. */
36
+ code;
37
+ constructor(code, message) {
38
+ super(message);
39
+ this.name = "NoydbError";
40
+ this.code = code;
41
+ }
42
+ };
43
+ var ValidationError = class extends NoydbError {
44
+ constructor(message = "Validation error") {
45
+ super("VALIDATION_ERROR", message);
46
+ this.name = "ValidationError";
47
+ }
48
+ };
49
+ var OverlayBaseIsVirtualError = class extends NoydbError {
50
+ overlayName;
51
+ base;
52
+ constructor(overlayName, base) {
53
+ super(
54
+ "OVERLAY_BASE_IS_VIRTUAL",
55
+ `withOverlayedView "${overlayName}": base "${base}" is another overlay's virtual name. Multi-overlay stacking is a v3 feature; base must reference a concrete collection (a real source or an MV output).`
56
+ );
57
+ this.name = "OverlayBaseIsVirtualError";
58
+ this.overlayName = overlayName;
59
+ this.base = base;
60
+ }
61
+ };
62
+ var OverlayCollectionUnavailableError = class extends NoydbError {
63
+ overlayName;
64
+ overlay;
65
+ constructor(overlayName, overlay) {
66
+ super(
67
+ "OVERLAY_COLLECTION_UNAVAILABLE",
68
+ `withOverlayedView "${overlayName}": overlay collection "${overlay}" is unavailable. It must be a real vault-known collection that is NOT itself an MV output collection.`
69
+ );
70
+ this.name = "OverlayCollectionUnavailableError";
71
+ this.overlayName = overlayName;
72
+ this.overlay = overlay;
73
+ }
74
+ };
75
+ var OverlayNameCollisionError = class extends NoydbError {
76
+ overlayName;
77
+ constructor(overlayName) {
78
+ super(
79
+ "OVERLAY_NAME_COLLISION",
80
+ `withOverlayedView "${overlayName}": virtual name collides with an MV output or a concrete source collection. Pick a unique name for the virtual collection.`
81
+ );
82
+ this.name = "OverlayNameCollisionError";
83
+ this.overlayName = overlayName;
84
+ }
85
+ };
86
+ var OverlayIdMismatchError = class extends NoydbError {
87
+ actual;
88
+ expected;
89
+ constructor(actual, expected) {
90
+ super(
91
+ "OVERLAY_ID_MISMATCH",
92
+ `Overlay put(id, record): id "${actual}" does not match the base MV's rowKey(record) \u2192 "${expected}". Pass the row directly via .put(record) to derive the id, or fix the id to match the base MV's rowKey output.`
93
+ );
94
+ this.name = "OverlayIdMismatchError";
95
+ this.actual = actual;
96
+ this.expected = expected;
97
+ }
98
+ };
99
+
100
+ // src/overlay-views/with-overlayed-view.ts
101
+ function withOverlayedView(spec) {
102
+ if (!spec.name || spec.name.length === 0) {
103
+ throw new ValidationError("withOverlayedView: name is required");
104
+ }
105
+ if (!spec.base || spec.base.length === 0) {
106
+ throw new ValidationError("withOverlayedView: base is required");
107
+ }
108
+ if (!spec.overlay || spec.overlay.length === 0) {
109
+ throw new ValidationError("withOverlayedView: overlay is required");
110
+ }
111
+ if (spec.base === spec.overlay) {
112
+ throw new ValidationError("withOverlayedView: base and overlay must be different collections");
113
+ }
114
+ if (spec.base === spec.name || spec.overlay === spec.name) {
115
+ throw new ValidationError(
116
+ "withOverlayedView: virtual name must differ from both base and overlay collection names"
117
+ );
118
+ }
119
+ if (!spec.shadowField || spec.shadowField.length === 0) {
120
+ throw new ValidationError("withOverlayedView: shadowField is required");
121
+ }
122
+ return {
123
+ __noydb_strategy: "overlayed-view",
124
+ spec
125
+ };
126
+ }
127
+
128
+ // src/overlay-views/registry.ts
129
+ var OverlayedViewRegistry = class {
130
+ _byName = /* @__PURE__ */ new Map();
131
+ /**
132
+ * Register an overlay. Validates name uniqueness, base concreteness,
133
+ * and overlay availability AGAINST the MV registry — overlays
134
+ * declared without the MV registry context skip cross-registry
135
+ * checks but still validate self-consistency.
136
+ */
137
+ register(spec, options) {
138
+ const { isOverlayName, isMVOutput, isKnownCollection } = options;
139
+ if (isMVOutput?.(spec.name) || isOverlayName?.(spec.name)) {
140
+ throw new OverlayNameCollisionError(spec.name);
141
+ }
142
+ if (isOverlayName?.(spec.base)) {
143
+ throw new OverlayBaseIsVirtualError(spec.name, spec.base);
144
+ }
145
+ if (isMVOutput?.(spec.overlay)) {
146
+ throw new OverlayCollectionUnavailableError(spec.name, spec.overlay);
147
+ }
148
+ void isKnownCollection;
149
+ this._byName.set(spec.name, spec);
150
+ }
151
+ byName(name) {
152
+ return this._byName.get(name);
153
+ }
154
+ /** All overlay virtual names. */
155
+ names() {
156
+ return new Set(this._byName.keys());
157
+ }
158
+ isOverlay(name) {
159
+ return this._byName.has(name);
160
+ }
161
+ /**
162
+ * Resolve the `rowKey` function for an overlay's base MV. Returns
163
+ * `undefined` if the base isn't an MV (raw source collection) or
164
+ * if the MV registry isn't supplied. Used by the virtual-collection
165
+ * proxy to derive ids from `put(record)` calls.
166
+ */
167
+ resolveBaseRowKey(name, mvRegistry) {
168
+ const spec = this._byName.get(name);
169
+ if (!spec || !mvRegistry) return void 0;
170
+ for (const reg of mvRegistry.all()) {
171
+ if (reg.outputCollection === spec.base || reg.spec.name === spec.base) {
172
+ return (row) => reg.spec.rowKey(row);
173
+ }
174
+ }
175
+ return void 0;
176
+ }
177
+ };
178
+
179
+ // src/overlay-views/virtual-collection.ts
180
+ var OverlayedCollection = class {
181
+ constructor(spec, baseCollection, overlayCollection, baseRowKey) {
182
+ this.spec = spec;
183
+ this.baseCollection = baseCollection;
184
+ this.overlayCollection = overlayCollection;
185
+ this.baseRowKey = baseRowKey;
186
+ }
187
+ spec;
188
+ baseCollection;
189
+ overlayCollection;
190
+ baseRowKey;
191
+ /**
192
+ * Convenience accessors for advanced callers that need to bypass the
193
+ * virtual layer (bulk imports, direct overlay queries). Mirrors the
194
+ * spec's "direct writes to the underlying overlay collection skip
195
+ * the validation" escape hatch.
196
+ */
197
+ overlay = {
198
+ rowKey: (row) => {
199
+ if (!this.baseRowKey) {
200
+ throw new Error(
201
+ `Overlay "${this.spec.name}": base "${this.spec.base}" is not an MV \u2014 cannot auto-derive id from the row. Use \`put(id, record)\` instead.`
202
+ );
203
+ }
204
+ return this.baseRowKey(row);
205
+ }
206
+ };
207
+ /** Get the merged row by id. */
208
+ async get(id) {
209
+ const overlayRow = await this.overlayCollection.get(id);
210
+ if (overlayRow !== null && this.shadowPredicateApplies(overlayRow)) {
211
+ return overlayRow;
212
+ }
213
+ const baseRow = await this.baseCollection.get(id);
214
+ if (baseRow !== null) return baseRow;
215
+ return null;
216
+ }
217
+ /** List union of base + overlay ids, applying the merge per row. */
218
+ async list() {
219
+ const baseRows = await this.baseCollection.list();
220
+ const overlayRows = await this.overlayCollection.list();
221
+ const merged = /* @__PURE__ */ new Map();
222
+ const idOf = (row) => {
223
+ if (this.baseRowKey) return this.baseRowKey(row);
224
+ const idField = row.id;
225
+ return typeof idField === "string" ? idField : "";
226
+ };
227
+ for (const row of baseRows) {
228
+ const id = idOf(row);
229
+ if (id) merged.set(id, row);
230
+ }
231
+ for (const row of overlayRows) {
232
+ const id = idOf(row);
233
+ if (!id) continue;
234
+ if (this.shadowPredicateApplies(row)) {
235
+ merged.set(id, row);
236
+ } else if (!merged.has(id)) {
237
+ continue;
238
+ }
239
+ }
240
+ return [...merged.values()];
241
+ }
242
+ /**
243
+ * Write to the overlay. Two forms:
244
+ * - `put(record)`: id is derived via the base MV's `rowKey(record)`.
245
+ * Throws if the base isn't an MV.
246
+ * - `put(id, record)`: validates `id === rowKey(record)`; throws
247
+ * `OverlayIdMismatchError` on mismatch.
248
+ */
249
+ async put(idOrRecord, maybeRecord) {
250
+ let id;
251
+ let record;
252
+ if (maybeRecord === void 0) {
253
+ record = idOrRecord;
254
+ if (!this.baseRowKey) {
255
+ throw new Error(
256
+ `Overlay "${this.spec.name}".put(record): base "${this.spec.base}" is not an MV. Use put(id, record) explicitly.`
257
+ );
258
+ }
259
+ id = this.baseRowKey(record);
260
+ } else {
261
+ id = idOrRecord;
262
+ record = maybeRecord;
263
+ if (this.baseRowKey) {
264
+ const expected = this.baseRowKey(record);
265
+ if (id !== expected) {
266
+ throw new OverlayIdMismatchError(id, expected);
267
+ }
268
+ }
269
+ }
270
+ await this.overlayCollection.put(id, record);
271
+ }
272
+ /**
273
+ * Remove the overlay row only. Idempotent (no-op on absent).
274
+ * The base row is untouched — if a base row exists for `id`,
275
+ * subsequent reads return it.
276
+ */
277
+ async delete(id) {
278
+ await this.overlayCollection.delete(id);
279
+ }
280
+ /** True when `overlay[shadowField] === shadowValue`. */
281
+ shadowPredicateApplies(row) {
282
+ return row[this.spec.shadowField] === this.spec.shadowValue;
283
+ }
284
+ // ─── Throw-stubs for the unimplemented Collection<T> surface ───────
285
+ //
286
+ // `Vault.collection(name)` widens the return type to `Collection<T>`
287
+ // for the overlay intercept, but `OverlayedCollection` doesn't
288
+ // implement the full surface. These stubs catch the common
289
+ // reactive / chainable APIs with a clear "not yet implemented"
290
+ // error pointing at the relevant issue — so consumers don't hit a
291
+ // cryptic `undefined is not a function` runtime crash.
292
+ //
293
+ // Closes niwat-review of PR #160.
294
+ /** @throws — chainable Query<T> over a virtual collection is deferred. */
295
+ query() {
296
+ throw new Error(
297
+ `OverlayedCollection "${this.spec.name}".query() is not yet implemented for overlay views (#154). Use \`list()\` + filter for now, or read from the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections directly. Reactive APIs land in a future MV sub-issue.`
298
+ );
299
+ }
300
+ /** @throws — change-stream subscription over a virtual collection is deferred. */
301
+ subscribe() {
302
+ throw new Error(
303
+ `OverlayedCollection "${this.spec.name}".subscribe() is not yet implemented for overlay views (#154). Subscribe to the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections individually for now. Merged change-stream lands in a future MV sub-issue.`
304
+ );
305
+ }
306
+ /** @throws — live query over a virtual collection is deferred. */
307
+ live() {
308
+ throw new Error(
309
+ `OverlayedCollection "${this.spec.name}".live() is not yet implemented for overlay views (#154). Reactive APIs land in a future MV sub-issue.`
310
+ );
311
+ }
312
+ /** @throws — async iteration over a virtual collection is deferred. */
313
+ scan() {
314
+ throw new Error(
315
+ `OverlayedCollection "${this.spec.name}".scan() is not yet implemented for overlay views (#154). Use \`list()\` for now (no row-count ceiling at niwat scale), or scan the underlying collections directly.`
316
+ );
317
+ }
318
+ /** @throws — lazy-mode query is not applicable to virtual collections. */
319
+ lazyQuery() {
320
+ throw new Error(
321
+ `OverlayedCollection "${this.spec.name}".lazyQuery() is not supported. Virtual collections always materialize through base + overlay reads \u2014 lazy-mode indexed lookups don't apply.`
322
+ );
323
+ }
324
+ /** @throws — bulk-atomic put is deferred to a future MV sub-issue. */
325
+ putManyAtomic() {
326
+ throw new Error(
327
+ `OverlayedCollection "${this.spec.name}".putManyAtomic() is not yet implemented for overlay views (#154). Use sequential \`.put(record)\` calls for now, or write to \`${this.spec.overlay}\` directly.`
328
+ );
329
+ }
330
+ /** @throws — bulk delete is deferred to a future MV sub-issue. */
331
+ deleteMany() {
332
+ throw new Error(
333
+ `OverlayedCollection "${this.spec.name}".deleteMany() is not yet implemented for overlay views (#154). Use sequential \`.delete(id)\` calls for now, or operate on \`${this.spec.overlay}\` directly.`
334
+ );
335
+ }
336
+ /** @throws — `.first()` over a virtual collection is deferred. */
337
+ first() {
338
+ throw new Error(
339
+ `OverlayedCollection "${this.spec.name}".first() is not yet implemented for overlay views (#154). Use \`(await list())[0]\` for now.`
340
+ );
341
+ }
342
+ /** @throws — `.count()` over a virtual collection is deferred. */
343
+ count() {
344
+ throw new Error(
345
+ `OverlayedCollection "${this.spec.name}".count() is not yet implemented for overlay views (#154). Use \`(await list()).length\` for now.`
346
+ );
347
+ }
348
+ };
349
+ // Annotate the CommonJS export names for ESM import in node:
350
+ 0 && (module.exports = {
351
+ OverlayBaseIsVirtualError,
352
+ OverlayCollectionUnavailableError,
353
+ OverlayIdMismatchError,
354
+ OverlayNameCollisionError,
355
+ OverlayedCollection,
356
+ OverlayedViewRegistry,
357
+ withOverlayedView
358
+ });
359
+ //# sourceMappingURL=index.cjs.map