mindoodb 0.0.23 → 0.0.32

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 (340) hide show
  1. package/README-server.md +9 -1
  2. package/README.md +5 -3
  3. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +1 -1
  4. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  5. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +24 -5
  6. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  7. package/dist/appendonlystores/network/HttpTransport.d.ts +14 -2
  8. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  9. package/dist/appendonlystores/network/HttpTransport.js +124 -27
  10. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  11. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +159 -4
  12. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  13. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +334 -25
  14. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
  15. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +9 -0
  16. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -1
  17. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +77 -5
  18. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -1
  19. package/dist/browser/index.mjs +103 -0
  20. package/dist/core/BaseMindooDB.d.ts +697 -4
  21. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  22. package/dist/core/BaseMindooDB.js +3273 -180
  23. package/dist/core/BaseMindooDB.js.map +1 -1
  24. package/dist/core/BaseMindooTenant.d.ts +192 -1
  25. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  26. package/dist/core/BaseMindooTenant.js +633 -88
  27. package/dist/core/BaseMindooTenant.js.map +1 -1
  28. package/dist/core/BaseMindooTenantDirectory.d.ts +770 -10
  29. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  30. package/dist/core/BaseMindooTenantDirectory.js +2715 -292
  31. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  32. package/dist/core/BaseMindooTenantFactory.d.ts +2 -0
  33. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  34. package/dist/core/BaseMindooTenantFactory.js +20 -0
  35. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  36. package/dist/core/accesscontrol/AccessDeniedError.d.ts +22 -0
  37. package/dist/core/accesscontrol/AccessDeniedError.d.ts.map +1 -0
  38. package/dist/core/accesscontrol/AccessDeniedError.js +28 -0
  39. package/dist/core/accesscontrol/AccessDeniedError.js.map +1 -0
  40. package/dist/core/accesscontrol/DirectoryStateNode.d.ts +220 -0
  41. package/dist/core/accesscontrol/DirectoryStateNode.d.ts.map +1 -0
  42. package/dist/core/accesscontrol/DirectoryStateNode.js +297 -0
  43. package/dist/core/accesscontrol/DirectoryStateNode.js.map +1 -0
  44. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts +118 -0
  45. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts.map +1 -0
  46. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js +173 -0
  47. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js.map +1 -0
  48. package/dist/core/accesscontrol/directoryProjection.d.ts +26 -0
  49. package/dist/core/accesscontrol/directoryProjection.d.ts.map +1 -0
  50. package/dist/core/accesscontrol/directoryProjection.js +174 -0
  51. package/dist/core/accesscontrol/directoryProjection.js.map +1 -0
  52. package/dist/core/accesscontrol/evaluate.d.ts +77 -0
  53. package/dist/core/accesscontrol/evaluate.d.ts.map +1 -0
  54. package/dist/core/accesscontrol/evaluate.js +206 -0
  55. package/dist/core/accesscontrol/evaluate.js.map +1 -0
  56. package/dist/core/accesscontrol/grantKeys.d.ts +113 -0
  57. package/dist/core/accesscontrol/grantKeys.d.ts.map +1 -0
  58. package/dist/core/accesscontrol/grantKeys.js +302 -0
  59. package/dist/core/accesscontrol/grantKeys.js.map +1 -0
  60. package/dist/core/accesscontrol/keyBagReconciler.d.ts +22 -0
  61. package/dist/core/accesscontrol/keyBagReconciler.d.ts.map +1 -0
  62. package/dist/core/accesscontrol/keyBagReconciler.js +3 -0
  63. package/dist/core/accesscontrol/keyBagReconciler.js.map +1 -0
  64. package/dist/core/accesscontrol/materializationGuard.d.ts +89 -0
  65. package/dist/core/accesscontrol/materializationGuard.d.ts.map +1 -0
  66. package/dist/core/accesscontrol/materializationGuard.js +69 -0
  67. package/dist/core/accesscontrol/materializationGuard.js.map +1 -0
  68. package/dist/core/accesscontrol/quarantine.d.ts +65 -0
  69. package/dist/core/accesscontrol/quarantine.d.ts.map +1 -0
  70. package/dist/core/accesscontrol/quarantine.js +79 -0
  71. package/dist/core/accesscontrol/quarantine.js.map +1 -0
  72. package/dist/core/accesscontrol/receiptValidation.d.ts +113 -0
  73. package/dist/core/accesscontrol/receiptValidation.d.ts.map +1 -0
  74. package/dist/core/accesscontrol/receiptValidation.js +142 -0
  75. package/dist/core/accesscontrol/receiptValidation.js.map +1 -0
  76. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts +31 -0
  77. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts.map +1 -0
  78. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js +66 -0
  79. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js.map +1 -0
  80. package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts +79 -0
  81. package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts.map +1 -0
  82. package/dist/core/accesscontrol/timestamp/TimestampProvider.js +22 -0
  83. package/dist/core/accesscontrol/timestamp/TimestampProvider.js.map +1 -0
  84. package/dist/core/accesscontrol/types.d.ts +825 -0
  85. package/dist/core/accesscontrol/types.d.ts.map +1 -0
  86. package/dist/core/accesscontrol/types.js +534 -0
  87. package/dist/core/accesscontrol/types.js.map +1 -0
  88. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +9 -0
  89. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  90. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +54 -0
  91. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  92. package/dist/core/appendonlystores/network/AuthenticationService.d.ts +38 -2
  93. package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
  94. package/dist/core/appendonlystores/network/AuthenticationService.js +199 -26
  95. package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
  96. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +17 -3
  97. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  98. package/dist/core/appendonlystores/network/types.d.ts +58 -4
  99. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  100. package/dist/core/appendonlystores/network/types.js +4 -0
  101. package/dist/core/appendonlystores/network/types.js.map +1 -1
  102. package/dist/core/appendonlystores/scanUtils.d.ts +27 -0
  103. package/dist/core/appendonlystores/scanUtils.d.ts.map +1 -0
  104. package/dist/core/appendonlystores/scanUtils.js +87 -0
  105. package/dist/core/appendonlystores/scanUtils.js.map +1 -0
  106. package/dist/core/appendonlystores/types.d.ts +23 -2
  107. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  108. package/dist/core/cache/CacheManager.d.ts +13 -3
  109. package/dist/core/cache/CacheManager.d.ts.map +1 -1
  110. package/dist/core/cache/CacheManager.js +7 -4
  111. package/dist/core/cache/CacheManager.js.map +1 -1
  112. package/dist/core/crypto/EntrySignature.d.ts +137 -0
  113. package/dist/core/crypto/EntrySignature.d.ts.map +1 -0
  114. package/dist/core/crypto/EntrySignature.js +210 -0
  115. package/dist/core/crypto/EntrySignature.js.map +1 -0
  116. package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -1
  117. package/dist/core/crypto/MindooDocSigner.js +6 -2
  118. package/dist/core/crypto/MindooDocSigner.js.map +1 -1
  119. package/dist/core/crypto/WitnessReceipt.d.ts +137 -0
  120. package/dist/core/crypto/WitnessReceipt.d.ts.map +1 -0
  121. package/dist/core/crypto/WitnessReceipt.js +182 -0
  122. package/dist/core/crypto/WitnessReceipt.js.map +1 -0
  123. package/dist/core/crypto/encryptedFields.d.ts +27 -0
  124. package/dist/core/crypto/encryptedFields.d.ts.map +1 -0
  125. package/dist/core/crypto/encryptedFields.js +58 -0
  126. package/dist/core/crypto/encryptedFields.js.map +1 -0
  127. package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
  128. package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -1
  129. package/dist/core/crypto/pbkdf2Iterations.js +23 -0
  130. package/dist/core/crypto/pbkdf2Iterations.js.map +1 -1
  131. package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -1
  132. package/dist/core/crypto/privateKeyEncryption.js +3 -1
  133. package/dist/core/crypto/privateKeyEncryption.js.map +1 -1
  134. package/dist/core/databaseIdValidation.d.ts +1 -1
  135. package/dist/core/databaseIdValidation.d.ts.map +1 -1
  136. package/dist/core/databaseIdValidation.js +4 -4
  137. package/dist/core/databaseIdValidation.js.map +1 -1
  138. package/dist/core/errors.d.ts +26 -0
  139. package/dist/core/errors.d.ts.map +1 -1
  140. package/dist/core/errors.js +42 -1
  141. package/dist/core/errors.js.map +1 -1
  142. package/dist/core/expressions/builder.d.ts +102 -0
  143. package/dist/core/expressions/builder.d.ts.map +1 -0
  144. package/dist/core/expressions/builder.js +249 -0
  145. package/dist/core/expressions/builder.js.map +1 -0
  146. package/dist/core/expressions/evaluateExpression.d.ts +78 -0
  147. package/dist/core/expressions/evaluateExpression.d.ts.map +1 -0
  148. package/dist/core/expressions/evaluateExpression.js +386 -0
  149. package/dist/core/expressions/evaluateExpression.js.map +1 -0
  150. package/dist/core/expressions/formulaSource.d.ts +24 -0
  151. package/dist/core/expressions/formulaSource.d.ts.map +1 -0
  152. package/dist/core/expressions/formulaSource.js +765 -0
  153. package/dist/core/expressions/formulaSource.js.map +1 -0
  154. package/dist/core/expressions/index.d.ts +8 -0
  155. package/dist/core/expressions/index.d.ts.map +1 -0
  156. package/dist/core/expressions/index.js +46 -0
  157. package/dist/core/expressions/index.js.map +1 -0
  158. package/dist/core/expressions/metadata.d.ts +23 -0
  159. package/dist/core/expressions/metadata.d.ts.map +1 -0
  160. package/dist/core/expressions/metadata.js +191 -0
  161. package/dist/core/expressions/metadata.js.map +1 -0
  162. package/dist/core/expressions/types.d.ts +164 -0
  163. package/dist/core/expressions/types.d.ts.map +1 -0
  164. package/dist/core/expressions/types.js +3 -0
  165. package/dist/core/expressions/types.js.map +1 -0
  166. package/dist/core/extraction/types.d.ts +47 -0
  167. package/dist/core/extraction/types.d.ts.map +1 -0
  168. package/dist/core/extraction/types.js +42 -0
  169. package/dist/core/extraction/types.js.map +1 -0
  170. package/dist/core/index.d.ts +13 -3
  171. package/dist/core/index.d.ts.map +1 -1
  172. package/dist/core/index.js +113 -4
  173. package/dist/core/index.js.map +1 -1
  174. package/dist/core/indexing/createViewDataProvider.d.ts +84 -0
  175. package/dist/core/indexing/createViewDataProvider.d.ts.map +1 -0
  176. package/dist/core/indexing/createViewDataProvider.js +139 -0
  177. package/dist/core/indexing/createViewDataProvider.js.map +1 -0
  178. package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts +180 -0
  179. package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts.map +1 -0
  180. package/dist/core/indexing/fulltext/DocumentFullTextIndex.js +548 -0
  181. package/dist/core/indexing/fulltext/DocumentFullTextIndex.js.map +1 -0
  182. package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts +69 -0
  183. package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts.map +1 -0
  184. package/dist/core/indexing/fulltext/SearchEngineAdapter.js +183 -0
  185. package/dist/core/indexing/fulltext/SearchEngineAdapter.js.map +1 -0
  186. package/dist/core/indexing/fulltext/extractFulltextText.d.ts +34 -0
  187. package/dist/core/indexing/fulltext/extractFulltextText.d.ts.map +1 -0
  188. package/dist/core/indexing/fulltext/extractFulltextText.js +129 -0
  189. package/dist/core/indexing/fulltext/extractFulltextText.js.map +1 -0
  190. package/dist/core/indexing/fulltext/index.d.ts +5 -0
  191. package/dist/core/indexing/fulltext/index.d.ts.map +1 -0
  192. package/dist/core/indexing/fulltext/index.js +20 -0
  193. package/dist/core/indexing/fulltext/index.js.map +1 -0
  194. package/dist/core/indexing/fulltext/types.d.ts +168 -0
  195. package/dist/core/indexing/fulltext/types.d.ts.map +1 -0
  196. package/dist/core/indexing/fulltext/types.js +89 -0
  197. package/dist/core/indexing/fulltext/types.js.map +1 -0
  198. package/dist/core/indexing/summary/DocumentSummaryStore.d.ts +137 -0
  199. package/dist/core/indexing/summary/DocumentSummaryStore.d.ts.map +1 -0
  200. package/dist/core/indexing/summary/DocumentSummaryStore.js +438 -0
  201. package/dist/core/indexing/summary/DocumentSummaryStore.js.map +1 -0
  202. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts +72 -0
  203. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts.map +1 -0
  204. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js +221 -0
  205. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js.map +1 -0
  206. package/dist/core/indexing/summary/extractSummaryFields.d.ts +75 -0
  207. package/dist/core/indexing/summary/extractSummaryFields.d.ts.map +1 -0
  208. package/dist/core/indexing/summary/extractSummaryFields.js +266 -0
  209. package/dist/core/indexing/summary/extractSummaryFields.js.map +1 -0
  210. package/dist/core/indexing/summary/index.d.ts +5 -0
  211. package/dist/core/indexing/summary/index.d.ts.map +1 -0
  212. package/dist/core/indexing/summary/index.js +23 -0
  213. package/dist/core/indexing/summary/index.js.map +1 -0
  214. package/dist/core/indexing/summary/types.d.ts +119 -0
  215. package/dist/core/indexing/summary/types.d.ts.map +1 -0
  216. package/dist/core/indexing/summary/types.js +81 -0
  217. package/dist/core/indexing/summary/types.js.map +1 -0
  218. package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts +47 -1
  219. package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts.map +1 -1
  220. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +24 -8
  221. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
  222. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +96 -41
  223. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
  224. package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts +2 -0
  225. package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts.map +1 -1
  226. package/dist/core/indexing/virtualviews/ViewEntrySortKey.js +8 -3
  227. package/dist/core/indexing/virtualviews/ViewEntrySortKey.js.map +1 -1
  228. package/dist/core/indexing/virtualviews/VirtualView.d.ts +111 -5
  229. package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
  230. package/dist/core/indexing/virtualviews/VirtualView.js +266 -75
  231. package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
  232. package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts +12 -0
  233. package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts.map +1 -1
  234. package/dist/core/indexing/virtualviews/VirtualViewColumn.js +1 -0
  235. package/dist/core/indexing/virtualviews/VirtualViewColumn.js.map +1 -1
  236. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +12 -0
  237. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
  238. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +66 -5
  239. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
  240. package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +50 -6
  241. package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -1
  242. package/dist/core/indexing/virtualviews/VirtualViewFactory.js +54 -12
  243. package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -1
  244. package/dist/core/indexing/virtualviews/index.d.ts +3 -3
  245. package/dist/core/indexing/virtualviews/index.d.ts.map +1 -1
  246. package/dist/core/indexing/virtualviews/index.js.map +1 -1
  247. package/dist/core/indexing/virtualviews/types.d.ts +6 -0
  248. package/dist/core/indexing/virtualviews/types.d.ts.map +1 -1
  249. package/dist/core/indexing/virtualviews/types.js +11 -3
  250. package/dist/core/indexing/virtualviews/types.js.map +1 -1
  251. package/dist/core/keys/KeyBag.d.ts +25 -0
  252. package/dist/core/keys/KeyBag.d.ts.map +1 -1
  253. package/dist/core/keys/KeyBag.js +37 -1
  254. package/dist/core/keys/KeyBag.js.map +1 -1
  255. package/dist/core/query/executeQuery.d.ts +18 -0
  256. package/dist/core/query/executeQuery.d.ts.map +1 -0
  257. package/dist/core/query/executeQuery.js +313 -0
  258. package/dist/core/query/executeQuery.js.map +1 -0
  259. package/dist/core/query/index.d.ts +5 -0
  260. package/dist/core/query/index.d.ts.map +1 -0
  261. package/dist/core/query/index.js +14 -0
  262. package/dist/core/query/index.js.map +1 -0
  263. package/dist/core/query/queryLive.d.ts +27 -0
  264. package/dist/core/query/queryLive.d.ts.map +1 -0
  265. package/dist/core/query/queryLive.js +104 -0
  266. package/dist/core/query/queryLive.js.map +1 -0
  267. package/dist/core/query/queryView.d.ts +156 -0
  268. package/dist/core/query/queryView.d.ts.map +1 -0
  269. package/dist/core/query/queryView.js +266 -0
  270. package/dist/core/query/queryView.js.map +1 -0
  271. package/dist/core/query/types.d.ts +121 -0
  272. package/dist/core/query/types.d.ts.map +1 -0
  273. package/dist/core/query/types.js +18 -0
  274. package/dist/core/query/types.js.map +1 -0
  275. package/dist/core/storeEntryTime.d.ts +57 -0
  276. package/dist/core/storeEntryTime.d.ts.map +1 -0
  277. package/dist/core/storeEntryTime.js +72 -0
  278. package/dist/core/storeEntryTime.js.map +1 -0
  279. package/dist/core/types.d.ts +1509 -39
  280. package/dist/core/types.d.ts.map +1 -1
  281. package/dist/core/types.js +13 -1
  282. package/dist/core/types.js.map +1 -1
  283. package/dist/core/uri/MindooURI.d.ts +53 -1
  284. package/dist/core/uri/MindooURI.d.ts.map +1 -1
  285. package/dist/core/uri/MindooURI.js +135 -0
  286. package/dist/core/uri/MindooURI.js.map +1 -1
  287. package/dist/core/utils/urlSafety.d.ts +46 -0
  288. package/dist/core/utils/urlSafety.d.ts.map +1 -0
  289. package/dist/core/utils/urlSafety.js +144 -0
  290. package/dist/core/utils/urlSafety.js.map +1 -0
  291. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +14 -0
  292. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
  293. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +95 -4
  294. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
  295. package/dist/node/server/CapabilityMatcher.d.ts +10 -0
  296. package/dist/node/server/CapabilityMatcher.d.ts.map +1 -1
  297. package/dist/node/server/CapabilityMatcher.js +14 -2
  298. package/dist/node/server/CapabilityMatcher.js.map +1 -1
  299. package/dist/node/server/MindooDBServer.d.ts.map +1 -1
  300. package/dist/node/server/MindooDBServer.js +117 -8
  301. package/dist/node/server/MindooDBServer.js.map +1 -1
  302. package/dist/node/server/PurgedDocRegistry.d.ts +32 -0
  303. package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -0
  304. package/dist/node/server/PurgedDocRegistry.js +94 -0
  305. package/dist/node/server/PurgedDocRegistry.js.map +1 -0
  306. package/dist/node/server/ServerSync.d.ts.map +1 -1
  307. package/dist/node/server/ServerSync.js +5 -2
  308. package/dist/node/server/ServerSync.js.map +1 -1
  309. package/dist/node/server/SystemAdminAuth.d.ts +10 -0
  310. package/dist/node/server/SystemAdminAuth.d.ts.map +1 -1
  311. package/dist/node/server/SystemAdminAuth.js +25 -0
  312. package/dist/node/server/SystemAdminAuth.js.map +1 -1
  313. package/dist/node/server/TenantManager.d.ts +95 -1
  314. package/dist/node/server/TenantManager.d.ts.map +1 -1
  315. package/dist/node/server/TenantManager.js +382 -15
  316. package/dist/node/server/TenantManager.js.map +1 -1
  317. package/dist/node/server/config.d.ts.map +1 -1
  318. package/dist/node/server/config.js +5 -1
  319. package/dist/node/server/config.js.map +1 -1
  320. package/dist/node/server/types.d.ts +29 -3
  321. package/dist/node/server/types.d.ts.map +1 -1
  322. package/dist/node/server/types.js +12 -0
  323. package/dist/node/server/types.js.map +1 -1
  324. package/dist/node/server/validation.d.ts +6 -0
  325. package/dist/node/server/validation.d.ts.map +1 -1
  326. package/dist/node/server/validation.js +7 -1
  327. package/dist/node/server/validation.js.map +1 -1
  328. package/package.json +4 -3
  329. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +0 -8
  330. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +0 -1
  331. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +0 -16
  332. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +0 -1
  333. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +0 -68
  334. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +0 -1
  335. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +0 -659
  336. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +0 -1
  337. package/dist/node/attachments/writeAttachmentToFile.d.ts +0 -15
  338. package/dist/node/attachments/writeAttachmentToFile.d.ts.map +0 -1
  339. package/dist/node/attachments/writeAttachmentToFile.js +0 -73
  340. package/dist/node/attachments/writeAttachmentToFile.js.map +0 -1
