@noy-db/hub 0.1.0-pre.8 → 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-HC7Z5EQZ.js → chunk-4TFSM22V.js} +4 -4
  23. package/dist/{chunk-7XBQS42M.js → chunk-537VFZTR.js} +4 -4
  24. package/dist/{chunk-M62XNWRA.js → chunk-5DWL3JBF.js} +2 -2
  25. package/dist/{chunk-RSPLI376.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-WN6UK7PM.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-2WGMYBYS.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-YVFTBQHL.js → chunk-PA6R5ZCI.js} +217 -10
  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-Y4CMTMUW.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-R2ZTGEVP.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-PJK6IOBC.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-BygpnIWe.d.ts → dev-unlock-D9s-loPr.d.ts} +1 -1
  97. package/dist/{dev-unlock-BZKx666y.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-B0eU2Qv9.d.ts → hash-DXXXusyk.d.ts} +1 -1
  112. package/dist/{hash-CIyfmKsg.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-Dp4tKCjX.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-DsVbTDZI.d.cts → index-hdFvZkBP.d.cts} +174 -3
  128. package/dist/index.cjs +5929 -1089
  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 +2402 -672
  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-UQIMMKO5.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-3QTQADDW.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-DD9eKKNc.d.ts → types-C4lwMKKF.d.cts} +2771 -322
  213. package/dist/{types-arFMsCtn.d.cts → types-DW9RGSSs.d.ts} +2771 -322
  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-ACLDOTNQ.js.map +0 -1
  226. package/dist/chunk-BTDCBVJW.js +0 -160
  227. package/dist/chunk-BTDCBVJW.js.map +0 -1
  228. package/dist/chunk-CIMZBAZB.js.map +0 -1
  229. package/dist/chunk-GOUT6DND.js.map +0 -1
  230. package/dist/chunk-M5INGEFC.js.map +0 -1
  231. package/dist/chunk-PJK6IOBC.js.map +0 -1
  232. package/dist/chunk-SCZXXXU4.js.map +0 -1
  233. package/dist/chunk-TDR6T5CJ.js.map +0 -1
  234. package/dist/chunk-TOQK4KAN.js +0 -79
  235. package/dist/chunk-TOQK4KAN.js.map +0 -1
  236. package/dist/chunk-WN6UK7PM.js.map +0 -1
  237. package/dist/chunk-Y4CMTMUW.js.map +0 -1
  238. package/dist/chunk-YVFTBQHL.js.map +0 -1
  239. /package/dist/{chunk-HC7Z5EQZ.js.map → chunk-4TFSM22V.js.map} +0 -0
  240. /package/dist/{chunk-7XBQS42M.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-RSPLI376.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-2WGMYBYS.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-R2ZTGEVP.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-UQIMMKO5.js.map → derivations/index.js.map} +0 -0
  253. /package/dist/{public-envelope-3QTQADDW.js.map → executor-7E3VFGW7.js.map} +0 -0
@@ -1,5 +1,5 @@
1
- import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-SBHmi6D0.js';
2
- import { A as AggregateStrategy, b as AggregateSpec, c as Aggregation, a as AggregateResult, g as GroupedQuery } from './strategy-D-SrOLCl.js';
1
+ import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-Dnu81tsS.cjs';
2
+ import { A as AggregateStrategy, b as AggregateSpec, c as Aggregation, a as AggregateResult, g as GroupedQuery, h as GroupedQueryN } from './strategy-DSTrsZ8t.cjs';
3
3
 
