@connecttomahdi/rxdb 17.0.0-beta.17 → 17.1.0

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 (379) hide show
  1. package/AGENTS.md +4 -0
  2. package/CHANGELOG.md +47 -4
  3. package/CLAUDE.md +2 -0
  4. package/dist/cjs/change-event-buffer.js +2 -1
  5. package/dist/cjs/change-event-buffer.js.map +1 -1
  6. package/dist/cjs/custom-index.js +85 -12
  7. package/dist/cjs/custom-index.js.map +1 -1
  8. package/dist/cjs/doc-cache.js +117 -35
  9. package/dist/cjs/doc-cache.js.map +1 -1
  10. package/dist/cjs/event-reduce.js +10 -1
  11. package/dist/cjs/event-reduce.js.map +1 -1
  12. package/dist/cjs/plugin-helpers.js +16 -0
  13. package/dist/cjs/plugin-helpers.js.map +1 -1
  14. package/dist/cjs/plugins/attachments/index.js +3 -3
  15. package/dist/cjs/plugins/attachments/index.js.map +1 -1
  16. package/dist/cjs/plugins/cleanup/cleanup.js +5 -3
  17. package/dist/cjs/plugins/cleanup/cleanup.js.map +1 -1
  18. package/dist/cjs/plugins/crdt/index.js +52 -0
  19. package/dist/cjs/plugins/crdt/index.js.map +1 -1
  20. package/dist/cjs/plugins/dev-mode/check-query.js +7 -1
  21. package/dist/cjs/plugins/dev-mode/check-query.js.map +1 -1
  22. package/dist/cjs/plugins/dev-mode/check-schema.js +2 -1
  23. package/dist/cjs/plugins/dev-mode/check-schema.js.map +1 -1
  24. package/dist/cjs/plugins/dev-mode/error-messages.js +43 -5
  25. package/dist/cjs/plugins/dev-mode/error-messages.js.map +1 -1
  26. package/dist/cjs/plugins/encryption-crypto-js/index.js +22 -6
  27. package/dist/cjs/plugins/encryption-crypto-js/index.js.map +1 -1
  28. package/dist/cjs/plugins/leader-election/index.js +5 -5
  29. package/dist/cjs/plugins/leader-election/index.js.map +1 -1
  30. package/dist/cjs/plugins/local-documents/local-documents.js +20 -13
  31. package/dist/cjs/plugins/local-documents/local-documents.js.map +1 -1
  32. package/dist/cjs/plugins/migration-schema/migration-helpers.js +3 -0
  33. package/dist/cjs/plugins/migration-schema/migration-helpers.js.map +1 -1
  34. package/dist/cjs/plugins/migration-schema/rx-migration-state.js +1 -1
  35. package/dist/cjs/plugins/migration-schema/rx-migration-state.js.map +1 -1
  36. package/dist/cjs/plugins/pipeline/rx-pipeline.js +5 -1
  37. package/dist/cjs/plugins/pipeline/rx-pipeline.js.map +1 -1
  38. package/dist/cjs/plugins/query-builder/mquery/nosql-query-builder.js +4 -2
  39. package/dist/cjs/plugins/query-builder/mquery/nosql-query-builder.js.map +1 -1
  40. package/dist/cjs/plugins/replication/index.js +40 -2
  41. package/dist/cjs/plugins/replication/index.js.map +1 -1
  42. package/dist/cjs/plugins/replication-google-drive/document-handling.js +17 -6
  43. package/dist/cjs/plugins/replication-google-drive/document-handling.js.map +1 -1
  44. package/dist/cjs/plugins/replication-google-drive/google-drive-helper.js +1 -1
  45. package/dist/cjs/plugins/replication-google-drive/google-drive-helper.js.map +1 -1
  46. package/dist/cjs/plugins/replication-google-drive/google-drive-types.js.map +1 -1
  47. package/dist/cjs/plugins/replication-google-drive/signaling.js +4 -1
  48. package/dist/cjs/plugins/replication-google-drive/signaling.js.map +1 -1
  49. package/dist/cjs/plugins/replication-google-drive/upstream.js +7 -4
  50. package/dist/cjs/plugins/replication-google-drive/upstream.js.map +1 -1
  51. package/dist/cjs/plugins/replication-microsoft-onedrive/signaling.js +4 -1
  52. package/dist/cjs/plugins/replication-microsoft-onedrive/signaling.js.map +1 -1
  53. package/dist/cjs/plugins/state/rx-state.js +14 -3
  54. package/dist/cjs/plugins/state/rx-state.js.map +1 -1
  55. package/dist/cjs/plugins/storage-dexie/rx-storage-instance-dexie.js +10 -17
  56. package/dist/cjs/plugins/storage-dexie/rx-storage-instance-dexie.js.map +1 -1
  57. package/dist/cjs/plugins/storage-memory/binary-search-bounds.js +112 -40
  58. package/dist/cjs/plugins/storage-memory/binary-search-bounds.js.map +1 -1
  59. package/dist/cjs/plugins/storage-memory/memory-helper.js +127 -40
  60. package/dist/cjs/plugins/storage-memory/memory-helper.js.map +1 -1
  61. package/dist/cjs/plugins/storage-memory/memory-indexes.js +1 -0
  62. package/dist/cjs/plugins/storage-memory/memory-indexes.js.map +1 -1
  63. package/dist/cjs/plugins/storage-memory/memory-types.js.map +1 -1
  64. package/dist/cjs/plugins/storage-memory/rx-storage-instance-memory.js +97 -37
  65. package/dist/cjs/plugins/storage-memory/rx-storage-instance-memory.js.map +1 -1
  66. package/dist/cjs/plugins/storage-mongodb/mongodb-helper.js +42 -1
  67. package/dist/cjs/plugins/storage-mongodb/mongodb-helper.js.map +1 -1
  68. package/dist/cjs/plugins/storage-mongodb/rx-storage-instance-mongodb.js +7 -7
  69. package/dist/cjs/plugins/storage-mongodb/rx-storage-instance-mongodb.js.map +1 -1
  70. package/dist/cjs/plugins/test-utils/config.js +1 -1
  71. package/dist/cjs/plugins/test-utils/config.js.map +1 -1
  72. package/dist/cjs/plugins/test-utils/performance.js +122 -92
  73. package/dist/cjs/plugins/test-utils/performance.js.map +1 -1
  74. package/dist/cjs/plugins/test-utils/schema-objects.js +1 -1
  75. package/dist/cjs/plugins/test-utils/schema-objects.js.map +1 -1
  76. package/dist/cjs/plugins/test-utils/test-util.js +62 -0
  77. package/dist/cjs/plugins/test-utils/test-util.js.map +1 -1
  78. package/dist/cjs/plugins/utils/utils-map.js +2 -2
  79. package/dist/cjs/plugins/utils/utils-map.js.map +1 -1
  80. package/dist/cjs/plugins/utils/utils-object-deep-equal.js +3 -2
  81. package/dist/cjs/plugins/utils/utils-object-deep-equal.js.map +1 -1
  82. package/dist/cjs/plugins/utils/utils-object-dot-prop.js +25 -0
  83. package/dist/cjs/plugins/utils/utils-object-dot-prop.js.map +1 -1
  84. package/dist/cjs/plugins/utils/utils-object.js +102 -27
  85. package/dist/cjs/plugins/utils/utils-object.js.map +1 -1
  86. package/dist/cjs/plugins/utils/utils-other.js +9 -4
  87. package/dist/cjs/plugins/utils/utils-other.js.map +1 -1
  88. package/dist/cjs/plugins/utils/utils-premium.js +1 -19
  89. package/dist/cjs/plugins/utils/utils-premium.js.map +1 -1
  90. package/dist/cjs/plugins/utils/utils-revision.js +20 -10
  91. package/dist/cjs/plugins/utils/utils-revision.js.map +1 -1
  92. package/dist/cjs/plugins/utils/utils-rxdb-version.js +1 -1
  93. package/dist/cjs/plugins/utils/utils-rxdb-version.js.map +1 -1
  94. package/dist/cjs/plugins/utils/utils-string.js +11 -8
  95. package/dist/cjs/plugins/utils/utils-string.js.map +1 -1
  96. package/dist/cjs/plugins/utils/utils-time.js +21 -16
  97. package/dist/cjs/plugins/utils/utils-time.js.map +1 -1
  98. package/dist/cjs/query-cache.js +6 -4
  99. package/dist/cjs/query-cache.js.map +1 -1
  100. package/dist/cjs/query-planner.js +2 -2
  101. package/dist/cjs/query-planner.js.map +1 -1
  102. package/dist/cjs/replication-protocol/downstream.js +1 -1
  103. package/dist/cjs/replication-protocol/downstream.js.map +1 -1
  104. package/dist/cjs/rx-collection-helper.js +11 -6
  105. package/dist/cjs/rx-collection-helper.js.map +1 -1
  106. package/dist/cjs/rx-collection.js +34 -6
  107. package/dist/cjs/rx-collection.js.map +1 -1
  108. package/dist/cjs/rx-database.js +40 -7
  109. package/dist/cjs/rx-database.js.map +1 -1
  110. package/dist/cjs/rx-document.js +10 -3
  111. package/dist/cjs/rx-document.js.map +1 -1
  112. package/dist/cjs/rx-query-helper.js +35 -12
  113. package/dist/cjs/rx-query-helper.js.map +1 -1
  114. package/dist/cjs/rx-query-single-result.js +9 -2
  115. package/dist/cjs/rx-query-single-result.js.map +1 -1
  116. package/dist/cjs/rx-query.js +72 -29
  117. package/dist/cjs/rx-query.js.map +1 -1
  118. package/dist/cjs/rx-schema-helper.js +9 -3
  119. package/dist/cjs/rx-schema-helper.js.map +1 -1
  120. package/dist/cjs/rx-schema.js +1 -0
  121. package/dist/cjs/rx-schema.js.map +1 -1
  122. package/dist/cjs/rx-storage-helper.js +212 -129
  123. package/dist/cjs/rx-storage-helper.js.map +1 -1
  124. package/dist/cjs/types/rx-error.d.js.map +1 -1
  125. package/dist/cjs/types/rx-schema.d.js.map +1 -1
  126. package/dist/esm/change-event-buffer.js +2 -1
  127. package/dist/esm/change-event-buffer.js.map +1 -1
  128. package/dist/esm/custom-index.js +85 -12
  129. package/dist/esm/custom-index.js.map +1 -1
  130. package/dist/esm/doc-cache.js +118 -36
  131. package/dist/esm/doc-cache.js.map +1 -1
  132. package/dist/esm/event-reduce.js +10 -1
  133. package/dist/esm/event-reduce.js.map +1 -1
  134. package/dist/esm/plugin-helpers.js +16 -0
  135. package/dist/esm/plugin-helpers.js.map +1 -1
  136. package/dist/esm/plugins/attachments/index.js +3 -3
  137. package/dist/esm/plugins/attachments/index.js.map +1 -1
  138. package/dist/esm/plugins/cleanup/cleanup.js +5 -3
  139. package/dist/esm/plugins/cleanup/cleanup.js.map +1 -1
  140. package/dist/esm/plugins/crdt/index.js +52 -0
  141. package/dist/esm/plugins/crdt/index.js.map +1 -1
  142. package/dist/esm/plugins/dev-mode/check-query.js +7 -1
  143. package/dist/esm/plugins/dev-mode/check-query.js.map +1 -1
  144. package/dist/esm/plugins/dev-mode/check-schema.js +2 -1
  145. package/dist/esm/plugins/dev-mode/check-schema.js.map +1 -1
  146. package/dist/esm/plugins/dev-mode/error-messages.js +43 -5
  147. package/dist/esm/plugins/dev-mode/error-messages.js.map +1 -1
  148. package/dist/esm/plugins/encryption-crypto-js/index.js +22 -6
  149. package/dist/esm/plugins/encryption-crypto-js/index.js.map +1 -1
  150. package/dist/esm/plugins/leader-election/index.js +4 -4
  151. package/dist/esm/plugins/leader-election/index.js.map +1 -1
  152. package/dist/esm/plugins/local-documents/local-documents.js +20 -13
  153. package/dist/esm/plugins/local-documents/local-documents.js.map +1 -1
  154. package/dist/esm/plugins/migration-schema/migration-helpers.js +3 -0
  155. package/dist/esm/plugins/migration-schema/migration-helpers.js.map +1 -1
  156. package/dist/esm/plugins/migration-schema/rx-migration-state.js +1 -1
  157. package/dist/esm/plugins/migration-schema/rx-migration-state.js.map +1 -1
  158. package/dist/esm/plugins/pipeline/rx-pipeline.js +5 -1
  159. package/dist/esm/plugins/pipeline/rx-pipeline.js.map +1 -1
  160. package/dist/esm/plugins/query-builder/mquery/nosql-query-builder.js +4 -2
  161. package/dist/esm/plugins/query-builder/mquery/nosql-query-builder.js.map +1 -1
  162. package/dist/esm/plugins/replication/index.js +40 -2
  163. package/dist/esm/plugins/replication/index.js.map +1 -1
  164. package/dist/esm/plugins/replication-google-drive/document-handling.js +17 -6
  165. package/dist/esm/plugins/replication-google-drive/document-handling.js.map +1 -1
  166. package/dist/esm/plugins/replication-google-drive/google-drive-helper.js +1 -1
  167. package/dist/esm/plugins/replication-google-drive/google-drive-helper.js.map +1 -1
  168. package/dist/esm/plugins/replication-google-drive/google-drive-types.js.map +1 -1
  169. package/dist/esm/plugins/replication-google-drive/signaling.js +4 -1
  170. package/dist/esm/plugins/replication-google-drive/signaling.js.map +1 -1
  171. package/dist/esm/plugins/replication-google-drive/upstream.js +7 -4
  172. package/dist/esm/plugins/replication-google-drive/upstream.js.map +1 -1
  173. package/dist/esm/plugins/replication-microsoft-onedrive/signaling.js +4 -1
  174. package/dist/esm/plugins/replication-microsoft-onedrive/signaling.js.map +1 -1
  175. package/dist/esm/plugins/state/rx-state.js +15 -4
  176. package/dist/esm/plugins/state/rx-state.js.map +1 -1
  177. package/dist/esm/plugins/storage-dexie/rx-storage-instance-dexie.js +11 -18
  178. package/dist/esm/plugins/storage-dexie/rx-storage-instance-dexie.js.map +1 -1
  179. package/dist/esm/plugins/storage-memory/binary-search-bounds.js +107 -40
  180. package/dist/esm/plugins/storage-memory/binary-search-bounds.js.map +1 -1
  181. package/dist/esm/plugins/storage-memory/memory-helper.js +128 -41
  182. package/dist/esm/plugins/storage-memory/memory-helper.js.map +1 -1
  183. package/dist/esm/plugins/storage-memory/memory-indexes.js +1 -0
  184. package/dist/esm/plugins/storage-memory/memory-indexes.js.map +1 -1
  185. package/dist/esm/plugins/storage-memory/memory-types.js.map +1 -1
  186. package/dist/esm/plugins/storage-memory/rx-storage-instance-memory.js +90 -30
  187. package/dist/esm/plugins/storage-memory/rx-storage-instance-memory.js.map +1 -1
  188. package/dist/esm/plugins/storage-mongodb/mongodb-helper.js +39 -0
  189. package/dist/esm/plugins/storage-mongodb/mongodb-helper.js.map +1 -1
  190. package/dist/esm/plugins/storage-mongodb/rx-storage-instance-mongodb.js +8 -8
  191. package/dist/esm/plugins/storage-mongodb/rx-storage-instance-mongodb.js.map +1 -1
  192. package/dist/esm/plugins/test-utils/config.js +1 -1
  193. package/dist/esm/plugins/test-utils/config.js.map +1 -1
  194. package/dist/esm/plugins/test-utils/performance.js +122 -92
  195. package/dist/esm/plugins/test-utils/performance.js.map +1 -1
  196. package/dist/esm/plugins/test-utils/schema-objects.js +1 -1
  197. package/dist/esm/plugins/test-utils/schema-objects.js.map +1 -1
  198. package/dist/esm/plugins/test-utils/test-util.js +59 -0
  199. package/dist/esm/plugins/test-utils/test-util.js.map +1 -1
  200. package/dist/esm/plugins/utils/utils-map.js +2 -2
  201. package/dist/esm/plugins/utils/utils-map.js.map +1 -1
  202. package/dist/esm/plugins/utils/utils-object-deep-equal.js +3 -2
  203. package/dist/esm/plugins/utils/utils-object-deep-equal.js.map +1 -1
  204. package/dist/esm/plugins/utils/utils-object-dot-prop.js +25 -0
  205. package/dist/esm/plugins/utils/utils-object-dot-prop.js.map +1 -1
  206. package/dist/esm/plugins/utils/utils-object.js +102 -27
  207. package/dist/esm/plugins/utils/utils-object.js.map +1 -1
  208. package/dist/esm/plugins/utils/utils-other.js +9 -4
  209. package/dist/esm/plugins/utils/utils-other.js.map +1 -1
  210. package/dist/esm/plugins/utils/utils-premium.js +1 -19
  211. package/dist/esm/plugins/utils/utils-premium.js.map +1 -1
  212. package/dist/esm/plugins/utils/utils-revision.js +20 -10
  213. package/dist/esm/plugins/utils/utils-revision.js.map +1 -1
  214. package/dist/esm/plugins/utils/utils-rxdb-version.js +1 -1
  215. package/dist/esm/plugins/utils/utils-rxdb-version.js.map +1 -1
  216. package/dist/esm/plugins/utils/utils-string.js +11 -8
  217. package/dist/esm/plugins/utils/utils-string.js.map +1 -1
  218. package/dist/esm/plugins/utils/utils-time.js +21 -16
  219. package/dist/esm/plugins/utils/utils-time.js.map +1 -1
  220. package/dist/esm/query-cache.js +7 -5
  221. package/dist/esm/query-cache.js.map +1 -1
  222. package/dist/esm/query-planner.js +2 -2
  223. package/dist/esm/query-planner.js.map +1 -1
  224. package/dist/esm/replication-protocol/downstream.js +1 -1
  225. package/dist/esm/replication-protocol/downstream.js.map +1 -1
  226. package/dist/esm/rx-collection-helper.js +12 -7
  227. package/dist/esm/rx-collection-helper.js.map +1 -1
  228. package/dist/esm/rx-collection.js +35 -7
  229. package/dist/esm/rx-collection.js.map +1 -1
  230. package/dist/esm/rx-database.js +40 -7
  231. package/dist/esm/rx-database.js.map +1 -1
  232. package/dist/esm/rx-document.js +11 -4
  233. package/dist/esm/rx-document.js.map +1 -1
  234. package/dist/esm/rx-query-helper.js +35 -12
  235. package/dist/esm/rx-query-helper.js.map +1 -1
  236. package/dist/esm/rx-query-single-result.js +10 -3
  237. package/dist/esm/rx-query-single-result.js.map +1 -1
  238. package/dist/esm/rx-query.js +72 -29
  239. package/dist/esm/rx-query.js.map +1 -1
  240. package/dist/esm/rx-schema-helper.js +9 -3
  241. package/dist/esm/rx-schema-helper.js.map +1 -1
  242. package/dist/esm/rx-schema.js +1 -0
  243. package/dist/esm/rx-schema.js.map +1 -1
  244. package/dist/esm/rx-storage-helper.js +176 -94
  245. package/dist/esm/rx-storage-helper.js.map +1 -1
  246. package/dist/esm/types/rx-error.d.js.map +1 -1
  247. package/dist/esm/types/rx-schema.d.js.map +1 -1
  248. package/dist/types/custom-index.d.ts +5 -0
  249. package/dist/types/doc-cache.d.ts +1 -1
  250. package/dist/types/index.d.ts +25 -26
  251. package/dist/types/plugins/dev-mode/error-messages.d.ts +36 -0
  252. package/dist/types/plugins/leader-election/index.d.ts +1 -0
  253. package/dist/types/plugins/replication-google-drive/document-handling.d.ts +4 -1
  254. package/dist/types/plugins/replication-google-drive/google-drive-types.d.ts +1 -0
  255. package/dist/types/plugins/state/rx-state.d.ts +1 -1
  256. package/dist/types/plugins/storage-denokv/index.d.ts +1 -1
  257. package/dist/types/plugins/storage-dexie/rx-storage-dexie.d.ts +1 -1
  258. package/dist/types/plugins/storage-localstorage/index.d.ts +1 -1
  259. package/dist/types/plugins/storage-memory/binary-search-bounds.d.ts +21 -10
  260. package/dist/types/plugins/storage-memory/memory-helper.d.ts +7 -3
  261. package/dist/types/plugins/storage-memory/memory-types.d.ts +5 -0
  262. package/dist/types/plugins/storage-mongodb/mongodb-helper.d.ts +9 -1
  263. package/dist/types/plugins/storage-mongodb/rx-storage-instance-mongodb.d.ts +2 -2
  264. package/dist/types/plugins/storage-mongodb/rx-storage-mongodb.d.ts +1 -1
  265. package/dist/types/plugins/storage-remote/rx-storage-remote.d.ts +1 -1
  266. package/dist/types/plugins/storage-sqlite/index.d.ts +1 -1
  267. package/dist/types/plugins/test-utils/performance.d.ts +36 -0
  268. package/dist/types/plugins/test-utils/test-util.d.ts +17 -0
  269. package/dist/types/plugins/utils/utils-object.d.ts +8 -3
  270. package/dist/types/plugins/utils/utils-premium.d.ts +0 -2
  271. package/dist/types/plugins/utils/utils-rxdb-version.d.ts +1 -1
  272. package/dist/types/rx-database.d.ts +1 -1
  273. package/dist/types/rx-query-single-result.d.ts +1 -1
  274. package/dist/types/rx-query.d.ts +3 -2
  275. package/dist/types/rx-storage-helper.d.ts +15 -0
  276. package/eslint.config.mjs +2 -1
  277. package/package.json +732 -729
  278. package/scripts/check-code-block-line-length.js +91 -0
  279. package/scripts/check-em-dashes.js +53 -0
  280. package/scripts/docs-fetch-git-history.mjs +36 -0
  281. package/scripts/install-foundationdb.sh +0 -6
  282. package/scripts/notify-indexnow.mjs +171 -0
  283. package/scripts/start-foundationdb-docker.sh +73 -0
  284. package/src/change-event-buffer.ts +4 -1
  285. package/src/custom-index.ts +93 -16
  286. package/src/doc-cache.ts +117 -41
  287. package/src/event-reduce.ts +10 -1
  288. package/src/plugin-helpers.ts +10 -0
  289. package/src/plugins/attachments/index.ts +10 -12
  290. package/src/plugins/cleanup/cleanup.ts +5 -3
  291. package/src/plugins/crdt/index.ts +55 -0
  292. package/src/plugins/dev-mode/check-query.ts +7 -1
  293. package/src/plugins/dev-mode/check-schema.ts +2 -1
  294. package/src/plugins/dev-mode/error-messages.ts +45 -5
  295. package/src/plugins/encryption-crypto-js/index.ts +18 -6
  296. package/src/plugins/leader-election/index.ts +9 -8
  297. package/src/plugins/local-documents/local-documents.ts +21 -12
  298. package/src/plugins/migration-schema/migration-helpers.ts +3 -0
  299. package/src/plugins/migration-schema/rx-migration-state.ts +1 -1
  300. package/src/plugins/pipeline/rx-pipeline.ts +5 -1
  301. package/src/plugins/query-builder/mquery/nosql-query-builder.ts +8 -2
  302. package/src/plugins/replication/index.ts +41 -3
  303. package/src/plugins/replication-google-drive/document-handling.ts +17 -5
  304. package/src/plugins/replication-google-drive/google-drive-helper.ts +1 -1
  305. package/src/plugins/replication-google-drive/google-drive-types.ts +1 -0
  306. package/src/plugins/replication-google-drive/signaling.ts +4 -1
  307. package/src/plugins/replication-google-drive/upstream.ts +7 -4
  308. package/src/plugins/replication-microsoft-onedrive/signaling.ts +4 -1
  309. package/src/plugins/state/rx-state.ts +17 -5
  310. package/src/plugins/storage-dexie/rx-storage-instance-dexie.ts +0 -27
  311. package/src/plugins/storage-memory/binary-search-bounds.ts +105 -40
  312. package/src/plugins/storage-memory/memory-helper.ts +158 -67
  313. package/src/plugins/storage-memory/memory-indexes.ts +1 -0
  314. package/src/plugins/storage-memory/memory-types.ts +5 -0
  315. package/src/plugins/storage-memory/rx-storage-instance-memory.ts +104 -53
  316. package/src/plugins/storage-mongodb/mongodb-helper.ts +43 -1
  317. package/src/plugins/storage-mongodb/rx-storage-instance-mongodb.ts +11 -9
  318. package/src/plugins/test-utils/config.ts +2 -1
  319. package/src/plugins/test-utils/performance.ts +159 -85
  320. package/src/plugins/test-utils/schema-objects.ts +1 -1
  321. package/src/plugins/test-utils/test-util.ts +71 -0
  322. package/src/plugins/utils/utils-map.ts +2 -2
  323. package/src/plugins/utils/utils-object-deep-equal.ts +2 -4
  324. package/src/plugins/utils/utils-object-dot-prop.ts +25 -0
  325. package/src/plugins/utils/utils-object.ts +103 -28
  326. package/src/plugins/utils/utils-other.ts +9 -4
  327. package/src/plugins/utils/utils-premium.ts +11 -37
  328. package/src/plugins/utils/utils-revision.ts +20 -9
  329. package/src/plugins/utils/utils-rxdb-version.ts +1 -1
  330. package/src/plugins/utils/utils-string.ts +11 -9
  331. package/src/plugins/utils/utils-time.ts +21 -17
  332. package/src/query-cache.ts +6 -5
  333. package/src/query-planner.ts +2 -2
  334. package/src/replication-protocol/downstream.ts +1 -1
  335. package/src/rx-collection-helper.ts +12 -6
  336. package/src/rx-collection.ts +39 -8
  337. package/src/rx-database.ts +49 -17
  338. package/src/rx-document.ts +12 -3
  339. package/src/rx-query-helper.ts +36 -15
  340. package/src/rx-query-single-result.ts +10 -3
  341. package/src/rx-query.ts +48 -8
  342. package/src/rx-schema-helper.ts +7 -4
  343. package/src/rx-schema.ts +1 -0
  344. package/src/rx-storage-helper.ts +210 -139
  345. package/src/types/rx-error.d.ts +3 -0
  346. package/src/types/rx-schema.d.ts +5 -0
  347. package/dist/esm/package.json +0 -1
  348. package/dist/types/types/conflict-handling.d.ts +0 -48
  349. package/dist/types/types/couchdb.d.ts +0 -293
  350. package/dist/types/types/index.d.ts +0 -32
  351. package/dist/types/types/modules/index.d.ts +0 -0
  352. package/dist/types/types/modules/mocha.parallel.d.ts +0 -1
  353. package/dist/types/types/plugins/backup.d.ts +0 -35
  354. package/dist/types/types/plugins/cleanup.d.ts +0 -38
  355. package/dist/types/types/plugins/crdt.d.ts +0 -76
  356. package/dist/types/types/plugins/dexie.d.ts +0 -30
  357. package/dist/types/types/plugins/local-documents.d.ts +0 -49
  358. package/dist/types/types/plugins/migration.d.ts +0 -14
  359. package/dist/types/types/plugins/reactivity.d.ts +0 -40
  360. package/dist/types/types/plugins/replication-graphql.d.ts +0 -98
  361. package/dist/types/types/plugins/replication.d.ts +0 -175
  362. package/dist/types/types/plugins/state.d.ts +0 -4
  363. package/dist/types/types/plugins/update.d.ts +0 -23
  364. package/dist/types/types/plugins/webmcp.d.ts +0 -40
  365. package/dist/types/types/query-planner.d.ts +0 -47
  366. package/dist/types/types/replication-protocol.d.ts +0 -296
  367. package/dist/types/types/rx-attachment.d.ts +0 -46
  368. package/dist/types/types/rx-change-event.d.ts +0 -85
  369. package/dist/types/types/rx-collection.d.ts +0 -117
  370. package/dist/types/types/rx-database-internal-store.d.ts +0 -54
  371. package/dist/types/types/rx-database.d.ts +0 -124
  372. package/dist/types/types/rx-document.d.ts +0 -160
  373. package/dist/types/types/rx-error.d.ts +0 -222
  374. package/dist/types/types/rx-plugin.d.ts +0 -167
  375. package/dist/types/types/rx-query.d.ts +0 -144
  376. package/dist/types/types/rx-schema.d.ts +0 -209
  377. package/dist/types/types/rx-storage.d.ts +0 -347
  378. package/dist/types/types/rx-storage.interface.d.ts +0 -312
  379. package/dist/types/types/util.d.ts +0 -180
