@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":"rx-storage-instance-mongodb.js","names":["BehaviorSubject","Subject","filter","firstValueFrom","getPrimaryFieldOfPrimaryKey","ensureNotFalsy","getFromMapOrThrow","isMaybeReadonlyArray","now","PROMISE_RESOLVE_VOID","requestIdlePromise","MongoClient","categorizeBulkWriteRows","MONGO_ID_SUBSTITUTE_FIELDNAME","MONGO_OPTIONS_DRIVER_INFO","getMongoDBIndexName","prepareMongoDBQuery","swapMongoToRxDoc","swapRxDocToMongo","RxStorageInstanceMongoDB","storage","databaseName","collectionName","schema","internals","options","settings","changes$","runningOperations","writeQueue","mongoObjectIdCache","WeakMap","attachments","Error","primaryPath","primaryKey","inMongoPrimaryPath","mongoClient","databaseSettings","connection","mongoDatabase","db","version","indexes","slice","map","index","arIndex","push","mongoCollectionPromise","createCollection","then","mongoCollection","createIndexes","mongoIndex","forEach","field","name","key","_proto","prototype","bulkWrite","documentWrites","context","next","getValue","closed","Promise","reject","ret","error","docIds","d","document","documentStates","findDocumentsById","documentStatesMap","Map","doc","docId","set","categorized","changeByDocId","eventBulk","events","change","documentId","errors","all","bulkInsertDocs","writeRow","writeResult","findOneAndUpdate","$setOnInsert","upsert","includeResultMetadata","value","conflictError","status","documentInDb","isError","event","get","bulkUpdateDocs","findOneAndReplace","_rev","previous","returnDocument","ok","currentDocState","currentDoc","length","lastState","newestRow","checkpoint","id","lwt","_meta","withDeleted","session","plainQuery","$in","_deleted","result","queryResult","find","toArray","row","query","originalPreparedQuery","preparedQuery","mongoSelector","skip","limit","sort","mongoSort","resultDocs","documents","count","countDocuments","mode","cleanup","minimumDeletedTime","maxDeletionTime","deleteMany","$lt","getAttachmentData","_documentId","_attachmentId","_digest","changeStream","remove","drop","close","pipe","c","createMongoDBStorageInstance","params","instance","resolve"],"sources":["../../../../src/plugins/storage-mongodb/rx-storage-instance-mongodb.ts"],"sourcesContent":["import {\r\n BehaviorSubject,\r\n Observable,\r\n Subject,\r\n filter,\r\n firstValueFrom\r\n} from 'rxjs';\r\nimport { getPrimaryFieldOfPrimaryKey } from '../../rx-schema-helper.ts';\r\nimport type {\r\n BulkWriteRow,\r\n EventBulk,\r\n PreparedQuery,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorageBulkWriteResponse,\r\n RxStorageChangeEvent,\r\n RxStorageCountResult,\r\n RxStorageDefaultCheckpoint,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams,\r\n RxStorageQueryResult,\r\n RxStorageWriteErrorConflict,\r\n StringKeys\r\n} from '../../types/index.d.ts';\r\nimport {\r\n ensureNotFalsy,\r\n getFromMapOrThrow,\r\n isMaybeReadonlyArray,\r\n now,\r\n PROMISE_RESOLVE_VOID,\r\n requestIdlePromise\r\n} from '../../plugins/utils/index.ts';\r\nimport {\r\n MongoDBStorageInternals,\r\n MongoQuerySelector,\r\n RxStorageMongoDBInstanceCreationOptions,\r\n RxStorageMongoDBSettings\r\n} from './mongodb-types.ts';\r\nimport { RxStorageMongoDB } from './rx-storage-mongodb.ts';\r\nimport {\r\n Db as MongoDatabase,\r\n Collection as MongoCollection,\r\n MongoClient,\r\n ObjectId,\r\n ClientSession\r\n} from 'mongodb';\r\nimport { categorizeBulkWriteRows } from '../../rx-storage-helper.ts';\r\nimport {\r\n MONGO_ID_SUBSTITUTE_FIELDNAME,\r\n MONGO_OPTIONS_DRIVER_INFO,\r\n getMongoDBIndexName,\r\n prepareMongoDBQuery,\r\n swapMongoToRxDoc,\r\n swapRxDocToMongo\r\n} from './mongodb-helper.ts';\r\n\r\nexport class RxStorageInstanceMongoDB<RxDocType> implements RxStorageInstance<\r\n RxDocType,\r\n MongoDBStorageInternals,\r\n RxStorageMongoDBInstanceCreationOptions,\r\n RxStorageDefaultCheckpoint\r\n> {\r\n\r\n public readonly primaryPath: StringKeys<RxDocumentData<RxDocType>>;\r\n public readonly inMongoPrimaryPath: string;\r\n public closed?: Promise<void>;\r\n private readonly changes$: Subject<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>> = new Subject();\r\n public readonly mongoClient: MongoClient;\r\n public readonly mongoDatabase: MongoDatabase;\r\n public readonly mongoCollectionPromise: Promise<MongoCollection<RxDocumentData<RxDocType> | any>>;\r\n // public mongoChangeStream?: MongoChangeStream<any, ChangeStreamDocument<any>>;\r\n\r\n\r\n /**\r\n * Closing the connection must not happen when\r\n * an operation is running, otherwise we get an error.\r\n * So we store all running operations here so that\r\n * they can be awaited.\r\n */\r\n public readonly runningOperations = new BehaviorSubject(0);\r\n public writeQueue: Promise<any> = PROMISE_RESOLVE_VOID;\r\n\r\n /**\r\n * We use this to be able to still fetch\r\n * the objectId after transforming the document from mongo-style (with _id)\r\n * to RxDB\r\n */\r\n public readonly mongoObjectIdCache = new WeakMap<RxDocumentData<RxDocType>, ObjectId>();\r\n\r\n constructor(\r\n public readonly storage: RxStorageMongoDB,\r\n public readonly databaseName: string,\r\n public readonly collectionName: string,\r\n public readonly schema: Readonly<RxJsonSchema<RxDocumentData<RxDocType>>>,\r\n public readonly internals: MongoDBStorageInternals,\r\n public readonly options: Readonly<RxStorageMongoDBInstanceCreationOptions>,\r\n public readonly settings: RxStorageMongoDBSettings\r\n ) {\r\n if (this.schema.attachments) {\r\n throw new Error('attachments not supported in mongodb storage, make a PR if you need that');\r\n }\r\n this.primaryPath = getPrimaryFieldOfPrimaryKey(this.schema.primaryKey);\r\n this.inMongoPrimaryPath = this.primaryPath === '_id' ? MONGO_ID_SUBSTITUTE_FIELDNAME : this.primaryPath;\r\n\r\n this.mongoClient = new MongoClient(storage.databaseSettings.connection, MONGO_OPTIONS_DRIVER_INFO);\r\n this.mongoDatabase = this.mongoClient.db(databaseName + '-v' + this.schema.version);\r\n\r\n const indexes = (this.schema.indexes ? this.schema.indexes.slice() : []).map(index => {\r\n const arIndex = isMaybeReadonlyArray(index) ? index.slice(0) : [index];\r\n return arIndex;\r\n });\r\n indexes.push([this.inMongoPrimaryPath]);\r\n\r\n this.mongoCollectionPromise = this.mongoDatabase.createCollection(collectionName)\r\n .then(async (mongoCollection: MongoCollection<any>) => {\r\n await mongoCollection.createIndexes(\r\n indexes.map(index => {\r\n const mongoIndex: any = {};\r\n index.forEach(field => mongoIndex[field] = 1);\r\n return { name: getMongoDBIndexName(index), key: mongoIndex };\r\n })\r\n );\r\n\r\n /**\r\n * TODO in a setup where multiple servers run node.js\r\n * processes that use the mongodb storage, we should propagate\r\n * events by listening to the mongodb changestream.\r\n * This maybe should be a premium feature.\r\n */\r\n // this.mongoChangeStream = mongoCollection.watch(\r\n // undefined, {\r\n // batchSize: 100\r\n // }\r\n // ).on('change', change => {\r\n\r\n\r\n // const eventBulkId = randomToken(10);\r\n // const newDocData: RxDocumentData<RxDocType> = (change as any).fullDocument;\r\n // const documentId = newDocData[this.primaryPath] as any;\r\n\r\n // const eventBulk: EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint> = {\r\n // checkpoint: {\r\n // id: newDocData[this.primaryPath] as any,\r\n // lwt: newDocData._meta.lwt\r\n // },\r\n // context: 'mongodb-write',\r\n // id: eventBulkId,\r\n // events: [{\r\n // documentData: newDocData,\r\n // documentId,\r\n // operation: 'INSERT',\r\n // previousDocumentData: undefined,\r\n // }],\r\n // };\r\n\r\n // this.changes$.next(eventBulk);\r\n // });\r\n\r\n\r\n return mongoCollection;\r\n });\r\n\r\n\r\n }\r\n\r\n /**\r\n * Bulk writes on the mongodb storage.\r\n * Notice that MongoDB does not support cross-document transactions\r\n * so we have to do a update-if-previous-is-correct like operations.\r\n * (Similar to what RxDB does with the revision system)\r\n */\r\n bulkWrite(\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ): Promise<RxStorageBulkWriteResponse<RxDocType>> {\r\n\r\n this.writeQueue = this.writeQueue.then(async () => {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n if (this.closed) {\r\n return Promise.reject(new Error('already closed'));\r\n }\r\n const primaryPath = this.primaryPath;\r\n const ret: RxStorageBulkWriteResponse<RxDocType> = {\r\n error: []\r\n };\r\n\r\n\r\n const docIds = documentWrites.map(d => (d.document as any)[primaryPath]);\r\n const documentStates = await this.findDocumentsById(\r\n docIds,\r\n true\r\n );\r\n const documentStatesMap = new Map();\r\n documentStates.forEach(doc => {\r\n const docId = doc[primaryPath];\r\n documentStatesMap.set(docId, doc);\r\n });\r\n const categorized = categorizeBulkWriteRows<RxDocType>(\r\n this,\r\n primaryPath as any,\r\n documentStatesMap,\r\n documentWrites,\r\n context\r\n );\r\n\r\n const changeByDocId = new Map<string, RxStorageChangeEvent<RxDocumentData<RxDocType>>>();\r\n categorized.eventBulk.events.forEach(change => {\r\n changeByDocId.set(change.documentId, change);\r\n });\r\n\r\n\r\n ret.error = categorized.errors;\r\n\r\n /**\r\n * Reset the event bulk because\r\n * conflicts can still appear after the categorization\r\n */\r\n const eventBulk = categorized.eventBulk;\r\n eventBulk.events = [];\r\n\r\n await Promise.all([\r\n /**\r\n * Inserts\r\n * @link https://sparkbyexamples.com/mongodb/mongodb-insert-if-not-exists/\r\n */\r\n Promise.all(\r\n categorized.bulkInsertDocs.map(async (writeRow) => {\r\n const docId: string = writeRow.document[primaryPath] as any;\r\n const writeResult = await mongoCollection.findOneAndUpdate(\r\n {\r\n [this.inMongoPrimaryPath]: docId\r\n },\r\n {\r\n $setOnInsert: swapRxDocToMongo(writeRow.document)\r\n },\r\n {\r\n upsert: true,\r\n includeResultMetadata: true\r\n }\r\n );\r\n if (writeResult.value) {\r\n // had insert conflict\r\n const conflictError: RxStorageWriteErrorConflict<RxDocType> = {\r\n status: 409,\r\n documentId: docId,\r\n writeRow,\r\n documentInDb: swapMongoToRxDoc(ensureNotFalsy(writeResult.value)),\r\n isError: true,\r\n context\r\n };\r\n ret.error.push(conflictError);\r\n } else {\r\n const event = changeByDocId.get(docId);\r\n if (event) {\r\n eventBulk.events.push(event);\r\n }\r\n }\r\n })\r\n ),\r\n /**\r\n * Updates\r\n */\r\n Promise.all(\r\n categorized.bulkUpdateDocs.map(async (writeRow) => {\r\n const docId = writeRow.document[primaryPath] as string;\r\n const writeResult = await mongoCollection.findOneAndReplace(\r\n {\r\n [this.inMongoPrimaryPath]: docId,\r\n _rev: ensureNotFalsy(writeRow.previous)._rev\r\n },\r\n swapRxDocToMongo(writeRow.document),\r\n {\r\n includeResultMetadata: true,\r\n upsert: false,\r\n returnDocument: 'before'\r\n }\r\n );\r\n if (!writeResult.ok) {\r\n const currentDocState = await this.findDocumentsById([docId], true);\r\n const currentDoc = currentDocState[0];\r\n // had insert conflict\r\n const conflictError: RxStorageWriteErrorConflict<RxDocType> = {\r\n status: 409,\r\n documentId: docId,\r\n writeRow,\r\n documentInDb: ensureNotFalsy(currentDoc),\r\n isError: true,\r\n context\r\n };\r\n ret.error.push(conflictError);\r\n } else {\r\n const event = getFromMapOrThrow(changeByDocId, docId);\r\n eventBulk.events.push(event);\r\n }\r\n\r\n })\r\n )\r\n ]);\r\n\r\n if (categorized.eventBulk.events.length > 0) {\r\n const lastState = ensureNotFalsy(categorized.newestRow).document;\r\n categorized.eventBulk.checkpoint = {\r\n id: lastState[primaryPath],\r\n lwt: lastState._meta.lwt\r\n };\r\n this.changes$.next(categorized.eventBulk);\r\n }\r\n\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return ret;\r\n });\r\n return this.writeQueue;\r\n\r\n }\r\n\r\n async findDocumentsById(\r\n docIds: string[],\r\n withDeleted: boolean,\r\n session?: ClientSession\r\n ): Promise<RxDocumentData<RxDocType>[]> {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const primaryPath = this.primaryPath;\r\n\r\n const plainQuery: MongoQuerySelector<any> = {\r\n [primaryPath]: {\r\n $in: docIds\r\n }\r\n };\r\n if (!withDeleted) {\r\n plainQuery._deleted = false;\r\n }\r\n const result: RxDocumentData<RxDocType>[] = [];\r\n const queryResult = await mongoCollection.find(\r\n plainQuery,\r\n {\r\n session\r\n }\r\n ).toArray();\r\n queryResult.forEach((row: any) => {\r\n result.push(\r\n swapMongoToRxDoc(\r\n row as any\r\n )\r\n );\r\n });\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return result;\r\n }\r\n\r\n async query(\r\n originalPreparedQuery: PreparedQuery<RxDocType>\r\n ): Promise<RxStorageQueryResult<RxDocType>> {\r\n const preparedQuery = prepareMongoDBQuery(this.schema, originalPreparedQuery.query);\r\n\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n await this.writeQueue;\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n\r\n let query = mongoCollection.find(preparedQuery.mongoSelector);\r\n if (preparedQuery.query.skip) {\r\n query = query.skip(preparedQuery.query.skip);\r\n }\r\n if (preparedQuery.query.limit) {\r\n query = query.limit(preparedQuery.query.limit);\r\n }\r\n if (preparedQuery.query.sort) {\r\n query = query.sort(preparedQuery.mongoSort);\r\n }\r\n const resultDocs = await query.toArray();\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return {\r\n documents: resultDocs.map((d: any) => swapMongoToRxDoc(d))\r\n };\r\n }\r\n\r\n async count(\r\n originalPreparedQuery: PreparedQuery<RxDocType>\r\n ): Promise<RxStorageCountResult> {\r\n const preparedQuery = prepareMongoDBQuery(this.schema, originalPreparedQuery.query);\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n await this.writeQueue;\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const count = await mongoCollection.countDocuments(preparedQuery.mongoSelector);\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return {\r\n count,\r\n mode: 'fast'\r\n };\r\n }\r\n\r\n async cleanup(minimumDeletedTime: number): Promise<boolean> {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const maxDeletionTime = now() - minimumDeletedTime;\r\n await mongoCollection.deleteMany({\r\n _deleted: true,\r\n '_meta.lwt': {\r\n $lt: maxDeletionTime\r\n }\r\n });\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return true;\r\n }\r\n\r\n async getAttachmentData(\r\n _documentId: string,\r\n _attachmentId: string,\r\n _digest: string\r\n ): Promise<Blob> {\r\n await this.mongoCollectionPromise;\r\n throw new Error('attachments not implemented, make a PR');\r\n }\r\n\r\n changeStream(): Observable<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>> {\r\n return this.changes$;\r\n }\r\n\r\n async remove(): Promise<void> {\r\n if (this.closed) {\r\n throw new Error('already closed');\r\n }\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n await mongoCollection.drop();\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n await this.close();\r\n }\r\n\r\n async close(): Promise<void> {\r\n // TODO without this next-tick we have random fails in the tests\r\n await requestIdlePromise(200);\r\n\r\n if (this.closed) {\r\n return this.closed;\r\n }\r\n this.closed = (async () => {\r\n await this.mongoCollectionPromise;\r\n await firstValueFrom(this.runningOperations.pipe(filter((c: number) => c === 0)));\r\n // await ensureNotFalsy(this.mongoChangeStream).close();\r\n await this.mongoClient.close();\r\n })();\r\n return this.closed;\r\n }\r\n}\r\n\r\nexport function createMongoDBStorageInstance<RxDocType>(\r\n storage: RxStorageMongoDB,\r\n params: RxStorageInstanceCreationParams<RxDocType, RxStorageMongoDBInstanceCreationOptions>,\r\n settings: RxStorageMongoDBSettings\r\n): Promise<RxStorageInstanceMongoDB<RxDocType>> {\r\n const instance = new RxStorageInstanceMongoDB(\r\n storage,\r\n params.databaseName,\r\n params.collectionName,\r\n params.schema,\r\n {},\r\n params.options,\r\n settings\r\n );\r\n return Promise.resolve(instance);\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"rx-storage-instance-mongodb.js","names":["BehaviorSubject","Subject","filter","firstValueFrom","getPrimaryFieldOfPrimaryKey","ensureNotFalsy","getFromMapOrThrow","isMaybeReadonlyArray","now","PROMISE_RESOLVE_VOID","requestIdlePromise","categorizeBulkWriteRows","MONGO_ID_SUBSTITUTE_FIELDNAME","getMongoDBIndexName","prepareMongoDBQuery","swapMongoToRxDoc","swapRxDocToMongo","getMongoDBClient","closeMongoDBClient","RxStorageInstanceMongoDB","storage","databaseName","collectionName","schema","internals","options","settings","mongoClient","changes$","runningOperations","writeQueue","mongoObjectIdCache","WeakMap","attachments","Error","primaryPath","primaryKey","inMongoPrimaryPath","mongoDatabase","db","version","indexes","slice","map","index","arIndex","push","mongoCollectionPromise","createCollection","then","mongoCollection","createIndexes","mongoIndex","forEach","field","name","key","_proto","prototype","bulkWrite","documentWrites","context","next","getValue","closed","Promise","reject","ret","error","docIds","d","document","documentStates","findDocumentsById","documentStatesMap","Map","doc","docId","set","categorized","changeByDocId","eventBulk","events","change","documentId","errors","all","bulkInsertDocs","writeRow","writeResult","findOneAndUpdate","$setOnInsert","upsert","includeResultMetadata","value","conflictError","status","documentInDb","isError","event","get","bulkUpdateDocs","findOneAndReplace","_rev","previous","returnDocument","ok","currentDocState","currentDoc","length","lastState","newestRow","checkpoint","id","lwt","_meta","withDeleted","session","plainQuery","$in","_deleted","result","queryResult","find","toArray","row","query","originalPreparedQuery","preparedQuery","mongoSelector","skip","limit","sort","mongoSort","resultDocs","documents","count","countDocuments","mode","cleanup","minimumDeletedTime","maxDeletionTime","deleteMany","$lt","getAttachmentData","_documentId","_attachmentId","_digest","changeStream","remove","drop","close","pipe","c","databaseSettings","connection","createMongoDBStorageInstance","params","instance"],"sources":["../../../../src/plugins/storage-mongodb/rx-storage-instance-mongodb.ts"],"sourcesContent":["import {\r\n BehaviorSubject,\r\n Observable,\r\n Subject,\r\n filter,\r\n firstValueFrom\r\n} from 'rxjs';\r\nimport { getPrimaryFieldOfPrimaryKey } from '../../rx-schema-helper.ts';\r\nimport type {\r\n BulkWriteRow,\r\n EventBulk,\r\n PreparedQuery,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorageBulkWriteResponse,\r\n RxStorageChangeEvent,\r\n RxStorageCountResult,\r\n RxStorageDefaultCheckpoint,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams,\r\n RxStorageQueryResult,\r\n RxStorageWriteErrorConflict,\r\n StringKeys\r\n} from '../../types/index.d.ts';\r\nimport {\r\n ensureNotFalsy,\r\n getFromMapOrThrow,\r\n isMaybeReadonlyArray,\r\n now,\r\n PROMISE_RESOLVE_VOID,\r\n requestIdlePromise\r\n} from '../../plugins/utils/index.ts';\r\nimport {\r\n MongoDBStorageInternals,\r\n MongoQuerySelector,\r\n RxStorageMongoDBInstanceCreationOptions,\r\n RxStorageMongoDBSettings\r\n} from './mongodb-types.ts';\r\nimport { RxStorageMongoDB } from './rx-storage-mongodb.ts';\r\nimport {\r\n Db as MongoDatabase,\r\n Collection as MongoCollection,\r\n MongoClient,\r\n ObjectId,\r\n ClientSession\r\n} from 'mongodb';\r\nimport { categorizeBulkWriteRows } from '../../rx-storage-helper.ts';\r\nimport {\r\n MONGO_ID_SUBSTITUTE_FIELDNAME,\r\n MONGO_OPTIONS_DRIVER_INFO,\r\n getMongoDBIndexName,\r\n prepareMongoDBQuery,\r\n swapMongoToRxDoc,\r\n swapRxDocToMongo,\r\n getMongoDBClient,\r\n closeMongoDBClient\r\n} from './mongodb-helper.ts';\r\n\r\nexport class RxStorageInstanceMongoDB<RxDocType> implements RxStorageInstance<\r\n RxDocType,\r\n MongoDBStorageInternals,\r\n RxStorageMongoDBInstanceCreationOptions,\r\n RxStorageDefaultCheckpoint\r\n> {\r\n\r\n public readonly primaryPath: StringKeys<RxDocumentData<RxDocType>>;\r\n public readonly inMongoPrimaryPath: string;\r\n public closed?: Promise<void>;\r\n private readonly changes$: Subject<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>> = new Subject();\r\n public readonly mongoDatabase: MongoDatabase;\r\n public readonly mongoCollectionPromise: Promise<MongoCollection<RxDocumentData<RxDocType> | any>>;\r\n // public mongoChangeStream?: MongoChangeStream<any, ChangeStreamDocument<any>>;\r\n\r\n\r\n /**\r\n * Closing the connection must not happen when\r\n * an operation is running, otherwise we get an error.\r\n * So we store all running operations here so that\r\n * they can be awaited.\r\n */\r\n public readonly runningOperations = new BehaviorSubject(0);\r\n public writeQueue: Promise<any> = PROMISE_RESOLVE_VOID;\r\n\r\n /**\r\n * We use this to be able to still fetch\r\n * the objectId after transforming the document from mongo-style (with _id)\r\n * to RxDB\r\n */\r\n public readonly mongoObjectIdCache = new WeakMap<RxDocumentData<RxDocType>, ObjectId>();\r\n\r\n constructor(\r\n public readonly storage: RxStorageMongoDB,\r\n public readonly databaseName: string,\r\n public readonly collectionName: string,\r\n public readonly schema: Readonly<RxJsonSchema<RxDocumentData<RxDocType>>>,\r\n public readonly internals: MongoDBStorageInternals,\r\n public readonly options: Readonly<RxStorageMongoDBInstanceCreationOptions>,\r\n public readonly settings: RxStorageMongoDBSettings,\r\n public readonly mongoClient: MongoClient\r\n ) {\r\n if (this.schema.attachments) {\r\n throw new Error('attachments not supported in mongodb storage, make a PR if you need that');\r\n }\r\n this.primaryPath = getPrimaryFieldOfPrimaryKey(this.schema.primaryKey);\r\n this.inMongoPrimaryPath = this.primaryPath === '_id' ? MONGO_ID_SUBSTITUTE_FIELDNAME : this.primaryPath;\r\n this.mongoDatabase = this.mongoClient.db(databaseName + '-v' + this.schema.version);\r\n\r\n const indexes = (this.schema.indexes ? this.schema.indexes.slice() : []).map(index => {\r\n const arIndex = isMaybeReadonlyArray(index) ? index.slice(0) : [index];\r\n return arIndex;\r\n });\r\n indexes.push([this.inMongoPrimaryPath]);\r\n\r\n this.mongoCollectionPromise = this.mongoDatabase.createCollection(collectionName)\r\n .then(async (mongoCollection: MongoCollection<any>) => {\r\n await mongoCollection.createIndexes(\r\n indexes.map(index => {\r\n const mongoIndex: any = {};\r\n index.forEach(field => mongoIndex[field] = 1);\r\n return { name: getMongoDBIndexName(index), key: mongoIndex };\r\n })\r\n );\r\n\r\n /**\r\n * TODO in a setup where multiple servers run node.js\r\n * processes that use the mongodb storage, we should propagate\r\n * events by listening to the mongodb changestream.\r\n * This maybe should be a premium feature.\r\n */\r\n // this.mongoChangeStream = mongoCollection.watch(\r\n // undefined, {\r\n // batchSize: 100\r\n // }\r\n // ).on('change', change => {\r\n\r\n\r\n // const eventBulkId = randomToken(10);\r\n // const newDocData: RxDocumentData<RxDocType> = (change as any).fullDocument;\r\n // const documentId = newDocData[this.primaryPath] as any;\r\n\r\n // const eventBulk: EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint> = {\r\n // checkpoint: {\r\n // id: newDocData[this.primaryPath] as any,\r\n // lwt: newDocData._meta.lwt\r\n // },\r\n // context: 'mongodb-write',\r\n // id: eventBulkId,\r\n // events: [{\r\n // documentData: newDocData,\r\n // documentId,\r\n // operation: 'INSERT',\r\n // previousDocumentData: undefined,\r\n // }],\r\n // };\r\n\r\n // this.changes$.next(eventBulk);\r\n // });\r\n\r\n\r\n return mongoCollection;\r\n });\r\n\r\n\r\n }\r\n\r\n /**\r\n * Bulk writes on the mongodb storage.\r\n * Notice that MongoDB does not support cross-document transactions\r\n * so we have to do a update-if-previous-is-correct like operations.\r\n * (Similar to what RxDB does with the revision system)\r\n */\r\n bulkWrite(\r\n documentWrites: BulkWriteRow<RxDocType>[],\r\n context: string\r\n ): Promise<RxStorageBulkWriteResponse<RxDocType>> {\r\n\r\n this.writeQueue = this.writeQueue.then(async () => {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n if (this.closed) {\r\n return Promise.reject(new Error('already closed'));\r\n }\r\n const primaryPath = this.primaryPath;\r\n const ret: RxStorageBulkWriteResponse<RxDocType> = {\r\n error: []\r\n };\r\n\r\n\r\n const docIds = documentWrites.map(d => (d.document as any)[primaryPath]);\r\n const documentStates = await this.findDocumentsById(\r\n docIds,\r\n true\r\n );\r\n const documentStatesMap = new Map();\r\n documentStates.forEach(doc => {\r\n const docId = doc[primaryPath];\r\n documentStatesMap.set(docId, doc);\r\n });\r\n const categorized = categorizeBulkWriteRows<RxDocType>(\r\n this,\r\n primaryPath as any,\r\n documentStatesMap,\r\n documentWrites,\r\n context\r\n );\r\n\r\n const changeByDocId = new Map<string, RxStorageChangeEvent<RxDocumentData<RxDocType>>>();\r\n categorized.eventBulk.events.forEach(change => {\r\n changeByDocId.set(change.documentId, change);\r\n });\r\n\r\n\r\n ret.error = categorized.errors;\r\n\r\n /**\r\n * Reset the event bulk because\r\n * conflicts can still appear after the categorization\r\n */\r\n const eventBulk = categorized.eventBulk;\r\n eventBulk.events = [];\r\n\r\n await Promise.all([\r\n /**\r\n * Inserts\r\n * @link https://sparkbyexamples.com/mongodb/mongodb-insert-if-not-exists/\r\n */\r\n Promise.all(\r\n categorized.bulkInsertDocs.map(async (writeRow) => {\r\n const docId: string = writeRow.document[primaryPath] as any;\r\n const writeResult = await mongoCollection.findOneAndUpdate(\r\n {\r\n [this.inMongoPrimaryPath]: docId\r\n },\r\n {\r\n $setOnInsert: swapRxDocToMongo(writeRow.document)\r\n },\r\n {\r\n upsert: true,\r\n includeResultMetadata: true\r\n }\r\n );\r\n if (writeResult.value) {\r\n // had insert conflict\r\n const conflictError: RxStorageWriteErrorConflict<RxDocType> = {\r\n status: 409,\r\n documentId: docId,\r\n writeRow,\r\n documentInDb: swapMongoToRxDoc(ensureNotFalsy(writeResult.value)),\r\n isError: true,\r\n context\r\n };\r\n ret.error.push(conflictError);\r\n } else {\r\n const event = changeByDocId.get(docId);\r\n if (event) {\r\n eventBulk.events.push(event);\r\n }\r\n }\r\n })\r\n ),\r\n /**\r\n * Updates\r\n */\r\n Promise.all(\r\n categorized.bulkUpdateDocs.map(async (writeRow) => {\r\n const docId = writeRow.document[primaryPath] as string;\r\n const writeResult = await mongoCollection.findOneAndReplace(\r\n {\r\n [this.inMongoPrimaryPath]: docId,\r\n _rev: ensureNotFalsy(writeRow.previous)._rev\r\n },\r\n swapRxDocToMongo(writeRow.document),\r\n {\r\n includeResultMetadata: true,\r\n upsert: false,\r\n returnDocument: 'before'\r\n }\r\n );\r\n if (!writeResult.ok) {\r\n const currentDocState = await this.findDocumentsById([docId], true);\r\n const currentDoc = currentDocState[0];\r\n // had insert conflict\r\n const conflictError: RxStorageWriteErrorConflict<RxDocType> = {\r\n status: 409,\r\n documentId: docId,\r\n writeRow,\r\n documentInDb: ensureNotFalsy(currentDoc),\r\n isError: true,\r\n context\r\n };\r\n ret.error.push(conflictError);\r\n } else {\r\n const event = getFromMapOrThrow(changeByDocId, docId);\r\n eventBulk.events.push(event);\r\n }\r\n\r\n })\r\n )\r\n ]);\r\n\r\n if (categorized.eventBulk.events.length > 0) {\r\n const lastState = ensureNotFalsy(categorized.newestRow).document;\r\n categorized.eventBulk.checkpoint = {\r\n id: lastState[primaryPath],\r\n lwt: lastState._meta.lwt\r\n };\r\n this.changes$.next(categorized.eventBulk);\r\n }\r\n\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return ret;\r\n });\r\n return this.writeQueue;\r\n\r\n }\r\n\r\n async findDocumentsById(\r\n docIds: string[],\r\n withDeleted: boolean,\r\n session?: ClientSession\r\n ): Promise<RxDocumentData<RxDocType>[]> {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const primaryPath = this.primaryPath;\r\n\r\n const plainQuery: MongoQuerySelector<any> = {\r\n [primaryPath]: {\r\n $in: docIds\r\n }\r\n };\r\n if (!withDeleted) {\r\n plainQuery._deleted = false;\r\n }\r\n const result: RxDocumentData<RxDocType>[] = [];\r\n const queryResult = await mongoCollection.find(\r\n plainQuery,\r\n {\r\n session\r\n }\r\n ).toArray();\r\n queryResult.forEach((row: any) => {\r\n result.push(\r\n swapMongoToRxDoc(\r\n row as any\r\n )\r\n );\r\n });\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return result;\r\n }\r\n\r\n async query(\r\n originalPreparedQuery: PreparedQuery<RxDocType>\r\n ): Promise<RxStorageQueryResult<RxDocType>> {\r\n const preparedQuery = prepareMongoDBQuery(this.schema, originalPreparedQuery.query);\r\n\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n await this.writeQueue;\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n\r\n let query = mongoCollection.find(preparedQuery.mongoSelector);\r\n if (preparedQuery.query.skip) {\r\n query = query.skip(preparedQuery.query.skip);\r\n }\r\n if (preparedQuery.query.limit) {\r\n query = query.limit(preparedQuery.query.limit);\r\n }\r\n if (preparedQuery.query.sort) {\r\n query = query.sort(preparedQuery.mongoSort);\r\n }\r\n const resultDocs = await query.toArray();\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return {\r\n documents: resultDocs.map((d: any) => swapMongoToRxDoc(d))\r\n };\r\n }\r\n\r\n async count(\r\n originalPreparedQuery: PreparedQuery<RxDocType>\r\n ): Promise<RxStorageCountResult> {\r\n const preparedQuery = prepareMongoDBQuery(this.schema, originalPreparedQuery.query);\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n await this.writeQueue;\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const count = await mongoCollection.countDocuments(preparedQuery.mongoSelector);\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return {\r\n count,\r\n mode: 'fast'\r\n };\r\n }\r\n\r\n async cleanup(minimumDeletedTime: number): Promise<boolean> {\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n const maxDeletionTime = now() - minimumDeletedTime;\r\n await mongoCollection.deleteMany({\r\n _deleted: true,\r\n '_meta.lwt': {\r\n $lt: maxDeletionTime\r\n }\r\n });\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n return true;\r\n }\r\n\r\n async getAttachmentData(\r\n _documentId: string,\r\n _attachmentId: string,\r\n _digest: string\r\n ): Promise<Blob> {\r\n await this.mongoCollectionPromise;\r\n throw new Error('attachments not implemented, make a PR');\r\n }\r\n\r\n changeStream(): Observable<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>> {\r\n return this.changes$;\r\n }\r\n\r\n async remove(): Promise<void> {\r\n if (this.closed) {\r\n throw new Error('already closed');\r\n }\r\n this.runningOperations.next(this.runningOperations.getValue() + 1);\r\n const mongoCollection = await this.mongoCollectionPromise;\r\n await mongoCollection.drop();\r\n this.runningOperations.next(this.runningOperations.getValue() - 1);\r\n await this.close();\r\n }\r\n\r\n async close(): Promise<void> {\r\n // TODO without this next-tick we have random fails in the tests\r\n await requestIdlePromise(200);\r\n\r\n if (this.closed) {\r\n return this.closed;\r\n }\r\n this.closed = (async () => {\r\n await this.mongoCollectionPromise;\r\n await firstValueFrom(this.runningOperations.pipe(filter((c: number) => c === 0)));\r\n // await ensureNotFalsy(this.mongoChangeStream).close();\r\n await closeMongoDBClient(this.storage.databaseSettings.connection);\r\n })();\r\n return this.closed;\r\n }\r\n}\r\n\r\nexport async function createMongoDBStorageInstance<RxDocType>(\r\n storage: RxStorageMongoDB,\r\n params: RxStorageInstanceCreationParams<RxDocType, RxStorageMongoDBInstanceCreationOptions>,\r\n settings: RxStorageMongoDBSettings\r\n): Promise<RxStorageInstanceMongoDB<RxDocType>> {\r\n const mongoClient = await getMongoDBClient(storage.databaseSettings.connection);\r\n const instance = new RxStorageInstanceMongoDB(\r\n storage,\r\n params.databaseName,\r\n params.collectionName,\r\n params.schema,\r\n {},\r\n params.options,\r\n settings,\r\n mongoClient\r\n );\r\n return instance;\r\n}\r\n"],"mappings":";AAAA,SACIA,eAAe,EAEfC,OAAO,EACPC,MAAM,EACNC,cAAc,QACX,MAAM;AACb,SAASC,2BAA2B,QAAQ,2BAA2B;AAiBvE,SACIC,cAAc,EACdC,iBAAiB,EACjBC,oBAAoB,EACpBC,GAAG,EACHC,oBAAoB,EACpBC,kBAAkB,QACf,8BAA8B;AAerC,SAASC,uBAAuB,QAAQ,4BAA4B;AACpE,SACIC,6BAA6B,EAE7BC,mBAAmB,EACnBC,mBAAmB,EACnBC,gBAAgB,EAChBC,gBAAgB,EAChBC,gBAAgB,EAChBC,kBAAkB,QACf,qBAAqB;AAE5B,WAAaC,wBAAwB;EAajC;;EAGA;AACJ;AACA;AACA;AACA;AACA;;EAII;AACJ;AACA;AACA;AACA;;EAGI,SAAAA,yBACoBC,OAAyB,EACzBC,YAAoB,EACpBC,cAAsB,EACtBC,MAAyD,EACzDC,SAAkC,EAClCC,OAA0D,EAC1DC,QAAkC,EAClCC,WAAwB,EAC1C;IAAA,KA/BeC,QAAQ,GAAoG,IAAI3B,OAAO,CAAC,CAAC;IAAA,KAY1H4B,iBAAiB,GAAG,IAAI7B,eAAe,CAAC,CAAC,CAAC;IAAA,KACnD8B,UAAU,GAAiBrB,oBAAoB;IAAA,KAOtCsB,kBAAkB,GAAG,IAAIC,OAAO,CAAsC,CAAC;IAAA,KAGnEZ,OAAyB,GAAzBA,OAAyB;IAAA,KACzBC,YAAoB,GAApBA,YAAoB;IAAA,KACpBC,cAAsB,GAAtBA,cAAsB;IAAA,KACtBC,MAAyD,GAAzDA,MAAyD;IAAA,KACzDC,SAAkC,GAAlCA,SAAkC;IAAA,KAClCC,OAA0D,GAA1DA,OAA0D;IAAA,KAC1DC,QAAkC,GAAlCA,QAAkC;IAAA,KAClCC,WAAwB,GAAxBA,WAAwB;IAExC,IAAI,IAAI,CAACJ,MAAM,CAACU,WAAW,EAAE;MACzB,MAAM,IAAIC,KAAK,CAAC,0EAA0E,CAAC;IAC/F;IACA,IAAI,CAACC,WAAW,GAAG/B,2BAA2B,CAAC,IAAI,CAACmB,MAAM,CAACa,UAAU,CAAC;IACtE,IAAI,CAACC,kBAAkB,GAAG,IAAI,CAACF,WAAW,KAAK,KAAK,GAAGvB,6BAA6B,GAAG,IAAI,CAACuB,WAAW;IACvG,IAAI,CAACG,aAAa,GAAG,IAAI,CAACX,WAAW,CAACY,EAAE,CAAClB,YAAY,GAAG,IAAI,GAAG,IAAI,CAACE,MAAM,CAACiB,OAAO,CAAC;IAEnF,IAAMC,OAAO,GAAG,CAAC,IAAI,CAAClB,MAAM,CAACkB,OAAO,GAAG,IAAI,CAAClB,MAAM,CAACkB,OAAO,CAACC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAEC,GAAG,CAACC,KAAK,IAAI;MAClF,IAAMC,OAAO,GAAGtC,oBAAoB,CAACqC,KAAK,CAAC,GAAGA,KAAK,CAACF,KAAK,CAAC,CAAC,CAAC,GAAG,CAACE,KAAK,CAAC;MACtE,OAAOC,OAAO;IAClB,CAAC,CAAC;IACFJ,OAAO,CAACK,IAAI,CAAC,CAAC,IAAI,CAACT,kBAAkB,CAAC,CAAC;IAEvC,IAAI,CAACU,sBAAsB,GAAG,IAAI,CAACT,aAAa,CAACU,gBAAgB,CAAC1B,cAAc,CAAC,CAC5E2B,IAAI,CAAC,MAAOC,eAAqC,IAAK;MACnD,MAAMA,eAAe,CAACC,aAAa,CAC/BV,OAAO,CAACE,GAAG,CAACC,KAAK,IAAI;QACjB,IAAMQ,UAAe,GAAG,CAAC,CAAC;QAC1BR,KAAK,CAACS,OAAO,CAACC,KAAK,IAAIF,UAAU,CAACE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,OAAO;UAAEC,IAAI,EAAE1C,mBAAmB,CAAC+B,KAAK,CAAC;UAAEY,GAAG,EAAEJ;QAAW,CAAC;MAChE,CAAC,CACL,CAAC;;MAED;AAChB;AACA;AACA;AACA;AACA;MACgB;MACA;MACA;MACA;MACA;;MAGA;MACA;MACA;;MAEA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;MAEA;MACA;;MAGA,OAAOF,eAAe;IAC1B,CAAC,CAAC;EAGV;;EAEA;AACJ;AACA;AACA;AACA;AACA;EALI,IAAAO,MAAA,GAAAtC,wBAAA,CAAAuC,SAAA;EAAAD,MAAA,CAMAE,SAAS,GAAT,SAAAA,SAASA,CACLC,cAAyC,EACzCC,OAAe,EAC+B;IAE9C,IAAI,CAAC/B,UAAU,GAAG,IAAI,CAACA,UAAU,CAACmB,IAAI,CAAC,YAAY;MAC/C,IAAI,CAACpB,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;MAElE,IAAMb,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;MACzD,IAAI,IAAI,CAACiB,MAAM,EAAE;QACb,OAAOC,OAAO,CAACC,MAAM,CAAC,IAAIhC,KAAK,CAAC,gBAAgB,CAAC,CAAC;MACtD;MACA,IAAMC,WAAW,GAAG,IAAI,CAACA,WAAW;MACpC,IAAMgC,GAA0C,GAAG;QAC/CC,KAAK,EAAE;MACX,CAAC;MAGD,IAAMC,MAAM,GAAGT,cAAc,CAACjB,GAAG,CAAC2B,CAAC,IAAKA,CAAC,CAACC,QAAQ,CAASpC,WAAW,CAAC,CAAC;MACxE,IAAMqC,cAAc,GAAG,MAAM,IAAI,CAACC,iBAAiB,CAC/CJ,MAAM,EACN,IACJ,CAAC;MACD,IAAMK,iBAAiB,GAAG,IAAIC,GAAG,CAAC,CAAC;MACnCH,cAAc,CAACnB,OAAO,CAACuB,GAAG,IAAI;QAC1B,IAAMC,KAAK,GAAGD,GAAG,CAACzC,WAAW,CAAC;QAC9BuC,iBAAiB,CAACI,GAAG,CAACD,KAAK,EAAED,GAAG,CAAC;MACrC,CAAC,CAAC;MACF,IAAMG,WAAW,GAAGpE,uBAAuB,CACvC,IAAI,EACJwB,WAAW,EACXuC,iBAAiB,EACjBd,cAAc,EACdC,OACJ,CAAC;MAED,IAAMmB,aAAa,GAAG,IAAIL,GAAG,CAA0D,CAAC;MACxFI,WAAW,CAACE,SAAS,CAACC,MAAM,CAAC7B,OAAO,CAAC8B,MAAM,IAAI;QAC3CH,aAAa,CAACF,GAAG,CAACK,MAAM,CAACC,UAAU,EAAED,MAAM,CAAC;MAChD,CAAC,CAAC;MAGFhB,GAAG,CAACC,KAAK,GAAGW,WAAW,CAACM,MAAM;;MAE9B;AACZ;AACA;AACA;MACY,IAAMJ,SAAS,GAAGF,WAAW,CAACE,SAAS;MACvCA,SAAS,CAACC,MAAM,GAAG,EAAE;MAErB,MAAMjB,OAAO,CAACqB,GAAG,CAAC;MACd;AAChB;AACA;AACA;MACgBrB,OAAO,CAACqB,GAAG,CACPP,WAAW,CAACQ,cAAc,CAAC5C,GAAG,CAAC,MAAO6C,QAAQ,IAAK;QAC/C,IAAMX,KAAa,GAAGW,QAAQ,CAACjB,QAAQ,CAACpC,WAAW,CAAQ;QAC3D,IAAMsD,WAAW,GAAG,MAAMvC,eAAe,CAACwC,gBAAgB,CACtD;UACI,CAAC,IAAI,CAACrD,kBAAkB,GAAGwC;QAC/B,CAAC,EACD;UACIc,YAAY,EAAE3E,gBAAgB,CAACwE,QAAQ,CAACjB,QAAQ;QACpD,CAAC,EACD;UACIqB,MAAM,EAAE,IAAI;UACZC,qBAAqB,EAAE;QAC3B,CACJ,CAAC;QACD,IAAIJ,WAAW,CAACK,KAAK,EAAE;UACnB;UACA,IAAMC,aAAqD,GAAG;YAC1DC,MAAM,EAAE,GAAG;YACXZ,UAAU,EAAEP,KAAK;YACjBW,QAAQ;YACRS,YAAY,EAAElF,gBAAgB,CAACV,cAAc,CAACoF,WAAW,CAACK,KAAK,CAAC,CAAC;YACjEI,OAAO,EAAE,IAAI;YACbrC;UACJ,CAAC;UACDM,GAAG,CAACC,KAAK,CAACtB,IAAI,CAACiD,aAAa,CAAC;QACjC,CAAC,MAAM;UACH,IAAMI,KAAK,GAAGnB,aAAa,CAACoB,GAAG,CAACvB,KAAK,CAAC;UACtC,IAAIsB,KAAK,EAAE;YACPlB,SAAS,CAACC,MAAM,CAACpC,IAAI,CAACqD,KAAK,CAAC;UAChC;QACJ;MACJ,CAAC,CACL,CAAC;MACD;AAChB;AACA;MACgBlC,OAAO,CAACqB,GAAG,CACPP,WAAW,CAACsB,cAAc,CAAC1D,GAAG,CAAC,MAAO6C,QAAQ,IAAK;QAC/C,IAAMX,KAAK,GAAGW,QAAQ,CAACjB,QAAQ,CAACpC,WAAW,CAAW;QACtD,IAAMsD,WAAW,GAAG,MAAMvC,eAAe,CAACoD,iBAAiB,CACvD;UACI,CAAC,IAAI,CAACjE,kBAAkB,GAAGwC,KAAK;UAChC0B,IAAI,EAAElG,cAAc,CAACmF,QAAQ,CAACgB,QAAQ,CAAC,CAACD;QAC5C,CAAC,EACDvF,gBAAgB,CAACwE,QAAQ,CAACjB,QAAQ,CAAC,EACnC;UACIsB,qBAAqB,EAAE,IAAI;UAC3BD,MAAM,EAAE,KAAK;UACba,cAAc,EAAE;QACpB,CACJ,CAAC;QACD,IAAI,CAAChB,WAAW,CAACiB,EAAE,EAAE;UACjB,IAAMC,eAAe,GAAG,MAAM,IAAI,CAAClC,iBAAiB,CAAC,CAACI,KAAK,CAAC,EAAE,IAAI,CAAC;UACnE,IAAM+B,UAAU,GAAGD,eAAe,CAAC,CAAC,CAAC;UACrC;UACA,IAAMZ,aAAqD,GAAG;YAC1DC,MAAM,EAAE,GAAG;YACXZ,UAAU,EAAEP,KAAK;YACjBW,QAAQ;YACRS,YAAY,EAAE5F,cAAc,CAACuG,UAAU,CAAC;YACxCV,OAAO,EAAE,IAAI;YACbrC;UACJ,CAAC;UACDM,GAAG,CAACC,KAAK,CAACtB,IAAI,CAACiD,aAAa,CAAC;QACjC,CAAC,MAAM;UACH,IAAMI,KAAK,GAAG7F,iBAAiB,CAAC0E,aAAa,EAAEH,KAAK,CAAC;UACrDI,SAAS,CAACC,MAAM,CAACpC,IAAI,CAACqD,KAAK,CAAC;QAChC;MAEJ,CAAC,CACL,CAAC,CACJ,CAAC;MAEF,IAAIpB,WAAW,CAACE,SAAS,CAACC,MAAM,CAAC2B,MAAM,GAAG,CAAC,EAAE;QACzC,IAAMC,SAAS,GAAGzG,cAAc,CAAC0E,WAAW,CAACgC,SAAS,CAAC,CAACxC,QAAQ;QAChEQ,WAAW,CAACE,SAAS,CAAC+B,UAAU,GAAG;UAC/BC,EAAE,EAAEH,SAAS,CAAC3E,WAAW,CAAC;UAC1B+E,GAAG,EAAEJ,SAAS,CAACK,KAAK,CAACD;QACzB,CAAC;QACD,IAAI,CAACtF,QAAQ,CAACkC,IAAI,CAACiB,WAAW,CAACE,SAAS,CAAC;MAC7C;MAEA,IAAI,CAACpD,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;MAClE,OAAOI,GAAG;IACd,CAAC,CAAC;IACF,OAAO,IAAI,CAACrC,UAAU;EAE1B,CAAC;EAAA2B,MAAA,CAEKgB,iBAAiB,GAAvB,eAAMA,iBAAiBA,CACnBJ,MAAgB,EAChB+C,WAAoB,EACpBC,OAAuB,EACa;IACpC,IAAI,CAACxF,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,IAAMb,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;IACzD,IAAMZ,WAAW,GAAG,IAAI,CAACA,WAAW;IAEpC,IAAMmF,UAAmC,GAAG;MACxC,CAACnF,WAAW,GAAG;QACXoF,GAAG,EAAElD;MACT;IACJ,CAAC;IACD,IAAI,CAAC+C,WAAW,EAAE;MACdE,UAAU,CAACE,QAAQ,GAAG,KAAK;IAC/B;IACA,IAAMC,MAAmC,GAAG,EAAE;IAC9C,IAAMC,WAAW,GAAG,MAAMxE,eAAe,CAACyE,IAAI,CAC1CL,UAAU,EACV;MACID;IACJ,CACJ,CAAC,CAACO,OAAO,CAAC,CAAC;IACXF,WAAW,CAACrE,OAAO,CAAEwE,GAAQ,IAAK;MAC9BJ,MAAM,CAAC3E,IAAI,CACP/B,gBAAgB,CACZ8G,GACJ,CACJ,CAAC;IACL,CAAC,CAAC;IACF,IAAI,CAAChG,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO0D,MAAM;EACjB,CAAC;EAAAhE,MAAA,CAEKqE,KAAK,GAAX,eAAMA,KAAKA,CACPC,qBAA+C,EACP;IACxC,IAAMC,aAAa,GAAGlH,mBAAmB,CAAC,IAAI,CAACS,MAAM,EAAEwG,qBAAqB,CAACD,KAAK,CAAC;IAEnF,IAAI,CAACjG,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,IAAI,CAACjC,UAAU;IACrB,IAAMoB,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;IAEzD,IAAI+E,KAAK,GAAG5E,eAAe,CAACyE,IAAI,CAACK,aAAa,CAACC,aAAa,CAAC;IAC7D,IAAID,aAAa,CAACF,KAAK,CAACI,IAAI,EAAE;MAC1BJ,KAAK,GAAGA,KAAK,CAACI,IAAI,CAACF,aAAa,CAACF,KAAK,CAACI,IAAI,CAAC;IAChD;IACA,IAAIF,aAAa,CAACF,KAAK,CAACK,KAAK,EAAE;MAC3BL,KAAK,GAAGA,KAAK,CAACK,KAAK,CAACH,aAAa,CAACF,KAAK,CAACK,KAAK,CAAC;IAClD;IACA,IAAIH,aAAa,CAACF,KAAK,CAACM,IAAI,EAAE;MAC1BN,KAAK,GAAGA,KAAK,CAACM,IAAI,CAACJ,aAAa,CAACK,SAAS,CAAC;IAC/C;IACA,IAAMC,UAAU,GAAG,MAAMR,KAAK,CAACF,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC/F,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO;MACHwE,SAAS,EAAED,UAAU,CAAC3F,GAAG,CAAE2B,CAAM,IAAKvD,gBAAgB,CAACuD,CAAC,CAAC;IAC7D,CAAC;EACL,CAAC;EAAAb,MAAA,CAEK+E,KAAK,GAAX,eAAMA,KAAKA,CACPT,qBAA+C,EAClB;IAC7B,IAAMC,aAAa,GAAGlH,mBAAmB,CAAC,IAAI,CAACS,MAAM,EAAEwG,qBAAqB,CAACD,KAAK,CAAC;IACnF,IAAI,CAACjG,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,IAAI,CAACjC,UAAU;IACrB,IAAMoB,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;IACzD,IAAMyF,KAAK,GAAG,MAAMtF,eAAe,CAACuF,cAAc,CAACT,aAAa,CAACC,aAAa,CAAC;IAC/E,IAAI,CAACpG,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO;MACHyE,KAAK;MACLE,IAAI,EAAE;IACV,CAAC;EACL,CAAC;EAAAjF,MAAA,CAEKkF,OAAO,GAAb,eAAMA,OAAOA,CAACC,kBAA0B,EAAoB;IACxD,IAAI,CAAC/G,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,IAAMb,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;IACzD,IAAM8F,eAAe,GAAGrI,GAAG,CAAC,CAAC,GAAGoI,kBAAkB;IAClD,MAAM1F,eAAe,CAAC4F,UAAU,CAAC;MAC7BtB,QAAQ,EAAE,IAAI;MACd,WAAW,EAAE;QACTuB,GAAG,EAAEF;MACT;IACJ,CAAC,CAAC;IACF,IAAI,CAAChH,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO,IAAI;EACf,CAAC;EAAAN,MAAA,CAEKuF,iBAAiB,GAAvB,eAAMA,iBAAiBA,CACnBC,WAAmB,EACnBC,aAAqB,EACrBC,OAAe,EACF;IACb,MAAM,IAAI,CAACpG,sBAAsB;IACjC,MAAM,IAAIb,KAAK,CAAC,wCAAwC,CAAC;EAC7D,CAAC;EAAAuB,MAAA,CAED2F,YAAY,GAAZ,SAAAA,YAAYA,CAAA,EAAuG;IAC/G,OAAO,IAAI,CAACxH,QAAQ;EACxB,CAAC;EAAA6B,MAAA,CAEK4F,MAAM,GAAZ,eAAMA,MAAMA,CAAA,EAAkB;IAC1B,IAAI,IAAI,CAACrF,MAAM,EAAE;MACb,MAAM,IAAI9B,KAAK,CAAC,gBAAgB,CAAC;IACrC;IACA,IAAI,CAACL,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,IAAMb,eAAe,GAAG,MAAM,IAAI,CAACH,sBAAsB;IACzD,MAAMG,eAAe,CAACoG,IAAI,CAAC,CAAC;IAC5B,IAAI,CAACzH,iBAAiB,CAACiC,IAAI,CAAC,IAAI,CAACjC,iBAAiB,CAACkC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,IAAI,CAACwF,KAAK,CAAC,CAAC;EACtB,CAAC;EAAA9F,MAAA,CAEK8F,KAAK,GAAX,eAAMA,KAAKA,CAAA,EAAkB;IACzB;IACA,MAAM7I,kBAAkB,CAAC,GAAG,CAAC;IAE7B,IAAI,IAAI,CAACsD,MAAM,EAAE;MACb,OAAO,IAAI,CAACA,MAAM;IACtB;IACA,IAAI,CAACA,MAAM,GAAG,CAAC,YAAY;MACvB,MAAM,IAAI,CAACjB,sBAAsB;MACjC,MAAM5C,cAAc,CAAC,IAAI,CAAC0B,iBAAiB,CAAC2H,IAAI,CAACtJ,MAAM,CAAEuJ,CAAS,IAAKA,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;MACjF;MACA,MAAMvI,kBAAkB,CAAC,IAAI,CAACE,OAAO,CAACsI,gBAAgB,CAACC,UAAU,CAAC;IACtE,CAAC,EAAE,CAAC;IACJ,OAAO,IAAI,CAAC3F,MAAM;EACtB,CAAC;EAAA,OAAA7C,wBAAA;AAAA;AAGL,OAAO,eAAeyI,4BAA4BA,CAC9CxI,OAAyB,EACzByI,MAA2F,EAC3FnI,QAAkC,EACU;EAC5C,IAAMC,WAAW,GAAG,MAAMV,gBAAgB,CAACG,OAAO,CAACsI,gBAAgB,CAACC,UAAU,CAAC;EAC/E,IAAMG,QAAQ,GAAG,IAAI3I,wBAAwB,CACzCC,OAAO,EACPyI,MAAM,CAACxI,YAAY,EACnBwI,MAAM,CAACvI,cAAc,EACrBuI,MAAM,CAACtI,MAAM,EACb,CAAC,CAAC,EACFsI,MAAM,CAACpI,OAAO,EACdC,QAAQ,EACRC,WACJ,CAAC;EACD,OAAOmI,QAAQ;AACnB","ignoreList":[]}
@@ -20,7 +20,7 @@ export function getConfig() {
20
20
  function getEnvVariables() {
21
21
  if (isDeno) {
22
22
  var ret = {};
23
- ['DEFAULT_STORAGE', 'NODE_ENV'].forEach(k => {
23
+ ['DEFAULT_STORAGE', 'NODE_ENV', 'STORAGE_PASSWORD'].forEach(k => {
24
24
  ret[k] = Deno.env.get(k);
25
25
  });
26
26
  return ret;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["ensureNotFalsy","isPromise","randomToken","enforceOptions","broadcastChannelEnforceOptions","wrappedKeyEncryptionCryptoJsStorage","isDeno","Deno","window","isBun","process","versions","bun","isNode","config","setConfig","newConfig","initDone","getConfig","initTestEnvironment","getEnvVariables","ret","forEach","k","env","get","__karma__","ENV_VARIABLES","DEFAULT_STORAGE","isFastMode","NODE_ENV","err","type","oldConsoleLog","console","log","bind","oldConsoleDir","dir","newLog","value","Error","JSON","stringify","setMaxListeners","startTime","performance","now","logTime","msg","diff","getEncryptedStorage","baseStorage","storage","getStorage","hasEncryption","isNotOneOfTheseStorages","storageNames","isName","name","includes","getPassword","Promise","resolve"],"sources":["../../../../src/plugins/test-utils/config.ts"],"sourcesContent":["/// <reference path=\"../../../node_modules/@types/mocha/index.d.ts\" />\r\nimport {\r\n ensureNotFalsy,\r\n isPromise,\r\n randomToken\r\n} from '../utils/index.ts';\r\nimport {\r\n enforceOptions as broadcastChannelEnforceOptions\r\n} from 'broadcast-channel';\r\nimport type { RxStorage, RxTestStorage } from '../../types';\r\nimport { wrappedKeyEncryptionCryptoJsStorage } from '../encryption-crypto-js/index.ts';\r\n\r\nexport type TestConfig = {\r\n storage: RxTestStorage;\r\n};\r\n\r\nexport const isDeno = typeof Deno !== 'undefined' || (typeof window !== 'undefined' && 'Deno' in window);\r\nexport const isBun = typeof process !== 'undefined' && typeof process.versions !== 'undefined' && !!process.versions.bun;\r\nexport const isNode = !isDeno && !isBun && typeof window === 'undefined';\r\n\r\nlet config: TestConfig;\r\n\r\nexport function setConfig(newConfig: TestConfig) {\r\n config = newConfig;\r\n}\r\n\r\nlet initDone = false;\r\nexport function getConfig() {\r\n if (!initDone) {\r\n initTestEnvironment();\r\n initDone = true;\r\n }\r\n return ensureNotFalsy(config, 'testConfig not set')\r\n}\r\n\r\n\r\ndeclare const Deno: any;\r\nfunction getEnvVariables() {\r\n if (isDeno) {\r\n const ret: any = {};\r\n [\r\n 'DEFAULT_STORAGE',\r\n 'NODE_ENV'\r\n ].forEach(k => {\r\n ret[k] = Deno.env.get(k);\r\n });\r\n return ret;\r\n }\r\n\r\n return isBun || isNode ? process.env : ((window as any).__karma__?.config?.env || {});\r\n}\r\nexport const ENV_VARIABLES = getEnvVariables() || {};\r\nexport const DEFAULT_STORAGE = ENV_VARIABLES.DEFAULT_STORAGE as string;\r\n\r\nexport function isFastMode(): boolean {\r\n try {\r\n return ENV_VARIABLES.NODE_ENV === 'fast';\r\n } catch (err) {\r\n return false;\r\n }\r\n}\r\n\r\nexport function initTestEnvironment() {\r\n if (ENV_VARIABLES.NODE_ENV === 'fast') {\r\n broadcastChannelEnforceOptions({\r\n type: 'simulate'\r\n });\r\n }\r\n\r\n /**\r\n * Overwrite the console for easier debugging\r\n */\r\n const oldConsoleLog = console.log.bind(console);\r\n const oldConsoleDir = console.dir.bind(console);\r\n function newLog(this: typeof console, value: any) {\r\n if (isPromise(value)) {\r\n oldConsoleDir(value);\r\n throw new Error('cannot log Promise(), you should await it first');\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n oldConsoleLog(value);\r\n return;\r\n }\r\n try {\r\n JSON.stringify(value);\r\n oldConsoleLog(JSON.stringify(value, null, 4));\r\n } catch (err) {\r\n oldConsoleDir(value);\r\n }\r\n }\r\n console.log = newLog.bind(console);\r\n console.dir = newLog.bind(console);\r\n\r\n console.log('DEFAULT_STORAGE: ' + DEFAULT_STORAGE);\r\n\r\n if (isNode) {\r\n process.setMaxListeners(100);\r\n\r\n /**\r\n * Add a global function to process, so we can debug timings\r\n */\r\n (process as any).startTime = performance.now();\r\n (process as any).logTime = (msg: string = '') => {\r\n const diff = performance.now() - (process as any).startTime;\r\n console.log('process logTime(' + msg + ') ' + diff + 'ms');\r\n };\r\n }\r\n}\r\n\r\nexport function getEncryptedStorage(baseStorage = getConfig().storage.getStorage()): RxStorage<any, any> {\r\n const ret = config.storage.hasEncryption ?\r\n baseStorage :\r\n wrappedKeyEncryptionCryptoJsStorage({\r\n storage: baseStorage\r\n });\r\n return ret;\r\n}\r\n\r\nexport function isNotOneOfTheseStorages(storageNames: string[]) {\r\n const isName = getConfig().storage.name;\r\n if (storageNames.includes(isName)) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\r\n\r\n\r\nexport function getPassword(): Promise<string> {\r\n if (getConfig().storage.hasEncryption) {\r\n return ensureNotFalsy(getConfig().storage.hasEncryption)();\r\n } else {\r\n return Promise.resolve('test-password-' + randomToken(10));\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"config.js","names":["ensureNotFalsy","isPromise","randomToken","enforceOptions","broadcastChannelEnforceOptions","wrappedKeyEncryptionCryptoJsStorage","isDeno","Deno","window","isBun","process","versions","bun","isNode","config","setConfig","newConfig","initDone","getConfig","initTestEnvironment","getEnvVariables","ret","forEach","k","env","get","__karma__","ENV_VARIABLES","DEFAULT_STORAGE","isFastMode","NODE_ENV","err","type","oldConsoleLog","console","log","bind","oldConsoleDir","dir","newLog","value","Error","JSON","stringify","setMaxListeners","startTime","performance","now","logTime","msg","diff","getEncryptedStorage","baseStorage","storage","getStorage","hasEncryption","isNotOneOfTheseStorages","storageNames","isName","name","includes","getPassword","Promise","resolve"],"sources":["../../../../src/plugins/test-utils/config.ts"],"sourcesContent":["/// <reference path=\"../../../node_modules/@types/mocha/index.d.ts\" />\r\nimport {\r\n ensureNotFalsy,\r\n isPromise,\r\n randomToken\r\n} from '../utils/index.ts';\r\nimport {\r\n enforceOptions as broadcastChannelEnforceOptions\r\n} from 'broadcast-channel';\r\nimport type { RxStorage, RxTestStorage } from '../../types';\r\nimport { wrappedKeyEncryptionCryptoJsStorage } from '../encryption-crypto-js/index.ts';\r\n\r\nexport type TestConfig = {\r\n storage: RxTestStorage;\r\n};\r\n\r\nexport const isDeno = typeof Deno !== 'undefined' || (typeof window !== 'undefined' && 'Deno' in window);\r\nexport const isBun = typeof process !== 'undefined' && typeof process.versions !== 'undefined' && !!process.versions.bun;\r\nexport const isNode = !isDeno && !isBun && typeof window === 'undefined';\r\n\r\nlet config: TestConfig;\r\n\r\nexport function setConfig(newConfig: TestConfig) {\r\n config = newConfig;\r\n}\r\n\r\nlet initDone = false;\r\nexport function getConfig() {\r\n if (!initDone) {\r\n initTestEnvironment();\r\n initDone = true;\r\n }\r\n return ensureNotFalsy(config, 'testConfig not set')\r\n}\r\n\r\n\r\ndeclare const Deno: any;\r\nfunction getEnvVariables() {\r\n if (isDeno) {\r\n const ret: any = {};\r\n [\r\n 'DEFAULT_STORAGE',\r\n 'NODE_ENV',\r\n 'STORAGE_PASSWORD'\r\n ].forEach(k => {\r\n ret[k] = Deno.env.get(k);\r\n });\r\n return ret;\r\n }\r\n\r\n return isBun || isNode ? process.env : ((window as any).__karma__?.config?.env || {});\r\n}\r\nexport const ENV_VARIABLES = getEnvVariables() || {};\r\nexport const DEFAULT_STORAGE = ENV_VARIABLES.DEFAULT_STORAGE as string;\r\n\r\nexport function isFastMode(): boolean {\r\n try {\r\n return ENV_VARIABLES.NODE_ENV === 'fast';\r\n } catch (err) {\r\n return false;\r\n }\r\n}\r\n\r\nexport function initTestEnvironment() {\r\n if (ENV_VARIABLES.NODE_ENV === 'fast') {\r\n broadcastChannelEnforceOptions({\r\n type: 'simulate'\r\n });\r\n }\r\n\r\n /**\r\n * Overwrite the console for easier debugging\r\n */\r\n const oldConsoleLog = console.log.bind(console);\r\n const oldConsoleDir = console.dir.bind(console);\r\n function newLog(this: typeof console, value: any) {\r\n if (isPromise(value)) {\r\n oldConsoleDir(value);\r\n throw new Error('cannot log Promise(), you should await it first');\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n oldConsoleLog(value);\r\n return;\r\n }\r\n try {\r\n JSON.stringify(value);\r\n oldConsoleLog(JSON.stringify(value, null, 4));\r\n } catch (err) {\r\n oldConsoleDir(value);\r\n }\r\n }\r\n console.log = newLog.bind(console);\r\n console.dir = newLog.bind(console);\r\n\r\n console.log('DEFAULT_STORAGE: ' + DEFAULT_STORAGE);\r\n\r\n if (isNode) {\r\n process.setMaxListeners(100);\r\n\r\n /**\r\n * Add a global function to process, so we can debug timings\r\n */\r\n (process as any).startTime = performance.now();\r\n (process as any).logTime = (msg: string = '') => {\r\n const diff = performance.now() - (process as any).startTime;\r\n console.log('process logTime(' + msg + ') ' + diff + 'ms');\r\n };\r\n }\r\n}\r\n\r\nexport function getEncryptedStorage(baseStorage = getConfig().storage.getStorage()): RxStorage<any, any> {\r\n const ret = config.storage.hasEncryption ?\r\n baseStorage :\r\n wrappedKeyEncryptionCryptoJsStorage({\r\n storage: baseStorage\r\n });\r\n return ret;\r\n}\r\n\r\nexport function isNotOneOfTheseStorages(storageNames: string[]) {\r\n const isName = getConfig().storage.name;\r\n if (storageNames.includes(isName)) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\r\n\r\n\r\nexport function getPassword(): Promise<string> {\r\n if (getConfig().storage.hasEncryption) {\r\n return ensureNotFalsy(getConfig().storage.hasEncryption)();\r\n } else {\r\n return Promise.resolve('test-password-' + randomToken(10));\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -21,9 +21,21 @@ export async function runPerformanceTests(storage, storageDescription, config =
21
21
  parallelQueryAmount = 4,
22
22
  insertBatches = 6,
23
23
  waitBetweenTests = 100,
24
- log = true
24
+ log = true,
25
+ password
25
26
  } = config;
27
+ var testBulkFindByIds = config.testBulkFindByIds !== false;
28
+ var testSerialFindById = config.testSerialFindById !== false;
29
+ var testFindByQuery = config.testFindByQuery !== false;
30
+ var testFindByQueryParallel = config.testFindByQueryParallel !== false;
31
+ var testCount = config.testCount !== false;
32
+ var testPropertyAccess = config.testPropertyAccess !== false;
26
33
  var totalTimes = {};
34
+
35
+ // Generate dbName outside the loop to reuse the exact same MongoDB database.
36
+ // This allows `.remove()` to drop the old collections and the next run to cleanly reuse the same
37
+ // namespace, avoiding creating thousands of collections on the DB server causing file exhaustion.
38
+ var dbName = 'test-db-performance-' + randomToken(10);
27
39
  var runsDone = 0;
28
40
  var _loop = async function () {
29
41
  if (log) {
@@ -48,8 +60,16 @@ export async function runPerformanceTests(storage, storageDescription, config =
48
60
  updateTime();
49
61
 
50
62
  // create database
51
- var dbName = 'test-db-performance-' + randomToken(10);
52
63
  var schema = averageSchema();
64
+ if (password) {
65
+ schema.encrypted = ['deep', 'list'];
66
+ schema.indexes = schema.indexes.filter(index => {
67
+ if (typeof index === 'string') {
68
+ return !index.startsWith('deep.');
69
+ }
70
+ return !index.some(field => field.startsWith('deep.'));
71
+ });
72
+ }
53
73
  var collection;
54
74
  async function createDbWithCollections() {
55
75
  if (collection) {
@@ -66,7 +86,8 @@ export async function runPerformanceTests(storage, storageDescription, config =
66
86
  * creation time.
67
87
  */
68
88
  multiInstance: false,
69
- storage
89
+ storage,
90
+ password
70
91
  });
71
92
 
72
93
  // create collections
@@ -111,19 +132,20 @@ export async function runPerformanceTests(storage, storageDescription, config =
111
132
  updateTime('insert-documents-' + docsPerBatch);
112
133
  await awaitBetweenTest(waitBetweenTests);
113
134
  }
135
+ if (testBulkFindByIds) {
136
+ // refresh db to ensure we do not run on caches
137
+ collection = await createDbWithCollections();
138
+ await awaitBetweenTest(waitBetweenTests);
114
139
 
115
- // refresh db to ensure we do not run on caches
116
- collection = await createDbWithCollections();
117
- await awaitBetweenTest(waitBetweenTests);
118
-
119
- /**
120
- * Bulk Find by id
121
- */
122
- updateTime();
123
- var idsResult = await collection.findByIds(docIds).exec();
124
- updateTime('find-by-ids-' + docsAmount);
125
- assert.strictEqual(Array.from(idsResult.keys()).length, docsAmount, 'find-by-id amount');
126
- await awaitBetweenTest(waitBetweenTests);
140
+ /**
141
+ * Bulk Find by id
142
+ */
143
+ updateTime();
144
+ var idsResult = await collection.findByIds(docIds).exec();
145
+ updateTime('find-by-ids-' + docsAmount);
146
+ assert.strictEqual(Array.from(idsResult.keys()).length, docsAmount, 'find-by-id amount');
147
+ await awaitBetweenTest(waitBetweenTests);
148
+ }
127
149
 
128
150
  /**
129
151
  * Serial inserts
@@ -140,86 +162,94 @@ export async function runPerformanceTests(storage, storageDescription, config =
140
162
  await collection.insert(data);
141
163
  }
142
164
  updateTime('serial-inserts-' + serialDocsAmount);
143
-
144
- // refresh db to ensure we do not run on caches
145
- collection = await createDbWithCollections();
146
- await awaitBetweenTest(waitBetweenTests);
147
-
148
- /**
149
- * Serial find-by-id
150
- */
151
- updateTime();
152
- for (var id of serialIds) {
153
- await collection.findByIds([id]).exec();
165
+ if (testSerialFindById || testFindByQuery) {
166
+ // refresh db to ensure we do not run on caches
167
+ collection = await createDbWithCollections();
168
+ await awaitBetweenTest(waitBetweenTests);
154
169
  }
155
- updateTime('serial-find-by-id-' + serialDocsAmount);
156
- await awaitBetweenTest(waitBetweenTests);
157
-
158
- // find by query
159
- updateTime();
160
- var query = collection.find({
161
- selector: {},
162
- sort: [{
163
- var2: 'asc'
164
- }, {
165
- var1: 'asc'
166
- }]
167
- });
168
- var queryResult = await query.exec();
169
- updateTime('find-by-query');
170
- assert.strictEqual(queryResult.length, docsAmount + serialDocsAmount, 'find-by-query');
171
-
172
- // refresh db to ensure we do not run on caches
173
- collection = await createDbWithCollections();
174
- await awaitBetweenTest(waitBetweenTests);
175
-
176
- // find by multiple queries in parallel
177
- updateTime();
178
- var parallelResult = await Promise.all(new Array(parallelQueryAmount).fill(0).map((_v, idx) => {
179
- var subQuery = collection.find({
180
- selector: {
181
- var2: idx
182
- }
170
+ if (testSerialFindById) {
171
+ /**
172
+ * Serial find-by-id
173
+ */
174
+ updateTime();
175
+ for (var id of serialIds) {
176
+ await collection.findByIds([id]).exec();
177
+ }
178
+ updateTime('serial-find-by-id-' + serialDocsAmount);
179
+ await awaitBetweenTest(waitBetweenTests);
180
+ }
181
+ var queryResult;
182
+ if (testFindByQuery) {
183
+ // find by query
184
+ updateTime();
185
+ var query = collection.find({
186
+ selector: {},
187
+ sort: [{
188
+ var2: 'asc'
189
+ }, {
190
+ var1: 'asc'
191
+ }]
183
192
  });
184
- return subQuery.exec();
185
- }));
186
- updateTime('find-by-query-parallel-' + parallelQueryAmount);
187
- var parallelSum = 0;
188
- parallelResult.forEach(r => parallelSum = parallelSum + r.length);
189
- assert.strictEqual(parallelSum, docsAmount, 'parallelSum');
190
- await awaitBetweenTest(waitBetweenTests);
191
-
192
- // run count query
193
- updateTime();
194
- var t = 0;
195
- while (t < parallelQueryAmount) {
196
- var countQuery = collection.count({
197
- selector: {
198
- var2: {
199
- $eq: t
193
+ queryResult = await query.exec();
194
+ updateTime('find-by-query');
195
+ assert.strictEqual(queryResult.length, docsAmount + serialDocsAmount, 'find-by-query');
196
+ }
197
+ if (testFindByQueryParallel || testCount) {
198
+ // refresh db to ensure we do not run on caches
199
+ collection = await createDbWithCollections();
200
+ await awaitBetweenTest(waitBetweenTests);
201
+ }
202
+ if (testFindByQueryParallel) {
203
+ // find by multiple queries in parallel
204
+ updateTime();
205
+ var parallelResult = await Promise.all(new Array(parallelQueryAmount).fill(0).map((_v, idx) => {
206
+ var subQuery = collection.find({
207
+ selector: {
208
+ var2: idx
200
209
  }
201
- }
202
- });
203
- var countQueryResult = await countQuery.exec();
204
- assert.ok(countQueryResult >= docsAmount / insertBatches - 5, 'count A ' + countQueryResult);
205
- assert.ok(countQueryResult < docsAmount * 0.8, 'count B ' + countQueryResult);
206
- t++;
210
+ });
211
+ return subQuery.exec();
212
+ }));
213
+ updateTime('find-by-query-parallel-' + parallelQueryAmount);
214
+ var parallelSum = 0;
215
+ parallelResult.forEach(r => parallelSum = parallelSum + r.length);
216
+ assert.strictEqual(parallelSum, docsAmount, 'parallelSum');
217
+ await awaitBetweenTest(waitBetweenTests);
207
218
  }
208
- updateTime('4x-count');
209
- await awaitBetweenTest(waitBetweenTests);
210
-
211
- // test property access time
212
- updateTime();
213
- var sum = 0;
214
- for (var _i = 0; _i < queryResult.length; _i++) {
215
- var doc = queryResult[_i];
219
+ if (testCount) {
220
+ // run count query
221
+ updateTime();
222
+ var t = 0;
223
+ while (t < parallelQueryAmount) {
224
+ var countQuery = collection.count({
225
+ selector: {
226
+ var2: {
227
+ $eq: t
228
+ }
229
+ }
230
+ });
231
+ var countQueryResult = await countQuery.exec();
232
+ assert.ok(countQueryResult >= docsAmount / insertBatches - 5, 'count A ' + countQueryResult);
233
+ assert.ok(countQueryResult < docsAmount * 0.8, 'count B ' + countQueryResult);
234
+ t++;
235
+ }
236
+ updateTime('4x-count');
237
+ await awaitBetweenTest(waitBetweenTests);
238
+ }
239
+ if (testPropertyAccess && testFindByQuery && queryResult) {
240
+ // test property access time
241
+ updateTime();
242
+ var sum = 0;
243
+ for (var _i = 0; _i < queryResult.length; _i++) {
244
+ var doc = queryResult[_i];
216
245
 
217
- // access the same property exactly 2 times
218
- sum += doc.deep.deeper.deepNr;
219
- sum += doc.deep.deeper.deepNr;
246
+ // access the same property exactly 2 times
247
+ sum += doc.deep.deeper.deepNr;
248
+ sum += doc.deep.deeper.deepNr;
249
+ }
250
+ updateTime('property-access');
251
+ assert.ok(sum > 10);
220
252
  }
221
- updateTime('property-access');
222
- assert.ok(sum > 10);
223
253
  await collection.database.remove();
224
254
  };
225
255
  while (runsDone < runs) {
@@ -231,7 +261,7 @@ export async function runPerformanceTests(storage, storageDescription, config =
231
261
  docsAmount
232
262
  };
233
263
  Object.entries(totalTimes).forEach(([key, times]) => {
234
- result[key] = roundToThree(averageOfTimeValues(times, 95));
264
+ result[key] = roundToTwo(averageOfTimeValues(times, 95));
235
265
  });
236
266
  if (log) {
237
267
  console.log('Performance test for ' + storageDescription);
@@ -253,8 +283,8 @@ striphighestXPercent) {
253
283
  useNumbers.forEach(nr => total = total + nr);
254
284
  return total / useNumbers.length;
255
285
  }
256
- function roundToThree(num) {
257
- return Math.round(num * 1000) / 1000;
286
+ function roundToTwo(num) {
287
+ return Math.round(num * 100) / 100;
258
288
  }
259
289
  async function awaitBetweenTest(waitMs) {
260
290
  await requestIdlePromise();
@@ -1 +1 @@
1
- {"version":3,"file":"performance.js","names":["assert","createRxDatabase","randomToken","requestIdlePromise","wait","averageSchemaData","averageSchema","runPerformanceTests","storage","storageDescription","config","runs","collectionsAmount","docsAmount","serialDocsAmount","parallelQueryAmount","insertBatches","waitBetweenTests","log","totalTimes","runsDone","_loop","console","time","performance","now","updateTime","flag","diff","push","awaitBetweenTest","dbName","schema","collection","createDbWithCollections","database","close","db","name","eventReduce","multiInstance","collectionData","collectionNames","Array","fill","forEach","_v","idx","statics","firstCollectionName","collections","addCollections","insert","docIds","docsPerBatch","i","docsData","map","data","var1","var2","id","bulkInsert","idsResult","findByIds","exec","strictEqual","from","keys","length","c","serialIds","query","find","selector","sort","queryResult","parallelResult","Promise","all","subQuery","parallelSum","r","t","countQuery","count","$eq","countQueryResult","ok","sum","doc","deep","deeper","deepNr","remove","result","description","Object","entries","key","times","roundToThree","averageOfTimeValues","JSON","stringify","striphighestXPercent","a","b","stripAmount","Math","floor","useNumbers","slice","total","nr","num","round","waitMs"],"sources":["../../../../src/plugins/test-utils/performance.ts"],"sourcesContent":["import assert from 'assert';\r\nimport {\r\n createRxDatabase,\r\n randomToken,\r\n requestIdlePromise,\r\n RxCollection,\r\n RxStorage\r\n} from '../../index.ts';\r\nimport { wait } from 'async-test-util';\r\nimport { averageSchemaData, AverageSchemaDocumentType } from './schema-objects.ts';\r\nimport { averageSchema } from './schemas.ts';\r\n\r\nexport type PerformanceTestConfig = {\r\n /**\r\n * How many times the test loop is run.\r\n * More runs give more stable averages but take longer.\r\n * @default 40\r\n */\r\n runs?: number;\r\n /**\r\n * Number of collections created per database.\r\n * @default 4\r\n */\r\n collectionsAmount?: number;\r\n /**\r\n * Number of documents inserted in bulk per run.\r\n * @default 3000\r\n */\r\n docsAmount?: number;\r\n /**\r\n * Number of documents inserted one-by-one (serial) per run.\r\n * @default 50\r\n */\r\n serialDocsAmount?: number;\r\n /**\r\n * Number of parallel queries executed per run.\r\n * @default 4\r\n */\r\n parallelQueryAmount?: number;\r\n /**\r\n * Number of batches used when doing bulk inserts.\r\n * @default 6\r\n */\r\n insertBatches?: number;\r\n /**\r\n * Milliseconds to wait between test operations.\r\n * Set to 0 to disable waiting (useful for smoke tests).\r\n * @default 100\r\n */\r\n waitBetweenTests?: number;\r\n /**\r\n * Whether to log progress and results to the console.\r\n * @default true\r\n */\r\n log?: boolean;\r\n};\r\n\r\nexport type PerformanceTestResult = {\r\n description: string;\r\n collectionsAmount: number;\r\n docsAmount: number;\r\n [timingKey: string]: number | string;\r\n};\r\n\r\n/**\r\n * Runs a performance benchmark against the given RxStorage.\r\n * Useful for comparing different RxStorage implementations.\r\n *\r\n * @param storage - The RxStorage to benchmark.\r\n * @param storageDescription - A human-readable description of the storage (used in results).\r\n * @param config - Optional configuration to override the defaults.\r\n * @returns An object with averaged timing values for each measured operation.\r\n */\r\nexport async function runPerformanceTests(\r\n storage: RxStorage<any, any>,\r\n storageDescription: string,\r\n config: PerformanceTestConfig = {}\r\n): Promise<PerformanceTestResult> {\r\n const {\r\n runs = 40,\r\n collectionsAmount = 4,\r\n docsAmount = 3000,\r\n serialDocsAmount = 50,\r\n parallelQueryAmount = 4,\r\n insertBatches = 6,\r\n waitBetweenTests = 100,\r\n log = true\r\n } = config;\r\n\r\n const totalTimes: { [k: string]: number[]; } = {};\r\n\r\n let runsDone = 0;\r\n while (runsDone < runs) {\r\n if (log) {\r\n console.log('runsDone: ' + runsDone + ' of ' + runs);\r\n }\r\n runsDone++;\r\n\r\n let time = performance.now();\r\n const updateTime = (flag?: string) => {\r\n if (!flag) {\r\n time = performance.now();\r\n return;\r\n }\r\n const diff = performance.now() - time;\r\n if (!totalTimes[flag]) {\r\n totalTimes[flag] = [diff];\r\n } else {\r\n totalTimes[flag].push(diff);\r\n }\r\n time = performance.now();\r\n };\r\n\r\n await awaitBetweenTest(waitBetweenTests);\r\n updateTime();\r\n\r\n // create database\r\n const dbName = 'test-db-performance-' + randomToken(10);\r\n const schema = averageSchema();\r\n let collection: RxCollection<AverageSchemaDocumentType>;\r\n async function createDbWithCollections() {\r\n if (collection) {\r\n await collection.database.close();\r\n }\r\n const db = await createRxDatabase({\r\n name: dbName,\r\n eventReduce: true,\r\n /**\r\n * A RxStorage implementation\r\n * might need a full leader election cycle to be usable.\r\n * So we disable multiInstance here because it would make no sense\r\n * to measure the leader election time instead of the database\r\n * creation time.\r\n */\r\n multiInstance: false,\r\n storage\r\n });\r\n\r\n // create collections\r\n const collectionData: any = {};\r\n const collectionNames: string[] = [];\r\n new Array(collectionsAmount)\r\n .fill(0)\r\n .forEach((_v, idx) => {\r\n const name = dbName + '_col_' + idx;\r\n collectionNames.push(name);\r\n collectionData[name] = {\r\n schema,\r\n statics: {}\r\n };\r\n });\r\n const firstCollectionName: string = collectionNames[0];\r\n const collections = await db.addCollections(collectionData);\r\n /**\r\n * Many storages have a lazy initialization.\r\n * So it makes no sense to measure the time of database/collection creation.\r\n * Instead we do a single insert and measure the time to the first insert.\r\n */\r\n await collections[collectionNames[1]].insert(averageSchemaData());\r\n return collections[firstCollectionName];\r\n }\r\n collection = await createDbWithCollections();\r\n updateTime('time-to-first-insert');\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // insert documents (in batches)\r\n const docIds: string[] = [];\r\n const docsPerBatch = docsAmount / insertBatches;\r\n for (let i = 0; i < insertBatches; i++) {\r\n const docsData = new Array(docsPerBatch)\r\n .fill(0)\r\n .map((_v, idx) => {\r\n const data = averageSchemaData({\r\n var1: (idx % 2) + '',\r\n var2: idx % parallelQueryAmount\r\n });\r\n docIds.push(data.id);\r\n return data;\r\n });\r\n updateTime();\r\n await collection.bulkInsert(docsData);\r\n updateTime('insert-documents-' + docsPerBatch);\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n /**\r\n * Bulk Find by id\r\n */\r\n updateTime();\r\n const idsResult = await collection.findByIds(docIds).exec();\r\n updateTime('find-by-ids-' + docsAmount);\r\n assert.strictEqual(Array.from(idsResult.keys()).length, docsAmount, 'find-by-id amount');\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n /**\r\n * Serial inserts\r\n */\r\n updateTime();\r\n let c = 0;\r\n const serialIds: string[] = [];\r\n while (c < serialDocsAmount) {\r\n c++;\r\n const data = averageSchemaData({\r\n var2: 1000\r\n });\r\n serialIds.push(data.id);\r\n await collection.insert(data);\r\n }\r\n updateTime('serial-inserts-' + serialDocsAmount);\r\n\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n /**\r\n * Serial find-by-id\r\n */\r\n updateTime();\r\n for (const id of serialIds) {\r\n await collection.findByIds([id]).exec();\r\n }\r\n updateTime('serial-find-by-id-' + serialDocsAmount);\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // find by query\r\n updateTime();\r\n const query = collection.find({\r\n selector: {},\r\n sort: [\r\n { var2: 'asc' },\r\n { var1: 'asc' }\r\n ]\r\n });\r\n const queryResult = await query.exec();\r\n updateTime('find-by-query');\r\n assert.strictEqual(queryResult.length, docsAmount + serialDocsAmount, 'find-by-query');\r\n\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // find by multiple queries in parallel\r\n updateTime();\r\n const parallelResult = await Promise.all(\r\n new Array(parallelQueryAmount).fill(0).map((_v, idx) => {\r\n const subQuery = collection.find({\r\n selector: {\r\n var2: idx\r\n }\r\n });\r\n return subQuery.exec();\r\n })\r\n );\r\n updateTime('find-by-query-parallel-' + parallelQueryAmount);\r\n let parallelSum = 0;\r\n parallelResult.forEach(r => parallelSum = parallelSum + r.length);\r\n assert.strictEqual(parallelSum, docsAmount, 'parallelSum');\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // run count query\r\n updateTime();\r\n let t = 0;\r\n while (t < parallelQueryAmount) {\r\n const countQuery = collection.count({\r\n selector: {\r\n var2: {\r\n $eq: t\r\n }\r\n }\r\n });\r\n const countQueryResult = await countQuery.exec();\r\n assert.ok(countQueryResult >= ((docsAmount / insertBatches) - 5), 'count A ' + countQueryResult);\r\n assert.ok(countQueryResult < (docsAmount * 0.8), 'count B ' + countQueryResult);\r\n t++;\r\n }\r\n updateTime('4x-count');\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // test property access time\r\n updateTime();\r\n let sum = 0;\r\n for (let i = 0; i < queryResult.length; i++) {\r\n const doc = queryResult[i];\r\n\r\n // access the same property exactly 2 times\r\n sum += doc.deep.deeper.deepNr;\r\n sum += doc.deep.deeper.deepNr;\r\n }\r\n updateTime('property-access');\r\n assert.ok(sum > 10);\r\n\r\n await collection.database.remove();\r\n }\r\n\r\n const result: PerformanceTestResult = {\r\n description: storageDescription,\r\n collectionsAmount,\r\n docsAmount\r\n };\r\n Object.entries(totalTimes).forEach(([key, times]) => {\r\n result[key] = roundToThree(averageOfTimeValues(times, 95));\r\n });\r\n\r\n if (log) {\r\n console.log('Performance test for ' + storageDescription);\r\n console.log(JSON.stringify(result, null, 4));\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function averageOfTimeValues(\r\n times: number[],\r\n /**\r\n * To better account for anomalies\r\n * during time measurements,\r\n * we strip the highest x percent.\r\n */\r\n striphighestXPercent: number\r\n): number {\r\n times = times.sort((a, b) => a - b);\r\n const stripAmount = Math.floor(times.length * (striphighestXPercent * 0.01));\r\n const useNumbers = times.slice(0, times.length - stripAmount);\r\n let total = 0;\r\n useNumbers.forEach(nr => total = total + nr);\r\n return total / useNumbers.length;\r\n}\r\n\r\nfunction roundToThree(num: number) {\r\n return Math.round(num * 1000) / 1000;\r\n}\r\n\r\nasync function awaitBetweenTest(waitMs: number) {\r\n await requestIdlePromise();\r\n if (waitMs > 0) {\r\n await wait(waitMs);\r\n }\r\n await requestIdlePromise();\r\n await requestIdlePromise();\r\n}\r\n"],"mappings":"AAAA,OAAOA,MAAM,MAAM,QAAQ;AAC3B,SACIC,gBAAgB,EAChBC,WAAW,EACXC,kBAAkB,QAGf,gBAAgB;AACvB,SAASC,IAAI,QAAQ,iBAAiB;AACtC,SAASC,iBAAiB,QAAmC,qBAAqB;AAClF,SAASC,aAAa,QAAQ,cAAc;AAsD5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeC,mBAAmBA,CACrCC,OAA4B,EAC5BC,kBAA0B,EAC1BC,MAA6B,GAAG,CAAC,CAAC,EACJ;EAC9B,IAAM;IACFC,IAAI,GAAG,EAAE;IACTC,iBAAiB,GAAG,CAAC;IACrBC,UAAU,GAAG,IAAI;IACjBC,gBAAgB,GAAG,EAAE;IACrBC,mBAAmB,GAAG,CAAC;IACvBC,aAAa,GAAG,CAAC;IACjBC,gBAAgB,GAAG,GAAG;IACtBC,GAAG,GAAG;EACV,CAAC,GAAGR,MAAM;EAEV,IAAMS,UAAsC,GAAG,CAAC,CAAC;EAEjD,IAAIC,QAAQ,GAAG,CAAC;EAAC,IAAAC,KAAA,kBAAAA,CAAA,EACO;IACpB,IAAIH,GAAG,EAAE;MACLI,OAAO,CAACJ,GAAG,CAAC,YAAY,GAAGE,QAAQ,GAAG,MAAM,GAAGT,IAAI,CAAC;IACxD;IACAS,QAAQ,EAAE;IAEV,IAAIG,IAAI,GAAGC,WAAW,CAACC,GAAG,CAAC,CAAC;IAC5B,IAAMC,UAAU,GAAIC,IAAa,IAAK;MAClC,IAAI,CAACA,IAAI,EAAE;QACPJ,IAAI,GAAGC,WAAW,CAACC,GAAG,CAAC,CAAC;QACxB;MACJ;MACA,IAAMG,IAAI,GAAGJ,WAAW,CAACC,GAAG,CAAC,CAAC,GAAGF,IAAI;MACrC,IAAI,CAACJ,UAAU,CAACQ,IAAI,CAAC,EAAE;QACnBR,UAAU,CAACQ,IAAI,CAAC,GAAG,CAACC,IAAI,CAAC;MAC7B,CAAC,MAAM;QACHT,UAAU,CAACQ,IAAI,CAAC,CAACE,IAAI,CAACD,IAAI,CAAC;MAC/B;MACAL,IAAI,GAAGC,WAAW,CAACC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,MAAMK,gBAAgB,CAACb,gBAAgB,CAAC;IACxCS,UAAU,CAAC,CAAC;;IAEZ;IACA,IAAMK,MAAM,GAAG,sBAAsB,GAAG7B,WAAW,CAAC,EAAE,CAAC;IACvD,IAAM8B,MAAM,GAAG1B,aAAa,CAAC,CAAC;IAC9B,IAAI2B,UAAmD;IACvD,eAAeC,uBAAuBA,CAAA,EAAG;MACrC,IAAID,UAAU,EAAE;QACZ,MAAMA,UAAU,CAACE,QAAQ,CAACC,KAAK,CAAC,CAAC;MACrC;MACA,IAAMC,EAAE,GAAG,MAAMpC,gBAAgB,CAAC;QAC9BqC,IAAI,EAAEP,MAAM;QACZQ,WAAW,EAAE,IAAI;QACjB;AAChB;AACA;AACA;AACA;AACA;AACA;QACgBC,aAAa,EAAE,KAAK;QACpBhC;MACJ,CAAC,CAAC;;MAEF;MACA,IAAMiC,cAAmB,GAAG,CAAC,CAAC;MAC9B,IAAMC,eAAyB,GAAG,EAAE;MACpC,IAAIC,KAAK,CAAC/B,iBAAiB,CAAC,CACvBgC,IAAI,CAAC,CAAC,CAAC,CACPC,OAAO,CAAC,CAACC,EAAE,EAAEC,GAAG,KAAK;QAClB,IAAMT,IAAI,GAAGP,MAAM,GAAG,OAAO,GAAGgB,GAAG;QACnCL,eAAe,CAACb,IAAI,CAACS,IAAI,CAAC;QAC1BG,cAAc,CAACH,IAAI,CAAC,GAAG;UACnBN,MAAM;UACNgB,OAAO,EAAE,CAAC;QACd,CAAC;MACL,CAAC,CAAC;MACN,IAAMC,mBAA2B,GAAGP,eAAe,CAAC,CAAC,CAAC;MACtD,IAAMQ,WAAW,GAAG,MAAMb,EAAE,CAACc,cAAc,CAACV,cAAc,CAAC;MAC3D;AACZ;AACA;AACA;AACA;MACY,MAAMS,WAAW,CAACR,eAAe,CAAC,CAAC,CAAC,CAAC,CAACU,MAAM,CAAC/C,iBAAiB,CAAC,CAAC,CAAC;MACjE,OAAO6C,WAAW,CAACD,mBAAmB,CAAC;IAC3C;IACAhB,UAAU,GAAG,MAAMC,uBAAuB,CAAC,CAAC;IAC5CR,UAAU,CAAC,sBAAsB,CAAC;IAClC,MAAMI,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;IACA,IAAMoC,MAAgB,GAAG,EAAE;IAC3B,IAAMC,YAAY,GAAGzC,UAAU,GAAGG,aAAa;IAC/C,KAAK,IAAIuC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGvC,aAAa,EAAEuC,CAAC,EAAE,EAAE;MACpC,IAAMC,QAAQ,GAAG,IAAIb,KAAK,CAACW,YAAY,CAAC,CACnCV,IAAI,CAAC,CAAC,CAAC,CACPa,GAAG,CAAC,CAACX,EAAE,EAAEC,GAAG,KAAK;QACd,IAAMW,IAAI,GAAGrD,iBAAiB,CAAC;UAC3BsD,IAAI,EAAGZ,GAAG,GAAG,CAAC,GAAI,EAAE;UACpBa,IAAI,EAAEb,GAAG,GAAGhC;QAChB,CAAC,CAAC;QACFsC,MAAM,CAACxB,IAAI,CAAC6B,IAAI,CAACG,EAAE,CAAC;QACpB,OAAOH,IAAI;MACf,CAAC,CAAC;MACNhC,UAAU,CAAC,CAAC;MACZ,MAAMO,UAAU,CAAC6B,UAAU,CAACN,QAAQ,CAAC;MACrC9B,UAAU,CAAC,mBAAmB,GAAG4B,YAAY,CAAC;MAC9C,MAAMxB,gBAAgB,CAACb,gBAAgB,CAAC;IAC5C;;IAEA;IACAgB,UAAU,GAAG,MAAMC,uBAAuB,CAAC,CAAC;IAC5C,MAAMJ,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;AACR;AACA;IACQS,UAAU,CAAC,CAAC;IACZ,IAAMqC,SAAS,GAAG,MAAM9B,UAAU,CAAC+B,SAAS,CAACX,MAAM,CAAC,CAACY,IAAI,CAAC,CAAC;IAC3DvC,UAAU,CAAC,cAAc,GAAGb,UAAU,CAAC;IACvCb,MAAM,CAACkE,WAAW,CAACvB,KAAK,CAACwB,IAAI,CAACJ,SAAS,CAACK,IAAI,CAAC,CAAC,CAAC,CAACC,MAAM,EAAExD,UAAU,EAAE,mBAAmB,CAAC;IACxF,MAAMiB,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;AACR;AACA;IACQS,UAAU,CAAC,CAAC;IACZ,IAAI4C,CAAC,GAAG,CAAC;IACT,IAAMC,SAAmB,GAAG,EAAE;IAC9B,OAAOD,CAAC,GAAGxD,gBAAgB,EAAE;MACzBwD,CAAC,EAAE;MACH,IAAMZ,IAAI,GAAGrD,iBAAiB,CAAC;QAC3BuD,IAAI,EAAE;MACV,CAAC,CAAC;MACFW,SAAS,CAAC1C,IAAI,CAAC6B,IAAI,CAACG,EAAE,CAAC;MACvB,MAAM5B,UAAU,CAACmB,MAAM,CAACM,IAAI,CAAC;IACjC;IACAhC,UAAU,CAAC,iBAAiB,GAAGZ,gBAAgB,CAAC;;IAEhD;IACAmB,UAAU,GAAG,MAAMC,uBAAuB,CAAC,CAAC;IAC5C,MAAMJ,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;AACR;AACA;IACQS,UAAU,CAAC,CAAC;IACZ,KAAK,IAAMmC,EAAE,IAAIU,SAAS,EAAE;MACxB,MAAMtC,UAAU,CAAC+B,SAAS,CAAC,CAACH,EAAE,CAAC,CAAC,CAACI,IAAI,CAAC,CAAC;IAC3C;IACAvC,UAAU,CAAC,oBAAoB,GAAGZ,gBAAgB,CAAC;IACnD,MAAMgB,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;IACAS,UAAU,CAAC,CAAC;IACZ,IAAM8C,KAAK,GAAGvC,UAAU,CAACwC,IAAI,CAAC;MAC1BC,QAAQ,EAAE,CAAC,CAAC;MACZC,IAAI,EAAE,CACF;QAAEf,IAAI,EAAE;MAAM,CAAC,EACf;QAAED,IAAI,EAAE;MAAM,CAAC;IAEvB,CAAC,CAAC;IACF,IAAMiB,WAAW,GAAG,MAAMJ,KAAK,CAACP,IAAI,CAAC,CAAC;IACtCvC,UAAU,CAAC,eAAe,CAAC;IAC3B1B,MAAM,CAACkE,WAAW,CAACU,WAAW,CAACP,MAAM,EAAExD,UAAU,GAAGC,gBAAgB,EAAE,eAAe,CAAC;;IAEtF;IACAmB,UAAU,GAAG,MAAMC,uBAAuB,CAAC,CAAC;IAC5C,MAAMJ,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;IACAS,UAAU,CAAC,CAAC;IACZ,IAAMmD,cAAc,GAAG,MAAMC,OAAO,CAACC,GAAG,CACpC,IAAIpC,KAAK,CAAC5B,mBAAmB,CAAC,CAAC6B,IAAI,CAAC,CAAC,CAAC,CAACa,GAAG,CAAC,CAACX,EAAE,EAAEC,GAAG,KAAK;MACpD,IAAMiC,QAAQ,GAAG/C,UAAU,CAACwC,IAAI,CAAC;QAC7BC,QAAQ,EAAE;UACNd,IAAI,EAAEb;QACV;MACJ,CAAC,CAAC;MACF,OAAOiC,QAAQ,CAACf,IAAI,CAAC,CAAC;IAC1B,CAAC,CACL,CAAC;IACDvC,UAAU,CAAC,yBAAyB,GAAGX,mBAAmB,CAAC;IAC3D,IAAIkE,WAAW,GAAG,CAAC;IACnBJ,cAAc,CAAChC,OAAO,CAACqC,CAAC,IAAID,WAAW,GAAGA,WAAW,GAAGC,CAAC,CAACb,MAAM,CAAC;IACjErE,MAAM,CAACkE,WAAW,CAACe,WAAW,EAAEpE,UAAU,EAAE,aAAa,CAAC;IAC1D,MAAMiB,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;IACAS,UAAU,CAAC,CAAC;IACZ,IAAIyD,CAAC,GAAG,CAAC;IACT,OAAOA,CAAC,GAAGpE,mBAAmB,EAAE;MAC5B,IAAMqE,UAAU,GAAGnD,UAAU,CAACoD,KAAK,CAAC;QAChCX,QAAQ,EAAE;UACNd,IAAI,EAAE;YACF0B,GAAG,EAAEH;UACT;QACJ;MACJ,CAAC,CAAC;MACF,IAAMI,gBAAgB,GAAG,MAAMH,UAAU,CAACnB,IAAI,CAAC,CAAC;MAChDjE,MAAM,CAACwF,EAAE,CAACD,gBAAgB,IAAM1E,UAAU,GAAGG,aAAa,GAAI,CAAE,EAAE,UAAU,GAAGuE,gBAAgB,CAAC;MAChGvF,MAAM,CAACwF,EAAE,CAACD,gBAAgB,GAAI1E,UAAU,GAAG,GAAI,EAAE,UAAU,GAAG0E,gBAAgB,CAAC;MAC/EJ,CAAC,EAAE;IACP;IACAzD,UAAU,CAAC,UAAU,CAAC;IACtB,MAAMI,gBAAgB,CAACb,gBAAgB,CAAC;;IAExC;IACAS,UAAU,CAAC,CAAC;IACZ,IAAI+D,GAAG,GAAG,CAAC;IACX,KAAK,IAAIlC,EAAC,GAAG,CAAC,EAAEA,EAAC,GAAGqB,WAAW,CAACP,MAAM,EAAEd,EAAC,EAAE,EAAE;MACzC,IAAMmC,GAAG,GAAGd,WAAW,CAACrB,EAAC,CAAC;;MAE1B;MACAkC,GAAG,IAAIC,GAAG,CAACC,IAAI,CAACC,MAAM,CAACC,MAAM;MAC7BJ,GAAG,IAAIC,GAAG,CAACC,IAAI,CAACC,MAAM,CAACC,MAAM;IACjC;IACAnE,UAAU,CAAC,iBAAiB,CAAC;IAC7B1B,MAAM,CAACwF,EAAE,CAACC,GAAG,GAAG,EAAE,CAAC;IAEnB,MAAMxD,UAAU,CAACE,QAAQ,CAAC2D,MAAM,CAAC,CAAC;EACtC,CAAC;EA5MD,OAAO1E,QAAQ,GAAGT,IAAI;IAAA,MAAAU,KAAA;EAAA;EA8MtB,IAAM0E,MAA6B,GAAG;IAClCC,WAAW,EAAEvF,kBAAkB;IAC/BG,iBAAiB;IACjBC;EACJ,CAAC;EACDoF,MAAM,CAACC,OAAO,CAAC/E,UAAU,CAAC,CAAC0B,OAAO,CAAC,CAAC,CAACsD,GAAG,EAAEC,KAAK,CAAC,KAAK;IACjDL,MAAM,CAACI,GAAG,CAAC,GAAGE,YAAY,CAACC,mBAAmB,CAACF,KAAK,EAAE,EAAE,CAAC,CAAC;EAC9D,CAAC,CAAC;EAEF,IAAIlF,GAAG,EAAE;IACLI,OAAO,CAACJ,GAAG,CAAC,uBAAuB,GAAGT,kBAAkB,CAAC;IACzDa,OAAO,CAACJ,GAAG,CAACqF,IAAI,CAACC,SAAS,CAACT,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;EAChD;EAEA,OAAOA,MAAM;AACjB;AAEA,OAAO,SAASO,mBAAmBA,CAC/BF,KAAe;AACf;AACJ;AACA;AACA;AACA;AACIK,oBAA4B,EACtB;EACNL,KAAK,GAAGA,KAAK,CAACzB,IAAI,CAAC,CAAC+B,CAAC,EAAEC,CAAC,KAAKD,CAAC,GAAGC,CAAC,CAAC;EACnC,IAAMC,WAAW,GAAGC,IAAI,CAACC,KAAK,CAACV,KAAK,CAAC/B,MAAM,IAAIoC,oBAAoB,GAAG,IAAI,CAAC,CAAC;EAC5E,IAAMM,UAAU,GAAGX,KAAK,CAACY,KAAK,CAAC,CAAC,EAAEZ,KAAK,CAAC/B,MAAM,GAAGuC,WAAW,CAAC;EAC7D,IAAIK,KAAK,GAAG,CAAC;EACbF,UAAU,CAAClE,OAAO,CAACqE,EAAE,IAAID,KAAK,GAAGA,KAAK,GAAGC,EAAE,CAAC;EAC5C,OAAOD,KAAK,GAAGF,UAAU,CAAC1C,MAAM;AACpC;AAEA,SAASgC,YAAYA,CAACc,GAAW,EAAE;EAC/B,OAAON,IAAI,CAACO,KAAK,CAACD,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI;AACxC;AAEA,eAAerF,gBAAgBA,CAACuF,MAAc,EAAE;EAC5C,MAAMlH,kBAAkB,CAAC,CAAC;EAC1B,IAAIkH,MAAM,GAAG,CAAC,EAAE;IACZ,MAAMjH,IAAI,CAACiH,MAAM,CAAC;EACtB;EACA,MAAMlH,kBAAkB,CAAC,CAAC;EAC1B,MAAMA,kBAAkB,CAAC,CAAC;AAC9B","ignoreList":[]}
1
+ {"version":3,"file":"performance.js","names":["assert","createRxDatabase","randomToken","requestIdlePromise","wait","averageSchemaData","averageSchema","runPerformanceTests","storage","storageDescription","config","runs","collectionsAmount","docsAmount","serialDocsAmount","parallelQueryAmount","insertBatches","waitBetweenTests","log","password","testBulkFindByIds","testSerialFindById","testFindByQuery","testFindByQueryParallel","testCount","testPropertyAccess","totalTimes","dbName","runsDone","_loop","console","time","performance","now","updateTime","flag","diff","push","awaitBetweenTest","schema","encrypted","indexes","filter","index","startsWith","some","field","collection","createDbWithCollections","database","close","db","name","eventReduce","multiInstance","collectionData","collectionNames","Array","fill","forEach","_v","idx","statics","firstCollectionName","collections","addCollections","insert","docIds","docsPerBatch","i","docsData","map","data","var1","var2","id","bulkInsert","idsResult","findByIds","exec","strictEqual","from","keys","length","c","serialIds","queryResult","query","find","selector","sort","parallelResult","Promise","all","subQuery","parallelSum","r","t","countQuery","count","$eq","countQueryResult","ok","sum","doc","deep","deeper","deepNr","remove","result","description","Object","entries","key","times","roundToTwo","averageOfTimeValues","JSON","stringify","striphighestXPercent","a","b","stripAmount","Math","floor","useNumbers","slice","total","nr","num","round","waitMs"],"sources":["../../../../src/plugins/test-utils/performance.ts"],"sourcesContent":["import assert from 'assert';\r\nimport {\r\n createRxDatabase,\r\n randomToken,\r\n requestIdlePromise,\r\n RxCollection,\r\n RxStorage\r\n} from '../../index.ts';\r\nimport { wait } from 'async-test-util';\r\nimport { averageSchemaData, AverageSchemaDocumentType } from './schema-objects.ts';\r\nimport { averageSchema } from './schemas.ts';\r\n\r\nexport type PerformanceTestConfig = {\r\n /**\r\n * How many times the test loop is run.\r\n * More runs give more stable averages but take longer.\r\n * @default 40\r\n */\r\n runs?: number;\r\n /**\r\n * Number of collections created per database.\r\n * @default 4\r\n */\r\n collectionsAmount?: number;\r\n /**\r\n * Number of documents inserted in bulk per run.\r\n * @default 3000\r\n */\r\n docsAmount?: number;\r\n /**\r\n * Number of documents inserted one-by-one (serial) per run.\r\n * @default 50\r\n */\r\n serialDocsAmount?: number;\r\n /**\r\n * Number of parallel queries executed per run.\r\n * @default 4\r\n */\r\n parallelQueryAmount?: number;\r\n /**\r\n * Number of batches used when doing bulk inserts.\r\n * @default 6\r\n */\r\n insertBatches?: number;\r\n /**\r\n * Milliseconds to wait between test operations.\r\n * Set to 0 to disable waiting (useful for smoke tests).\r\n * @default 100\r\n */\r\n waitBetweenTests?: number;\r\n /**\r\n * Whether to log progress and results to the console.\r\n * @default true\r\n */\r\n log?: boolean;\r\n /**\r\n * If set, the database will be created with encryption\r\n * and the schema will mark applicable fields as encrypted.\r\n */\r\n password?: any;\r\n /**\r\n * Whether to run the bulk find-by-ids test.\r\n * @default true\r\n */\r\n testBulkFindByIds?: boolean;\r\n /**\r\n * Whether to run the serial find-by-id test.\r\n * @default true\r\n */\r\n testSerialFindById?: boolean;\r\n /**\r\n * Whether to run the find-by-query test.\r\n * @default true\r\n */\r\n testFindByQuery?: boolean;\r\n /**\r\n * Whether to run the find-by-query-parallel test.\r\n * @default true\r\n */\r\n testFindByQueryParallel?: boolean;\r\n /**\r\n * Whether to run the count query test.\r\n * @default true\r\n */\r\n testCount?: boolean;\r\n /**\r\n * Whether to run the property access test.\r\n * Requires testFindByQuery to also be enabled.\r\n * @default true\r\n */\r\n testPropertyAccess?: boolean;\r\n};\r\n\r\nexport type PerformanceTestResult = {\r\n description: string;\r\n collectionsAmount: number;\r\n docsAmount: number;\r\n [timingKey: string]: number | string;\r\n};\r\n\r\n/**\r\n * Runs a performance benchmark against the given RxStorage.\r\n * Useful for comparing different RxStorage implementations.\r\n *\r\n * @param storage - The RxStorage to benchmark.\r\n * @param storageDescription - A human-readable description of the storage (used in results).\r\n * @param config - Optional configuration to override the defaults.\r\n * @returns An object with averaged timing values for each measured operation.\r\n */\r\nexport async function runPerformanceTests(\r\n storage: RxStorage<any, any>,\r\n storageDescription: string,\r\n config: PerformanceTestConfig = {}\r\n): Promise<PerformanceTestResult> {\r\n const {\r\n runs = 40,\r\n collectionsAmount = 4,\r\n docsAmount = 3000,\r\n serialDocsAmount = 50,\r\n parallelQueryAmount = 4,\r\n insertBatches = 6,\r\n waitBetweenTests = 100,\r\n log = true,\r\n password\r\n } = config;\r\n const testBulkFindByIds = config.testBulkFindByIds !== false;\r\n const testSerialFindById = config.testSerialFindById !== false;\r\n const testFindByQuery = config.testFindByQuery !== false;\r\n const testFindByQueryParallel = config.testFindByQueryParallel !== false;\r\n const testCount = config.testCount !== false;\r\n const testPropertyAccess = config.testPropertyAccess !== false;\r\n\r\n const totalTimes: { [k: string]: number[]; } = {};\r\n\r\n // Generate dbName outside the loop to reuse the exact same MongoDB database.\r\n // This allows `.remove()` to drop the old collections and the next run to cleanly reuse the same \r\n // namespace, avoiding creating thousands of collections on the DB server causing file exhaustion.\r\n const dbName = 'test-db-performance-' + randomToken(10);\r\n\r\n let runsDone = 0;\r\n while (runsDone < runs) {\r\n if (log) {\r\n console.log('runsDone: ' + runsDone + ' of ' + runs);\r\n }\r\n runsDone++;\r\n\r\n let time = performance.now();\r\n const updateTime = (flag?: string) => {\r\n if (!flag) {\r\n time = performance.now();\r\n return;\r\n }\r\n const diff = performance.now() - time;\r\n if (!totalTimes[flag]) {\r\n totalTimes[flag] = [diff];\r\n } else {\r\n totalTimes[flag].push(diff);\r\n }\r\n time = performance.now();\r\n };\r\n\r\n await awaitBetweenTest(waitBetweenTests);\r\n updateTime();\r\n\r\n // create database\r\n const schema = averageSchema();\r\n if (password) {\r\n schema.encrypted = ['deep', 'list'];\r\n schema.indexes = schema.indexes!.filter(index => {\r\n if (typeof index === 'string') {\r\n return !index.startsWith('deep.');\r\n }\r\n return !index.some(field => field.startsWith('deep.'));\r\n });\r\n }\r\n let collection: RxCollection<AverageSchemaDocumentType>;\r\n async function createDbWithCollections() {\r\n if (collection) {\r\n await collection.database.close();\r\n }\r\n const db = await createRxDatabase({\r\n name: dbName,\r\n eventReduce: true,\r\n /**\r\n * A RxStorage implementation\r\n * might need a full leader election cycle to be usable.\r\n * So we disable multiInstance here because it would make no sense\r\n * to measure the leader election time instead of the database\r\n * creation time.\r\n */\r\n multiInstance: false,\r\n storage,\r\n password\r\n });\r\n\r\n // create collections\r\n const collectionData: any = {};\r\n const collectionNames: string[] = [];\r\n new Array(collectionsAmount)\r\n .fill(0)\r\n .forEach((_v, idx) => {\r\n const name = dbName + '_col_' + idx;\r\n collectionNames.push(name);\r\n collectionData[name] = {\r\n schema,\r\n statics: {}\r\n };\r\n });\r\n const firstCollectionName: string = collectionNames[0];\r\n const collections = await db.addCollections(collectionData);\r\n /**\r\n * Many storages have a lazy initialization.\r\n * So it makes no sense to measure the time of database/collection creation.\r\n * Instead we do a single insert and measure the time to the first insert.\r\n */\r\n await collections[collectionNames[1]].insert(averageSchemaData());\r\n return collections[firstCollectionName];\r\n }\r\n collection = await createDbWithCollections();\r\n updateTime('time-to-first-insert');\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n // insert documents (in batches)\r\n const docIds: string[] = [];\r\n const docsPerBatch = docsAmount / insertBatches;\r\n for (let i = 0; i < insertBatches; i++) {\r\n const docsData = new Array(docsPerBatch)\r\n .fill(0)\r\n .map((_v, idx) => {\r\n const data = averageSchemaData({\r\n var1: (idx % 2) + '',\r\n var2: idx % parallelQueryAmount\r\n });\r\n docIds.push(data.id);\r\n return data;\r\n });\r\n updateTime();\r\n await collection.bulkInsert(docsData);\r\n updateTime('insert-documents-' + docsPerBatch);\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n if (testBulkFindByIds) {\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n\r\n /**\r\n * Bulk Find by id\r\n */\r\n updateTime();\r\n const idsResult = await collection.findByIds(docIds).exec();\r\n updateTime('find-by-ids-' + docsAmount);\r\n assert.strictEqual(Array.from(idsResult.keys()).length, docsAmount, 'find-by-id amount');\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n /**\r\n * Serial inserts\r\n */\r\n updateTime();\r\n let c = 0;\r\n const serialIds: string[] = [];\r\n while (c < serialDocsAmount) {\r\n c++;\r\n const data = averageSchemaData({\r\n var2: 1000\r\n });\r\n serialIds.push(data.id);\r\n await collection.insert(data);\r\n }\r\n updateTime('serial-inserts-' + serialDocsAmount);\r\n\r\n if (testSerialFindById || testFindByQuery) {\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n if (testSerialFindById) {\r\n /**\r\n * Serial find-by-id\r\n */\r\n updateTime();\r\n for (const id of serialIds) {\r\n await collection.findByIds([id]).exec();\r\n }\r\n updateTime('serial-find-by-id-' + serialDocsAmount);\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n let queryResult: any[] | undefined;\r\n if (testFindByQuery) {\r\n // find by query\r\n updateTime();\r\n const query = collection.find({\r\n selector: {},\r\n sort: [\r\n { var2: 'asc' },\r\n { var1: 'asc' }\r\n ]\r\n });\r\n queryResult = await query.exec();\r\n updateTime('find-by-query');\r\n assert.strictEqual(queryResult.length, docsAmount + serialDocsAmount, 'find-by-query');\r\n }\r\n\r\n if (testFindByQueryParallel || testCount) {\r\n // refresh db to ensure we do not run on caches\r\n collection = await createDbWithCollections();\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n if (testFindByQueryParallel) {\r\n // find by multiple queries in parallel\r\n updateTime();\r\n const parallelResult = await Promise.all(\r\n new Array(parallelQueryAmount).fill(0).map((_v, idx) => {\r\n const subQuery = collection.find({\r\n selector: {\r\n var2: idx\r\n }\r\n });\r\n return subQuery.exec();\r\n })\r\n );\r\n updateTime('find-by-query-parallel-' + parallelQueryAmount);\r\n let parallelSum = 0;\r\n parallelResult.forEach(r => parallelSum = parallelSum + r.length);\r\n assert.strictEqual(parallelSum, docsAmount, 'parallelSum');\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n if (testCount) {\r\n // run count query\r\n updateTime();\r\n let t = 0;\r\n while (t < parallelQueryAmount) {\r\n const countQuery = collection.count({\r\n selector: {\r\n var2: {\r\n $eq: t\r\n }\r\n }\r\n });\r\n const countQueryResult = await countQuery.exec();\r\n assert.ok(countQueryResult >= ((docsAmount / insertBatches) - 5), 'count A ' + countQueryResult);\r\n assert.ok(countQueryResult < (docsAmount * 0.8), 'count B ' + countQueryResult);\r\n t++;\r\n }\r\n updateTime('4x-count');\r\n await awaitBetweenTest(waitBetweenTests);\r\n }\r\n\r\n if (testPropertyAccess && testFindByQuery && queryResult) {\r\n // test property access time\r\n updateTime();\r\n let sum = 0;\r\n for (let i = 0; i < queryResult.length; i++) {\r\n const doc = queryResult[i];\r\n\r\n // access the same property exactly 2 times\r\n sum += doc.deep.deeper.deepNr;\r\n sum += doc.deep.deeper.deepNr;\r\n }\r\n updateTime('property-access');\r\n assert.ok(sum > 10);\r\n }\r\n\r\n await collection.database.remove();\r\n }\r\n\r\n const result: PerformanceTestResult = {\r\n description: storageDescription,\r\n collectionsAmount,\r\n docsAmount\r\n };\r\n Object.entries(totalTimes).forEach(([key, times]) => {\r\n result[key] = roundToTwo(averageOfTimeValues(times, 95));\r\n });\r\n\r\n if (log) {\r\n console.log('Performance test for ' + storageDescription);\r\n console.log(JSON.stringify(result, null, 4));\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function averageOfTimeValues(\r\n times: number[],\r\n /**\r\n * To better account for anomalies\r\n * during time measurements,\r\n * we strip the highest x percent.\r\n */\r\n striphighestXPercent: number\r\n): number {\r\n times = times.sort((a, b) => a - b);\r\n const stripAmount = Math.floor(times.length * (striphighestXPercent * 0.01));\r\n const useNumbers = times.slice(0, times.length - stripAmount);\r\n let total = 0;\r\n useNumbers.forEach(nr => total = total + nr);\r\n return total / useNumbers.length;\r\n}\r\n\r\nfunction roundToTwo(num: number) {\r\n return Math.round(num * 100) / 100;\r\n}\r\n\r\nasync function awaitBetweenTest(waitMs: number) {\r\n await requestIdlePromise();\r\n if (waitMs > 0) {\r\n await wait(waitMs);\r\n }\r\n await requestIdlePromise();\r\n await requestIdlePromise();\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -138,7 +138,7 @@ export function heroArrayData() {
138
138
  }
139
139
  export function simpleHeroArray(partial = {}) {
140
140
  var defaultObj = {
141
- name: randomStringWithSpecialChars(6, 8),
141
+ name: randomStringWithSpecialChars(8, 10),
142
142
  skills: new Array(3).fill(0).map(() => randomStringWithSpecialChars(3, 6))
143
143
  };
144
144
  return Object.assign(defaultObj, partial);