4
4
  /**
5
5
  * All NOYDB error classes — a single import surface for `catch` blocks and
@@ -116,6 +116,26 @@ declare class TamperedError extends NoydbError {
116
116
  declare class InvalidKeyError extends NoydbError {
117
117
  constructor(message?: string);
118
118
  }
119
+ /**
120
+ * Thrown when a keyring's wrapped-DEK set unwraps partially — at least
121
+ * one DEK succeeds (proving the KEK is correct) but at least one fails.
122
+ * The passphrase is right; the failed entries are corrupted.
123
+ *
124
+ * This is distinct from {@link InvalidKeyError} so that
125
+ * `NoydbOptions.onInvalidKey: 'reset'` does NOT fire — resetting on
126
+ * partial corruption would destroy the still-valid DEKs and the data
127
+ * they protect, which is silent data loss in response to a feature
128
+ * designed for stale-credential recovery.
129
+ */
130
+ declare class KeyringCorruptError extends NoydbError {
131
+ readonly failedCollections: readonly string[];
132
+ readonly intactCount: number;
133
+ constructor(opts: {
134
+ failedCollections: readonly string[];
135
+ intactCount: number;
136
+ message?: string;
137
+ });
138
+ }
119
139
  /**
120
140
  * Thrown when the authenticated user does not have a DEK for the requested
121
141
  * collection — i.e. the collection is not in their keyring at all.
@@ -229,7 +249,7 @@ declare class KeyringExpiredError extends NoydbError {
229
249
  }
230
250
  /**
231
251
  * Thrown when an `@noy-db/as-*` import is attempted but the invoking
232
- * keyring lacks the required import-capability bit (issue ).
252
+ * keyring lacks the required import-capability bit.
233
253
  *
234
254
  * - `tier: 'plaintext'` — a plaintext-tier import (`as-csv`, `as-json`,
235
255
  * `as-ndjson`, `as-zip`, …) was attempted but the keyring's
@@ -327,6 +347,64 @@ declare class PeriodClosedError extends NoydbError {
327
347
  readonly recordTs: string;
328
348
  constructor(periodName: string, endDate: string, recordTs: string);
329
349
  }
350
+ /**
351
+ * Thrown when a `put()` or `delete()` is rejected by a guard's `check`
352
+ * function. The `reason` is the message the guard supplied — typically a
353
+ * short business description (e.g. "invoice is issued"). The full
354
+ * collection + id are surfaced so audit UIs can link back to the record.
355
+ */
356
+ declare class RecordLockedError extends NoydbError {
357
+ readonly collection: string;
358
+ readonly id: string;
359
+ readonly reason: string;
360
+ constructor(collection: string, id: string, reason: string);
361
+ }
362
+ /**
363
+ * Thrown when a `put()` changes one or more fields that are frozen by a
364
+ * `frozenFields` guard. The `fields` list contains the specific paths
365
+ * that were detected as changed.
366
+ */
367
+ declare class FieldFrozenError extends NoydbError {
368
+ readonly collection: string;
369
+ readonly id: string;
370
+ readonly fields: readonly string[];
371
+ constructor(collection: string, id: string, fields: readonly string[]);
372
+ }
373
+ /**
374
+ * Thrown by an amendment invariant when the proposed change-set violates
375
+ * the declared business rule (e.g. disbursement total not preserved).
376
+ * Triggers a full transaction rollback via the existing revert pass.
377
+ */
378
+ declare class InvariantError extends NoydbError {
379
+ constructor(message: string);
380
+ }
381
+ /**
382
+ * Thrown at `withTransactions({ amendment: true })` open if the caller's
383
+ * role is not in the guard's allowed amendment roles. Fail-fast: thrown
384
+ * before any writes are attempted.
385
+ */
386
+ declare class AmendmentForbiddenError extends NoydbError {
387
+ readonly userId: string;
388
+ readonly role: string;
389
+ constructor(userId: string, role: string);
390
+ }
391
+ /**
392
+ * Thrown by `listUsersWithEnvelopes` when the vault's user directory
393
+ * has been disabled (via `db.setDirectoryEnabled(vault, false)`) and
394
+ * the caller's role is neither `owner` nor `admin`. Owner/admin can
395
+ * still enumerate users — the toggle is a UX privacy switch, not a
396
+ * security boundary.
397
+ *
398
+ * Honest caveat: this is a UX flag, not a privacy guarantee. The
399
+ * envelope ciphertext is still in the store, the keyring file is
400
+ * still listed at `_keyring/*`, and anyone with direct store read
401
+ * access can count keyrings without going through the hub. See
402
+ * `docs/subsystems/user-envelope.md` → "Directory visibility".
403
+ */
404
+ declare class DirectoryDisabledError extends NoydbError {
405
+ readonly vault: string;
406
+ constructor(vault: string);
407
+ }
330
408
  /**
331
409
  * Thrown when a user tries to act at a tier they are not cleared for.
332
410
  *
@@ -584,6 +662,33 @@ declare class IndexWriteFailureError extends NoydbError {
584
662
  declare class BundleIntegrityError extends NoydbError {
585
663
  constructor(message: string);
586
664
  }
665
+ /**
666
+ * Thrown by `readNoydbBundle` (#197) when the bundle carries
667
+ * sealed per-user passphrases but no supplied `SealingKeyProvider`
668
+ * has a `.id` (= `pid`) matching the sealed entry's `pid`.
669
+ *
670
+ * Carries the failing pid + the user id so the recipient can
671
+ * surface an actionable prompt:
672
+ *
673
+ * ```
674
+ * BundleSealMismatchError: bundle carries sealed passphrase for user "alice"
675
+ * under provider "macos-keychain:com.acme.app/alice@acme.example",
676
+ * but no registered provider matches that pid.
677
+ * ```
678
+ *
679
+ * Three resolution paths the message names (per foundation §11.9.4):
680
+ *
681
+ * 1. Configure a provider matching the pid and retry import.
682
+ * 2. Pass `attemptUnsealAcrossProviders: true` to try each
683
+ * registered provider regardless of pid.
684
+ * 3. Inspect without unsealing — pass no `sealingProviders` to
685
+ * receive the sealed entries unmodified for offline analysis.
686
+ */
687
+ declare class BundleSealMismatchError extends NoydbError {
688
+ readonly userId: string;
689
+ readonly pid: string;
690
+ constructor(userId: string, pid: string);
691
+ }
587
692
  /**
588
693
  * Thrown when `vault.collection()` is called with a name that is
589
694
  * reserved for NOYDB internal use (any name starting with `_dict_`).
@@ -830,6 +935,156 @@ declare class PathEscapeError extends NoydbError {
830
935
  targetDir: string;
831
936
  });
832
937
  }
938
+ /**
939
+ * Thrown at vault open if the derivation graph contains a cycle.
940
+ * `path` is the offending chain (e.g. `['a', 'b', 'c', 'a']`).
941
+ */
942
+ declare class DerivationCycleError extends NoydbError {
943
+ readonly path: readonly string[];
944
+ constructor(path: readonly string[]);
945
+ }
946
+ /**
947
+ * Thrown when a cascade of source → output → source → … exceeds the
948
+ * configured `maxDepth` (default 5).
949
+ */
950
+ declare class DerivationDepthError extends NoydbError {
951
+ readonly limit: number;
952
+ readonly attempted: number;
953
+ constructor(limit: number, attempted: number);
954
+ }
955
+ /**
956
+ * Thrown at registration if a `withDerivation` strategy references an
957
+ * output `collection` that isn't otherwise declared (no schema, no use
958
+ * elsewhere). Surfacing this early catches typos in collection names.
959
+ */
960
+ declare class DerivationOutputUnknownError extends NoydbError {
961
+ readonly collection: string;
962
+ constructor(collection: string);
963
+ }
964
+ /**
965
+ * Thrown when the user's `derive` function returns a value that doesn't
966
+ * match the declared output spec (e.g. wrong shape, wrong key set).
967
+ */
968
+ declare class DerivationOutputShapeError extends NoydbError {
969
+ readonly outputKey: string;
970
+ constructor(outputKey: string, detail: string);
971
+ }
972
+ /**
973
+ * Thrown by array-shape derivations (#200) when the `derive` function
974
+ * returns more rows than the output's `maxFanout` cap. The cap exists
975
+ * to keep dispatch cost bounded — without it a single source-row
976
+ * update could fan out to thousands of derived rows, dominating the
977
+ * write path.
978
+ *
979
+ * Defaults to `maxFanout: 64`. Raise on the output spec for
980
+ * carry-forward expansion cases (e.g. monthly rows across multi-year
981
+ * contracts).
982
+ */
983
+ declare class DerivationCapExceededError extends NoydbError {
984
+ readonly outputKey: string;
985
+ readonly returned: number;
986
+ readonly maxFanout: number;
987
+ constructor(outputKey: string, returned: number, maxFanout: number);
988
+ }
989
+ /**
990
+ * Thrown at vault open if the materialized-view graph contains a
991
+ * cycle. `path` is the offending chain (e.g. `['a-mv', 'b-mv', 'a-mv']`).
992
+ * Detected by the same shared DFS that catches `DerivationCycleError`;
993
+ * surfaces with a distinct error type so consumers can disambiguate.
994
+ */
995
+ declare class MaterializedViewCycleError extends NoydbError {
996
+ readonly path: readonly string[];
997
+ constructor(path: readonly string[]);
998
+ }
999
+ /**
1000
+ * Thrown at MV registration if the query references a source
1001
+ * collection that isn't declared on the vault. Surfacing this early
1002
+ * catches typos in collection names.
1003
+ */
1004
+ declare class MaterializedViewSourceUnknownError extends NoydbError {
1005
+ readonly mvName: string;
1006
+ readonly collection: string;
1007
+ constructor(mvName: string, collection: string);
1008
+ }
1009
+ /**
1010
+ * Thrown by the MV executor when a refresh produces more rows than
1011
+ * the configured ceiling. Default ceiling is 100k rows; override
1012
+ * per-MV via `maxRows`. Mirrors `JoinTooLargeError` /
1013
+ * `GroupCardinalityError` from the query DSL — the explosion is
1014
+ * detected BEFORE writes hit the store, so the source-write
1015
+ * transaction can roll back cleanly via strict-mode.
1016
+ */
1017
+ declare class MaterializedViewTooLargeError extends NoydbError {
1018
+ readonly mvName: string;
1019
+ readonly expected: number;
1020
+ readonly limit: number;
1021
+ constructor(mvName: string, expected: number, limit: number);
1022
+ }
1023
+ /**
1024
+ * Thrown by `withMaterializedView()` at registration time when the
1025
+ * strategy is structurally malformed. Distinct from
1026
+ * `MaterializedViewSourceUnknownError` (the source list is well-formed
1027
+ * but names a collection the vault doesn't know) and
1028
+ * `MaterializedViewCycleError` (the source graph has a cycle): this
1029
+ * error fires before either check, at the moment the spec is being
1030
+ * normalized.
1031
+ *
1032
+ * Today the trigger cases are all about the `query` / `unionSources`
1033
+ * dichotomy introduced by #165:
1034
+ * - both `query` and `unionSources` were set (mutually exclusive),
1035
+ * - neither `query` nor `unionSources` was set,
1036
+ * - `unionSources` has fewer than 2 arms,
1037
+ * - two arms in `unionSources` reference the same `collection`.
1038
+ *
1039
+ * The error message is prefixed with `[noy-db] withMaterializedView:`
1040
+ * so it's grep-friendly in logs and looks consistent with the existing
1041
+ * `ValidationError` messages from the same factory.
1042
+ */
1043
+ declare class MaterializedViewConfigError extends NoydbError {
1044
+ constructor(message: string);
1045
+ }
1046
+ /**
1047
+ * Thrown at vault open when a `withOverlayedView` declaration uses
1048
+ * another virtual-overlay name as its `base`. Multi-overlay stacking
1049
+ * is a v2 non-goal — the shallow expansion in
1050
+ * `QueryDependencyAnalyzer` would truncate at the inner overlay
1051
+ * name, leaving downstream MVs silently stale.
1052
+ */
1053
+ declare class OverlayBaseIsVirtualError extends NoydbError {
1054
+ readonly overlayName: string;
1055
+ readonly base: string;
1056
+ constructor(overlayName: string, base: string);
1057
+ }
1058
+ /**
1059
+ * Thrown at vault open when a `withOverlayedView`'s `overlay`
1060
+ * references an unknown collection or an MV-owned collection. The
1061
+ * overlay collection is user-writable; MV-owned collections aren't.
1062
+ */
1063
+ declare class OverlayCollectionUnavailableError extends NoydbError {
1064
+ readonly overlayName: string;
1065
+ readonly overlay: string;
1066
+ constructor(overlayName: string, overlay: string);
1067
+ }
1068
+ /**
1069
+ * Thrown at vault open when a `withOverlayedView`'s virtual `name`
1070
+ * collides with an MV output or a concrete source collection.
1071
+ */
1072
+ declare class OverlayNameCollisionError extends NoydbError {
1073
+ readonly overlayName: string;
1074
+ constructor(overlayName: string);
1075
+ }
1076
+ /**
1077
+ * Thrown by the virtual overlay's `put(id, record)` when the
1078
+ * consumer-supplied `id` doesn't match `rowKey(record)`. Catches
1079
+ * fat-finger separator typos that would otherwise silently produce
1080
+ * orphaned overlay rows. Direct writes to the underlying overlay
1081
+ * collection (bypass the virtual layer) skip this validation.
1082
+ */
1083
+ declare class OverlayIdMismatchError extends NoydbError {
1084
+ readonly actual: string;
1085
+ readonly expected: string;
1086
+ constructor(actual: string, expected: string);
1087
+ }
833
1088
 
