@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
@@ -12,6 +12,7 @@
12
12
  import { getSchemaByObjectPath } from "./rx-schema-helper.js";
13
13
  import { ensureNotFalsy, objectPathMonad } from "./plugins/utils/index.js";
14
14
  import { INDEX_MAX, INDEX_MIN } from "./query-planner.js";
15
+ import { newRxError } from "./rx-error.js";
15
16
 
16
17
  /**
17
18
  * Prepare all relevant information
@@ -25,7 +26,9 @@ export function getIndexMeta(schema, index) {
25
26
  var fieldNameProperties = index.map(fieldName => {
26
27
  var schemaPart = getSchemaByObjectPath(schema, fieldName);
27
28
  if (!schemaPart) {
28
- throw new Error('not in schema: ' + fieldName);
29
+ throw newRxError('CI1', {
30
+ fieldName
31
+ });
29
32
  }
30
33
  var type = schemaPart.type;
31
34
  var parsedLengths;
@@ -50,10 +53,51 @@ export function getIndexMeta(schema, index) {
50
53
  };
51
54
  } else {
52
55
  // number
53
- getIndexStringPart = docData => {
54
- var fieldValue = getValue(docData);
55
- return getNumberIndexString(parsedLengths, fieldValue);
56
- };
56
+ /**
57
+ * @performance
58
+ * Inline the number index string generation to avoid
59
+ * function call overhead and redundant boundary checks.
60
+ * Document data in the hot path is assumed to be valid.
61
+ */
62
+ var pLengths = parsedLengths;
63
+ var pMin = pLengths.minimum;
64
+ var pMax = pLengths.maximum;
65
+ var pRoundedMin = pLengths.roundedMinimum;
66
+ var pNonDecimals = pLengths.nonDecimals;
67
+ var pDecimals = pLengths.decimals;
68
+ var pMultiplier = pLengths.multiplier;
69
+ if (pDecimals === 0) {
70
+ getIndexStringPart = docData => {
71
+ var fieldValue = getValue(docData);
72
+ if (typeof fieldValue === 'undefined') {
73
+ fieldValue = 0;
74
+ }
75
+ if (fieldValue < pMin) {
76
+ fieldValue = pMin;
77
+ }
78
+ if (fieldValue > pMax) {
79
+ fieldValue = pMax;
80
+ }
81
+ return (Math.floor(fieldValue) - pRoundedMin).toString().padStart(pNonDecimals, '0');
82
+ };
83
+ } else {
84
+ getIndexStringPart = docData => {
85
+ var fieldValue = getValue(docData);
86
+ if (typeof fieldValue === 'undefined') {
87
+ fieldValue = 0;
88
+ }
89
+ if (fieldValue < pMin) {
90
+ fieldValue = pMin;
91
+ }
92
+ if (fieldValue > pMax) {
93
+ fieldValue = pMax;
94
+ }
95
+ var flooredValue = Math.floor(fieldValue);
96
+ var shifted = Math.min(Math.round((fieldValue - flooredValue) * pMultiplier), pMultiplier - 1);
97
+ var str = (flooredValue - pRoundedMin).toString().padStart(pNonDecimals, '0');
98
+ return str + shifted.toString().padStart(pDecimals, '0');
99
+ };
100
+ }
57
101
  }
58
102
  var ret = {
59
103
  fieldName,
@@ -85,7 +129,22 @@ export function getIndexableStringMonad(schema, index) {
85
129
 
86
130
  /**
87
131
  * @hotPath Performance of this function is very critical!
132
+ * Specialize for common field counts to avoid loop overhead.
88
133
  */
134
+ if (fieldNamePropertiesAmount === 1) {
135
+ return indexPartsFunctions[0];
136
+ }
137
+ if (fieldNamePropertiesAmount === 2) {
138
+ var fn0 = indexPartsFunctions[0];
139
+ var fn1 = indexPartsFunctions[1];
140
+ return docData => fn0(docData) + fn1(docData);
141
+ }
142
+ if (fieldNamePropertiesAmount === 3) {
143
+ var _fn = indexPartsFunctions[0];
144
+ var _fn2 = indexPartsFunctions[1];
145
+ var fn2 = indexPartsFunctions[2];
146
+ return docData => _fn(docData) + _fn2(docData) + fn2(docData);
147
+ }
89
148
  var ret = function (docData) {
90
149
  var str = '';
91
150
  for (var i = 0; i < fieldNamePropertiesAmount; ++i) {
@@ -111,7 +170,8 @@ export function getStringLengthOfIndexNumber(schemaPart) {
111
170
  maximum,
112
171
  nonDecimals,
113
172
  decimals,
114
- roundedMinimum: minimum
173
+ roundedMinimum: minimum,
174
+ multiplier: Math.pow(10, decimals)
115
175
  };
116
176
  }
117
177
  export function getIndexStringLength(schema, index) {
@@ -159,9 +219,16 @@ export function getNumberIndexString(parsedLengths, fieldValue) {
159
219
  var nonDecimalsValueAsString = (Math.floor(fieldValue) - parsedLengths.roundedMinimum).toString();
160
220
  var str = nonDecimalsValueAsString.padStart(parsedLengths.nonDecimals, '0');
161
221
  if (parsedLengths.decimals > 0) {
162
- var splitByDecimalPoint = fieldValue.toString().split('.');
163
- var decimalValueAsString = splitByDecimalPoint.length > 1 ? splitByDecimalPoint[1] : '0';
164
- str += decimalValueAsString.padEnd(parsedLengths.decimals, '0');
222
+ /**
223
+ * @performance
224
+ * Use math to extract decimal digits instead of toString().split('.')
225
+ * which creates intermediate strings and arrays.
226
+ * multiplier is pre-computed in ParsedLengths to avoid Math.pow() per call.
227
+ */
228
+ var multiplier = parsedLengths.multiplier;
229
+ var shifted = Math.min(Math.round((fieldValue - Math.floor(fieldValue)) * multiplier), multiplier - 1);
230
+ var decimalPart = shifted.toString();
231
+ str += decimalPart.padStart(parsedLengths.decimals, '0');
165
232
  }
166
233
  return str;
167
234
  }
@@ -207,7 +274,9 @@ export function getStartIndexStringFromLowerBound(schema, index, lowerBound) {
207
274
  }
208
275
  break;
209
276
  default:
210
- throw new Error('unknown index type ' + type);
277
+ throw newRxError('CI2', {
278
+ type: type
279
+ });
211
280
  }
212
281
  });
213
282
  return str;
@@ -230,8 +299,10 @@ export function getStartIndexStringFromUpperBound(schema, index, upperBound) {
230
299
  }
231
300
  break;
232
301
  case 'boolean':
233
- if (bound === null) {
302
+ if (bound === null || bound === INDEX_MAX) {
234
303
  str += '1';
304
+ } else if (bound === INDEX_MIN) {
305
+ str += '0';
235
306
  } else {
236
307
  var boolToStr = bound ? '1' : '0';
237
308
  str += boolToStr;
@@ -251,7 +322,9 @@ export function getStartIndexStringFromUpperBound(schema, index, upperBound) {
251
322
  }
252
323
  break;
253
324
  default:
254
- throw new Error('unknown index type ' + type);
325
+ throw newRxError('CI2', {
326
+ type: type
327
+ });
255
328
  }
256
329
  });