@@ -1,9 +1,20 @@
1
- import { MindooDB, CreateOptions, DeleteOptions, UndeleteOptions, ChangeOptions, DocumentDagAnalysisTimestamp, DocumentDagAnalysisResult, DocumentDagBranchMaterializationResult, DocumentDagEntryDetails, DocumentConflictAnalysisEvent, DocumentConflictAnalysisOptions, DocumentConflictBaseValue, DocumentConflictBaseValueQuery, DocumentConflictReport, DocumentConflictReportOptions, ConflictScanCheckpoint, MindooDoc, MindooTenant, ProcessChangesCursor, ProcessChangesResult, DocumentHistoryResult, AttachmentConfig, DocumentCacheConfig, SnapshotConfig, SigningKeyPair, PerformanceCallback, ProcessChangeSummaryResult, IncompleteAttachmentUploadReclaimResult, SyncOptions, SyncResult, DocumentHistoryPageOptions, DocumentHistoryPageResult, MindooJsonPatch, MindooJsonPatchResult, MindooRichTextPatch, MindooRichTextPatchResult, MindooRichTextSnapshot, MindooTextPatch, MindooTextPatchResult, StartBackgroundWarmerOptions, BackgroundWarmerProgress } from "./types";
1
+ import { MindooDB, CreateOptions, DeleteOptions, UndeleteOptions, ChangeOptions, DocumentDagAnalysisTimestamp, DocumentDagAnalysisResult, DocumentDagBranchMaterializationResult, DocumentDagEntryDetails, DocumentConflictAnalysisEvent, DocumentConflictAnalysisOptions, DocumentConflictBaseValue, DocumentConflictBaseValueQuery, DocumentConflictReport, DocumentConflictReportOptions, ConflictScanCheckpoint, MindooDoc, MindooTenant, ProcessChangesCursor, ProcessChangesResult, DocumentHistoryResult, RevisionCursor, ChangeRevisionResult, AttachmentConfig, DocumentCacheConfig, SnapshotConfig, SigningKeyPair, PerformanceCallback, ProcessChangeSummaryResult, IncompleteAttachmentUploadReclaimResult, SyncOptions, SyncResult, DocumentHistoryPageOptions, DocumentHistoryPageResult, MindooJsonPatch, MindooJsonPatchResult, MindooRichTextPatch, MindooRichTextPatchResult, MindooRichTextStepPatch, MindooRichTextSnapshot, MindooAutomergeSnapshot, MindooAutomergeChangesPatch, MindooAutomergePatchResult, MindooTextPatch, MindooTextPatchResult, StartBackgroundWarmerOptions, BackgroundWarmerProgress, DbChangeListener } from "./types";
2
2
  import { BaseMindooTenant } from "./BaseMindooTenant";
