@enbox/dwn-sdk-js 0.0.6 → 0.0.8

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 (527) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +762 -911
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/abstract-message.js +4 -0
  6. package/dist/esm/src/core/abstract-message.js.map +1 -1
  7. package/dist/esm/src/core/auth.js +22 -33
  8. package/dist/esm/src/core/auth.js.map +1 -1
  9. package/dist/esm/src/core/constants.js +11 -0
  10. package/dist/esm/src/core/constants.js.map +1 -0
  11. package/dist/esm/src/core/core-protocol.js +44 -0
  12. package/dist/esm/src/core/core-protocol.js.map +1 -0
  13. package/dist/esm/src/core/dwn-constant.js +7 -7
  14. package/dist/esm/src/core/dwn-constant.js.map +1 -1
  15. package/dist/esm/src/core/dwn-error.js +10 -12
  16. package/dist/esm/src/core/dwn-error.js.map +1 -1
  17. package/dist/esm/src/core/grant-authorization.js +50 -52
  18. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  19. package/dist/esm/src/core/message.js +85 -116
  20. package/dist/esm/src/core/message.js.map +1 -1
  21. package/dist/esm/src/core/messages-grant-authorization.js +63 -78
  22. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  23. package/dist/esm/src/core/protocol-authorization-action.js +266 -0
  24. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
  25. package/dist/esm/src/core/protocol-authorization-validation.js +321 -0
  26. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
  27. package/dist/esm/src/core/protocol-authorization.js +144 -741
  28. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  29. package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
  30. package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
  31. package/dist/esm/src/core/record-chain.js +64 -0
  32. package/dist/esm/src/core/record-chain.js.map +1 -0
  33. package/dist/esm/src/core/records-grant-authorization.js +53 -72
  34. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  35. package/dist/esm/src/core/resumable-task-manager.js +50 -65
  36. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  37. package/dist/esm/src/core/tenant-gate.js +2 -13
  38. package/dist/esm/src/core/tenant-gate.js.map +1 -1
  39. package/dist/esm/src/dwn.js +108 -101
  40. package/dist/esm/src/dwn.js.map +1 -1
  41. package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
  42. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
  43. package/dist/esm/src/handlers/messages-read.js +67 -81
  44. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  45. package/dist/esm/src/handlers/messages-subscribe.js +51 -63
  46. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  47. package/dist/esm/src/handlers/messages-sync.js +75 -89
  48. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  49. package/dist/esm/src/handlers/protocols-configure.js +153 -163
  50. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  51. package/dist/esm/src/handlers/protocols-query.js +52 -55
  52. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  53. package/dist/esm/src/handlers/records-count.js +97 -85
  54. package/dist/esm/src/handlers/records-count.js.map +1 -1
  55. package/dist/esm/src/handlers/records-delete.js +75 -93
  56. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  57. package/dist/esm/src/handlers/records-query.js +116 -105
  58. package/dist/esm/src/handlers/records-query.js.map +1 -1
  59. package/dist/esm/src/handlers/records-read.js +130 -132
  60. package/dist/esm/src/handlers/records-read.js.map +1 -1
  61. package/dist/esm/src/handlers/records-subscribe.js +164 -104
  62. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  63. package/dist/esm/src/handlers/records-write.js +213 -280
  64. package/dist/esm/src/handlers/records-write.js.map +1 -1
  65. package/dist/esm/src/index.js +5 -2
  66. package/dist/esm/src/index.js.map +1 -1
  67. package/dist/esm/src/interfaces/messages-read.js +24 -32
  68. package/dist/esm/src/interfaces/messages-read.js.map +1 -1
  69. package/dist/esm/src/interfaces/messages-subscribe.js +28 -41
  70. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  71. package/dist/esm/src/interfaces/messages-sync.js +26 -40
  72. package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
  73. package/dist/esm/src/interfaces/protocols-configure.js +87 -65
  74. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  75. package/dist/esm/src/interfaces/protocols-query.js +55 -68
  76. package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
  77. package/dist/esm/src/interfaces/records-count.js +50 -66
  78. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  79. package/dist/esm/src/interfaces/records-delete.js +45 -55
  80. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  81. package/dist/esm/src/interfaces/records-query.js +60 -76
  82. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  83. package/dist/esm/src/interfaces/records-read.js +51 -67
  84. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  85. package/dist/esm/src/interfaces/records-subscribe.js +53 -68
  86. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  87. package/dist/esm/src/interfaces/records-write-query.js +102 -0
  88. package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
  89. package/dist/esm/src/interfaces/records-write-signing.js +81 -0
  90. package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
  91. package/dist/esm/src/interfaces/records-write.js +396 -610
  92. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  93. package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
  94. package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
  95. package/dist/esm/src/jose/jws/general/builder.js +23 -35
  96. package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
  97. package/dist/esm/src/jose/jws/general/verifier.js +56 -69
  98. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  99. package/dist/esm/src/protocols/permission-grant.js +43 -14
  100. package/dist/esm/src/protocols/permission-grant.js.map +1 -1
  101. package/dist/esm/src/protocols/permission-request.js +28 -14
  102. package/dist/esm/src/protocols/permission-request.js.map +1 -1
  103. package/dist/esm/src/protocols/permissions.js +325 -227
  104. package/dist/esm/src/protocols/permissions.js.map +1 -1
  105. package/dist/esm/src/smt/smt-store-level.js +42 -64
  106. package/dist/esm/src/smt/smt-store-level.js.map +1 -1
  107. package/dist/esm/src/smt/smt-store-memory.js +19 -45
  108. package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
  109. package/dist/esm/src/smt/smt-utils.js +28 -45
  110. package/dist/esm/src/smt/smt-utils.js.map +1 -1
  111. package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
  112. package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
  113. package/dist/esm/src/state-index/state-index-level.js +113 -150
  114. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  115. package/dist/esm/src/store/blockstore-level.js +54 -156
  116. package/dist/esm/src/store/blockstore-level.js.map +1 -1
  117. package/dist/esm/src/store/blockstore-mock.js +48 -153
  118. package/dist/esm/src/store/blockstore-mock.js.map +1 -1
  119. package/dist/esm/src/store/data-store-level.js +137 -100
  120. package/dist/esm/src/store/data-store-level.js.map +1 -1
  121. package/dist/esm/src/store/index-level-compound.js +246 -0
  122. package/dist/esm/src/store/index-level-compound.js.map +1 -0
  123. package/dist/esm/src/store/index-level.js +307 -715
  124. package/dist/esm/src/store/index-level.js.map +1 -1
  125. package/dist/esm/src/store/level-wrapper.js +143 -244
  126. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  127. package/dist/esm/src/store/message-store-level.js +71 -94
  128. package/dist/esm/src/store/message-store-level.js.map +1 -1
  129. package/dist/esm/src/store/resumable-task-store-level.js +62 -101
  130. package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
  131. package/dist/esm/src/store/storage-controller.js +131 -146
  132. package/dist/esm/src/store/storage-controller.js.map +1 -1
  133. package/dist/esm/src/types/permission-types.js.map +1 -1
  134. package/dist/esm/src/types/protocols-types.js +10 -0
  135. package/dist/esm/src/types/protocols-types.js.map +1 -1
  136. package/dist/esm/src/types/records-types.js.map +1 -1
  137. package/dist/esm/src/utils/abort.js +8 -19
  138. package/dist/esm/src/utils/abort.js.map +1 -1
  139. package/dist/esm/src/utils/array.js +15 -49
  140. package/dist/esm/src/utils/array.js.map +1 -1
  141. package/dist/esm/src/utils/cid.js +29 -77
  142. package/dist/esm/src/utils/cid.js.map +1 -1
  143. package/dist/esm/src/utils/data-stream.js +37 -65
  144. package/dist/esm/src/utils/data-stream.js.map +1 -1
  145. package/dist/esm/src/utils/encryption.js +136 -162
  146. package/dist/esm/src/utils/encryption.js.map +1 -1
  147. package/dist/esm/src/utils/filter.js +1 -12
  148. package/dist/esm/src/utils/filter.js.map +1 -1
  149. package/dist/esm/src/utils/hd-key.js +45 -71
  150. package/dist/esm/src/utils/hd-key.js.map +1 -1
  151. package/dist/esm/src/utils/jws.js +9 -20
  152. package/dist/esm/src/utils/jws.js.map +1 -1
  153. package/dist/esm/src/utils/memory-cache.js +12 -23
  154. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  155. package/dist/esm/src/utils/messages.js +21 -33
  156. package/dist/esm/src/utils/messages.js.map +1 -1
  157. package/dist/esm/src/utils/private-key-signer.js +9 -17
  158. package/dist/esm/src/utils/private-key-signer.js.map +1 -1
  159. package/dist/esm/src/utils/protocols.js +62 -70
  160. package/dist/esm/src/utils/protocols.js.map +1 -1
  161. package/dist/esm/src/utils/records.js +103 -166
  162. package/dist/esm/src/utils/records.js.map +1 -1
  163. package/dist/esm/src/utils/secp256k1.js +60 -96
  164. package/dist/esm/src/utils/secp256k1.js.map +1 -1
  165. package/dist/esm/src/utils/secp256r1.js +54 -71
  166. package/dist/esm/src/utils/secp256r1.js.map +1 -1
  167. package/dist/esm/src/utils/time.js +5 -18
  168. package/dist/esm/src/utils/time.js.map +1 -1
  169. package/dist/esm/src/utils/url.js +3 -3
  170. package/dist/esm/src/utils/url.js.map +1 -1
  171. package/dist/esm/tests/core/auth.spec.js +3 -12
  172. package/dist/esm/tests/core/auth.spec.js.map +1 -1
  173. package/dist/esm/tests/core/message.spec.js +50 -59
  174. package/dist/esm/tests/core/message.spec.js.map +1 -1
  175. package/dist/esm/tests/core/protocol-authorization.spec.js +10 -18
  176. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  177. package/dist/esm/tests/dwn.spec.js +65 -89
  178. package/dist/esm/tests/dwn.spec.js.map +1 -1
  179. package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
  180. package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
  181. package/dist/esm/tests/features/author-delegated-grant.spec.js +337 -347
  182. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  183. package/dist/esm/tests/features/owner-delegated-grant.spec.js +160 -172
  184. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  185. package/dist/esm/tests/features/owner-signature.spec.js +78 -82
  186. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  187. package/dist/esm/tests/features/permissions.spec.js +449 -184
  188. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  189. package/dist/esm/tests/features/protocol-composition.spec.js +981 -360
  190. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  191. package/dist/esm/tests/features/protocol-create-action.spec.js +45 -54
  192. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  193. package/dist/esm/tests/features/protocol-delete-action.spec.js +99 -108
  194. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  195. package/dist/esm/tests/features/protocol-update-action.spec.js +108 -117
  196. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  197. package/dist/esm/tests/features/records-immutable.spec.js +315 -0
  198. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
  199. package/dist/esm/tests/features/records-prune.spec.js +178 -194
  200. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  201. package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
  202. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
  203. package/dist/esm/tests/features/records-tags.spec.js +456 -463
  204. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  205. package/dist/esm/tests/features/resumable-tasks.spec.js +88 -98
  206. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  207. package/dist/esm/tests/handlers/messages-read.spec.js +215 -210
  208. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  209. package/dist/esm/tests/handlers/messages-subscribe.spec.js +309 -171
  210. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  211. package/dist/esm/tests/handlers/messages-sync.spec.js +272 -199
  212. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  213. package/dist/esm/tests/handlers/protocols-configure.spec.js +247 -241
  214. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  215. package/dist/esm/tests/handlers/protocols-query.spec.js +159 -172
  216. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  217. package/dist/esm/tests/handlers/records-count.spec.js +101 -105
  218. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  219. package/dist/esm/tests/handlers/records-delete.spec.js +266 -279
  220. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  221. package/dist/esm/tests/handlers/records-query.spec.js +984 -996
  222. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  223. package/dist/esm/tests/handlers/records-read.spec.js +542 -671
  224. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  225. package/dist/esm/tests/handlers/records-subscribe.spec.js +433 -302
  226. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  227. package/dist/esm/tests/handlers/records-write.spec.js +1216 -1140
  228. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  229. package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
  230. package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
  231. package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
  232. package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
  233. package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
  234. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  235. package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
  236. package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
  237. package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
  238. package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
  239. package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
  240. package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
  241. package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
  242. package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
  243. package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
  244. package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
  245. package/dist/esm/tests/interfaces/records-write.spec.js +190 -219
  246. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  247. package/dist/esm/tests/jose/jws/general.spec.js +36 -45
  248. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  249. package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
  250. package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
  251. package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
  252. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  253. package/dist/esm/tests/protocols/permissions.spec.js +49 -55
  254. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  255. package/dist/esm/tests/scenarios/aggregator.spec.js +127 -138
  256. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  257. package/dist/esm/tests/scenarios/deleted-record.spec.js +372 -36
  258. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  259. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +55 -64
  260. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  261. package/dist/esm/tests/scenarios/nested-roles.spec.js +66 -76
  262. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  263. package/dist/esm/tests/scenarios/subscriptions.spec.js +451 -354
  264. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  265. package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
  266. package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
  267. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
  268. package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
  269. package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
  270. package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
  271. package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
  272. package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
  273. package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
  274. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  275. package/dist/esm/tests/store/data-store-level.spec.js +160 -108
  276. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  277. package/dist/esm/tests/store/index-level.spec.js +404 -414
  278. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  279. package/dist/esm/tests/store/message-store-level.spec.js +13 -22
  280. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  281. package/dist/esm/tests/store/message-store.spec.js +229 -238
  282. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  283. package/dist/esm/tests/test-event-stream.js +12 -13
  284. package/dist/esm/tests/test-event-stream.js.map +1 -1
  285. package/dist/esm/tests/test-stores.js +16 -13
  286. package/dist/esm/tests/test-stores.js.map +1 -1
  287. package/dist/esm/tests/test-suite.js +8 -15
  288. package/dist/esm/tests/test-suite.js.map +1 -1
  289. package/dist/esm/tests/utils/cid.spec.js +24 -33
  290. package/dist/esm/tests/utils/cid.spec.js.map +1 -1
  291. package/dist/esm/tests/utils/data-stream.spec.js +48 -57
  292. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  293. package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
  294. package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
  295. package/dist/esm/tests/utils/encryption.spec.js +229 -82
  296. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  297. package/dist/esm/tests/utils/filters.spec.js +46 -55
  298. package/dist/esm/tests/utils/filters.spec.js.map +1 -1
  299. package/dist/esm/tests/utils/hd-key.spec.js +10 -19
  300. package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
  301. package/dist/esm/tests/utils/jws.spec.js +3 -12
  302. package/dist/esm/tests/utils/jws.spec.js.map +1 -1
  303. package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
  304. package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
  305. package/dist/esm/tests/utils/messages.spec.js +18 -20
  306. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  307. package/dist/esm/tests/utils/poller.js +22 -33
  308. package/dist/esm/tests/utils/poller.js.map +1 -1
  309. package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
  310. package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
  311. package/dist/esm/tests/utils/records.spec.js +14 -27
  312. package/dist/esm/tests/utils/records.spec.js.map +1 -1
  313. package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
  314. package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
  315. package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
  316. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  317. package/dist/esm/tests/utils/test-data-generator.js +446 -467
  318. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  319. package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
  320. package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
  321. package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +4 -13
  322. package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
  323. package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -17
  324. package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
  325. package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +3 -12
  326. package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
  327. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +4 -13
  328. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
  329. package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +2 -11
  330. package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
  331. package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +2 -11
  332. package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
  333. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +44 -24
  334. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  335. package/dist/types/generated/precompiled-validators.d.ts +49 -40
  336. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  337. package/dist/types/src/core/constants.d.ts +11 -0
  338. package/dist/types/src/core/constants.d.ts.map +1 -0
  339. package/dist/types/src/core/core-protocol.d.ts +89 -0
  340. package/dist/types/src/core/core-protocol.d.ts.map +1 -0
  341. package/dist/types/src/core/dwn-error.d.ts +9 -12
  342. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  343. package/dist/types/src/core/grant-authorization.d.ts +6 -2
  344. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  345. package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
  346. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
  347. package/dist/types/src/core/protocol-authorization-validation.d.ts +81 -0
  348. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
  349. package/dist/types/src/core/protocol-authorization.d.ts +24 -106
  350. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  351. package/dist/types/src/core/record-chain.d.ts +24 -0
  352. package/dist/types/src/core/record-chain.d.ts.map +1 -0
  353. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  354. package/dist/types/src/dwn.d.ts +19 -7
  355. package/dist/types/src/dwn.d.ts.map +1 -1
  356. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
  357. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
  358. package/dist/types/src/handlers/messages-read.d.ts +3 -8
  359. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  360. package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
  361. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  362. package/dist/types/src/handlers/messages-sync.d.ts +3 -8
  363. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  364. package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
  365. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  366. package/dist/types/src/handlers/protocols-query.d.ts +3 -8
  367. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  368. package/dist/types/src/handlers/records-count.d.ts +3 -6
  369. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  370. package/dist/types/src/handlers/records-delete.d.ts +3 -8
  371. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  372. package/dist/types/src/handlers/records-query.d.ts +3 -8
  373. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  374. package/dist/types/src/handlers/records-read.d.ts +3 -8
  375. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  376. package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
  377. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  378. package/dist/types/src/handlers/records-write.d.ts +4 -24
  379. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  380. package/dist/types/src/index.d.ts +8 -4
  381. package/dist/types/src/index.d.ts.map +1 -1
  382. package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
  383. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  384. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  385. package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
  386. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  387. package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
  388. package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
  389. package/dist/types/src/interfaces/records-write-signing.d.ts +34 -0
  390. package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
  391. package/dist/types/src/interfaces/records-write.d.ts +13 -53
  392. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  393. package/dist/types/src/protocols/permission-grant.d.ts +1 -1
  394. package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
  395. package/dist/types/src/protocols/permission-request.d.ts +1 -1
  396. package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
  397. package/dist/types/src/protocols/permissions.d.ts +40 -3
  398. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  399. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  400. package/dist/types/src/store/data-store-level.d.ts +20 -4
  401. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  402. package/dist/types/src/store/index-level-compound.d.ts +70 -0
  403. package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
  404. package/dist/types/src/store/index-level.d.ts +4 -58
  405. package/dist/types/src/store/index-level.d.ts.map +1 -1
  406. package/dist/types/src/store/storage-controller.d.ts +4 -4
  407. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  408. package/dist/types/src/types/message-types.d.ts +3 -3
  409. package/dist/types/src/types/message-types.d.ts.map +1 -1
  410. package/dist/types/src/types/messages-types.d.ts +12 -3
  411. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  412. package/dist/types/src/types/method-handler.d.ts +24 -3
  413. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  414. package/dist/types/src/types/permission-types.d.ts +7 -0
  415. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  416. package/dist/types/src/types/protocols-types.d.ts +41 -1
  417. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  418. package/dist/types/src/types/records-types.d.ts +16 -6
  419. package/dist/types/src/types/records-types.d.ts.map +1 -1
  420. package/dist/types/src/types/subscriptions.d.ts +151 -13
  421. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  422. package/dist/types/src/utils/hd-key.d.ts +1 -9
  423. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  424. package/dist/types/src/utils/messages.d.ts +7 -5
  425. package/dist/types/src/utils/messages.d.ts.map +1 -1
  426. package/dist/types/src/utils/protocols.d.ts +5 -0
  427. package/dist/types/src/utils/protocols.d.ts.map +1 -1
  428. package/dist/types/src/utils/records.d.ts +1 -11
  429. package/dist/types/src/utils/records.d.ts.map +1 -1
  430. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  431. package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
  432. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
  433. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  434. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  435. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  436. package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
  437. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  438. package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
  439. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
  440. package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
  441. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
  442. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  443. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  444. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  445. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  446. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  447. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  448. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  449. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  450. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  451. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  452. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  453. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  454. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  455. package/dist/types/tests/test-event-stream.d.ts +11 -12
  456. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  457. package/dist/types/tests/test-suite.d.ts +2 -2
  458. package/dist/types/tests/test-suite.d.ts.map +1 -1
  459. package/dist/types/tests/utils/test-data-generator.d.ts +18 -0
  460. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  461. package/package.json +5 -4
  462. package/src/core/constants.ts +11 -0
  463. package/src/core/core-protocol.ts +129 -0
  464. package/src/core/dwn-error.ts +15 -12
  465. package/src/core/grant-authorization.ts +20 -3
  466. package/src/core/protocol-authorization-action.ts +377 -0
  467. package/src/core/protocol-authorization-validation.ts +487 -0
  468. package/src/core/protocol-authorization.ts +111 -856
  469. package/src/core/record-chain.ts +99 -0
  470. package/src/core/records-grant-authorization.ts +6 -8
  471. package/src/dwn.ts +58 -73
  472. package/src/event-stream/event-emitter-event-log.ts +283 -0
  473. package/src/handlers/messages-read.ts +8 -9
  474. package/src/handlers/messages-subscribe.ts +24 -28
  475. package/src/handlers/messages-sync.ts +10 -16
  476. package/src/handlers/protocols-configure.ts +47 -32
  477. package/src/handlers/protocols-query.ts +6 -9
  478. package/src/handlers/records-count.ts +11 -10
  479. package/src/handlers/records-delete.ts +12 -21
  480. package/src/handlers/records-query.ts +12 -12
  481. package/src/handlers/records-read.ts +34 -22
  482. package/src/handlers/records-subscribe.ts +47 -26
  483. package/src/handlers/records-write.ts +47 -104
  484. package/src/index.ts +9 -5
  485. package/src/interfaces/messages-subscribe.ts +7 -1
  486. package/src/interfaces/protocols-configure.ts +73 -8
  487. package/src/interfaces/records-count.ts +1 -1
  488. package/src/interfaces/records-delete.ts +1 -1
  489. package/src/interfaces/records-query.ts +1 -1
  490. package/src/interfaces/records-read.ts +1 -1
  491. package/src/interfaces/records-subscribe.ts +8 -1
  492. package/src/interfaces/records-write-query.ts +139 -0
  493. package/src/interfaces/records-write-signing.ts +123 -0
  494. package/src/interfaces/records-write.ts +66 -261
  495. package/src/protocols/permission-grant.ts +1 -1
  496. package/src/protocols/permission-request.ts +1 -1
  497. package/src/protocols/permissions.ts +148 -6
  498. package/src/state-index/state-index-level.ts +5 -7
  499. package/src/store/data-store-level.ts +124 -34
  500. package/src/store/index-level-compound.ts +324 -0
  501. package/src/store/index-level.ts +68 -341
  502. package/src/store/storage-controller.ts +11 -11
  503. package/src/types/message-types.ts +3 -3
  504. package/src/types/messages-types.ts +12 -3
  505. package/src/types/method-handler.ts +26 -4
  506. package/src/types/mitt.d.ts +28 -0
  507. package/src/types/permission-types.ts +7 -0
  508. package/src/types/protocols-types.ts +46 -0
  509. package/src/types/records-types.ts +16 -6
  510. package/src/types/subscriptions.ts +178 -14
  511. package/src/utils/hd-key.ts +0 -9
  512. package/src/utils/messages.ts +17 -37
  513. package/src/utils/protocols.ts +8 -0
  514. package/src/utils/records.ts +8 -59
  515. package/dist/esm/src/event-stream/event-emitter-stream.js +0 -60
  516. package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
  517. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -77
  518. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
  519. package/dist/esm/tests/event-stream/event-stream.spec.js +0 -123
  520. package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
  521. package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
  522. package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
  523. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
  524. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
  525. package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
  526. package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
  527. package/src/event-stream/event-emitter-stream.ts +0 -69