257
330
  return str;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-index.js","names":["getSchemaByObjectPath","ensureNotFalsy","objectPathMonad","INDEX_MAX","INDEX_MIN","getIndexMeta","schema","index","fieldNameProperties","map","fieldName","schemaPart","Error","type","parsedLengths","getStringLengthOfIndexNumber","getValue","maxLength","getIndexStringPart","docData","fieldValue","padEnd","getNumberIndexString","ret","getIndexableStringMonad","fieldNamePropertiesAmount","length","indexPartsFunctions","r","str","i","minimum","Math","floor","maximum","ceil","multipleOf","valueSpan","nonDecimals","toString","multipleOfParts","split","decimals","roundedMinimum","getIndexStringLength","forEach","props","getPrimaryKeyFromIndexableString","indexableString","primaryKeyLength","paddedPrimaryKey","slice","primaryKey","trim","nonDecimalsValueAsString","padStart","splitByDecimalPoint","decimalValueAsString","getStartIndexStringFromLowerBound","lowerBound","idx","bound","boolToStr","fillChar","repeat","add","getStartIndexStringFromUpperBound","upperBound","changeIndexableStringByOneQuantum","direction","lastChar","charCode","charCodeAt","withoutLastChar","String","fromCharCode"],"sources":["../../src/custom-index.ts"],"sourcesContent":["/**\r\n * For some RxStorage implementations,\r\n * we need to use our custom crafted indexes\r\n * so we can easily iterate over them. And sort plain arrays of document data.\r\n *\r\n * We really often have to craft an index string for a given document.\r\n * Performance of everything in this file is very important\r\n * which is why the code sometimes looks strange.\r\n * Run performance tests before and after you touch anything here!\r\n */\r\n\r\nimport {\r\n getSchemaByObjectPath\r\n} from './rx-schema-helper.ts';\r\nimport type {\r\n JsonSchema,\r\n RxDocumentData,\r\n RxJsonSchema\r\n} from './types/index.d.ts';\r\nimport {\r\n ensureNotFalsy,\r\n objectPathMonad,\r\n ObjectPathMonadFunction\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n INDEX_MAX,\r\n INDEX_MIN\r\n} from './query-planner.ts';\r\n\r\n\r\n/**\r\n * Prepare all relevant information\r\n * outside of the returned function\r\n * from getIndexableStringMonad()\r\n * to save performance when the returned\r\n * function is called many times.\r\n */\r\ntype IndexMetaField<RxDocType> = {\r\n fieldName: string;\r\n schemaPart: JsonSchema;\r\n /*\r\n * Only in number fields.\r\n */\r\n parsedLengths?: ParsedLengths;\r\n getValue: ObjectPathMonadFunction<RxDocType>;\r\n getIndexStringPart: (docData: RxDocumentData<RxDocType>) => string;\r\n};\r\n\r\nexport function getIndexMeta<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): IndexMetaField<RxDocType>[] {\r\n const fieldNameProperties: IndexMetaField<RxDocType>[] = index.map(fieldName => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n if (!schemaPart) {\r\n throw new Error('not in schema: ' + fieldName);\r\n }\r\n const type = schemaPart.type;\r\n let parsedLengths: ParsedLengths | undefined;\r\n if (type === 'number' || type === 'integer') {\r\n parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n }\r\n\r\n const getValue = objectPathMonad(fieldName);\r\n const maxLength = schemaPart.maxLength ? schemaPart.maxLength : 0;\r\n\r\n let getIndexStringPart: (docData: RxDocumentData<RxDocType>) => string;\r\n if (type === 'string') {\r\n getIndexStringPart = docData => {\r\n let fieldValue = getValue(docData);\r\n if (!fieldValue) {\r\n fieldValue = '';\r\n }\r\n return fieldValue.padEnd(maxLength, ' ');\r\n };\r\n } else if (type === 'boolean') {\r\n getIndexStringPart = docData => {\r\n const fieldValue = getValue(docData);\r\n return fieldValue ? '1' : '0';\r\n };\r\n } else { // number\r\n getIndexStringPart = docData => {\r\n const fieldValue = getValue(docData);\r\n return getNumberIndexString(\r\n parsedLengths as any,\r\n fieldValue\r\n );\r\n };\r\n }\r\n\r\n const ret: IndexMetaField<RxDocType> = {\r\n fieldName,\r\n schemaPart,\r\n parsedLengths,\r\n getValue,\r\n getIndexStringPart\r\n };\r\n return ret;\r\n });\r\n return fieldNameProperties;\r\n}\r\n\r\n\r\n/**\r\n * Crafts an indexable string that can be used\r\n * to check if a document would be sorted below or above\r\n * another documents, dependent on the index values.\r\n * @monad for better performance\r\n *\r\n * IMPORTANT: Performance is really important here\r\n * which is why we code so 'strange'.\r\n * Always run performance tests when you want to\r\n * change something in this method.\r\n */\r\nexport function getIndexableStringMonad<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): (docData: RxDocumentData<RxDocType>) => string {\r\n const fieldNameProperties = getIndexMeta(schema, index);\r\n const fieldNamePropertiesAmount = fieldNameProperties.length;\r\n const indexPartsFunctions = fieldNameProperties.map(r => r.getIndexStringPart);\r\n\r\n\r\n /**\r\n * @hotPath Performance of this function is very critical!\r\n */\r\n const ret = function (docData: RxDocumentData<RxDocType>): string {\r\n let str = '';\r\n for (let i = 0; i < fieldNamePropertiesAmount; ++i) {\r\n str += indexPartsFunctions[i](docData);\r\n }\r\n return str;\r\n };\r\n return ret;\r\n}\r\n\r\n\r\ndeclare type ParsedLengths = {\r\n minimum: number;\r\n maximum: number;\r\n nonDecimals: number;\r\n decimals: number;\r\n roundedMinimum: number;\r\n};\r\nexport function getStringLengthOfIndexNumber(\r\n schemaPart: JsonSchema\r\n): ParsedLengths {\r\n const minimum = Math.floor(schemaPart.minimum as number);\r\n const maximum = Math.ceil(schemaPart.maximum as number);\r\n const multipleOf: number = schemaPart.multipleOf as number;\r\n\r\n const valueSpan = maximum - minimum;\r\n const nonDecimals = valueSpan.toString().length;\r\n\r\n const multipleOfParts = multipleOf.toString().split('.');\r\n let decimals = 0;\r\n if (multipleOfParts.length > 1) {\r\n decimals = multipleOfParts[1].length;\r\n }\r\n return {\r\n minimum,\r\n maximum,\r\n nonDecimals,\r\n decimals,\r\n roundedMinimum: minimum\r\n };\r\n}\r\n\r\nexport function getIndexStringLength<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): number {\r\n const fieldNameProperties = getIndexMeta(schema, index);\r\n let length = 0;\r\n fieldNameProperties.forEach(props => {\r\n const schemaPart = props.schemaPart;\r\n const type = schemaPart.type;\r\n\r\n if (type === 'string') {\r\n length += schemaPart.maxLength as number;\r\n } else if (type === 'boolean') {\r\n length += 1;\r\n } else {\r\n const parsedLengths = props.parsedLengths as ParsedLengths;\r\n length = length + parsedLengths.nonDecimals + parsedLengths.decimals;\r\n }\r\n\r\n });\r\n return length;\r\n}\r\n\r\n\r\nexport function getPrimaryKeyFromIndexableString(\r\n indexableString: string,\r\n primaryKeyLength: number\r\n): string {\r\n const paddedPrimaryKey = indexableString.slice(primaryKeyLength * -1);\r\n // we can safely trim here because the primary key is not allowed to start or end with a space char.\r\n const primaryKey = paddedPrimaryKey.trim();\r\n return primaryKey;\r\n}\r\n\r\n\r\nexport function getNumberIndexString(\r\n parsedLengths: ParsedLengths,\r\n fieldValue: number\r\n): string {\r\n /**\r\n * Ensure that the given value is in the boundaries\r\n * of the schema, otherwise it would create a broken index string.\r\n * This can happen for example if you have a minimum of 0\r\n * and run a query like\r\n * selector {\r\n * numField: { $gt: -1000 }\r\n * }\r\n */\r\n if (typeof fieldValue === 'undefined') {\r\n fieldValue = 0;\r\n }\r\n if (fieldValue < parsedLengths.minimum) {\r\n fieldValue = parsedLengths.minimum;\r\n }\r\n if (fieldValue > parsedLengths.maximum) {\r\n fieldValue = parsedLengths.maximum;\r\n }\r\n\r\n const nonDecimalsValueAsString = (Math.floor(fieldValue) - parsedLengths.roundedMinimum).toString();\r\n let str = nonDecimalsValueAsString.padStart(parsedLengths.nonDecimals, '0');\r\n\r\n if (parsedLengths.decimals > 0) {\r\n const splitByDecimalPoint = fieldValue.toString().split('.');\r\n const decimalValueAsString = splitByDecimalPoint.length > 1 ? splitByDecimalPoint[1] : '0';\r\n str += decimalValueAsString.padEnd(parsedLengths.decimals, '0');\r\n }\r\n return str;\r\n}\r\n\r\nexport function getStartIndexStringFromLowerBound(\r\n schema: RxJsonSchema<any>,\r\n index: string[],\r\n lowerBound: (string | boolean | number | null | undefined)[]\r\n): string {\r\n let str = '';\r\n index.forEach((fieldName, idx) => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n const bound = lowerBound[idx];\r\n const type = schemaPart.type;\r\n\r\n switch (type) {\r\n case 'string':\r\n const maxLength = ensureNotFalsy(schemaPart.maxLength, 'maxLength not set');\r\n if (typeof bound === 'string') {\r\n str += (bound as string).padEnd(maxLength, ' ');\r\n } else {\r\n // str += ''.padStart(maxLength, inclusiveStart ? ' ' : INDEX_MAX);\r\n str += ''.padEnd(maxLength, ' ');\r\n }\r\n break;\r\n case 'boolean':\r\n if (bound === null) {\r\n str += '0';\r\n } else if (bound === INDEX_MIN) {\r\n str += '0';\r\n } else if (bound === INDEX_MAX) {\r\n str += '1';\r\n } else {\r\n const boolToStr = bound ? '1' : '0';\r\n str += boolToStr;\r\n }\r\n break;\r\n case 'number':\r\n case 'integer':\r\n const parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n if (bound === null || bound === INDEX_MIN) {\r\n const fillChar = '0';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else if (bound === INDEX_MAX) {\r\n str += getNumberIndexString(\r\n parsedLengths,\r\n parsedLengths.maximum\r\n );\r\n } else {\r\n const add = getNumberIndexString(\r\n parsedLengths,\r\n bound as number\r\n );\r\n str += add;\r\n }\r\n break;\r\n default:\r\n throw new Error('unknown index type ' + type);\r\n }\r\n });\r\n return str;\r\n}\r\n\r\n\r\nexport function getStartIndexStringFromUpperBound(\r\n schema: RxJsonSchema<any>,\r\n index: string[],\r\n upperBound: (string | boolean | number | null | undefined)[]\r\n): string {\r\n let str = '';\r\n index.forEach((fieldName, idx) => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n const bound = upperBound[idx];\r\n const type = schemaPart.type;\r\n\r\n switch (type) {\r\n case 'string':\r\n const maxLength = ensureNotFalsy(schemaPart.maxLength, 'maxLength not set');\r\n if (typeof bound === 'string' && bound !== INDEX_MAX) {\r\n str += (bound as string).padEnd(maxLength, ' ');\r\n } else if (bound === INDEX_MIN) {\r\n str += ''.padEnd(maxLength, ' ');\r\n } else {\r\n str += ''.padEnd(maxLength, INDEX_MAX);\r\n }\r\n break;\r\n case 'boolean':\r\n if (bound === null) {\r\n str += '1';\r\n } else {\r\n const boolToStr = bound ? '1' : '0';\r\n str += boolToStr;\r\n }\r\n break;\r\n case 'number':\r\n case 'integer':\r\n const parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n if (bound === null || bound === INDEX_MAX) {\r\n const fillChar = '9';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else if (bound === INDEX_MIN) {\r\n const fillChar = '0';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else {\r\n str += getNumberIndexString(\r\n parsedLengths,\r\n bound as number\r\n );\r\n }\r\n break;\r\n default:\r\n throw new Error('unknown index type ' + type);\r\n }\r\n });\r\n return str;\r\n}\r\n\r\n/**\r\n * Used in storages where it is not possible\r\n * to define inclusiveEnd/inclusiveStart\r\n */\r\nexport function changeIndexableStringByOneQuantum(str: string, direction: 1 | -1): string {\r\n const lastChar = str.slice(-1);\r\n let charCode = lastChar.charCodeAt(0);\r\n charCode = charCode + direction;\r\n const withoutLastChar = str.slice(0, -1);\r\n return withoutLastChar + String.fromCharCode(charCode);\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"custom-index.js","names":["getSchemaByObjectPath","ensureNotFalsy","objectPathMonad","INDEX_MAX","INDEX_MIN","newRxError","getIndexMeta","schema","index","fieldNameProperties","map","fieldName","schemaPart","type","parsedLengths","getStringLengthOfIndexNumber","getValue","maxLength","getIndexStringPart","docData","fieldValue","padEnd","pLengths","pMin","minimum","pMax","maximum","pRoundedMin","roundedMinimum","pNonDecimals","nonDecimals","pDecimals","decimals","pMultiplier","multiplier","Math","floor","toString","padStart","flooredValue","shifted","min","round","str","ret","getIndexableStringMonad","fieldNamePropertiesAmount","length","indexPartsFunctions","r","fn0","fn1","fn2","i","ceil","multipleOf","valueSpan","multipleOfParts","split","pow","getIndexStringLength","forEach","props","getPrimaryKeyFromIndexableString","indexableString","primaryKeyLength","paddedPrimaryKey","slice","primaryKey","trim","getNumberIndexString","nonDecimalsValueAsString","decimalPart","getStartIndexStringFromLowerBound","lowerBound","idx","bound","boolToStr","fillChar","repeat","add","getStartIndexStringFromUpperBound","upperBound","changeIndexableStringByOneQuantum","direction","lastChar","charCode","charCodeAt","withoutLastChar","String","fromCharCode"],"sources":["../../src/custom-index.ts"],"sourcesContent":["/**\r\n * For some RxStorage implementations,\r\n * we need to use our custom crafted indexes\r\n * so we can easily iterate over them. And sort plain arrays of document data.\r\n *\r\n * We really often have to craft an index string for a given document.\r\n * Performance of everything in this file is very important\r\n * which is why the code sometimes looks strange.\r\n * Run performance tests before and after you touch anything here!\r\n */\r\n\r\nimport {\r\n getSchemaByObjectPath\r\n} from './rx-schema-helper.ts';\r\nimport type {\r\n JsonSchema,\r\n RxDocumentData,\r\n RxJsonSchema\r\n} from './types/index.d.ts';\r\nimport {\r\n ensureNotFalsy,\r\n objectPathMonad,\r\n ObjectPathMonadFunction\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n INDEX_MAX,\r\n INDEX_MIN\r\n} from './query-planner.ts';\r\nimport {\r\n newRxError\r\n} from './rx-error.ts';\r\n\r\n\r\n/**\r\n * Prepare all relevant information\r\n * outside of the returned function\r\n * from getIndexableStringMonad()\r\n * to save performance when the returned\r\n * function is called many times.\r\n */\r\ntype IndexMetaField<RxDocType> = {\r\n fieldName: string;\r\n schemaPart: JsonSchema;\r\n /*\r\n * Only in number fields.\r\n */\r\n parsedLengths?: ParsedLengths;\r\n getValue: ObjectPathMonadFunction<RxDocType>;\r\n getIndexStringPart: (docData: RxDocumentData<RxDocType>) => string;\r\n};\r\n\r\nexport function getIndexMeta<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): IndexMetaField<RxDocType>[] {\r\n const fieldNameProperties: IndexMetaField<RxDocType>[] = index.map(fieldName => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n if (!schemaPart) {\r\n throw newRxError('CI1', { fieldName });\r\n }\r\n const type = schemaPart.type;\r\n let parsedLengths: ParsedLengths | undefined;\r\n if (type === 'number' || type === 'integer') {\r\n parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n }\r\n\r\n const getValue = objectPathMonad(fieldName);\r\n const maxLength = schemaPart.maxLength ? schemaPart.maxLength : 0;\r\n\r\n let getIndexStringPart: (docData: RxDocumentData<RxDocType>) => string;\r\n if (type === 'string') {\r\n getIndexStringPart = docData => {\r\n let fieldValue = getValue(docData);\r\n if (!fieldValue) {\r\n fieldValue = '';\r\n }\r\n return fieldValue.padEnd(maxLength, ' ');\r\n };\r\n } else if (type === 'boolean') {\r\n getIndexStringPart = docData => {\r\n const fieldValue = getValue(docData);\r\n return fieldValue ? '1' : '0';\r\n };\r\n } else { // number\r\n /**\r\n * @performance\r\n * Inline the number index string generation to avoid\r\n * function call overhead and redundant boundary checks.\r\n * Document data in the hot path is assumed to be valid.\r\n */\r\n const pLengths = parsedLengths as ParsedLengths;\r\n const pMin = pLengths.minimum;\r\n const pMax = pLengths.maximum;\r\n const pRoundedMin = pLengths.roundedMinimum;\r\n const pNonDecimals = pLengths.nonDecimals;\r\n const pDecimals = pLengths.decimals;\r\n const pMultiplier = pLengths.multiplier;\r\n if (pDecimals === 0) {\r\n getIndexStringPart = docData => {\r\n let fieldValue = getValue(docData);\r\n if (typeof fieldValue === 'undefined') {\r\n fieldValue = 0;\r\n }\r\n if (fieldValue < pMin) {\r\n fieldValue = pMin;\r\n }\r\n if (fieldValue > pMax) {\r\n fieldValue = pMax;\r\n }\r\n return (Math.floor(fieldValue) - pRoundedMin).toString().padStart(pNonDecimals, '0');\r\n };\r\n } else {\r\n getIndexStringPart = docData => {\r\n let fieldValue = getValue(docData);\r\n if (typeof fieldValue === 'undefined') {\r\n fieldValue = 0;\r\n }\r\n if (fieldValue < pMin) {\r\n fieldValue = pMin;\r\n }\r\n if (fieldValue > pMax) {\r\n fieldValue = pMax;\r\n }\r\n const flooredValue = Math.floor(fieldValue);\r\n const shifted = Math.min(\r\n Math.round((fieldValue - flooredValue) * pMultiplier),\r\n pMultiplier - 1\r\n );\r\n const str = (flooredValue - pRoundedMin).toString().padStart(pNonDecimals, '0');\r\n return str + shifted.toString().padStart(pDecimals, '0');\r\n };\r\n }\r\n }\r\n\r\n const ret: IndexMetaField<RxDocType> = {\r\n fieldName,\r\n schemaPart,\r\n parsedLengths,\r\n getValue,\r\n getIndexStringPart\r\n };\r\n return ret;\r\n });\r\n return fieldNameProperties;\r\n}\r\n\r\n\r\n/**\r\n * Crafts an indexable string that can be used\r\n * to check if a document would be sorted below or above\r\n * another documents, dependent on the index values.\r\n * @monad for better performance\r\n *\r\n * IMPORTANT: Performance is really important here\r\n * which is why we code so 'strange'.\r\n * Always run performance tests when you want to\r\n * change something in this method.\r\n */\r\nexport function getIndexableStringMonad<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): (docData: RxDocumentData<RxDocType>) => string {\r\n const fieldNameProperties = getIndexMeta(schema, index);\r\n const fieldNamePropertiesAmount = fieldNameProperties.length;\r\n const indexPartsFunctions = fieldNameProperties.map(r => r.getIndexStringPart);\r\n\r\n /**\r\n * @hotPath Performance of this function is very critical!\r\n * Specialize for common field counts to avoid loop overhead.\r\n */\r\n if (fieldNamePropertiesAmount === 1) {\r\n return indexPartsFunctions[0];\r\n }\r\n if (fieldNamePropertiesAmount === 2) {\r\n const fn0 = indexPartsFunctions[0];\r\n const fn1 = indexPartsFunctions[1];\r\n return (docData: RxDocumentData<RxDocType>): string => fn0(docData) + fn1(docData);\r\n }\r\n if (fieldNamePropertiesAmount === 3) {\r\n const fn0 = indexPartsFunctions[0];\r\n const fn1 = indexPartsFunctions[1];\r\n const fn2 = indexPartsFunctions[2];\r\n return (docData: RxDocumentData<RxDocType>): string => fn0(docData) + fn1(docData) + fn2(docData);\r\n }\r\n\r\n const ret = function (docData: RxDocumentData<RxDocType>): string {\r\n let str = '';\r\n for (let i = 0; i < fieldNamePropertiesAmount; ++i) {\r\n str += indexPartsFunctions[i](docData);\r\n }\r\n return str;\r\n };\r\n return ret;\r\n}\r\n\r\n\r\ndeclare type ParsedLengths = {\r\n minimum: number;\r\n maximum: number;\r\n nonDecimals: number;\r\n decimals: number;\r\n roundedMinimum: number;\r\n /**\r\n * Pre-computed Math.pow(10, decimals) to avoid\r\n * recomputing on every getNumberIndexString call.\r\n */\r\n multiplier: number;\r\n};\r\nexport function getStringLengthOfIndexNumber(\r\n schemaPart: JsonSchema\r\n): ParsedLengths {\r\n const minimum = Math.floor(schemaPart.minimum as number);\r\n const maximum = Math.ceil(schemaPart.maximum as number);\r\n const multipleOf: number = schemaPart.multipleOf as number;\r\n\r\n const valueSpan = maximum - minimum;\r\n const nonDecimals = valueSpan.toString().length;\r\n\r\n const multipleOfParts = multipleOf.toString().split('.');\r\n let decimals = 0;\r\n if (multipleOfParts.length > 1) {\r\n decimals = multipleOfParts[1].length;\r\n }\r\n return {\r\n minimum,\r\n maximum,\r\n nonDecimals,\r\n decimals,\r\n roundedMinimum: minimum,\r\n multiplier: Math.pow(10, decimals)\r\n };\r\n}\r\n\r\nexport function getIndexStringLength<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n index: string[]\r\n): number {\r\n const fieldNameProperties = getIndexMeta(schema, index);\r\n let length = 0;\r\n fieldNameProperties.forEach(props => {\r\n const schemaPart = props.schemaPart;\r\n const type = schemaPart.type;\r\n\r\n if (type === 'string') {\r\n length += schemaPart.maxLength as number;\r\n } else if (type === 'boolean') {\r\n length += 1;\r\n } else {\r\n const parsedLengths = props.parsedLengths as ParsedLengths;\r\n length = length + parsedLengths.nonDecimals + parsedLengths.decimals;\r\n }\r\n\r\n });\r\n return length;\r\n}\r\n\r\n\r\nexport function getPrimaryKeyFromIndexableString(\r\n indexableString: string,\r\n primaryKeyLength: number\r\n): string {\r\n const paddedPrimaryKey = indexableString.slice(primaryKeyLength * -1);\r\n // we can safely trim here because the primary key is not allowed to start or end with a space char.\r\n const primaryKey = paddedPrimaryKey.trim();\r\n return primaryKey;\r\n}\r\n\r\n\r\nexport function getNumberIndexString(\r\n parsedLengths: ParsedLengths,\r\n fieldValue: number\r\n): string {\r\n /**\r\n * Ensure that the given value is in the boundaries\r\n * of the schema, otherwise it would create a broken index string.\r\n * This can happen for example if you have a minimum of 0\r\n * and run a query like\r\n * selector {\r\n * numField: { $gt: -1000 }\r\n * }\r\n */\r\n if (typeof fieldValue === 'undefined') {\r\n fieldValue = 0;\r\n }\r\n if (fieldValue < parsedLengths.minimum) {\r\n fieldValue = parsedLengths.minimum;\r\n }\r\n if (fieldValue > parsedLengths.maximum) {\r\n fieldValue = parsedLengths.maximum;\r\n }\r\n\r\n const nonDecimalsValueAsString = (Math.floor(fieldValue) - parsedLengths.roundedMinimum).toString();\r\n let str = nonDecimalsValueAsString.padStart(parsedLengths.nonDecimals, '0');\r\n\r\n if (parsedLengths.decimals > 0) {\r\n /**\r\n * @performance\r\n * Use math to extract decimal digits instead of toString().split('.')\r\n * which creates intermediate strings and arrays.\r\n * multiplier is pre-computed in ParsedLengths to avoid Math.pow() per call.\r\n */\r\n const multiplier = parsedLengths.multiplier;\r\n const shifted = Math.min(\r\n Math.round((fieldValue - Math.floor(fieldValue)) * multiplier),\r\n multiplier - 1\r\n );\r\n const decimalPart = shifted.toString();\r\n str += decimalPart.padStart(parsedLengths.decimals, '0');\r\n }\r\n return str;\r\n}\r\n\r\nexport function getStartIndexStringFromLowerBound(\r\n schema: RxJsonSchema<any>,\r\n index: string[],\r\n lowerBound: (string | boolean | number | null | undefined)[]\r\n): string {\r\n let str = '';\r\n index.forEach((fieldName, idx) => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n const bound = lowerBound[idx];\r\n const type = schemaPart.type;\r\n\r\n switch (type) {\r\n case 'string':\r\n const maxLength = ensureNotFalsy(schemaPart.maxLength, 'maxLength not set');\r\n if (typeof bound === 'string') {\r\n str += (bound as string).padEnd(maxLength, ' ');\r\n } else {\r\n // str += ''.padStart(maxLength, inclusiveStart ? ' ' : INDEX_MAX);\r\n str += ''.padEnd(maxLength, ' ');\r\n }\r\n break;\r\n case 'boolean':\r\n if (bound === null) {\r\n str += '0';\r\n } else if (bound === INDEX_MIN) {\r\n str += '0';\r\n } else if (bound === INDEX_MAX) {\r\n str += '1';\r\n } else {\r\n const boolToStr = bound ? '1' : '0';\r\n str += boolToStr;\r\n }\r\n break;\r\n case 'number':\r\n case 'integer':\r\n const parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n if (bound === null || bound === INDEX_MIN) {\r\n const fillChar = '0';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else if (bound === INDEX_MAX) {\r\n str += getNumberIndexString(\r\n parsedLengths,\r\n parsedLengths.maximum\r\n );\r\n } else {\r\n const add = getNumberIndexString(\r\n parsedLengths,\r\n bound as number\r\n );\r\n str += add;\r\n }\r\n break;\r\n default:\r\n throw newRxError('CI2', { type: type as string });\r\n }\r\n });\r\n return str;\r\n}\r\n\r\n\r\nexport function getStartIndexStringFromUpperBound(\r\n schema: RxJsonSchema<any>,\r\n index: string[],\r\n upperBound: (string | boolean | number | null | undefined)[]\r\n): string {\r\n let str = '';\r\n index.forEach((fieldName, idx) => {\r\n const schemaPart = getSchemaByObjectPath(\r\n schema,\r\n fieldName\r\n );\r\n const bound = upperBound[idx];\r\n const type = schemaPart.type;\r\n\r\n switch (type) {\r\n case 'string':\r\n const maxLength = ensureNotFalsy(schemaPart.maxLength, 'maxLength not set');\r\n if (typeof bound === 'string' && bound !== INDEX_MAX) {\r\n str += (bound as string).padEnd(maxLength, ' ');\r\n } else if (bound === INDEX_MIN) {\r\n str += ''.padEnd(maxLength, ' ');\r\n } else {\r\n str += ''.padEnd(maxLength, INDEX_MAX);\r\n }\r\n break;\r\n case 'boolean':\r\n if (bound === null || bound === INDEX_MAX) {\r\n str += '1';\r\n } else if (bound === INDEX_MIN) {\r\n str += '0';\r\n } else {\r\n const boolToStr = bound ? '1' : '0';\r\n str += boolToStr;\r\n }\r\n break;\r\n case 'number':\r\n case 'integer':\r\n const parsedLengths = getStringLengthOfIndexNumber(\r\n schemaPart\r\n );\r\n if (bound === null || bound === INDEX_MAX) {\r\n const fillChar = '9';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else if (bound === INDEX_MIN) {\r\n const fillChar = '0';\r\n str += fillChar.repeat(parsedLengths.nonDecimals + parsedLengths.decimals);\r\n } else {\r\n str += getNumberIndexString(\r\n parsedLengths,\r\n bound as number\r\n );\r\n }\r\n break;\r\n default:\r\n throw newRxError('CI2', { type: type as string });\r\n }\r\n });\r\n return str;\r\n}\r\n\r\n/**\r\n * Used in storages where it is not possible\r\n * to define inclusiveEnd/inclusiveStart\r\n */\r\nexport function changeIndexableStringByOneQuantum(str: string, direction: 1 | -1): string {\r\n const lastChar = str.slice(-1);\r\n let charCode = lastChar.charCodeAt(0);\r\n charCode = charCode + direction;\r\n const withoutLastChar = str.slice(0, -1);\r\n return withoutLastChar + String.fromCharCode(charCode);\r\n}\r\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SACIA,qBAAqB,QAClB,uBAAuB;AAM9B,SACIC,cAAc,EACdC,eAAe,QAEZ,0BAA0B;AACjC,SACIC,SAAS,EACTC,SAAS,QACN,oBAAoB;AAC3B,SACIC,UAAU,QACP,eAAe;;AAGtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA,OAAO,SAASC,YAAYA,CACxBC,MAA+C,EAC/CC,KAAe,EACY;EAC3B,IAAMC,mBAAgD,GAAGD,KAAK,CAACE,GAAG,CAACC,SAAS,IAAI;IAC5E,IAAMC,UAAU,GAAGZ,qBAAqB,CACpCO,MAAM,EACNI,SACJ,CAAC;IACD,IAAI,CAACC,UAAU,EAAE;MACb,MAAMP,UAAU,CAAC,KAAK,EAAE;QAAEM;MAAU,CAAC,CAAC;IAC1C;IACA,IAAME,IAAI,GAAGD,UAAU,CAACC,IAAI;IAC5B,IAAIC,aAAwC;IAC5C,IAAID,IAAI,KAAK,QAAQ,IAAIA,IAAI,KAAK,SAAS,EAAE;MACzCC,aAAa,GAAGC,4BAA4B,CACxCH,UACJ,CAAC;IACL;IAEA,IAAMI,QAAQ,GAAGd,eAAe,CAACS,SAAS,CAAC;IAC3C,IAAMM,SAAS,GAAGL,UAAU,CAACK,SAAS,GAAGL,UAAU,CAACK,SAAS,GAAG,CAAC;IAEjE,IAAIC,kBAAkE;IACtE,IAAIL,IAAI,KAAK,QAAQ,EAAE;MACnBK,kBAAkB,GAAGC,OAAO,IAAI;QAC5B,IAAIC,UAAU,GAAGJ,QAAQ,CAACG,OAAO,CAAC;QAClC,IAAI,CAACC,UAAU,EAAE;UACbA,UAAU,GAAG,EAAE;QACnB;QACA,OAAOA,UAAU,CAACC,MAAM,CAACJ,SAAS,EAAE,GAAG,CAAC;MAC5C,CAAC;IACL,CAAC,MAAM,IAAIJ,IAAI,KAAK,SAAS,EAAE;MAC3BK,kBAAkB,GAAGC,OAAO,IAAI;QAC5B,IAAMC,UAAU,GAAGJ,QAAQ,CAACG,OAAO,CAAC;QACpC,OAAOC,UAAU,GAAG,GAAG,GAAG,GAAG;MACjC,CAAC;IACL,CAAC,MAAM;MAAE;MACL;AACZ;AACA;AACA;AACA;AACA;MACY,IAAME,QAAQ,GAAGR,aAA8B;MAC/C,IAAMS,IAAI,GAAGD,QAAQ,CAACE,OAAO;MAC7B,IAAMC,IAAI,GAAGH,QAAQ,CAACI,OAAO;MAC7B,IAAMC,WAAW,GAAGL,QAAQ,CAACM,cAAc;MAC3C,IAAMC,YAAY,GAAGP,QAAQ,CAACQ,WAAW;MACzC,IAAMC,SAAS,GAAGT,QAAQ,CAACU,QAAQ;MACnC,IAAMC,WAAW,GAAGX,QAAQ,CAACY,UAAU;MACvC,IAAIH,SAAS,KAAK,CAAC,EAAE;QACjBb,kBAAkB,GAAGC,OAAO,IAAI;UAC5B,IAAIC,UAAU,GAAGJ,QAAQ,CAACG,OAAO,CAAC;UAClC,IAAI,OAAOC,UAAU,KAAK,WAAW,EAAE;YACnCA,UAAU,GAAG,CAAC;UAClB;UACA,IAAIA,UAAU,GAAGG,IAAI,EAAE;YACnBH,UAAU,GAAGG,IAAI;UACrB;UACA,IAAIH,UAAU,GAAGK,IAAI,EAAE;YACnBL,UAAU,GAAGK,IAAI;UACrB;UACA,OAAO,CAACU,IAAI,CAACC,KAAK,CAAChB,UAAU,CAAC,GAAGO,WAAW,EAAEU,QAAQ,CAAC,CAAC,CAACC,QAAQ,CAACT,YAAY,EAAE,GAAG,CAAC;QACxF,CAAC;MACL,CAAC,MAAM;QACHX,kBAAkB,GAAGC,OAAO,IAAI;UAC5B,IAAIC,UAAU,GAAGJ,QAAQ,CAACG,OAAO,CAAC;UAClC,IAAI,OAAOC,UAAU,KAAK,WAAW,EAAE;YACnCA,UAAU,GAAG,CAAC;UAClB;UACA,IAAIA,UAAU,GAAGG,IAAI,EAAE;YACnBH,UAAU,GAAGG,IAAI;UACrB;UACA,IAAIH,UAAU,GAAGK,IAAI,EAAE;YACnBL,UAAU,GAAGK,IAAI;UACrB;UACA,IAAMc,YAAY,GAAGJ,IAAI,CAACC,KAAK,CAAChB,UAAU,CAAC;UAC3C,IAAMoB,OAAO,GAAGL,IAAI,CAACM,GAAG,CACpBN,IAAI,CAACO,KAAK,CAAC,CAACtB,UAAU,GAAGmB,YAAY,IAAIN,WAAW,CAAC,EACrDA,WAAW,GAAG,CAClB,CAAC;UACD,IAAMU,GAAG,GAAG,CAACJ,YAAY,GAAGZ,WAAW,EAAEU,QAAQ,CAAC,CAAC,CAACC,QAAQ,CAACT,YAAY,EAAE,GAAG,CAAC;UAC/E,OAAOc,GAAG,GAAGH,OAAO,CAACH,QAAQ,CAAC,CAAC,CAACC,QAAQ,CAACP,SAAS,EAAE,GAAG,CAAC;QAC5D,CAAC;MACL;IACJ;IAEA,IAAMa,GAA8B,GAAG;MACnCjC,SAAS;MACTC,UAAU;MACVE,aAAa;MACbE,QAAQ;MACRE;IACJ,CAAC;IACD,OAAO0B,GAAG;EACd,CAAC,CAAC;EACF,OAAOnC,mBAAmB;AAC9B;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASoC,uBAAuBA,CACnCtC,MAA+C,EAC/CC,KAAe,EAC+B;EAC9C,IAAMC,mBAAmB,GAAGH,YAAY,CAACC,MAAM,EAAEC,KAAK,CAAC;EACvD,IAAMsC,yBAAyB,GAAGrC,mBAAmB,CAACsC,MAAM;EAC5D,IAAMC,mBAAmB,GAAGvC,mBAAmB,CAACC,GAAG,CAACuC,CAAC,IAAIA,CAAC,CAAC/B,kBAAkB,CAAC;;EAE9E;AACJ;AACA;AACA;EACI,IAAI4B,yBAAyB,KAAK,CAAC,EAAE;IACjC,OAAOE,mBAAmB,CAAC,CAAC,CAAC;EACjC;EACA,IAAIF,yBAAyB,KAAK,CAAC,EAAE;IACjC,IAAMI,GAAG,GAAGF,mBAAmB,CAAC,CAAC,CAAC;IAClC,IAAMG,GAAG,GAAGH,mBAAmB,CAAC,CAAC,CAAC;IAClC,OAAQ7B,OAAkC,IAAa+B,GAAG,CAAC/B,OAAO,CAAC,GAAGgC,GAAG,CAAChC,OAAO,CAAC;EACtF;EACA,IAAI2B,yBAAyB,KAAK,CAAC,EAAE;IACjC,IAAMI,GAAG,GAAGF,mBAAmB,CAAC,CAAC,CAAC;IAClC,IAAMG,IAAG,GAAGH,mBAAmB,CAAC,CAAC,CAAC;IAClC,IAAMI,GAAG,GAAGJ,mBAAmB,CAAC,CAAC,CAAC;IAClC,OAAQ7B,OAAkC,IAAa+B,GAAG,CAAC/B,OAAO,CAAC,GAAGgC,IAAG,CAAChC,OAAO,CAAC,GAAGiC,GAAG,CAACjC,OAAO,CAAC;EACrG;EAEA,IAAMyB,GAAG,GAAG,SAAAA,CAAUzB,OAAkC,EAAU;IAC9D,IAAIwB,GAAG,GAAG,EAAE;IACZ,KAAK,IAAIU,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGP,yBAAyB,EAAE,EAAEO,CAAC,EAAE;MAChDV,GAAG,IAAIK,mBAAmB,CAACK,CAAC,CAAC,CAAClC,OAAO,CAAC;IAC1C;IACA,OAAOwB,GAAG;EACd,CAAC;EACD,OAAOC,GAAG;AACd;AAeA,OAAO,SAAS7B,4BAA4BA,CACxCH,UAAsB,EACT;EACb,IAAMY,OAAO,GAAGW,IAAI,CAACC,KAAK,CAACxB,UAAU,CAACY,OAAiB,CAAC;EACxD,IAAME,OAAO,GAAGS,IAAI,CAACmB,IAAI,CAAC1C,UAAU,CAACc,OAAiB,CAAC;EACvD,IAAM6B,UAAkB,GAAG3C,UAAU,CAAC2C,UAAoB;EAE1D,IAAMC,SAAS,GAAG9B,OAAO,GAAGF,OAAO;EACnC,IAAMM,WAAW,GAAG0B,SAAS,CAACnB,QAAQ,CAAC,CAAC,CAACU,MAAM;EAE/C,IAAMU,eAAe,GAAGF,UAAU,CAAClB,QAAQ,CAAC,CAAC,CAACqB,KAAK,CAAC,GAAG,CAAC;EACxD,IAAI1B,QAAQ,GAAG,CAAC;EAChB,IAAIyB,eAAe,CAACV,MAAM,GAAG,CAAC,EAAE;IAC5Bf,QAAQ,GAAGyB,eAAe,CAAC,CAAC,CAAC,CAACV,MAAM;EACxC;EACA,OAAO;IACHvB,OAAO;IACPE,OAAO;IACPI,WAAW;IACXE,QAAQ;IACRJ,cAAc,EAAEJ,OAAO;IACvBU,UAAU,EAAEC,IAAI,CAACwB,GAAG,CAAC,EAAE,EAAE3B,QAAQ;EACrC,CAAC;AACL;AAEA,OAAO,SAAS4B,oBAAoBA,CAChCrD,MAA+C,EAC/CC,KAAe,EACT;EACN,IAAMC,mBAAmB,GAAGH,YAAY,CAACC,MAAM,EAAEC,KAAK,CAAC;EACvD,IAAIuC,MAAM,GAAG,CAAC;EACdtC,mBAAmB,CAACoD,OAAO,CAACC,KAAK,IAAI;IACjC,IAAMlD,UAAU,GAAGkD,KAAK,CAAClD,UAAU;IACnC,IAAMC,IAAI,GAAGD,UAAU,CAACC,IAAI;IAE5B,IAAIA,IAAI,KAAK,QAAQ,EAAE;MACnBkC,MAAM,IAAInC,UAAU,CAACK,SAAmB;IAC5C,CAAC,MAAM,IAAIJ,IAAI,KAAK,SAAS,EAAE;MAC3BkC,MAAM,IAAI,CAAC;IACf,CAAC,MAAM;MACH,IAAMjC,aAAa,GAAGgD,KAAK,CAAChD,aAA8B;MAC1DiC,MAAM,GAAGA,MAAM,GAAGjC,aAAa,CAACgB,WAAW,GAAGhB,aAAa,CAACkB,QAAQ;IACxE;EAEJ,CAAC,CAAC;EACF,OAAOe,MAAM;AACjB;AAGA,OAAO,SAASgB,gCAAgCA,CAC5CC,eAAuB,EACvBC,gBAAwB,EAClB;EACN,IAAMC,gBAAgB,GAAGF,eAAe,CAACG,KAAK,CAACF,gBAAgB,GAAG,CAAC,CAAC,CAAC;EACrE;EACA,IAAMG,UAAU,GAAGF,gBAAgB,CAACG,IAAI,CAAC,CAAC;EAC1C,OAAOD,UAAU;AACrB;AAGA,OAAO,SAASE,oBAAoBA,CAChCxD,aAA4B,EAC5BM,UAAkB,EACZ;EACN;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,IAAI,OAAOA,UAAU,KAAK,WAAW,EAAE;IACnCA,UAAU,GAAG,CAAC;EAClB;EACA,IAAIA,UAAU,GAAGN,aAAa,CAACU,OAAO,EAAE;IACpCJ,UAAU,GAAGN,aAAa,CAACU,OAAO;EACtC;EACA,IAAIJ,UAAU,GAAGN,aAAa,CAACY,OAAO,EAAE;IACpCN,UAAU,GAAGN,aAAa,CAACY,OAAO;EACtC;EAEA,IAAM6C,wBAAwB,GAAG,CAACpC,IAAI,CAACC,KAAK,CAAChB,UAAU,CAAC,GAAGN,aAAa,CAACc,cAAc,EAAES,QAAQ,CAAC,CAAC;EACnG,IAAIM,GAAG,GAAG4B,wBAAwB,CAACjC,QAAQ,CAACxB,aAAa,CAACgB,WAAW,EAAE,GAAG,CAAC;EAE3E,IAAIhB,aAAa,CAACkB,QAAQ,GAAG,CAAC,EAAE;IAC5B;AACR;AACA;AACA;AACA;AACA;IACQ,IAAME,UAAU,GAAGpB,aAAa,CAACoB,UAAU;IAC3C,IAAMM,OAAO,GAAGL,IAAI,CAACM,GAAG,CACpBN,IAAI,CAACO,KAAK,CAAC,CAACtB,UAAU,GAAGe,IAAI,CAACC,KAAK,CAAChB,UAAU,CAAC,IAAIc,UAAU,CAAC,EAC9DA,UAAU,GAAG,CACjB,CAAC;IACD,IAAMsC,WAAW,GAAGhC,OAAO,CAACH,QAAQ,CAAC,CAAC;IACtCM,GAAG,IAAI6B,WAAW,CAAClC,QAAQ,CAACxB,aAAa,CAACkB,QAAQ,EAAE,GAAG,CAAC;EAC5D;EACA,OAAOW,GAAG;AACd;AAEA,OAAO,SAAS8B,iCAAiCA,CAC7ClE,MAAyB,EACzBC,KAAe,EACfkE,UAA4D,EACtD;EACN,IAAI/B,GAAG,GAAG,EAAE;EACZnC,KAAK,CAACqD,OAAO,CAAC,CAAClD,SAAS,EAAEgE,GAAG,KAAK;IAC9B,IAAM/D,UAAU,GAAGZ,qBAAqB,CACpCO,MAAM,EACNI,SACJ,CAAC;IACD,IAAMiE,KAAK,GAAGF,UAAU,CAACC,GAAG,CAAC;IAC7B,IAAM9D,IAAI,GAAGD,UAAU,CAACC,IAAI;IAE5B,QAAQA,IAAI;MACR,KAAK,QAAQ;QACT,IAAMI,SAAS,GAAGhB,cAAc,CAACW,UAAU,CAACK,SAAS,EAAE,mBAAmB,CAAC;QAC3E,IAAI,OAAO2D,KAAK,KAAK,QAAQ,EAAE;UAC3BjC,GAAG,IAAKiC,KAAK,CAAYvD,MAAM,CAACJ,SAAS,EAAE,GAAG,CAAC;QACnD,CAAC,MAAM;UACH;UACA0B,GAAG,IAAI,EAAE,CAACtB,MAAM,CAACJ,SAAS,EAAE,GAAG,CAAC;QACpC;QACA;MACJ,KAAK,SAAS;QACV,IAAI2D,KAAK,KAAK,IAAI,EAAE;UAChBjC,GAAG,IAAI,GAAG;QACd,CAAC,MAAM,IAAIiC,KAAK,KAAKxE,SAAS,EAAE;UAC5BuC,GAAG,IAAI,GAAG;QACd,CAAC,MAAM,IAAIiC,KAAK,KAAKzE,SAAS,EAAE;UAC5BwC,GAAG,IAAI,GAAG;QACd,CAAC,MAAM;UACH,IAAMkC,SAAS,GAAGD,KAAK,GAAG,GAAG,GAAG,GAAG;UACnCjC,GAAG,IAAIkC,SAAS;QACpB;QACA;MACJ,KAAK,QAAQ;MACb,KAAK,SAAS;QACV,IAAM/D,aAAa,GAAGC,4BAA4B,CAC9CH,UACJ,CAAC;QACD,IAAIgE,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKxE,SAAS,EAAE;UACvC,IAAM0E,QAAQ,GAAG,GAAG;UACpBnC,GAAG,IAAImC,QAAQ,CAACC,MAAM,CAACjE,aAAa,CAACgB,WAAW,GAAGhB,aAAa,CAACkB,QAAQ,CAAC;QAC9E,CAAC,MAAM,IAAI4C,KAAK,KAAKzE,SAAS,EAAE;UAC5BwC,GAAG,IAAI2B,oBAAoB,CACvBxD,aAAa,EACbA,aAAa,CAACY,OAClB,CAAC;QACL,CAAC,MAAM;UACH,IAAMsD,GAAG,GAAGV,oBAAoB,CAC5BxD,aAAa,EACb8D,KACJ,CAAC;UACDjC,GAAG,IAAIqC,GAAG;QACd;QACA;MACJ;QACI,MAAM3E,UAAU,CAAC,KAAK,EAAE;UAAEQ,IAAI,EAAEA;QAAe,CAAC,CAAC;IACzD;EACJ,CAAC,CAAC;EACF,OAAO8B,GAAG;AACd;AAGA,OAAO,SAASsC,iCAAiCA,CAC7C1E,MAAyB,EACzBC,KAAe,EACf0E,UAA4D,EACtD;EACN,IAAIvC,GAAG,GAAG,EAAE;EACZnC,KAAK,CAACqD,OAAO,CAAC,CAAClD,SAAS,EAAEgE,GAAG,KAAK;IAC9B,IAAM/D,UAAU,GAAGZ,qBAAqB,CACpCO,MAAM,EACNI,SACJ,CAAC;IACD,IAAMiE,KAAK,GAAGM,UAAU,CAACP,GAAG,CAAC;IAC7B,IAAM9D,IAAI,GAAGD,UAAU,CAACC,IAAI;IAE5B,QAAQA,IAAI;MACR,KAAK,QAAQ;QACT,IAAMI,SAAS,GAAGhB,cAAc,CAACW,UAAU,CAACK,SAAS,EAAE,mBAAmB,CAAC;QAC3E,IAAI,OAAO2D,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAKzE,SAAS,EAAE;UAClDwC,GAAG,IAAKiC,KAAK,CAAYvD,MAAM,CAACJ,SAAS,EAAE,GAAG,CAAC;QACnD,CAAC,MAAM,IAAI2D,KAAK,KAAKxE,SAAS,EAAE;UAC5BuC,GAAG,IAAI,EAAE,CAACtB,MAAM,CAACJ,SAAS,EAAE,GAAG,CAAC;QACpC,CAAC,MAAM;UACH0B,GAAG,IAAI,EAAE,CAACtB,MAAM,CAACJ,SAAS,EAAEd,SAAS,CAAC;QAC1C;QACA;MACJ,KAAK,SAAS;QACV,IAAIyE,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKzE,SAAS,EAAE;UACvCwC,GAAG,IAAI,GAAG;QACd,CAAC,MAAM,IAAIiC,KAAK,KAAKxE,SAAS,EAAE;UAC5BuC,GAAG,IAAI,GAAG;QACd,CAAC,MAAM;UACH,IAAMkC,SAAS,GAAGD,KAAK,GAAG,GAAG,GAAG,GAAG;UACnCjC,GAAG,IAAIkC,SAAS;QACpB;QACA;MACJ,KAAK,QAAQ;MACb,KAAK,SAAS;QACV,IAAM/D,aAAa,GAAGC,4BAA4B,CAC9CH,UACJ,CAAC;QACD,IAAIgE,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKzE,SAAS,EAAE;UACvC,IAAM2E,QAAQ,GAAG,GAAG;UACpBnC,GAAG,IAAImC,QAAQ,CAACC,MAAM,CAACjE,aAAa,CAACgB,WAAW,GAAGhB,aAAa,CAACkB,QAAQ,CAAC;QAC9E,CAAC,MAAM,IAAI4C,KAAK,KAAKxE,SAAS,EAAE;UAC5B,IAAM0E,SAAQ,GAAG,GAAG;UACpBnC,GAAG,IAAImC,SAAQ,CAACC,MAAM,CAACjE,aAAa,CAACgB,WAAW,GAAGhB,aAAa,CAACkB,QAAQ,CAAC;QAC9E,CAAC,MAAM;UACHW,GAAG,IAAI2B,oBAAoB,CACvBxD,aAAa,EACb8D,KACJ,CAAC;QACL;QACA;MACJ;QACI,MAAMvE,UAAU,CAAC,KAAK,EAAE;UAAEQ,IAAI,EAAEA;QAAe,CAAC,CAAC;IACzD;EACJ,CAAC,CAAC;EACF,OAAO8B,GAAG;AACd;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASwC,iCAAiCA,CAACxC,GAAW,EAAEyC,SAAiB,EAAU;EACtF,IAAMC,QAAQ,GAAG1C,GAAG,CAACwB,KAAK,CAAC,CAAC,CAAC,CAAC;EAC9B,IAAImB,QAAQ,GAAGD,QAAQ,CAACE,UAAU,CAAC,CAAC,CAAC;EACrCD,QAAQ,GAAGA,QAAQ,GAAGF,SAAS;EAC/B,IAAMI,eAAe,GAAG7C,GAAG,CAACwB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACxC,OAAOqB,eAAe,GAAGC,MAAM,CAACC,YAAY,CAACJ,QAAQ,CAAC;AAC1D","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import _createClass from "@babel/runtime/helpers/createClass";
2
- import { getFromMapOrThrow, getHeightOfRevision, overwriteGetterForCaching, requestIdlePromiseNoQueue } from "./plugins/utils/index.js";
2
+ import { getFromMapOrThrow, overwriteGetterForCaching, requestIdlePromiseNoQueue } from "./plugins/utils/index.js";
3
3
  import { overwritable } from "./overwritable.js";
4
4
 
5
5
  /**
@@ -47,7 +47,7 @@ export var DocumentCache = /*#__PURE__*/function () {
47
47
  var docId = docMeta.docId;
48
48
  var cacheItem = this.cacheItemByDocId.get(docId);
49
49
  if (cacheItem) {
50
- cacheItem[0].delete(docMeta.revisionHeight + docMeta.lwt + '');
50
+ cacheItem[0].delete(docMeta.rev + docMeta.lwt);
51
51
  if (cacheItem[0].size === 0) {
52
52
  /**
53
53
  * No state of the document is cached anymore,
@@ -87,8 +87,7 @@ export var DocumentCache = /*#__PURE__*/function () {
87
87
  if (this.tasks.size === 0) {
88
88
  return;
89
89
  }
90
- var tasks = Array.from(this.tasks);
91
- tasks.forEach(task => task());
90
+ this.tasks.forEach(task => task());
92
91
  this.tasks.clear();
93
92
  }
94
93
 
@@ -123,12 +122,77 @@ export var DocumentCache = /*#__PURE__*/function () {
123
122
  }, {
124
123
  key: "getCachedRxDocument",
125
124
  get: function () {
126
- var fn = getCachedRxDocumentMonad(this);
127
- return overwriteGetterForCaching(this, 'getCachedRxDocument', doc => fn([doc])[0]);
125
+ var fn = getCachedRxDocumentSingle(this);
126
+ return overwriteGetterForCaching(this, 'getCachedRxDocument', fn);
128
127
  }
129
128
  }]);
130
129
  }();
131
130
 
131
+ /**
132
+ * @hotPath Dedicated single-document function that avoids array allocations.
133
+ * Used by getCachedRxDocument which is called from many call sites.
134
+ */
135
+ function getCachedRxDocumentSingle(docCache) {
136
+ var primaryPath = docCache.primaryPath;
137
+ var cacheItemByDocId = docCache.cacheItemByDocId;
138
+ var registry = docCache.registry;
139
+ var deepFreezeWhenDevMode = overwritable.deepFreezeWhenDevMode;
140
+ var documentCreator = docCache.documentCreator;
141
+ return docData => {
142
+ var docId = docData[primaryPath];
143
+ var rev = docData._rev;
144
+ var lwt = docData._meta.lwt;
145
+ var cacheKey = rev + lwt;
146
+ var cacheItem = cacheItemByDocId.get(docId);
147
+ if (!cacheItem) {
148
+ docData = deepFreezeWhenDevMode(docData);
149
+ var newDoc = documentCreator(docData);
150
+ var newByRev = new Map();
151
+ newByRev.set(cacheKey, createWeakRefWithFallback(newDoc));
152
+ cacheItemByDocId.set(docId, [newByRev, docData]);
153
+ if (registry) {
154
+ docCache.tasks.add(() => {
155
+ registry.register(newDoc, {
156
+ docId: newDoc.primary,
157
+ rev,
158
+ lwt
159
+ });
160
+ });
161
+ if (docCache.tasks.size <= 1) {
162
+ requestIdlePromiseNoQueue().then(() => {
163
+ docCache.processTasks();
164
+ });
165
+ }
166
+ }
167
+ return newDoc;
168
+ }
169
+ var byRev = cacheItem[0];
170
+ var cachedRxDocumentWeakRef = byRev.get(cacheKey);
171
+ var cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;
172
+ if (!cachedRxDocument) {
173
+ docData = deepFreezeWhenDevMode(docData);
174
+ cachedRxDocument = documentCreator(docData);
175
+ byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));
176
+ if (registry) {
177
+ var registeredDoc = cachedRxDocument;
178
+ docCache.tasks.add(() => {
179
+ registry.register(registeredDoc, {
180
+ docId: registeredDoc.primary,
181
+ rev,
182
+ lwt
183
+ });
184
+ });
185
+ if (docCache.tasks.size <= 1) {
186
+ requestIdlePromiseNoQueue().then(() => {
187
+ docCache.processTasks();
188
+ });
189
+ }
190
+ }
191
+ }
192
+ return cachedRxDocument;
193
+ };
194
+ }
195
+
132
196
  /**
133
197
  * This function is called very very often.
134
198
  * @hotPath This is one of the most important methods for performance.
@@ -142,53 +206,71 @@ function getCachedRxDocumentMonad(docCache) {
142
206
  var documentCreator = docCache.documentCreator;
143
207
  var fn = docsData => {
144
208
  var ret = new Array(docsData.length);
145
- var registryTasks = [];
209
+ var registryTasks;
146
210
  for (var index = 0; index < docsData.length; index++) {
147
211
  var docData = docsData[index];
148
212
  var docId = docData[primaryPath];
149
- var revisionHeight = getHeightOfRevision(docData._rev);
150
-
151
- /**
152
- * @performance
153
- * Compute the byRev cache key once and reuse it
154
- * for both the Map.get() and Map.set() calls.
155
- */
156
- var cacheKey = revisionHeight + docData._meta.lwt + '';
157
- var byRev = void 0;
158
- var cachedRxDocumentWeakRef = void 0;
213
+ var rev = docData._rev;
214
+ var lwt = docData._meta.lwt;
215
+ var cacheKey = rev + lwt;
159
216
  var cacheItem = cacheItemByDocId.get(docId);
160
217
  if (!cacheItem) {
161
- byRev = new Map();
162
- cacheItem = [byRev, docData];
163
- cacheItemByDocId.set(docId, cacheItem);
164
- } else {
165
- byRev = cacheItem[0];
166
- cachedRxDocumentWeakRef = byRev.get(cacheKey);
167
- }
168
- var cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;
169
- if (!cachedRxDocument) {
218
+ /**
219
+ * New document - no need for WeakRef lookup.
220
+ * Create cache item directly.
221
+ */
170
222
  docData = deepFreezeWhenDevMode(docData);
171
- cachedRxDocument = documentCreator(docData);
223
+ var cachedRxDocument = documentCreator(docData);
224
+ var byRev = new Map();
172
225
  byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));