@@ -60,24 +60,33 @@ export async function insertLocal<DocData extends Record<string, any> = any, Rea
60
60
  * save the local-document-data
61
61
  * overwrites existing if exists
62
62
  */
63
- export function upsertLocal<DocData extends Record<string, any> = any, Reactivity = unknown>(
63
+ export async function upsertLocal<DocData extends Record<string, any> = any, Reactivity = unknown>(
64
64
  this: any,
65
65
  id: string,
66
66
  data: DocData
67
67
  ): Promise<RxLocalDocument<DocData, any, Reactivity>> {
68
- return this.getLocal(id)
69
- .then((existing: RxDocument) => {
70
- if (!existing) {
71
- // create new one
72
- const docPromise = this.insertLocal(id, data);
73
- return docPromise;
74
- } else {
75
- // update existing
76
- return existing.incrementalModify(() => {
77
- return data;
78
- });
68
+ const existing = await this.getLocal(id);
69
+ if (!existing) {
70
+ // create new one
71
+ return this.insertLocal(id, data);
72
+ } else if (existing.deleted) {
73
+ // document was deleted before, un-delete it via the write queue
74
+ const state = await getLocalDocStateByParent(this);
75
+ const writeResult = await state.incrementalWriteQueue.addWrite(
76
+ (existing as any)._data,
77
+ (docData: any) => {
78
+ docData.data = data;
79
+ docData._deleted = false;
80
+ return docData;
79
81
  }
82
+ );
83
+ return state.docCache.getCachedRxDocument(writeResult) as any;
84
+ } else {
85
+ // update existing
86
+ return existing.incrementalModify(() => {
87
+ return data;
80
88
  });
89
+ }
81
90
  }
82
91
 
83
92
  export async function getLocal<DocData = any, Reactivity = unknown>(this: any, id: string): Promise<RxLocalDocument<DocData, any, Reactivity> | null> {
@@ -70,6 +70,8 @@ export function migrateDocumentData(
70
70
  const attachmentsBefore = flatClone(docData._attachments);
71
71
  const mutateableDocData = clone(docData);
72
72
  const meta = mutateableDocData._meta;
73
+ const deleted = mutateableDocData._deleted;
74
+ delete mutateableDocData._deleted;
73
75
  delete mutateableDocData._meta;
74
76
  mutateableDocData._attachments = attachmentsBefore;
75
77
 
@@ -95,6 +97,7 @@ export function migrateDocumentData(
95
97
  if (meta) {
96
98
  doc._meta = meta;
97
99
  }
100
+ doc._deleted = deleted;
98
101
  return doc;
99
102
  });
100
103
  }
@@ -329,7 +329,7 @@ export class RxMigrationState {
329
329
  for (const oneHandler of useHandlers) {
330
330
  status = oneHandler(status);
331
331
  }
332
- status.count.percent = Math.round((status.count.handled / status.count.total) * 100);
332
+ status.count.percent = status.count.total === 0 ? 100 : Math.round((status.count.handled / status.count.total) * 100);
333
333
 
334
334
  if (
335
335
  newDoc && previous &&
@@ -172,6 +172,8 @@ export class RxPipeline<RxDocType> {
172
172
  done = true;
173
173
  }
174
174
  }
175
+ }).catch(err => {
176
+ this.error = err;
175
177
  });
176
178
  }
177
179
 
@@ -205,11 +207,14 @@ export class RxPipeline<RxDocType> {
205
207
  * Remove the pipeline and all metadata which it has stored
206
208
  */
207
209
  async remove() {
210
+ await this.close();
208
211
  const insternalStore = this.destination.database.internalStore;
209
212
  const checkpointDoc = await getCheckpointDoc(this);
210
213
  if (checkpointDoc) {
211
214
  const newDoc: RxDocumentData<InternalStoreDocType> = clone(checkpointDoc);
212
215
  newDoc._deleted = true;
216
+ newDoc._meta.lwt = now();
217
+ newDoc._rev = createRevision(this.destination.database.token, checkpointDoc);
213
218
  const writeResult = await insternalStore.bulkWrite([{
214
219
  previous: checkpointDoc,
215
220
  document: newDoc,
@@ -218,7 +223,6 @@ export class RxPipeline<RxDocType> {
218
223
  throw writeResult.error;
219
224
  }
220
225
  }
221
- return this.close();
222
226
  }
223
227
  }
224
228
 
@@ -92,7 +92,10 @@ export class NoSqlQueryBuilderClass<DocType> {
92
92
  equals(val: any): NoSqlQueryBuilder<DocType> {
93
93
  this._ensurePath('equals');
94
94
  const path = this._path;
95
- (this._conditions as any)[path] = val;
95
+ const conds = (this._conditions as any)[path] !== null && typeof (this._conditions as any)[path] === 'object' ?
96
+ (this._conditions as any)[path] :
97
+ ((this._conditions as any)[path] = {});
98
+ conds.$eq = val;
96
99
  return this as any;
97
100
  }
98
101
 
@@ -103,7 +106,10 @@ export class NoSqlQueryBuilderClass<DocType> {
103
106
  eq(val: any): NoSqlQueryBuilder<DocType> {
104
107
  this._ensurePath('eq');
105
108
  const path = this._path;
106
- (this._conditions as any)[path] = val;
109
+ const conds = (this._conditions as any)[path] !== null && typeof (this._conditions as any)[path] === 'object' ?
110
+ (this._conditions as any)[path] :
111
+ ((this._conditions as any)[path] = {});
112
+ conds.$eq = val;
107
113
  return this as any;
108
114
  }
109
115
 
@@ -237,7 +237,7 @@ export class RxReplicationState<RxDocType, CheckpointType> {
237
237
  waitBeforePersist: this.push ? this.push.waitBeforePersist : undefined,
238
238
  replicationHandler: {
239
239
  masterChangeStream$: this.remoteEvents$.asObservable().pipe(
240
- filter((_v: RxReplicationPullStreamItem<RxDocType, CheckpointType>) => !!this.pull),
240
+ filter((_v: RxReplicationPullStreamItem<RxDocType, CheckpointType>) => !!this.pull || _v === 'RESYNC'),
241
241
  mergeMap(async (ev: RxReplicationPullStreamItem<RxDocType, CheckpointType>) => {
242
242
  if (ev === 'RESYNC') {
243
243
  return ev;
@@ -548,6 +548,20 @@ export class RxReplicationState<RxDocType, CheckpointType> {
548
548
  this.subjects.received.complete();
549
549
  this.subjects.sent.complete();
550
550
 
551
+ /**
552
+ * Remove from the REPLICATION_STATE_BY_COLLECTION registry
553
+ * so that the cleanup plugin does not try to access a stopped
554
+ * replication's meta instance, and to prevent memory leaks
555
+ * from accumulating canceled replication state objects.
556
+ */
557
+ const states = REPLICATION_STATE_BY_COLLECTION.get(this.collection as any);
558
+ if (states) {
559
+ const idx = states.indexOf(this);
560
+ if (idx !== -1) {
561
+ states.splice(idx, 1);
562
+ }
563
+ }
564
+
551
565
  return Promise.all(promises);
552
566
  }
553
567
 
@@ -555,8 +569,32 @@ export class RxReplicationState<RxDocType, CheckpointType> {
555
569
  this.startQueue = this.startQueue.then(async () => {
556
570
  const metaInfo = await this.metaInfoPromise;
557
571
  await this._cancel(true);
558
- await ensureNotFalsy(this.internalReplicationState).checkpointQueue
559
- .then(() => ensureNotFalsy(this.metaInstance).remove());
572
+
573
+ /**
574
+ * If the replication was never started (e.g. autoStart: false
575
+ * and start() was never called), we still have to
576
+ * create the meta storage instance and then remove its data.
577
+ * This is required so that old meta data from a previous
578
+ * replication with the same identifier is properly deleted.
579
+ */
580
+ if (!this.metaInstance) {
581
+ const database = this.collection.database;
582
+ this.metaInstance = await database.storage.createStorageInstance<RxStorageReplicationMeta<RxDocType, CheckpointType>>({
583
+ databaseName: database.name,
584
+ collectionName: metaInfo.collectionName,
585
+ databaseInstanceToken: database.token,
586
+ multiInstance: database.multiInstance,
587
+ options: {},
588
+ schema: metaInfo.schema,
589
+ password: database.password,
590
+ devMode: overwritable.isDevMode()
591
+ });
592
+ }
593
+
594
+ if (this.internalReplicationState) {
595
+ await this.internalReplicationState.checkpointQueue;
596
+ }
597
+ await ensureNotFalsy(this.metaInstance).remove();
560
598
  await removeConnectedStorageFromCollection(
561
599
  this.collection,
562
600
  metaInfo.collectionName,
@@ -29,7 +29,7 @@ export async function getDocumentFiles(
29
29
  const params = new URLSearchParams({
30
30
  q,
31
31
  pageSize: MAX_DRIVE_PAGE_SIZE + '',
32
- fields: "nextPageToken, files(id,name,mimeType,parents,modifiedTime,size)",
32
+ fields: "nextPageToken, files(id,name,mimeType,parents,modifiedTime,size,etag)",
33
33
  // Shared drives support (safe to include always)
34
34
  includeItemsFromAllDrives: "true",
35
35
  supportsAllDrives: "true",
@@ -109,7 +109,7 @@ export async function updateDocumentFiles<DocType>(
109
109
  googleDriveOptions: GoogleDriveOptionsWithDefaults,
110
110
  primaryPath: keyof DocType,
111
111
  docs: DocType[],
112
- fileIdByDocId: Record<string, string>,
112
+ fileMetaByDocId: Record<string, { fileId: string; etag: string }>,
113
113
  concurrency = 5
114
114
  ) {
115
115
  const queue = docs.slice(0);
@@ -119,22 +119,34 @@ export async function updateDocumentFiles<DocType>(
119
119
  while (queue.length) {
120
120
  const doc = queue.shift()!;
121
121
  const docId = (doc as any)[primaryPath] as string;
122
- const fileId = ensureNotFalsy(fileIdByDocId[docId]);
122
+ const meta = ensureNotFalsy(fileMetaByDocId[docId]);
123
+ const fileId = meta.fileId;
124
+ const etag = meta.etag;
123
125
 
124
126
  const url =
125
127
  googleDriveOptions.apiEndpoint +
126
- `/upload/drive/v3/files/${encodeURIComponent(fileId)}` +
128
+ `/upload/drive/v2/files/${encodeURIComponent(fileId)}` +
127
129
  `?uploadType=media&supportsAllDrives=true&fields=id`;
128
130
 
129
131
  const res = await fetch(url, {
130
- method: "PATCH",
132
+ method: "PUT",
131
133
  headers: {
132
134
  Authorization: `Bearer ${googleDriveOptions.authToken}`,
133
135
  "Content-Type": "application/json; charset=UTF-8",
136
+ "If-Match": etag,
134
137
  },
135
138
  body: JSON.stringify(doc),
136
139
  });
137
140
 
141
+ if (res.status === 412) {
142
+ throw newRxError('GDR20', {
143
+ args: {
144
+ docId,
145
+ fileId
146
+ }
147
+ });
148
+ }
149
+
138
150
  if (!res.ok) {
139
151
  throw await newRxFetchError(res, {
140
152
  args: {
@@ -392,7 +392,7 @@ export async function insertMultipartFile<T>(
392
392
  const metadata = {
393
393
  name: filename,
394
394
  mimeType: 'application/json',
395
- parents: folderId,
395
+ parents: [folderId],
396
396
  };
397
397
 
398
398
  const postData = createMultipartBody(
@@ -26,6 +26,7 @@ export interface DriveFileMetadata {
26
26
  modifiedTime?: string;
27
27
  size?: string; // Drive returns size as string
28
28
  fileSize?: string; // v2
29
+ etag?: string;
29
30
  }
30
31
 
31
32
  export type GoogleDriveOptions = {
@@ -144,7 +144,9 @@ export class SignalingState {
144
144
 
145
145
  async pingPeers(message: SIGNAL) {
146
146
  Array.from(this.peerBySenderId.values()).forEach(peer => {
147
- peer.send(message);
147
+ if (peer.connected) {
148
+ peer.send(message);
149
+ }
148
150
  });
149
151
  }
150
152
 
@@ -195,6 +197,7 @@ export class SignalingState {
195
197
  });
196
198
  peer.on('connect', () => {
197
199
  this._resync$.next();
200
+ peer.send('RESYNC');
198
201
  });
199
202
  peer.on('data', (dataBuffer: any) => {
200
203
  const data = dataBuffer + '';
@@ -213,18 +213,21 @@ export async function processWalFile<RxDocType>(
213
213
  init,
214
214
  docIds as string[]
215
215
  );
216
- const fileIdByDocId: Record<string, string> = {};
216
+ const fileMetaByDocId: Record<string, { fileId: string; etag: string }> = {};
217
217
 
218
218
  docFiles.files.forEach(file => {
219
219
  const docId = file.name.split('.')[0] as any;
220
- fileIdByDocId[docId] = file.id;
220
+ fileMetaByDocId[docId] = {
221
+ fileId: file.id,
222
+ etag: ensureNotFalsy(file.etag),
223
+ };
221
224
  });
222
225
 
223
226
  const toInsert: WithDeletedAndAttachments<RxDocType>[] = [];
224
227
  const toUpdate: WithDeletedAndAttachments<RxDocType>[] = [];
225
228
  content.rows.filter(row => {
226
229
  const docId = row.newDocumentState[primaryPath];
227
- const fileExists = fileIdByDocId[docId as any];
230
+ const fileExists = fileMetaByDocId[docId as any];
228
231
  if (!fileExists) {
229
232
  toInsert.push(row.newDocumentState);
230
233
  } else {
@@ -243,7 +246,7 @@ export async function processWalFile<RxDocType>(
243
246
  googleDriveOptions,
244
247
  primaryPath,
245
248
  toUpdate,
246
- fileIdByDocId,
249
+ fileMetaByDocId,
247
250
  )
248
251
  ]);
249
252
 
@@ -152,7 +152,9 @@ export class SignalingState {
152
152
 
153
153
  async pingPeers(message: SIGNAL) {
154
154
  Array.from(this.peerBySenderId.values()).forEach(peer => {
155
- peer.send(message);
155
+ if (peer.connected) {
156
+ peer.send(message);
157
+ }
156
158
  });
157
159
  }
158
160
 
@@ -203,6 +205,7 @@ export class SignalingState {
203
205
  });
204
206
  peer.on('connect', () => {
205
207
  this._resync$.next();
208
+ peer.send('RESYNC');
206
209
  });
207
210
  peer.on('data', (dataBuffer: any) => {
208
211
  const data = dataBuffer + '';
@@ -27,7 +27,8 @@ import {
27
27
  clone,
28
28
  randomToken,
29
29
  deepEqual,
30
- getFromMapOrCreate
30
+ getFromMapOrCreate,
31
+ promiseWait
31
32
  } from '../utils/index.ts';
32
33
  import {
33
34
  RX_STATE_COLLECTION_SCHEMA,
@@ -148,7 +149,7 @@ export class RxStateBase<T, Reactivity = unknown> {
148
149
  const ops: RxStateOperation[] = [];
149
150
  for (let index = 0; index < useWrites.length; index++) {
150
151
  const writeRow = useWrites[index];
151
- const value = getProperty(newState, writeRow.path);
152
+ const value = writeRow.path === '' ? newState : getProperty(newState, writeRow.path);
152
153
  const newValue = writeRow.modifier(value);
153
154
  /**
154
155
  * Here we have to clone the value because
@@ -182,6 +183,12 @@ export class RxStateBase<T, Reactivity = unknown> {
182
183
  if ((err as RxError).code !== 'CONFLICT') {
183
184
  throw err;
184
185
  }
186
+ /**
187
+ * Yield to the event loop so that cross-instance
188
+ * change events can be processed and the _lastIdQuery
189
+ * cache gets updated before retrying.
190
+ */
191
+ await promiseWait(0);
185
192
  }
186
193
  }
187
194
  }).catch(error => {
@@ -328,7 +335,7 @@ export async function createRxState<T>(
328
335
  } else {
329
336
  for (let index = 0; index < documents.length; index++) {
330
337
  const document = documents[index];
331
- mergeOperationsIntoState(rxState._state, document.ops);
338
+ rxState._state = mergeOperationsIntoState(rxState._state, document.ops);
332
339
  }
333
340
  }
334
341
  }
@@ -378,9 +385,14 @@ export async function createRxState<T>(
378
385
  export function mergeOperationsIntoState<T>(
379
386
  state: T,
380
387
  operations: RxStateOperation[]
381
- ) {
388
+ ): T {
382
389
  for (let index = 0; index < operations.length; index++) {
383
390
  const operation = operations[index];
384
- setProperty(state, operation.k, clone(operation.v));
391
+ if (operation.k === '') {
392
+ state = clone(operation.v);
393
+ } else {
394
+ setProperty(state, operation.k, clone(operation.v));
395
+ }
385
396
  }
397
+ return state;
386
398
  }
@@ -5,10 +5,6 @@ import {
5
5
  import {
6
6
  now,
7
7
  ensureNotFalsy,
8
- defaultHashSha256,
9
- RXDB_UTILS_GLOBAL,
10
- PREMIUM_FLAG_HASH,
11
- hasPremiumFlag
12
8
  } from '../utils/index.ts';
13
9
  import type {
14
10
  RxStorageInstance,
@@ -47,8 +43,6 @@ import { newRxError } from '../../rx-error.ts';
47
43
 
48
44
  let instanceId = now();
49
45
 
50
- let shownNonPremiumLog = false;
51
-
52
46
 
53
47
  export class RxStorageInstanceDexie<RxDocType> implements RxStorageInstance<
54
48
  RxDocType,
@@ -80,27 +74,6 @@ export class RxStorageInstanceDexie<RxDocType> implements RxStorageInstance<
80
74
  ): Promise<RxStorageBulkWriteResponse<RxDocType>> {
81
75
  ensureNotClosed(this);
82
76
 
83
- if (
84
- !shownNonPremiumLog &&
85
- !(await hasPremiumFlag())
86
- ) {
87
- console.warn(
88
- [
89
- '-------------- RxDB Open Core RxStorage -------------------------------',
90
- 'You are using the free Dexie.js based RxStorage implementation from RxDB https://rxdb.info/rx-storage-dexie.html?console=dexie ',
91
- 'While this is a great option, we want to let you know that there are faster storage solutions available in our premium plugins.',
92
- 'For professional users and production environments, we highly recommend considering these premium options to enhance performance and reliability.',
93
- ' https://rxdb.info/premium/?console=dexie ',
94
- 'If you already purchased premium access you can disable this log by calling the setPremiumFlag() function from rxdb-premium/plugins/shared.',
95
- '---------------------------------------------------------------------'
96
- ].join('\n')
97
- );
98
- shownNonPremiumLog = true;
99
- } else {
100
- shownNonPremiumLog = true;
101
- }
102
-
103
-
104
77
  /**
105
78
  * Check some assumptions to ensure RxDB
106
79
  * does not call the storage with an invalid write.
@@ -1,22 +1,21 @@
1
1
  /**
2
- * Everything in this file was copied and adapted from
3
- * @link https://github.com/mikolalysenko/binary-search-bounds
4
- *
5
- * We should use the original npm module instead when this bug is fixed:
6
- * @link https://github.com/mikolalysenko/binary-search-bounds/pull/14
2
+ * Optimized binary search functions for the memory storage.
3
+ * Based on https://github.com/mikolalysenko/binary-search-bounds
4
+ * but with performance improvements:
5
+ * - Removed unnecessary undefined checks for comparator
6
+ * - Inlined the norm() wrapper to avoid extra function calls
7
+ * - Added string-specialized variants to avoid temporary array allocations
7
8
  */
8
9
 
9
-
10
-
11
10
  type Compare<T> = ((a: T, b: T) => number | null | undefined);
12
11
 
13
- function ge<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
12
+ export function boundGE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {
13
+ let l: number = lo === undefined ? 0 : lo | 0;
14
+ let h: number = hi === undefined ? a.length - 1 : hi | 0;
14
15
  let i: number = h + 1;
15
16
  while (l <= h) {
16
17
  const m = (l + h) >>> 1;
17
- const x: any = a[m];
18
- const p: any = (c !== undefined) ? c(x, y) : (x - (y as any));
19
- if (p >= 0) {
18
+ if ((c(a[m], y) as number) >= 0) {
20
19
  i = m; h = m - 1;
21
20
  } else {
22
21
  l = m + 1;
@@ -25,13 +24,13 @@ function ge<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
25
24
  return i;
26
25
  }
27
26
 
28
- function gt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
27
+ export function boundGT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {
28
+ let l: number = lo === undefined ? 0 : lo | 0;
29
+ let h: number = hi === undefined ? a.length - 1 : hi | 0;
29
30
  let i = h + 1;
30
31
  while (l <= h) {
31
32
  const m = (l + h) >>> 1;
32
- const x = a[m];
33
- const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));
34
- if (p > 0) {
33
+ if ((c(a[m], y) as number) > 0) {
35
34
  i = m; h = m - 1;
36
35
  } else {
37
36
  l = m + 1;
@@ -40,12 +39,13 @@ function gt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
40
39
  return i;
41
40
  }
42
41
 
43
- function lt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
42
+ export function boundLT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {
43
+ let l: number = lo === undefined ? 0 : lo | 0;
44
+ let h: number = hi === undefined ? a.length - 1 : hi | 0;
44
45
  let i = l - 1;
45
46
  while (l <= h) {
46
- const m = (l + h) >>> 1, x = a[m];
47
- const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));
48
- if (p < 0) {
47
+ const m = (l + h) >>> 1;
48
+ if ((c(a[m], y) as number) < 0) {
49
49
  i = m; l = m + 1;
50
50
  } else {
51
51
  h = m - 1;
@@ -54,12 +54,13 @@ function lt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
54
54
  return i;
55
55
  }
56
56
 
57
- function le<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
57
+ export function boundLE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {
58
+ let l: number = lo === undefined ? 0 : lo | 0;
59
+ let h: number = hi === undefined ? a.length - 1 : hi | 0;
58
60
  let i = l - 1;
59
61
  while (l <= h) {
60
- const m = (l + h) >>> 1, x = a[m];
61
- const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));
62
- if (p <= 0) {
62
+ const m = (l + h) >>> 1;
63
+ if ((c(a[m], y) as number) <= 0) {
63
64
  i = m; l = m + 1;
64
65
  } else {
65
66
  h = m - 1;
@@ -68,10 +69,12 @@ function le<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
68
69
  return i;
69
70
  }
70
71
 
71
- function eq<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
72
+ export function boundEQ<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {
73
+ let l: number = lo === undefined ? 0 : lo | 0;
74
+ let h: number = hi === undefined ? a.length - 1 : hi | 0;
72
75
  while (l <= h) {
73
- const m = (l + h) >>> 1, x = a[m];
74
- const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));
76
+ const m = (l + h) >>> 1;
77
+ const p = c(a[m], y) as number;
75
78
  if (p === 0) {
76
79
  return m;
77
80
  }
@@ -84,23 +87,85 @@ function eq<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {
84
87
  return -1;
85
88
  }
86
89
 
87
- function norm<T>(a: T[], y: T, c: Compare<T>, l: any, h: any, f: any) {
88
- return f(a, y, c, (l === undefined) ? 0 : l | 0, (h === undefined) ? a.length - 1 : h | 0);
90
+ /**
91
+ * Specialized binary search functions that compare DocWithIndexString
92
+ * entries directly against an index string, avoiding temporary array allocations.
93
+ * Used in query() and count() hot paths.
94
+ */
95
+ export function boundGEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {
96
+ let l = 0;
97
+ let h = a.length - 1;
98
+ let i: number = h + 1;
99
+ while (l <= h) {
100
+ const m = (l + h) >>> 1;
101
+ if (a[m][0] >= indexString) {
102
+ i = m; h = m - 1;
103
+ } else {
104
+ l = m + 1;
105
+ }
106
+ }
107
+ return i;
89
108
  }
90
109
 
91
-
92
- export function boundGE<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {
93
- return norm(a, y, c, l, h, ge);
94
- }
95
- export function boundGT<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {
96
- return norm(a, y, c, l, h, gt);
110
+ export function boundGTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {
111
+ let l = 0;
112
+ let h = a.length - 1;
113
+ let i = h + 1;
114
+ while (l <= h) {
115
+ const m = (l + h) >>> 1;
116
+ if (a[m][0] > indexString) {
117
+ i = m; h = m - 1;
118
+ } else {
119
+ l = m + 1;
120
+ }
121
+ }
122
+ return i;
97
123
  }
98
- export function boundLT<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {
99
- return norm(a, y, c, l, h, lt);
124
+
125
+ export function boundEQByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {
126
+ let l = 0;
127
+ let h = a.length - 1;
128
+ while (l <= h) {
129
+ const m = (l + h) >>> 1;
130
+ const s = a[m][0];
131
+ if (s === indexString) {
132
+ return m;
133
+ }
134
+ if (s < indexString) {
135
+ l = m + 1;
136
+ } else {
137
+ h = m - 1;
138
+ }
139
+ }
140
+ return -1;
100
141
  }
101
- export function boundLE<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {
102
- return norm(a, y, c, l, h, le);
142
+
143
+ export function boundLTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {
144
+ let l = 0;
145
+ let h = a.length - 1;
146
+ let i = l - 1;
147
+ while (l <= h) {
148
+ const m = (l + h) >>> 1;
149
+ if (a[m][0] < indexString) {
150
+ i = m; l = m + 1;
151
+ } else {
152
+ h = m - 1;
153
+ }
154
+ }
155
+ return i;
103
156
  }
104
- export function boundEQ<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {
105
- return norm(a, y, c, l, h, eq);
157
+
158
+ export function boundLEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {
159
+ let l = 0;
160
+ let h = a.length - 1;
161
+ let i = l - 1;
162
+ while (l <= h) {
163
+ const m = (l + h) >>> 1;
164
+ if (a[m][0] <= indexString) {
165
+ i = m; l = m + 1;
166
+ } else {
167
+ h = m - 1;
168
+ }
169
+ }
170
+ return i;
106
171
  }