@@ -1,72 +1,41 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __asyncValues = (this && this.__asyncValues) || function (o) {
11
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
12
- var m = o[Symbol.asyncIterator], i;
13
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
14
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
15
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
16
- };
17
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
18
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
19
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
20
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
21
- return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
22
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
23
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
24
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
25
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
26
- function fulfill(value) { resume("next", value); }
27
- function reject(value) { resume("throw", value); }
28
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
29
- };
30
1
  import { isEmptyObject } from '../utils/object.js';
31
2
  import { lexicographicalCompare } from '../utils/string.js';
32
3
  import { SortDirection } from '../types/query-types.js';
4
+ import { countWithCompoundIndex, createCompoundIndexDeleteOperation, createCompoundIndexPutOperation, queryWithCompoundIndex, selectCompoundIndex, } from './index-level-compound.js';
33
5
  import { createLevelDatabase, LevelWrapper } from './level-wrapper.js';
34
6
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
35
7
  import { FilterSelector, FilterUtility } from '../utils/filter.js';
36
8
  const INDEX_SUBLEVEL_NAME = 'index';
37
- /** Separator between compound key segments (higher than \x00 so prefix scans work correctly). */
38
- const COMPOUND_SEGMENT_SEPARATOR = '\x01';
39
9
  /**
40
10
  * A LevelDB implementation for indexing the messages and events stored in the DWN.
41
11
  */