226
+ cacheItemByDocId.set(docId, [byRev, docData]);
227
+ ret[index] = cachedRxDocument;
173
228
  if (registry) {
174
- registryTasks.push(cachedRxDocument);
229
+ if (!registryTasks) {
230
+ registryTasks = [];
231
+ }
232
+ registryTasks.push({
233
+ doc: cachedRxDocument,
234
+ rev,
235
+ lwt
236
+ });
237
+ }
238
+ } else {
239
+ var _byRev = cacheItem[0];
240
+ var cachedRxDocumentWeakRef = _byRev.get(cacheKey);
241
+ var _cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;
242
+ if (!_cachedRxDocument) {
243
+ docData = deepFreezeWhenDevMode(docData);
244
+ _cachedRxDocument = documentCreator(docData);
245
+ _byRev.set(cacheKey, createWeakRefWithFallback(_cachedRxDocument));
246
+ if (registry) {
247
+ if (!registryTasks) {
248
+ registryTasks = [];
249
+ }
250
+ registryTasks.push({
251
+ doc: _cachedRxDocument,
252
+ rev,
253
+ lwt
254
+ });
255
+ }
175
256
  }
257
+ ret[index] = _cachedRxDocument;
176
258
  }
177
- ret[index] = cachedRxDocument;
178
259
  }
