@powersync/service-core 0.0.0-dev-20240718134716 → 0.0.0-dev-20240918082156

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 (352) hide show
  1. package/CHANGELOG.md +89 -6
  2. package/dist/api/RouteAPI.d.ts +68 -0
  3. package/dist/api/RouteAPI.js +2 -0
  4. package/dist/api/RouteAPI.js.map +1 -0
  5. package/dist/api/api-index.d.ts +1 -0
  6. package/dist/api/api-index.js +1 -0
  7. package/dist/api/api-index.js.map +1 -1
  8. package/dist/api/diagnostics.d.ts +4 -4
  9. package/dist/api/diagnostics.js +11 -65
  10. package/dist/api/diagnostics.js.map +1 -1
  11. package/dist/api/schema.d.ts +3 -5
  12. package/dist/api/schema.js +9 -79
  13. package/dist/api/schema.js.map +1 -1
  14. package/dist/auth/KeyStore.d.ts +7 -4
  15. package/dist/auth/KeyStore.js +1 -1
  16. package/dist/auth/KeyStore.js.map +1 -1
  17. package/dist/auth/auth-index.d.ts +0 -1
  18. package/dist/auth/auth-index.js +0 -1
  19. package/dist/auth/auth-index.js.map +1 -1
  20. package/dist/entry/cli-entry.js +4 -2
  21. package/dist/entry/cli-entry.js.map +1 -1
  22. package/dist/entry/commands/compact-action.d.ts +2 -0
  23. package/dist/entry/commands/compact-action.js +52 -0
  24. package/dist/entry/commands/compact-action.js.map +1 -0
  25. package/dist/entry/commands/migrate-action.js +4 -5
  26. package/dist/entry/commands/migrate-action.js.map +1 -1
  27. package/dist/entry/commands/teardown-action.js +2 -2
  28. package/dist/entry/commands/teardown-action.js.map +1 -1
  29. package/dist/entry/entry-index.d.ts +1 -0
  30. package/dist/entry/entry-index.js +1 -0
  31. package/dist/entry/entry-index.js.map +1 -1
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.js +4 -2
  34. package/dist/index.js.map +1 -1
  35. package/dist/metrics/Metrics.d.ts +6 -5
  36. package/dist/metrics/Metrics.js +53 -10
  37. package/dist/metrics/Metrics.js.map +1 -1
  38. package/dist/migrations/db/migrations/1684951997326-init.d.ts +2 -2
  39. package/dist/migrations/db/migrations/1684951997326-init.js +4 -2
  40. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
  41. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +2 -2
  42. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +4 -2
  43. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
  44. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +2 -2
  45. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +4 -2
  46. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
  47. package/dist/migrations/migrations.d.ts +8 -0
  48. package/dist/migrations/migrations.js +19 -7
  49. package/dist/migrations/migrations.js.map +1 -1
  50. package/dist/modules/AbstractModule.d.ts +26 -0
  51. package/dist/modules/AbstractModule.js +11 -0
  52. package/dist/modules/AbstractModule.js.map +1 -0
  53. package/dist/modules/ModuleManager.d.ts +11 -0
  54. package/dist/modules/ModuleManager.js +32 -0
  55. package/dist/modules/ModuleManager.js.map +1 -0
  56. package/dist/modules/modules-index.d.ts +2 -0
  57. package/dist/modules/modules-index.js +3 -0
  58. package/dist/modules/modules-index.js.map +1 -0
  59. package/dist/replication/AbstractReplicationJob.d.ts +38 -0
  60. package/dist/replication/AbstractReplicationJob.js +51 -0
  61. package/dist/replication/AbstractReplicationJob.js.map +1 -0
  62. package/dist/replication/AbstractReplicator.d.ts +53 -0
  63. package/dist/replication/AbstractReplicator.js +187 -0
  64. package/dist/replication/AbstractReplicator.js.map +1 -0
  65. package/dist/replication/ErrorRateLimiter.d.ts +0 -9
  66. package/dist/replication/ErrorRateLimiter.js +1 -42
  67. package/dist/replication/ErrorRateLimiter.js.map +1 -1
  68. package/dist/replication/ReplicationEngine.d.ts +18 -0
  69. package/dist/replication/ReplicationEngine.js +41 -0
  70. package/dist/replication/ReplicationEngine.js.map +1 -0
  71. package/dist/replication/ReplicationModule.d.ts +39 -0
  72. package/dist/replication/ReplicationModule.js +65 -0
  73. package/dist/replication/ReplicationModule.js.map +1 -0
  74. package/dist/replication/replication-index.d.ts +4 -6
  75. package/dist/replication/replication-index.js +4 -6
  76. package/dist/replication/replication-index.js.map +1 -1
  77. package/dist/routes/RouterEngine.d.ts +42 -0
  78. package/dist/routes/RouterEngine.js +80 -0
  79. package/dist/routes/RouterEngine.js.map +1 -0
  80. package/dist/routes/auth.d.ts +2 -2
  81. package/dist/routes/auth.js +11 -11
  82. package/dist/routes/auth.js.map +1 -1
  83. package/dist/routes/configure-fastify.d.ts +737 -0
  84. package/dist/routes/configure-fastify.js +57 -0
  85. package/dist/routes/configure-fastify.js.map +1 -0
  86. package/dist/routes/configure-rsocket.d.ts +13 -0
  87. package/dist/routes/configure-rsocket.js +47 -0
  88. package/dist/routes/configure-rsocket.js.map +1 -0
  89. package/dist/routes/endpoints/admin.d.ts +0 -34
  90. package/dist/routes/endpoints/admin.js +48 -89
  91. package/dist/routes/endpoints/admin.js.map +1 -1
  92. package/dist/routes/endpoints/checkpointing.d.ts +56 -16
  93. package/dist/routes/endpoints/checkpointing.js +33 -12
  94. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  95. package/dist/routes/endpoints/route-endpoints-index.d.ts +0 -1
  96. package/dist/routes/endpoints/route-endpoints-index.js +0 -1
  97. package/dist/routes/endpoints/route-endpoints-index.js.map +1 -1
  98. package/dist/routes/endpoints/socket-route.js +46 -39
  99. package/dist/routes/endpoints/socket-route.js.map +1 -1
  100. package/dist/routes/endpoints/sync-rules.d.ts +1 -1
  101. package/dist/routes/endpoints/sync-rules.js +32 -23
  102. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  103. package/dist/routes/endpoints/sync-stream.d.ts +10 -0
  104. package/dist/routes/endpoints/sync-stream.js +17 -13
  105. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  106. package/dist/routes/route-register.d.ts +1 -1
  107. package/dist/routes/route-register.js +1 -1
  108. package/dist/routes/route-register.js.map +1 -1
  109. package/dist/routes/router-socket.d.ts +5 -4
  110. package/dist/routes/router-socket.js +2 -1
  111. package/dist/routes/router-socket.js.map +1 -1
  112. package/dist/routes/router.d.ts +7 -2
  113. package/dist/routes/router.js.map +1 -1
  114. package/dist/routes/routes-index.d.ts +3 -0
  115. package/dist/routes/routes-index.js +3 -0
  116. package/dist/routes/routes-index.js.map +1 -1
  117. package/dist/runner/teardown.js +47 -76
  118. package/dist/runner/teardown.js.map +1 -1
  119. package/dist/storage/BucketStorage.d.ts +61 -20
  120. package/dist/storage/BucketStorage.js +0 -10
  121. package/dist/storage/BucketStorage.js.map +1 -1
  122. package/dist/storage/MongoBucketStorage.d.ts +4 -4
  123. package/dist/storage/MongoBucketStorage.js +19 -24
  124. package/dist/storage/MongoBucketStorage.js.map +1 -1
  125. package/dist/storage/SourceEntity.d.ts +20 -0
  126. package/dist/storage/SourceEntity.js +2 -0
  127. package/dist/storage/SourceEntity.js.map +1 -0
  128. package/dist/storage/SourceTable.d.ts +4 -5
  129. package/dist/storage/SourceTable.js +3 -4
  130. package/dist/storage/SourceTable.js.map +1 -1
  131. package/dist/storage/StorageEngine.d.ts +24 -0
  132. package/dist/storage/StorageEngine.js +43 -0
  133. package/dist/storage/StorageEngine.js.map +1 -0
  134. package/dist/storage/StorageProvider.d.ts +21 -0
  135. package/dist/storage/StorageProvider.js +2 -0
  136. package/dist/storage/StorageProvider.js.map +1 -0
  137. package/dist/storage/mongo/MongoBucketBatch.d.ts +1 -1
  138. package/dist/storage/mongo/MongoBucketBatch.js +6 -7
  139. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
  140. package/dist/storage/mongo/MongoCompactor.d.ts +40 -0
  141. package/dist/storage/mongo/MongoCompactor.js +293 -0
  142. package/dist/storage/mongo/MongoCompactor.js.map +1 -0
  143. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +2 -2
  144. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +2 -2
  145. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
  146. package/dist/storage/mongo/MongoStorageProvider.d.ts +5 -0
  147. package/dist/storage/mongo/MongoStorageProvider.js +26 -0
  148. package/dist/storage/mongo/MongoStorageProvider.js.map +1 -0
  149. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +9 -7
  150. package/dist/storage/mongo/MongoSyncBucketStorage.js +43 -28
  151. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
  152. package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
  153. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
  154. package/dist/storage/mongo/OperationBatch.d.ts +7 -3
  155. package/dist/storage/mongo/OperationBatch.js +16 -7
  156. package/dist/storage/mongo/OperationBatch.js.map +1 -1
  157. package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
  158. package/dist/storage/mongo/PersistedBatch.js +2 -2
  159. package/dist/storage/mongo/PersistedBatch.js.map +1 -1
  160. package/dist/storage/mongo/models.d.ts +17 -7
  161. package/dist/storage/mongo/models.js.map +1 -1
  162. package/dist/storage/mongo/util.d.ts +14 -0
  163. package/dist/storage/mongo/util.js +70 -0
  164. package/dist/storage/mongo/util.js.map +1 -1
  165. package/dist/storage/storage-index.d.ts +5 -2
  166. package/dist/storage/storage-index.js +5 -2
  167. package/dist/storage/storage-index.js.map +1 -1
  168. package/dist/sync/RequestTracker.js +2 -3
  169. package/dist/sync/RequestTracker.js.map +1 -1
  170. package/dist/sync/sync-index.d.ts +1 -0
  171. package/dist/sync/sync-index.js +1 -0
  172. package/dist/sync/sync-index.js.map +1 -1
  173. package/dist/sync/sync.d.ts +2 -1
  174. package/dist/sync/sync.js +56 -17
  175. package/dist/sync/sync.js.map +1 -1
  176. package/dist/system/ServiceContext.d.ts +37 -0
  177. package/dist/system/ServiceContext.js +48 -0
  178. package/dist/system/ServiceContext.js.map +1 -0
  179. package/dist/system/system-index.d.ts +1 -1
  180. package/dist/system/system-index.js +1 -1
  181. package/dist/system/system-index.js.map +1 -1
  182. package/dist/util/config/collectors/config-collector.d.ts +12 -0
  183. package/dist/util/config/collectors/config-collector.js +43 -0
  184. package/dist/util/config/collectors/config-collector.js.map +1 -1
  185. package/dist/util/config/compound-config-collector.d.ts +10 -29
  186. package/dist/util/config/compound-config-collector.js +28 -84
  187. package/dist/util/config/compound-config-collector.js.map +1 -1
  188. package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
  189. package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
  190. package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
  191. package/dist/util/config/types.d.ts +6 -4
  192. package/dist/util/config/types.js.map +1 -1
  193. package/dist/util/config.d.ts +3 -4
  194. package/dist/util/config.js +5 -20
  195. package/dist/util/config.js.map +1 -1
  196. package/dist/util/protocol-types.d.ts +4 -0
  197. package/dist/util/protocol-types.js +5 -1
  198. package/dist/util/protocol-types.js.map +1 -1
  199. package/dist/util/util-index.d.ts +3 -6
  200. package/dist/util/util-index.js +3 -6
  201. package/dist/util/util-index.js.map +1 -1
  202. package/dist/util/utils.d.ts +10 -6
  203. package/dist/util/utils.js +45 -25
  204. package/dist/util/utils.js.map +1 -1
  205. package/package.json +7 -7
  206. package/src/api/RouteAPI.ts +78 -0
  207. package/src/api/api-index.ts +1 -0
  208. package/src/api/diagnostics.ts +16 -71
  209. package/src/api/schema.ts +13 -89
  210. package/src/auth/KeyStore.ts +9 -6
  211. package/src/auth/auth-index.ts +0 -1
  212. package/src/entry/cli-entry.ts +4 -2
  213. package/src/entry/commands/compact-action.ts +57 -0
  214. package/src/entry/commands/migrate-action.ts +5 -8
  215. package/src/entry/commands/teardown-action.ts +2 -2
  216. package/src/entry/entry-index.ts +1 -0
  217. package/src/index.ts +5 -2
  218. package/src/metrics/Metrics.ts +70 -15
  219. package/src/migrations/db/migrations/1684951997326-init.ts +9 -4
  220. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -4
  221. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +6 -4
  222. package/src/migrations/migrations.ts +24 -8
  223. package/src/modules/AbstractModule.ts +37 -0
  224. package/src/modules/ModuleManager.ts +34 -0
  225. package/src/modules/modules-index.ts +2 -0
  226. package/src/replication/AbstractReplicationJob.ts +79 -0
  227. package/src/replication/AbstractReplicator.ts +227 -0
  228. package/src/replication/ErrorRateLimiter.ts +0 -44
  229. package/src/replication/ReplicationEngine.ts +43 -0
  230. package/src/replication/ReplicationModule.ts +101 -0
  231. package/src/replication/replication-index.ts +4 -6
  232. package/src/routes/RouterEngine.ts +120 -0
  233. package/src/routes/auth.ts +21 -12
  234. package/src/routes/configure-fastify.ts +101 -0
  235. package/src/routes/configure-rsocket.ts +60 -0
  236. package/src/routes/endpoints/admin.ts +74 -100
  237. package/src/routes/endpoints/checkpointing.ts +46 -12
  238. package/src/routes/endpoints/route-endpoints-index.ts +0 -1
  239. package/src/routes/endpoints/socket-route.ts +50 -42
  240. package/src/routes/endpoints/sync-rules.ts +41 -25
  241. package/src/routes/endpoints/sync-stream.ts +17 -13
  242. package/src/routes/route-register.ts +2 -2
  243. package/src/routes/router-socket.ts +6 -5
  244. package/src/routes/router.ts +7 -2
  245. package/src/routes/routes-index.ts +3 -0
  246. package/src/runner/teardown.ts +50 -88
  247. package/src/storage/BucketStorage.ts +74 -26
  248. package/src/storage/MongoBucketStorage.ts +23 -26
  249. package/src/storage/SourceEntity.ts +22 -0
  250. package/src/storage/SourceTable.ts +4 -6
  251. package/src/storage/StorageEngine.ts +55 -0
  252. package/src/storage/StorageProvider.ts +27 -0
  253. package/src/storage/mongo/MongoBucketBatch.ts +8 -8
  254. package/src/storage/mongo/MongoCompactor.ts +372 -0
  255. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +3 -3
  256. package/src/storage/mongo/MongoStorageProvider.ts +31 -0
  257. package/src/storage/mongo/MongoSyncBucketStorage.ts +64 -34
  258. package/src/storage/mongo/MongoSyncRulesLock.ts +1 -1
  259. package/src/storage/mongo/OperationBatch.ts +18 -11
  260. package/src/storage/mongo/PersistedBatch.ts +6 -5
  261. package/src/storage/mongo/models.ts +17 -7
  262. package/src/storage/mongo/util.ts +71 -1
  263. package/src/storage/storage-index.ts +5 -2
  264. package/src/sync/RequestTracker.ts +3 -3
  265. package/src/sync/sync-index.ts +1 -0
  266. package/src/sync/sync.ts +66 -17
  267. package/src/system/ServiceContext.ts +68 -0
  268. package/src/system/system-index.ts +1 -1
  269. package/src/util/config/collectors/config-collector.ts +48 -0
  270. package/src/util/config/compound-config-collector.ts +45 -110
  271. package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
  272. package/src/util/config/types.ts +6 -5
  273. package/src/util/config.ts +6 -23
  274. package/src/util/protocol-types.ts +6 -1
  275. package/src/util/util-index.ts +3 -6
  276. package/src/util/utils.ts +55 -39
  277. package/test/src/__snapshots__/sync.test.ts.snap +90 -5
  278. package/test/src/auth.test.ts +7 -7
  279. package/test/src/broadcast_iterable.test.ts +1 -1
  280. package/test/src/bucket_validation.test.ts +142 -0
  281. package/test/src/bucket_validation.ts +116 -0
  282. package/test/src/checksum_cache.test.ts +3 -3
  283. package/test/src/compacting.test.ts +216 -0
  284. package/test/src/data_storage.test.ts +275 -204
  285. package/test/src/env.ts +1 -3
  286. package/test/src/merge_iterable.test.ts +1 -6
  287. package/test/src/setup.ts +1 -1
  288. package/test/src/stream_utils.ts +42 -0
  289. package/test/src/sync.test.ts +209 -48
  290. package/test/src/util.ts +110 -55
  291. package/test/tsconfig.json +1 -1
  292. package/tsconfig.tsbuildinfo +1 -1
  293. package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
  294. package/dist/auth/SupabaseKeyCollector.js +0 -61
  295. package/dist/auth/SupabaseKeyCollector.js.map +0 -1
  296. package/dist/replication/PgRelation.d.ts +0 -16
  297. package/dist/replication/PgRelation.js +0 -26
  298. package/dist/replication/PgRelation.js.map +0 -1
  299. package/dist/replication/WalConnection.d.ts +0 -34
  300. package/dist/replication/WalConnection.js +0 -190
  301. package/dist/replication/WalConnection.js.map +0 -1
  302. package/dist/replication/WalStream.d.ts +0 -57
  303. package/dist/replication/WalStream.js +0 -517
  304. package/dist/replication/WalStream.js.map +0 -1
  305. package/dist/replication/WalStreamManager.d.ts +0 -30
  306. package/dist/replication/WalStreamManager.js +0 -198
  307. package/dist/replication/WalStreamManager.js.map +0 -1
  308. package/dist/replication/WalStreamRunner.d.ts +0 -38
  309. package/dist/replication/WalStreamRunner.js +0 -155
  310. package/dist/replication/WalStreamRunner.js.map +0 -1
  311. package/dist/replication/util.d.ts +0 -9
  312. package/dist/replication/util.js +0 -62
  313. package/dist/replication/util.js.map +0 -1
  314. package/dist/routes/endpoints/dev.d.ts +0 -312
  315. package/dist/routes/endpoints/dev.js +0 -172
  316. package/dist/routes/endpoints/dev.js.map +0 -1
  317. package/dist/system/CorePowerSyncSystem.d.ts +0 -23
  318. package/dist/system/CorePowerSyncSystem.js +0 -52
  319. package/dist/system/CorePowerSyncSystem.js.map +0 -1
  320. package/dist/util/PgManager.d.ts +0 -24
  321. package/dist/util/PgManager.js +0 -55
  322. package/dist/util/PgManager.js.map +0 -1
  323. package/dist/util/migration_lib.d.ts +0 -11
  324. package/dist/util/migration_lib.js +0 -64
  325. package/dist/util/migration_lib.js.map +0 -1
  326. package/dist/util/pgwire_utils.d.ts +0 -24
  327. package/dist/util/pgwire_utils.js +0 -117
  328. package/dist/util/pgwire_utils.js.map +0 -1
  329. package/dist/util/populate_test_data.d.ts +0 -8
  330. package/dist/util/populate_test_data.js +0 -65
  331. package/dist/util/populate_test_data.js.map +0 -1
  332. package/src/auth/SupabaseKeyCollector.ts +0 -67
  333. package/src/replication/PgRelation.ts +0 -42
  334. package/src/replication/WalConnection.ts +0 -227
  335. package/src/replication/WalStream.ts +0 -628
  336. package/src/replication/WalStreamManager.ts +0 -213
  337. package/src/replication/WalStreamRunner.ts +0 -180
  338. package/src/replication/util.ts +0 -76
  339. package/src/routes/endpoints/dev.ts +0 -199
  340. package/src/system/CorePowerSyncSystem.ts +0 -64
  341. package/src/util/PgManager.ts +0 -64
  342. package/src/util/migration_lib.ts +0 -79
  343. package/src/util/pgwire_utils.ts +0 -139
  344. package/src/util/populate_test_data.ts +0 -78
  345. package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
  346. package/test/src/large_batch.test.ts +0 -194
  347. package/test/src/pg_test.test.ts +0 -450
  348. package/test/src/schema_changes.test.ts +0 -545
  349. package/test/src/slow_tests.test.ts +0 -296
  350. package/test/src/validation.test.ts +0 -63
  351. package/test/src/wal_stream.test.ts +0 -314
  352. package/test/src/wal_stream_utils.ts +0 -147