42
12
  export class IndexLevel {
13
+ db;
14
+ config;
15
+ _compoundIndexes;
43
16
  constructor(config) {
44
- var _a;
45
- this.config = Object.assign({ createLevelDatabase }, config);
46
- this._compoundIndexes = (_a = config.compoundIndexes) !== null && _a !== void 0 ? _a : [];
17
+ this.config = {
18
+ createLevelDatabase,
19
+ ...config,
20
+ };
21
+ this._compoundIndexes = config.compoundIndexes ?? [];
47
22
  this.db = new LevelWrapper({
48
23
  location: this.config.location,
49
24
  createLevelDatabase: this.config.createLevelDatabase,
50
25
  keyEncoding: 'utf8'
51
26
  });
52
27
  }
53
- open() {
54
- return __awaiter(this, void 0, void 0, function* () {
55
- yield this.db.open();
56
- });
28
+ async open() {
29
+ await this.db.open();
57
30
  }
58
- close() {
59
- return __awaiter(this, void 0, void 0, function* () {
60
- yield this.db.close();
61
- });
31
+ async close() {
32
+ await this.db.close();
62
33
  }
63
34
  /**
64
35
  * deletes everything in the underlying index db.
65
36
  */
66
- clear() {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- yield this.db.clear();
69
- });
37
+ async clear() {
38
+ await this.db.clear();
70
39
  }
71
40
  /**
72
41
  * Put an item into the index using information that will allow it to be queried for.
@@ -76,132 +45,120 @@ export class IndexLevel {
76
45
  * @param indexes - (key-value pairs) to be included as part of indexing this item. Must include at least one indexing property.
77
46
  * @param options IndexLevelOptions that include an AbortSignal.
78
47
  */
79
- put(tenant, messageCid, indexes, options) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- // ensure we have something valid to index
82
- if (isEmptyObject(indexes)) {
83
- throw new DwnError(DwnErrorCode.IndexMissingIndexableProperty, 'Index must include at least one valid indexable property');
84
- }
85
- const item = { messageCid, indexes };
86
- const opCreationPromises = [];
87
- // create an index entry for each property index
88
- // these indexes are all sortable lexicographically.
89
- for (const indexName in indexes) {
90
- const indexValue = indexes[indexName];
91
- if (Array.isArray(indexValue)) {
92
- for (const indexValueItem of indexValue) {
93
- const partitionOperationPromise = this.createPutIndexedItemOperation(tenant, item, indexName, indexValueItem);
94
- opCreationPromises.push(partitionOperationPromise);
95
- }
96
- }
97
- else {
98
- const partitionOperationPromise = this.createPutIndexedItemOperation(tenant, item, indexName, indexValue);
48
+ async put(tenant, messageCid, indexes, options) {
49
+ // ensure we have something valid to index
50
+ if (isEmptyObject(indexes)) {
51
+ throw new DwnError(DwnErrorCode.IndexMissingIndexableProperty, 'Index must include at least one valid indexable property');
52
+ }
53
+ const item = { messageCid, indexes };
54
+ const opCreationPromises = [];
55
+ // create an index entry for each property index
56
+ // these indexes are all sortable lexicographically.
57
+ for (const indexName in indexes) {
58
+ const indexValue = indexes[indexName];
59
+ if (Array.isArray(indexValue)) {
60
+ for (const indexValueItem of indexValue) {
61
+ const partitionOperationPromise = this.createPutIndexedItemOperation(tenant, item, indexName, indexValueItem);
99
62
  opCreationPromises.push(partitionOperationPromise);
100
63
  }
101
64
  }
102
- // create compound index entries for any registered compound indexes whose properties are all present in the indexes.
103
- for (const compoundIndex of this._compoundIndexes) {
104
- const compoundOp = this.createCompoundIndexPutOperation(tenant, item, compoundIndex);
105
- if (compoundOp !== undefined) {
106
- opCreationPromises.push(compoundOp);
107
- }
65
+ else {
66
+ const partitionOperationPromise = this.createPutIndexedItemOperation(tenant, item, indexName, indexValue);
67
+ opCreationPromises.push(partitionOperationPromise);
108
68
  }
109
- // create a reverse lookup for the sortedIndex values. This is used during deletion and cursor starting point lookup.
110
- const partitionOperationPromise = this.createOperationForIndexesLookupPartition(tenant, { type: 'put', key: messageCid, value: JSON.stringify(indexes) });
111
- opCreationPromises.push(partitionOperationPromise);
112
- const indexOps = yield Promise.all(opCreationPromises);
113
- const tenantPartition = yield this.db.partition(tenant);
114
- yield tenantPartition.batch(indexOps, options);
115
- });
69
+ }
70
+ // create compound index entries for any registered compound indexes whose properties are all present in the indexes.
71
+ for (const compoundIndex of this._compoundIndexes) {
72
+ const compoundOp = createCompoundIndexPutOperation(this.db, tenant, item, compoundIndex, IndexLevel.encodeValue, IndexLevel.delimiter);
73
+ if (compoundOp !== undefined) {
74
+ opCreationPromises.push(compoundOp);
75
+ }
76
+ }
77
+ // create a reverse lookup for the sortedIndex values. This is used during deletion and cursor starting point lookup.
78
+ const partitionOperationPromise = this.createOperationForIndexesLookupPartition(tenant, { type: 'put', key: messageCid, value: JSON.stringify(indexes) });
79
+ opCreationPromises.push(partitionOperationPromise);
80
+ const indexOps = await Promise.all(opCreationPromises);
81
+ const tenantPartition = await this.db.partition(tenant);
82
+ await tenantPartition.batch(indexOps, options);
116
83
  }
117
84
  /**
118
85
  * Deletes all of the index data associated with the item.
119
86
  */
120
- delete(tenant, messageCid, options) {
121
- return __awaiter(this, void 0, void 0, function* () {
122
- const opCreationPromises = [];
123
- const indexes = yield this.getIndexes(tenant, messageCid);
124
- if (indexes === undefined) {
125
- // invalid messageCid
126
- return;
127
- }
128
- // delete the reverse lookup
129
- const partitionOperationPromise = this.createOperationForIndexesLookupPartition(tenant, { type: 'del', key: messageCid });
130
- opCreationPromises.push(partitionOperationPromise);
131
- // delete the keys for each index
132
- for (const indexName in indexes) {
133
- const indexValue = indexes[indexName];
134
- if (Array.isArray(indexValue)) {
135
- for (const indexValueItem of indexValue) {
136
- const partitionOperationPromise = this.createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValueItem);
137
- opCreationPromises.push(partitionOperationPromise);
138
- }
139
- }
140
- else {
141
- const partitionOperationPromise = this.createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValue);
87
+ async delete(tenant, messageCid, options) {
88
+ const opCreationPromises = [];
89
+ const indexes = await this.getIndexes(tenant, messageCid);
90
+ if (indexes === undefined) {
91
+ // invalid messageCid
92
+ return;
93
+ }
94
+ // delete the reverse lookup
95
+ const partitionOperationPromise = this.createOperationForIndexesLookupPartition(tenant, { type: 'del', key: messageCid });
96
+ opCreationPromises.push(partitionOperationPromise);
97
+ // delete the keys for each index
98
+ for (const indexName in indexes) {
99
+ const indexValue = indexes[indexName];
100
+ if (Array.isArray(indexValue)) {
101
+ for (const indexValueItem of indexValue) {
102
+ const partitionOperationPromise = this.createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValueItem);
142
103
  opCreationPromises.push(partitionOperationPromise);
143
104
  }
144
105
  }
145
- // delete compound index entries
146
- for (const compoundIndex of this._compoundIndexes) {
147
- const compoundOp = this.createCompoundIndexDeleteOperation(tenant, messageCid, indexes, compoundIndex);
148
- if (compoundOp !== undefined) {
149
- opCreationPromises.push(compoundOp);
150
- }
106
+ else {
107
+ const partitionOperationPromise = this.createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValue);
108
+ opCreationPromises.push(partitionOperationPromise);
151
109
  }
152
- const indexOps = yield Promise.all(opCreationPromises);
153
- const tenantPartition = yield this.db.partition(tenant);
154
- yield tenantPartition.batch(indexOps, options);
155
- });
110
+ }
111
+ // delete compound index entries
112
+ for (const compoundIndex of this._compoundIndexes) {
113
+ const compoundOp = createCompoundIndexDeleteOperation(this.db, tenant, messageCid, indexes, compoundIndex, IndexLevel.encodeValue, IndexLevel.delimiter);
114
+ if (compoundOp !== undefined) {
115
+ opCreationPromises.push(compoundOp);
116
+ }
117
+ }
118
+ const indexOps = await Promise.all(opCreationPromises);
119
+ const tenantPartition = await this.db.partition(tenant);
120
+ await tenantPartition.batch(indexOps, options);
156
121
  }
157
122
  /**
158
123
  * Creates an IndexLevel `put` operation for indexing an item, creating a partition by `tenant` and by `indexName`
159
124
  */
160
- createPutIndexedItemOperation(tenant, item, indexName, indexValue) {
161
- return __awaiter(this, void 0, void 0, function* () {
162
- const { messageCid } = item;
163
- // The key is the indexValue followed by the messageCid as a tie-breaker.
164
- // for example if the property is messageTimestamp the key would look like:
165
- // '"2023-05-25T18:23:29.425008Z"\u0000bafyreigs3em7lrclhntzhgvkrf75j2muk6e7ypq3lrw3ffgcpyazyw6pry'
166
- const key = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(indexValue), messageCid);
167
- return this.createOperationForIndexPartition(tenant, indexName, { type: 'put', key, value: JSON.stringify(item) });
168
- });
125
+ async createPutIndexedItemOperation(tenant, item, indexName, indexValue) {
126
+ const { messageCid } = item;
127
+ // The key is the indexValue followed by the messageCid as a tie-breaker.
128
+ // for example if the property is messageTimestamp the key would look like:
129
+ // '"2023-05-25T18:23:29.425008Z"\u0000bafyreigs3em7lrclhntzhgvkrf75j2muk6e7ypq3lrw3ffgcpyazyw6pry'
130
+ const key = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(indexValue), messageCid);
131
+ return this.createOperationForIndexPartition(tenant, indexName, { type: 'put', key, value: JSON.stringify(item) });
169
132
  }
170
133
  /**
171
134
  * Creates an IndexLevel `del` operation for deleting an item, creating a partition by `tenant` and by `indexName`
172
135
  */
173
- createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValue) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- // The key is the indexValue followed by the messageCid as a tie-breaker.
176
- // for example if the property is messageTimestamp the key would look like:
177
- // '"2023-05-25T18:23:29.425008Z"\u0000bafyreigs3em7lrclhntzhgvkrf75j2muk6e7ypq3lrw3ffgcpyazyw6pry'
178
- const key = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(indexValue), messageCid);
179
- return this.createOperationForIndexPartition(tenant, indexName, { type: 'del', key });
180
- });
136
+ async createDeleteIndexedItemOperation(tenant, messageCid, indexName, indexValue) {
137
+ // The key is the indexValue followed by the messageCid as a tie-breaker.
138
+ // for example if the property is messageTimestamp the key would look like:
139
+ // '"2023-05-25T18:23:29.425008Z"\u0000bafyreigs3em7lrclhntzhgvkrf75j2muk6e7ypq3lrw3ffgcpyazyw6pry'
140
+ const key = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(indexValue), messageCid);
141
+ return this.createOperationForIndexPartition(tenant, indexName, { type: 'del', key });
181
142
  }