834
1089
  /**
835
1090
  * Foreign-key references — the soft-FK mechanism.
@@ -1361,12 +1616,54 @@ interface QuerySource<T> {
1361
1616
  * joinContext, and calling `.join()` on it throws with an actionable
1362
1617
  * error. See `query/join.ts` for the full design.
1363
1618
  */
1619
+ /**
1620
+ * Declared deterministic predicate (#153). Carries the consumer's
1621
+ * stable `hash` (for function-body identity), the function itself,
1622
+ * and is keyed by name when registered on a `Query<T>` via
1623
+ * `_withPredicates()`.
1624
+ */
1625
+ interface DeclaredPredicate {
1626
+ hash: string;
1627
+ fn: (record: unknown, ctx?: unknown) => boolean;
1628
+ }
1364
1629
  declare class Query<T> {
1365
1630
  private readonly source;
1366
1631
  private readonly plan;
1367
1632
  private readonly joinContext;
1368
1633
  private readonly aggregateStrategy;
1369
- constructor(source: QuerySource<T>, plan?: QueryPlan, joinContext?: JoinContext, aggregateStrategy?: AggregateStrategy);
1634
+ private readonly predicates;
1635
+ constructor(source: QuerySource<T>, plan?: QueryPlan, joinContext?: JoinContext, aggregateStrategy?: AggregateStrategy, predicates?: ReadonlyMap<string, DeclaredPredicate>);
1636
+ /**
1637
+ * @internal — accessor for the materialized-view dependency
1638
+ * analyzer. Not part of the public API; consumers should use the
1639
+ * builder methods, not inspect the plan directly.
1640
+ */
1641
+ _plan(): QueryPlan;
1642
+ /**
1643
+ * @internal — accessor for the materialized-view dependency
1644
+ * analyzer. Returns the join resolution context (or `undefined` for
1645
+ * queries constructed without a Collection backing).
1646
+ */
1647
+ _joinContext(): JoinContext | undefined;
1648
+ /**
1649
+ * @internal — clone this Query with a declared-predicate map
1650
+ * attached. Used by the materialized-view registry to enable
1651
+ * `.wherePredicate(name, ctx?)` for the MV's query callback (#153).
1652
+ * Consumers don't call this directly.
1653
+ */
1654
+ _withPredicates(predicates: ReadonlyMap<string, DeclaredPredicate>): Query<T>;
1655
+ /**
1656
+ * Filter by a registered deterministic predicate (#153). Requires
1657
+ * the Query to have been augmented with a predicates map (typically
1658
+ * via the materialized-view registry — bare Queries constructed
1659
+ * outside an MV throw on `.wherePredicate()`).
1660
+ *
1661
+ * `ctx` is an optional opaque value passed verbatim to the predicate
1662
+ * function. Both `predicateHash` (from the registration) and a
1663
+ * canonical-JSON hash of `ctx` fold into the MV's `queryHash`, so
1664
+ * either changing forces refresh on next visit.
1665
+ */
1666
+ wherePredicate(name: string, ctx?: unknown): Query<T>;
1370
1667
  /** Add a field comparison. Multiple where() calls are AND-combined. */
1371
1668
  where(field: string, op: Operator, value: unknown): Query<T>;
1372
1669
  /**
@@ -1558,6 +1855,7 @@ declare class Query<T> {
1558
1855
  * per record and can't be index-accelerated.
1559
1856
  */
1560
1857
  groupBy<F extends string>(field: F): GroupedQuery<T, F>;
1858
+ groupBy<F extends readonly [string, string, ...string[]]>(...fields: F): GroupedQueryN<T, F>;
1561
1859
  /**
1562
1860
  * Re-run the query whenever the source notifies of changes.
1563
1861
  * Returns an unsubscribe function. The callback receives the latest result.
@@ -1937,4 +2235,4 @@ declare class ScanBuilder<T> implements AsyncIterable<T> {
1937
2235
  private recordMatches;
1938
2236
  }
1939
2237
 
1940
- export { ScanBuilder as $, AlreadyElevatedError as A, BackupCorruptedError as B, ConflictError as C, DEFAULT_JOIN_MAX_ROWS as D, ElevationExpiredError as E, FilenameSanitizationError as F, GroupCardinalityError as G, type QuerySource as H, ImportCapabilityError as I, type JoinContext as J, KeyringExpiredError as K, LedgerContentionError as L, MissingTranslationError as M, NoydbError as N, type OrderBy as O, PathEscapeError as P, Query as Q, ReadOnlyAtInstantError as R, ReadOnlyError as S, ReadOnlyFrameError as T, type RefDescriptor as U, RefIntegrityError as V, type RefMode as W, RefRegistry as X, RefScopeError as Y, type RefViolation as Z, ReservedCollectionNameError as _, BackupLedgerError as a, type ScanPageProvider as a0, SchemaValidationError as a1, SessionExpiredError as a2, SessionNotFoundError as a3, SessionPolicyError as a4, StoreCapabilityError as a5, TamperedError as a6, TierDemoteDeniedError as a7, TierNotGrantedError as a8, TranslatorNotConfiguredError as a9, ValidationError as aa, applyJoins as ab, buildLiveQuery as ac, executePlan as ad, ref as ae, resetJoinWarnings as af, BundleIntegrityError as b, BundleVersionConflictError as c, DanglingReferenceError as d, DecryptionError as e, DelegationTargetMissingError as f, DictKeyInUseError as g, DictKeyMissingError as h, ExportCapabilityError as i, IndexRequiredError as j, IndexWriteFailureError as k, InvalidKeyError as l, type JoinLeg as m, type JoinStrategy as n, JoinTooLargeError as o, type JoinableSource as p, type LiveQuery as q, type LiveUpstream as r, LocaleNotSpecifiedError as s, NetworkError as t, NoAccessError as u, NotFoundError as v, PeriodClosedError as w, PermissionDeniedError as x, PrivilegeEscalationError as y, type QueryPlan as z };
2238
+ export { KeyringCorruptError as $, AmendmentForbiddenError as A, BackupCorruptedError as B, ConflictError as C, DictKeyInUseError as D, ElevationExpiredError as E, FieldFrozenError as F, ExportCapabilityError as G, FilenameSanitizationError as H, InvariantError as I, GroupCardinalityError as J, ImportCapabilityError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, IndexRequiredError as P, Query as Q, ReservedCollectionNameError as R, SessionExpiredError as S, TranslatorNotConfiguredError as T, IndexWriteFailureError as U, InvalidKeyError as V, type JoinContext as W, type JoinLeg as X, type JoinStrategy as Y, JoinTooLargeError as Z, type JoinableSource as _, DictKeyMissingError as a, KeyringExpiredError as a0, LedgerContentionError as a1, type LiveQuery as a2, type LiveUpstream as a3, NetworkError as a4, NoAccessError as a5, NotFoundError as a6, type OrderBy as a7, PathEscapeError as a8, PeriodClosedError as a9, PermissionDeniedError as aa, PrivilegeEscalationError as ab, type QueryPlan as ac, type QuerySource as ad, ReadOnlyAtInstantError as ae, ReadOnlyError as af, ReadOnlyFrameError as ag, type RefDescriptor as ah, RefIntegrityError as ai, type RefMode as aj, RefRegistry as ak, RefScopeError as al, type RefViolation as am, ScanBuilder as an, type ScanPageProvider as ao, SchemaValidationError as ap, StoreCapabilityError as aq, TamperedError as ar, TierDemoteDeniedError as as, TierNotGrantedError as at, ValidationError as au, applyJoins as av, buildLiveQuery as aw, executePlan as ax, ref as ay, resetJoinWarnings as az, SessionNotFoundError as b, SessionPolicyError as c, RecordLockedError as d, DerivationCapExceededError as e, DerivationCycleError as f, DerivationDepthError as g, DerivationOutputShapeError as h, DerivationOutputUnknownError as i, OverlayCollectionUnavailableError as j, OverlayIdMismatchError as k, OverlayNameCollisionError as l, MaterializedViewConfigError as m, MaterializedViewCycleError as n, MaterializedViewSourceUnknownError as o, MaterializedViewTooLargeError as p, AlreadyElevatedError as q, BackupLedgerError as r, BundleIntegrityError as s, BundleSealMismatchError as t, BundleVersionConflictError as u, DEFAULT_JOIN_MAX_ROWS as v, DanglingReferenceError as w, DecryptionError as x, DelegationTargetMissingError as y, DirectoryDisabledError as z };
@@ -1,4 +1,5 @@
1
- import { aS as PublicEnvelope, b0 as BundleRecipient, aY as Vault } from './types-arFMsCtn.cjs';
1
+ import { bh as PublicEnvelope, dj as SealingKeyProvider, bu as BundleRecipient, bq as Vault } from './types-C4lwMKKF.cjs';
2
+ import './index-CmVgTkqk.cjs';
2
3
 
3
4
  /**
4
5
  * `.noydb` container format — byte layout, header schema, validators.
@@ -123,6 +124,22 @@ interface NoydbBundleHeader {
123
124
  * other unknown header key still rejects at parse time.
124
125
  */
125
126
  readonly publicEnvelope?: PublicEnvelope;
127
+ /**
128
+ * Auto-unlock material indicator (#197). When present, the bundle
129
+ * body wraps the dump JSON in a structure carrying per-user
130
+ * passphrases — either plaintext (`'unsealed'`, public-by-design)
131
+ * or sealed under a `SealingKeyProvider` (`'sealed'`, requires
132
+ * matching provider on the recipient side).
133
+ *
134
+ * Visible pre-decompression so cloud listing UIs can warn before
135
+ * download: "this bundle opens itself for anyone holding the file"
136
+ * (unsealed) or "this bundle is sealed for a specific provider"
137
+ * (sealed).
138
+ *
139
+ * Absent → the body is a raw `vault.dump()` JSON string (the
140
+ * pre-#197 shape; back-compatible).
141
+ */
142
+ readonly autoUnlock?: 'unsealed' | 'sealed';
126
143
  }
