@noy-db/hub 0.7.0-pre.13 → 0.7.0-pre.15

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 (233) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +4 -3
  3. package/dist/{api-UE2XQKDN.js → api-JPZT6BDD.js} +1 -2
  4. package/dist/as/index.js +3 -4
  5. package/dist/as/index.js.map +1 -1
  6. package/dist/at/index.js +0 -1
  7. package/dist/attestation/index.js +6 -7
  8. package/dist/attestation/index.js.map +1 -1
  9. package/dist/{backup-R6A4VZRX.js → backup-AKWIMYWU.js} +1 -2
  10. package/dist/{backup-R6A4VZRX.js.map → backup-AKWIMYWU.js.map} +1 -1
  11. package/dist/blobs/index.js +0 -1
  12. package/dist/blobs/index.js.map +1 -1
  13. package/dist/broker/index.js +3 -4
  14. package/dist/broker/index.js.map +1 -1
  15. package/dist/by/index.js +0 -1
  16. package/dist/cargo/index.js +10 -11
  17. package/dist/{chunk-5FUULQ6F.js → chunk-2HVILGVR.js} +6 -6
  18. package/dist/{chunk-DJ3LNNZQ.js → chunk-3LK2XZCW.js} +2 -2
  19. package/dist/{chunk-PQKG5AHH.js → chunk-6X6SEMEE.js} +4 -2
  20. package/dist/{chunk-PQKG5AHH.js.map → chunk-6X6SEMEE.js.map} +1 -1
  21. package/dist/{chunk-E2MYJGSG.js → chunk-AMODH7AU.js} +2 -2
  22. package/dist/{chunk-B2ZSGYSF.js → chunk-B2KCRDJM.js} +3 -3
  23. package/dist/{chunk-TO3EQ7HF.js → chunk-BLN54W3L.js} +2 -2
  24. package/dist/{chunk-IHFXR2VQ.js → chunk-BOBFL5TW.js} +2 -2
  25. package/dist/{chunk-ZR2YMODS.js → chunk-EKZ6VZYF.js} +2 -2
  26. package/dist/{chunk-RTYJRFQO.js → chunk-EWPRPP3M.js} +1 -1
  27. package/dist/{chunk-VGICZPVE.js → chunk-FUJSIP4K.js} +2 -2
  28. package/dist/{chunk-BWXGSSFX.js → chunk-NJXX55QX.js} +79 -16
  29. package/dist/chunk-NJXX55QX.js.map +1 -0
  30. package/dist/{chunk-PKJ43CMD.js → chunk-NLOLF6LD.js} +2 -2
  31. package/dist/{chunk-COTPDJR5.js → chunk-OMB2ZKIT.js} +8 -8
  32. package/dist/{chunk-BMELYFHU.js → chunk-P3KOF624.js} +3 -3
  33. package/dist/{chunk-Y4MJQ2UG.js → chunk-QQ2YMQZU.js} +2 -2
  34. package/dist/{chunk-URHRIAV6.js → chunk-REDOOY2Q.js} +2 -2
  35. package/dist/chunk-REDOOY2Q.js.map +1 -0
  36. package/dist/{chunk-YCXICMOY.js → chunk-RJ7NN2UR.js} +2 -2
  37. package/dist/{chunk-PDD75NUZ.js → chunk-SMH6SRX7.js} +2 -2
  38. package/dist/{chunk-QHW35ZON.js → chunk-TGPST6FK.js} +2 -2
  39. package/dist/{chunk-BERJ4AWW.js → chunk-VGXZT72I.js} +2 -2
  40. package/dist/{chunk-ZVCC36XQ.js → chunk-WL36WA3O.js} +55 -55
  41. package/dist/{chunk-2Z47NMFK.js → chunk-WZW37ZHL.js} +2 -2
  42. package/dist/{chunk-SXCYYMVS.js → chunk-YINEDONN.js} +5 -5
  43. package/dist/{chunk-AJQY44CE.js → chunk-ZXLZ62R5.js} +3 -20
  44. package/dist/chunk-ZXLZ62R5.js.map +1 -0
  45. package/dist/classified/index.js +1 -2
  46. package/dist/{classified-marker-67HBIJMZ.js → classified-marker-OO65UYXN.js} +3 -5
  47. package/dist/{classified-marker-67HBIJMZ.js.map → classified-marker-OO65UYXN.js.map} +1 -1
  48. package/dist/{collection-facade-4ACKIDDY.js → collection-facade-VOWW732S.js} +3 -4
  49. package/dist/{computed-LSEZYRJS.js → computed-VPOKQK4N.js} +1 -2
  50. package/dist/consent/index.js +0 -1
  51. package/dist/consent/index.js.map +1 -1
  52. package/dist/cover/index.js +0 -1
  53. package/dist/crdt/index.js +0 -1
  54. package/dist/crdt/index.js.map +1 -1
  55. package/dist/custody/index.js +1 -2
  56. package/dist/{dead-filter-M3NZUWBZ.js → dead-filter-OMMVBAKZ.js} +2 -3
  57. package/dist/{dead-filter-M3NZUWBZ.js.map → dead-filter-OMMVBAKZ.js.map} +1 -1
  58. package/dist/debug/index.js +0 -1
  59. package/dist/debug/index.js.map +1 -1
  60. package/dist/{delegation-OLJUWTVA.js → delegation-VRYMQRCF.js} +1 -2
  61. package/dist/{delegation-OLJUWTVA.js.map → delegation-VRYMQRCF.js.map} +1 -1
  62. package/dist/derivations/index.js +3 -4
  63. package/dist/{derive-LY47HG7Q.js → derive-HHBRFS2U.js} +2 -3
  64. package/dist/directory/index.js +0 -1
  65. package/dist/{dispatch-MSTR5VBI.js → dispatch-DC3LQJ3S.js} +6 -7
  66. package/dist/{dispatch-MSTR5VBI.js.map → dispatch-DC3LQJ3S.js.map} +1 -1
  67. package/dist/{dispatch-PDP5TA73.js → dispatch-GGFBWQU7.js} +5 -7
  68. package/dist/{dispatch-PDP5TA73.js.map → dispatch-GGFBWQU7.js.map} +1 -1
  69. package/dist/{enclave-4YBQK77G.js → enclave-VM2YQONI.js} +1 -2
  70. package/dist/{executor-TOLPBHOC.js → executor-5NIMLSKZ.js} +1 -2
  71. package/dist/{executor-YDDC5XGY.js → executor-5XJNV5H5.js} +1 -2
  72. package/dist/{executor-MZJXBWNM.js → executor-AQVXV5GZ.js} +1 -2
  73. package/dist/{export-accessible-LGV6IAFX.js → export-accessible-2LOBM67T.js} +3 -4
  74. package/dist/{extract-partition-RYJZIKQZ.js → extract-partition-AZGSEMIF.js} +3 -4
  75. package/dist/{fanout-sidecar-TSFPXY5C.js → fanout-sidecar-HJIVUPTD.js} +1 -2
  76. package/dist/{fanout-sidecar-TSFPXY5C.js.map → fanout-sidecar-HJIVUPTD.js.map} +1 -1
  77. package/dist/{fence-watcher-ZVSMLKQD.js → fence-watcher-U2PW6JU5.js} +1 -3
  78. package/dist/{fence-watcher-ZVSMLKQD.js.map → fence-watcher-U2PW6JU5.js.map} +1 -1
  79. package/dist/{find-LC7P63MX.js → find-2ABFCZX4.js} +1 -2
  80. package/dist/forget/index.js +0 -1
  81. package/dist/forget/index.js.map +1 -1
  82. package/dist/guards/index.js +0 -1
  83. package/dist/history/index.js +0 -1
  84. package/dist/history/index.js.map +1 -1
  85. package/dist/i18n/index.js +0 -1
  86. package/dist/i18n/index.js.map +1 -1
  87. package/dist/index.js +26 -27
  88. package/dist/index.js.map +1 -1
  89. package/dist/indexing/index.js +0 -1
  90. package/dist/indexing/index.js.map +1 -1
  91. package/dist/introspection/index.js +2 -3
  92. package/dist/{issue-IOXM3RSJ.js → issue-RH4H733Z.js} +1 -2
  93. package/dist/{json-schema-I22JCYCG.js → json-schema-V3M5MUCM.js} +1 -3
  94. package/dist/{json-schema-I22JCYCG.js.map → json-schema-V3M5MUCM.js.map} +1 -1
  95. package/dist/kernel/collection-config.d.ts +34 -0
  96. package/dist/lazy/index.js +0 -1
  97. package/dist/{ledger-HXHIOD36.js → ledger-454SU3VE.js} +1 -2
  98. package/dist/{liberate-4APIV7FR.js → liberate-AAZSP2BT.js} +5 -6
  99. package/dist/{link-set-6RAHEKZN.js → link-set-67CAMUAL.js} +1 -2
  100. package/dist/{managed-secret-P3JQ7ZG4.js → managed-secret-NHRYG7CD.js} +1 -2
  101. package/dist/materialized-views/index.js +2 -3
  102. package/dist/{migrate-cek-25KNTS5U.js → migrate-cek-5ENH64AA.js} +1 -2
  103. package/dist/{migrate-cek-25KNTS5U.js.map → migrate-cek-5ENH64AA.js.map} +1 -1
  104. package/dist/money/index.js +0 -1
  105. package/dist/{noydb-2C6QQJ5S.js → noydb-F5CABCU4.js} +11 -12
  106. package/dist/overlay-views/index.js +0 -1
  107. package/dist/periods/index.js +1 -2
  108. package/dist/pod/index.js +12 -13
  109. package/dist/{pod-handle-6II7KFBR.js → pod-handle-S7AMCJIF.js} +2 -3
  110. package/dist/{pod-handle-6II7KFBR.js.map → pod-handle-S7AMCJIF.js.map} +1 -1
  111. package/dist/policy/index.js +0 -1
  112. package/dist/portability/index.js +6 -7
  113. package/dist/portability/index.js.map +1 -1
  114. package/dist/{post-register-BPJ36A6D.js → post-register-HIYY4Y5S.js} +4 -5
  115. package/dist/{post-register-BPJ36A6D.js.map → post-register-HIYY4Y5S.js.map} +1 -1
  116. package/dist/{purge-scope-FGNNLWHD.js → purge-scope-4HEFPDOW.js} +1 -3
  117. package/dist/{purge-scope-FGNNLWHD.js.map → purge-scope-4HEFPDOW.js.map} +1 -1
  118. package/dist/query/index.js +0 -1
  119. package/dist/{read-only-facade-CHCKSEPD.js → read-only-facade-BIGO37U3.js} +1 -2
  120. package/dist/reduce/index.js +0 -1
  121. package/dist/reduce/index.js.map +1 -1
  122. package/dist/{register-AEOOGKNO.js → register-7OJWAWT5.js} +3 -4
  123. package/dist/{registry-SKSOUXNF.js → registry-23WF3TGH.js} +1 -2
  124. package/dist/{registry-SHMGHEK4.js → registry-4AYVUNXK.js} +1 -2
  125. package/dist/{registry-I6FP4677.js → registry-5MVJGPXW.js} +1 -2
  126. package/dist/{registry-D2YXKRYC.js → registry-BOHIKFWG.js} +4 -5
  127. package/dist/{request-withdrawal-6HJT4ODF.js → request-withdrawal-P5EQATZ7.js} +5 -6
  128. package/dist/{reveal-DDQBDWPM.js → reveal-IMGQ2EE5.js} +1 -2
  129. package/dist/{reveal-DDQBDWPM.js.map → reveal-IMGQ2EE5.js.map} +1 -1
  130. package/dist/{revoke-U7U3FMXU.js → revoke-POHP4GPB.js} +1 -2
  131. package/dist/satellites/index.js +0 -1
  132. package/dist/schema-update/index.js +0 -1
  133. package/dist/sealed-record/index.js +3 -4
  134. package/dist/sealed-record/index.js.map +1 -1
  135. package/dist/search/index.js +1 -2
  136. package/dist/{seed-3RXT4VGN.js → seed-UYR6YG3V.js} +1 -2
  137. package/dist/{seed-3RXT4VGN.js.map → seed-UYR6YG3V.js.map} +1 -1
  138. package/dist/sequence/index.js +0 -1
  139. package/dist/session/index.js +0 -1
  140. package/dist/session/index.js.map +1 -1
  141. package/dist/shadow/index.js +0 -1
  142. package/dist/shadow/index.js.map +1 -1
  143. package/dist/share-link/index.js +0 -1
  144. package/dist/share-link/index.js.map +1 -1
  145. package/dist/{signer-7NK7TMWU.js → signer-5K3WDHOC.js} +1 -2
  146. package/dist/snapshots/index.js +1 -2
  147. package/dist/snapshots/index.js.map +1 -1
  148. package/dist/{stale-2CHKZTMK.js → stale-AU74OPUW.js} +2 -3
  149. package/dist/{storage-WP4M7IFO.js → storage-AVJA5BTW.js} +1 -2
  150. package/dist/store/index.js +0 -1
  151. package/dist/{store-coordination-provider-O2VUEMJH.js → store-coordination-provider-RX2CGWXV.js} +1 -2
  152. package/dist/{store-coordination-provider-O2VUEMJH.js.map → store-coordination-provider-RX2CGWXV.js.map} +1 -1
  153. package/dist/sync/index.js +0 -1
  154. package/dist/sync/index.js.map +1 -1
  155. package/dist/team/index.js +0 -1
  156. package/dist/tiers/index.js +1 -2
  157. package/dist/to/index.js +0 -1
  158. package/dist/to/index.js.map +1 -1
  159. package/dist/transactions/index.js +2 -3
  160. package/dist/transactions/index.js.map +1 -1
  161. package/dist/{ulid-VQW6ERQN.js → ulid-4MKXG325.js} +1 -2
  162. package/dist/util/index.js +0 -1
  163. package/dist/util/index.js.map +1 -1
  164. package/dist/{vault-diff-FE5J35NJ.js → vault-diff-C6WUJFNP.js} +1 -2
  165. package/dist/vault-head/index.js +0 -1
  166. package/dist/vault-head/index.js.map +1 -1
  167. package/dist/{verify-JBXCAGDL.js → verify-KOV2G5D6.js} +1 -2
  168. package/dist/{verify-JBXCAGDL.js.map → verify-KOV2G5D6.js.map} +1 -1
  169. package/dist/{walk-P3E6QSNC.js → walk-ERAJ5RHO.js} +3 -4
  170. package/dist/with-formula/derivations/registry.d.ts +6 -0
  171. package/dist/with-shape/introspection/describe.d.ts +2 -53
  172. package/dist/with-shape/introspection/field-meta.d.ts +86 -0
  173. package/dist/{withdraw-accessible-6Q7NE4EY.js → withdraw-accessible-42D32Z7G.js} +4 -5
  174. package/package.json +7 -3
  175. package/dist/chunk-AJQY44CE.js.map +0 -1
  176. package/dist/chunk-BWXGSSFX.js.map +0 -1
  177. package/dist/chunk-PZ5AY32C.js +0 -10
  178. package/dist/chunk-URHRIAV6.js.map +0 -1
  179. package/dist/withdraw-accessible-6Q7NE4EY.js.map +0 -1
  180. package/dist/zod-HAJM7LMS.js +0 -14763
  181. package/dist/zod-HAJM7LMS.js.map +0 -1
  182. /package/dist/{api-UE2XQKDN.js.map → api-JPZT6BDD.js.map} +0 -0
  183. /package/dist/{chunk-5FUULQ6F.js.map → chunk-2HVILGVR.js.map} +0 -0
  184. /package/dist/{chunk-DJ3LNNZQ.js.map → chunk-3LK2XZCW.js.map} +0 -0
  185. /package/dist/{chunk-E2MYJGSG.js.map → chunk-AMODH7AU.js.map} +0 -0
  186. /package/dist/{chunk-B2ZSGYSF.js.map → chunk-B2KCRDJM.js.map} +0 -0
  187. /package/dist/{chunk-TO3EQ7HF.js.map → chunk-BLN54W3L.js.map} +0 -0
  188. /package/dist/{chunk-IHFXR2VQ.js.map → chunk-BOBFL5TW.js.map} +0 -0
  189. /package/dist/{chunk-ZR2YMODS.js.map → chunk-EKZ6VZYF.js.map} +0 -0
  190. /package/dist/{chunk-RTYJRFQO.js.map → chunk-EWPRPP3M.js.map} +0 -0
  191. /package/dist/{chunk-VGICZPVE.js.map → chunk-FUJSIP4K.js.map} +0 -0
  192. /package/dist/{chunk-PKJ43CMD.js.map → chunk-NLOLF6LD.js.map} +0 -0
  193. /package/dist/{chunk-COTPDJR5.js.map → chunk-OMB2ZKIT.js.map} +0 -0
  194. /package/dist/{chunk-BMELYFHU.js.map → chunk-P3KOF624.js.map} +0 -0
  195. /package/dist/{chunk-Y4MJQ2UG.js.map → chunk-QQ2YMQZU.js.map} +0 -0
  196. /package/dist/{chunk-YCXICMOY.js.map → chunk-RJ7NN2UR.js.map} +0 -0
  197. /package/dist/{chunk-PDD75NUZ.js.map → chunk-SMH6SRX7.js.map} +0 -0
  198. /package/dist/{chunk-QHW35ZON.js.map → chunk-TGPST6FK.js.map} +0 -0
  199. /package/dist/{chunk-BERJ4AWW.js.map → chunk-VGXZT72I.js.map} +0 -0
  200. /package/dist/{chunk-ZVCC36XQ.js.map → chunk-WL36WA3O.js.map} +0 -0
  201. /package/dist/{chunk-2Z47NMFK.js.map → chunk-WZW37ZHL.js.map} +0 -0
  202. /package/dist/{chunk-SXCYYMVS.js.map → chunk-YINEDONN.js.map} +0 -0
  203. /package/dist/{chunk-PZ5AY32C.js.map → collection-facade-VOWW732S.js.map} +0 -0
  204. /package/dist/{collection-facade-4ACKIDDY.js.map → computed-VPOKQK4N.js.map} +0 -0
  205. /package/dist/{computed-LSEZYRJS.js.map → derive-HHBRFS2U.js.map} +0 -0
  206. /package/dist/{derive-LY47HG7Q.js.map → enclave-VM2YQONI.js.map} +0 -0
  207. /package/dist/{enclave-4YBQK77G.js.map → executor-5NIMLSKZ.js.map} +0 -0
  208. /package/dist/{executor-MZJXBWNM.js.map → executor-5XJNV5H5.js.map} +0 -0
  209. /package/dist/{executor-TOLPBHOC.js.map → executor-AQVXV5GZ.js.map} +0 -0
  210. /package/dist/{executor-YDDC5XGY.js.map → export-accessible-2LOBM67T.js.map} +0 -0
  211. /package/dist/{export-accessible-LGV6IAFX.js.map → extract-partition-AZGSEMIF.js.map} +0 -0
  212. /package/dist/{extract-partition-RYJZIKQZ.js.map → find-2ABFCZX4.js.map} +0 -0
  213. /package/dist/{find-LC7P63MX.js.map → issue-RH4H733Z.js.map} +0 -0
  214. /package/dist/{issue-IOXM3RSJ.js.map → ledger-454SU3VE.js.map} +0 -0
  215. /package/dist/{ledger-HXHIOD36.js.map → liberate-AAZSP2BT.js.map} +0 -0
  216. /package/dist/{liberate-4APIV7FR.js.map → link-set-67CAMUAL.js.map} +0 -0
  217. /package/dist/{link-set-6RAHEKZN.js.map → managed-secret-NHRYG7CD.js.map} +0 -0
  218. /package/dist/{managed-secret-P3JQ7ZG4.js.map → noydb-F5CABCU4.js.map} +0 -0
  219. /package/dist/{noydb-2C6QQJ5S.js.map → read-only-facade-BIGO37U3.js.map} +0 -0
  220. /package/dist/{read-only-facade-CHCKSEPD.js.map → register-7OJWAWT5.js.map} +0 -0
  221. /package/dist/{register-AEOOGKNO.js.map → registry-23WF3TGH.js.map} +0 -0
  222. /package/dist/{registry-D2YXKRYC.js.map → registry-4AYVUNXK.js.map} +0 -0
  223. /package/dist/{registry-I6FP4677.js.map → registry-5MVJGPXW.js.map} +0 -0
  224. /package/dist/{registry-SHMGHEK4.js.map → registry-BOHIKFWG.js.map} +0 -0
  225. /package/dist/{registry-SKSOUXNF.js.map → request-withdrawal-P5EQATZ7.js.map} +0 -0
  226. /package/dist/{request-withdrawal-6HJT4ODF.js.map → revoke-POHP4GPB.js.map} +0 -0
  227. /package/dist/{revoke-U7U3FMXU.js.map → signer-5K3WDHOC.js.map} +0 -0
  228. /package/dist/{signer-7NK7TMWU.js.map → stale-AU74OPUW.js.map} +0 -0
  229. /package/dist/{stale-2CHKZTMK.js.map → storage-AVJA5BTW.js.map} +0 -0
  230. /package/dist/{storage-WP4M7IFO.js.map → ulid-4MKXG325.js.map} +0 -0
  231. /package/dist/{ulid-VQW6ERQN.js.map → vault-diff-C6WUJFNP.js.map} +0 -0
  232. /package/dist/{vault-diff-FE5J35NJ.js.map → walk-ERAJ5RHO.js.map} +0 -0
  233. /package/dist/{walk-P3E6QSNC.js.map → withdraw-accessible-42D32Z7G.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  walkClosure
3
- } from "./chunk-DJ3LNNZQ.js";
3
+ } from "./chunk-3LK2XZCW.js";
4
4
  import {
5
5
  resolveManagedSecret
6
6
  } from "./chunk-JUBWUJY5.js";