182
143
  /**
183
144
  * Wraps the given operation as an operation for the specified index partition.
184
145
  */
185
- createOperationForIndexPartition(tenant, indexName, operation) {
186
- return __awaiter(this, void 0, void 0, function* () {
187
- // we write the index entry into a sublevel-partition of tenantPartition.
188
- // putting each index entry within a sublevel allows the levelDB system to calculate a gt minKey and lt maxKey for each of the properties
189
- // this prevents them from clashing, especially when iterating in reverse without iterating through other properties.
190
- const tenantPartition = yield this.db.partition(tenant);
191
- const indexPartitionName = IndexLevel.getIndexPartitionName(indexName);
192
- const partitionOperation = tenantPartition.createPartitionOperation(indexPartitionName, operation);
193
- return partitionOperation;
194
- });
146
+ async createOperationForIndexPartition(tenant, indexName, operation) {
147
+ // we write the index entry into a sublevel-partition of tenantPartition.
148
+ // putting each index entry within a sublevel allows the levelDB system to calculate a gt minKey and lt maxKey for each of the properties
149
+ // this prevents them from clashing, especially when iterating in reverse without iterating through other properties.
150
+ const tenantPartition = await this.db.partition(tenant);
151
+ const indexPartitionName = IndexLevel.getIndexPartitionName(indexName);
152
+ const partitionOperation = tenantPartition.createPartitionOperation(indexPartitionName, operation);
153
+ return partitionOperation;
195
154
  }
196
155
  /**
197
156
  * Wraps the given operation as an operation for the messageCid to indexes lookup partition.
198
157
  */
199
- createOperationForIndexesLookupPartition(tenant, operation) {
200
- return __awaiter(this, void 0, void 0, function* () {
201
- const tenantPartition = yield this.db.partition(tenant);
202
- const partitionOperation = tenantPartition.createPartitionOperation(INDEX_SUBLEVEL_NAME, operation);
203
- return partitionOperation;
204
- });
158
+ async createOperationForIndexesLookupPartition(tenant, operation) {
159
+ const tenantPartition = await this.db.partition(tenant);
160
+ const partitionOperation = tenantPartition.createPartitionOperation(INDEX_SUBLEVEL_NAME, operation);
161
+ return partitionOperation;
205
162
  }
206
163
  static getIndexPartitionName(indexName) {
207
164
  // we create index partition names in __${indexName}__ wrapping so they do not clash with other sublevels that are created for other purposes.
@@ -210,19 +167,15 @@ export class IndexLevel {
210
167
  /**
211
168
  * Gets the index partition of the given indexName.
212
169
  */
213
- getIndexPartition(tenant, indexName) {
214
- return __awaiter(this, void 0, void 0, function* () {
215
- const indexPartitionName = IndexLevel.getIndexPartitionName(indexName);
216
- return (yield this.db.partition(tenant)).partition(indexPartitionName);
217
- });
170
+ async getIndexPartition(tenant, indexName) {
171
+ const indexPartitionName = IndexLevel.getIndexPartitionName(indexName);
172
+ return (await this.db.partition(tenant)).partition(indexPartitionName);
218
173
  }
219
174
  /**
220
175
  * Gets the messageCid to indexes lookup partition.
221
176
  */
222
- getIndexesLookupPartition(tenant) {
223
- return __awaiter(this, void 0, void 0, function* () {
224
- return (yield this.db.partition(tenant)).partition(INDEX_SUBLEVEL_NAME);
225
- });
177
+ async getIndexesLookupPartition(tenant) {
178
+ return (await this.db.partition(tenant)).partition(INDEX_SUBLEVEL_NAME);
226
179
  }
227
180
  /**
228
181
  * Queries the index for items that match the filters. If no filters are provided, all items are returned.
@@ -238,22 +191,20 @@ export class IndexLevel {
238
191
  * @param options IndexLevelOptions that include an AbortSignal.
239
192
  * @returns {IndexedItem[]} an array of `IndexedItem` that match the given filters.
240
193
  */
241
- query(tenant, filters, queryOptions, options) {
242
- return __awaiter(this, void 0, void 0, function* () {
243
- // Strategy 1: try compound index for single-filter queries
244
- if (filters.length === 1 && !isEmptyObject(filters[0])) {
245
- const compoundResult = this.selectCompoundIndex(filters[0], queryOptions);
246
- if (compoundResult !== undefined) {
247
- return this.queryWithCompoundIndex(tenant, filters[0], queryOptions, compoundResult, options);
248
- }
249
- }
250
- // Strategy 2: in-memory paging for concise filters
251
- if (IndexLevel.shouldQueryWithInMemoryPaging(filters, queryOptions)) {
252
- return this.queryWithInMemoryPaging(tenant, filters, queryOptions, options);
194
+ async query(tenant, filters, queryOptions, options) {
195
+ // Strategy 1: try compound index for single-filter queries
196
+ if (filters.length === 1 && !isEmptyObject(filters[0])) {
197
+ const compoundResult = selectCompoundIndex(filters[0], queryOptions, this._compoundIndexes);
198
+ if (compoundResult !== undefined) {
199
+ return queryWithCompoundIndex(this.db, tenant, filters[0], queryOptions, compoundResult, IndexLevel.encodeValue, IndexLevel.delimiter, this.queryWithIteratorPaging.bind(this), options);
253
200
  }
254
- // Strategy 3: iterator paging (default)
255
- return this.queryWithIteratorPaging(tenant, filters, queryOptions, options);
256
- });
201
+ }
202
+ // Strategy 2: in-memory paging for concise filters
203
+ if (IndexLevel.shouldQueryWithInMemoryPaging(filters, queryOptions)) {
204
+ return this.queryWithInMemoryPaging(tenant, filters, queryOptions, options);
205
+ }
206
+ // Strategy 3: iterator paging (default)
207
+ return this.queryWithIteratorPaging(tenant, filters, queryOptions, options);
257
208
  }
258
209
  /**
259
210
  * Counts the number of items that match the given filters without loading full records.
@@ -261,94 +212,62 @@ export class IndexLevel {
261
212
  * When a compound index covers the query, counting is a simple key iteration without value deserialization.
262
213
  * Otherwise, falls back to counting via the existing query strategies.
263
214
  */
264
- count(tenant, filters, queryOptions, options) {
265
- return __awaiter(this, void 0, void 0, function* () {
266
- // try compound index for single-filter queries
267
- if (filters.length === 1 && !isEmptyObject(filters[0])) {
268
- const compoundResult = this.selectCompoundIndex(filters[0], Object.assign({}, queryOptions));
269
- if (compoundResult !== undefined) {
270
- return this.countWithCompoundIndex(tenant, filters[0], compoundResult, options);
271
- }
215
+ async count(tenant, filters, queryOptions, options) {
216
+ // try compound index for single-filter queries
217
+ if (filters.length === 1 && !isEmptyObject(filters[0])) {
218
+ const compoundResult = selectCompoundIndex(filters[0], { ...queryOptions }, this._compoundIndexes);
219
+ if (compoundResult !== undefined) {
220
+ return countWithCompoundIndex(this.db, tenant, filters[0], compoundResult, IndexLevel.encodeValue, this.query.bind(this), options);
272
221
  }
273
- // fallback: run a full query without limit and count the results
274
- const results = yield this.query(tenant, filters, Object.assign({}, queryOptions), options);
275
- return results.length;
276
- });
222
+ }
223
+ // fallback: run a full query without limit and count the results
224
+ const results = await this.query(tenant, filters, { ...queryOptions }, options);
225
+ return results.length;
277
226
  }
278
227
  /**
279
228
  * Queries the sort property index for items that match the filters. If no filters are provided, all items are returned.
280
229
  * This query is a linear iterator over the sorted index, checking each item for a match.
281
230
  * If a cursor is provided it starts the iteration from the cursor point.
282
231
  */
283
- queryWithIteratorPaging(tenant, filters, queryOptions, options) {
284
- return __awaiter(this, void 0, void 0, function* () {
285
- var _a, e_1, _b, _c;
286
- const { cursor: queryCursor, limit } = queryOptions;
287
- // if there is a cursor we fetch the starting key given the sort property, otherwise we start from the beginning of the index.
288
- const startKey = queryCursor ? this.createStartingKeyFromCursor(queryCursor) : '';
289
- const matches = [];
290
- try {
291
- for (var _d = true, _e = __asyncValues(this.getIndexIterator(tenant, startKey, queryOptions, options)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
292
- _c = _f.value;
293
- _d = false;
294
- const item = _c;
295
- if (limit !== undefined && limit === matches.length) {
296
- break;
297
- }
298
- const { indexes } = item;
299
- if (FilterUtility.matchAnyFilter(indexes, filters)) {
300
- matches.push(item);
301
- }
302
- }
232
+ async queryWithIteratorPaging(tenant, filters, queryOptions, options) {
233
+ const { cursor: queryCursor, limit } = queryOptions;
234
+ // if there is a cursor we fetch the starting key given the sort property, otherwise we start from the beginning of the index.
235
+ const startKey = queryCursor ? this.createStartingKeyFromCursor(queryCursor) : '';
236
+ const matches = [];
237
+ for await (const item of this.getIndexIterator(tenant, startKey, queryOptions, options)) {
238
+ if (limit !== undefined && limit === matches.length) {
239
+ break;
303
240
  }
304
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
305
- finally {
306
- try {
307
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
308
- }
309
- finally { if (e_1) throw e_1.error; }
241
+ const { indexes } = item;
242
+ if (FilterUtility.matchAnyFilter(indexes, filters)) {
243
+ matches.push(item);
310
244
  }
311
- return matches;
312
- });
245
+ }
246
+ return matches;
313
247
  }
314
248
  /**
315
249
  * Creates an AsyncGenerator that returns each sorted index item given a specific sortProperty.
316
250
  * If a cursor is passed, the starting value (gt or lt) is derived from that.
317
251
  */
318
- getIndexIterator(tenant, startKey, queryOptions, options) {
319
- return __asyncGenerator(this, arguments, function* getIndexIterator_1() {
320
- var _a, e_2, _b, _c;
321
- const { sortProperty, sortDirection = SortDirection.Ascending, cursor } = queryOptions;
322
- const iteratorOptions = {
323
- gt: startKey
324
- };
325
- // if we are sorting in descending order we can iterate in reverse.
326
- if (sortDirection === SortDirection.Descending) {
327
- iteratorOptions.reverse = true;
328
- // if a cursor is provided and we are sorting in descending order, the startKey should be the upper bound.
329
- if (cursor !== undefined) {
330
- iteratorOptions.lt = startKey;
331
- delete iteratorOptions.gt;
332
- }
333
- }
334
- const sortPartition = yield __await(this.getIndexPartition(tenant, sortProperty));
335
- try {
336
- for (var _d = true, _e = __asyncValues(sortPartition.iterator(iteratorOptions, options)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
337
- _c = _f.value;
338
- _d = false;
339
- const [_, val] = _c;
340
- const { indexes, messageCid } = JSON.parse(val);
341
- yield yield __await({ indexes, messageCid });
342
- }
343
- }
344
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
345
- finally {
346
- try {
347
- if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
348
- }
349
- finally { if (e_2) throw e_2.error; }
252
+ async *getIndexIterator(tenant, startKey, queryOptions, options) {
253
+ const { sortProperty, sortDirection = SortDirection.Ascending, cursor } = queryOptions;
254
+ const iteratorOptions = {
255
+ gt: startKey
256
+ };
257
+ // if we are sorting in descending order we can iterate in reverse.
258
+ if (sortDirection === SortDirection.Descending) {
259
+ iteratorOptions.reverse = true;
260
+ // if a cursor is provided and we are sorting in descending order, the startKey should be the upper bound.
261
+ if (cursor !== undefined) {
262
+ iteratorOptions.lt = startKey;
263
+ delete iteratorOptions.gt;
350
264
  }
351
- });
265
+ }
266
+ const sortPartition = await this.getIndexPartition(tenant, sortProperty);
267
+ for await (const [_, val] of sortPartition.iterator(iteratorOptions, options)) {
268
+ const { indexes, messageCid } = JSON.parse(val);
269
+ yield { indexes, messageCid };
270
+ }
352
271
  }
353
272
  /**
354
273
  * Creates the starting point for a LevelDB query given an messageCid as a cursor and the indexed property.
@@ -394,151 +313,127 @@ export class IndexLevel {
394
313
  *
395
314
  * @throws {DwnErrorCode.IndexLevelInMemoryInvalidSortProperty} if an invalid sort property is provided.
396
315
  */
397
- queryWithInMemoryPaging(tenant, filters, queryOptions, options) {
398
- return __awaiter(this, void 0, void 0, function* () {
399
- const { sortProperty, sortDirection = SortDirection.Ascending, cursor: queryCursor, limit } = queryOptions;
400
- // we get the cursor start key here so that we match the failing behavior of `queryWithIteratorPaging`
401
- const cursorStartingKey = queryCursor ? this.createStartingKeyFromCursor(queryCursor) : undefined;
402
- // we create a matches map so that we can short-circuit matched items within the async single query below.
403
- const matches = new Map();
404
- // If the filter is empty, we just give it an empty filter so that we can iterate over all the items later in executeSingleFilterQuery().
405
- // We could do the iteration here, but it would be duplicating the same logic, so decided to just setup the data structure here.
406
- if (filters.length === 0) {
407
- filters = [{}];
408
- }
409
- try {
410
- yield Promise.all(filters.map(filter => {
411
- return this.executeSingleFilterQuery(tenant, filter, sortProperty, matches, options);
412
- }));
413
- }
414
- catch (error) {
415
- if (error.code === DwnErrorCode.IndexInvalidSortPropertyInMemory) {
416
- // return empty results if the sort property is invalid.
417
- return [];
418
- }
316
+ async queryWithInMemoryPaging(tenant, filters, queryOptions, options) {
317
+ const { sortProperty, sortDirection = SortDirection.Ascending, cursor: queryCursor, limit } = queryOptions;
318
+ // we get the cursor start key here so that we match the failing behavior of `queryWithIteratorPaging`
319
+ const cursorStartingKey = queryCursor ? this.createStartingKeyFromCursor(queryCursor) : undefined;
320
+ // we create a matches map so that we can short-circuit matched items within the async single query below.
321
+ const matches = new Map();
322
+ // If the filter is empty, we just give it an empty filter so that we can iterate over all the items later in executeSingleFilterQuery().
323
+ // We could do the iteration here, but it would be duplicating the same logic, so decided to just setup the data structure here.
324
+ if (filters.length === 0) {
325
+ filters = [{}];
326
+ }
327
+ try {
328
+ // Execute filters sequentially rather than with Promise.all.
329
+ // Firefox's IndexedDB implementation has two related async issues that cause flaky failures:
330
+ // 1. Concurrent cursors/transactions can silently miss recently-committed data
331
+ // 2. A read transaction opened immediately after a write transaction's oncomplete event
332
+ // can fail to see the written data (write-read race)
333
+ // Serializing eliminates both races. Performance impact is negligible: only 3 call sites
334
+ // (non-owner RecordsQuery/Subscribe/Count) ever pass multiple filters, and each filter
335
+ // reduces to a single bounded LevelDB range scan completing in single-digit ms.
336
+ // See: https://github.com/enboxorg/enbox/issues/264
337
+ for (const filter of filters) {
338
+ await this.executeSingleFilterQuery(tenant, filter, sortProperty, matches, options);
419
339
  }
420
- const sortedValues = [...matches.values()].sort((a, b) => this.sortItems(a, b, sortProperty, sortDirection));
421
- const start = cursorStartingKey !== undefined ? this.findCursorStartingIndex(sortedValues, sortDirection, sortProperty, cursorStartingKey) : 0;
422
- if (start < 0) {
423
- // if the provided cursor does not come before any of the results, we return no results
340
+ }
341
+ catch (error) {
342
+ if (error.code === DwnErrorCode.IndexInvalidSortPropertyInMemory) {
343
+ // return empty results if the sort property is invalid.
424
344
  return [];
425
345
  }
426
- const end = limit !== undefined ? start + limit : undefined;
427
- return sortedValues.slice(start, end);
428
- });
346
+ }
347
+ const sortedValues = [...matches.values()].sort((a, b) => this.sortItems(a, b, sortProperty, sortDirection));
348
+ const start = cursorStartingKey !== undefined ? this.findCursorStartingIndex(sortedValues, sortDirection, sortProperty, cursorStartingKey) : 0;
349
+ if (start < 0) {
350
+ // if the provided cursor does not come before any of the results, we return no results
351
+ return [];
352
+ }
353
+ const end = limit !== undefined ? start + limit : undefined;
354
+ return sortedValues.slice(start, end);
429
355
  }
430
356
  /**
431
357
  * Execute a filtered query against a single filter and return all results.
432
- */
433
- executeSingleFilterQuery(tenant, filter, sortProperty, matches, levelOptions) {
434
- return __awaiter(this, void 0, void 0, function* () {
435
- // Note: We have an array of Promises in order to support OR (anyOf) matches when given a list of accepted values for a property
436
- const filterPromises = [];
437
- // If the filter is empty, then we just iterate over one of the indexes that contains all the records and return all items.
438
- if (isEmptyObject(filter)) {
439
- const getAllItemsPromise = this.getAllItems(tenant, sortProperty);
440
- filterPromises.push(getAllItemsPromise);
441
- }
442
- // else the filter is not empty
443
- const searchFilter = FilterSelector.reduceFilter(filter);
444
- for (const propertyName in searchFilter) {
445
- const propertyFilter = searchFilter[propertyName];
446
- // We will find the union of these many individual queries later.
447
- if (FilterUtility.isEqualFilter(propertyFilter)) {
448
- // propertyFilter is an EqualFilter, meaning it is a non-object primitive type
449
- const exactMatchesPromise = this.filterExactMatches(tenant, propertyName, propertyFilter, levelOptions);
450
- filterPromises.push(exactMatchesPromise);
451
- }
452
- else if (FilterUtility.isOneOfFilter(propertyFilter)) {
453
- // `propertyFilter` is a OneOfFilter
454
- // Support OR matches by querying for each values separately, then adding them to the promises array.
455
- for (const propertyValue of new Set(propertyFilter)) {
456
- const exactMatchesPromise = this.filterExactMatches(tenant, propertyName, propertyValue, levelOptions);
457
- filterPromises.push(exactMatchesPromise);
458
- }
459
- }
460
- else if (FilterUtility.isRangeFilter(propertyFilter)) {
461
- // `propertyFilter` is a `RangeFilter`
462
- const rangeMatchesPromise = this.filterRangeMatches(tenant, propertyName, propertyFilter, levelOptions);
463
- filterPromises.push(rangeMatchesPromise);
464
- }
358
+ *
359
+ * Sub-queries (exact match, range, OneOf) are executed sequentially to avoid opening
360
+ * multiple concurrent IndexedDB cursors. Firefox's IDB implementation intermittently
361
+ * drops results when cursors overlap see https://github.com/enboxorg/enbox/issues/264
362
+ */
363
+ async executeSingleFilterQuery(tenant, filter, sortProperty, matches, levelOptions) {
364
+ // Collects results from each sub-query sequentially to avoid concurrent IndexedDB cursor races in Firefox.
365
+ const processResults = (indexItems) => {
366
+ for (const indexedItem of indexItems) {
367
+ // short circuit: if a data is already included to the final matched key set (by a different `Filter`),
368
+ // no need to evaluate if the data satisfies this current filter being evaluated
369
+ // otherwise check that the item is a match.
370
+ if (matches.has(indexedItem.messageCid) || !FilterUtility.matchFilter(indexedItem.indexes, filter)) {
371
+ continue;
372
+ }
373
+ // ensure that each matched item has the sortProperty, otherwise fail the entire query.
374
+ if (indexedItem.indexes[sortProperty] === undefined) {
375
+ throw new DwnError(DwnErrorCode.IndexInvalidSortPropertyInMemory, `invalid sort property ${sortProperty}`);
376
+ }
377
+ matches.set(indexedItem.messageCid, indexedItem);
465
378
  }
466
- // acting as an OR match for the property, any of the promises returning a match will be treated as a property match
467
- for (const promise of filterPromises) {
468
- const indexItems = yield promise;
469
- // reminder: the promise returns a list of IndexedItem satisfying a particular property match
470
- for (const indexedItem of indexItems) {
471
- // short circuit: if a data is already included to the final matched key set (by a different `Filter`),
472
- // no need to evaluate if the data satisfies this current filter being evaluated
473
- // otherwise check that the item is a match.
474
- if (matches.has(indexedItem.messageCid) || !FilterUtility.matchFilter(indexedItem.indexes, filter)) {
475
- continue;
476
- }
477
- // ensure that each matched item has the sortProperty, otherwise fail the entire query.
478
- if (indexedItem.indexes[sortProperty] === undefined) {
479
- throw new DwnError(DwnErrorCode.IndexInvalidSortPropertyInMemory, `invalid sort property ${sortProperty}`);
480
- }
481
- matches.set(indexedItem.messageCid, indexedItem);
482
- }
379
+ };
380
+ // If the filter is empty, then we just iterate over one of the indexes that contains all the records and return all items.
381
+ if (isEmptyObject(filter)) {
382
+ const allItems = await this.getAllItems(tenant, sortProperty);
383
+ processResults(allItems);
384
+ return;
385
+ }
386
+ // else the filter is not empty
387
+ const searchFilter = FilterSelector.reduceFilter(filter);
388
+ for (const propertyName in searchFilter) {
389
+ const propertyFilter = searchFilter[propertyName];
390
+ // We will find the union of these many individual queries later.
391
+ if (FilterUtility.isEqualFilter(propertyFilter)) {
392
+ // propertyFilter is an EqualFilter, meaning it is a non-object primitive type
393
+ const exactMatches = await this.filterExactMatches(tenant, propertyName, propertyFilter, levelOptions);
394
+ processResults(exactMatches);
395
+ }
396
+ else if (FilterUtility.isOneOfFilter(propertyFilter)) {
397
+ // `propertyFilter` is a OneOfFilter
398
+ // Support OR matches by querying for each value separately and sequentially.
399
+ for (const propertyValue of new Set(propertyFilter)) {
400
+ const exactMatches = await this.filterExactMatches(tenant, propertyName, propertyValue, levelOptions);
401
+ processResults(exactMatches);
402
+ }
403
+ }
404
+ else if (FilterUtility.isRangeFilter(propertyFilter)) {
405
+ // `propertyFilter` is a `RangeFilter`
406
+ const rangeMatches = await this.filterRangeMatches(tenant, propertyName, propertyFilter, levelOptions);
407
+ processResults(rangeMatches);
483
408
  }
484
- });
409
+ }
485
410
  }
486
- getAllItems(tenant, sortProperty) {
487
- return __awaiter(this, void 0, void 0, function* () {
488
- var _a, e_3, _b, _c;
489
- const filterPartition = yield this.getIndexPartition(tenant, sortProperty);
490
- const items = [];
491
- try {
492
- for (var _d = true, _e = __asyncValues(filterPartition.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
493
- _c = _f.value;
494
- _d = false;
495
- const [_key, value] = _c;
496
- items.push(JSON.parse(value));
497
- }
498
- }
499
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
500
- finally {
501
- try {
502
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
503
- }
504
- finally { if (e_3) throw e_3.error; }
505
- }
506
- return items;
507
- });
411
+ async getAllItems(tenant, sortProperty) {
412
+ const filterPartition = await this.getIndexPartition(tenant, sortProperty);
413
+ const items = [];
414
+ for await (const [_key, value] of filterPartition.iterator()) {
415
+ items.push(JSON.parse(value));
416
+ }
417
+ return items;
508
418
  }
509
419
  /**
510
420
  * Returns items that match the exact property and value.
511
421
  */
512
- filterExactMatches(tenant, propertyName, propertyValue, options) {
513
- return __awaiter(this, void 0, void 0, function* () {
514
- var _a, e_4, _b, _c;
515
- const matchPrefix = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(propertyValue));
516
- const iteratorOptions = {
517
- gt: matchPrefix
518
- };
519
- const filterPartition = yield this.getIndexPartition(tenant, propertyName);
520
- const matches = [];
521
- try {
522
- for (var _d = true, _e = __asyncValues(filterPartition.iterator(iteratorOptions, options)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
523
- _c = _f.value;
524
- _d = false;
525
- const [key, value] = _c;
526
- // immediately stop if we arrive at an index that contains a different property value
527
- if (!key.startsWith(matchPrefix)) {
528
- break;
529
- }
530
- matches.push(JSON.parse(value));
531
- }
532
- }
533
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
534
- finally {
535
- try {
536
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
537
- }
538
- finally { if (e_4) throw e_4.error; }
539
- }
540
- return matches;
541
- });
422
+ async filterExactMatches(tenant, propertyName, propertyValue, options) {
423
+ const matchPrefix = IndexLevel.keySegmentJoin(IndexLevel.encodeValue(propertyValue));
424
+ const iteratorOptions = {
425
+ gt: matchPrefix
426
+ };
427
+ const filterPartition = await this.getIndexPartition(tenant, propertyName);
428
+ const matches = [];
429
+ for await (const [key, value] of filterPartition.iterator(iteratorOptions, options)) {
430
+ // immediately stop if we arrive at an index that contains a different property value
431
+ if (!key.startsWith(matchPrefix)) {
432
+ break;
433
+ }
434
+ matches.push(JSON.parse(value));
435
+ }
436
+ return matches;
542
437
  }
543
438
  /**
544
439
  * Returns items that match the range filter.
@@ -547,51 +442,36 @@ export class IndexLevel {
547
442
  * of the form `<encodedValue>\x00<messageCid>` are naturally included in the range scan,
548
443
  * eliminating the need for a separate exact-match query.
549
444
  */
550
- filterRangeMatches(tenant, propertyName, rangeFilter, options) {
551
- return __awaiter(this, void 0, void 0, function* () {
552
- var _a, e_5, _b, _c;
553
- const iteratorOptions = {};
554
- for (const comparator in rangeFilter) {
555
- const comparatorName = comparator;
556
- const encodedValue = IndexLevel.encodeValue(rangeFilter[comparatorName]);
557
- if (comparatorName === 'lte') {
558
- // Extend the lte bound so that composite keys `<encodedValue>\x00<messageCid>` are included.
559
- // Since \x00 < \xff, any key starting with encodedValue followed by the \x00 delimiter
560
- // will be lexicographically less than encodedValue + \xff.
561
- iteratorOptions[comparatorName] = encodedValue + '\xff';
562
- }
563
- else {
564
- iteratorOptions[comparatorName] = encodedValue;
565
- }
566
- }
567
- // if there is no lower bound specified (`gt` or `gte`), we need to iterate from the upper bound,
568
- // so that we will iterate over all the matches before hitting mismatches.
569
- if (iteratorOptions.gt === undefined && iteratorOptions.gte === undefined) {
570
- iteratorOptions.reverse = true;
445
+ async filterRangeMatches(tenant, propertyName, rangeFilter, options) {
446
+ const iteratorOptions = {};
447
+ for (const comparator in rangeFilter) {
448
+ const comparatorName = comparator;
449
+ const encodedValue = IndexLevel.encodeValue(rangeFilter[comparatorName]);
450
+ if (comparatorName === 'lte') {
451
+ // Extend the lte bound so that composite keys `<encodedValue>\x00<messageCid>` are included.
452
+ // Since \x00 < \xff, any key starting with encodedValue followed by the \x00 delimiter
453
+ // will be lexicographically less than encodedValue + \xff.
454
+ iteratorOptions[comparatorName] = encodedValue + '\xff';
571
455
  }
572
- const matches = [];
573
- const filterPartition = yield this.getIndexPartition(tenant, propertyName);
574
- try {
575
- for (var _d = true, _e = __asyncValues(filterPartition.iterator(iteratorOptions, options)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
576
- _c = _f.value;
577
- _d = false;
578
- const [key, value] = _c;
579
- // if "greater-than" is specified, skip all keys that contain the exact value given in the "greater-than" condition
580
- if ('gt' in rangeFilter && this.extractIndexValueFromKey(key) === IndexLevel.encodeValue(rangeFilter.gt)) {
581
- continue;
582
- }
583
- matches.push(JSON.parse(value));
584
- }
456
+ else {
457
+ iteratorOptions[comparatorName] = encodedValue;
585
458
  }
586
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
587
- finally {
588
- try {
589
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
590
- }
591
- finally { if (e_5) throw e_5.error; }
459
+ }
460
+ // if there is no lower bound specified (`gt` or `gte`), we need to iterate from the upper bound,
461
+ // so that we will iterate over all the matches before hitting mismatches.
462
+ if (iteratorOptions.gt === undefined && iteratorOptions.gte === undefined) {
463
+ iteratorOptions.reverse = true;
464
+ }
465
+ const matches = [];
466
+ const filterPartition = await this.getIndexPartition(tenant, propertyName);
467
+ for await (const [key, value] of filterPartition.iterator(iteratorOptions, options)) {
468
+ // if "greater-than" is specified, skip all keys that contain the exact value given in the "greater-than" condition
469
+ if ('gt' in rangeFilter && this.extractIndexValueFromKey(key) === IndexLevel.encodeValue(rangeFilter.gt)) {
470
+ continue;
592
471
  }
593
- return matches;
594
- });
472
+ matches.push(JSON.parse(value));
473
+ }
474
+ return matches;
595
475
  }
596
476
  /**
597
477
  * Sorts Items lexicographically in ascending or descending order given a specific indexName, using the messageCid as a tie breaker.
@@ -639,16 +519,14 @@ export class IndexLevel {
639
519
  /**
640
520
  * Gets the indexes given an messageCid. This is a reverse lookup to construct starting keys, as well as deleting indexed items.
641
521
  */
642
- getIndexes(tenant, messageCid) {
643
- return __awaiter(this, void 0, void 0, function* () {
644
- const indexesLookupPartition = yield this.getIndexesLookupPartition(tenant);
645
- const serializedIndexes = yield indexesLookupPartition.get(messageCid);
646
- if (serializedIndexes === undefined) {
647
- // invalid messageCid
648
- return;
649
- }
650
- return JSON.parse(serializedIndexes);
651
- });
522
+ async getIndexes(tenant, messageCid) {
523
+ const indexesLookupPartition = await this.getIndexesLookupPartition(tenant);
524
+ const serializedIndexes = await indexesLookupPartition.get(messageCid);
525
+ if (serializedIndexes === undefined) {
526
+ // invalid messageCid
527
+ return;
528
+ }
529
+ return JSON.parse(serializedIndexes);
652
530
  }
653
531
  /**
654
532
  * Given a key from an indexed partitioned property key.
@@ -660,6 +538,10 @@ export class IndexLevel {
660
538
  const [value] = key.split(IndexLevel.delimiter);
661
539
  return value;
662
540
  }
541
+ /**
542
+ * Joins the given values using the `\x00` (\u0000) character.
543
+ */
544
+ static delimiter = `\x00`;
663
545
  static keySegmentJoin(...values) {
664
546
  return values.join(IndexLevel.delimiter);
665
547
  }
@@ -694,292 +576,6 @@ export class IndexLevel {
694
576
  }
695
577
  }
696
578
  // =========================================================================
697
- // Compound index methods
698
- // =========================================================================
699
- /**
700
- * Gets the compound index partition for a given compound index definition.
701
- * Compound index sublevels use the naming convention `__compound:<name>__`.
702
- */
703
- getCompoundIndexPartition(tenant, compoundIndex) {
704
- return __awaiter(this, void 0, void 0, function* () {
705
- const partitionName = `__compound:${compoundIndex.name}__`;
706
- return (yield this.db.partition(tenant)).partition(partitionName);
707
- });
708
- }
709
- /**
710
- * Builds a compound index key from the given indexes and compound index definition.
711
- *
712
- * Key format: `<prop1>\x01<prop2>\x01...\x01<sortValue>\x00<messageCid>`
713
- *
714
- * @returns the compound key, or undefined if the indexes don't contain all required properties.
715
- */
716
- static buildCompoundKey(messageCid, indexes, compoundIndex) {
717
- const segments = [];
718
- for (const property of compoundIndex.properties) {
719
- const value = indexes[property];
720
- if (value === undefined || Array.isArray(value)) {
721
- return undefined; // compound indexes don't support array values or missing properties
722
- }
723
- segments.push(IndexLevel.encodeValue(value));
724
- }
725
- const sortValue = indexes[compoundIndex.sortProperty];
726
- if (sortValue === undefined || Array.isArray(sortValue)) {
727
- return undefined;
728
- }
729
- // join prefix segments with \x01, then append sort value and messageCid with the standard delimiters
730
- const prefixPart = segments.join(COMPOUND_SEGMENT_SEPARATOR);
731
- const sortPart = IndexLevel.encodeValue(sortValue);
732
- return prefixPart + COMPOUND_SEGMENT_SEPARATOR + sortPart + IndexLevel.delimiter + messageCid;
733
- }
734
- /**
735
- * Builds the prefix portion of a compound key from filter values (without the sort/messageCid suffix).
736
- * Used for range scans: all entries with this prefix match the filter.
737
- */
738
- static buildCompoundPrefix(filter, compoundIndex) {
739
- const segments = [];
740
- for (const property of compoundIndex.properties) {
741
- const filterValue = filter[property];
742
- if (filterValue === undefined || typeof filterValue === 'object') {
743
- return undefined; // compound prefix only works with equality filters
744
- }
745
- segments.push(IndexLevel.encodeValue(filterValue));
746
- }
747
- return segments.join(COMPOUND_SEGMENT_SEPARATOR) + COMPOUND_SEGMENT_SEPARATOR;
748
- }
749
- /**
750
- * Creates a put operation for a compound index entry.
751
- * Returns undefined if the indexes don't contain all required compound index properties.
752
- */
753
- createCompoundIndexPutOperation(tenant, item, compoundIndex) {
754
- const key = IndexLevel.buildCompoundKey(item.messageCid, item.indexes, compoundIndex);
755
- if (key === undefined) {
756
- return undefined;
757
- }
758
- return this.createOperationForPartition(tenant, `__compound:${compoundIndex.name}__`, {
759
- type: 'put',
760
- key,
761
- value: JSON.stringify(item),
762
- });
763
- }
764
- /**
765
- * Creates a delete operation for a compound index entry.
766
- * Returns undefined if the indexes don't contain all required compound index properties.
767
- */
768
- createCompoundIndexDeleteOperation(tenant, messageCid, indexes, compoundIndex) {
769
- const key = IndexLevel.buildCompoundKey(messageCid, indexes, compoundIndex);
770
- if (key === undefined) {
771
- return undefined;
772
- }
773
- return this.createOperationForPartition(tenant, `__compound:${compoundIndex.name}__`, {
774
- type: 'del',
775
- key,
776
- });
777
- }
778
- /**
779
- * Generic helper to create a batch operation for any named partition under a tenant.
780
- */
781
- createOperationForPartition(tenant, partitionName, operation) {
782
- return __awaiter(this, void 0, void 0, function* () {
783
- const tenantPartition = yield this.db.partition(tenant);
784
- return tenantPartition.createPartitionOperation(partitionName, operation);
785
- });
786
- }
787
- /**
788
- * Selects the best compound index that covers the given filter and sort requirements.
789
- *
790
- * A compound index "covers" a query when:
791
- * 1. Every property in the compound index definition is present in the filter as an equality filter.
792
- * 2. The compound index's sort property matches the query's sort property.
793
- *
794
- * Among multiple matching compound indexes, the one with the most properties is preferred
795
- * (more specific = fewer false positives in the prefix scan).
796
- */
797
- selectCompoundIndex(filter, queryOptions) {
798
- let bestMatch;
799
- let bestPropertyCount = 0;
800
- for (const compoundIndex of this._compoundIndexes) {
801
- // check that the sort property matches
802
- if (compoundIndex.sortProperty !== queryOptions.sortProperty) {
803
- continue;
804
- }
805
- // check that all compound properties are present in the filter as equality filters
806
- let allPropertiesMatch = true;
807
- for (const property of compoundIndex.properties) {
808
- const filterValue = filter[property];
809
- if (filterValue === undefined || typeof filterValue === 'object') {
810
- allPropertiesMatch = false;
811
- break;
812
- }
813
- }
814
- if (allPropertiesMatch && compoundIndex.properties.length > bestPropertyCount) {
815
- bestMatch = compoundIndex;
816
- bestPropertyCount = compoundIndex.properties.length;
817
- }
818
- }
819
- return bestMatch;
820
- }
821
- /**
822
- * Queries using a compound index. This is the most efficient query strategy: a single LevelDB
823
- * range scan that filters, sorts, and paginates all at once.
824
- *
825
- * The compound key encodes the filter properties as a prefix and the sort property as a suffix,
826
- * so iterating over keys with the filter prefix yields results in sort order.
827
- *
828
- * Any remaining filter properties not covered by the compound index are verified in memory.
829
- */
830
- queryWithCompoundIndex(tenant, filter, queryOptions, compoundIndex, options) {
831
- return __awaiter(this, void 0, void 0, function* () {
832
- var _a, e_6, _b, _c;
833
- const { sortDirection = SortDirection.Ascending, cursor, limit } = queryOptions;
834
- const prefix = IndexLevel.buildCompoundPrefix(filter, compoundIndex);
835
- if (prefix === undefined) {
836
- // should not happen since selectCompoundIndex already validated, but guard against it
837
- return this.queryWithIteratorPaging(tenant, [filter], queryOptions, options);
838
- }
839
- const partition = yield this.getCompoundIndexPartition(tenant, compoundIndex);
840
- // determine the iterator bounds from the prefix
841
- const iteratorOptions = {};
842
- if (cursor !== undefined) {
843
- // build the full compound key for the cursor position
844
- const cursorSortEncoded = IndexLevel.encodeValue(cursor.value);
845
- const cursorKey = prefix + cursorSortEncoded + IndexLevel.delimiter + cursor.messageCid;
846
- if (sortDirection === SortDirection.Ascending) {
847
- iteratorOptions.gt = cursorKey;
848
- // upper bound: everything with this prefix (prefix + \xff is past all valid compound keys with this prefix)
849
- iteratorOptions.lt = prefix + '\xff';
850
- }
851
- else {
852
- iteratorOptions.lt = cursorKey;
853
- iteratorOptions.gt = prefix;
854
- iteratorOptions.reverse = true;
855
- }
856
- }
857
- else {
858
- if (sortDirection === SortDirection.Ascending) {
859
- iteratorOptions.gt = prefix;
860
- iteratorOptions.lt = prefix + '\xff';
861
- }
862
- else {
863
- // for descending without cursor, start from the end of the prefix range
864
- iteratorOptions.gt = prefix;
865
- iteratorOptions.lt = prefix + '\xff';
866
- iteratorOptions.reverse = true;
867
- }
868
- }
869
- // determine which filter properties are NOT covered by the compound index
870
- // (need in-memory verification for these)
871
- // NOTE: the compound index equality properties are fully covered by the prefix scan,
872
- // but the sort property is only covered for ordering — any range filter on the sort
873
- // property must still be applied as a residual filter.
874
- const coveredEqualityProperties = new Set(compoundIndex.properties);
875
- const residualFilter = {};
876
- let hasResidualFilter = false;
877
- for (const property in filter) {
878
- if (!coveredEqualityProperties.has(property)) {
879
- residualFilter[property] = filter[property];
880
- hasResidualFilter = true;
881
- }
882
- }
883
- const matches = [];
884
- try {
885
- for (var _d = true, _e = __asyncValues(partition.iterator(iteratorOptions, options)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
886
- _c = _f.value;
887
- _d = false;
888
- const [_key, value] = _c;
889
- if (limit !== undefined && matches.length === limit) {
890
- break;
891
- }
892
- const item = JSON.parse(value);
893
- // verify any residual filter properties in memory
894
- if (hasResidualFilter && !FilterUtility.matchFilter(item.indexes, residualFilter)) {
895
- continue;
896
- }
897
- matches.push(item);
898
- }
899
- }
900
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
901
- finally {
902
- try {
903
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
904
- }
905
- finally { if (e_6) throw e_6.error; }
906
- }
907
- return matches;
908
- });
909
- }
910
- /**
911
- * Counts items matching a compound index prefix without loading full records.
912
- * Iterates only keys (not values) for maximum efficiency.
913
- */
914
- countWithCompoundIndex(tenant, filter, compoundIndex, options) {
915
- return __awaiter(this, void 0, void 0, function* () {
916
- var _a, e_7, _b, _c, _d, e_8, _e, _f;
917
- const prefix = IndexLevel.buildCompoundPrefix(filter, compoundIndex);
918
- if (prefix === undefined) {
919
- // fallback
920
- const results = yield this.query(tenant, [filter], { sortProperty: compoundIndex.sortProperty }, options);
921
- return results.length;
922
- }
923
- const partition = yield this.getCompoundIndexPartition(tenant, compoundIndex);
924
- // determine which filter properties are NOT covered by the compound index
925
- // (same logic as queryWithCompoundIndex: sort property range filters are residual)
926
- const coveredEqualityProperties = new Set(compoundIndex.properties);
927
- let hasResidualFilter = false;
928
- const residualFilter = {};
929
- for (const property in filter) {
930
- if (!coveredEqualityProperties.has(property)) {
931
- residualFilter[property] = filter[property];
932
- hasResidualFilter = true;
933
- }
934
- }
935
- const iteratorOptions = {
936
- gt: prefix,
937
- lt: prefix + '\xff',
938
- };
939
- let count = 0;
940
- if (hasResidualFilter) {
941
- try {
942
- // must read values to check residual filter
943
- for (var _g = true, _h = __asyncValues(partition.iterator(iteratorOptions, options)), _j; _j = yield _h.next(), _a = _j.done, !_a; _g = true) {
944
- _c = _j.value;
945
- _g = false;
946
- const [_key, value] = _c;
947
- const item = JSON.parse(value);
948
- if (FilterUtility.matchFilter(item.indexes, residualFilter)) {
949
- count++;
950
- }
951
- }
952
- }
953
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
954
- finally {
955
- try {
956
- if (!_g && !_a && (_b = _h.return)) yield _b.call(_h);
957
- }
958
- finally { if (e_7) throw e_7.error; }
959
- }
960
- }
961
- else {
962
- try {
963
- // no residual filter — iterate keys via iterator without parsing values
964
- for (var _k = true, _l = __asyncValues(partition.iterator(iteratorOptions, options)), _m; _m = yield _l.next(), _d = _m.done, !_d; _k = true) {
965
- _f = _m.value;
966
- _k = false;
967
- const [_key, _value] = _f;
968
- count++;
969
- }
970
- }
971
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
972
- finally {
973
- try {
974
- if (!_k && !_d && (_e = _l.return)) yield _e.call(_l);
975
- }
976
- finally { if (e_8) throw e_8.error; }
977
- }
978
- }
979
- return count;
980
- });
981
- }
982
- // =========================================================================
983
579
  // Query strategy selection
984
580
  // =========================================================================
985
581
  static shouldQueryWithInMemoryPaging(filters, queryOptions) {
@@ -1011,8 +607,4 @@ export class IndexLevel {
1011
607
  return false;
1012
608
  }
1013
609
  }
1014
- /**
1015
- * Joins the given values using the `\x00` (\u0000) character.
1016
- */
1017
- IndexLevel.delimiter = `\x00`;
1018
610
  //# sourceMappingURL=index-level.js.map