127
144
  /**
128
145
  * Validate a parsed bundle header. Throws on any deviation from
@@ -188,6 +205,26 @@ declare function hasNoydbBundleMagic(bytes: Uint8Array): boolean;
188
205
  * archive utilities that don't care about decryption.
189
206
  */
190
207
 
208
+ /**
209
+ * The credential kinds that can be bundled for auto-unlock.
210
+ * WebAuthn is intentionally excluded — it is hardware-bound and
211
+ * cannot be embedded as a portable credential.
212
+ */
213
+ type AutoCredentialKind = 'passphrase' | 'password' | 'pin';
214
+ /**
215
+ * A typed credential for auto-unlock. Carries the credential `kind`
216
+ * alongside the plaintext `value`, so consumers can dispatch the
217
+ * correct login/prefill path rather than treating all credentials
218
+ * as passphrases.
219
+ *
220
+ * `bundle.ts` is a pure format layer — it carries the credential
221
+ * without interpreting it. The consumer is responsible for
222
+ * dispatching on `kind`.
223
+ */
224
+ interface AutoCredential {
225
+ readonly kind: AutoCredentialKind;
226
+ readonly value: string;
227
+ }
191
228
  /**
192
229
  * Options accepted by `writeNoydbBundle`.
193
230
  *
@@ -258,6 +295,96 @@ interface WriteNoydbBundleOptions {
258
295
  * suited to personal backup-and-restore).
259
296
  */