3
3
  import type { ContentAddressedStore } from "./appendonlystores/types";
4
+ import { QuarantineRecord } from "./accesscontrol/materializationGuard";
5
+ import type { AccessDecision } from "./accesscontrol/types";
4
6
  import { Logger } from "./logging";
5
7
  import type { LocalCacheStore } from "./cache/LocalCacheStore";
6
8
  import type { CacheManager } from "./cache/CacheManager";
9
+ import { DocumentSummaryStore } from "./indexing/summary/DocumentSummaryStore";
10
+ import type { SummaryConfig } from "./indexing/summary/types";
11
+ import { DocumentFullTextIndex } from "./indexing/fulltext/DocumentFullTextIndex";
12
+ import type { AttachmentTextExtractor, FulltextConfig, FulltextSearchOptions, FulltextSearchResult } from "./indexing/fulltext/types";
13
+ import { ExtractionConfig } from "./extraction/types";
14
+ import type { MindooQuery, MindooQueryOptions, MindooQueryResult } from "./query/types";
15
+ import type { EphemeralSummaryView, MindooQueryViewDefinition } from "./query/queryView";
16
+ import type { MindooQuerySubscription } from "./query/queryLive";
17
+ import type { VirtualViewUpdateOptions } from "./indexing/virtualviews/IVirtualViewDataProvider";
7
18
  /**
8
19
  * Hard-coded initial Automerge change bytes that seed every document created
9
20
  * with a caller-provided id (`createDocument({ id })`).
@@ -57,11 +68,40 @@ export declare class BaseMindooDB implements MindooDB {
57
68
  private tenant;
58
69
  private store;
59
70
  private attachmentStore;
71
+ /**
72
+ * Per-tenant quarantine/audit log of entries rejected during materialization
73
+ * (docs/accesscontrol.md §10). In-memory; surfaced via {@link getQuarantineLog}
74
+ * for Haven's audit view.
75
+ */
76
+ private quarantineLog;
77
+ /**
78
+ * Short-TTL cache of "is access control active for this tenant?" so the
79
+ * materialization fast-path does not re-query the directory on every load.
80
+ */
81
+ private aclActiveCache;
82
+ /**
83
+ * Per-document cache of the original creator's signing public key (the
84
+ * `doc_create` entry's `createdByPublicKey`). Used by the client write
85
+ * prechecks to resolve `$author` (`isAuthor`) without re-scanning metadata on
86
+ * every change/delete. Populated on create and lazily on first lookup.
87
+ */
88
+ private creatorKeyCache;
60
89
  private chunkSizeBytes;
61
90
  private _isAdminOnlyDb;
62
91
  private readonly timeTravelDate;
63
92
  private index;
64
93
  private indexLookup;
94
+ /**
95
+ * Lazily-deferred repair marker for {@link indexLookup}: when set, positions
96
+ * stored in the map for array indices >= this value may be stale (entries
97
+ * shifted by an {@link updateIndex} splice). Key presence is always exact.
98
+ * Reads go through {@link getDocIndexPosition}, which validates a hit
99
+ * against {@link index} and triggers {@link flushIndexLookupPatch} only when
100
+ * the position actually moved. This turns the per-update O(index size)
101
+ * lookup rewrite into a single deferred pass — bulk syncs that append at the
102
+ * index tail never pay it at all.
103
+ */
104
+ private indexLookupStaleFrom;
65
105
  private nextChangeSeq;
66
106
  private docCache;
67
107
  private wrappedInternalDocs;