@@ -0,0 +1,293 @@
1
+ import { logger } from '@powersync/lib-services-framework';
2
+ import { MaxKey, MinKey } from 'mongodb';
3
+ import { addChecksums } from '../../util/utils.js';
4
+ import { cacheKey } from './OperationBatch.js';
5
+ const DEFAULT_CLEAR_BATCH_LIMIT = 5000;
6
+ const DEFAULT_MOVE_BATCH_LIMIT = 2000;
7
+ const DEFAULT_MOVE_BATCH_QUERY_LIMIT = 10000;
8
+ /** This default is primarily for tests. */
9
+ const DEFAULT_MEMORY_LIMIT_MB = 64;
10
+ export class MongoCompactor {
11
+ constructor(db, group_id, options) {
12
+ this.db = db;
13
+ this.group_id = group_id;
14
+ this.updates = [];
15
+ this.idLimitBytes = (options?.memoryLimitMB ?? DEFAULT_MEMORY_LIMIT_MB) * 1024 * 1024;
16
+ this.moveBatchLimit = options?.moveBatchLimit ?? DEFAULT_MOVE_BATCH_LIMIT;
17
+ this.moveBatchQueryLimit = options?.moveBatchQueryLimit ?? DEFAULT_MOVE_BATCH_QUERY_LIMIT;
18
+ this.clearBatchLimit = options?.clearBatchLimit ?? DEFAULT_CLEAR_BATCH_LIMIT;
19
+ this.maxOpId = options?.maxOpId;
20
+ this.buckets = options?.compactBuckets;
21
+ }
22
+ /**
23
+ * Compact buckets by converting operations into MOVE and/or CLEAR operations.
24
+ *
25
+ * See /docs/compacting-operations.md for details.
26
+ */
27
+ async compact() {
28
+ if (this.buckets) {
29
+ for (let bucket of this.buckets) {
30
+ // We can make this more efficient later on by iterating
31
+ // through the buckets in a single query.
32
+ // That makes batching more tricky, so we leave for later.
33
+ await this.compactInternal(bucket);
34
+ }
35
+ }
36
+ else {
37
+ await this.compactInternal(undefined);
38
+ }
39
+ }
40
+ async compactInternal(bucket) {
41
+ const idLimitBytes = this.idLimitBytes;
42
+ let currentState = null;
43
+ // Constant lower bound
44
+ const lowerBound = {
45
+ g: this.group_id,
46
+ b: bucket ?? new MinKey(),
47
+ o: new MinKey()
48
+ };
49
+ // Upper bound is adjusted for each batch
50
+ let upperBound = {
51
+ g: this.group_id,
52
+ b: bucket ?? new MaxKey(),
53
+ o: new MaxKey()
54
+ };
55
+ while (true) {
56
+ // Query one batch at a time, to avoid cursor timeouts
57
+ const batch = await this.db.bucket_data
58
+ .find({
59
+ _id: {
60
+ $gte: lowerBound,
61
+ $lt: upperBound
62
+ }
63
+ }, {
64
+ projection: {
65
+ _id: 1,
66
+ op: 1,
67
+ table: 1,
68
+ row_id: 1,
69
+ source_table: 1,
70
+ source_key: 1
71
+ },
72
+ limit: this.moveBatchQueryLimit,
73
+ sort: { _id: -1 },
74
+ singleBatch: true
75
+ })
76
+ .toArray();
77
+ if (batch.length == 0) {
78
+ // We've reached the end
79
+ break;
80
+ }
81
+ // Set upperBound for the next batch
82
+ upperBound = batch[batch.length - 1]._id;
83
+ for (let doc of batch) {
84
+ if (currentState == null || doc._id.b != currentState.bucket) {
85
+ if (currentState != null && currentState.lastNotPut != null && currentState.opsSincePut >= 1) {
86
+ // Important to flush before clearBucket()
87
+ await this.flush();
88
+ logger.info(`Inserting CLEAR at ${this.group_id}:${currentState.bucket}:${currentState.lastNotPut} to remove ${currentState.opsSincePut} operations`);
89
+ const bucket = currentState.bucket;
90
+ const clearOp = currentState.lastNotPut;
91
+ // Free memory before clearing bucket
92
+ currentState = null;
93
+ await this.clearBucket(bucket, clearOp);
94
+ }
95
+ currentState = {
96
+ bucket: doc._id.b,
97
+ seen: new Map(),
98
+ trackingSize: 0,
99
+ lastNotPut: null,
100
+ opsSincePut: 0
101
+ };
102
+ }
103
+ if (this.maxOpId != null && doc._id.o > this.maxOpId) {
104
+ continue;
105
+ }
106
+ let isPersistentPut = doc.op == 'PUT';
107
+ if (doc.op == 'REMOVE' || doc.op == 'PUT') {
108
+ const key = `${doc.table}/${doc.row_id}/${cacheKey(doc.source_table, doc.source_key)}`;
109
+ const targetOp = currentState.seen.get(key);
110
+ if (targetOp) {
111
+ // Will convert to MOVE, so don't count as PUT
112
+ isPersistentPut = false;
113
+ this.updates.push({
114
+ updateOne: {
115
+ filter: {
116
+ _id: doc._id
117
+ },
118
+ update: {
119
+ $set: {
120
+ op: 'MOVE',
121
+ target_op: targetOp
122
+ },
123
+ $unset: {
124
+ source_table: 1,
125
+ source_key: 1,
126
+ table: 1,
127
+ row_id: 1,
128
+ data: 1
129
+ }
130
+ }
131
+ }
132
+ });
133
+ }
134
+ else {
135
+ if (currentState.trackingSize >= idLimitBytes) {
136
+ // Reached memory limit.
137
+ // Keep the highest seen values in this case.
138
+ }
139
+ else {
140
+ // flatstr reduces the memory usage by flattening the string
141
+ currentState.seen.set(flatstr(key), doc._id.o);
142
+ // length + 16 for the string
143
+ // 24 for the bigint
144
+ // 50 for map overhead
145
+ // 50 for additional overhead
146
+ currentState.trackingSize += key.length + 140;
147
+ }
148
+ }
149
+ }
150
+ if (isPersistentPut) {
151
+ currentState.lastNotPut = null;
152
+ currentState.opsSincePut = 0;
153
+ }
154
+ else if (doc.op != 'CLEAR') {
155
+ if (currentState.lastNotPut == null) {
156
+ currentState.lastNotPut = doc._id.o;
157
+ }
158
+ currentState.opsSincePut += 1;
159
+ }
160
+ if (this.updates.length >= this.moveBatchLimit) {
161
+ await this.flush();
162
+ }
163
+ }
164
+ }
165
+ await this.flush();
166
+ currentState?.seen.clear();
167
+ if (currentState?.lastNotPut != null && currentState?.opsSincePut > 1) {
168
+ logger.info(`Inserting CLEAR at ${this.group_id}:${currentState.bucket}:${currentState.lastNotPut} to remove ${currentState.opsSincePut} operations`);
169
+ const bucket = currentState.bucket;
170
+ const clearOp = currentState.lastNotPut;
171
+ // Free memory before clearing bucket
172
+ currentState = null;
173
+ await this.clearBucket(bucket, clearOp);
174
+ }
175
+ }
176
+ async flush() {
177
+ if (this.updates.length > 0) {
178
+ logger.info(`Compacting ${this.updates.length} ops`);
179
+ await this.db.bucket_data.bulkWrite(this.updates, {
180
+ // Order is not important.
181
+ // Since checksums are not affected, these operations can happen in any order,
182
+ // and it's fine if the operations are partially applied.
183
+ // Each individual operation is atomic.
184
+ ordered: false
185
+ });
186
+ this.updates = [];
187
+ }
188
+ }
189
+ /**
190
+ * Perform a CLEAR compact for a bucket.
191
+ *
192
+ * @param bucket bucket name
193
+ * @param op op_id of the last non-PUT operation, which will be converted to CLEAR.
194
+ */
195
+ async clearBucket(bucket, op) {
196
+ const opFilter = {
197
+ _id: {
198
+ $gte: {
199
+ g: this.group_id,
200
+ b: bucket,
201
+ o: new MinKey()
202
+ },
203
+ $lte: {
204
+ g: this.group_id,
205
+ b: bucket,
206
+ o: op
207
+ }
208
+ }
209
+ };
210
+ const session = this.db.client.startSession();
211
+ try {
212
+ let done = false;
213
+ while (!done) {
214
+ // Do the CLEAR operation in batches, with each batch a separate transaction.
215
+ // The state after each batch is fully consistent.
216
+ // We need a transaction per batch to make sure checksums stay consistent.
217
+ await session.withTransaction(async () => {
218
+ const query = this.db.bucket_data.find(opFilter, {
219
+ session,
220
+ sort: { _id: 1 },
221
+ projection: {
222
+ _id: 1,
223
+ op: 1,
224
+ checksum: 1,
225
+ target_op: 1
226
+ },
227
+ limit: this.clearBatchLimit
228
+ });
229
+ let checksum = 0;
230
+ let lastOpId = null;
231
+ let targetOp = null;
232
+ let gotAnOp = false;
233
+ for await (let op of query.stream()) {
234
+ if (op.op == 'MOVE' || op.op == 'REMOVE' || op.op == 'CLEAR') {
235
+ checksum = addChecksums(checksum, op.checksum);
236
+ lastOpId = op._id;
237
+ if (op.op != 'CLEAR') {
238
+ gotAnOp = true;
239
+ }
240
+ if (op.target_op != null) {
241
+ if (targetOp == null || op.target_op > targetOp) {
242
+ targetOp = op.target_op;
243
+ }
244
+ }
245
+ }
246
+ else {
247
+ throw new Error(`Unexpected ${op.op} operation at ${op._id.g}:${op._id.b}:${op._id.o}`);
248
+ }
249
+ }
250
+ if (!gotAnOp) {
251
+ done = true;
252
+ return;
253
+ }
254
+ logger.info(`Flushing CLEAR at ${lastOpId?.o}`);
255
+ await this.db.bucket_data.deleteMany({
256
+ _id: {
257
+ $gte: {
258
+ g: this.group_id,
259
+ b: bucket,
260
+ o: new MinKey()
261
+ },
262
+ $lte: lastOpId
263
+ }
264
+ }, { session });
265
+ await this.db.bucket_data.insertOne({
266
+ _id: lastOpId,
267
+ op: 'CLEAR',
268
+ checksum: checksum,
269
+ data: null,
270
+ target_op: targetOp
271
+ }, { session });
272
+ }, {
273
+ writeConcern: { w: 'majority' },
274
+ readConcern: { level: 'snapshot' }
275
+ });
276
+ }
277
+ }
278
+ finally {
279
+ await session.endSession();
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * Flattens string to reduce memory usage (around 320 bytes -> 120 bytes),
285
+ * at the cost of some upfront CPU usage.
286
+ *
287
+ * From: https://github.com/davidmarkclements/flatstr/issues/8
288
+ */
289
+ function flatstr(s) {
290
+ s.match(/\n/g);
291
+ return s;
292
+ }
293
+ //# sourceMappingURL=MongoCompactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoCompactor.js","sourceRoot":"","sources":["../../../src/storage/mongo/MongoCompactor.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as mongo from 'mongodb';
2
- import { PersistedSyncRulesContent } from '../BucketStorage.js';
2
+ import { ParseSyncRulesOptions, PersistedSyncRulesContent } from '../BucketStorage.js';
3
3
  import { MongoPersistedSyncRules } from './MongoPersistedSyncRules.js';
4
4
  import { MongoSyncRulesLock } from './MongoSyncRulesLock.js';
5
5
  import { PowerSyncMongo } from './db.js';
@@ -15,6 +15,6 @@ export declare class MongoPersistedSyncRulesContent implements PersistedSyncRule
15
15
  readonly last_checkpoint_ts: Date | null;
16
16
  current_lock: MongoSyncRulesLock | null;
17
17
  constructor(db: PowerSyncMongo, doc: mongo.WithId<SyncRuleDocument>);
18
- parsed(): MongoPersistedSyncRules;
18
+ parsed(options: ParseSyncRulesOptions): MongoPersistedSyncRules;
19
19
  lock(): Promise<MongoSyncRulesLock>;
20
20
  }
@@ -14,8 +14,8 @@ export class MongoPersistedSyncRulesContent {
14
14
  this.last_checkpoint_ts = doc.last_checkpoint_ts;
15
15
  this.last_keepalive_ts = doc.last_keepalive_ts;
16
16
  }
17
- parsed() {
18
- return new MongoPersistedSyncRules(this.id, SqlSyncRules.fromYaml(this.sync_rules_content), this.last_checkpoint_lsn, this.slot_name);
17
+ parsed(options) {
18
+ return new MongoPersistedSyncRules(this.id, SqlSyncRules.fromYaml(this.sync_rules_content, options), this.last_checkpoint_lsn, this.slot_name);
19
19
  }
20
20
  async lock() {
21
21
  const lock = await MongoSyncRulesLock.createLock(this.db, this);
@@ -1 +1 @@
1
- {"version":3,"file":"MongoPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/mongo/MongoPersistedSyncRulesContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAI7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAI7D,MAAM,OAAO,8BAA8B;IAYzC,YAAoB,EAAkB,EAAE,GAAmC;QAAvD,OAAE,GAAF,EAAE,CAAgB;QAF/B,iBAAY,GAA8B,IAAI,CAAC;QAGpD,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC;QAClB,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC;QACnD,uBAAuB;QACvB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC;QAC7C,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,kBAAkB,CAAC;QACjD,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACjD,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,uBAAuB,CAChC,IAAI,CAAC,EAAE,EACP,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAC9C,IAAI,CAAC,mBAAmB,EACxB,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"MongoPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/mongo/MongoPersistedSyncRulesContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAI7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAI7D,MAAM,OAAO,8BAA8B;IAYzC,YAAoB,EAAkB,EAAE,GAAmC;QAAvD,OAAE,GAAF,EAAE,CAAgB;QAF/B,iBAAY,GAA8B,IAAI,CAAC;QAGpD,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC;QAClB,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC;QACnD,uBAAuB;QACvB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC;QAC7C,IAAI,CAAC,kBAAkB,GAAG,GAAG,CAAC,kBAAkB,CAAC;QACjD,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACjD,CAAC;IAED,MAAM,CAAC,OAA8B;QACnC,OAAO,IAAI,uBAAuB,CAChC,IAAI,CAAC,EAAE,EACP,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC,EACvD,IAAI,CAAC,mBAAmB,EACxB,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import { BucketStorageProvider, ActiveStorage, GetStorageOptions } from '../StorageProvider.js';
2
+ export declare class MongoStorageProvider implements BucketStorageProvider {
3
+ get type(): string;
4
+ getStorage(options: GetStorageOptions): Promise<ActiveStorage>;
5
+ }
@@ -0,0 +1,26 @@
1
+ import * as db from '../../db/db-index.js';
2
+ import { MongoBucketStorage } from '../MongoBucketStorage.js';
3
+ import { PowerSyncMongo } from './db.js';
4
+ import { logger } from '@powersync/lib-services-framework';
5
+ export class MongoStorageProvider {
6
+ get type() {
7
+ return 'mongodb';
8
+ }
9
+ async getStorage(options) {
10
+ const { resolvedConfig } = options;
11
+ const client = db.mongo.createMongoClient(resolvedConfig.storage);
12
+ const database = new PowerSyncMongo(client, { database: resolvedConfig.storage.database });
13
+ return {
14
+ storage: new MongoBucketStorage(database, {
15
+ // TODO currently need the entire resolved config due to this
16
+ slot_name_prefix: resolvedConfig.slot_name_prefix
17
+ }),
18
+ shutDown: () => client.close(),
19
+ tearDown: () => {
20
+ logger.info(`Tearing down storage: ${database.db.namespace}...`);
21
+ return database.db.dropDatabase();
22
+ }
23
+ };
24
+ }
25
+ }
26
+ //# sourceMappingURL=MongoStorageProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoStorageProvider.js","sourceRoot":"","sources":["../../../src/storage/mongo/MongoStorageProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAE3D,MAAM,OAAO,oBAAoB;IAC/B,IAAI,IAAI;QACN,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA0B;QACzC,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;QAEnC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAElE,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE3F,OAAO;YACL,OAAO,EAAE,IAAI,kBAAkB,CAAC,QAAQ,EAAE;gBACxC,6DAA6D;gBAC7D,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;aAClD,CAAC;YACF,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE;YAC9B,QAAQ,EAAE,GAAG,EAAE;gBACb,MAAM,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC;gBACjE,OAAO,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;YACpC,CAAC;SACsB,CAAC;IAC5B,CAAC;CACF"}
@@ -1,29 +1,31 @@
1
1
  import { SqliteJsonRow, SqliteJsonValue, SqlSyncRules } from '@powersync/service-sync-rules';
2
2
  import * as util from '../../util/util-index.js';
3
- import { BucketDataBatchOptions, BucketStorageBatch, FlushedResult, ResolveTableOptions, ResolveTableResult, SyncRulesBucketStorage, SyncRuleStatus } from '../BucketStorage.js';
3
+ import { BucketDataBatchOptions, BucketStorageBatch, CompactOptions, FlushedResult, ParseSyncRulesOptions, PersistedSyncRulesContent, ResolveTableOptions, ResolveTableResult, StartBatchOptions, SyncBucketDataBatch, SyncRulesBucketStorage, SyncRuleStatus, TerminateOptions } from '../BucketStorage.js';
4
4
  import { MongoBucketStorage } from '../MongoBucketStorage.js';
5
5
  export declare class MongoSyncBucketStorage implements SyncRulesBucketStorage {
6
6
  readonly factory: MongoBucketStorage;
7
7
  readonly group_id: number;
8
- readonly sync_rules: SqlSyncRules;
8
+ private readonly sync_rules;
9
9
  readonly slot_name: string;
10
10
  private readonly db;
11
11
  private checksumCache;
12
- constructor(factory: MongoBucketStorage, group_id: number, sync_rules: SqlSyncRules, slot_name: string);
12
+ private parsedSyncRulesCache;
13
+ constructor(factory: MongoBucketStorage, group_id: number, sync_rules: PersistedSyncRulesContent, slot_name: string);
14
+ getParsedSyncRules(options: ParseSyncRulesOptions): SqlSyncRules;
13
15
  getCheckpoint(): Promise<{
14
16
  checkpoint: string;
15
- lsn: string;
16
17
  }>;
17
- startBatch(options: {}, callback: (batch: BucketStorageBatch) => Promise<void>): Promise<FlushedResult | null>;
18
+ startBatch(options: StartBatchOptions, callback: (batch: BucketStorageBatch) => Promise<void>): Promise<FlushedResult | null>;
18
19
  resolveTable(options: ResolveTableOptions): Promise<ResolveTableResult>;
19
20
  getParameterSets(checkpoint: util.OpId, lookups: SqliteJsonValue[][]): Promise<SqliteJsonRow[]>;
20
- getBucketDataBatch(checkpoint: util.OpId, dataBuckets: Map<string, string>, options?: BucketDataBatchOptions): AsyncIterable<util.SyncBucketData>;
21
+ getBucketDataBatch(checkpoint: util.OpId, dataBuckets: Map<string, string>, options?: BucketDataBatchOptions): AsyncIterable<SyncBucketDataBatch>;
21
22
  getChecksums(checkpoint: util.OpId, buckets: string[]): Promise<util.ChecksumMap>;
22
23
  private getChecksumsInternal;
23
- terminate(): Promise<void>;
24
+ terminate(options?: TerminateOptions): Promise<void>;
24
25
  getStatus(): Promise<SyncRuleStatus>;
25
26
  clear(): Promise<void>;
26
27
  setSnapshotDone(lsn: string): Promise<void>;
27
28
  autoActivate(): Promise<void>;
28
29
  reportError(e: any): Promise<void>;
30
+ compact(options?: CompactOptions): Promise<void>;
29
31
  }
@@ -1,13 +1,13 @@
1
1
  import * as bson from 'bson';
2
2
  import * as db from '../../db/db-index.js';
3
- import * as replication from '../../replication/WalStream.js';
4
3
  import * as util from '../../util/util-index.js';
5
4
  import { DEFAULT_DOCUMENT_BATCH_LIMIT, DEFAULT_DOCUMENT_CHUNK_LIMIT_BYTES } from '../BucketStorage.js';
5
+ import { ChecksumCache } from '../ChecksumCache.js';
6
6
  import { SourceTable } from '../SourceTable.js';
7
7
  import { SyncRuleState } from './models.js';
8
8
  import { MongoBucketBatch } from './MongoBucketBatch.js';
9
- import { BSON_DESERIALIZE_OPTIONS, idPrefixFilter, readSingleBatch, serializeLookup } from './util.js';
10
- import { ChecksumCache } from '../ChecksumCache.js';
9
+ import { MongoCompactor } from './MongoCompactor.js';
10
+ import { BSON_DESERIALIZE_OPTIONS, idPrefixFilter, mapOpEntry, readSingleBatch, serializeLookup } from './util.js';
11
11
  export class MongoSyncBucketStorage {
12
12
  constructor(factory, group_id, sync_rules, slot_name) {
13
13
  this.factory = factory;
@@ -21,13 +21,16 @@ export class MongoSyncBucketStorage {
21
21
  });
22
22
  this.db = factory.db;
23
23
  }
24
+ getParsedSyncRules(options) {
25
+ this.parsedSyncRulesCache ?? (this.parsedSyncRulesCache = this.sync_rules.parsed(options).sync_rules);
26
+ return this.parsedSyncRulesCache;
27
+ }
24
28
  async getCheckpoint() {
25
29
  const doc = await this.db.sync_rules.findOne({ _id: this.group_id }, {
26
- projection: { last_checkpoint: 1, last_checkpoint_lsn: 1 }
30
+ projection: { last_checkpoint: 1 }
27
31
  });
28
32
  return {
29
- checkpoint: util.timestampToOpId(doc?.last_checkpoint ?? 0n),
30
- lsn: doc?.last_checkpoint_lsn ?? replication.ZERO_LSN
33
+ checkpoint: util.timestampToOpId(doc?.last_checkpoint ?? 0n)
31
34
  };
32
35
  }
33
36
  async startBatch(options, callback) {
@@ -35,7 +38,7 @@ export class MongoSyncBucketStorage {
35
38
  _id: this.group_id
36
39
  }, { projection: { last_checkpoint_lsn: 1, no_checkpoint_before: 1 } });
37
40
  const checkpoint_lsn = doc?.last_checkpoint_lsn ?? null;
38
- const batch = new MongoBucketBatch(this.db, this.sync_rules, this.group_id, this.slot_name, checkpoint_lsn, doc?.no_checkpoint_before ?? null);
41
+ const batch = new MongoBucketBatch(this.db, this.sync_rules.parsed(options).sync_rules, this.group_id, this.slot_name, checkpoint_lsn, doc?.no_checkpoint_before ?? options.zeroLSN);
39
42
  try {
40
43
  await callback(batch);
41
44
  await batch.flush();
@@ -53,16 +56,20 @@ export class MongoSyncBucketStorage {
53
56
  }
54
57
  }
55
58
  async resolveTable(options) {
56
- const { group_id, connection_id, connection_tag, relation } = options;
57
- const { schema, name: table, relationId, replicationColumns } = relation;
58
- const columns = replicationColumns.map((column) => ({ name: column.name, type_oid: column.typeOid }));
59
+ const { group_id, connection_id, connection_tag, entity_descriptor } = options;
60
+ const { schema, name: table, objectId, replicationColumns } = entity_descriptor;
61
+ const columns = replicationColumns.map((column) => ({
62
+ name: column.name,
63
+ type: column.type,
64
+ type_oid: column.typeId
65
+ }));
59
66
  let result = null;
60
67
  await this.db.client.withSession(async (session) => {
61
68
  const col = this.db.source_tables;
62
69
  let doc = await col.findOne({
63
70
  group_id: group_id,
64
71
  connection_id: connection_id,
65
- relation_id: relationId,
72
+ relation_id: objectId,
66
73
  schema_name: schema,
67
74
  table_name: table,
68
75
  replica_id_columns2: columns
@@ -72,7 +79,7 @@ export class MongoSyncBucketStorage {
72
79
  _id: new bson.ObjectId(),
73
80
  group_id: group_id,
74
81
  connection_id: connection_id,
75
- relation_id: relationId,
82
+ relation_id: objectId,
76
83
  schema_name: schema,
77
84
  table_name: table,
78
85
  replica_id_columns: null,
@@ -81,7 +88,7 @@ export class MongoSyncBucketStorage {
81
88
  };
82
89
  await col.insertOne(doc, { session });
83
90
  }
84
- const sourceTable = new SourceTable(doc._id, connection_tag, relationId, schema, table, replicationColumns, doc.snapshot_done ?? true);
91
+ const sourceTable = new SourceTable(doc._id, connection_tag, objectId, schema, table, replicationColumns, doc.snapshot_done ?? true);
85
92
  sourceTable.syncData = options.sync_rules.tableSyncsData(sourceTable);
86
93
  sourceTable.syncParameters = options.sync_rules.tableSyncsParameters(sourceTable);
87
94
  const truncate = await col
@@ -89,12 +96,12 @@ export class MongoSyncBucketStorage {
89
96
  group_id: group_id,
90
97
  connection_id: connection_id,
91
98
  _id: { $ne: doc._id },
92
- $or: [{ relation_id: relationId }, { schema_name: schema, table_name: table }]
99
+ $or: [{ relation_id: objectId }, { schema_name: schema, table_name: table }]
93
100
  }, { session })
94
101
  .toArray();
95
102
  result = {
96
103
  table: sourceTable,
97
- dropTables: truncate.map((doc) => new SourceTable(doc._id, connection_tag, doc.relation_id ?? 0, doc.schema_name, doc.table_name, doc.replica_id_columns2?.map((c) => ({ name: c.name, typeOid: c.type_oid })) ?? [], doc.snapshot_done ?? true))
104
+ dropTables: truncate.map((doc) => new SourceTable(doc._id, connection_tag, doc.relation_id ?? 0, doc.schema_name, doc.table_name, doc.replica_id_columns2?.map((c) => ({ name: c.name, typeOid: c.type_oid, type: c.type })) ?? [], doc.snapshot_done ?? true))
98
105
  };
99
106
  });
100
107
  return result;
@@ -189,6 +196,7 @@ export class MongoSyncBucketStorage {
189
196
  }
190
197
  let batchSize = 0;
191
198
  let currentBatch = null;
199
+ let targetOp = null;
192
200
  // Ordered by _id, meaning buckets are grouped together
193
201
  for (let rawData of data) {
194
202
  const row = bson.deserialize(rawData, BSON_DESERIALIZE_OPTIONS);
@@ -203,7 +211,8 @@ export class MongoSyncBucketStorage {
203
211
  start = currentBatch.after;
204
212
  currentBatch = null;
205
213
  batchSize = 0;
206
- yield yieldBatch;
214
+ yield { batch: yieldBatch, targetOp: targetOp };
215
+ targetOp = null;
207
216
  }
208
217
  start ?? (start = dataBuckets.get(bucket));
209
218
  if (start == null) {
@@ -216,16 +225,15 @@ export class MongoSyncBucketStorage {
216
225
  data: [],
217
226
  next_after: start
218
227
  };
228
+ targetOp = null;
229
+ }
230
+ const entry = mapOpEntry(row);
231
+ if (row.target_op != null) {
232
+ // MOVE, CLEAR
233
+ if (targetOp == null || row.target_op > targetOp) {
234
+ targetOp = row.target_op;
235
+ }
219
236
  }
220
- const entry = {
221
- op_id: util.timestampToOpId(row._id.o),
222
- op: row.op,
223
- object_type: row.table,
224
- object_id: row.row_id,
225
- checksum: Number(row.checksum),
226
- subkey: `${row.source_table}/${row.source_key.toHexString()}`,
227
- data: row.data
228
- };
229
237
  currentBatch.data.push(entry);
230
238
  currentBatch.next_after = entry.op_id;
231
239
  batchSize += rawData.byteLength;
@@ -233,7 +241,8 @@ export class MongoSyncBucketStorage {
233
241
  if (currentBatch != null) {
234
242
  const yieldBatch = currentBatch;
235
243
  currentBatch = null;
236
- yield yieldBatch;
244
+ yield { batch: yieldBatch, targetOp: targetOp };
245
+ targetOp = null;
237
246
  }
238
247
  }
239
248
  async getChecksums(checkpoint, buckets) {
@@ -283,8 +292,11 @@ export class MongoSyncBucketStorage {
283
292
  ];
284
293
  }));
285
294
  }
286
- async terminate() {
287
- await this.clear();
295
+ async terminate(options) {
296
+ // Default is to clear the storage except when explicitly requested not to.
297
+ if (!options || options?.clearStorage) {
298
+ await this.clear();
299
+ }
288
300
  await this.db.sync_rules.updateOne({
289
301
  _id: this.group_id
290
302
  }, {
@@ -387,5 +399,8 @@ export class MongoSyncBucketStorage {
387
399
  }
388
400
  });
389
401
  }
402
+ async compact(options) {
403
+ return new MongoCompactor(this.db, this.group_id, options).compact();
404
+ }
390
405
  }
391
406
  //# sourceMappingURL=MongoSyncBucketStorage.js.map