260
297
  readonly recipients?: readonly BundleRecipient[];
298
+ /**
299
+ * Auto-unlock — unsealed per-user credentials (#215).
300
+ *
301
+ * Generalises `autoPassphrases` to support any bundleable credential
302
+ * kind (`passphrase` | `password` | `pin`).
303
+ *
304
+ * Public-by-design: anyone holding the bundle bytes can read these
305
+ * plaintext credentials. Use for demo data, sample vaults,
306
+ * prospect onboarding.
307
+ *
308
+ * The `policy: 'public-by-design'` discriminant is mandatory. A
309
+ * bare `{ perUser }` without it is rejected at write time — the
310
+ * safety net against a careless call against a production vault.
311
+ *
312
+ * Mutually exclusive with `sealedCredentials`, `autoPassphrases`,
313
+ * and `sealedPassphrases`.
314
+ */
315
+ readonly autoCredentials?: {
316
+ readonly policy: 'public-by-design';
317
+ readonly perUser: Record<string, AutoCredential>;
318
+ };
319
+ /**
320
+ * Auto-unlock — per-user credentials sealed under a
321
+ * {@link SealingKeyProvider} (#215).
322
+ *
323
+ * Generalises `sealedPassphrases` to support any bundleable
324
+ * credential kind (`passphrase` | `password` | `pin`).
325
+ *
326
+ * The hub seals each user's plaintext credential under `provider`
327
+ * and embeds the resulting sealed envelopes in the bundle. The
328
+ * recipient must hold a provider with a matching `pid` (i.e.,
329
+ * `provider.id`) to auto-unseal on import.
330
+ *
331
+ * `mode: 'self-target'` is the only supported mode — sender and
332
+ * recipient share the same provider identity (same iCloud Keychain
333
+ * entry, same MDM-provisioned bundle id, same KMS account, etc.).
334
+ *
335
+ * Mutually exclusive with `autoCredentials`, `autoPassphrases`,
336
+ * and `sealedPassphrases`.
337
+ */
338
+ readonly sealedCredentials?: {
339
+ readonly mode: 'self-target';
340
+ readonly provider: SealingKeyProvider;
341
+ readonly perUser: Record<string, AutoCredential>;
342
+ };
343
+ /**
344
+ * @deprecated Use `autoCredentials` instead (#215).
345
+ *
346
+ * Auto-unlock — unsealed per-user passphrases (#197 slice 1).
347
+ *
348
+ * Public-by-design: anyone holding the bundle bytes can read these
349
+ * plaintext credentials. Use for demo data, sample vaults,
350
+ * prospect onboarding.
351
+ *
352
+ * The `policy: 'public-by-design'` discriminant is mandatory. A
353
+ * bare `{ perUser }` without it is rejected at write time — the
354
+ * safety net against a careless call against a production vault.
355
+ *
356
+ * Mutually exclusive with `autoCredentials`, `sealedCredentials`,
357
+ * and `sealedPassphrases`.
358
+ */
359
+ readonly autoPassphrases?: {
360
+ readonly policy: 'public-by-design';
361
+ readonly perUser: Record<string, string>;
362
+ };
363
+ /**
364
+ * @deprecated Use `sealedCredentials` instead (#215).
365
+ *
366
+ * Auto-unlock — per-user passphrases sealed under a
367
+ * {@link SealingKeyProvider} (#197 slice 1, self-target only).
368
+ *
369
+ * The hub seals each user's plaintext passphrase under `provider`
370
+ * and embeds the resulting sealed envelopes in the bundle. The
371
+ * recipient must hold a provider with a matching `pid` (i.e.,
372
+ * `provider.id`) to auto-unseal on import.
373
+ *
374
+ * `mode: 'self-target'` is the only mode in slice 1 — sender and
375
+ * recipient share the same provider identity (same iCloud Keychain
376
+ * entry, same MDM-provisioned bundle id, same KMS account, etc.).
377
+ * Recipient-target sealing via the `RecipientSealer` interface
378
+ * (foundation §11.4) is deferred to a follow-up slice.
379
+ *
380
+ * Mutually exclusive with `autoCredentials`, `sealedCredentials`,
381
+ * and `autoPassphrases`.
382
+ */
383
+ readonly sealedPassphrases?: {
384
+ readonly mode: 'self-target';
385
+ readonly provider: SealingKeyProvider;
386
+ readonly perUser: Record<string, string>;
387
+ };
261
388
  }