179
- if (registryTasks.length > 0 && registry) {
260
+ if (registryTasks && registry) {
180
261
  /**
181
262
  * Calling registry.register() has shown to have
182
263
  * really bad performance. So we add the cached documents
183
264
  * lazily.
184
265
  */
266
+ var tasks = registryTasks;
185
267
  docCache.tasks.add(() => {
186
- for (var _index = 0; _index < registryTasks.length; _index++) {
187
- var doc = registryTasks[_index];
188
- registry.register(doc, {
189
- docId: doc.primary,
190
- revisionHeight: getHeightOfRevision(doc.revision),
191
- lwt: doc._data._meta.lwt
268
+ for (var _index = 0; _index < tasks.length; _index++) {
269
+ var task = tasks[_index];
270
+ registry.register(task.doc, {
271
+ docId: task.doc.primary,
272
+ rev: task.rev,
273
+ lwt: task.lwt
192
274
  });
193
275
  }
194
276
  });
@@ -1 +1 @@
1
- {"version":3,"file":"doc-cache.js","names":["getFromMapOrThrow","getHeightOfRevision","overwriteGetterForCaching","requestIdlePromiseNoQueue","overwritable","DocumentCache","primaryPath","changes$","documentCreator","cacheItemByDocId","Map","tasks","Set","registry","FinalizationRegistry","docMeta","docId","cacheItem","get","delete","revisionHeight","lwt","size","undefined","subscribe","events","add","index","length","event","documentId","documentData","previousDocumentData","then","processTasks","_proto","prototype","Array","from","forEach","task","clear","getLatestDocumentData","getLatestDocumentDataIfExists","_createClass","key","fn","getCachedRxDocumentMonad","doc","docCache","deepFreezeWhenDevMode","docsData","ret","registryTasks","docData","_rev","cacheKey","_meta","byRev","cachedRxDocumentWeakRef","set","cachedRxDocument","deref","createWeakRefWithFallback","push","register","primary","revision","_data","mapDocumentsDataToCacheDocs","getCachedRxDocuments","HAS_WEAK_REF","WeakRef","createWeakRef","createWeakRefFallback","obj"],"sources":["../../src/doc-cache.ts"],"sourcesContent":["import type {\r\n RxDocument,\r\n RxDocumentData,\r\n RxStorageChangeEvent,\r\n WeakRef,\r\n FinalizationRegistry\r\n} from './types/index.d.ts';\r\nimport {\r\n getFromMapOrThrow,\r\n getHeightOfRevision,\r\n overwriteGetterForCaching,\r\n requestIdlePromiseNoQueue\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n overwritable\r\n} from './overwritable.ts';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Because we have to create many cache items,\r\n * we use an array instead of an object with properties\r\n * for better performance and less memory usage.\r\n * @link https://stackoverflow.com/questions/17295056/array-vs-object-efficiency-in-javascript\r\n */\r\ndeclare type CacheItem<RxDocType, OrmMethods> = [\r\n /**\r\n * Store the different document states of time\r\n * based on their [revisionHeight+_meta.lwt] .\r\n * We store WeakRefs so that we can later clean up\r\n * document states that are no longer needed.\r\n *\r\n * Notice that we can not only rely on the revisionHeight\r\n * because when cleanup is used, two document states can end up with\r\n * the same revision but different _meta.lwt.\r\n */\r\n Map<string, WeakRef<RxDocument<RxDocType, OrmMethods>>>,\r\n\r\n /**\r\n * Store the latest known document state.\r\n * As long as any state of the document is in the cache,\r\n * we observe the changestream and update the latestDoc accordingly.\r\n * This makes it easier to optimize performance on other parts\r\n * because for each known document we can always get the current state\r\n * in the storage.\r\n * Also it makes it possible to call RxDocument.latest() in a non-async way\r\n * to retrieve the latest document state or to observe$ some property.\r\n *\r\n * To not prevent the whole cacheItem from being garbage collected,\r\n * we store only the document data here, but not the RxDocument.\r\n */\r\n RxDocumentData<RxDocType>\r\n];\r\n\r\n\r\n/**\r\n * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry\r\n */\r\ndeclare type FinalizationRegistryValue = {\r\n docId: string;\r\n revisionHeight: number;\r\n lwt: number;\r\n};\r\n\r\n/**\r\n * The DocumentCache stores RxDocument objects\r\n * by their primary key and revision.\r\n * This is useful on client side applications where\r\n * it is not known how much memory can be used, so\r\n * we de-duplicate RxDocument states to save memory.\r\n * To not fill up the memory with old document states, the DocumentCache\r\n * only contains weak references to the RxDocuments themself.\r\n * @link https://caniuse.com/?search=weakref\r\n */\r\nexport class DocumentCache<RxDocType, OrmMethods> {\r\n public readonly cacheItemByDocId = new Map<string, CacheItem<RxDocType, OrmMethods>>();\r\n\r\n /**\r\n * Process stuff lazy to not block the CPU\r\n * on critical paths.\r\n */\r\n public readonly tasks = new Set<Function>();\r\n\r\n /**\r\n * Some JavaScript runtimes like QuickJS,\r\n * so not have a FinalizationRegistry or WeakRef.\r\n * Therefore we need a workaround which might waste a lot of memory,\r\n * but at least works.\r\n */\r\n public readonly registry?: FinalizationRegistry<FinalizationRegistryValue> = typeof FinalizationRegistry === 'function' ?\r\n new FinalizationRegistry<FinalizationRegistryValue>(docMeta => {\r\n const docId = docMeta.docId;\r\n const cacheItem = this.cacheItemByDocId.get(docId);\r\n if (cacheItem) {\r\n cacheItem[0].delete(docMeta.revisionHeight + docMeta.lwt + '');\r\n if (cacheItem[0].size === 0) {\r\n /**\r\n * No state of the document is cached anymore,\r\n * so we can clean up.\r\n */\r\n this.cacheItemByDocId.delete(docId);\r\n }\r\n }\r\n }) as any :\r\n undefined;\r\n\r\n constructor(\r\n public readonly primaryPath: string,\r\n public readonly changes$: Observable<RxStorageChangeEvent<RxDocType>[]>,\r\n /**\r\n * A method that can create a RxDocument by the given document data.\r\n */\r\n public documentCreator: (docData: RxDocumentData<RxDocType>) => RxDocument<RxDocType, OrmMethods>\r\n ) {\r\n changes$.subscribe((events: RxStorageChangeEvent<RxDocType>[]) => {\r\n this.tasks.add(() => {\r\n const cacheItemByDocId = this.cacheItemByDocId;\r\n for (let index = 0; index < events.length; index++) {\r\n const event = events[index];\r\n const cacheItem = cacheItemByDocId.get(event.documentId);\r\n if (cacheItem) {\r\n let documentData = event.documentData;\r\n if (!documentData) {\r\n documentData = event.previousDocumentData as any;\r\n }\r\n cacheItem[1] = documentData;\r\n }\r\n }\r\n });\r\n if (this.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n this.processTasks();\r\n });\r\n }\r\n });\r\n }\r\n\r\n public processTasks() {\r\n if (this.tasks.size === 0) {\r\n return;\r\n }\r\n const tasks = Array.from(this.tasks);\r\n tasks.forEach(task => task());\r\n this.tasks.clear();\r\n }\r\n\r\n /**\r\n * Get the RxDocument from the cache\r\n * and create a new one if not exits before.\r\n * @overwrites itself with the actual function\r\n * because this is @performance relevant.\r\n * It is called on each document row for each write and read.\r\n */\r\n get getCachedRxDocuments(): (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] {\r\n const fn = getCachedRxDocumentMonad(this);\r\n return overwriteGetterForCaching(\r\n this,\r\n 'getCachedRxDocuments',\r\n fn\r\n );\r\n }\r\n\r\n get getCachedRxDocument(): (docData: RxDocumentData<RxDocType>) => RxDocument<RxDocType, OrmMethods> {\r\n const fn = getCachedRxDocumentMonad(this);\r\n return overwriteGetterForCaching(\r\n this,\r\n 'getCachedRxDocument',\r\n doc => fn([doc])[0]\r\n );\r\n }\r\n\r\n /**\r\n * Throws if not exists\r\n */\r\n public getLatestDocumentData(docId: string): RxDocumentData<RxDocType> {\r\n this.processTasks();\r\n const cacheItem = getFromMapOrThrow(this.cacheItemByDocId, docId);\r\n return cacheItem[1];\r\n }\r\n\r\n public getLatestDocumentDataIfExists(docId: string): RxDocumentData<RxDocType> | undefined {\r\n this.processTasks();\r\n const cacheItem = this.cacheItemByDocId.get(docId);\r\n if (cacheItem) {\r\n return cacheItem[1];\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * This function is called very very often.\r\n * @hotPath This is one of the most important methods for performance.\r\n * It is used in many places to transform the raw document data into RxDocuments.\r\n */\r\nfunction getCachedRxDocumentMonad<RxDocType, OrmMethods>(\r\n docCache: DocumentCache<RxDocType, OrmMethods>\r\n): (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] {\r\n const primaryPath = docCache.primaryPath;\r\n const cacheItemByDocId = docCache.cacheItemByDocId;\r\n const registry = docCache.registry;\r\n const deepFreezeWhenDevMode = overwritable.deepFreezeWhenDevMode;\r\n const documentCreator = docCache.documentCreator;\r\n const fn: (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] = (docsData: RxDocumentData<RxDocType>[]) => {\r\n const ret: RxDocument<RxDocType, OrmMethods>[] = new Array(docsData.length);\r\n const registryTasks: RxDocument<RxDocType, OrmMethods>[] = [];\r\n for (let index = 0; index < docsData.length; index++) {\r\n let docData = docsData[index];\r\n const docId: string = (docData as any)[primaryPath];\r\n\r\n const revisionHeight = getHeightOfRevision(docData._rev);\r\n\r\n /**\r\n * @performance\r\n * Compute the byRev cache key once and reuse it\r\n * for both the Map.get() and Map.set() calls.\r\n */\r\n const cacheKey = revisionHeight + docData._meta.lwt + '';\r\n\r\n let byRev: Map<string, WeakRef<RxDocument<RxDocType, OrmMethods>>>;\r\n let cachedRxDocumentWeakRef: WeakRef<RxDocument<RxDocType, OrmMethods>> | undefined;\r\n let cacheItem = cacheItemByDocId.get(docId);\r\n if (!cacheItem) {\r\n byRev = new Map();\r\n cacheItem = [\r\n byRev,\r\n docData\r\n ];\r\n cacheItemByDocId.set(docId, cacheItem);\r\n } else {\r\n byRev = cacheItem[0];\r\n cachedRxDocumentWeakRef = byRev.get(cacheKey);\r\n }\r\n let cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;\r\n if (!cachedRxDocument) {\r\n docData = deepFreezeWhenDevMode(docData) as any;\r\n cachedRxDocument = documentCreator(docData) as RxDocument<RxDocType, OrmMethods>;\r\n byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));\r\n if (registry) {\r\n registryTasks.push(cachedRxDocument);\r\n }\r\n }\r\n ret[index] = cachedRxDocument;\r\n }\r\n if (registryTasks.length > 0 && registry) {\r\n /**\r\n * Calling registry.register() has shown to have\r\n * really bad performance. So we add the cached documents\r\n * lazily.\r\n */\r\n docCache.tasks.add(() => {\r\n for (let index = 0; index < registryTasks.length; index++) {\r\n const doc = registryTasks[index];\r\n registry.register(doc, {\r\n docId: doc.primary,\r\n revisionHeight: getHeightOfRevision(doc.revision),\r\n lwt: doc._data._meta.lwt\r\n });\r\n }\r\n });\r\n if (docCache.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n docCache.processTasks();\r\n });\r\n }\r\n }\r\n return ret;\r\n };\r\n return fn;\r\n}\r\n\r\nexport function mapDocumentsDataToCacheDocs<RxDocType, OrmMethods>(\r\n docCache: DocumentCache<RxDocType, OrmMethods>,\r\n docsData: RxDocumentData<RxDocType>[]\r\n) {\r\n const getCachedRxDocuments = docCache.getCachedRxDocuments;\r\n return getCachedRxDocuments(docsData);\r\n}\r\n\r\n/**\r\n * Fallback for JavaScript runtimes that do not support WeakRef.\r\n * The fallback will keep the items in cache forever,\r\n * but at least works.\r\n */\r\nconst HAS_WEAK_REF = typeof WeakRef === 'function';\r\nconst createWeakRefWithFallback = HAS_WEAK_REF ? createWeakRef : createWeakRefFallback;\r\nfunction createWeakRef<T extends object>(obj: T): WeakRef<T> {\r\n return new WeakRef(obj) as any;\r\n}\r\nfunction createWeakRefFallback<T extends object>(obj: T): WeakRef<T> {\r\n return {\r\n deref() {\r\n return obj;\r\n }\r\n } as any;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"doc-cache.js","names":["getFromMapOrThrow","overwriteGetterForCaching","requestIdlePromiseNoQueue","overwritable","DocumentCache","primaryPath","changes$","documentCreator","cacheItemByDocId","Map","tasks","Set","registry","FinalizationRegistry","docMeta","docId","cacheItem","get","delete","rev","lwt","size","undefined","subscribe","events","add","index","length","event","documentId","documentData","previousDocumentData","then","processTasks","_proto","prototype","forEach","task","clear","getLatestDocumentData","getLatestDocumentDataIfExists","_createClass","key","fn","getCachedRxDocumentMonad","getCachedRxDocumentSingle","docCache","deepFreezeWhenDevMode","docData","_rev","_meta","cacheKey","newDoc","newByRev","set","createWeakRefWithFallback","register","primary","byRev","cachedRxDocumentWeakRef","cachedRxDocument","deref","registeredDoc","docsData","ret","Array","registryTasks","push","doc","mapDocumentsDataToCacheDocs","getCachedRxDocuments","HAS_WEAK_REF","WeakRef","createWeakRef","createWeakRefFallback","obj"],"sources":["../../src/doc-cache.ts"],"sourcesContent":["import type {\r\n RxDocument,\r\n RxDocumentData,\r\n RxStorageChangeEvent,\r\n WeakRef,\r\n FinalizationRegistry\r\n} from './types/index.d.ts';\r\nimport {\r\n getFromMapOrThrow,\r\n overwriteGetterForCaching,\r\n requestIdlePromiseNoQueue\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n overwritable\r\n} from './overwritable.ts';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Because we have to create many cache items,\r\n * we use an array instead of an object with properties\r\n * for better performance and less memory usage.\r\n * @link https://stackoverflow.com/questions/17295056/array-vs-object-efficiency-in-javascript\r\n */\r\ndeclare type CacheItem<RxDocType, OrmMethods> = [\r\n /**\r\n * Store the different document states of time\r\n * based on their [revisionHeight+_meta.lwt] .\r\n * We store WeakRefs so that we can later clean up\r\n * document states that are no longer needed.\r\n *\r\n * Notice that we can not only rely on the revisionHeight\r\n * because when cleanup is used, two document states can end up with\r\n * the same revision but different _meta.lwt.\r\n */\r\n Map<string, WeakRef<RxDocument<RxDocType, OrmMethods>>>,\r\n\r\n /**\r\n * Store the latest known document state.\r\n * As long as any state of the document is in the cache,\r\n * we observe the changestream and update the latestDoc accordingly.\r\n * This makes it easier to optimize performance on other parts\r\n * because for each known document we can always get the current state\r\n * in the storage.\r\n * Also it makes it possible to call RxDocument.latest() in a non-async way\r\n * to retrieve the latest document state or to observe$ some property.\r\n *\r\n * To not prevent the whole cacheItem from being garbage collected,\r\n * we store only the document data here, but not the RxDocument.\r\n */\r\n RxDocumentData<RxDocType>\r\n];\r\n\r\n\r\n/**\r\n * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry\r\n */\r\ndeclare type FinalizationRegistryValue = {\r\n docId: string;\r\n rev: string;\r\n lwt: number;\r\n};\r\n\r\n/**\r\n * The DocumentCache stores RxDocument objects\r\n * by their primary key and revision.\r\n * This is useful on client side applications where\r\n * it is not known how much memory can be used, so\r\n * we de-duplicate RxDocument states to save memory.\r\n * To not fill up the memory with old document states, the DocumentCache\r\n * only contains weak references to the RxDocuments themself.\r\n * @link https://caniuse.com/?search=weakref\r\n */\r\nexport class DocumentCache<RxDocType, OrmMethods> {\r\n public readonly cacheItemByDocId = new Map<string, CacheItem<RxDocType, OrmMethods>>();\r\n\r\n /**\r\n * Process stuff lazy to not block the CPU\r\n * on critical paths.\r\n */\r\n public readonly tasks = new Set<Function>();\r\n\r\n /**\r\n * Some JavaScript runtimes like QuickJS,\r\n * so not have a FinalizationRegistry or WeakRef.\r\n * Therefore we need a workaround which might waste a lot of memory,\r\n * but at least works.\r\n */\r\n public readonly registry?: FinalizationRegistry<FinalizationRegistryValue> = typeof FinalizationRegistry === 'function' ?\r\n new FinalizationRegistry<FinalizationRegistryValue>(docMeta => {\r\n const docId = docMeta.docId;\r\n const cacheItem = this.cacheItemByDocId.get(docId);\r\n if (cacheItem) {\r\n cacheItem[0].delete(docMeta.rev + docMeta.lwt);\r\n if (cacheItem[0].size === 0) {\r\n /**\r\n * No state of the document is cached anymore,\r\n * so we can clean up.\r\n */\r\n this.cacheItemByDocId.delete(docId);\r\n }\r\n }\r\n }) as any :\r\n undefined;\r\n\r\n constructor(\r\n public readonly primaryPath: string,\r\n public readonly changes$: Observable<RxStorageChangeEvent<RxDocType>[]>,\r\n /**\r\n * A method that can create a RxDocument by the given document data.\r\n */\r\n public documentCreator: (docData: RxDocumentData<RxDocType>) => RxDocument<RxDocType, OrmMethods>\r\n ) {\r\n changes$.subscribe((events: RxStorageChangeEvent<RxDocType>[]) => {\r\n this.tasks.add(() => {\r\n const cacheItemByDocId = this.cacheItemByDocId;\r\n for (let index = 0; index < events.length; index++) {\r\n const event = events[index];\r\n const cacheItem = cacheItemByDocId.get(event.documentId);\r\n if (cacheItem) {\r\n let documentData = event.documentData;\r\n if (!documentData) {\r\n documentData = event.previousDocumentData as any;\r\n }\r\n cacheItem[1] = documentData;\r\n }\r\n }\r\n });\r\n if (this.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n this.processTasks();\r\n });\r\n }\r\n });\r\n }\r\n\r\n public processTasks() {\r\n if (this.tasks.size === 0) {\r\n return;\r\n }\r\n this.tasks.forEach(task => task());\r\n this.tasks.clear();\r\n }\r\n\r\n /**\r\n * Get the RxDocument from the cache\r\n * and create a new one if not exits before.\r\n * @overwrites itself with the actual function\r\n * because this is @performance relevant.\r\n * It is called on each document row for each write and read.\r\n */\r\n get getCachedRxDocuments(): (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] {\r\n const fn = getCachedRxDocumentMonad(this);\r\n return overwriteGetterForCaching(\r\n this,\r\n 'getCachedRxDocuments',\r\n fn\r\n );\r\n }\r\n\r\n get getCachedRxDocument(): (docData: RxDocumentData<RxDocType>) => RxDocument<RxDocType, OrmMethods> {\r\n const fn = getCachedRxDocumentSingle(this);\r\n return overwriteGetterForCaching(\r\n this,\r\n 'getCachedRxDocument',\r\n fn\r\n );\r\n }\r\n\r\n /**\r\n * Throws if not exists\r\n */\r\n public getLatestDocumentData(docId: string): RxDocumentData<RxDocType> {\r\n this.processTasks();\r\n const cacheItem = getFromMapOrThrow(this.cacheItemByDocId, docId);\r\n return cacheItem[1];\r\n }\r\n\r\n public getLatestDocumentDataIfExists(docId: string): RxDocumentData<RxDocType> | undefined {\r\n this.processTasks();\r\n const cacheItem = this.cacheItemByDocId.get(docId);\r\n if (cacheItem) {\r\n return cacheItem[1];\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * @hotPath Dedicated single-document function that avoids array allocations.\r\n * Used by getCachedRxDocument which is called from many call sites.\r\n */\r\nfunction getCachedRxDocumentSingle<RxDocType, OrmMethods>(\r\n docCache: DocumentCache<RxDocType, OrmMethods>\r\n): (docData: RxDocumentData<RxDocType>) => RxDocument<RxDocType, OrmMethods> {\r\n const primaryPath = docCache.primaryPath;\r\n const cacheItemByDocId = docCache.cacheItemByDocId;\r\n const registry = docCache.registry;\r\n const deepFreezeWhenDevMode = overwritable.deepFreezeWhenDevMode;\r\n const documentCreator = docCache.documentCreator;\r\n\r\n return (docData: RxDocumentData<RxDocType>): RxDocument<RxDocType, OrmMethods> => {\r\n const docId: string = (docData as any)[primaryPath];\r\n const rev = docData._rev;\r\n const lwt = docData._meta.lwt;\r\n const cacheKey = rev + lwt;\r\n\r\n const cacheItem = cacheItemByDocId.get(docId);\r\n if (!cacheItem) {\r\n docData = deepFreezeWhenDevMode(docData) as any;\r\n const newDoc = documentCreator(docData) as RxDocument<RxDocType, OrmMethods>;\r\n const newByRev = new Map<string, WeakRef<RxDocument<RxDocType, OrmMethods>>>();\r\n newByRev.set(cacheKey, createWeakRefWithFallback(newDoc));\r\n cacheItemByDocId.set(docId, [newByRev, docData]);\r\n if (registry) {\r\n docCache.tasks.add(() => {\r\n registry.register(newDoc, {\r\n docId: newDoc.primary,\r\n rev,\r\n lwt\r\n });\r\n });\r\n if (docCache.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n docCache.processTasks();\r\n });\r\n }\r\n }\r\n return newDoc;\r\n }\r\n\r\n const byRev = cacheItem[0];\r\n const cachedRxDocumentWeakRef = byRev.get(cacheKey);\r\n let cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;\r\n if (!cachedRxDocument) {\r\n docData = deepFreezeWhenDevMode(docData) as any;\r\n cachedRxDocument = documentCreator(docData) as RxDocument<RxDocType, OrmMethods>;\r\n byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));\r\n if (registry) {\r\n const registeredDoc = cachedRxDocument;\r\n docCache.tasks.add(() => {\r\n registry.register(registeredDoc, {\r\n docId: registeredDoc.primary,\r\n rev,\r\n lwt\r\n });\r\n });\r\n if (docCache.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n docCache.processTasks();\r\n });\r\n }\r\n }\r\n }\r\n return cachedRxDocument;\r\n };\r\n}\r\n\r\n\r\n/**\r\n * This function is called very very often.\r\n * @hotPath This is one of the most important methods for performance.\r\n * It is used in many places to transform the raw document data into RxDocuments.\r\n */\r\nfunction getCachedRxDocumentMonad<RxDocType, OrmMethods>(\r\n docCache: DocumentCache<RxDocType, OrmMethods>\r\n): (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] {\r\n const primaryPath = docCache.primaryPath;\r\n const cacheItemByDocId = docCache.cacheItemByDocId;\r\n const registry = docCache.registry;\r\n const deepFreezeWhenDevMode = overwritable.deepFreezeWhenDevMode;\r\n const documentCreator = docCache.documentCreator;\r\n const fn: (docsData: RxDocumentData<RxDocType>[]) => RxDocument<RxDocType, OrmMethods>[] = (docsData: RxDocumentData<RxDocType>[]) => {\r\n const ret: RxDocument<RxDocType, OrmMethods>[] = new Array(docsData.length);\r\n let registryTasks: { doc: RxDocument<RxDocType, OrmMethods>; rev: string; lwt: number; }[] | undefined;\r\n for (let index = 0; index < docsData.length; index++) {\r\n let docData = docsData[index];\r\n const docId: string = (docData as any)[primaryPath];\r\n\r\n const rev = docData._rev;\r\n const lwt = docData._meta.lwt;\r\n const cacheKey = rev + lwt;\r\n\r\n const cacheItem = cacheItemByDocId.get(docId);\r\n if (!cacheItem) {\r\n /**\r\n * New document - no need for WeakRef lookup.\r\n * Create cache item directly.\r\n */\r\n docData = deepFreezeWhenDevMode(docData) as any;\r\n const cachedRxDocument = documentCreator(docData) as RxDocument<RxDocType, OrmMethods>;\r\n const byRev = new Map<string, WeakRef<RxDocument<RxDocType, OrmMethods>>>();\r\n byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));\r\n cacheItemByDocId.set(docId, [byRev, docData]);\r\n ret[index] = cachedRxDocument;\r\n if (registry) {\r\n if (!registryTasks) {\r\n registryTasks = [];\r\n }\r\n registryTasks.push({ doc: cachedRxDocument, rev, lwt });\r\n }\r\n } else {\r\n const byRev = cacheItem[0];\r\n const cachedRxDocumentWeakRef = byRev.get(cacheKey);\r\n let cachedRxDocument = cachedRxDocumentWeakRef ? cachedRxDocumentWeakRef.deref() : undefined;\r\n if (!cachedRxDocument) {\r\n docData = deepFreezeWhenDevMode(docData) as any;\r\n cachedRxDocument = documentCreator(docData) as RxDocument<RxDocType, OrmMethods>;\r\n byRev.set(cacheKey, createWeakRefWithFallback(cachedRxDocument));\r\n if (registry) {\r\n if (!registryTasks) {\r\n registryTasks = [];\r\n }\r\n registryTasks.push({ doc: cachedRxDocument, rev, lwt });\r\n }\r\n }\r\n ret[index] = cachedRxDocument;\r\n }\r\n }\r\n if (registryTasks && registry) {\r\n /**\r\n * Calling registry.register() has shown to have\r\n * really bad performance. So we add the cached documents\r\n * lazily.\r\n */\r\n const tasks = registryTasks;\r\n docCache.tasks.add(() => {\r\n for (let index = 0; index < tasks.length; index++) {\r\n const task = tasks[index];\r\n registry.register(task.doc, {\r\n docId: task.doc.primary,\r\n rev: task.rev,\r\n lwt: task.lwt\r\n });\r\n }\r\n });\r\n if (docCache.tasks.size <= 1) {\r\n requestIdlePromiseNoQueue().then(() => {\r\n docCache.processTasks();\r\n });\r\n }\r\n }\r\n return ret;\r\n };\r\n return fn;\r\n}\r\n\r\nexport function mapDocumentsDataToCacheDocs<RxDocType, OrmMethods>(\r\n docCache: DocumentCache<RxDocType, OrmMethods>,\r\n docsData: RxDocumentData<RxDocType>[]\r\n) {\r\n const getCachedRxDocuments = docCache.getCachedRxDocuments;\r\n return getCachedRxDocuments(docsData);\r\n}\r\n\r\n/**\r\n * Fallback for JavaScript runtimes that do not support WeakRef.\r\n * The fallback will keep the items in cache forever,\r\n * but at least works.\r\n */\r\nconst HAS_WEAK_REF = typeof WeakRef === 'function';\r\nconst createWeakRefWithFallback = HAS_WEAK_REF ? createWeakRef : createWeakRefFallback;\r\nfunction createWeakRef<T extends object>(obj: T): WeakRef<T> {\r\n return new WeakRef(obj) as any;\r\n}\r\nfunction createWeakRefFallback<T extends object>(obj: T): WeakRef<T> {\r\n return {\r\n deref() {\r\n return obj;\r\n }\r\n } as any;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -52,7 +52,16 @@ export function calculateNewResults(rxQuery, rxChangeEvents) {
52
52
  }
53
53
  var queryParams = getQueryParams(rxQuery);
54
54
  var previousResults = ensureNotFalsy(rxQuery._result).docsData.slice(0);
55
- var previousResultsMap = ensureNotFalsy(rxQuery._result).docsDataMap;
55
+ /**
56
+ * Copy the map to avoid mutating the cached docsDataMap on the result object.
57
+ * runAction() modifies the map in-place (adds/removes entries),
58
+ * which would corrupt the cached map if a later event triggers runFullQueryAgain
59
+ * and the full re-exec returns the same results (keeping the old result object).
60
+ * On subsequent event-reduce calls, the corrupted map would cause incorrect
61
+ * results because insertAtSortPosition checks keyDocumentMap.has(docId)
62
+ * to decide whether to skip insertion.
63
+ */
64
+ var previousResultsMap = new Map(ensureNotFalsy(rxQuery._result).docsDataMap);
56
65
  var changed = false;
57
66
  var eventReduceEvents = [];
58
67
  for (var index = 0; index < rxChangeEvents.length; index++) {