@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
@@ -1 +1 @@
1
- {"version":3,"file":"doc-cache.js","names":["_index2","require","_overwritable","DocumentCache","exports","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","requestIdlePromiseNoQueue","then","processTasks","_proto","prototype","Array","from","forEach","task","clear","getLatestDocumentData","getFromMapOrThrow","getLatestDocumentDataIfExists","_createClass2","default","key","fn","getCachedRxDocumentMonad","overwriteGetterForCaching","doc","docCache","deepFreezeWhenDevMode","overwritable","docsData","ret","registryTasks","docData","getHeightOfRevision","_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":["_index2","require","_overwritable","DocumentCache","exports","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","requestIdlePromiseNoQueue","then","processTasks","_proto","prototype","forEach","task","clear","getLatestDocumentData","getFromMapOrThrow","getLatestDocumentDataIfExists","_createClass2","default","key","fn","getCachedRxDocumentMonad","overwriteGetterForCaching","getCachedRxDocumentSingle","docCache","deepFreezeWhenDevMode","overwritable","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":[]}
@@ -61,7 +61,16 @@ function calculateNewResults(rxQuery, rxChangeEvents) {
61
61
  }
62
62
  var queryParams = getQueryParams(rxQuery);
63
63
  var previousResults = (0, _index.ensureNotFalsy)(rxQuery._result).docsData.slice(0);
64
- var previousResultsMap = (0, _index.ensureNotFalsy)(rxQuery._result).docsDataMap;
64
+ /**
65
+ * Copy the map to avoid mutating the cached docsDataMap on the result object.
66
+ * runAction() modifies the map in-place (adds/removes entries),
67
+ * which would corrupt the cached map if a later event triggers runFullQueryAgain
68
+ * and the full re-exec returns the same results (keeping the old result object).
69
+ * On subsequent event-reduce calls, the corrupted map would cause incorrect
70
+ * results because insertAtSortPosition checks keyDocumentMap.has(docId)
71
+ * to decide whether to skip insertion.
72
+ */
73
+ var previousResultsMap = new Map((0, _index.ensureNotFalsy)(rxQuery._result).docsDataMap);
65
74
  var changed = false;
66
75
  var eventReduceEvents = [];
67
76
  for (var index = 0; index < rxChangeEvents.length; index++) {
@@ -1 +1 @@
1
- {"version":3,"file":"event-reduce.js","names":["_eventReduceJs","require","_rxChangeEvent","_index","_rxQueryHelper","getSortFieldsOfQuery","primaryKey","query","sort","length","map","part","Object","keys","RXQUERY_QUERY_PARAMS_CACHE","exports","WeakMap","getQueryParams","rxQuery","getFromMapOrCreate","collection","normalizedMangoQuery","normalizeMangoQuery","storageInstance","schema","clone","mangoQuery","primaryPath","useSortComparator","getSortComparator","jsonSchema","useQueryMatcher","getQueryMatcher","ret","skip","limit","sortFields","sortComparator","queryMatcher","calculateNewResults","rxChangeEvents","database","eventReduce","runFullQueryAgain","queryParams","previousResults","ensureNotFalsy","_result","docsData","slice","previousResultsMap","docsDataMap","changed","eventReduceEvents","index","cE","eventReduceEvent","rxChangeEventToEventReduceChangeEvent","push","foundNonOptimizeable","find","stateResolveFunctionInput","changeEvent","keyDocumentMap","actionName","calculateActionName","runAction","newResults"],"sources":["../../src/event-reduce.ts"],"sourcesContent":["import {\r\n ActionName,\r\n calculateActionName,\r\n runAction,\r\n QueryParams,\r\n StateResolveFunctionInput,\r\n ChangeEvent\r\n} from 'event-reduce-js';\r\nimport type {\r\n RxQuery,\r\n MangoQuery,\r\n StringKeys,\r\n RxDocumentData,\r\n RxStorageChangeEvent\r\n} from './types/index.d.ts';\r\nimport { rxChangeEventToEventReduceChangeEvent } from './rx-change-event.ts';\r\nimport {\r\n clone,\r\n ensureNotFalsy,\r\n getFromMapOrCreate\r\n} from './plugins/utils/index.ts';\r\nimport { getQueryMatcher, getSortComparator, normalizeMangoQuery } from './rx-query-helper.ts';\r\n\r\nexport type EventReduceResultNeg = {\r\n runFullQueryAgain: true;\r\n};\r\nexport type EventReduceResultPos<RxDocumentType> = {\r\n runFullQueryAgain: false;\r\n changed: boolean;\r\n newResults: RxDocumentType[];\r\n};\r\nexport type EventReduceResult<RxDocumentType> = EventReduceResultNeg | EventReduceResultPos<RxDocumentType>;\r\n\r\n\r\nexport function getSortFieldsOfQuery<RxDocType>(\r\n primaryKey: StringKeys<RxDocumentData<RxDocType>>,\r\n query: MangoQuery<RxDocType>\r\n): (string | StringKeys<RxDocType>)[] {\r\n if (!query.sort || query.sort.length === 0) {\r\n return [primaryKey];\r\n } else {\r\n return query.sort.map(part => Object.keys(part)[0]);\r\n }\r\n}\r\n\r\n\r\n\r\nexport const RXQUERY_QUERY_PARAMS_CACHE: WeakMap<RxQuery, QueryParams<any>> = new WeakMap();\r\nexport function getQueryParams<RxDocType>(\r\n rxQuery: RxQuery<RxDocType>\r\n): QueryParams<RxDocType> {\r\n return getFromMapOrCreate(\r\n RXQUERY_QUERY_PARAMS_CACHE,\r\n rxQuery,\r\n () => {\r\n const collection = rxQuery.collection;\r\n const normalizedMangoQuery = normalizeMangoQuery(\r\n collection.storageInstance.schema,\r\n clone(rxQuery.mangoQuery)\r\n );\r\n const primaryKey = collection.schema.primaryPath;\r\n\r\n /**\r\n * Create a custom sort comparator\r\n * that uses the hooks to ensure\r\n * we send for example compressed documents to be sorted by compressed queries.\r\n *\r\n * @performance\r\n * Avoid creating intermediate wrapper objects on every comparison call.\r\n * The sortComparator and queryMatcher are called directly.\r\n */\r\n const useSortComparator = getSortComparator(\r\n collection.schema.jsonSchema,\r\n normalizedMangoQuery\r\n );\r\n\r\n /**\r\n * Create a custom query matcher\r\n * that uses the hooks to ensure\r\n * we send for example compressed documents to match compressed queries.\r\n */\r\n const useQueryMatcher = getQueryMatcher(\r\n collection.schema.jsonSchema,\r\n normalizedMangoQuery\r\n );\r\n\r\n const ret: QueryParams<any> = {\r\n primaryKey: rxQuery.collection.schema.primaryPath as any,\r\n skip: normalizedMangoQuery.skip,\r\n limit: normalizedMangoQuery.limit,\r\n sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],\r\n sortComparator: useSortComparator,\r\n queryMatcher: useQueryMatcher\r\n };\r\n return ret;\r\n }\r\n );\r\n}\r\n\r\n\r\nexport function calculateNewResults<RxDocumentType>(\r\n rxQuery: RxQuery<RxDocumentType>,\r\n rxChangeEvents: RxStorageChangeEvent<RxDocumentType>[]\r\n): EventReduceResult<RxDocumentType> {\r\n if (!rxQuery.collection.database.eventReduce) {\r\n return {\r\n runFullQueryAgain: true\r\n };\r\n }\r\n const queryParams = getQueryParams(rxQuery);\r\n const previousResults: RxDocumentType[] = ensureNotFalsy(rxQuery._result).docsData.slice(0);\r\n const previousResultsMap: Map<string, RxDocumentType> = ensureNotFalsy(rxQuery._result).docsDataMap;\r\n let changed: boolean = false;\r\n\r\n\r\n const eventReduceEvents: ChangeEvent<RxDocumentType>[] = [];\r\n for (let index = 0; index < rxChangeEvents.length; index++) {\r\n const cE = rxChangeEvents[index];\r\n const eventReduceEvent = rxChangeEventToEventReduceChangeEvent(cE);\r\n if (eventReduceEvent) {\r\n eventReduceEvents.push(eventReduceEvent);\r\n }\r\n }\r\n\r\n const foundNonOptimizeable = eventReduceEvents.find(eventReduceEvent => {\r\n const stateResolveFunctionInput: StateResolveFunctionInput<RxDocumentType> = {\r\n queryParams,\r\n changeEvent: eventReduceEvent,\r\n previousResults,\r\n keyDocumentMap: previousResultsMap\r\n };\r\n\r\n const actionName: ActionName = calculateActionName(stateResolveFunctionInput);\r\n if (actionName === 'runFullQueryAgain') {\r\n return true;\r\n } else if (actionName !== 'doNothing') {\r\n changed = true;\r\n runAction(\r\n actionName,\r\n queryParams,\r\n eventReduceEvent,\r\n previousResults,\r\n previousResultsMap\r\n );\r\n return false;\r\n }\r\n });\r\n if (foundNonOptimizeable) {\r\n return {\r\n runFullQueryAgain: true,\r\n };\r\n } else {\r\n return {\r\n runFullQueryAgain: false,\r\n changed,\r\n newResults: previousResults\r\n };\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"event-reduce.js","names":["_eventReduceJs","require","_rxChangeEvent","_index","_rxQueryHelper","getSortFieldsOfQuery","primaryKey","query","sort","length","map","part","Object","keys","RXQUERY_QUERY_PARAMS_CACHE","exports","WeakMap","getQueryParams","rxQuery","getFromMapOrCreate","collection","normalizedMangoQuery","normalizeMangoQuery","storageInstance","schema","clone","mangoQuery","primaryPath","useSortComparator","getSortComparator","jsonSchema","useQueryMatcher","getQueryMatcher","ret","skip","limit","sortFields","sortComparator","queryMatcher","calculateNewResults","rxChangeEvents","database","eventReduce","runFullQueryAgain","queryParams","previousResults","ensureNotFalsy","_result","docsData","slice","previousResultsMap","Map","docsDataMap","changed","eventReduceEvents","index","cE","eventReduceEvent","rxChangeEventToEventReduceChangeEvent","push","foundNonOptimizeable","find","stateResolveFunctionInput","changeEvent","keyDocumentMap","actionName","calculateActionName","runAction","newResults"],"sources":["../../src/event-reduce.ts"],"sourcesContent":["import {\r\n ActionName,\r\n calculateActionName,\r\n runAction,\r\n QueryParams,\r\n StateResolveFunctionInput,\r\n ChangeEvent\r\n} from 'event-reduce-js';\r\nimport type {\r\n RxQuery,\r\n MangoQuery,\r\n StringKeys,\r\n RxDocumentData,\r\n RxStorageChangeEvent\r\n} from './types/index.d.ts';\r\nimport { rxChangeEventToEventReduceChangeEvent } from './rx-change-event.ts';\r\nimport {\r\n clone,\r\n ensureNotFalsy,\r\n getFromMapOrCreate\r\n} from './plugins/utils/index.ts';\r\nimport { getQueryMatcher, getSortComparator, normalizeMangoQuery } from './rx-query-helper.ts';\r\n\r\nexport type EventReduceResultNeg = {\r\n runFullQueryAgain: true;\r\n};\r\nexport type EventReduceResultPos<RxDocumentType> = {\r\n runFullQueryAgain: false;\r\n changed: boolean;\r\n newResults: RxDocumentType[];\r\n};\r\nexport type EventReduceResult<RxDocumentType> = EventReduceResultNeg | EventReduceResultPos<RxDocumentType>;\r\n\r\n\r\nexport function getSortFieldsOfQuery<RxDocType>(\r\n primaryKey: StringKeys<RxDocumentData<RxDocType>>,\r\n query: MangoQuery<RxDocType>\r\n): (string | StringKeys<RxDocType>)[] {\r\n if (!query.sort || query.sort.length === 0) {\r\n return [primaryKey];\r\n } else {\r\n return query.sort.map(part => Object.keys(part)[0]);\r\n }\r\n}\r\n\r\n\r\n\r\nexport const RXQUERY_QUERY_PARAMS_CACHE: WeakMap<RxQuery, QueryParams<any>> = new WeakMap();\r\nexport function getQueryParams<RxDocType>(\r\n rxQuery: RxQuery<RxDocType>\r\n): QueryParams<RxDocType> {\r\n return getFromMapOrCreate(\r\n RXQUERY_QUERY_PARAMS_CACHE,\r\n rxQuery,\r\n () => {\r\n const collection = rxQuery.collection;\r\n const normalizedMangoQuery = normalizeMangoQuery(\r\n collection.storageInstance.schema,\r\n clone(rxQuery.mangoQuery)\r\n );\r\n const primaryKey = collection.schema.primaryPath;\r\n\r\n /**\r\n * Create a custom sort comparator\r\n * that uses the hooks to ensure\r\n * we send for example compressed documents to be sorted by compressed queries.\r\n *\r\n * @performance\r\n * Avoid creating intermediate wrapper objects on every comparison call.\r\n * The sortComparator and queryMatcher are called directly.\r\n */\r\n const useSortComparator = getSortComparator(\r\n collection.schema.jsonSchema,\r\n normalizedMangoQuery\r\n );\r\n\r\n /**\r\n * Create a custom query matcher\r\n * that uses the hooks to ensure\r\n * we send for example compressed documents to match compressed queries.\r\n */\r\n const useQueryMatcher = getQueryMatcher(\r\n collection.schema.jsonSchema,\r\n normalizedMangoQuery\r\n );\r\n\r\n const ret: QueryParams<any> = {\r\n primaryKey: rxQuery.collection.schema.primaryPath as any,\r\n skip: normalizedMangoQuery.skip,\r\n limit: normalizedMangoQuery.limit,\r\n sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],\r\n sortComparator: useSortComparator,\r\n queryMatcher: useQueryMatcher\r\n };\r\n return ret;\r\n }\r\n );\r\n}\r\n\r\n\r\nexport function calculateNewResults<RxDocumentType>(\r\n rxQuery: RxQuery<RxDocumentType>,\r\n rxChangeEvents: RxStorageChangeEvent<RxDocumentType>[]\r\n): EventReduceResult<RxDocumentType> {\r\n if (!rxQuery.collection.database.eventReduce) {\r\n return {\r\n runFullQueryAgain: true\r\n };\r\n }\r\n const queryParams = getQueryParams(rxQuery);\r\n const previousResults: RxDocumentType[] = ensureNotFalsy(rxQuery._result).docsData.slice(0);\r\n /**\r\n * Copy the map to avoid mutating the cached docsDataMap on the result object.\r\n * runAction() modifies the map in-place (adds/removes entries),\r\n * which would corrupt the cached map if a later event triggers runFullQueryAgain\r\n * and the full re-exec returns the same results (keeping the old result object).\r\n * On subsequent event-reduce calls, the corrupted map would cause incorrect\r\n * results because insertAtSortPosition checks keyDocumentMap.has(docId)\r\n * to decide whether to skip insertion.\r\n */\r\n const previousResultsMap: Map<string, RxDocumentType> = new Map(ensureNotFalsy(rxQuery._result).docsDataMap);\r\n let changed: boolean = false;\r\n\r\n\r\n const eventReduceEvents: ChangeEvent<RxDocumentType>[] = [];\r\n for (let index = 0; index < rxChangeEvents.length; index++) {\r\n const cE = rxChangeEvents[index];\r\n const eventReduceEvent = rxChangeEventToEventReduceChangeEvent(cE);\r\n if (eventReduceEvent) {\r\n eventReduceEvents.push(eventReduceEvent);\r\n }\r\n }\r\n\r\n const foundNonOptimizeable = eventReduceEvents.find(eventReduceEvent => {\r\n const stateResolveFunctionInput: StateResolveFunctionInput<RxDocumentType> = {\r\n queryParams,\r\n changeEvent: eventReduceEvent,\r\n previousResults,\r\n keyDocumentMap: previousResultsMap\r\n };\r\n\r\n const actionName: ActionName = calculateActionName(stateResolveFunctionInput);\r\n if (actionName === 'runFullQueryAgain') {\r\n return true;\r\n } else if (actionName !== 'doNothing') {\r\n changed = true;\r\n runAction(\r\n actionName,\r\n queryParams,\r\n eventReduceEvent,\r\n previousResults,\r\n previousResultsMap\r\n );\r\n return false;\r\n }\r\n });\r\n if (foundNonOptimizeable) {\r\n return {\r\n runFullQueryAgain: true,\r\n };\r\n } else {\r\n return {\r\n runFullQueryAgain: false,\r\n changed,\r\n newResults: previousResults\r\n };\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -8,6 +8,7 @@ exports.wrappedValidateStorageFactory = wrappedValidateStorageFactory;
8
8
  var _operators = require("rxjs/operators");
9
9
  var _rxSchemaHelper = require("./rx-schema-helper.js");
10
10
  var _index = require("./plugins/utils/index.js");
11
+ var _rxError = require("./rx-error.js");
11
12
  var _rxjs = require("rxjs");
12
13
  /**
13
14
  * Returns the validation errors.
@@ -168,6 +169,11 @@ function wrapRxStorageInstance(originalSchema, instance, modifyToStorage, modify
168
169
  },
169
170
  query: preparedQuery => {
170
171
  return instance.query(preparedQuery).then(queryResult => {
172
+ if (typeof queryResult === 'string') {
173
+ throw (0, _rxError.newRxError)('EN5', {
174
+ method: 'query'
175
+ });
176
+ }
171
177
  return Promise.all(queryResult.documents.map(doc => fromStorage(doc)));
172
178
  }).then(documents => ({
173
179
  documents: documents
@@ -180,6 +186,11 @@ function wrapRxStorageInstance(originalSchema, instance, modifyToStorage, modify
180
186
  },
181
187
  findDocumentsById: (ids, deleted) => {
182
188
  return instance.findDocumentsById(ids, deleted).then(async findResult => {
189
+ if (typeof findResult === 'string') {
190
+ throw (0, _rxError.newRxError)('EN5', {
191
+ method: 'findDocumentsById'
192
+ });
193
+ }
183
194
  var ret = [];
184
195
  await Promise.all(findResult.map(async doc => {
185
196
  ret.push(await fromStorage(doc));
@@ -189,6 +200,11 @@ function wrapRxStorageInstance(originalSchema, instance, modifyToStorage, modify
189
200
  },
190
201
  getChangedDocumentsSince: !instance.getChangedDocumentsSince ? undefined : (limit, checkpoint) => {
191
202
  return instance.getChangedDocumentsSince(limit, checkpoint).then(async result => {
203
+ if (typeof result === 'string') {
204
+ throw (0, _rxError.newRxError)('EN5', {
205
+ method: 'getChangedDocumentsSince'
206
+ });
207
+ }
192
208
  return {
193
209
  checkpoint: result.checkpoint,
194
210
  documents: await Promise.all(result.documents.map(d => fromStorage(d)))
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-helpers.js","names":["_operators","require","_rxSchemaHelper","_index","_rxjs","VALIDATOR_CACHE_BY_VALIDATOR_KEY","Map","wrappedValidateStorageFactory","getValidator","validatorKey","VALIDATOR_CACHE","getFromMapOrCreate","initValidator","schema","JSON","stringify","args","Object","assign","storage","name","createStorageInstance","params","instance","primaryPath","getPrimaryFieldOfPrimaryKey","primaryKey","validatorCached","requestIdleCallbackIfAvailable","oldBulkWrite","bulkWrite","bind","documentWrites","context","errors","continueWrites","forEach","row","documentId","document","validationErrors","length","push","status","isError","writeRow","writePromise","Promise","resolve","error","success","then","writeResult","validationError","wrapRxStorageInstance","originalSchema","modifyToStorage","modifyFromStorage","modifyAttachmentFromStorage","v","toStorage","docData","fromStorage","errorFromStorage","ret","flatClone","documentInDb","previous","processingChangesCount$","BehaviorSubject","wrappedInstance","databaseName","internals","cleanup","options","close","collectionName","count","remove","originalStorageInstance","useRows","all","map","undefined","promises","err","firstValueFrom","pipe","filter","query","preparedQuery","queryResult","documents","doc","getAttachmentData","attachmentId","digest","data","findDocumentsById","ids","deleted","findResult","getChangedDocumentsSince","limit","checkpoint","result","d","changeStream","tap","next","getValue","mergeMap","eventBulk","useEvents","events","event","documentData","previousDocumentData","ev","operation","isLocal","id"],"sources":["../../src/plugin-helpers.ts"],"sourcesContent":["import { filter, mergeMap, tap } from 'rxjs/operators';\r\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\r\nimport { WrappedRxStorageInstance } from './rx-storage-helper.ts';\r\nimport type {\r\n BulkWriteRow,\r\n EventBulk,\r\n RxChangeEvent,\r\n RxDocumentData,\r\n RxDocumentWriteData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageWriteError,\r\n RxStorageBulkWriteResponse,\r\n RxStorageChangeEvent,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams,\r\n RxValidationError,\r\n RxStorageWriteErrorConflict,\r\n MaybePromise\r\n} from './types/index.d.ts';\r\nimport {\r\n flatClone,\r\n getFromMapOrCreate,\r\n requestIdleCallbackIfAvailable\r\n} from './plugins/utils/index.ts';\r\nimport { BehaviorSubject, firstValueFrom } from 'rxjs';\r\n\r\n\r\ntype WrappedStorageFunction = <Internals, InstanceCreationOptions>(\r\n args: {\r\n storage: RxStorage<Internals, InstanceCreationOptions>;\r\n }\r\n) => RxStorage<Internals, InstanceCreationOptions>;\r\n\r\n/**\r\n * Returns the validation errors.\r\n * If document is fully valid, returns an empty array.\r\n */\r\ntype ValidatorFunction = (docData: RxDocumentData<any>) => RxValidationError[];\r\n\r\n/**\r\n * cache the validators by the schema string\r\n * so we can reuse them when multiple collections have the same schema\r\n *\r\n * Notice: to make it easier and not dependent on a hash function,\r\n * we use the plain json string.\r\n */\r\nconst VALIDATOR_CACHE_BY_VALIDATOR_KEY: Map<string, Map<string, ValidatorFunction>> = new Map();\r\n\r\n/**\r\n * This factory is used in the validation plugins\r\n * so that we can reuse the basic storage wrapping code.\r\n */\r\nexport function wrappedValidateStorageFactory(\r\n /**\r\n * Returns a method that can be used to validate\r\n * documents and throws when the document is not valid.\r\n */\r\n getValidator: (schema: RxJsonSchema<any>) => ValidatorFunction,\r\n /**\r\n * A string to identify the validation library.\r\n */\r\n validatorKey: string\r\n): WrappedStorageFunction {\r\n const VALIDATOR_CACHE = getFromMapOrCreate(\r\n VALIDATOR_CACHE_BY_VALIDATOR_KEY,\r\n validatorKey,\r\n () => new Map()\r\n );\r\n\r\n function initValidator(\r\n schema: RxJsonSchema<any>\r\n ): ValidatorFunction {\r\n return getFromMapOrCreate(\r\n VALIDATOR_CACHE,\r\n JSON.stringify(schema),\r\n () => getValidator(schema)\r\n );\r\n }\r\n\r\n return (args) => {\r\n return Object.assign(\r\n {},\r\n args.storage,\r\n {\r\n name: 'validate-' + validatorKey + '-' + args.storage.name,\r\n async createStorageInstance<RxDocType>(\r\n params: RxStorageInstanceCreationParams<RxDocType, any>\r\n ) {\r\n const instance = await args.storage.createStorageInstance(params);\r\n const primaryPath = getPrimaryFieldOfPrimaryKey(params.schema.primaryKey);\r\n\r\n /**\r\n * Lazy initialize the validator\r\n * to save initial page load performance.\r\n * Some libraries take really long to initialize the validator\r\n * from the schema.\r\n */\r\n let validatorCached: ValidatorFunction;\r\n requestIdleCallbackIfAvailable(() => validatorCached = initValidator(params.schema));\r\n\r\n const oldBulkWrite = instance.bulkWrite.bind(instance);\r\n instance.bulkWrite = (\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ) => {\r\n if (!validatorCached) {\r\n validatorCached = initValidator(params.schema);\r\n }\r\n const errors: RxStorageWriteError<RxDocType>[] = [];\r\n const continueWrites: typeof documentWrites = [];\r\n documentWrites.forEach(row => {\r\n const documentId: string = row.document[primaryPath] as any;\r\n const validationErrors = validatorCached(row.document);\r\n if (validationErrors.length > 0) {\r\n errors.push({\r\n status: 422,\r\n isError: true,\r\n documentId,\r\n validationErrors,\r\n schema: instance.schema,\r\n writeRow: row,\r\n context\r\n });\r\n } else {\r\n continueWrites.push(row);\r\n }\r\n });\r\n const writePromise: Promise<RxStorageBulkWriteResponse<RxDocType>> = continueWrites.length > 0 ?\r\n oldBulkWrite(continueWrites, context) :\r\n Promise.resolve({ error: [], success: [] });\r\n return writePromise.then(writeResult => {\r\n errors.forEach(validationError => {\r\n writeResult.error.push(validationError);\r\n });\r\n return writeResult;\r\n });\r\n };\r\n\r\n return instance;\r\n }\r\n }\r\n );\r\n };\r\n\r\n}\r\n\r\n\r\n\r\n/**\r\n * Used in plugins to easily modify all in- and outgoing\r\n * data of that storage instance.\r\n */\r\nexport function wrapRxStorageInstance<RxDocType>(\r\n originalSchema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n instance: RxStorageInstance<RxDocType, any, any>,\r\n modifyToStorage: (docData: RxDocumentWriteData<RxDocType>) => MaybePromise<RxDocumentData<any>>,\r\n modifyFromStorage: (docData: RxDocumentData<any>) => MaybePromise<RxDocumentData<RxDocType>>,\r\n modifyAttachmentFromStorage: (attachmentData: Blob) => MaybePromise<Blob> = (v) => v\r\n): WrappedRxStorageInstance<RxDocType, any, any> {\r\n async function toStorage(docData: RxDocumentWriteData<RxDocType>): Promise<RxDocumentData<any>> {\r\n if (!docData) {\r\n return docData;\r\n }\r\n return await modifyToStorage(docData);\r\n }\r\n async function fromStorage(docData: RxDocumentData<any> | null): Promise<RxDocumentData<RxDocType>> {\r\n if (!docData) {\r\n return docData;\r\n }\r\n return await modifyFromStorage(docData);\r\n }\r\n async function errorFromStorage(\r\n error: RxStorageWriteError<any>\r\n ): Promise<RxStorageWriteError<RxDocType>> {\r\n const ret = flatClone(error);\r\n ret.writeRow = flatClone(ret.writeRow);\r\n if ((ret as RxStorageWriteErrorConflict<any>).documentInDb) {\r\n (ret as RxStorageWriteErrorConflict<any>).documentInDb = await fromStorage((ret as RxStorageWriteErrorConflict<any>).documentInDb);\r\n }\r\n if (ret.writeRow.previous) {\r\n ret.writeRow.previous = await fromStorage(ret.writeRow.previous);\r\n }\r\n ret.writeRow.document = await fromStorage(ret.writeRow.document);\r\n return ret;\r\n }\r\n\r\n\r\n const processingChangesCount$ = new BehaviorSubject(0);\r\n\r\n const wrappedInstance: WrappedRxStorageInstance<RxDocType, any, any> = {\r\n databaseName: instance.databaseName,\r\n internals: instance.internals,\r\n cleanup: instance.cleanup.bind(instance),\r\n options: instance.options,\r\n close: instance.close.bind(instance),\r\n schema: originalSchema,\r\n collectionName: instance.collectionName,\r\n count: instance.count.bind(instance),\r\n remove: instance.remove.bind(instance),\r\n originalStorageInstance: instance,\r\n bulkWrite: async (\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ) => {\r\n const useRows: BulkWriteRow<any>[] = [];\r\n await Promise.all(\r\n documentWrites.map(async (row) => {\r\n const [previous, document] = await Promise.all([\r\n row.previous ? toStorage(row.previous) : undefined,\r\n toStorage(row.document)\r\n ]);\r\n useRows.push({ previous, document });\r\n })\r\n );\r\n\r\n const writeResult = await instance.bulkWrite(useRows, context);\r\n const ret: RxStorageBulkWriteResponse<RxDocType> = {\r\n error: []\r\n };\r\n const promises: Promise<any>[] = [];\r\n writeResult.error.forEach(error => {\r\n promises.push(\r\n errorFromStorage(error).then(err => ret.error.push(err))\r\n );\r\n });\r\n await Promise.all(promises);\r\n\r\n /**\r\n * By definition, all change events must be emitted\r\n * BEFORE the write call resolves.\r\n * To ensure that even when the modifiers are async,\r\n * we wait here until the processing queue is empty.\r\n */\r\n await firstValueFrom(\r\n processingChangesCount$.pipe(\r\n filter((v: number) => v === 0)\r\n )\r\n );\r\n return ret;\r\n },\r\n query: (preparedQuery) => {\r\n return instance.query(preparedQuery)\r\n .then(queryResult => {\r\n return Promise.all(queryResult.documents.map(doc => fromStorage(doc)));\r\n })\r\n .then(documents => ({ documents: documents as any }));\r\n },\r\n getAttachmentData: async (\r\n documentId: string,\r\n attachmentId: string,\r\n digest: string\r\n ) => {\r\n let data = await instance.getAttachmentData(documentId, attachmentId, digest);\r\n data = await modifyAttachmentFromStorage(data);\r\n return data;\r\n },\r\n findDocumentsById: (ids, deleted) => {\r\n return instance.findDocumentsById(ids, deleted)\r\n .then(async (findResult) => {\r\n const ret: RxDocumentData<RxDocType>[] = [];\r\n await Promise.all(\r\n findResult\r\n .map(async (doc) => {\r\n ret.push(await fromStorage(doc));\r\n })\r\n );\r\n return ret;\r\n });\r\n },\r\n getChangedDocumentsSince: !instance.getChangedDocumentsSince ? undefined : (limit, checkpoint) => {\r\n return ((instance as any).getChangedDocumentsSince)(limit, checkpoint)\r\n .then(async (result: any) => {\r\n return {\r\n checkpoint: result.checkpoint,\r\n documents: await Promise.all(\r\n result.documents.map((d: any) => fromStorage(d))\r\n )\r\n };\r\n });\r\n },\r\n changeStream: () => {\r\n return instance.changeStream().pipe(\r\n tap(() => processingChangesCount$.next(processingChangesCount$.getValue() + 1)),\r\n mergeMap(async (eventBulk: EventBulk<RxStorageChangeEvent<RxDocType>, any>) => {\r\n const useEvents = await Promise.all(\r\n eventBulk.events.map(async (event: RxStorageChangeEvent<RxDocType>) => {\r\n const [\r\n documentData,\r\n previousDocumentData\r\n ] = await Promise.all([\r\n fromStorage(event.documentData),\r\n fromStorage(event.previousDocumentData)\r\n ]);\r\n const ev: RxChangeEvent<RxDocType> = {\r\n operation: event.operation,\r\n documentId: event.documentId,\r\n documentData: documentData as any,\r\n previousDocumentData: previousDocumentData as any,\r\n isLocal: false\r\n };\r\n return ev;\r\n })\r\n );\r\n const ret: EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, any> = {\r\n id: eventBulk.id,\r\n events: useEvents,\r\n checkpoint: eventBulk.checkpoint,\r\n context: eventBulk.context\r\n };\r\n return ret;\r\n }),\r\n tap(() => processingChangesCount$.next(processingChangesCount$.getValue() - 1))\r\n );\r\n },\r\n };\r\n\r\n return wrappedInstance;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"plugin-helpers.js","names":["_operators","require","_rxSchemaHelper","_index","_rxError","_rxjs","VALIDATOR_CACHE_BY_VALIDATOR_KEY","Map","wrappedValidateStorageFactory","getValidator","validatorKey","VALIDATOR_CACHE","getFromMapOrCreate","initValidator","schema","JSON","stringify","args","Object","assign","storage","name","createStorageInstance","params","instance","primaryPath","getPrimaryFieldOfPrimaryKey","primaryKey","validatorCached","requestIdleCallbackIfAvailable","oldBulkWrite","bulkWrite","bind","documentWrites","context","errors","continueWrites","forEach","row","documentId","document","validationErrors","length","push","status","isError","writeRow","writePromise","Promise","resolve","error","success","then","writeResult","validationError","wrapRxStorageInstance","originalSchema","modifyToStorage","modifyFromStorage","modifyAttachmentFromStorage","v","toStorage","docData","fromStorage","errorFromStorage","ret","flatClone","documentInDb","previous","processingChangesCount$","BehaviorSubject","wrappedInstance","databaseName","internals","cleanup","options","close","collectionName","count","remove","originalStorageInstance","useRows","all","map","undefined","promises","err","firstValueFrom","pipe","filter","query","preparedQuery","queryResult","newRxError","method","documents","doc","getAttachmentData","attachmentId","digest","data","findDocumentsById","ids","deleted","findResult","getChangedDocumentsSince","limit","checkpoint","result","d","changeStream","tap","next","getValue","mergeMap","eventBulk","useEvents","events","event","documentData","previousDocumentData","ev","operation","isLocal","id"],"sources":["../../src/plugin-helpers.ts"],"sourcesContent":["import { filter, mergeMap, tap } from 'rxjs/operators';\r\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\r\nimport { WrappedRxStorageInstance } from './rx-storage-helper.ts';\r\nimport type {\r\n BulkWriteRow,\r\n EventBulk,\r\n RxChangeEvent,\r\n RxDocumentData,\r\n RxDocumentWriteData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageWriteError,\r\n RxStorageBulkWriteResponse,\r\n RxStorageChangeEvent,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams,\r\n RxValidationError,\r\n RxStorageWriteErrorConflict,\r\n MaybePromise\r\n} from './types/index.d.ts';\r\nimport {\r\n flatClone,\r\n getFromMapOrCreate,\r\n requestIdleCallbackIfAvailable\r\n} from './plugins/utils/index.ts';\r\nimport { newRxError } from './rx-error.ts';\r\nimport { BehaviorSubject, firstValueFrom } from 'rxjs';\r\n\r\n\r\ntype WrappedStorageFunction = <Internals, InstanceCreationOptions>(\r\n args: {\r\n storage: RxStorage<Internals, InstanceCreationOptions>;\r\n }\r\n) => RxStorage<Internals, InstanceCreationOptions>;\r\n\r\n/**\r\n * Returns the validation errors.\r\n * If document is fully valid, returns an empty array.\r\n */\r\ntype ValidatorFunction = (docData: RxDocumentData<any>) => RxValidationError[];\r\n\r\n/**\r\n * cache the validators by the schema string\r\n * so we can reuse them when multiple collections have the same schema\r\n *\r\n * Notice: to make it easier and not dependent on a hash function,\r\n * we use the plain json string.\r\n */\r\nconst VALIDATOR_CACHE_BY_VALIDATOR_KEY: Map<string, Map<string, ValidatorFunction>> = new Map();\r\n\r\n/**\r\n * This factory is used in the validation plugins\r\n * so that we can reuse the basic storage wrapping code.\r\n */\r\nexport function wrappedValidateStorageFactory(\r\n /**\r\n * Returns a method that can be used to validate\r\n * documents and throws when the document is not valid.\r\n */\r\n getValidator: (schema: RxJsonSchema<any>) => ValidatorFunction,\r\n /**\r\n * A string to identify the validation library.\r\n */\r\n validatorKey: string\r\n): WrappedStorageFunction {\r\n const VALIDATOR_CACHE = getFromMapOrCreate(\r\n VALIDATOR_CACHE_BY_VALIDATOR_KEY,\r\n validatorKey,\r\n () => new Map()\r\n );\r\n\r\n function initValidator(\r\n schema: RxJsonSchema<any>\r\n ): ValidatorFunction {\r\n return getFromMapOrCreate(\r\n VALIDATOR_CACHE,\r\n JSON.stringify(schema),\r\n () => getValidator(schema)\r\n );\r\n }\r\n\r\n return (args) => {\r\n return Object.assign(\r\n {},\r\n args.storage,\r\n {\r\n name: 'validate-' + validatorKey + '-' + args.storage.name,\r\n async createStorageInstance<RxDocType>(\r\n params: RxStorageInstanceCreationParams<RxDocType, any>\r\n ) {\r\n const instance = await args.storage.createStorageInstance(params);\r\n const primaryPath = getPrimaryFieldOfPrimaryKey(params.schema.primaryKey);\r\n\r\n /**\r\n * Lazy initialize the validator\r\n * to save initial page load performance.\r\n * Some libraries take really long to initialize the validator\r\n * from the schema.\r\n */\r\n let validatorCached: ValidatorFunction;\r\n requestIdleCallbackIfAvailable(() => validatorCached = initValidator(params.schema));\r\n\r\n const oldBulkWrite = instance.bulkWrite.bind(instance);\r\n instance.bulkWrite = (\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ) => {\r\n if (!validatorCached) {\r\n validatorCached = initValidator(params.schema);\r\n }\r\n const errors: RxStorageWriteError<RxDocType>[] = [];\r\n const continueWrites: typeof documentWrites = [];\r\n documentWrites.forEach(row => {\r\n const documentId: string = row.document[primaryPath] as any;\r\n const validationErrors = validatorCached(row.document);\r\n if (validationErrors.length > 0) {\r\n errors.push({\r\n status: 422,\r\n isError: true,\r\n documentId,\r\n validationErrors,\r\n schema: instance.schema,\r\n writeRow: row,\r\n context\r\n });\r\n } else {\r\n continueWrites.push(row);\r\n }\r\n });\r\n const writePromise: Promise<RxStorageBulkWriteResponse<RxDocType>> = continueWrites.length > 0 ?\r\n oldBulkWrite(continueWrites, context) :\r\n Promise.resolve({ error: [], success: [] });\r\n return writePromise.then(writeResult => {\r\n errors.forEach(validationError => {\r\n writeResult.error.push(validationError);\r\n });\r\n return writeResult;\r\n });\r\n };\r\n\r\n return instance;\r\n }\r\n }\r\n );\r\n };\r\n\r\n}\r\n\r\n\r\n\r\n/**\r\n * Used in plugins to easily modify all in- and outgoing\r\n * data of that storage instance.\r\n */\r\nexport function wrapRxStorageInstance<RxDocType>(\r\n originalSchema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n instance: RxStorageInstance<RxDocType, any, any>,\r\n modifyToStorage: (docData: RxDocumentWriteData<RxDocType>) => MaybePromise<RxDocumentData<any>>,\r\n modifyFromStorage: (docData: RxDocumentData<any>) => MaybePromise<RxDocumentData<RxDocType>>,\r\n modifyAttachmentFromStorage: (attachmentData: Blob) => MaybePromise<Blob> = (v) => v\r\n): WrappedRxStorageInstance<RxDocType, any, any> {\r\n async function toStorage(docData: RxDocumentWriteData<RxDocType>): Promise<RxDocumentData<any>> {\r\n if (!docData) {\r\n return docData;\r\n }\r\n return await modifyToStorage(docData);\r\n }\r\n async function fromStorage(docData: RxDocumentData<any> | null): Promise<RxDocumentData<RxDocType>> {\r\n if (!docData) {\r\n return docData;\r\n }\r\n return await modifyFromStorage(docData);\r\n }\r\n async function errorFromStorage(\r\n error: RxStorageWriteError<any>\r\n ): Promise<RxStorageWriteError<RxDocType>> {\r\n const ret = flatClone(error);\r\n ret.writeRow = flatClone(ret.writeRow);\r\n if ((ret as RxStorageWriteErrorConflict<any>).documentInDb) {\r\n (ret as RxStorageWriteErrorConflict<any>).documentInDb = await fromStorage((ret as RxStorageWriteErrorConflict<any>).documentInDb);\r\n }\r\n if (ret.writeRow.previous) {\r\n ret.writeRow.previous = await fromStorage(ret.writeRow.previous);\r\n }\r\n ret.writeRow.document = await fromStorage(ret.writeRow.document);\r\n return ret;\r\n }\r\n\r\n\r\n const processingChangesCount$ = new BehaviorSubject(0);\r\n\r\n const wrappedInstance: WrappedRxStorageInstance<RxDocType, any, any> = {\r\n databaseName: instance.databaseName,\r\n internals: instance.internals,\r\n cleanup: instance.cleanup.bind(instance),\r\n options: instance.options,\r\n close: instance.close.bind(instance),\r\n schema: originalSchema,\r\n collectionName: instance.collectionName,\r\n count: instance.count.bind(instance),\r\n remove: instance.remove.bind(instance),\r\n originalStorageInstance: instance,\r\n bulkWrite: async (\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ) => {\r\n const useRows: BulkWriteRow<any>[] = [];\r\n await Promise.all(\r\n documentWrites.map(async (row) => {\r\n const [previous, document] = await Promise.all([\r\n row.previous ? toStorage(row.previous) : undefined,\r\n toStorage(row.document)\r\n ]);\r\n useRows.push({ previous, document });\r\n })\r\n );\r\n\r\n const writeResult = await instance.bulkWrite(useRows, context);\r\n const ret: RxStorageBulkWriteResponse<RxDocType> = {\r\n error: []\r\n };\r\n const promises: Promise<any>[] = [];\r\n writeResult.error.forEach(error => {\r\n promises.push(\r\n errorFromStorage(error).then(err => ret.error.push(err))\r\n );\r\n });\r\n await Promise.all(promises);\r\n\r\n /**\r\n * By definition, all change events must be emitted\r\n * BEFORE the write call resolves.\r\n * To ensure that even when the modifiers are async,\r\n * we wait here until the processing queue is empty.\r\n */\r\n await firstValueFrom(\r\n processingChangesCount$.pipe(\r\n filter((v: number) => v === 0)\r\n )\r\n );\r\n return ret;\r\n },\r\n query: (preparedQuery) => {\r\n return instance.query(preparedQuery)\r\n .then(queryResult => {\r\n if (typeof queryResult === 'string') {\r\n throw newRxError('EN5', { method: 'query' });\r\n }\r\n return Promise.all(queryResult.documents.map(doc => fromStorage(doc)));\r\n })\r\n .then(documents => ({ documents: documents as any }));\r\n },\r\n getAttachmentData: async (\r\n documentId: string,\r\n attachmentId: string,\r\n digest: string\r\n ) => {\r\n let data = await instance.getAttachmentData(documentId, attachmentId, digest);\r\n data = await modifyAttachmentFromStorage(data);\r\n return data;\r\n },\r\n findDocumentsById: (ids, deleted) => {\r\n return instance.findDocumentsById(ids, deleted)\r\n .then(async (findResult) => {\r\n if (typeof findResult === 'string') {\r\n throw newRxError('EN5', { method: 'findDocumentsById' });\r\n }\r\n const ret: RxDocumentData<RxDocType>[] = [];\r\n await Promise.all(\r\n findResult\r\n .map(async (doc) => {\r\n ret.push(await fromStorage(doc));\r\n })\r\n );\r\n return ret;\r\n });\r\n },\r\n getChangedDocumentsSince: !instance.getChangedDocumentsSince ? undefined : (limit, checkpoint) => {\r\n return ((instance as any).getChangedDocumentsSince)(limit, checkpoint)\r\n .then(async (result: any) => {\r\n if (typeof result === 'string') {\r\n throw newRxError('EN5', { method: 'getChangedDocumentsSince' });\r\n }\r\n return {\r\n checkpoint: result.checkpoint,\r\n documents: await Promise.all(\r\n result.documents.map((d: any) => fromStorage(d))\r\n )\r\n };\r\n });\r\n },\r\n changeStream: () => {\r\n return instance.changeStream().pipe(\r\n tap(() => processingChangesCount$.next(processingChangesCount$.getValue() + 1)),\r\n mergeMap(async (eventBulk: EventBulk<RxStorageChangeEvent<RxDocType>, any>) => {\r\n const useEvents = await Promise.all(\r\n eventBulk.events.map(async (event: RxStorageChangeEvent<RxDocType>) => {\r\n const [\r\n documentData,\r\n previousDocumentData\r\n ] = await Promise.all([\r\n fromStorage(event.documentData),\r\n fromStorage(event.previousDocumentData)\r\n ]);\r\n const ev: RxChangeEvent<RxDocType> = {\r\n operation: event.operation,\r\n documentId: event.documentId,\r\n documentData: documentData as any,\r\n previousDocumentData: previousDocumentData as any,\r\n isLocal: false\r\n };\r\n return ev;\r\n })\r\n );\r\n const ret: EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, any> = {\r\n id: eventBulk.id,\r\n events: useEvents,\r\n checkpoint: eventBulk.checkpoint,\r\n context: eventBulk.context\r\n };\r\n return ret;\r\n }),\r\n tap(() => processingChangesCount$.next(processingChangesCount$.getValue() - 1))\r\n );\r\n },\r\n };\r\n\r\n return wrappedInstance;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -215,9 +215,9 @@ var RxDBAttachmentsPlugin = exports.RxDBAttachmentsPlugin = {
215
215
  proto.allAttachments = allAttachments;
216
216
  Object.defineProperty(proto, 'allAttachments$', {
217
217
  get: function allAttachments$() {
218
- return this.$.pipe((0, _rxjs.map)(rxDocument => Object.entries(rxDocument.toJSON(true)._attachments)), (0, _rxjs.map)(entries => {
219
- return entries.map(([id, attachmentData]) => {
220
- return fromStorageInstanceResult(id, attachmentData, this);
218
+ return this.$.pipe((0, _rxjs.map)(rxDocument => {
219
+ return Object.entries(rxDocument.toJSON(true)._attachments).map(([id, attachmentData]) => {
220
+ return fromStorageInstanceResult(id, attachmentData, rxDocument);
221
221
  });
222
222
  }));
223
223
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_rxjs","require","_index","_attachmentsUtils","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","RxAttachment","doc","id","type","length","digest","assignMethodsToAttachment","_proto","remove","collection","incrementalWriteQueue","addWrite","_data","docWriteData","_attachments","then","getData","blob","storageInstance","getAttachmentData","primary","slice","size","getStringData","data","asString","blobToString","getDataBase64","blobToBase64String","fromStorageInstanceResult","attachmentData","rxDocument","_putAttachmentsImpl","attachments","ensureSchemaSupportsAttachments","prepared","Promise","all","map","att","database","hashFunction","writeResult","flatClone","newDocument","_docCache","getCachedRxDocument","putAttachment","results","putAttachmentBase64","createBlobFromBase64","putAttachments","getAttachment","docData","attachment","allAttachments","preMigrateDocument","newAttachments","attachmentId","docPrimary","oldCollection","schema","primaryPath","rawAttachmentBlob","postMigrateDocument","_action","PROMISE_RESOLVE_VOID","RxDBAttachmentsPlugin","name","rxdb","prototypes","RxDocument","proto","allAttachments$","$","pipe","entries","toJSON","overwritable","hooks","after"],"sources":["../../../../src/plugins/attachments/index.ts"],"sourcesContent":["import {\r\n map\r\n} from 'rxjs';\r\n\r\nimport {\r\n blobToBase64String,\r\n blobToString,\r\n createBlobFromBase64,\r\n flatClone,\r\n PROMISE_RESOLVE_VOID\r\n} from '../../plugins/utils/index.ts';\r\nimport type {\r\n RxDocument,\r\n RxPlugin,\r\n RxDocumentWriteData,\r\n RxAttachmentData,\r\n RxDocumentData,\r\n RxAttachmentCreator,\r\n RxAttachmentWriteData,\r\n RxCollection,\r\n RxAttachmentCreatorBase64\r\n} from '../../types/index.d.ts';\r\nimport {\r\n assignMethodsToAttachment,\r\n ensureSchemaSupportsAttachments\r\n} from './attachments-utils.ts';\r\n\r\n\r\n\r\n/**\r\n * an RxAttachment is basically just the attachment-stub\r\n * wrapped so that you can access the attachment-data\r\n */\r\nexport class RxAttachment {\r\n public doc: RxDocument;\r\n public id: string;\r\n public type: string;\r\n public length: number;\r\n public digest: string;\r\n constructor({\r\n doc,\r\n id,\r\n type,\r\n length,\r\n digest\r\n }: any) {\r\n this.doc = doc;\r\n this.id = id;\r\n this.type = type;\r\n this.length = length;\r\n this.digest = digest;\r\n\r\n assignMethodsToAttachment(this);\r\n }\r\n\r\n remove(): Promise<void> {\r\n return this.doc.collection.incrementalWriteQueue.addWrite(\r\n this.doc._data,\r\n docWriteData => {\r\n delete docWriteData._attachments[this.id];\r\n return docWriteData;\r\n }\r\n ).then(() => { });\r\n }\r\n\r\n /**\r\n * returns the data for the attachment\r\n */\r\n async getData(): Promise<Blob> {\r\n const blob = await this.doc.collection.storageInstance.getAttachmentData(\r\n this.doc.primary,\r\n this.id,\r\n this.digest\r\n );\r\n // Some storage layers return blobs without the original MIME type.\r\n // Ensure the returned Blob has the attachment's MIME type.\r\n if (blob && blob.type !== this.type) {\r\n return blob.slice(0, blob.size, this.type);\r\n }\r\n return blob;\r\n }\r\n\r\n async getStringData(): Promise<string> {\r\n const data = await this.getData();\r\n const asString = await blobToString(data);\r\n return asString;\r\n }\r\n\r\n async getDataBase64(): Promise<string> {\r\n const blob = await this.getData();\r\n return blobToBase64String(blob);\r\n }\r\n}\r\n\r\nexport function fromStorageInstanceResult<RxDocType>(\r\n id: string,\r\n attachmentData: RxAttachmentData,\r\n rxDocument: RxDocument<RxDocType>\r\n) {\r\n return new RxAttachment({\r\n doc: rxDocument,\r\n id,\r\n type: attachmentData.type,\r\n length: attachmentData.length,\r\n digest: attachmentData.digest\r\n });\r\n}\r\n\r\nasync function _putAttachmentsImpl<RxDocType>(\r\n doc: RxDocument<RxDocType>,\r\n attachments: RxAttachmentCreator[]\r\n): Promise<RxAttachment[]> {\r\n ensureSchemaSupportsAttachments(doc);\r\n\r\n if (attachments.length === 0) {\r\n return [];\r\n }\r\n\r\n const prepared = await Promise.all(\r\n attachments.map(async (att) => ({\r\n id: att.id,\r\n type: att.type,\r\n data: att.data,\r\n digest: await doc.collection.database.hashFunction(att.data)\r\n }))\r\n );\r\n\r\n const writeResult = await doc.collection.incrementalWriteQueue.addWrite(\r\n doc._data,\r\n (docWriteData: RxDocumentWriteData<RxDocType>) => {\r\n docWriteData = flatClone(docWriteData);\r\n docWriteData._attachments = flatClone(docWriteData._attachments);\r\n for (const att of prepared) {\r\n docWriteData._attachments[att.id] = {\r\n length: att.data.size,\r\n type: att.type,\r\n data: att.data,\r\n digest: att.digest\r\n };\r\n }\r\n return docWriteData;\r\n }\r\n );\r\n\r\n const newDocument = doc.collection._docCache.getCachedRxDocument(writeResult);\r\n return prepared.map((att) => fromStorageInstanceResult(\r\n att.id,\r\n writeResult._attachments[att.id],\r\n newDocument\r\n ));\r\n}\r\n\r\nexport async function putAttachment<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachmentData: RxAttachmentCreator\r\n): Promise<RxAttachment> {\r\n const results = await _putAttachmentsImpl(this, [attachmentData]);\r\n return results[0];\r\n}\r\n\r\nexport async function putAttachmentBase64<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachmentData: RxAttachmentCreatorBase64\r\n) {\r\n ensureSchemaSupportsAttachments(this);\r\n const blob = await createBlobFromBase64(attachmentData.data, attachmentData.type);\r\n return this.putAttachment({\r\n id: attachmentData.id,\r\n type: attachmentData.type,\r\n data: blob\r\n });\r\n}\r\n\r\n/**\r\n * Write multiple attachments in a single atomic operation.\r\n */\r\nexport function putAttachments<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachments: RxAttachmentCreator[]\r\n): Promise<RxAttachment[]> {\r\n return _putAttachmentsImpl(this, attachments);\r\n}\r\n\r\n/**\r\n * get an attachment of the document by its id\r\n */\r\nexport function getAttachment(\r\n this: RxDocument,\r\n id: string\r\n): RxAttachment | null {\r\n ensureSchemaSupportsAttachments(this);\r\n const docData: any = this._data;\r\n if (!docData._attachments || !docData._attachments[id])\r\n return null;\r\n\r\n const attachmentData = docData._attachments[id];\r\n const attachment = fromStorageInstanceResult(\r\n id,\r\n attachmentData,\r\n this\r\n );\r\n return attachment;\r\n}\r\n\r\n/**\r\n * returns all attachments of the document\r\n */\r\nexport function allAttachments(\r\n this: RxDocument\r\n): RxAttachment[] {\r\n ensureSchemaSupportsAttachments(this);\r\n const docData: any = this._data;\r\n\r\n // if there are no attachments, the field is missing\r\n if (!docData._attachments) {\r\n return [];\r\n }\r\n return Object.keys(docData._attachments)\r\n .map(id => {\r\n return fromStorageInstanceResult(\r\n id,\r\n docData._attachments[id],\r\n this\r\n );\r\n });\r\n}\r\n\r\nexport async function preMigrateDocument<RxDocType>(\r\n data: {\r\n docData: RxDocumentData<RxDocType>;\r\n oldCollection: RxCollection<RxDocType>;\r\n }\r\n): Promise<void> {\r\n const attachments = data.docData._attachments;\r\n if (attachments) {\r\n const newAttachments: { [attachmentId: string]: RxAttachmentWriteData; } = {};\r\n await Promise.all(\r\n Object.keys(attachments).map(async (attachmentId) => {\r\n const attachment: RxAttachmentData = attachments[attachmentId];\r\n const docPrimary: string = (data.docData as any)[data.oldCollection.schema.primaryPath];\r\n const rawAttachmentBlob = await data.oldCollection.storageInstance.getAttachmentData(\r\n docPrimary,\r\n attachmentId,\r\n attachment.digest\r\n );\r\n const digest = await data.oldCollection.database.hashFunction(rawAttachmentBlob);\r\n newAttachments[attachmentId] = {\r\n length: rawAttachmentBlob.size,\r\n type: attachment.type,\r\n data: rawAttachmentBlob,\r\n digest\r\n };\r\n })\r\n );\r\n\r\n /**\r\n * Hooks mutate the input\r\n * instead of returning stuff\r\n */\r\n (data.docData as RxDocumentWriteData<RxDocType>)._attachments = newAttachments;\r\n }\r\n}\r\n\r\nexport function postMigrateDocument(_action: any): Promise<void> {\r\n /**\r\n * No longer needed because\r\n * we store the attachments data buffers directly in the document.\r\n */\r\n return PROMISE_RESOLVE_VOID;\r\n}\r\n\r\nexport const RxDBAttachmentsPlugin: RxPlugin = {\r\n name: 'attachments',\r\n rxdb: true,\r\n prototypes: {\r\n RxDocument: (proto: any) => {\r\n proto.putAttachment = putAttachment;\r\n proto.putAttachments = putAttachments;\r\n proto.putAttachmentBase64 = putAttachmentBase64;\r\n proto.getAttachment = getAttachment;\r\n proto.allAttachments = allAttachments;\r\n Object.defineProperty(proto, 'allAttachments$', {\r\n get: function allAttachments$(this: RxDocument) {\r\n return this.$\r\n .pipe(\r\n map((rxDocument: RxDocument) => Object.entries(\r\n rxDocument.toJSON(true)._attachments\r\n )),\r\n map((entries: [string, any][]) => {\r\n return entries\r\n .map(([id, attachmentData]: [string, any]) => {\r\n return fromStorageInstanceResult(\r\n id,\r\n attachmentData,\r\n this\r\n );\r\n });\r\n })\r\n );\r\n }\r\n });\r\n }\r\n },\r\n overwritable: {},\r\n hooks: {\r\n preMigrateDocument: {\r\n after: preMigrateDocument\r\n },\r\n postMigrateDocument: {\r\n after: postMigrateDocument\r\n }\r\n }\r\n};\r\n\r\n\r\nexport * from './attachments-utils.ts';\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_rxjs","require","_index","_attachmentsUtils","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","RxAttachment","doc","id","type","length","digest","assignMethodsToAttachment","_proto","remove","collection","incrementalWriteQueue","addWrite","_data","docWriteData","_attachments","then","getData","blob","storageInstance","getAttachmentData","primary","slice","size","getStringData","data","asString","blobToString","getDataBase64","blobToBase64String","fromStorageInstanceResult","attachmentData","rxDocument","_putAttachmentsImpl","attachments","ensureSchemaSupportsAttachments","prepared","Promise","all","map","att","database","hashFunction","writeResult","flatClone","newDocument","_docCache","getCachedRxDocument","putAttachment","results","putAttachmentBase64","createBlobFromBase64","putAttachments","getAttachment","docData","attachment","allAttachments","preMigrateDocument","newAttachments","attachmentId","docPrimary","oldCollection","schema","primaryPath","rawAttachmentBlob","postMigrateDocument","_action","PROMISE_RESOLVE_VOID","RxDBAttachmentsPlugin","name","rxdb","prototypes","RxDocument","proto","allAttachments$","$","pipe","entries","toJSON","overwritable","hooks","after"],"sources":["../../../../src/plugins/attachments/index.ts"],"sourcesContent":["import {\r\n map\r\n} from 'rxjs';\r\n\r\nimport {\r\n blobToBase64String,\r\n blobToString,\r\n createBlobFromBase64,\r\n flatClone,\r\n PROMISE_RESOLVE_VOID\r\n} from '../../plugins/utils/index.ts';\r\nimport type {\r\n RxDocument,\r\n RxPlugin,\r\n RxDocumentWriteData,\r\n RxAttachmentData,\r\n RxDocumentData,\r\n RxAttachmentCreator,\r\n RxAttachmentWriteData,\r\n RxCollection,\r\n RxAttachmentCreatorBase64\r\n} from '../../types/index.d.ts';\r\nimport {\r\n assignMethodsToAttachment,\r\n ensureSchemaSupportsAttachments\r\n} from './attachments-utils.ts';\r\n\r\n\r\n\r\n/**\r\n * an RxAttachment is basically just the attachment-stub\r\n * wrapped so that you can access the attachment-data\r\n */\r\nexport class RxAttachment {\r\n public doc: RxDocument;\r\n public id: string;\r\n public type: string;\r\n public length: number;\r\n public digest: string;\r\n constructor({\r\n doc,\r\n id,\r\n type,\r\n length,\r\n digest\r\n }: any) {\r\n this.doc = doc;\r\n this.id = id;\r\n this.type = type;\r\n this.length = length;\r\n this.digest = digest;\r\n\r\n assignMethodsToAttachment(this);\r\n }\r\n\r\n remove(): Promise<void> {\r\n return this.doc.collection.incrementalWriteQueue.addWrite(\r\n this.doc._data,\r\n docWriteData => {\r\n delete docWriteData._attachments[this.id];\r\n return docWriteData;\r\n }\r\n ).then(() => { });\r\n }\r\n\r\n /**\r\n * returns the data for the attachment\r\n */\r\n async getData(): Promise<Blob> {\r\n const blob = await this.doc.collection.storageInstance.getAttachmentData(\r\n this.doc.primary,\r\n this.id,\r\n this.digest\r\n );\r\n // Some storage layers return blobs without the original MIME type.\r\n // Ensure the returned Blob has the attachment's MIME type.\r\n if (blob && blob.type !== this.type) {\r\n return blob.slice(0, blob.size, this.type);\r\n }\r\n return blob;\r\n }\r\n\r\n async getStringData(): Promise<string> {\r\n const data = await this.getData();\r\n const asString = await blobToString(data);\r\n return asString;\r\n }\r\n\r\n async getDataBase64(): Promise<string> {\r\n const blob = await this.getData();\r\n return blobToBase64String(blob);\r\n }\r\n}\r\n\r\nexport function fromStorageInstanceResult<RxDocType>(\r\n id: string,\r\n attachmentData: RxAttachmentData,\r\n rxDocument: RxDocument<RxDocType>\r\n) {\r\n return new RxAttachment({\r\n doc: rxDocument,\r\n id,\r\n type: attachmentData.type,\r\n length: attachmentData.length,\r\n digest: attachmentData.digest\r\n });\r\n}\r\n\r\nasync function _putAttachmentsImpl<RxDocType>(\r\n doc: RxDocument<RxDocType>,\r\n attachments: RxAttachmentCreator[]\r\n): Promise<RxAttachment[]> {\r\n ensureSchemaSupportsAttachments(doc);\r\n\r\n if (attachments.length === 0) {\r\n return [];\r\n }\r\n\r\n const prepared = await Promise.all(\r\n attachments.map(async (att) => ({\r\n id: att.id,\r\n type: att.type,\r\n data: att.data,\r\n digest: await doc.collection.database.hashFunction(att.data)\r\n }))\r\n );\r\n\r\n const writeResult = await doc.collection.incrementalWriteQueue.addWrite(\r\n doc._data,\r\n (docWriteData: RxDocumentWriteData<RxDocType>) => {\r\n docWriteData = flatClone(docWriteData);\r\n docWriteData._attachments = flatClone(docWriteData._attachments);\r\n for (const att of prepared) {\r\n docWriteData._attachments[att.id] = {\r\n length: att.data.size,\r\n type: att.type,\r\n data: att.data,\r\n digest: att.digest\r\n };\r\n }\r\n return docWriteData;\r\n }\r\n );\r\n\r\n const newDocument = doc.collection._docCache.getCachedRxDocument(writeResult);\r\n return prepared.map((att) => fromStorageInstanceResult(\r\n att.id,\r\n writeResult._attachments[att.id],\r\n newDocument\r\n ));\r\n}\r\n\r\nexport async function putAttachment<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachmentData: RxAttachmentCreator\r\n): Promise<RxAttachment> {\r\n const results = await _putAttachmentsImpl(this, [attachmentData]);\r\n return results[0];\r\n}\r\n\r\nexport async function putAttachmentBase64<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachmentData: RxAttachmentCreatorBase64\r\n) {\r\n ensureSchemaSupportsAttachments(this);\r\n const blob = await createBlobFromBase64(attachmentData.data, attachmentData.type);\r\n return this.putAttachment({\r\n id: attachmentData.id,\r\n type: attachmentData.type,\r\n data: blob\r\n });\r\n}\r\n\r\n/**\r\n * Write multiple attachments in a single atomic operation.\r\n */\r\nexport function putAttachments<RxDocType>(\r\n this: RxDocument<RxDocType>,\r\n attachments: RxAttachmentCreator[]\r\n): Promise<RxAttachment[]> {\r\n return _putAttachmentsImpl(this, attachments);\r\n}\r\n\r\n/**\r\n * get an attachment of the document by its id\r\n */\r\nexport function getAttachment(\r\n this: RxDocument,\r\n id: string\r\n): RxAttachment | null {\r\n ensureSchemaSupportsAttachments(this);\r\n const docData: any = this._data;\r\n if (!docData._attachments || !docData._attachments[id])\r\n return null;\r\n\r\n const attachmentData = docData._attachments[id];\r\n const attachment = fromStorageInstanceResult(\r\n id,\r\n attachmentData,\r\n this\r\n );\r\n return attachment;\r\n}\r\n\r\n/**\r\n * returns all attachments of the document\r\n */\r\nexport function allAttachments(\r\n this: RxDocument\r\n): RxAttachment[] {\r\n ensureSchemaSupportsAttachments(this);\r\n const docData: any = this._data;\r\n\r\n // if there are no attachments, the field is missing\r\n if (!docData._attachments) {\r\n return [];\r\n }\r\n return Object.keys(docData._attachments)\r\n .map(id => {\r\n return fromStorageInstanceResult(\r\n id,\r\n docData._attachments[id],\r\n this\r\n );\r\n });\r\n}\r\n\r\nexport async function preMigrateDocument<RxDocType>(\r\n data: {\r\n docData: RxDocumentData<RxDocType>;\r\n oldCollection: RxCollection<RxDocType>;\r\n }\r\n): Promise<void> {\r\n const attachments = data.docData._attachments;\r\n if (attachments) {\r\n const newAttachments: { [attachmentId: string]: RxAttachmentWriteData; } = {};\r\n await Promise.all(\r\n Object.keys(attachments).map(async (attachmentId) => {\r\n const attachment: RxAttachmentData = attachments[attachmentId];\r\n const docPrimary: string = (data.docData as any)[data.oldCollection.schema.primaryPath];\r\n const rawAttachmentBlob = await data.oldCollection.storageInstance.getAttachmentData(\r\n docPrimary,\r\n attachmentId,\r\n attachment.digest\r\n );\r\n const digest = await data.oldCollection.database.hashFunction(rawAttachmentBlob);\r\n newAttachments[attachmentId] = {\r\n length: rawAttachmentBlob.size,\r\n type: attachment.type,\r\n data: rawAttachmentBlob,\r\n digest\r\n };\r\n })\r\n );\r\n\r\n /**\r\n * Hooks mutate the input\r\n * instead of returning stuff\r\n */\r\n (data.docData as RxDocumentWriteData<RxDocType>)._attachments = newAttachments;\r\n }\r\n}\r\n\r\nexport function postMigrateDocument(_action: any): Promise<void> {\r\n /**\r\n * No longer needed because\r\n * we store the attachments data buffers directly in the document.\r\n */\r\n return PROMISE_RESOLVE_VOID;\r\n}\r\n\r\nexport const RxDBAttachmentsPlugin: RxPlugin = {\r\n name: 'attachments',\r\n rxdb: true,\r\n prototypes: {\r\n RxDocument: (proto: any) => {\r\n proto.putAttachment = putAttachment;\r\n proto.putAttachments = putAttachments;\r\n proto.putAttachmentBase64 = putAttachmentBase64;\r\n proto.getAttachment = getAttachment;\r\n proto.allAttachments = allAttachments;\r\n Object.defineProperty(proto, 'allAttachments$', {\r\n get: function allAttachments$(this: RxDocument) {\r\n return this.$\r\n .pipe(\r\n map((rxDocument: RxDocument) => {\r\n return Object.entries(\r\n rxDocument.toJSON(true)._attachments\r\n ).map(([id, attachmentData]: [string, any]) => {\r\n return fromStorageInstanceResult(\r\n id,\r\n attachmentData,\r\n rxDocument\r\n );\r\n });\r\n })\r\n );\r\n }\r\n });\r\n }\r\n },\r\n overwritable: {},\r\n hooks: {\r\n preMigrateDocument: {\r\n after: preMigrateDocument\r\n },\r\n postMigrateDocument: {\r\n after: postMigrateDocument\r\n }\r\n }\r\n};\r\n\r\n\r\nexport * from './attachments-utils.ts';\r\n"],"mappings":"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","ignoreList":[]}
@@ -78,17 +78,19 @@ async function cleanupRxCollection(rxCollection, cleanupPolicy) {
78
78
  return true;
79
79
  }
80
80
  await rxDatabase.requestIdlePromise();
81
+ if (rxCollection.closed) {
82
+ return true;
83
+ }
81
84
  var allDone = [];
82
85
  allDone.push(storageInstance.cleanup(cleanupPolicy.minimumDeletedTime));
83
86
  var replicationStates = (0, _index.getFromMapOrCreate)(_index2.REPLICATION_STATE_BY_COLLECTION, rxCollection, () => []);
84
87
  for (var replicationState of replicationStates) {
85
88
  var meta = replicationState.metaInstance;
86
- if (meta) {
89
+ if (meta && !replicationState.isStopped()) {
87
90
  allDone.push(meta.cleanup(cleanupPolicy.minimumDeletedTime));
88
91
  }
89
92
  }
90
- var hasFalse = (await Promise.all(allDone)).find(v => !v);
91
- return !hasFalse;
93
+ return (await Promise.all(allDone)).every(v => v);
92
94
  });
93
95
  isDone = await RXSTORAGE_CLEANUP_QUEUE;
94
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.js","names":["_index","require","_index2","_cleanupHelper","_hooks","_rxjs","RXSTORAGE_CLEANUP_QUEUE","PROMISE_RESOLVE_TRUE","startCleanupForRxCollection","rxCollection","rxDatabase","database","cleanupPolicy","Object","assign","DEFAULT_CLEANUP_POLICY","initialCleanupWait","closed","cleanupRxCollection","runCleanupAfterDelete","collection","promiseWait","minimumCollectionAge","multiInstance","waitForLeadership","storageInstance","isDone","awaitReplicationsInSync","replicationStates","getFromMapOrCreate","REPLICATION_STATE_BY_COLLECTION","Promise","all","map","replicationState","isStopped","awaitInSync","then","requestIdlePromise","allDone","push","cleanup","minimumDeletedTime","meta","metaInstance","hasFalse","find","v","runAsyncPluginHooks","collectionName","name","databaseName","firstValueFrom","eventBulks$","catch","runEach"],"sources":["../../../../src/plugins/cleanup/cleanup.ts"],"sourcesContent":["import type { RxCleanupPolicy, RxCollection } from '../../types/index.d.ts';\r\nimport { PROMISE_RESOLVE_TRUE, getFromMapOrCreate } from '../../plugins/utils/index.ts';\r\nimport { REPLICATION_STATE_BY_COLLECTION } from '../replication/index.ts';\r\nimport { DEFAULT_CLEANUP_POLICY } from './cleanup-helper.ts';\r\nimport { runAsyncPluginHooks } from '../../hooks.ts';\r\nimport { filter, firstValueFrom } from 'rxjs';\r\n\r\n/**\r\n * Even on multiple databases,\r\n * the calls to RxStorage().cleanup()\r\n * must never run in parallel.\r\n * The cleanup is a background task which should\r\n * not affect the performance of other, more important tasks.\r\n */\r\nlet RXSTORAGE_CLEANUP_QUEUE: Promise<boolean> = PROMISE_RESOLVE_TRUE;\r\n\r\nexport async function startCleanupForRxCollection(\r\n rxCollection: RxCollection\r\n) {\r\n const rxDatabase = rxCollection.database;\r\n const cleanupPolicy = Object.assign(\r\n {},\r\n DEFAULT_CLEANUP_POLICY,\r\n rxDatabase.cleanupPolicy ? rxDatabase.cleanupPolicy : {}\r\n );\r\n\r\n\r\n await initialCleanupWait(rxCollection, cleanupPolicy);\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n\r\n // initially cleanup the collection\r\n await cleanupRxCollection(rxCollection, cleanupPolicy);\r\n\r\n /**\r\n * Afterwards we listen to deletes\r\n * and only re-run the cleanup after\r\n * minimumDeletedTime is reached.\r\n */\r\n await runCleanupAfterDelete(rxCollection, cleanupPolicy);\r\n}\r\n\r\n\r\nexport async function initialCleanupWait(collection: RxCollection, cleanupPolicy: RxCleanupPolicy) {\r\n /**\r\n * Wait until minimumDatabaseInstanceAge is reached\r\n * or collection is closed.\r\n */\r\n await collection.promiseWait(cleanupPolicy.minimumCollectionAge);\r\n if (collection.closed) {\r\n return;\r\n }\r\n\r\n if (collection.database.multiInstance && cleanupPolicy.waitForLeadership) {\r\n await collection.database.waitForLeadership();\r\n }\r\n}\r\n\r\n/**\r\n * Runs the cleanup for a single RxCollection\r\n */\r\nexport async function cleanupRxCollection(\r\n rxCollection: RxCollection,\r\n cleanupPolicy: RxCleanupPolicy\r\n) {\r\n const rxDatabase = rxCollection.database;\r\n const storageInstance = rxCollection.storageInstance;\r\n\r\n // run cleanup() until it returns true\r\n let isDone = false;\r\n while (!isDone && !rxCollection.closed) {\r\n if (cleanupPolicy.awaitReplicationsInSync) {\r\n const replicationStates = getFromMapOrCreate(\r\n REPLICATION_STATE_BY_COLLECTION,\r\n rxCollection,\r\n () => []\r\n );\r\n await Promise.all(\r\n replicationStates.map(replicationState => {\r\n if (!replicationState.isStopped()) {\r\n return replicationState.awaitInSync();\r\n }\r\n })\r\n );\r\n }\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n RXSTORAGE_CLEANUP_QUEUE = RXSTORAGE_CLEANUP_QUEUE\r\n .then(async () => {\r\n if (rxCollection.closed) {\r\n return true;\r\n }\r\n await rxDatabase.requestIdlePromise();\r\n const allDone: Promise<boolean>[] = [];\r\n allDone.push(storageInstance.cleanup(cleanupPolicy.minimumDeletedTime));\r\n const replicationStates = getFromMapOrCreate(\r\n REPLICATION_STATE_BY_COLLECTION,\r\n rxCollection,\r\n () => []\r\n );\r\n for (const replicationState of replicationStates) {\r\n const meta = replicationState.metaInstance;\r\n if (meta) {\r\n allDone.push(meta.cleanup(cleanupPolicy.minimumDeletedTime));\r\n }\r\n }\r\n\r\n const hasFalse = (await Promise.all(allDone)).find(v => !v);\r\n return !hasFalse;\r\n });\r\n isDone = await RXSTORAGE_CLEANUP_QUEUE;\r\n }\r\n await runAsyncPluginHooks('postCleanup', {\r\n collectionName: rxCollection.name,\r\n databaseName: rxDatabase.name\r\n });\r\n}\r\n\r\nexport async function runCleanupAfterDelete(\r\n rxCollection: RxCollection,\r\n cleanupPolicy: RxCleanupPolicy\r\n) {\r\n while (!rxCollection.closed) {\r\n /**\r\n * In theory we should wait here until a document is deleted.\r\n * But this would mean we have to search through all events ever processed.\r\n * So instead we just wait for any write event and then we anyway throttle\r\n * the calls with the promiseWait() below.\r\n */\r\n await firstValueFrom(rxCollection.eventBulks$).catch(() => { });\r\n\r\n await rxCollection.promiseWait(cleanupPolicy.runEach);\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n await cleanupRxCollection(rxCollection, cleanupPolicy);\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"cleanup.js","names":["_index","require","_index2","_cleanupHelper","_hooks","_rxjs","RXSTORAGE_CLEANUP_QUEUE","PROMISE_RESOLVE_TRUE","startCleanupForRxCollection","rxCollection","rxDatabase","database","cleanupPolicy","Object","assign","DEFAULT_CLEANUP_POLICY","initialCleanupWait","closed","cleanupRxCollection","runCleanupAfterDelete","collection","promiseWait","minimumCollectionAge","multiInstance","waitForLeadership","storageInstance","isDone","awaitReplicationsInSync","replicationStates","getFromMapOrCreate","REPLICATION_STATE_BY_COLLECTION","Promise","all","map","replicationState","isStopped","awaitInSync","then","requestIdlePromise","allDone","push","cleanup","minimumDeletedTime","meta","metaInstance","every","v","runAsyncPluginHooks","collectionName","name","databaseName","firstValueFrom","eventBulks$","catch","runEach"],"sources":["../../../../src/plugins/cleanup/cleanup.ts"],"sourcesContent":["import type { RxCleanupPolicy, RxCollection } from '../../types/index.d.ts';\r\nimport { PROMISE_RESOLVE_TRUE, getFromMapOrCreate } from '../../plugins/utils/index.ts';\r\nimport { REPLICATION_STATE_BY_COLLECTION } from '../replication/index.ts';\r\nimport { DEFAULT_CLEANUP_POLICY } from './cleanup-helper.ts';\r\nimport { runAsyncPluginHooks } from '../../hooks.ts';\r\nimport { filter, firstValueFrom } from 'rxjs';\r\n\r\n/**\r\n * Even on multiple databases,\r\n * the calls to RxStorage().cleanup()\r\n * must never run in parallel.\r\n * The cleanup is a background task which should\r\n * not affect the performance of other, more important tasks.\r\n */\r\nlet RXSTORAGE_CLEANUP_QUEUE: Promise<boolean> = PROMISE_RESOLVE_TRUE;\r\n\r\nexport async function startCleanupForRxCollection(\r\n rxCollection: RxCollection\r\n) {\r\n const rxDatabase = rxCollection.database;\r\n const cleanupPolicy = Object.assign(\r\n {},\r\n DEFAULT_CLEANUP_POLICY,\r\n rxDatabase.cleanupPolicy ? rxDatabase.cleanupPolicy : {}\r\n );\r\n\r\n\r\n await initialCleanupWait(rxCollection, cleanupPolicy);\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n\r\n // initially cleanup the collection\r\n await cleanupRxCollection(rxCollection, cleanupPolicy);\r\n\r\n /**\r\n * Afterwards we listen to deletes\r\n * and only re-run the cleanup after\r\n * minimumDeletedTime is reached.\r\n */\r\n await runCleanupAfterDelete(rxCollection, cleanupPolicy);\r\n}\r\n\r\n\r\nexport async function initialCleanupWait(collection: RxCollection, cleanupPolicy: RxCleanupPolicy) {\r\n /**\r\n * Wait until minimumDatabaseInstanceAge is reached\r\n * or collection is closed.\r\n */\r\n await collection.promiseWait(cleanupPolicy.minimumCollectionAge);\r\n if (collection.closed) {\r\n return;\r\n }\r\n\r\n if (collection.database.multiInstance && cleanupPolicy.waitForLeadership) {\r\n await collection.database.waitForLeadership();\r\n }\r\n}\r\n\r\n/**\r\n * Runs the cleanup for a single RxCollection\r\n */\r\nexport async function cleanupRxCollection(\r\n rxCollection: RxCollection,\r\n cleanupPolicy: RxCleanupPolicy\r\n) {\r\n const rxDatabase = rxCollection.database;\r\n const storageInstance = rxCollection.storageInstance;\r\n\r\n // run cleanup() until it returns true\r\n let isDone = false;\r\n while (!isDone && !rxCollection.closed) {\r\n if (cleanupPolicy.awaitReplicationsInSync) {\r\n const replicationStates = getFromMapOrCreate(\r\n REPLICATION_STATE_BY_COLLECTION,\r\n rxCollection,\r\n () => []\r\n );\r\n await Promise.all(\r\n replicationStates.map(replicationState => {\r\n if (!replicationState.isStopped()) {\r\n return replicationState.awaitInSync();\r\n }\r\n })\r\n );\r\n }\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n RXSTORAGE_CLEANUP_QUEUE = RXSTORAGE_CLEANUP_QUEUE\r\n .then(async () => {\r\n if (rxCollection.closed) {\r\n return true;\r\n }\r\n await rxDatabase.requestIdlePromise();\r\n if (rxCollection.closed) {\r\n return true;\r\n }\r\n const allDone: Promise<boolean>[] = [];\r\n allDone.push(storageInstance.cleanup(cleanupPolicy.minimumDeletedTime));\r\n const replicationStates = getFromMapOrCreate(\r\n REPLICATION_STATE_BY_COLLECTION,\r\n rxCollection,\r\n () => []\r\n );\r\n for (const replicationState of replicationStates) {\r\n const meta = replicationState.metaInstance;\r\n if (meta && !replicationState.isStopped()) {\r\n allDone.push(meta.cleanup(cleanupPolicy.minimumDeletedTime));\r\n }\r\n }\r\n\r\n return (await Promise.all(allDone)).every(v => v);\r\n });\r\n isDone = await RXSTORAGE_CLEANUP_QUEUE;\r\n }\r\n await runAsyncPluginHooks('postCleanup', {\r\n collectionName: rxCollection.name,\r\n databaseName: rxDatabase.name\r\n });\r\n}\r\n\r\nexport async function runCleanupAfterDelete(\r\n rxCollection: RxCollection,\r\n cleanupPolicy: RxCleanupPolicy\r\n) {\r\n while (!rxCollection.closed) {\r\n /**\r\n * In theory we should wait here until a document is deleted.\r\n * But this would mean we have to search through all events ever processed.\r\n * So instead we just wait for any write event and then we anyway throttle\r\n * the calls with the promiseWait() below.\r\n */\r\n await firstValueFrom(rxCollection.eventBulks$).catch(() => { });\r\n\r\n await rxCollection.promiseWait(cleanupPolicy.runEach);\r\n if (rxCollection.closed) {\r\n return;\r\n }\r\n await cleanupRxCollection(rxCollection, cleanupPolicy);\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -16,6 +16,7 @@ var _rxError = require("../../rx-error.js");
16
16
  var _index = require("../../plugins/utils/index.js");
17
17
  var _index2 = require("../../index.js");
18
18
  var _mingoUpdater = require("../update/mingo-updater.js");
19
+ var _rxSchemaHelper = require("../../rx-schema-helper.js");
19
20
  async function updateCRDT(entry) {
20
21
  entry = _index2.overwritable.deepFreezeWhenDevMode(entry);
21
22
  var jsonSchema = this.collection.schema.jsonSchema;
@@ -258,6 +259,42 @@ var RxDBcrdtPlugin = exports.RxDBcrdtPlugin = {
258
259
  }
259
260
  });
260
261
  };
262
+ var oldincrementalRemove = proto.incrementalRemove;
263
+ proto.incrementalRemove = function () {
264
+ if (!this.collection.schema.jsonSchema.crdt) {
265
+ return oldincrementalRemove.call(this);
266
+ }
267
+ return this.updateCRDT({
268
+ ifMatch: {
269
+ $set: {
270
+ _deleted: true
271
+ }
272
+ }
273
+ });
274
+ };
275
+ var oldModify = proto.modify;
276
+ proto.modify = function (fn, context) {
277
+ if (!this.collection.schema.jsonSchema.crdt) {
278
+ return oldModify.call(this, fn, context);
279
+ }
280
+ throw (0, _rxError.newRxError)('CRDT4', {
281
+ id: this.primary,
282
+ args: {
283
+ method: 'modify'
284
+ }
285
+ });
286
+ };
287
+ var oldPatch = proto.patch;
288
+ proto.patch = function (patch) {
289
+ if (!this.collection.schema.jsonSchema.crdt) {
290
+ return oldPatch.call(this, patch);
291
+ }
292
+ return this.updateCRDT({
293
+ ifMatch: {
294
+ $set: patch
295
+ }
296
+ });
297
+ };
261
298
  var oldincrementalPatch = proto.incrementalPatch;
262
299
  proto.incrementalPatch = function (patch) {
263
300
  if (!this.collection.schema.jsonSchema.crdt) {
@@ -285,6 +322,15 @@ var RxDBcrdtPlugin = exports.RxDBcrdtPlugin = {
285
322
  });
286
323
  }
287
324
  };
325
+ var oldUpdate = proto.update;
326
+ proto.update = function (updateObj) {
327
+ if (!this.collection.schema.jsonSchema.crdt) {
328
+ return oldUpdate.call(this, updateObj);
329
+ }
330
+ return this.updateCRDT({
331
+ ifMatch: updateObj
332
+ });
333
+ };
288
334
  },
289
335
  RxCollection: proto => {
290
336
  proto.insertCRDT = insertCRDT;
@@ -361,6 +407,12 @@ var RxDBcrdtPlugin = exports.RxDBcrdtPlugin = {
361
407
  collection.bulkInsert = async function (docsData) {
362
408
  var storageToken = await collection.database.storageToken;
363
409
  var useDocsData = await Promise.all(docsData.map(async docData => {
410
+ /**
411
+ * Fill schema default values before creating CRDT operations,
412
+ * so that default values are captured in the operations and
413
+ * will be preserved during rebuildFromCRDT (conflict resolution).
414
+ */
415
+ (0, _rxSchemaHelper.fillObjectWithDefaults)(collection.schema, docData);
364
416
  var setMe = {};
365
417
  Object.entries(docData).forEach(([key, value]) => {
366
418
  if (!key.startsWith('_') && key !== crdtField) {