262
389
  /**
263
390
  * Result returned by `readNoydbBundle`. The caller is expected to
@@ -268,6 +395,50 @@ interface WriteNoydbBundleOptions {
268
395
  interface NoydbBundleReadResult {
269
396
  readonly header: NoydbBundleHeader;
270
397
  readonly dumpJson: string;
398
+ /**
399
+ * Auto-unlock material (#197, widened in #215). Present only when
400
+ * the header's `autoUnlock` flag is set AND the body's wrapped
401
+ * structure survived parsing. Values are typed credentials — either
402
+ * delivered plain (`kind: 'unsealed'`) or unsealed at read time
403
+ * using one of the supplied `sealingProviders` (`kind: 'sealed'`).
404
+ *
405
+ * Consumers dispatch on `cred.kind` to choose the correct login /
406
+ * prefill path. Pre-0.2 bundles (bare string entries) are coerced
407
+ * to `{ kind: 'passphrase', value }` on read for back-compat.
408
+ *
409
+ * For `kind: 'sealed'` bundles read without `sealingProviders`, the
410
+ * `value` field is the raw base64 sealed bytes — opaque to the
411
+ * consumer until unsealed elsewhere.
412
+ */
413
+ readonly autoUnlock?: {
414
+ readonly kind: 'unsealed' | 'sealed';
415
+ readonly perUser: Record<string, AutoCredential>;
416
+ };
417
+ }
418
+ /**
419
+ * Options accepted by {@link readNoydbBundle} for the #197
420
+ * auto-unlock paths. Without these the reader behaves exactly as
421
+ * pre-#197 (header parsed; body returned as `dumpJson`).
422
+ */
423
+ interface ReadNoydbBundleOptions {
424
+ /**
425
+ * Recipient-side sealing providers used to unseal entries from
426
+ * `sealedPassphrases`. The reader picks the one whose `.id`
427
+ * matches each entry's `pid`. Multiple providers may be supplied
428
+ * (different users may seal under different identities).
429
+ *
430
+ * When unset and the bundle carries sealed envelopes, the
431
+ * `autoUnlock.perUser` map remains the SEALED entries unmodified
432
+ * — callers can inspect them or unseal elsewhere.
433
+ */
434
+ readonly sealingProviders?: readonly SealingKeyProvider[];
435
+ /**
436
+ * Opt-in trial mode for unsealing — when an entry's `pid` doesn't
437
+ * match a registered provider, try each provider whose alg
438
+ * matches. Default `false` (strict-pid dispatch per foundation
439
+ * §11.9.2). Surfaces extra credential prompts; use deliberately.
440
+ */
441
+ readonly attemptUnsealAcrossProviders?: boolean;
271
442
  }