@@ -8,7 +8,7 @@ import {
8
8
  parseExtractedPartitionBody,
9
9
  readPod,
10
10
  readPodHeader
11
- } from "./chunk-PKJ43CMD.js";
11
+ } from "./chunk-NLOLF6LD.js";
12
12
  import {
13
13
  createOwnerKeyring,
14
14
  mintRosterTag,
@@ -41,7 +41,7 @@ import {
41
41
  function withCargo() {
42
42
  return {
43
43
  async extractPartition(vault, opts) {
44
- const { extractPartitionCore } = await import("./extract-partition-RYJZIKQZ.js");
44
+ const { extractPartitionCore } = await import("./extract-partition-AZGSEMIF.js");
45
45
  return extractPartitionCore(vault, opts);
46
46
  }
47
47
  };
@@ -252,7 +252,7 @@ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
252
252
  }
253
253
  }
254
254
  if (isManaged(opts)) {
255
- const { createNoydb } = await import("./noydb-2C6QQJ5S.js");
255
+ const { createNoydb } = await import("./noydb-F5CABCU4.js");
256
256
  const db = await createNoydb({
257
257
  store,
258
258
  user: userId,
@@ -307,4 +307,4 @@ export {
307
307
  withCargo,
308
308
  describeExtraction
309
309
  };
310
- //# sourceMappingURL=chunk-SXCYYMVS.js.map
310
+ //# sourceMappingURL=chunk-YINEDONN.js.map
@@ -3,9 +3,9 @@ import {
3
3
  } from "./chunk-TPHAGLUH.js";
4
4
  import {
5
5
  ViaGraph,
6
- computedEntryParts,
6
+ matchTargetFieldNames,
7
7
  schemaFieldKeys
8
- } from "./chunk-BWXGSSFX.js";
8
+ } from "./chunk-NJXX55QX.js";
9
9
  import {
10
10
  sha256Hex
11
11
  } from "./chunk-SL3JAAKN.js";
@@ -36,23 +36,6 @@ function stripArtifactSuffix(displayId) {
36
36
  const suffix = `.${WHOLE_RECORD}`;
37
37
  return displayId.endsWith(suffix) ? displayId.slice(0, -suffix.length) : displayId;
38
38
  }
39
- function matchTargetFieldNames(opts) {
40
- const declared = [];
41
- const virtual = [];
42
- for (const [field, entry] of Object.entries(opts.computed ?? {})) {
43
- declared.push(field);
44
- const parts = computedEntryParts(entry);
45
- if (parts.mode === "virtual") virtual.push(field);
46
- }
47
- for (const [field, spec] of Object.entries(opts.viaFields ?? {})) {
48
- declared.push(field);
49
- const descriptors = spec.descriptors ?? [];
50
- for (const d of descriptors) {
51
- if (d._viaBrand === "computed" && d.mode === "virtual") virtual.push(field);
52
- }
53
- }
54
- return { declared, virtual };
55
- }
56
39
  var DerivationRegistry = class {
57
40
  _bySource = /* @__PURE__ */ new Map();
58
41
  _byOutput = /* @__PURE__ */ new Map();
@@ -252,4 +235,4 @@ var DerivationRegistry = class {
252
235
  export {
253
236
  DerivationRegistry
254
237
  };
255
- //# sourceMappingURL=chunk-AJQY44CE.js.map
238
+ //# sourceMappingURL=chunk-ZXLZ62R5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/derivations/strategy-hash.ts","../src/with-formula/derivations/registry.ts"],"sourcesContent":["/**\n * Deterministic hash of a derivation strategy's \"shape\": source\n * collection, declared sibling sources, output keys, derive function\n * source. Used to detect\n * strategy drift: a record whose `_derivedFrom.strategyHash` doesn't\n * match the current strategy is considered stale.\n *\n * Web Crypto SHA-256 — no extra deps.\n */\nimport { sha256Hex } from '../../kernel/enclave/index.js'\n\nexport async function computeStrategyHash(\n source: string,\n outputKeys: readonly string[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n derive: (...args: any[]) => any,\n sources?: ReadonlyArray<string>,\n): Promise<string> {\n const canonical = JSON.stringify({\n source,\n outputs: [...outputKeys].sort(),\n derive: derive.toString(),\n // Declared sibling sources — adding/removing a trigger\n // collection invalidates cached derived records. Omitted when empty\n // so strategies without siblings keep their existing hash.\n ...(sources?.length ? { sources: [...sources].sort() } : {}),\n })\n const bytes = new TextEncoder().encode(canonical)\n return sha256Hex(bytes)\n}\n","import { matchTargetFieldNames } from '../../kernel/collection-config.js'\nimport { DerivationCycleError, DuplicateBehaviorNameError, ValidationError } from '../../kernel/errors.js'\nimport { ViaGraph, type FieldRef, type EdgeKind, type Grain } from '../../kernel/via/graph.js'\nimport { schemaFieldKeys } from '../../with-shape/introspection/describe.js'\nimport { computeStrategyHash } from './strategy-hash.js'\nimport { normalizeTriggerBy, type NormalizedTrigger } from './trigger-match.js'\nimport type { DerivationSpec } from './types.js'\n\n/**\n * Whole-record artifact-grain field marker (#638 Task 2). A derivation's\n * `derive()`/a rollup's `compute()` reads the WHOLE source record — there is\n * no single declared field to point at — so a trigger/output collection is\n * modelled as one artifact node per collection (`kernel/via/graph.ts`'s\n * \"Artifact-grain targets... modelled as a field node whose field is the\n * artifact key\" convention). MUST match `materialized-views/registry.ts`'s\n * and `vault.ts`'s overlay-edge marker so cross-registry edges (a derivation\n * feeding into / out of an MV or overlay collection) resolve to the SAME\n * graph node.\n */\nconst WHOLE_RECORD = '*'\n\n/** Strip this registry's `.${WHOLE_RECORD}` artifact suffix off a graph cycle\n * path entry, recovering the bare collection name — preserves the exact\n * pre-#638 `DerivationCycleError` message shape (behavior lock) for a pure\n * record-shape derivation cycle. A rollup's real-field target (not suffixed\n * `.${WHOLE_RECORD}`) is left untouched. */\nfunction stripArtifactSuffix(displayId: string): string {\n const suffix = `.${WHOLE_RECORD}`\n return displayId.endsWith(suffix) ? displayId.slice(0, -suffix.length) : displayId\n}\n\ninterface RegisteredStrategy {\n // Type-erased to allow the registry to hold heterogeneous strategies.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n spec: DerivationSpec<any, any>\n strategyHash: string\n readonly triggers: ReadonlyArray<NormalizedTrigger>\n}\n\n/**\n * Vault-internal registry of derivation strategies. Owned by `Vault`;\n * not exported.\n *\n * @internal\n */\nexport class DerivationRegistry {\n private readonly _bySource = new Map<string, RegisteredStrategy[]>()\n private readonly _byOutput = new Map<string, RegisteredStrategy[]>()\n private readonly _byName = new Map<string, RegisteredStrategy>()\n\n /**\n * Register a derivation strategy. If `spec.name` is given and already\n * registered by another derivation in this vault, throws\n * {@link DuplicateBehaviorNameError} before indexing.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async register(spec: DerivationSpec<any, any>): Promise<void> {\n if (spec.name !== undefined && this._byName.has(spec.name)) {\n throw new DuplicateBehaviorNameError(spec.name, 'derivation')\n }\n\n const outputKeys = Object.keys(spec.outputs)\n const strategyHash = await computeStrategyHash(spec.source, outputKeys, spec.derive, spec.sources)\n const triggers = normalizeTriggerBy(spec.triggerBy)\n const reg: RegisteredStrategy = { spec, strategyHash, triggers }\n\n if (spec.name !== undefined) this._byName.set(spec.name, reg)\n\n const fromSource = this._bySource.get(spec.source)\n if (fromSource) fromSource.push(reg)\n else this._bySource.set(spec.source, [reg])\n\n // Declared sibling sources index the SAME `reg` under each\n // extra collection so `strategiesForSource(extra)` returns it and a\n // sibling write re-fires the derivation. Sibling keys also enter\n // `_bySource`, so `validate()`'s cycle DFS walks them automatically.\n for (const extra of spec.sources ?? []) {\n const fromExtra = this._bySource.get(extra)\n if (fromExtra) fromExtra.push(reg)\n else this._bySource.set(extra, [reg])\n }\n\n // FK triggers index the SAME `reg` under each parent collection so\n // a parent write re-fires the derivation (fanned out to matching source\n // records in `dispatchDerivations`). Like sources[], these keys enter\n // `_bySource` so the cycle DFS walks the trigger→output edge.\n for (const t of triggers) {\n const fromTrigger = this._bySource.get(t.collection)\n if (fromTrigger) fromTrigger.push(reg)\n else this._bySource.set(t.collection, [reg])\n }\n\n // Rollup: a write to the child `from` collection recomputes\n // the parent (= spec.source = into) at id child[key]. Index under `from`\n // so a child write fires it; spec.source (into) is already indexed above,\n // so a parent write also recomputes its own aggregate (covers the\n // parent-created-after-children case). The from→into edge enters the cycle\n // DFS automatically.\n if (spec.rollup) {\n const fromRollup = this._bySource.get(spec.rollup.from)\n if (fromRollup) fromRollup.push(reg)\n else this._bySource.set(spec.rollup.from, [reg])\n }\n\n for (const key of outputKeys) {\n const output = spec.outputs[key]\n if (!output) continue\n const outputCollection = output.collection\n const arr = this._byOutput.get(outputCollection)\n if (arr) arr.push(reg)\n else this._byOutput.set(outputCollection, [reg])\n }\n }\n\n strategiesForSource(source: string): ReadonlyArray<RegisteredStrategy> {\n return this._bySource.get(source) ?? []\n }\n\n strategiesProducingOutput(collection: string): ReadonlyArray<RegisteredStrategy> {\n return this._byOutput.get(collection) ?? []\n }\n\n /**\n * The #1253-pattern typo guard for match fields (#1249): a misspelt\n * `to`/`from` silently matches nothing forever, so validate against the\n * collection's enumerable field set at the earliest point it exists.\n * `schemaFieldKeys(schema) === undefined` (TS-generic collection,\n * unreadable validator) is DELIBERATELY silent — those fields are real\n * and unenumerable. `configKeys` folds in the collection's other\n * non-schema field declarations (fieldMeta/moneyFields/dictKeyFields/\n * refs/computed); `denormExempt` is derived here from this registry's\n * own strategies rather than taken as a parameter — a field this\n * collection's own derivations write via `denorm` is never a typo.\n */\n validateFieldsFor(\n collectionName: string,\n schema: unknown,\n configKeys: ReadonlyArray<string>,\n viaSources: {\n readonly computed?: Readonly<Record<string, unknown>> | undefined\n readonly viaFields?: Readonly<Record<string, unknown>> | undefined\n } | undefined = undefined,\n ): void {\n const targets = matchTargetFieldNames(viaSources ?? {})\n const virtual = new Set(targets.virtual)\n const shapeKeys = schemaFieldKeys(schema)\n // The two checks have DIFFERENT preconditions, which is why one loop runs\n // both rather than an early return covering both. The typo check needs a\n // readable field list and must stay silent without one — a false \"unknown\n // field\" on a TS-generic collection would be worse than no check. The\n // virtual check needs nothing but the declaration in hand: \"declared, and\n // never stored\" is provable from the declaration alone (#1266).\n if (shapeKeys === undefined && virtual.size === 0) return\n const keys = shapeKeys === undefined ? undefined\n : new Set([...shapeKeys, ...configKeys, ...targets.declared])\n const denormExempt = new Set<string>()\n const regs = new Set([...this._bySource.values()].flat())\n for (const reg of regs) {\n if (reg.spec.source !== collectionName) continue\n for (const out of Object.values(reg.spec.outputs) as Array<{ collection?: string; denorm?: readonly string[] }>) {\n if (out.collection === collectionName) for (const d of out.denorm ?? []) denormExempt.add(d)\n }\n }\n const unknown = (f: string): boolean =>\n keys !== undefined && !keys.has(f) && !denormExempt.has(f)\n for (const reg of regs) {\n const name = reg.spec.name ?? reg.spec.source\n for (const t of reg.triggers) {\n for (const p of t.match) {\n // `to` reads the SOURCE record; `from` reads the WRITTEN record.\n // Both are the stored shape, so both refuse a virtual target.\n if (reg.spec.source === collectionName) {\n if (virtual.has(p.to)) throw new ValidationError(this._virtualMatchMessage(name, collectionName, p.to, 'to'))\n if (unknown(p.to)) {\n throw new ValidationError(\n `derivation \"${name}\": triggerBy match names source field \"${p.to}\", which \"${collectionName}\" does not declare — a typo here silently matches nothing forever`)\n }\n }\n if (t.collection === collectionName && p.from !== 'id') {\n if (virtual.has(p.from)) throw new ValidationError(this._virtualMatchMessage(name, collectionName, p.from, 'from'))\n if (unknown(p.from)) {\n throw new ValidationError(\n `derivation \"${name}\": triggerBy match reads \"${p.from}\" from written \"${collectionName}\" records, which that collection does not declare — a typo here silently matches nothing forever`)\n }\n }\n }\n }\n }\n }\n\n /** #1266 — one message shape for both match sides; see {@link matchTargetFieldNames}. */\n private _virtualMatchMessage(name: string, collectionName: string, field: string, side: 'to' | 'from'): string {\n const where = side === 'to'\n ? `names source field \"${field}\", which \"${collectionName}\"`\n : `reads \"${field}\" from written \"${collectionName}\" records, which that collection`\n return `derivation \"${name}\": triggerBy match ${where} declares as a VIRTUAL computed field — virtual fields are evaluated on read and never stored, so the matcher would read every candidate record and match nothing, forever. Declare it as \\`mode: 'materialized'\\` (stored, indexable) or match on a stored field.`\n }\n\n /**\n * All registered strategies as a flat, deduplicated array.\n * Each strategy is indexed once per source (not once per output key),\n * so iterating `_bySource.values()` naturally yields each strategy\n * exactly once per source — deduplication is handled by flattening\n * the per-source arrays and collecting into a Set by identity.\n *\n * Used by `dumpSchema()` / `describeDerivations()` in the introspection\n * walker to populate the derivations map.\n */\n all(): ReadonlyArray<RegisteredStrategy> {\n const seen = new Set<RegisteredStrategy>()\n for (const strategies of this._bySource.values()) {\n for (const s of strategies) seen.add(s)\n }\n return [...seen]\n }\n\n /**\n * Graph edges for #638 Task 2: one `'derivation'`/`'record'` edge per\n * (non-self-write) output key — target = the output collection (a\n * `WHOLE_RECORD` artifact node), sources = every collection that can\n * trigger this strategy (`source`, `sources[]`, `triggerBy[].collection`,\n * and — for a rollup — `rollup.from`), mirroring EXACTLY the trigger keys\n * `register()` indexes under `_bySource`. The self-write reverse-denorm\n * output (`output.collection === source` with `denorm` declared) is\n * skipped — the SAME condition the old local DFS used; it is not a cycle\n * (see the comment `validate()` used to carry, now on this skip).\n * Rollups ADDITIONALLY get a dedicated `'rollup'`/`'aggregate'` edge\n * targeting the real `rollup.field` on the parent (`source`) — the\n * self-write output above only covers the cycle-DFS skip, not\n * dispatch/taint (Tasks 3/4/6), which need the real field.\n */\n edges(): ReadonlyArray<{ readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly kind: EdgeKind; readonly grain: Grain }> {\n const out: Array<{ target: FieldRef; sources: FieldRef[]; kind: EdgeKind; grain: Grain }> = []\n for (const reg of this.all()) {\n const spec = reg.spec\n const triggerCollections = [\n spec.source,\n ...(spec.sources ?? []),\n ...(spec.triggerBy ?? []).map((t) => t.collection),\n ...(spec.rollup ? [spec.rollup.from] : []),\n ]\n const sources: FieldRef[] = triggerCollections.map((c) => ({ collection: c, field: WHOLE_RECORD }))\n for (const key of Object.keys(spec.outputs)) {\n const output = spec.outputs[key]\n if (!output) continue\n if (output.shape === 'record' && output.collection === spec.source && output.denorm !== undefined) continue\n out.push({ target: { collection: output.collection, field: WHOLE_RECORD }, sources, kind: 'derivation', grain: 'record' })\n }\n if (spec.rollup) {\n out.push({\n target: { collection: spec.source, field: spec.rollup.field },\n sources: [{ collection: spec.rollup.from, field: WHOLE_RECORD }],\n kind: 'rollup',\n grain: 'aggregate',\n })\n }\n }\n return out\n }\n\n /**\n * Cycle detection, delegated to `ViaGraph.assertAcyclic()` (#638 Task 2 —\n * retires the local DFS). Call after all `register()` calls complete (i.e.\n * at vault open). Throws `DerivationCycleError` on the first cycle found —\n * SAME class/timing as before; the message/path is byte-identical to the\n * pre-#638 shape for a pure record-shape derivation cycle (the\n * `WHOLE_RECORD` artifact suffix is stripped back to a bare collection\n * name before re-throwing).\n *\n * `graph` is the caller's shared per-vault graph, ALREADY carrying this\n * registry's `edges()` (the caller registers them — see `Vault._initDerivations`)\n * — omit it (e.g. this registry's own unit tests) to validate this\n * registry's edges in isolation against a throwaway graph.\n */\n validate(graph?: ViaGraph): void {\n const g = graph ?? new ViaGraph()\n if (!graph) {\n for (const edge of this.edges()) g.registerDerived(edge.target, edge.sources, edge.kind, edge.grain)\n }\n try {\n g.assertAcyclic()\n } catch (e) {\n if (e instanceof DerivationCycleError) throw new DerivationCycleError(e.path.map(stripArtifactSuffix))\n throw e\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  classified,
3
3
  luhnCheck,
4
4
  withClassified
5
- } from "../chunk-5FUULQ6F.js";
5
+ } from "../chunk-2HVILGVR.js";
6
6
  import {
7
7
  ClassifiedNeverStoredError,
8
8
  ClassifiedValidationError,
@@ -20,7 +20,6 @@ import {
20
20
  ClassifiedRotationError,
21
21
  ClassifiedVerifyError
22
22
  } from "../chunk-7O3Y4PPD.js";
23
- import "../chunk-PZ5AY32C.js";
24
23
  export {
25
24
  ClassifiedConfigError,
26
25
  ClassifiedNeverStoredError,
@@ -1,5 +1,3 @@
1
- import "./chunk-PZ5AY32C.js";
2
-
3
1
  // src/via/classified/config-drift.ts
4
2
  function markerForFields(vdigFields) {
5
3
  if (vdigFields === null || vdigFields.size === 0) return null;
@@ -13,11 +11,11 @@ function markerForFields(vdigFields) {
13
11
  async function persistClassifiedMarkerForFields(store, vault, collectionName, vdigFields, dek) {
14
12
  const marker = markerForFields(vdigFields);
15
13
  if (marker === null) return;
16
- const { persistClassifiedMarker } = await import("./register-AEOOGKNO.js");
14
+ const { persistClassifiedMarker } = await import("./register-7OJWAWT5.js");
17
15
  await persistClassifiedMarker({ store, vault, collectionName, dek, marker });
18
16
  }
19
17
  async function readClassifiedMarkerDigestOnly(store, vault, collectionName, dek) {
20
- const { loadPersistedSchema } = await import("./storage-WP4M7IFO.js");
18
+ const { loadPersistedSchema } = await import("./storage-AVJA5BTW.js");
21
19
  const persisted = await loadPersistedSchema(store, vault, collectionName, dek);
22
20
  return persisted?.classified?.digestOnly ?? [];
23
21
  }
@@ -25,4 +23,4 @@ export {
25
23
  persistClassifiedMarkerForFields,
26
24
  readClassifiedMarkerDigestOnly
27
25
  };
28
- //# sourceMappingURL=classified-marker-67HBIJMZ.js.map
26
+ //# sourceMappingURL=classified-marker-OO65UYXN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/via/classified/config-drift.ts"],"sourcesContent":["/**\n * C-A / R10 config-drift marker I/O — the store side of the guard, kept OUT of\n * the kernel `Collection` so the always-on kernel surface stays lean. The\n * kernel holds only the per-handle memoization; these helpers do the actual\n * persisted-schema read/write (via the persisted-schemas storage seam, lazily\n * imported so the classified spine tree-shakes).\n *\n * Marker semantics: a collection declaring classified digest-only fields writes\n * an `x-classified` marker into its `_schemas/<collection>` record on the first\n * classified write. A handle later opened WITHOUT `classifiedFields` (a naive\n * handle) reads it back and refuses to write — see RecordCodec.encryptRecord's\n * R10 guard.\n *\n * `dek` is typed as the bare `CryptoKey` global rather than `EnclaveKey`\n * (`kernel/enclave/crypto.ts`'s alias for the same type) — this file lives\n * under `via/classified/`, which the `via-enclave-isolation`\n * architecture guard (#629) forbids from importing `kernel/enclave/` at\n * all, even type-only.\n *\n * @module\n */\nimport type { NoydbStore, VdigFieldPolicy, ClassifiedMarker } from '../../kernel/types.js'\n\n/**\n * Build the marker for a handle's digest-only field map, or null when it\n * declares none. `epoch` (#597) is stamped fresh on every call, but only\n * ever lands in storage on a genuine first-write or a real reconfiguration —\n * `persistClassifiedMarker`'s equality check (register.ts) ignores epoch, so\n * an identical re-declare's freshly-stamped value is discarded as a no-op\n * and the already-persisted epoch is left untouched (stable per lifetime).\n */\nfunction markerForFields(vdigFields: ReadonlyMap<string, VdigFieldPolicy> | null): ClassifiedMarker | null {\n if (vdigFields === null || vdigFields.size === 0) return null\n const digestOnly = [...vdigFields.keys()]\n return {\n digestOnly, equatable: digestOnly.filter((f) => vdigFields.get(f)?.equatable === true),\n epoch: new Date().toISOString(),\n }\n}\n\n/**\n * Persist the classified marker for a handle's digest-only fields. No-op when\n * the handle declares none. Idempotent (delegates to `persistClassifiedMarker`).\n */\nexport async function persistClassifiedMarkerForFields(\n store: NoydbStore,\n vault: string,\n collectionName: string,\n vdigFields: ReadonlyMap<string, VdigFieldPolicy> | null,\n dek: CryptoKey,\n): Promise<void> {\n const marker = markerForFields(vdigFields)\n if (marker === null) return\n const { persistClassifiedMarker } = await import('../../with-shape/persisted-schemas/register.js')\n await persistClassifiedMarker({ store, vault, collectionName, dek, marker })\n}\n\n/**\n * Read a collection's persisted classified marker's declared digest-only field\n * set (empty when the collection carries no marker). Cross-session drift signal:\n * the R10 superset guard refuses a handle whose declared classified set does not\n * cover every field in this set.\n */\nexport async function readClassifiedMarkerDigestOnly(\n store: NoydbStore,\n vault: string,\n collectionName: string,\n dek: CryptoKey,\n): Promise<readonly string[]> {\n const { loadPersistedSchema } = await import('../../with-shape/persisted-schemas/storage.js')\n const persisted = await loadPersistedSchema(store, vault, collectionName, dek)\n return persisted?.classified?.digestOnly ?? []\n}\n"],"mappings":";;;AA+BA,SAAS,gBAAgB,YAAkF;AACzG,MAAI,eAAe,QAAQ,WAAW,SAAS,EAAG,QAAO;AACzD,QAAM,aAAa,CAAC,GAAG,WAAW,KAAK,CAAC;AACxC,SAAO;AAAA,IACL;AAAA,IAAY,WAAW,WAAW,OAAO,CAAC,MAAM,WAAW,IAAI,CAAC,GAAG,cAAc,IAAI;AAAA,IACrF,QAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,EAChC;AACF;AAMA,eAAsB,iCACpB,OACA,OACA,gBACA,YACA,KACe;AACf,QAAM,SAAS,gBAAgB,UAAU;AACzC,MAAI,WAAW,KAAM;AACrB,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,wBAAgD;AACjG,QAAM,wBAAwB,EAAE,OAAO,OAAO,gBAAgB,KAAK,OAAO,CAAC;AAC7E;AAQA,eAAsB,+BACpB,OACA,OACA,gBACA,KAC4B;AAC5B,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,uBAA+C;AAC5F,QAAM,YAAY,MAAM,oBAAoB,OAAO,OAAO,gBAAgB,GAAG;AAC7E,SAAO,WAAW,YAAY,cAAc,CAAC;AAC/C;","names":[]}
1
+ {"version":3,"sources":["../src/via/classified/config-drift.ts"],"sourcesContent":["/**\n * C-A / R10 config-drift marker I/O — the store side of the guard, kept OUT of\n * the kernel `Collection` so the always-on kernel surface stays lean. The\n * kernel holds only the per-handle memoization; these helpers do the actual\n * persisted-schema read/write (via the persisted-schemas storage seam, lazily\n * imported so the classified spine tree-shakes).\n *\n * Marker semantics: a collection declaring classified digest-only fields writes\n * an `x-classified` marker into its `_schemas/<collection>` record on the first\n * classified write. A handle later opened WITHOUT `classifiedFields` (a naive\n * handle) reads it back and refuses to write — see RecordCodec.encryptRecord's\n * R10 guard.\n *\n * `dek` is typed as the bare `CryptoKey` global rather than `EnclaveKey`\n * (`kernel/enclave/crypto.ts`'s alias for the same type) — this file lives\n * under `via/classified/`, which the `via-enclave-isolation`\n * architecture guard (#629) forbids from importing `kernel/enclave/` at\n * all, even type-only.\n *\n * @module\n */\nimport type { NoydbStore, VdigFieldPolicy, ClassifiedMarker } from '../../kernel/types.js'\n\n/**\n * Build the marker for a handle's digest-only field map, or null when it\n * declares none. `epoch` (#597) is stamped fresh on every call, but only\n * ever lands in storage on a genuine first-write or a real reconfiguration —\n * `persistClassifiedMarker`'s equality check (register.ts) ignores epoch, so\n * an identical re-declare's freshly-stamped value is discarded as a no-op\n * and the already-persisted epoch is left untouched (stable per lifetime).\n */\nfunction markerForFields(vdigFields: ReadonlyMap<string, VdigFieldPolicy> | null): ClassifiedMarker | null {\n if (vdigFields === null || vdigFields.size === 0) return null\n const digestOnly = [...vdigFields.keys()]\n return {\n digestOnly, equatable: digestOnly.filter((f) => vdigFields.get(f)?.equatable === true),\n epoch: new Date().toISOString(),\n }\n}\n\n/**\n * Persist the classified marker for a handle's digest-only fields. No-op when\n * the handle declares none. Idempotent (delegates to `persistClassifiedMarker`).\n */\nexport async function persistClassifiedMarkerForFields(\n store: NoydbStore,\n vault: string,\n collectionName: string,\n vdigFields: ReadonlyMap<string, VdigFieldPolicy> | null,\n dek: CryptoKey,\n): Promise<void> {\n const marker = markerForFields(vdigFields)\n if (marker === null) return\n const { persistClassifiedMarker } = await import('../../with-shape/persisted-schemas/register.js')\n await persistClassifiedMarker({ store, vault, collectionName, dek, marker })\n}\n\n/**\n * Read a collection's persisted classified marker's declared digest-only field\n * set (empty when the collection carries no marker). Cross-session drift signal:\n * the R10 superset guard refuses a handle whose declared classified set does not\n * cover every field in this set.\n */\nexport async function readClassifiedMarkerDigestOnly(\n store: NoydbStore,\n vault: string,\n collectionName: string,\n dek: CryptoKey,\n): Promise<readonly string[]> {\n const { loadPersistedSchema } = await import('../../with-shape/persisted-schemas/storage.js')\n const persisted = await loadPersistedSchema(store, vault, collectionName, dek)\n return persisted?.classified?.digestOnly ?? []\n}\n"],"mappings":";AA+BA,SAAS,gBAAgB,YAAkF;AACzG,MAAI,eAAe,QAAQ,WAAW,SAAS,EAAG,QAAO;AACzD,QAAM,aAAa,CAAC,GAAG,WAAW,KAAK,CAAC;AACxC,SAAO;AAAA,IACL;AAAA,IAAY,WAAW,WAAW,OAAO,CAAC,MAAM,WAAW,IAAI,CAAC,GAAG,cAAc,IAAI;AAAA,IACrF,QAAO,oBAAI,KAAK,GAAE,YAAY;AAAA,EAChC;AACF;AAMA,eAAsB,iCACpB,OACA,OACA,gBACA,YACA,KACe;AACf,QAAM,SAAS,gBAAgB,UAAU;AACzC,MAAI,WAAW,KAAM;AACrB,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,wBAAgD;AACjG,QAAM,wBAAwB,EAAE,OAAO,OAAO,gBAAgB,KAAK,OAAO,CAAC;AAC7E;AAQA,eAAsB,+BACpB,OACA,OACA,gBACA,KAC4B;AAC5B,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,uBAA+C;AAC5F,QAAM,YAAY,MAAM,oBAAoB,OAAO,OAAO,gBAAgB,GAAG;AAC7E,SAAO,WAAW,YAAY,cAAc,CAAC;AAC/C;","names":[]}
@@ -10,9 +10,9 @@ import {
10
10
  similarTo,
11
11
  syncTierSearch,
12
12
  warmIndex
13
- } from "./chunk-IHFXR2VQ.js";
13
+ } from "./chunk-BOBFL5TW.js";
14
14
  import "./chunk-RTBJ5IOO.js";
15
- import "./chunk-COTPDJR5.js";
15
+ import "./chunk-OMB2ZKIT.js";
16
16
  import "./chunk-AURFOK3D.js";
17
17
  import "./chunk-MVMXZYXT.js";
18
18
  import "./chunk-RDZZHYMV.js";
@@ -29,7 +29,6 @@ import "./chunk-LP7BEXCT.js";
29
29
  import "./chunk-SL3JAAKN.js";
30
30
  import "./chunk-N4CHCXDL.js";
31
31
  import "./chunk-7O3Y4PPD.js";
32
- import "./chunk-PZ5AY32C.js";
33
32
  export {
34
33
  buildPersistedIndexCallbacks,
35
34
  buildRetrievalDocs,
@@ -43,4 +42,4 @@ export {
43
42
  syncTierSearch,
44
43
  warmIndex
45
44
  };
46
- //# sourceMappingURL=collection-facade-4ACKIDDY.js.map
45
+ //# sourceMappingURL=collection-facade-VOWW732S.js.map
@@ -3,9 +3,8 @@ import {
3
3
  evalComputedFields
4
4
  } from "./chunk-LWBCUYZW.js";
5
5
  import "./chunk-7O3Y4PPD.js";
6
- import "./chunk-PZ5AY32C.js";
7
6
  export {
8
7
  ComputedFieldError,
9
8
  evalComputedFields
10
9
  };
11
- //# sourceMappingURL=computed-LSEZYRJS.js.map
10
+ //# sourceMappingURL=computed-VPOKQK4N.js.map
@@ -16,7 +16,6 @@ import "../chunk-LP7BEXCT.js";
16
16
  import "../chunk-SL3JAAKN.js";
17
17
  import "../chunk-N4CHCXDL.js";
18
18
  import "../chunk-7O3Y4PPD.js";
19
- import "../chunk-PZ5AY32C.js";
20
19
 
21
20
  // src/with-audit/consent/active.ts
22
21
  function withConsent() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/with-audit/consent/active.ts"],"sourcesContent":["/**\n * Active consent strategy. Calling `withConsent()` returns a\n * `ConsentStrategy` that delegates to the real\n * `writeConsentEntry` / `loadConsentEntries` functions. Only\n * reachable through the `@noy-db/hub/consent` subpath.\n */\n\nimport { writeConsentEntry, loadConsentEntries } from './consent.js'\nimport type { ConsentStrategy } from './strategy.js'\n\n/**\n * Build the default consent strategy. Pass into\n * `createNoydb({ consentStrategy: withConsent() })` to enable\n * per-operation audit writes into the reserved `_consent_audit`\n * collection.\n */\nexport function withConsent(): ConsentStrategy {\n return {\n write: writeConsentEntry,\n read: loadConsentEntries,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAgBO,SAAS,cAA+B;AAC7C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/with-audit/consent/active.ts"],"sourcesContent":["/**\n * Active consent strategy. Calling `withConsent()` returns a\n * `ConsentStrategy` that delegates to the real\n * `writeConsentEntry` / `loadConsentEntries` functions. Only\n * reachable through the `@noy-db/hub/consent` subpath.\n */\n\nimport { writeConsentEntry, loadConsentEntries } from './consent.js'\nimport type { ConsentStrategy } from './strategy.js'\n\n/**\n * Build the default consent strategy. Pass into\n * `createNoydb({ consentStrategy: withConsent() })` to enable\n * per-operation audit writes into the reserved `_consent_audit`\n * collection.\n */\nexport function withConsent(): ConsentStrategy {\n return {\n write: writeConsentEntry,\n read: loadConsentEntries,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgBO,SAAS,cAA+B;AAC7C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;","names":[]}
@@ -24,7 +24,6 @@ import "../chunk-LP7BEXCT.js";
24
24
  import "../chunk-SL3JAAKN.js";
25
25
  import "../chunk-N4CHCXDL.js";
26
26
  import "../chunk-7O3Y4PPD.js";
27
- import "../chunk-PZ5AY32C.js";
28
27
  export {
29
28
  COVER_FIELDS,
30
29
  COVER_RECORD_ID,
@@ -7,7 +7,6 @@ import {
7
7
  import {
8
8
  NO_CRDT
9
9
  } from "../chunk-PVEWA2DU.js";
10
- import "../chunk-PZ5AY32C.js";
11
10
 
12
11
  // src/with-commit/crdt/active.ts
13
12
  function withCrdt() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/with-commit/crdt/active.ts"],"sourcesContent":["/**\n * Active CRDT strategy factory. Calling `withCrdt()` returns a\n * `CrdtStrategy` whose methods delegate to the real LWW-Map / RGA /\n * merge / snapshot helpers in `./crdt.ts`. Only reachable through\n * the `@noy-db/hub/crdt` subpath.\n */\n\nimport {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n} from './crdt.js'\nimport type { CrdtStrategy } from './strategy.js'\n\n/**\n * Build the default CRDT strategy. Pass into\n * `createNoydb({ crdtStrategy: withCrdt() })` to enable collections\n * declared with `crdt: 'lww-map' | 'rga' | 'yjs'`.\n *\n * @example\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withCrdt } from '@noy-db/hub/crdt'\n *\n * const db = await createNoydb({\n * store, user, secret,\n * crdtStrategy: withCrdt(),\n * })\n * const notes = vault.collection('notes', { crdt: 'lww-map' })\n * ```\n */\nexport function withCrdt(): CrdtStrategy {\n return {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n }\n}\n"],"mappings":";;;;;;;;;;;;AAgCO,SAAS,WAAyB;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/with-commit/crdt/active.ts"],"sourcesContent":["/**\n * Active CRDT strategy factory. Calling `withCrdt()` returns a\n * `CrdtStrategy` whose methods delegate to the real LWW-Map / RGA /\n * merge / snapshot helpers in `./crdt.ts`. Only reachable through\n * the `@noy-db/hub/crdt` subpath.\n */\n\nimport {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n} from './crdt.js'\nimport type { CrdtStrategy } from './strategy.js'\n\n/**\n * Build the default CRDT strategy. Pass into\n * `createNoydb({ crdtStrategy: withCrdt() })` to enable collections\n * declared with `crdt: 'lww-map' | 'rga' | 'yjs'`.\n *\n * @example\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withCrdt } from '@noy-db/hub/crdt'\n *\n * const db = await createNoydb({\n * store, user, secret,\n * crdtStrategy: withCrdt(),\n * })\n * const notes = vault.collection('notes', { crdt: 'lww-map' })\n * ```\n */\nexport function withCrdt(): CrdtStrategy {\n return {\n buildLwwMapState,\n buildRgaState,\n mergeCrdtStates,\n resolveCrdtSnapshot,\n }\n}\n"],"mappings":";;;;;;;;;;;AAgCO,SAAS,WAAyB;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  CustodyApi,
3
3
  NO_CUSTODY,
4
4
  withCustody
5
- } from "../chunk-Y4MJQ2UG.js";
5
+ } from "../chunk-QQ2YMQZU.js";
6
6
  import "../chunk-VNR2SNVJ.js";
7
7
  import "../chunk-YQWBEJCS.js";
8
8
  import "../chunk-JMGDHKQF.js";
@@ -17,7 +17,6 @@ import "../chunk-N4CHCXDL.js";
17
17
  import {
18
18
  CustodyNotEnabledError
19
19
  } from "../chunk-7O3Y4PPD.js";
20
- import "../chunk-PZ5AY32C.js";
21
20
  export {
22
21
  CustodyApi,
23
22
  CustodyNotEnabledError,
@@ -1,11 +1,10 @@
1
1
  import {
2
2
  liveBaseIdSet
3
3
  } from "./chunk-GYGLAVCX.js";
4
- import "./chunk-PZ5AY32C.js";
5
4
 
6
5
  // src/with-shape/satellites/dead-filter.ts
7
6
  async function liveBaseIdSetsForBundle(store, vaultName, collectionNames, getDEK) {
8
- const { loadPersistedSchema } = await import("./storage-WP4M7IFO.js");
7
+ const { loadPersistedSchema } = await import("./storage-AVJA5BTW.js");
9
8
  const out = /* @__PURE__ */ new Map();
10
9
  for (const name of collectionNames) {
11
10
  if (name.startsWith("_")) continue;
@@ -25,4 +24,4 @@ async function liveBaseIdSetsForBundle(store, vaultName, collectionNames, getDEK
25
24
  export {
26
25
  liveBaseIdSetsForBundle
27
26
  };
28
- //# sourceMappingURL=dead-filter-M3NZUWBZ.js.map
27
+ //# sourceMappingURL=dead-filter-OMMVBAKZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/with-shape/satellites/dead-filter.ts"],"sourcesContent":["import type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport { liveBaseIdSet } from './existence.js'\n\n/**\n * Build a live-base id set for every satellite collection detectable from\n * its persisted `_schemas/<name>` pairing marker (#591 Task 10).\n *\n * The bundle-export path (`with-pod/bundle.ts`) has no reachable\n * `SatelliteRegistry` — that registry is private to `Vault` and adding an\n * accessor would grow a kernel file past its line-ceiling ratchet. The\n * marker persisted by `ensureSatelliteMarker` (`_schemas/<satellite>`,\n * decrypted with the satellite collection's own DEK — see\n * `with-shape/persisted-schemas/storage.ts`) is the fallback pairing-info\n * source that's always reachable from just a raw store + a per-collection\n * DEK accessor, so export uses that instead of the in-memory registry.\n *\n * Returns a `Map` from satellite collection name to its base's live id set\n * (existence.ts rule 1: absent or tombstoned base ⇒ not live). Only\n * satellite collections are present as keys — callers should treat a\n * missing key as \"not a satellite, don't filter.\"\n */\nexport async function liveBaseIdSetsForBundle(\n store: NoydbStore,\n vaultName: string,\n collectionNames: readonly string[],\n getDEK: (collectionName: string) => Promise<EnclaveKey>,\n): Promise<Map<string, Set<string>>> {\n const { loadPersistedSchema } = await import('../persisted-schemas/storage.js')\n const out = new Map<string, Set<string>>()\n for (const name of collectionNames) {\n if (name.startsWith('_')) continue\n // SILENT-DEGRADE surface (deliberate asymmetry): on ANY marker-read\n // failure the collection is treated as non-satellite and exported\n // UNFILTERED. That covers, precisely:\n // (a) `getDEK(name)` throwing for any reason (caught below);\n // (b) the persisted `_schemas/<name>` record failing to decrypt or\n // parse — corruption, wrong DEK, transient store error —\n // `loadPersistedSchema` catches internally and returns\n // `undefined` (storage.ts), which reads here as \"no marker\";\n // (c) the marker not yet persisted — `declareSatellite`'s\n // `postRegister` is fire-and-forget, so an export racing a\n // fresh declaration can miss it.\n // Leak-on-error is chosen over exclude-on-error because this is a\n // BACKUP path: exporting stale dead-satellite ciphertext is\n // recoverable; silently dropping live records from a backup is the\n // strictly worse failure. Pinned by the \"leak-on-error posture\" tests\n // in satellites-bundle-filter.test.ts.\n let dek: EnclaveKey\n try {\n dek = await getDEK(name)\n } catch {\n continue // (a) no DEK reachable — can't read the marker, export unfiltered\n }\n const persisted = await loadPersistedSchema(store, vaultName, name, dek)\n const marker = persisted?.satellite\n if (!marker) continue // (b)/(c) — undecryptable/absent/markerless schema record, export unfiltered\n out.set(name, await liveBaseIdSet(store, vaultName, marker.base))\n }\n return out\n}\n"],"mappings":";;;;;;AAsBA,eAAsB,wBACpB,OACA,WACA,iBACA,QACmC;AACnC,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,uBAAiC;AAC9E,QAAM,MAAM,oBAAI,IAAyB;AACzC,aAAW,QAAQ,iBAAiB;AAClC,QAAI,KAAK,WAAW,GAAG,EAAG;AAiB1B,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,OAAO,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,UAAM,YAAY,MAAM,oBAAoB,OAAO,WAAW,MAAM,GAAG;AACvE,UAAM,SAAS,WAAW;AAC1B,QAAI,CAAC,OAAQ;AACb,QAAI,IAAI,MAAM,MAAM,cAAc,OAAO,WAAW,OAAO,IAAI,CAAC;AAAA,EAClE;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/with-shape/satellites/dead-filter.ts"],"sourcesContent":["import type { NoydbStore } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport { liveBaseIdSet } from './existence.js'\n\n/**\n * Build a live-base id set for every satellite collection detectable from\n * its persisted `_schemas/<name>` pairing marker (#591 Task 10).\n *\n * The bundle-export path (`with-pod/bundle.ts`) has no reachable\n * `SatelliteRegistry` — that registry is private to `Vault` and adding an\n * accessor would grow a kernel file past its line-ceiling ratchet. The\n * marker persisted by `ensureSatelliteMarker` (`_schemas/<satellite>`,\n * decrypted with the satellite collection's own DEK — see\n * `with-shape/persisted-schemas/storage.ts`) is the fallback pairing-info\n * source that's always reachable from just a raw store + a per-collection\n * DEK accessor, so export uses that instead of the in-memory registry.\n *\n * Returns a `Map` from satellite collection name to its base's live id set\n * (existence.ts rule 1: absent or tombstoned base ⇒ not live). Only\n * satellite collections are present as keys — callers should treat a\n * missing key as \"not a satellite, don't filter.\"\n */\nexport async function liveBaseIdSetsForBundle(\n store: NoydbStore,\n vaultName: string,\n collectionNames: readonly string[],\n getDEK: (collectionName: string) => Promise<EnclaveKey>,\n): Promise<Map<string, Set<string>>> {\n const { loadPersistedSchema } = await import('../persisted-schemas/storage.js')\n const out = new Map<string, Set<string>>()\n for (const name of collectionNames) {\n if (name.startsWith('_')) continue\n // SILENT-DEGRADE surface (deliberate asymmetry): on ANY marker-read\n // failure the collection is treated as non-satellite and exported\n // UNFILTERED. That covers, precisely:\n // (a) `getDEK(name)` throwing for any reason (caught below);\n // (b) the persisted `_schemas/<name>` record failing to decrypt or\n // parse — corruption, wrong DEK, transient store error —\n // `loadPersistedSchema` catches internally and returns\n // `undefined` (storage.ts), which reads here as \"no marker\";\n // (c) the marker not yet persisted — `declareSatellite`'s\n // `postRegister` is fire-and-forget, so an export racing a\n // fresh declaration can miss it.\n // Leak-on-error is chosen over exclude-on-error because this is a\n // BACKUP path: exporting stale dead-satellite ciphertext is\n // recoverable; silently dropping live records from a backup is the\n // strictly worse failure. Pinned by the \"leak-on-error posture\" tests\n // in satellites-bundle-filter.test.ts.\n let dek: EnclaveKey\n try {\n dek = await getDEK(name)\n } catch {\n continue // (a) no DEK reachable — can't read the marker, export unfiltered\n }\n const persisted = await loadPersistedSchema(store, vaultName, name, dek)\n const marker = persisted?.satellite\n if (!marker) continue // (b)/(c) — undecryptable/absent/markerless schema record, export unfiltered\n out.set(name, await liveBaseIdSet(store, vaultName, marker.base))\n }\n return out\n}\n"],"mappings":";;;;;AAsBA,eAAsB,wBACpB,OACA,WACA,iBACA,QACmC;AACnC,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,uBAAiC;AAC9E,QAAM,MAAM,oBAAI,IAAyB;AACzC,aAAW,QAAQ,iBAAiB;AAClC,QAAI,KAAK,WAAW,GAAG,EAAG;AAiB1B,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,OAAO,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,UAAM,YAAY,MAAM,oBAAoB,OAAO,WAAW,MAAM,GAAG;AACvE,UAAM,SAAS,WAAW;AAC1B,QAAI,CAAC,OAAQ;AACb,QAAI,IAAI,MAAM,MAAM,cAAc,OAAO,WAAW,OAAO,IAAI,CAAC;AAAA,EAClE;AACA,SAAO;AACT;","names":[]}
@@ -2,7 +2,6 @@ import {
2
2
  DebugPlaintextError,
3
3
  DebugReservedFieldError
4
4
  } from "../chunk-7O3Y4PPD.js";
5
- import "../chunk-PZ5AY32C.js";
6
5
 
7
6
  // src/kernel/debug.ts
8
7
  function readPlaintextRecord(envelope) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/kernel/debug.ts"],"sourcesContent":["/**\n * Helpers for reading records out of a *plaintext* store (`encrypt: false`)\n * with native tooling — the programmatic core of a `noydb cat`-style unwrap.\n * See the plaintext/debug-store-mode design.\n */\nimport type { EncryptedEnvelope } from './types.js'\n\n/**\n * The option's two failure modes, re-exported here so a consumer can `catch`\n * them by identity (#914). Both are thrown from the kernel — `createNoydb`\n * raises `DebugPlaintextError` when `debugPlaintext` is combined with\n * encryption, and the record codec raises `DebugReservedFieldError` for a\n * field colliding with the `_`-prefixed metadata. This entry is the only one\n * that publishes them.\n */\nexport { DebugPlaintextError, DebugReservedFieldError } from './errors.js'\n\n/** Re-exported so `readPlaintextRecord`'s parameter is nameable from this entry. */\nexport type { EncryptedEnvelope } from './types.js'\n\n/**\n * Extract the record from a plaintext stored envelope, handling both layouts:\n *\n * - **classic plaintext** (`encrypt: false`): the record is JSON in `_data`.\n * - **debugPlaintext**: the record's fields are inlined beside the\n * `_`-prefixed metadata (marked by `_debug`).\n *\n * Returns `null` for an empty/absent body. Throws if handed an **encrypted**\n * envelope (non-empty `_iv`) — there is no key here; decrypt through the vault\n * instead. Intended for record envelopes, not blob chunks.\n *\n * @example\n * ```ts\n * // node script over a to-file store, no vault needed:\n * const env = JSON.parse(readFileSync('data/acme/invoices/inv-1.json', 'utf8'))\n * console.log(readPlaintextRecord(env)) // → { id: 'inv-1', total: '120.00', … }\n * ```\n */\nexport function readPlaintextRecord<T = Record<string, unknown>>(\n envelope: EncryptedEnvelope,\n): T | null {\n if (envelope._iv !== '') {\n throw new Error(\n 'readPlaintextRecord: envelope is encrypted (non-empty _iv) — decrypt via the vault, not this helper',\n )\n }\n if (envelope._debug !== undefined) {\n const record: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(envelope)) {\n if (!key.startsWith('_')) record[key] = value\n }\n return record as T\n }\n if (!envelope._data) return null\n return JSON.parse(envelope._data) as T\n}\n"],"mappings":";;;;;;;AAsCO,SAAS,oBACd,UACU;AACV,MAAI,SAAS,QAAQ,IAAI;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,WAAW,QAAW;AACjC,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,CAAC,IAAI,WAAW,GAAG,EAAG,QAAO,GAAG,IAAI;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,MAAO,QAAO;AAC5B,SAAO,KAAK,MAAM,SAAS,KAAK;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../src/kernel/debug.ts"],"sourcesContent":["/**\n * Helpers for reading records out of a *plaintext* store (`encrypt: false`)\n * with native tooling — the programmatic core of a `noydb cat`-style unwrap.\n * See the plaintext/debug-store-mode design.\n */\nimport type { EncryptedEnvelope } from './types.js'\n\n/**\n * The option's two failure modes, re-exported here so a consumer can `catch`\n * them by identity (#914). Both are thrown from the kernel — `createNoydb`\n * raises `DebugPlaintextError` when `debugPlaintext` is combined with\n * encryption, and the record codec raises `DebugReservedFieldError` for a\n * field colliding with the `_`-prefixed metadata. This entry is the only one\n * that publishes them.\n */\nexport { DebugPlaintextError, DebugReservedFieldError } from './errors.js'\n\n/** Re-exported so `readPlaintextRecord`'s parameter is nameable from this entry. */\nexport type { EncryptedEnvelope } from './types.js'\n\n/**\n * Extract the record from a plaintext stored envelope, handling both layouts:\n *\n * - **classic plaintext** (`encrypt: false`): the record is JSON in `_data`.\n * - **debugPlaintext**: the record's fields are inlined beside the\n * `_`-prefixed metadata (marked by `_debug`).\n *\n * Returns `null` for an empty/absent body. Throws if handed an **encrypted**\n * envelope (non-empty `_iv`) — there is no key here; decrypt through the vault\n * instead. Intended for record envelopes, not blob chunks.\n *\n * @example\n * ```ts\n * // node script over a to-file store, no vault needed:\n * const env = JSON.parse(readFileSync('data/acme/invoices/inv-1.json', 'utf8'))\n * console.log(readPlaintextRecord(env)) // → { id: 'inv-1', total: '120.00', … }\n * ```\n */\nexport function readPlaintextRecord<T = Record<string, unknown>>(\n envelope: EncryptedEnvelope,\n): T | null {\n if (envelope._iv !== '') {\n throw new Error(\n 'readPlaintextRecord: envelope is encrypted (non-empty _iv) — decrypt via the vault, not this helper',\n )\n }\n if (envelope._debug !== undefined) {\n const record: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(envelope)) {\n if (!key.startsWith('_')) record[key] = value\n }\n return record as T\n }\n if (!envelope._data) return null\n return JSON.parse(envelope._data) as T\n}\n"],"mappings":";;;;;;AAsCO,SAAS,oBACd,UACU;AACV,MAAI,SAAS,QAAQ,IAAI;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,WAAW,QAAW;AACjC,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,CAAC,IAAI,WAAW,GAAG,EAAG,QAAO,GAAG,IAAI;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,MAAO,QAAO;AAC5B,SAAO,KAAK,MAAM,SAAS,KAAK;AAClC;","names":[]}
@@ -25,7 +25,6 @@ import "./chunk-N4CHCXDL.js";
25
25
  import {
26
26
  DelegationTargetMissingError
27
27
  } from "./chunk-7O3Y4PPD.js";
28
- import "./chunk-PZ5AY32C.js";
29
28
 
30
29
  // src/with-party/team/delegation.ts
31
30
  var DELEGATIONS_COLLECTION = "_delegations";
@@ -103,4 +102,4 @@ export {
103
102
  loadActiveDelegations,
104
103
  revokeDelegation
105
104
  };
106
- //# sourceMappingURL=delegation-OLJUWTVA.js.map
105
+ //# sourceMappingURL=delegation-VRYMQRCF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/with-party/team/delegation.ts"],"sourcesContent":["/**\n * Time-boxed cross-tier delegation tokens.\n *\n * A higher-tier user can issue a delegation that grants another user\n * temporary access to records at a specified tier. The delegation is\n * persisted as an encrypted envelope in the reserved `_delegations`\n * collection. The target user's runtime scans this collection on every\n * open and, while `until` is still in the future, merges the\n * unwrapped tier DEKs into their in-memory DEK map.\n *\n * ## Token shape\n *\n * ```\n * {\n * id, // ULID, also the _delegations record id\n * toUser, // grantee user id\n * fromUser, // grantor user id (owner/admin/higher-tier principal)\n * tier, // tier being delegated\n * collection, // collection name OR null for \"every collection\"\n * record, // optional specific record id\n * until, // ISO timestamp — token expires at this instant\n * wrappedDek, // base64 AES-KW-wrapped tier DEK, wrapped under target KEK\n * createdAt, // ISO timestamp\n * }\n * ```\n *\n * The ciphertext is stored as a normal noy-db envelope — the\n * `_delegations` collection has its own DEK shared across all vault\n * users, so an operator can enumerate active delegations for audit\n * without being able to *use* them (the `wrappedDek` inside is still\n * keyed to the target user's KEK).\n *\n * ## Revocation\n *\n * Delete the `_delegations/<id>` envelope. The target user's runtime\n * reloads the delegation list at each open and at periodic intervals\n * (tracked by the caller — this module is pure logic).\n *\n * @module\n */\n\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from './keyring.js'\nimport { buildRecordAad, buildRecordEnvelope, encrypt, openEnvelopeJson, wrapKey, unwrapKey, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { dekKey } from './tiers.js'\nimport { DelegationTargetMissingError } from '../../kernel/errors.js'\nimport { generateULID } from '../../with-pod/ulid.js'\n\nexport const DELEGATIONS_COLLECTION = '_delegations'\n\n/**\n * Durable payload of a delegation token. Encrypted under the vault's\n * `_delegations` DEK; the `wrappedDek` inside is additionally wrapped\n * under the target user's KEK.\n */\nexport interface DelegationToken {\n readonly id: string\n readonly toUser: string\n readonly fromUser: string\n readonly tier: number\n /** Collection name or `null` for all collections. */\n readonly collection: string | null\n /** Optional specific record id scope. */\n readonly record?: string\n readonly until: string\n readonly wrappedDek: string\n readonly createdAt: string\n}\n\nexport interface IssueDelegationOptions {\n readonly toUser: string\n readonly tier: number\n readonly collection?: string\n readonly record?: string\n readonly until: Date | string\n}\n\n/**\n * Build and persist a delegation token. The caller must hold a tier-N\n * DEK and must have already located the target user's keyring file\n * (so the `wrappedDek` can be re-wrapped against their KEK).\n */\nexport async function issueDelegation(\n store: NoydbStore,\n vault: string,\n grantor: UnlockedKeyring,\n targetKek: EnclaveKey | null,\n delegationsDek: EnclaveKey,\n opts: IssueDelegationOptions,\n): Promise<DelegationToken> {\n if (!targetKek) {\n throw new DelegationTargetMissingError(opts.toUser)\n }\n const tier = opts.tier\n const collectionName = opts.collection ?? null\n const dekLookupCollection = collectionName ?? ''\n // Tier DEK to delegate — fetched from the grantor's own keyring.\n const sourceDek = collectionName\n ? grantor.deks.get(dekKey(collectionName, tier))\n : undefined\n if (!sourceDek) {\n throw new DelegationTargetMissingError(\n `grantor cannot find tier ${tier} DEK for ${dekLookupCollection || '(any)'}`,\n )\n }\n const wrappedDek = await wrapKey(sourceDek, targetKek)\n\n const until = typeof opts.until === 'string' ? opts.until : opts.until.toISOString()\n const token: DelegationToken = {\n id: generateULID(),\n toUser: opts.toUser,\n fromUser: grantor.userId,\n tier,\n collection: collectionName,\n ...(opts.record && { record: opts.record }),\n until,\n wrappedDek,\n createdAt: new Date().toISOString(),\n }\n\n const plaintext = JSON.stringify(token)\n const identity = { collection: DELEGATIONS_COLLECTION, id: token.id, by: grantor.userId, version: 1 }\n const { iv, data } = await encrypt(plaintext, delegationsDek, buildRecordAad(identity))\n const envelope = buildRecordEnvelope(\n identity,\n { ts: token.createdAt, iv, data},\n )\n await store.put(vault, DELEGATIONS_COLLECTION, token.id, envelope)\n return token\n}\n\n/**\n * Enumerate every live (non-expired) delegation addressed to `toUser`\n * and merge the unwrapped tier DEKs into their keyring. Returns the\n * list of merged delegations so the caller can register per-access\n * audit context.\n */\nexport async function loadActiveDelegations(\n store: NoydbStore,\n vault: string,\n user: UnlockedKeyring,\n delegationsDek: EnclaveKey,\n now: Date = new Date(),\n): Promise<DelegationToken[]> {\n const ids = await store.list(vault, DELEGATIONS_COLLECTION)\n const merged: DelegationToken[] = []\n const nowIso = now.toISOString()\n for (const id of ids) {\n const env = await store.get(vault, DELEGATIONS_COLLECTION, id)\n if (!env) continue\n let token: DelegationToken\n try {\n const plaintext = await openEnvelopeJson({ collection: DELEGATIONS_COLLECTION, id }, env, delegationsDek)\n token = JSON.parse(plaintext) as DelegationToken\n } catch {\n continue\n }\n if (token.toUser !== user.userId) continue\n if (token.until <= nowIso) continue\n\n // A user without a KEK in memory (tier-3 PIN resume, wrap-DEKs\n // tier-2 unlock, session restore) cannot unwrap delegation tokens\n // — those were wrapped under the user's KEK at issue time. Skip\n // this token; the consumer reaches it again at tier-1 unlock.\n if (!user.kek) continue\n let dek: EnclaveKey\n try {\n dek = await unwrapKey(token.wrappedDek, user.kek)\n } catch {\n continue\n }\n const k = token.collection\n ? dekKey(token.collection, token.tier)\n : `__any#${token.tier}`\n user.deks.set(k, dek)\n merged.push(token)\n }\n return merged\n}\n\n/**\n * Revoke a delegation by id — the caller resolves the envelope and\n * issues a `delete`. Provided as a stable helper so the naming is\n * symmetric to `issueDelegation`.\n */\nexport async function revokeDelegation(\n store: NoydbStore,\n vault: string,\n id: string,\n): Promise<void> {\n await store.delete(vault, DELEGATIONS_COLLECTION, id)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDO,IAAM,yBAAyB;AAkCtC,eAAsB,gBACpB,OACA,OACA,SACA,WACA,gBACA,MAC0B;AAC1B,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,6BAA6B,KAAK,MAAM;AAAA,EACpD;AACA,QAAM,OAAO,KAAK;AAClB,QAAM,iBAAiB,KAAK,cAAc;AAC1C,QAAM,sBAAsB,kBAAkB;AAE9C,QAAM,YAAY,iBACd,QAAQ,KAAK,IAAI,OAAO,gBAAgB,IAAI,CAAC,IAC7C;AACJ,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR,4BAA4B,IAAI,YAAY,uBAAuB,OAAO;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,aAAa,MAAM,QAAQ,WAAW,SAAS;AAErD,QAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAK,MAAM,YAAY;AACnF,QAAM,QAAyB;AAAA,IAC7B,IAAI,aAAa;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,YAAY;AAAA,IACZ,GAAI,KAAK,UAAU,EAAE,QAAQ,KAAK,OAAO;AAAA,IACzC;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,YAAY,KAAK,UAAU,KAAK;AACtC,QAAM,WAAW,EAAE,YAAY,wBAAwB,IAAI,MAAM,IAAI,IAAI,QAAQ,QAAQ,SAAS,EAAE;AACpG,QAAM,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,WAAW,gBAAgB,eAAe,QAAQ,CAAC;AACtF,QAAM,WAAW;AAAA,IACf;AAAA,IACA,EAAE,IAAI,MAAM,WAAW,IAAI,KAAI;AAAA,EACjC;AACA,QAAM,MAAM,IAAI,OAAO,wBAAwB,MAAM,IAAI,QAAQ;AACjE,SAAO;AACT;AAQA,eAAsB,sBACpB,OACA,OACA,MACA,gBACA,MAAY,oBAAI,KAAK,GACO;AAC5B,QAAM,MAAM,MAAM,MAAM,KAAK,OAAO,sBAAsB;AAC1D,QAAM,SAA4B,CAAC;AACnC,QAAM,SAAS,IAAI,YAAY;AAC/B,aAAW,MAAM,KAAK;AACpB,UAAM,MAAM,MAAM,MAAM,IAAI,OAAO,wBAAwB,EAAE;AAC7D,QAAI,CAAC,IAAK;AACV,QAAI;AACJ,QAAI;AACF,YAAM,YAAY,MAAM,iBAAiB,EAAE,YAAY,wBAAwB,GAAG,GAAG,KAAK,cAAc;AACxG,cAAQ,KAAK,MAAM,SAAS;AAAA,IAC9B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,MAAM,WAAW,KAAK,OAAQ;AAClC,QAAI,MAAM,SAAS,OAAQ;AAM3B,QAAI,CAAC,KAAK,IAAK;AACf,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,UAAU,MAAM,YAAY,KAAK,GAAG;AAAA,IAClD,QAAQ;AACN;AAAA,IACF;AACA,UAAM,IAAI,MAAM,aACZ,OAAO,MAAM,YAAY,MAAM,IAAI,IACnC,SAAS,MAAM,IAAI;AACvB,SAAK,KAAK,IAAI,GAAG,GAAG;AACpB,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO;AACT;AAOA,eAAsB,iBACpB,OACA,OACA,IACe;AACf,QAAM,MAAM,OAAO,OAAO,wBAAwB,EAAE;AACtD;","names":[]}
1
+ {"version":3,"sources":["../src/with-party/team/delegation.ts"],"sourcesContent":["/**\n * Time-boxed cross-tier delegation tokens.\n *\n * A higher-tier user can issue a delegation that grants another user\n * temporary access to records at a specified tier. The delegation is\n * persisted as an encrypted envelope in the reserved `_delegations`\n * collection. The target user's runtime scans this collection on every\n * open and, while `until` is still in the future, merges the\n * unwrapped tier DEKs into their in-memory DEK map.\n *\n * ## Token shape\n *\n * ```\n * {\n * id, // ULID, also the _delegations record id\n * toUser, // grantee user id\n * fromUser, // grantor user id (owner/admin/higher-tier principal)\n * tier, // tier being delegated\n * collection, // collection name OR null for \"every collection\"\n * record, // optional specific record id\n * until, // ISO timestamp — token expires at this instant\n * wrappedDek, // base64 AES-KW-wrapped tier DEK, wrapped under target KEK\n * createdAt, // ISO timestamp\n * }\n * ```\n *\n * The ciphertext is stored as a normal noy-db envelope — the\n * `_delegations` collection has its own DEK shared across all vault\n * users, so an operator can enumerate active delegations for audit\n * without being able to *use* them (the `wrappedDek` inside is still\n * keyed to the target user's KEK).\n *\n * ## Revocation\n *\n * Delete the `_delegations/<id>` envelope. The target user's runtime\n * reloads the delegation list at each open and at periodic intervals\n * (tracked by the caller — this module is pure logic).\n *\n * @module\n */\n\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from './keyring.js'\nimport { buildRecordAad, buildRecordEnvelope, encrypt, openEnvelopeJson, wrapKey, unwrapKey, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { dekKey } from './tiers.js'\nimport { DelegationTargetMissingError } from '../../kernel/errors.js'\nimport { generateULID } from '../../with-pod/ulid.js'\n\nexport const DELEGATIONS_COLLECTION = '_delegations'\n\n/**\n * Durable payload of a delegation token. Encrypted under the vault's\n * `_delegations` DEK; the `wrappedDek` inside is additionally wrapped\n * under the target user's KEK.\n */\nexport interface DelegationToken {\n readonly id: string\n readonly toUser: string\n readonly fromUser: string\n readonly tier: number\n /** Collection name or `null` for all collections. */\n readonly collection: string | null\n /** Optional specific record id scope. */\n readonly record?: string\n readonly until: string\n readonly wrappedDek: string\n readonly createdAt: string\n}\n\nexport interface IssueDelegationOptions {\n readonly toUser: string\n readonly tier: number\n readonly collection?: string\n readonly record?: string\n readonly until: Date | string\n}\n\n/**\n * Build and persist a delegation token. The caller must hold a tier-N\n * DEK and must have already located the target user's keyring file\n * (so the `wrappedDek` can be re-wrapped against their KEK).\n */\nexport async function issueDelegation(\n store: NoydbStore,\n vault: string,\n grantor: UnlockedKeyring,\n targetKek: EnclaveKey | null,\n delegationsDek: EnclaveKey,\n opts: IssueDelegationOptions,\n): Promise<DelegationToken> {\n if (!targetKek) {\n throw new DelegationTargetMissingError(opts.toUser)\n }\n const tier = opts.tier\n const collectionName = opts.collection ?? null\n const dekLookupCollection = collectionName ?? ''\n // Tier DEK to delegate — fetched from the grantor's own keyring.\n const sourceDek = collectionName\n ? grantor.deks.get(dekKey(collectionName, tier))\n : undefined\n if (!sourceDek) {\n throw new DelegationTargetMissingError(\n `grantor cannot find tier ${tier} DEK for ${dekLookupCollection || '(any)'}`,\n )\n }\n const wrappedDek = await wrapKey(sourceDek, targetKek)\n\n const until = typeof opts.until === 'string' ? opts.until : opts.until.toISOString()\n const token: DelegationToken = {\n id: generateULID(),\n toUser: opts.toUser,\n fromUser: grantor.userId,\n tier,\n collection: collectionName,\n ...(opts.record && { record: opts.record }),\n until,\n wrappedDek,\n createdAt: new Date().toISOString(),\n }\n\n const plaintext = JSON.stringify(token)\n const identity = { collection: DELEGATIONS_COLLECTION, id: token.id, by: grantor.userId, version: 1 }\n const { iv, data } = await encrypt(plaintext, delegationsDek, buildRecordAad(identity))\n const envelope = buildRecordEnvelope(\n identity,\n { ts: token.createdAt, iv, data},\n )\n await store.put(vault, DELEGATIONS_COLLECTION, token.id, envelope)\n return token\n}\n\n/**\n * Enumerate every live (non-expired) delegation addressed to `toUser`\n * and merge the unwrapped tier DEKs into their keyring. Returns the\n * list of merged delegations so the caller can register per-access\n * audit context.\n */\nexport async function loadActiveDelegations(\n store: NoydbStore,\n vault: string,\n user: UnlockedKeyring,\n delegationsDek: EnclaveKey,\n now: Date = new Date(),\n): Promise<DelegationToken[]> {\n const ids = await store.list(vault, DELEGATIONS_COLLECTION)\n const merged: DelegationToken[] = []\n const nowIso = now.toISOString()\n for (const id of ids) {\n const env = await store.get(vault, DELEGATIONS_COLLECTION, id)\n if (!env) continue\n let token: DelegationToken\n try {\n const plaintext = await openEnvelopeJson({ collection: DELEGATIONS_COLLECTION, id }, env, delegationsDek)\n token = JSON.parse(plaintext) as DelegationToken\n } catch {\n continue\n }\n if (token.toUser !== user.userId) continue\n if (token.until <= nowIso) continue\n\n // A user without a KEK in memory (tier-3 PIN resume, wrap-DEKs\n // tier-2 unlock, session restore) cannot unwrap delegation tokens\n // — those were wrapped under the user's KEK at issue time. Skip\n // this token; the consumer reaches it again at tier-1 unlock.\n if (!user.kek) continue\n let dek: EnclaveKey\n try {\n dek = await unwrapKey(token.wrappedDek, user.kek)\n } catch {\n continue\n }\n const k = token.collection\n ? dekKey(token.collection, token.tier)\n : `__any#${token.tier}`\n user.deks.set(k, dek)\n merged.push(token)\n }\n return merged\n}\n\n/**\n * Revoke a delegation by id — the caller resolves the envelope and\n * issues a `delete`. Provided as a stable helper so the naming is\n * symmetric to `issueDelegation`.\n */\nexport async function revokeDelegation(\n store: NoydbStore,\n vault: string,\n id: string,\n): Promise<void> {\n await store.delete(vault, DELEGATIONS_COLLECTION, id)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDO,IAAM,yBAAyB;AAkCtC,eAAsB,gBACpB,OACA,OACA,SACA,WACA,gBACA,MAC0B;AAC1B,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,6BAA6B,KAAK,MAAM;AAAA,EACpD;AACA,QAAM,OAAO,KAAK;AAClB,QAAM,iBAAiB,KAAK,cAAc;AAC1C,QAAM,sBAAsB,kBAAkB;AAE9C,QAAM,YAAY,iBACd,QAAQ,KAAK,IAAI,OAAO,gBAAgB,IAAI,CAAC,IAC7C;AACJ,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR,4BAA4B,IAAI,YAAY,uBAAuB,OAAO;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,aAAa,MAAM,QAAQ,WAAW,SAAS;AAErD,QAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAK,MAAM,YAAY;AACnF,QAAM,QAAyB;AAAA,IAC7B,IAAI,aAAa;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,YAAY;AAAA,IACZ,GAAI,KAAK,UAAU,EAAE,QAAQ,KAAK,OAAO;AAAA,IACzC;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,YAAY,KAAK,UAAU,KAAK;AACtC,QAAM,WAAW,EAAE,YAAY,wBAAwB,IAAI,MAAM,IAAI,IAAI,QAAQ,QAAQ,SAAS,EAAE;AACpG,QAAM,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,WAAW,gBAAgB,eAAe,QAAQ,CAAC;AACtF,QAAM,WAAW;AAAA,IACf;AAAA,IACA,EAAE,IAAI,MAAM,WAAW,IAAI,KAAI;AAAA,EACjC;AACA,QAAM,MAAM,IAAI,OAAO,wBAAwB,MAAM,IAAI,QAAQ;AACjE,SAAO;AACT;AAQA,eAAsB,sBACpB,OACA,OACA,MACA,gBACA,MAAY,oBAAI,KAAK,GACO;AAC5B,QAAM,MAAM,MAAM,MAAM,KAAK,OAAO,sBAAsB;AAC1D,QAAM,SAA4B,CAAC;AACnC,QAAM,SAAS,IAAI,YAAY;AAC/B,aAAW,MAAM,KAAK;AACpB,UAAM,MAAM,MAAM,MAAM,IAAI,OAAO,wBAAwB,EAAE;AAC7D,QAAI,CAAC,IAAK;AACV,QAAI;AACJ,QAAI;AACF,YAAM,YAAY,MAAM,iBAAiB,EAAE,YAAY,wBAAwB,GAAG,GAAG,KAAK,cAAc;AACxG,cAAQ,KAAK,MAAM,SAAS;AAAA,IAC9B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,MAAM,WAAW,KAAK,OAAQ;AAClC,QAAI,MAAM,SAAS,OAAQ;AAM3B,QAAI,CAAC,KAAK,IAAK;AACf,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,UAAU,MAAM,YAAY,KAAK,GAAG;AAAA,IAClD,QAAQ;AACN;AAAA,IACF;AACA,UAAM,IAAI,MAAM,aACZ,OAAO,MAAM,YAAY,MAAM,IAAI,IACnC,SAAS,MAAM,IAAI;AACvB,SAAK,KAAK,IAAI,GAAG,GAAG;AACpB,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO;AACT;AAOA,eAAsB,iBACpB,OACA,OACA,IACe;AACf,QAAM,MAAM,OAAO,OAAO,wBAAwB,EAAE;AACtD;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DerivationRegistry
3
- } from "../chunk-AJQY44CE.js";
3
+ } from "../chunk-ZXLZ62R5.js";
4
4
  import "../chunk-TPHAGLUH.js";
5
5
  import {
6
6
  DerivationExecutor
@@ -9,12 +9,12 @@ import {
9
9
  withDerivation,
10
10
  withRollup
11
11
  } from "../chunk-BUE2D7PX.js";
12
- import "../chunk-BWXGSSFX.js";
12
+ import "../chunk-NJXX55QX.js";
13
13
  import "../chunk-TFMM5DBB.js";
14
14
  import "../chunk-RTBJ5IOO.js";
15
15
  import "../chunk-KCUIMITG.js";
16
16
  import "../chunk-VYYM3MEN.js";
17
- import "../chunk-URHRIAV6.js";
17
+ import "../chunk-REDOOY2Q.js";
18
18
  import "../chunk-Y2NBBT6K.js";
19
19
  import "../chunk-WWNYSV7S.js";
20
20
  import "../chunk-YPXNAP72.js";
@@ -39,7 +39,6 @@ import {
39
39
  DerivationOutputShapeError,
40
40
  DerivationOutputUnknownError
41
41
  } from "../chunk-7O3Y4PPD.js";
42
- import "../chunk-PZ5AY32C.js";
43
42
  export {
44
43
  DerivationCapExceededError,
45
44
  DerivationCycleError,
@@ -2,7 +2,7 @@ import {
2
2
  derivePersistedSchema,
3
3
  isZod4Schema,
4
4
  isZodSchema
5
- } from "./chunk-URHRIAV6.js";
5
+ } from "./chunk-REDOOY2Q.js";
6
6
  import "./chunk-Y2NBBT6K.js";
7
7
  import "./chunk-CIGAQBJR.js";
8
8
  import "./chunk-4RUFYGWG.js";
@@ -13,10 +13,9 @@ import "./chunk-LP7BEXCT.js";
13
13
  import "./chunk-SL3JAAKN.js";
14
14
  import "./chunk-N4CHCXDL.js";
15
15
  import "./chunk-7O3Y4PPD.js";
16
- import "./chunk-PZ5AY32C.js";
17
16
  export {
18
17
  derivePersistedSchema,
19
18
  isZod4Schema,
20
19
  isZodSchema
21
20
  };
22
- //# sourceMappingURL=derive-LY47HG7Q.js.map
21
+ //# sourceMappingURL=derive-HHBRFS2U.js.map
@@ -26,7 +26,6 @@ import "../chunk-LP7BEXCT.js";
26
26
  import "../chunk-SL3JAAKN.js";
27
27
  import "../chunk-N4CHCXDL.js";
28
28
  import "../chunk-7O3Y4PPD.js";
29
- import "../chunk-PZ5AY32C.js";
30
29
  export {
31
30
  DIRECTORY_RECORD_ID,
32
31
  META_COLLECTION,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-TPHAGLUH.js";
5
5
  import {
6
6
  markStale
7
- } from "./chunk-PDD75NUZ.js";
7
+ } from "./chunk-SMH6SRX7.js";
8
8
  import "./chunk-TFMM5DBB.js";
9
9
  import {
10
10
  putDerivedOutput,
@@ -27,14 +27,13 @@ import "./chunk-N4CHCXDL.js";
27
27
  import {
28
28
  DerivationCapExceededError
29
29
  } from "./chunk-7O3Y4PPD.js";
30
- import "./chunk-PZ5AY32C.js";
31
30
 
32
31
  // src/with-formula/derivations/dispatch.ts
33
32
  async function dispatchArrayDerivationsOnDelete(ctx, id, eraseRecordShapeToo = false) {
34
33
  const { derivationSource, collectionName, adapter, vault, getDEK, storeCiphertext } = ctx;
35
34
  const strategies = derivationSource.registry().strategiesForSource(collectionName);
36
35
  if (strategies.length === 0) return 0;
37
- const { loadFanoutSidecar, deleteFanoutSidecar } = await import("./fanout-sidecar-TSFPXY5C.js");
36
+ const { loadFanoutSidecar, deleteFanoutSidecar } = await import("./fanout-sidecar-HJIVUPTD.js");
38
37
  const txCtx = derivationSource.getActiveTxContext();
39
38
  let erased = 0;
40
39
  for (const { spec } of strategies) {
@@ -131,7 +130,7 @@ async function dispatchDerivations(ctx, id, record, version, wave, prior) {
131
130
  }
132
131
  if (executorClass === null) {
133
132
  ;
134
- ({ DerivationExecutor: executorClass } = await import("./executor-TOLPBHOC.js"));
133
+ ({ DerivationExecutor: executorClass } = await import("./executor-5NIMLSKZ.js"));
135
134
  }
136
135
  for (const run of runs) await runOne(ctx, spec, strategyHash, executorClass, run);
137
136
  }
@@ -155,7 +154,7 @@ async function runOne(ctx, spec, strategyHash, executorClass, run) {
155
154
  const outputCollection = derivationSource.getCollection(outSpec.collection);
156
155
  const txCtx = derivationSource.getActiveTxContext();
157
156
  if (out.kind === "array") {
158
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-TSFPXY5C.js");
157
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-HJIVUPTD.js");
159
158
  const prior = await loadFanoutSidecar(adapter, vault, spec.source, run.runId, key, getDEK, storeCiphertext);
160
159
  const prevKeys = new Set(prior?.keys ?? []);
161
160
  const newKeysList = out.entries.map((e) => e.key);
@@ -239,7 +238,7 @@ async function dispatchTriggerDerivationsOnDelete(ctx, id, deleted) {
239
238
  for (const sid of matched) await markStale(registry, spec, sid);
240
239
  continue;
241
240
  }
242
- if (executorClass === null) ({ DerivationExecutor: executorClass } = await import("./executor-TOLPBHOC.js"));
241
+ if (executorClass === null) ({ DerivationExecutor: executorClass } = await import("./executor-5NIMLSKZ.js"));
243
242
  for (const sid of matched) {
244
243
  const raw = await srcColl._getStoredRecord(sid);
245
244
  if (raw === null) continue;
@@ -252,4 +251,4 @@ export {
252
251
  dispatchDerivations,
253
252
  dispatchTriggerDerivationsOnDelete
254
253
  };
255
- //# sourceMappingURL=dispatch-MSTR5VBI.js.map
254
+ //# sourceMappingURL=dispatch-DC3LQJ3S.js.map