@@ -78,16 +118,83 @@ export declare class BaseMindooDB implements MindooDB {
78
118
  private readonly restoreToL2;
79
119
  private readonly snapshotMinChanges;
80
120
  private readonly snapshotCooldownMs;
121
+ /**
122
+ * Per-document count of local writes since the last snapshot eligibility
123
+ * check that scanned the store. Lets {@link maybeWriteSnapshotForDocument}
124
+ * skip the per-doc metadata scan entirely while a document is still far
125
+ * below {@link snapshotMinChanges}. Absent key = unknown (scan once).
126
+ */
127
+ private writesSinceSnapshotCheck;
81
128
  private processedEntryIds;
82
129
  private processedEntryCursor;
130
+ /**
131
+ * In-memory LRU of per-document merged state used by the revision-grain
132
+ * changefeed ({@link iterateRevisionsInternal}). Each entry holds a document's
133
+ * fully-merged Automerge doc together with the exact set of replay entry ids
134
+ * that merge covers, so an incremental feed advance can seed the next fold
135
+ * from the cached state (applying only the newly-arrived suffix) instead of
136
+ * re-decrypting and re-folding the document's whole history. Bounded by
137
+ * {@link revisionFeedCacheLimit}; least-recently-used docs are evicted and
138
+ * reconstructed from the best snapshot on the next touch.
139
+ */
140
+ private revisionFeedDocCache;
141
+ private readonly revisionFeedCacheLimit;
142
+ /**
143
+ * Window size for batching encrypted-payload loads while folding a document's
144
+ * revision suffix ({@link foldDocRevisions}): one {@link ContentAddressedStore.getEntries}
145
+ * round trip per window instead of one per revision, while bounding peak
146
+ * memory and response size on a snapshot-less cold-start re-fold.
147
+ */
148
+ private readonly revisionFoldLoadWindow;
83
149
  private automergeHashToEntryId;
84
150
  private logger;
85
151
  private performanceCallback?;
86
152
  private publicKeyCache;
87
153
  private cacheManager;
88
154
  private cachePrefix;
155
+ /**
156
+ * Lazily created document summary buffer backing ad-hoc queries and
157
+ * summary-based views. `null` until {@link getSummaryStore} is first
158
+ * called, so databases that never query pay no cost.
159
+ */
160
+ private summaryStore;
161
+ /**
162
+ * Lazily created full-text index (opt-in via `fulltextSetup` or an
163
+ * explicit config). `null` until {@link getFullTextIndex} is first
164
+ * called or the setup document enables indexing.
165
+ */
166
+ private fulltextIndex;
167
+ /**
168
+ * Attachment text extractors registered by the host environment (see
169
+ * {@link registerAttachmentTextExtractor}). Consulted lazily by the
170
+ * full-text index while documents with attachments are indexed.
171
+ */
172
+ private attachmentTextExtractors;
173
+ private changeListeners;
174
+ private pendingChangeNotifications;
175
+ private changeNotifyTimer;
176
+ /** While > 0, timer-based emission is suppressed (e.g. during a sync batch). */
177
+ private changeNotificationHolds;
178
+ private summaryAutoUpdateEnabled;
179
+ private summaryAutoUpdateRunning;
180
+ private summaryAutoUpdatePending;
181
+ /** Whether the setup document was already probed for auto-activation. */
182
+ private summarySetupProbed;
183
+ private fulltextAutoUpdateEnabled;
184
+ private fulltextAutoUpdateRunning;
185
+ private fulltextAutoUpdatePending;
186
+ /** Whether the setup document was already probed for FTS auto-activation. */
187
+ private fulltextSetupProbed;
89
188
  private dirtyDocIds;
90
189
  private cacheMetaDirty;
190
+ /**
191
+ * Per-document fingerprint (`changeSeq:automergeHeads`) of the state last
192
+ * written to the L2 cache by {@link flushDirtyDocToCache}. Lets the periodic
193
+ * flush skip the expensive `Automerge.save` + L2 write for documents that
194
+ * were marked dirty but whose persisted state is already current (e.g. docs
195
+ * that were merely loaded and cached, not changed).
196
+ */
197
+ private lastFlushedDocState;
91
198
  /**
92
199
  * Tenant KeyBag fingerprint observed at the time the in-memory index
93
200
  * was last reconciled with the underlying store.
@@ -126,6 +233,13 @@ export declare class BaseMindooDB implements MindooDB {
126
233
  */
127
234
  private warmerProgress;
128
235
  constructor(tenant: BaseMindooTenant, store: ContentAddressedStore, attachmentStore: ContentAddressedStore, attachmentConfig?: AttachmentConfig, documentCacheConfig?: DocumentCacheConfig, snapshotConfig?: SnapshotConfig, adminOnlyDb?: boolean, logger?: Logger, performanceCallback?: PerformanceCallback, timeTravelDate?: number | null);
236
+ /**
237
+ * Whether debug logging is enabled. Used to guard hot-path debug statements
238
+ * whose message interpolation is itself expensive (e.g.
239
+ * `JSON.stringify(Automerge.getHeads(...))` — a WASM call plus stringify per
240
+ * document), so bulk operations don't pay for logging that is discarded.
241
+ */
242
+ private isDebugEnabled;
129
243
  /**
130
244
  * Get the admin public key from the tenant.
131
245
  * Only used when adminOnlyDb is true.
@@ -143,6 +257,205 @@ export declare class BaseMindooDB implements MindooDB {
143
257
  * Attach a CacheManager so this DB participates in periodic cache flushing.
144
258
  */
145
259
  setCacheManager(cacheManager: CacheManager): void;
260
+ /**
261
+ * Get (lazily creating) the document summary buffer for this database.
262
+ *
263
+ * The summary is a changefeed-maintained map of queryable field values
264
+ * per document — the substrate for `query()`/`queryView()` (see
265
+ * docs/adhoc-queries.md). Passing a `config` on a later call replaces the
266
+ * configuration; if it differs from the active one, a resumable backfill
267
+ * re-extracts all documents on the next `update()` (documents are never
268
+ * rewritten).
269
+ */
270
+ getSummaryStore(config?: SummaryConfig): DocumentSummaryStore;
271
+ /**
272
+ * Read the summary configuration stored in the synced setup document
273
+ * (`dbsetup`, field `summarySetup`) — the "design document" that lets
274
+ * users/apps (e.g. the Haven UI) configure the summary fields in one
275
+ * place for all replicas. Returns `null` when no setup document or no
276
+ * configuration exists.
277
+ */
278
+ getSummarySetup(): Promise<SummaryConfig | null>;
279
+ /**
280
+ * Write the summary configuration into the synced setup document
281
+ * (creating `dbsetup` idempotently when missing; custom-ID documents
282
+ * share seeded Automerge ancestry, so concurrent creates on different
283
+ * replicas merge). Passing `null` removes the configuration (replicas
284
+ * fall back to the default auto-include config).
285
+ *
286
+ * Summary stores without an explicit code-provided configuration pick
287
+ * the change up through the changefeed and re-extract via a resumable
288
+ * backfill — locally and, after sync, on every other replica.
289
+ */
290
+ setSummarySetup(config: SummaryConfig | null): Promise<void>;
291
+ /**
292
+ * Enable/disable summary auto-follow (default: enabled). When enabled,
293
+ * the summary buffer is brought up to date in the background after every
294
+ * coalesced change event — one catch-up run per sync batch, one per
295
+ * event-loop turn for local writes — so queries don't stall on a full
296
+ * catch-up after receiving many documents. Compared to the network I/O
297
+ * of a sync the incremental extraction is cheap; disable it for
298
+ * bulk-import scenarios where even that is unwanted (the next query
299
+ * catches up lazily as before).
300
+ */
301
+ setSummaryAutoUpdateEnabled(enabled: boolean): void;
302
+ /**
303
+ * Change-event hook for summary auto-follow. While no summary store
304
+ * exists, the setup document decides whether to activate one: it is
305
+ * probed on the first event (covers reopening a database whose `dbsetup`
306
+ * synced earlier) and re-checked whenever a `dbsetup` change arrives
307
+ * (covers the configuration being created/updated locally or via sync).
308
+ */
309
+ private handleChangesForSummaryAutoUpdate;
310
+ /** Create the summary store when the setup document configures one. */
311
+ private activateSummaryFromSetupDoc;
312
+ /**
313
+ * Run a background summary catch-up, coalescing further requests into
314
+ * one follow-up run (mirrors the live-view scheduling in VirtualView).
315
+ * Errors are logged and never propagate into write/sync paths.
316
+ */
317
+ private scheduleSummaryAutoUpdate;
318
+ /**
319
+ * Get (lazily creating) the full-text index for this database.
320
+ *
321
+ * The index is a changefeed-maintained, encrypted-at-rest search index
322
+ * over extracted document text — configured via the synced setup
323
+ * document (`dbsetup`, field `fulltextSetup`) or an explicit `config`.
324
+ * Passing a `config` on a later call replaces the configuration; if it
325
+ * differs from the active one, the engine is recreated and a resumable
326
+ * backfill re-indexes all documents on the next `update()`.
327
+ *
328
+ * Note that indexing is OPT-IN: without `enabled: true` (in the setup
329
+ * document or the explicit config) the index stays empty and
330
+ * {@link searchText} throws.
331
+ */
332
+ getFullTextIndex(config?: FulltextConfig): DocumentFullTextIndex;
333
+ /**
334
+ * Read the full-text configuration stored in the synced setup document
335
+ * (`dbsetup`, field `fulltextSetup`). Returns `null` when no setup
336
+ * document or no configuration exists.
337
+ */
338
+ getFulltextSetup(): Promise<FulltextConfig | null>;
339
+ /**
340
+ * Write the full-text configuration into the synced setup document
341
+ * (creating `dbsetup` idempotently when missing). Passing `null`
342
+ * removes the configuration (indexing falls back to disabled).
343
+ *
344
+ * Idempotent: when the sanitized config equals what is already stored,
345
+ * no change is written — apps can safely call this on every start
346
+ * without producing changefeed/sync churn.
347
+ *
348
+ * Full-text indexes without an explicit code-provided configuration
349
+ * pick the change up through the changefeed and re-index via a
350
+ * resumable backfill — locally and, after sync, on every other replica.
351
+ */
352
+ setFulltextSetup(config: FulltextConfig | null): Promise<void>;
353
+ /**
354
+ * Read the attachment extraction configuration stored in the synced
355
+ * setup document (`dbsetup`, field `extractionSetup`). Configures
356
+ * host-side extraction services (e.g. Haven's OCR service) that persist
357
+ * results at the attachment entry via
358
+ * {@link MindooDoc.setAttachmentExtractedText}. Returns `null` when no
359
+ * setup document or no configuration exists.
360
+ */
361
+ getExtractionSetup(): Promise<ExtractionConfig | null>;
362
+ /**
363
+ * Write the attachment extraction configuration into the synced setup
364
+ * document (creating `dbsetup` idempotently when missing). Passing
365
+ * `null` removes the configuration (extraction services stay idle).
366
+ *
367
+ * Idempotent: when the sanitized config equals what is already stored,
368
+ * no change is written — services can safely call this on every start
369
+ * without producing changefeed/sync churn.
370
+ */
371
+ setExtractionSetup(config: ExtractionConfig | null): Promise<void>;
372
+ /**
373
+ * Register an attachment text extractor for full-text indexing (see
374
+ * {@link AttachmentTextExtractor}). Host environments call this when
375
+ * opening the database (e.g. Haven registers text/PDF/Office extractors
376
+ * from its preview parsers). Extraction only happens for databases
377
+ * whose `fulltextSetup` has `attachments: true`.
378
+ *
379
+ * @returns An unregister function.
380
+ */
381
+ registerAttachmentTextExtractor(extractor: AttachmentTextExtractor): () => void;
382
+ /**
383
+ * Full-text search over the document full-text index (see
384
+ * docs/fulltext-search.md). Brings the index up to date first, then
385
+ * returns matching documents best-score-first. Results are
386
+ * device-specific under E2EE: documents whose decryption keys are
387
+ * missing from the local KeyBag are not indexed and cannot match.
388
+ *
389
+ * @throws Error when full-text indexing is not enabled for this
390
+ * database (see {@link setFulltextSetup} / {@link getFullTextIndex}).
391
+ */
392
+ searchText(query: string, options?: FulltextSearchOptions): Promise<FulltextSearchResult>;
393
+ /**
394
+ * Enable/disable full-text auto-follow (default: enabled). Mirrors
395
+ * {@link setSummaryAutoUpdateEnabled}: when enabled, an ACTIVE full-text
396
+ * index catches up in the background after every coalesced change
397
+ * event, so the first search after a large sync doesn't stall.
398
+ * Databases without an enabled `fulltextSetup` never pay any cost.
399
+ */
400
+ setFulltextAutoUpdateEnabled(enabled: boolean): void;
401
+ /**
402
+ * Change-event hook for full-text auto-follow. While no index exists,
403
+ * the setup document decides whether to activate one — probed on the
404
+ * first event and re-checked whenever a `dbsetup` change arrives
405
+ * (mirrors {@link handleChangesForSummaryAutoUpdate}).
406
+ */
407
+ private handleChangesForFulltextAutoUpdate;
408
+ /** Create the full-text index when the setup document enables one. */
409
+ private activateFulltextFromSetupDoc;
410
+ /**
411
+ * Run a background full-text catch-up, coalescing further requests into
412
+ * one follow-up run (mirrors {@link scheduleSummaryAutoUpdate}).
413
+ */
414
+ private scheduleFulltextAutoUpdate;
415
+ /**
416
+ * Register a listener notified after documents change (local writes,
417
+ * sync ingest, access flips, witness updates). Events are coalesced:
418
+ * one event per sync batch, one per event-loop turn for local writes.
419
+ * The event carries only lightweight metadata plus the latest change
420
+ * cursor — no replay guarantee; consumers needing completeness read
421
+ * {@link iterateChangesSince} from their own cursor.
422
+ *
423
+ * @returns An unsubscribe function.
424
+ */
425
+ addChangeListener(listener: DbChangeListener): () => void;
426
+ /** Record a document transition for the coalesced change event. */
427
+ private noteChangeForListeners;
428
+ private scheduleChangeNotification;
429
+ /**
430
+ * Suppress timer-based change emission for the duration of a batch
431
+ * operation (sync ingest); the release emits one coalesced event.
432
+ */
433
+ private beginChangeNotificationHold;
434
+ private endChangeNotificationHold;
435
+ private emitPendingChangeEvent;
436
+ /**
437
+ * Run an ad-hoc query against the document summary buffer (see
438
+ * docs/adhoc-queries.md). Filters and expression sort keys use the
439
+ * MindooDB expression language; documents are never materialized unless
440
+ * `options.allowFullScan` is set.
441
+ */
442
+ query(query: MindooQuery, options?: MindooQueryOptions): Promise<MindooQueryResult>;
443
+ /**
444
+ * Build an ephemeral, summary-backed VirtualView (categories, sorting,
445
+ * totals as usual — but fed from the summary buffer, so no documents are
446
+ * materialized and re-sorting via `resort()` is a pure in-memory
447
+ * operation). The view is not cached; call `dispose()` when done.
448
+ */
449
+ queryView(definition: MindooQueryViewDefinition, options?: VirtualViewUpdateOptions): Promise<EphemeralSummaryView>;
450
+ /**
451
+ * Live query: delivers the initial result asynchronously, then keeps
452
+ * re-evaluating after coalesced change events. `onResult` only fires
453
+ * when the result fingerprint (docIds + lastModified of the matches)
454
+ * actually changed.
455
+ */
456
+ queryLive(query: MindooQuery, onResult: (result: MindooQueryResult) => void, options?: MindooQueryOptions & {
457
+ onError?: (error: unknown) => void;
458
+ }): MindooQuerySubscription;
146
459
  getCachePrefix(): string;
147
460
  hasDirtyState(): boolean;
148
461
  clearDirty(): void;
@@ -219,10 +532,42 @@ export declare class BaseMindooDB implements MindooDB {
219
532
  */
220
533
  private getOrImportPublicKey;
221
534
  /**
222
- * Verify a signature using a pre-imported CryptoKey.
223
- * This bypasses the key import step for better performance when keys are cached.
535
+ * Compute the author's metadata-binding signature for a new entry (audit
536
+ * finding #5). The signature covers the canonical, versioned, length-prefixed
537
+ * metadata layout (see crypto/EntrySignature.ts) rather than only the
538
+ * ciphertext, so the cleartext metadata cannot be tampered with after signing.
539
+ * Uses the supplied custom signing key when present, otherwise the current
540
+ * user's signing key.
541
+ */
542
+ private computeEntryMetadataSignature;
543
+ /**
544
+ * Collect the full set of attachment references a document holds right now,
545
+ * for the signed {@link StoreEntryMetadata.attachmentRefs} snapshot.
546
+ *
547
+ * Refs are sorted by `attachmentId` to give a canonical, deterministic order
548
+ * so the bytes signed by the writer match the bytes a verifier reconstructs
549
+ * (see crypto/EntrySignature.ts). Reads the merged `_attachments` array, so
550
+ * additions, removals, and appends are all reflected.
551
+ */
552
+ private collectAttachmentRefs;
553
+ /**
554
+ * Verify a store entry's author signature using a pre-imported CryptoKey,
555
+ * version-aware (audit finding #5): prefers the metadata-binding
556
+ * `metadataSignature` when present, otherwise the legacy ciphertext signature,
557
+ * and re-verifies `SHA-256(encryptedData) === contentHash`. Returns false on
558
+ * any mismatch. The caller is responsible for the directory trust check.
224
559
  */
225
- private verifySignatureWithKey;
560
+ private verifyEntrySignatureWithKey;
561
+ /**
562
+ * Whether the tenant storage-format floor (`requireMetadataSignatureSince`)
563
+ * requires `entry` to carry the v2 metadata-binding signature, based on its
564
+ * trusted time. The `directory` store is exempt (it must always load so the
565
+ * policy that defines the floor can be read); entries that already carry a
566
+ * `metadataSignature` short-circuit. Fail-open on resolution errors is safe —
567
+ * the legacy signature is still cryptographically verified; the floor only
568
+ * refuses the weaker fallback for new entries.
569
+ */
570
+ private requiresMetadataSignature;
226
571
  /**
227
572
  * Compare two index entries for sorting.
228
573
  * Returns negative if a < b, positive if a > b, 0 if equal.
@@ -251,11 +596,22 @@ export declare class BaseMindooDB implements MindooDB {
251
596
  * tombstones produced by the key visibility layer
252
597
  */
253
598
  private updateIndex;
599
+ /**
600
+ * Resolve a document's position in the sorted {@link index} through the
601
+ * lookup map, repairing lazily-deferred staleness (see
602
+ * {@link indexLookupStaleFrom}) only when the cached position no longer
603
+ * matches. All `indexLookup.get` reads must go through this accessor.
604
+ */
605
+ private getDocIndexPosition;
606
+ /** Rewrite the stale tail of {@link indexLookup} recorded by {@link updateIndex}. */
607
+ private flushIndexLookupPatch;
254
608
  /**
255
609
  * Register an automerge hash -> entry ID mapping for a document.
256
610
  * This is used to resolve Automerge dependency hashes to entry IDs.
257
611
  */
258
612
  private registerAutomergeHashMapping;
613
+ private registerAutomergeHashMappingIfAbsent;
614
+ private registerSnapshotHeadHashMappings;
259
615
  /**
260
616
  * Get the entry ID for an automerge hash within a document.
261
617
  * Returns null if not found.
@@ -294,6 +650,16 @@ export declare class BaseMindooDB implements MindooDB {
294
650
  * then processes only the delta. Falls back to full rebuild on cache miss.
295
651
  */
296
652
  initialize(): Promise<void>;
653
+ /**
654
+ * Open-time probe for full-text auto-activation. Without it, a
655
+ * database whose synced `fulltextSetup` is already enabled would not
656
+ * build its index until the first change event arrives or the first
657
+ * search runs. Fired once (fire-and-forget) at the end of
658
+ * {@link initialize}; uses the same system-database exclusions and
659
+ * activation path as the change-event probe (see
660
+ * {@link handleChangesForFulltextAutoUpdate}).
661
+ */
662
+ private probeFulltextSetupAtOpen;
297
663
  /**
298
664
  * Compute the current tenant KeyBag fingerprint, or `null` when the
299
665
  * tenant does not expose one (older `MindooTenant` implementations).
@@ -384,6 +750,7 @@ export declare class BaseMindooDB implements MindooDB {
384
750
  * the workload is about to benefit from it.
385
751
  */
386
752
  syncStoreChanges(): Promise<void>;
753
+ private syncStoreChangesInternal;
387
754
  private supportsCursorScan;
388
755
  private scanAllMetadata;
389
756
  private getNewEntryMetadataForSync;
@@ -463,6 +830,33 @@ export declare class BaseMindooDB implements MindooDB {
463
830
  * @deprecated Use `createDocument({ signingKeyPair, signingKeyPassword, decryptionKeyId })` instead.
464
831
  */
465
832
  createDocumentWithSigningKey(signingKeyPair: SigningKeyPair, signingKeyPassword: string, decryptionKeyId?: string): Promise<MindooDoc>;
833
+ /**
834
+ * Bulk-create documents in a single append-only store write.
835
+ *
836
+ * Semantically equivalent to calling {@link createDocument} once per input,
837
+ * with these bulk-oriented differences:
838
+ * - All produced store entries are written through ONE `putEntries()` call,
839
+ * so IndexedDB-backed stores commit the whole batch in a single readwrite
840
+ * transaction instead of one per document.
841
+ * - Custom-id documents MAY combine `id` with `initialValues`: the values are
842
+ * applied as a separate `doc_change` entry on top of the deterministic
843
+ * seed change, and both entries land in the same batch. (The single-create
844
+ * path rejects this combination and requires a follow-up `changeDoc()`.)
845
+ * - Freshly created documents are cached but intentionally NOT added to the
846
+ * dirty-doc tracking: their entries are already durable in the store, so
847
+ * an L1 eviction can always re-materialize them. This avoids the per-doc
848
+ * flush-before-evict L2 write storm during large imports.
849
+ * - Snapshot scheduling is skipped (fresh documents cannot exceed the
850
+ * snapshot threshold).
851
+ *
852
+ * Existing custom-id documents keep the idempotent single-create semantics:
853
+ * the existing document is returned (tombstones are undeleted first) and any
854
+ * `initialValues` are applied as a follow-up change.
855
+ *
856
+ * Fail-fast: invalid inputs are rejected up front, and a denied ACL
857
+ * precheck rejects the whole call before any fresh document is written.
858
+ */
859
+ createDocuments(inputs: CreateOptions[]): Promise<MindooDoc[]>;
466
860
  /**
467
861
  * Internal method to create a new document.
468
862
  *
@@ -477,9 +871,105 @@ export declare class BaseMindooDB implements MindooDB {
477
871
  * custom ID converge when synced (see `getCustomIdInitialChangeBytes`).
478
872
  */
479
873
  private createDocumentInternal;
874
+ /**
875
+ * Build the store entries and in-memory state for one fresh document of a
876
+ * {@link createDocuments} batch WITHOUT writing anything. The caller is
877
+ * responsible for persisting the returned entries (batched `putEntries`)
878
+ * and for cache/index registration afterwards.
879
+ *
880
+ * Mirrors {@link createDocumentInternal} for the fresh-document case, with
881
+ * one bulk-only extension: a custom-id document MAY carry `initialValues`,
882
+ * which are emitted as an extra `doc_change` entry on top of the
883
+ * deterministic seed change so both land in the same store batch.
884
+ */
885
+ private prepareFreshDocumentCreate;
480
886
  getDocument(docId: string): Promise<MindooDoc>;
481
887
  getDocumentAtTimestamp(docId: string, timestamp: number): Promise<MindooDoc | null>;
482
888
  iterateDocumentHistory(docId: string): AsyncGenerator<DocumentHistoryResult, void, unknown>;
889
+ iterateChangeRevisionsSince(cursor: RevisionCursor | null): AsyncGenerator<ChangeRevisionResult, void, unknown>;
890
+ iterateDocRevisionsSince(docId: string, cursor: RevisionCursor | null): AsyncGenerator<ChangeRevisionResult, void, unknown>;
891
+ /**
892
+ * Shared implementation of the revision-grain changefeed
893
+ * ({@link iterateChangeRevisionsSince} / {@link iterateDocRevisionsSince}).
894
+ *
895
+ * Two distinct orderings drive the feed (docs/accesscontrol.md §8):
896
+ *
897
+ * - **Discovery (receiptOrder).** New entries are discovered via the store's
898
+ * gap-free `scanEntriesSince(cursor)` scan in `(receiptOrder, id)` order, so
899
+ * an incremental advance reads only entries appended since the cursor and
900
+ * never re-scans cold documents. The resumable {@link RevisionCursor} is this
901
+ * scan position, parked just before the earliest un-witnessed entry so the
902
+ * provisional head overlay is re-evaluated on every resume.
903
+ * - **Materialization (trusted time).** Each affected document's changes are
904
+ * folded in trusted-time order, so every yielded revision carries the
905
+ * document's *trusted-time-bounded merge* — the merge of all of the doc's
906
+ * changes with `trustedTime <= this revision's trustedTime`. This is correct
907
+ * at the head and at every intermediate node, and concurrent same-base
908
+ * changes merge from the larger-trusted-time instant onward.
909
+ *
910
+ * Trusted-time rule: witnessed entries use their witness `receivedAt`;
911
+ * un-witnessed local entries use the current wall clock, so they always sit at
912
+ * the provisional head and never appear in past-time reads until witnessed.
913
+ *
914
+ * An in-memory per-doc LRU ({@link revisionFeedDocCache}) lets the common
915
+ * in-order advance seed from cached state and decrypt only the new suffix; a
916
+ * cache miss reconstructs the seed from the best snapshot whose coverage is
917
+ * within the fold prefix via {@link computeDocumentMaterializationPlan}.
918
+ */
919
+ private iterateRevisionsInternal;
920
+ /**
921
+ * Discovery phase of {@link iterateRevisionsInternal}: walk the store in
922
+ * `(receiptOrder, id)` order from `cursor`, collecting the newly-appended
923
+ * replay entries and computing the resume cursor.
924
+ *
925
+ * The resume cursor is the witnessed stable-prefix watermark: it advances over
926
+ * leading witnessed entries but stops just before the first un-witnessed entry,
927
+ * so un-witnessed entries (whose trusted time is provisional `now`) are
928
+ * re-discovered and re-evaluated as a head overlay on the next resume.
929
+ */
930
+ private discoverRevisionEntries;
931
+ /** Compare two entries by `(receiptOrder, id)` ascending. */
932
+ private compareReceiptOrder;
933
+ /** True when `em` is strictly after `cursor` in `(receiptOrder, id)` order. */
934
+ private isAfterReceiptCursor;
935
+ /**
936
+ * Materialization phase for a single affected document: fold its changes in
937
+ * trusted-time order and yield one revision per change from the earliest
938
+ * newly-discovered (or superseded) position onward, each carrying the
939
+ * trusted-time-bounded merged document state.
940
+ */
941
+ private foldDocRevisions;
942
+ /**
943
+ * Reconstruct the merged state of a document covering exactly the replay
944
+ * entries in `prefix` (the unchanged head of a trusted-time fold).
945
+ *
946
+ * Fast path: if the LRU holds a merged doc whose coverage is a subset of the
947
+ * prefix, clone it and apply only the missing entries. Otherwise reconstruct
948
+ * from the best snapshot whose coverage is fully within the prefix (so the
949
+ * snapshot can never pull in changes beyond the fold point) plus the uncovered
950
+ * prefix tail, via {@link computeDocumentMaterializationPlan}.
951
+ */
952
+ private seedRevisionFold;
953
+ /** True when every id in `sub` is contained in `sup`. */
954
+ private isIdSubset;
955
+ /**
956
+ * True when all of a snapshot's coverage roots are within `idSet`, i.e. the
957
+ * snapshot represents a state reachable from entries inside the set (safe to
958
+ * use as a seed without pulling in later changes).
959
+ */
960
+ private snapshotRootsWithin;
961
+ /** Load, verify, and decrypt a snapshot into an Automerge doc, or `null`. */
962
+ private loadSnapshotForFold;
963
+ /**
964
+ * Load, verify, decrypt, and apply a set of replay change entries onto `doc`.
965
+ * `Automerge.applyChanges` buffers changes whose causal dependencies are not
966
+ * yet present, so the entries need not be supplied in dependency order.
967
+ */
968
+ private applyChangeEntries;
969
+ /** Touch the revision-feed LRU, moving `docId` to most-recently-used. */
970
+ private getRevisionFeedCache;
971
+ /** Insert/update the revision-feed LRU, evicting the least-recently-used. */
972
+ private putRevisionFeedCache;
483
973
  getDocumentHistoryPage(docId: string, options?: DocumentHistoryPageOptions): Promise<DocumentHistoryPageResult>;
484
974
  analyzeDocumentDagAtTimestamp(docId: string, timestamp: DocumentDagAnalysisTimestamp): Promise<DocumentDagAnalysisResult>;
485
975
  /**
@@ -785,6 +1275,21 @@ export declare class BaseMindooDB implements MindooDB {
785
1275
  getDeletedDocumentIds(): Promise<string[]>;
786
1276
  getAllDocumentIdsAtTimestamp(timestamp: number): Promise<string[]>;
787
1277
  deleteDocument(docId: string, options?: DeleteOptions): Promise<void>;
1278
+ /**
1279
+ * Bulk-delete documents in a single append-only store write.
1280
+ *
1281
+ * Semantically equivalent to calling {@link deleteDocument} once per id, but
1282
+ * all `doc_delete` lifecycle entries are written through ONE `putEntries()`
1283
+ * call (a single readwrite transaction on IndexedDB-backed stores), and the
1284
+ * deleted documents are dropped from the L1 cache instead of being
1285
+ * dirty-tracked (the entries are already durable, so no L2 flush is needed).
1286
+ *
1287
+ * Documents that are missing or already deleted are skipped (idempotent
1288
+ * bulk semantics: a re-run of a destructive import must not fail because a
1289
+ * previous run already removed some documents). Any other failure, including
1290
+ * a denied ACL precheck, rejects the whole call before anything is written.
1291
+ */
1292
+ deleteDocuments(docIds: string[], options?: DeleteOptions): Promise<void>;
788
1293
  deleteDocumentWithSigningKey(docId: string, signingKeyPair: SigningKeyPair, signingKeyPassword: string): Promise<void>;
789
1294
  undeleteDocument(docId: string, options?: UndeleteOptions): Promise<void>;
790
1295
  private assertLifecycleMutationAllowed;
@@ -796,6 +1301,24 @@ export declare class BaseMindooDB implements MindooDB {
796
1301
  * StoreEntry type, signs/encrypts it, and updates local caches/indexes.
797
1302
  */
798
1303
  private writeLifecycleEntry;
1304
+ /**
1305
+ * Build (but do not persist) a delete/undelete lifecycle entry for an
1306
+ * existing document, including the ACL precheck. Callers persist the
1307
+ * returned `fullEntry` (single or batched `putEntries`) and then call
1308
+ * {@link applyLifecycleEntryLocally} to update caches and indexes.
1309
+ */
1310
+ private prepareLifecycleEntry;
1311
+ /**
1312
+ * Apply a persisted lifecycle entry (see {@link prepareLifecycleEntry}) to
1313
+ * the in-memory document, cache, and changefeed index. Must be called after
1314
+ * the entry was written to the store.
1315
+ *
1316
+ * With `markDirty: false` (bulk path) the document is dropped from the L1
1317
+ * cache instead of being dirty-tracked: the lifecycle entry is already
1318
+ * durable in the append-only store, so skipping the L2 flush avoids the
1319
+ * per-document flush-before-evict write storm during large batches.
1320
+ */
1321
+ private applyLifecycleEntryLocally;
799
1322
  /**
800
1323
  * Internal method to delete a document.
801
1324
  * Handles both regular deletion (signed by current user) and
@@ -807,20 +1330,30 @@ export declare class BaseMindooDB implements MindooDB {
807
1330
  changeDocWithSigningKey(doc: MindooDoc, changeFunc: (doc: MindooDoc) => void | Promise<void>, signingKeyPair: SigningKeyPair, signingKeyPassword: string): Promise<void>;
808
1331
  applyTextPatch(doc: MindooDoc, patch: MindooTextPatch): Promise<MindooTextPatchResult>;
809
1332
  applyRichTextPatch(doc: MindooDoc, patch: MindooRichTextPatch): Promise<MindooRichTextPatchResult>;
1333
+ applyRichTextStepsPatch(doc: MindooDoc, patch: MindooRichTextStepPatch): Promise<MindooRichTextPatchResult>;
810
1334
  getRichTextSnapshot(doc: MindooDoc, path: Array<string | number>): Promise<MindooRichTextSnapshot>;
1335
+ exportAutomergeSnapshot(doc: MindooDoc): Promise<MindooAutomergeSnapshot>;
1336
+ applyAutomergeChanges(doc: MindooDoc, patch: MindooAutomergeChangesPatch): Promise<MindooAutomergePatchResult>;
1337
+ private resolveReadableInternalDoc;
811
1338
  applyJsonPatch(doc: MindooDoc, patch: MindooJsonPatch): Promise<MindooJsonPatchResult>;
812
1339
  private changeDocInternal;
813
1340
  private validateTextPatch;
814
1341
  private validateJsonPatch;
815
1342
  private validateRichTextPatch;
1343
+ private validateRichTextSpans;
1344
+ private validateRichTextStepPatch;
816
1345
  private validateJsonPath;
817
1346
  private reviveRichTextSpans;
818
1347
  private reviveRichTextValue;
819
1348
  private dehydrateRichTextSpans;
820
1349
  private dehydrateRichTextValue;
821
1350
  private applyJsonPatchOperations;
1351
+ private spliceJsonTextAtPath;
1352
+ private unmarkJsonTextAtPath;
1353
+ private clampIndex;
822
1354
  private setJsonValueAtPath;
823
1355
  private unsetJsonValueAtPath;
1356
+ private readValueAtPath;
824
1357
  private readJsonListAtPath;
825
1358
  /**
826
1359
  * Like {@link readJsonListAtPath} but creates the array (and any missing
@@ -839,8 +1372,31 @@ export declare class BaseMindooDB implements MindooDB {
839
1372
  private ensureJsonParentAtPath;
840
1373
  private readJsonParentAtPath;
841
1374
  private ensureTextPath;
1375
+ /**
1376
+ * Run an Automerge change operation against `internalDoc.doc`, recovering
1377
+ * from the "outdated document" error by cloning the cached doc and
1378
+ * retrying once.
1379
+ *
1380
+ * Automerge marks a document as outdated whenever the JS reference has
1381
+ * already been passed to `Automerge.change` / `Automerge.applyChanges` /
1382
+ * `Automerge.changeAt` (the WASM handle's `state.heads` is set to a
1383
+ * non-null value, putting the doc into "view" mode). The mindoodb cache
1384
+ * normally avoids this by reassigning `internalDoc.doc = newDoc` after
1385
+ * every change, but a stale reference (left over from an aborted or
1386
+ * out-of-band Automerge operation) can still leak in. When that happens
1387
+ * the doc is still semantically up to date - it just can't be mutated -
1388
+ * and `Automerge.clone(...)` produces a fresh, writable copy at the same
1389
+ * heads. The same workaround already lives in
1390
+ * {@link applyNewEntriesToCachedDocument} (line ~6606) for the sync
1391
+ * pipeline; this helper centralizes it for the patch / changeDoc paths.
1392
+ */
1393
+ private runChangeWithOutdatedDocRecovery;
1394
+ private isOutdatedDocumentError;
1395
+ private isRichTextUpdateSpansBoundsError;
842
1396
  private ensureRichTextPath;
843
1397
  private persistDocumentChange;
1398
+ private persistAutomergeDocumentChanges;
1399
+ private buildDocChangeStoreEntry;
844
1400
  /**
845
1401
  * Best-effort snapshot scheduling and writing.
846
1402
  * A snapshot is written only when enough replay history has accumulated and
@@ -897,6 +1453,12 @@ export declare class BaseMindooDB implements MindooDB {
897
1453
  private materializeDocumentFromPlan;
898
1454
  iterateChangeMetadataSince(cursor: ProcessChangesCursor | null): AsyncGenerator<ProcessChangeSummaryResult, void, unknown>;
899
1455
  getLatestChangeCursor(): ProcessChangesCursor | null;
1456
+ /**
1457
+ * Count the changefeed entries after the given cursor without iterating
1458
+ * them. O(log n) binary search on the internal `(changeSeq, docId)` index —
1459
+ * used for progress reporting around {@link iterateChangesSince}.
1460
+ */
1461
+ countChangesSince(cursor: ProcessChangesCursor | null): number;
900
1462
  iterateChangesSince(cursor: ProcessChangesCursor | null): AsyncGenerator<ProcessChangesResult, void, unknown>;
901
1463
  /**
902
1464
  * Incrementally update a cached document with new entries.
@@ -994,6 +1556,116 @@ export declare class BaseMindooDB implements MindooDB {
994
1556
  * plus once at the end of the pass with the terminal phase.
995
1557
  */
996
1558
  private runBackgroundWarmer;
1559
+ /**
1560
+ * The per-tenant quarantine/audit log: entries rejected during
1561
+ * materialization by the access-control layer (docs/accesscontrol.md §10).
1562
+ * Exposed for audit views (e.g. Haven). Entries remain in the append-only
1563
+ * store but are excluded from materialized state and queries.
1564
+ */
1565
+ getQuarantineLog(): readonly QuarantineRecord[];
1566
+ /**
1567
+ * Whether access control is active for this tenant and should gate
1568
+ * materialization. Admin-only databases (incl. the directory itself) are
1569
+ * always exempt — admin is the root of trust, and exempting the directory DB
1570
+ * also avoids re-entrancy. Cached briefly to keep the load fast-path cheap.
1571
+ * Fails closed-to-disabled on any directory error so document loads never
1572
+ * break due to a transient directory issue (Tier 2 only gates honest clients).
1573
+ */
1574
+ private isAclEnforced;
1575
+ /**
1576
+ * Synchronous client-side write-policy precheck (docs/accesscontrol.md §9).
1577
+ * Evaluates the full Tier 1 + Tier 2 ruleset for the candidate write and
1578
+ * throws {@link AccessDeniedError} when it is denied, so applications get
1579
+ * immediate, meaningful feedback at the call site instead of an optimistic
1580
+ * local write that is later rejected by the server witness or quarantined on
1581
+ * materialization.
1582
+ *
1583
+ * Fails CLOSED on any directory/infra error while access control is enforced
1584
+ * (audit finding #2): the precheck denies the write rather than letting it
1585
+ * through optimistically. The server witness (Tier 1) and
1586
+ * quarantine-on-materialization (Tier 2) remain the authoritative enforcers,
1587
+ * and the user can retry once the directory is reachable again.
1588
+ *
1589
+ * `getBeforeDoc`/`getAfterDoc` are lazy so the (potentially costly) Automerge
1590
+ * -> JS materialization is skipped entirely when the active policy has no
1591
+ * Tier 2 (`withfields`) content rule for this operation/database.
1592
+ */
1593
+ private assertWriteAllowed;
1594
+ /**
1595
+ * Resolve the `decryptionKeyId` for a `doc_create`: the caller's explicit key
1596
+ * when given, else the policy-configured default for this database (see
1597
+ * `getEffectiveDefaultCreateKeyId` on the directory), else the legacy
1598
+ * `"default"`. The policy default is a create-time convenience only; read/write
1599
+ * access is governed by key possession (distribution + rotation, §13), not the
1600
+ * server. Directory ACL writes always pass an explicit key, so this never
1601
+ * re-enters the directory for them.
1602
+ */
1603
+ private resolveCreateKeyId;
1604
+ /**
1605
+ * Evaluate the full client-side (Tier 1 + Tier 2) write ruleset for a
1606
+ * candidate write, returning the {@link AccessDecision}. Returns `null` only
1607
+ * when access control is not enforced for this database (callers treat `null`
1608
+ * as "allowed"). When access control IS enforced but the directory cannot be
1609
+ * consulted, it returns a DENY decision (fail closed, audit finding #2). The
1610
+ * `getBeforeDoc`/`getAfterDoc` materializers are only invoked when the active
1611
+ * policy has a Tier 2 (`withfields`) content rule for this op/db.
1612
+ */
1613
+ private evaluateClientWriteAccess;
1614
+ /** The "access control not enforced" allow decision returned by the
1615
+ * non-throwing `canCreate`/`canChange`/`canDelete` prediction helpers. */
1616
+ private static readonly ACL_NOT_ENFORCED_DECISION;
1617
+ /**
1618
+ * Predict whether a `createDocument` would be allowed by the active write
1619
+ * policy, without writing anything (docs/accesscontrol.md §9). Lets a UI
1620
+ * disable a Save action and surface `decision.reason` up front. The returned
1621
+ * decision mirrors what {@link createDocument} would enforce.
1622
+ */
1623
+ canCreate(options?: CreateOptions): Promise<AccessDecision>;
1624
+ /**
1625
+ * Predict whether applying `candidateAfter` as the document's next state via
1626
+ * {@link changeDoc} would be allowed by the active write policy, without
1627
+ * writing anything. `candidateAfter` is the intended full "after" document
1628
+ * (e.g. the edited JSON in a database-browser editor).
1629
+ */
1630
+ canChange(doc: MindooDoc, candidateAfter: Record<string, unknown>, signingKeyPair?: SigningKeyPair): Promise<AccessDecision>;
1631
+ /**
1632
+ * Predict whether deleting `doc` via {@link deleteDocument} would be allowed
1633
+ * by the active write policy, without writing anything.
1634
+ */
1635
+ canDelete(doc: MindooDoc, signingKeyPair?: SigningKeyPair): Promise<AccessDecision>;
1636
+ /**
1637
+ * Predict whether undeleting `doc` via {@link undeleteDocument} would be
1638
+ * allowed by the active write policy, without writing anything.
1639
+ */
1640
+ canUndelete(doc: MindooDoc, signingKeyPair?: SigningKeyPair): Promise<AccessDecision>;
1641
+ /**
1642
+ * Resolve the signing public key of the document's original creator (the
1643
+ * `doc_create` entry's `createdByPublicKey`), used to set `$author`
1644
+ * (`isAuthor`) for the client write prechecks on change/delete/undelete.
1645
+ * Cached per document; returns `null` if the create entry isn't present yet
1646
+ * (in which case `isAuthor` is treated as false, matching materialization).
1647
+ */
1648
+ private resolveCreatorSigningKey;
1649
+ /** Append a record to the quarantine/audit log (and log it). */
1650
+ private recordQuarantine;
1651
+ /**
1652
+ * Materialize a document through the access-control (Tier 2) path
1653
+ * (docs/accesscontrol.md §10). Entries are evaluated deterministically in
1654
+ * trusted-time order; an entry is quarantined if it violates a rule, fails
1655
+ * op-type re-derivation, or causally depends on a quarantined entry
1656
+ * (cascade). The accepted set is therefore a causally-closed prefix identical
1657
+ * across replicas, which is what makes "quarantine on receipt" safe under
1658
+ * eventual consistency.
1659
+ *
1660
+ * Snapshots are intentionally bypassed here and the document is rebuilt from
1661
+ * individually-verified lifecycle entries (the spec's fallback), so a snapshot
1662
+ * can never smuggle content past Tier 2.
1663
+ *
1664
+ * @returns the materialized {@link InternalDoc} (or `null` if nothing is
1665
+ * accepted / the document is absent), or `undefined` when access control is
1666
+ * not enforced (caller uses the optimized fast path).
1667
+ */
1668
+ private maybeMaterializeWithAccessControl;
997
1669
  /**
998
1670
  * Internal method to load a document from the content-addressed store
999
1671
  */
@@ -1010,6 +1682,27 @@ export declare class BaseMindooDB implements MindooDB {
1010
1682
  * This is the read-only wrapper - write methods throw errors.
1011
1683
  */
1012
1684
  private wrapDocument;
1685
+ /**
1686
+ * Build a lightweight read-only tombstone for a now-inaccessible index entry
1687
+ * (docs/accesscontrol.md §13): a document that was readable before but whose
1688
+ * decryption key the current KeyBag no longer holds (e.g. a revoked key).
1689
+ * Emitted by {@link iterateChangesSince} so incremental consumers get a
1690
+ * removal signal. Per the design rule it reports `isDeleted() === true`,
1691
+ * `isAccessible() === false`, `getData() === {}` (the plaintext is purged,
1692
+ * never materialized) and `getHeads() === []` — backed by an empty Automerge
1693
+ * document so it never touches the underlying ciphertext or the document cache.
1694
+ */
1695
+ private buildInaccessibleDoc;
1696
+ /**
1697
+ * Build a lightweight read-only tombstone for a deleted document, emitted
1698
+ * by {@link iterateChangesSince} instead of materializing the deleted
1699
+ * body. Reports `isDeleted() === true`, `isAccessible() === true` and
1700
+ * `getData() === {}` — the counterpart to {@link buildInaccessibleDoc} for
1701
+ * genuine deletions (distinguish the two via `isAccessible()`). Consumers
1702
+ * that need the last state of a deleted document can use
1703
+ * {@link iterateDocumentHistory} or {@link getDocumentAtTimestamp}.
1704
+ */
1705
+ private buildDeletedDoc;
1013
1706
  /**
1014
1707
  * Get an attachment reference by ID from a document's _attachments array.
1015
1708
  */