272
443
  /** Test-only: reset the brotli detection cache between tests. */
273
444
  declare function resetBrotliSupportCache(): void;
@@ -344,7 +515,7 @@ declare function readNoydbBundlePublicEnvelope(bytes: Uint8Array, opts?: {
344
515
  * free of crypto concerns and lets the same code feed format
345
516
  * inspectors that never decrypt anything.
346
517
  */
347
- declare function readNoydbBundle(bytes: Uint8Array): Promise<NoydbBundleReadResult>;
518
+ declare function readNoydbBundle(bytes: Uint8Array, opts?: ReadNoydbBundleOptions): Promise<NoydbBundleReadResult>;
348
519
 
349
520
  /**
350
521
  * Minimal ULID generator — zero dependencies, Web Crypto API only.
@@ -411,4 +582,4 @@ declare function generateULID(): string;
411
582
  */
412
583
  declare function isULID(value: string): boolean;
413
584
 
414
- export { type CompressionAlgo as C, FLAG_COMPRESSED as F, NOYDB_BUNDLE_FORMAT_VERSION as N, type WriteNoydbBundleOptions as W, NOYDB_BUNDLE_MAGIC as a, NOYDB_BUNDLE_PREFIX_BYTES as b, type NoydbBundleHeader as c, type NoydbBundleReadResult as d, readNoydbBundleHeader as e, readNoydbBundlePublicEnvelope as f, generateULID as g, hasNoydbBundleMagic as h, isULID as i, resetBrotliSupportCache as j, COMPRESSION_BROTLI as k, COMPRESSION_GZIP as l, COMPRESSION_NONE as m, FLAG_HAS_INTEGRITY_HASH as n, encodeBundleHeader as o, readNoydbBundle as r, validateBundleHeader as v, writeNoydbBundle as w };
585
+ export { type AutoCredential as A, type CompressionAlgo as C, FLAG_COMPRESSED as F, NOYDB_BUNDLE_FORMAT_VERSION as N, type ReadNoydbBundleOptions as R, type WriteNoydbBundleOptions as W, type AutoCredentialKind as a, NOYDB_BUNDLE_MAGIC as b, NOYDB_BUNDLE_PREFIX_BYTES as c, type NoydbBundleHeader as d, type NoydbBundleReadResult as e, readNoydbBundleHeader as f, generateULID as g, hasNoydbBundleMagic as h, isULID as i, readNoydbBundlePublicEnvelope as j, resetBrotliSupportCache as k, COMPRESSION_BROTLI as l, COMPRESSION_GZIP as m, COMPRESSION_NONE as n, FLAG_HAS_INTEGRITY_HASH as o, encodeBundleHeader as p, readNoydbBundle as r, validateBundleHeader as v, writeNoydbBundle as w };