@powersync/service-core 0.8.7 → 0.9.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 (377) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/api/RouteAPI.d.ts +67 -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 +170 -158
  10. package/dist/api/diagnostics.js.map +1 -1
  11. package/dist/api/schema.d.ts +3 -5
  12. package/dist/api/schema.js +14 -80
  13. package/dist/api/schema.js.map +1 -1
  14. package/dist/auth/CachedKeyCollector.js.map +1 -1
  15. package/dist/auth/KeySpec.js.map +1 -1
  16. package/dist/auth/KeyStore.d.ts +7 -4
  17. package/dist/auth/KeyStore.js +1 -1
  18. package/dist/auth/KeyStore.js.map +1 -1
  19. package/dist/auth/LeakyBucket.js.map +1 -1
  20. package/dist/auth/RemoteJWKSCollector.d.ts +0 -2
  21. package/dist/auth/RemoteJWKSCollector.js.map +1 -1
  22. package/dist/auth/auth-index.d.ts +0 -1
  23. package/dist/auth/auth-index.js +0 -1
  24. package/dist/auth/auth-index.js.map +1 -1
  25. package/dist/db/mongo.js +5 -3
  26. package/dist/db/mongo.js.map +1 -1
  27. package/dist/entry/cli-entry.js +3 -2
  28. package/dist/entry/cli-entry.js.map +1 -1
  29. package/dist/entry/commands/compact-action.js +90 -14
  30. package/dist/entry/commands/compact-action.js.map +1 -1
  31. package/dist/entry/commands/migrate-action.js +4 -5
  32. package/dist/entry/commands/migrate-action.js.map +1 -1
  33. package/dist/entry/commands/teardown-action.js +2 -2
  34. package/dist/entry/commands/teardown-action.js.map +1 -1
  35. package/dist/index.d.ts +4 -2
  36. package/dist/index.js +4 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/locks/MongoLocks.js.map +1 -1
  39. package/dist/metrics/Metrics.d.ts +2 -2
  40. package/dist/metrics/Metrics.js +5 -13
  41. package/dist/metrics/Metrics.js.map +1 -1
  42. package/dist/migrations/db/migrations/1684951997326-init.d.ts +2 -2
  43. package/dist/migrations/db/migrations/1684951997326-init.js +4 -2
  44. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
  45. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +2 -2
  46. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +4 -2
  47. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
  48. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +2 -2
  49. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +4 -2
  50. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
  51. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.d.ts +3 -0
  52. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js +31 -0
  53. package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js.map +1 -0
  54. package/dist/migrations/executor.js.map +1 -1
  55. package/dist/migrations/migrations.d.ts +8 -0
  56. package/dist/migrations/migrations.js +19 -7
  57. package/dist/migrations/migrations.js.map +1 -1
  58. package/dist/migrations/store/migration-store.js.map +1 -1
  59. package/dist/modules/AbstractModule.d.ts +26 -0
  60. package/dist/modules/AbstractModule.js +11 -0
  61. package/dist/modules/AbstractModule.js.map +1 -0
  62. package/dist/modules/ModuleManager.d.ts +11 -0
  63. package/dist/modules/ModuleManager.js +32 -0
  64. package/dist/modules/ModuleManager.js.map +1 -0
  65. package/dist/modules/modules-index.d.ts +2 -0
  66. package/dist/modules/modules-index.js +3 -0
  67. package/dist/modules/modules-index.js.map +1 -0
  68. package/dist/replication/AbstractReplicationJob.d.ts +37 -0
  69. package/dist/replication/AbstractReplicationJob.js +51 -0
  70. package/dist/replication/AbstractReplicationJob.js.map +1 -0
  71. package/dist/replication/AbstractReplicator.d.ts +53 -0
  72. package/dist/replication/AbstractReplicator.js +250 -0
  73. package/dist/replication/AbstractReplicator.js.map +1 -0
  74. package/dist/replication/ErrorRateLimiter.d.ts +0 -10
  75. package/dist/replication/ErrorRateLimiter.js +1 -42
  76. package/dist/replication/ErrorRateLimiter.js.map +1 -1
  77. package/dist/replication/ReplicationEngine.d.ts +18 -0
  78. package/dist/replication/ReplicationEngine.js +41 -0
  79. package/dist/replication/ReplicationEngine.js.map +1 -0
  80. package/dist/replication/ReplicationModule.d.ts +51 -0
  81. package/dist/replication/ReplicationModule.js +68 -0
  82. package/dist/replication/ReplicationModule.js.map +1 -0
  83. package/dist/replication/replication-index.d.ts +4 -6
  84. package/dist/replication/replication-index.js +4 -6
  85. package/dist/replication/replication-index.js.map +1 -1
  86. package/dist/routes/RouterEngine.d.ts +42 -0
  87. package/dist/routes/RouterEngine.js +80 -0
  88. package/dist/routes/RouterEngine.js.map +1 -0
  89. package/dist/routes/auth.d.ts +2 -2
  90. package/dist/routes/auth.js +11 -11
  91. package/dist/routes/auth.js.map +1 -1
  92. package/dist/routes/configure-fastify.d.ts +37 -7
  93. package/dist/routes/configure-fastify.js +20 -19
  94. package/dist/routes/configure-fastify.js.map +1 -1
  95. package/dist/routes/configure-rsocket.d.ts +3 -4
  96. package/dist/routes/configure-rsocket.js +7 -4
  97. package/dist/routes/configure-rsocket.js.map +1 -1
  98. package/dist/routes/endpoints/admin.d.ts +30 -0
  99. package/dist/routes/endpoints/admin.js +46 -67
  100. package/dist/routes/endpoints/admin.js.map +1 -1
  101. package/dist/routes/endpoints/checkpointing.js +103 -15
  102. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  103. package/dist/routes/endpoints/probes.d.ts +74 -0
  104. package/dist/routes/endpoints/probes.js +51 -0
  105. package/dist/routes/endpoints/probes.js.map +1 -0
  106. package/dist/routes/endpoints/socket-route.js +8 -6
  107. package/dist/routes/endpoints/socket-route.js.map +1 -1
  108. package/dist/routes/endpoints/sync-rules.d.ts +1 -1
  109. package/dist/routes/endpoints/sync-rules.js +32 -23
  110. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  111. package/dist/routes/endpoints/sync-stream.d.ts +0 -1
  112. package/dist/routes/endpoints/sync-stream.js +8 -8
  113. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  114. package/dist/routes/hooks.js.map +1 -1
  115. package/dist/routes/route-register.js.map +1 -1
  116. package/dist/routes/router.d.ts +11 -4
  117. package/dist/routes/router.js.map +1 -1
  118. package/dist/routes/routes-index.d.ts +1 -0
  119. package/dist/routes/routes-index.js +1 -0
  120. package/dist/routes/routes-index.js.map +1 -1
  121. package/dist/runner/teardown.js +109 -76
  122. package/dist/runner/teardown.js.map +1 -1
  123. package/dist/storage/BucketStorage.d.ts +86 -36
  124. package/dist/storage/BucketStorage.js +6 -10
  125. package/dist/storage/BucketStorage.js.map +1 -1
  126. package/dist/storage/ChecksumCache.js.map +1 -1
  127. package/dist/storage/MongoBucketStorage.d.ts +7 -11
  128. package/dist/storage/MongoBucketStorage.js +48 -41
  129. package/dist/storage/MongoBucketStorage.js.map +1 -1
  130. package/dist/storage/ReplicationEventPayload.d.ts +14 -0
  131. package/dist/storage/ReplicationEventPayload.js +2 -0
  132. package/dist/storage/ReplicationEventPayload.js.map +1 -0
  133. package/dist/storage/SourceEntity.d.ts +20 -0
  134. package/dist/storage/SourceEntity.js +2 -0
  135. package/dist/storage/SourceEntity.js.map +1 -0
  136. package/dist/storage/SourceTable.d.ts +12 -5
  137. package/dist/storage/SourceTable.js +12 -5
  138. package/dist/storage/SourceTable.js.map +1 -1
  139. package/dist/storage/StorageEngine.d.ts +28 -0
  140. package/dist/storage/StorageEngine.js +45 -0
  141. package/dist/storage/StorageEngine.js.map +1 -0
  142. package/dist/storage/StorageProvider.d.ts +21 -0
  143. package/dist/storage/StorageProvider.js +2 -0
  144. package/dist/storage/StorageProvider.js.map +1 -0
  145. package/dist/storage/WriteCheckpointAPI.d.ts +74 -0
  146. package/dist/storage/WriteCheckpointAPI.js +16 -0
  147. package/dist/storage/WriteCheckpointAPI.js.map +1 -0
  148. package/dist/storage/mongo/MongoBucketBatch.d.ts +24 -5
  149. package/dist/storage/mongo/MongoBucketBatch.js +119 -62
  150. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
  151. package/dist/storage/mongo/MongoCompactor.js +20 -3
  152. package/dist/storage/mongo/MongoCompactor.js.map +1 -1
  153. package/dist/storage/mongo/MongoIdSequence.js.map +1 -1
  154. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +2 -2
  155. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +2 -2
  156. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
  157. package/dist/storage/mongo/MongoStorageProvider.d.ts +5 -0
  158. package/dist/storage/mongo/MongoStorageProvider.js +26 -0
  159. package/dist/storage/mongo/MongoStorageProvider.js.map +1 -0
  160. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +18 -10
  161. package/dist/storage/mongo/MongoSyncBucketStorage.js +140 -25
  162. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
  163. package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
  164. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
  165. package/dist/storage/mongo/MongoWriteCheckpointAPI.d.ts +20 -0
  166. package/dist/storage/mongo/MongoWriteCheckpointAPI.js +103 -0
  167. package/dist/storage/mongo/MongoWriteCheckpointAPI.js.map +1 -0
  168. package/dist/storage/mongo/OperationBatch.d.ts +13 -4
  169. package/dist/storage/mongo/OperationBatch.js +25 -7
  170. package/dist/storage/mongo/OperationBatch.js.map +1 -1
  171. package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
  172. package/dist/storage/mongo/PersistedBatch.js +2 -2
  173. package/dist/storage/mongo/PersistedBatch.js.map +1 -1
  174. package/dist/storage/mongo/config.d.ts +19 -0
  175. package/dist/storage/mongo/config.js +26 -0
  176. package/dist/storage/mongo/config.js.map +1 -0
  177. package/dist/storage/mongo/db.d.ts +3 -2
  178. package/dist/storage/mongo/db.js +1 -0
  179. package/dist/storage/mongo/db.js.map +1 -1
  180. package/dist/storage/mongo/models.d.ts +20 -5
  181. package/dist/storage/mongo/models.js.map +1 -1
  182. package/dist/storage/mongo/util.d.ts +12 -1
  183. package/dist/storage/mongo/util.js +50 -2
  184. package/dist/storage/mongo/util.js.map +1 -1
  185. package/dist/storage/storage-index.d.ts +8 -2
  186. package/dist/storage/storage-index.js +8 -2
  187. package/dist/storage/storage-index.js.map +1 -1
  188. package/dist/sync/BroadcastIterable.d.ts +0 -1
  189. package/dist/sync/BroadcastIterable.js.map +1 -1
  190. package/dist/sync/LastValueSink.d.ts +0 -1
  191. package/dist/sync/LastValueSink.js.map +1 -1
  192. package/dist/sync/merge.d.ts +0 -1
  193. package/dist/sync/merge.js.map +1 -1
  194. package/dist/sync/safeRace.js.map +1 -1
  195. package/dist/sync/sync.d.ts +1 -1
  196. package/dist/sync/sync.js +5 -5
  197. package/dist/sync/sync.js.map +1 -1
  198. package/dist/sync/util.d.ts +0 -2
  199. package/dist/sync/util.js.map +1 -1
  200. package/dist/system/ServiceContext.d.ts +37 -0
  201. package/dist/system/ServiceContext.js +48 -0
  202. package/dist/system/ServiceContext.js.map +1 -0
  203. package/dist/system/system-index.d.ts +1 -1
  204. package/dist/system/system-index.js +1 -1
  205. package/dist/system/system-index.js.map +1 -1
  206. package/dist/util/Mutex.js.map +1 -1
  207. package/dist/util/config/collectors/config-collector.js.map +1 -1
  208. package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -1
  209. package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -1
  210. package/dist/util/config/compound-config-collector.d.ts +9 -2
  211. package/dist/util/config/compound-config-collector.js +16 -24
  212. package/dist/util/config/compound-config-collector.js.map +1 -1
  213. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -1
  214. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -1
  215. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -1
  216. package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
  217. package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
  218. package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
  219. package/dist/util/config/types.d.ts +7 -4
  220. package/dist/util/config/types.js.map +1 -1
  221. package/dist/util/config.d.ts +3 -4
  222. package/dist/util/config.js +5 -20
  223. package/dist/util/config.js.map +1 -1
  224. package/dist/util/memory-tracking.js.map +1 -1
  225. package/dist/util/secs.js.map +1 -1
  226. package/dist/util/util-index.d.ts +3 -6
  227. package/dist/util/util-index.js +3 -6
  228. package/dist/util/util-index.js.map +1 -1
  229. package/dist/util/utils.d.ts +10 -7
  230. package/dist/util/utils.js +36 -25
  231. package/dist/util/utils.js.map +1 -1
  232. package/package.json +8 -12
  233. package/src/api/RouteAPI.ts +78 -0
  234. package/src/api/api-index.ts +1 -0
  235. package/src/api/diagnostics.ts +18 -70
  236. package/src/api/schema.ts +18 -90
  237. package/src/auth/KeyStore.ts +9 -6
  238. package/src/auth/RemoteJWKSCollector.ts +4 -1
  239. package/src/auth/auth-index.ts +0 -1
  240. package/src/db/mongo.ts +5 -3
  241. package/src/entry/cli-entry.ts +3 -2
  242. package/src/entry/commands/compact-action.ts +24 -12
  243. package/src/entry/commands/migrate-action.ts +5 -8
  244. package/src/entry/commands/teardown-action.ts +2 -2
  245. package/src/index.ts +5 -2
  246. package/src/metrics/Metrics.ts +6 -16
  247. package/src/migrations/db/migrations/1684951997326-init.ts +9 -4
  248. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -4
  249. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +6 -4
  250. package/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts +37 -0
  251. package/src/migrations/migrations.ts +24 -8
  252. package/src/modules/AbstractModule.ts +37 -0
  253. package/src/modules/ModuleManager.ts +34 -0
  254. package/src/modules/modules-index.ts +2 -0
  255. package/src/replication/AbstractReplicationJob.ts +79 -0
  256. package/src/replication/AbstractReplicator.ts +228 -0
  257. package/src/replication/ErrorRateLimiter.ts +0 -44
  258. package/src/replication/ReplicationEngine.ts +43 -0
  259. package/src/replication/ReplicationModule.ts +122 -0
  260. package/src/replication/replication-index.ts +4 -6
  261. package/src/routes/RouterEngine.ts +120 -0
  262. package/src/routes/auth.ts +21 -12
  263. package/src/routes/configure-fastify.ts +28 -28
  264. package/src/routes/configure-rsocket.ts +13 -8
  265. package/src/routes/endpoints/admin.ts +72 -76
  266. package/src/routes/endpoints/checkpointing.ts +51 -11
  267. package/src/routes/endpoints/probes.ts +58 -0
  268. package/src/routes/endpoints/socket-route.ts +10 -6
  269. package/src/routes/endpoints/sync-rules.ts +41 -25
  270. package/src/routes/endpoints/sync-stream.ts +8 -8
  271. package/src/routes/router.ts +10 -5
  272. package/src/routes/routes-index.ts +1 -0
  273. package/src/runner/teardown.ts +50 -88
  274. package/src/storage/BucketStorage.ts +103 -41
  275. package/src/storage/MongoBucketStorage.ts +65 -53
  276. package/src/storage/ReplicationEventPayload.ts +16 -0
  277. package/src/storage/SourceEntity.ts +22 -0
  278. package/src/storage/SourceTable.ts +14 -7
  279. package/src/storage/StorageEngine.ts +62 -0
  280. package/src/storage/StorageProvider.ts +27 -0
  281. package/src/storage/WriteCheckpointAPI.ts +85 -0
  282. package/src/storage/mongo/MongoBucketBatch.ts +164 -84
  283. package/src/storage/mongo/MongoCompactor.ts +25 -4
  284. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +7 -4
  285. package/src/storage/mongo/MongoStorageProvider.ts +31 -0
  286. package/src/storage/mongo/MongoSyncBucketStorage.ts +118 -41
  287. package/src/storage/mongo/MongoSyncRulesLock.ts +7 -3
  288. package/src/storage/mongo/MongoWriteCheckpointAPI.ts +151 -0
  289. package/src/storage/mongo/OperationBatch.ts +28 -12
  290. package/src/storage/mongo/PersistedBatch.ts +10 -6
  291. package/src/storage/mongo/config.ts +40 -0
  292. package/src/storage/mongo/db.ts +4 -1
  293. package/src/storage/mongo/models.ts +21 -5
  294. package/src/storage/mongo/util.ts +48 -3
  295. package/src/storage/storage-index.ts +8 -2
  296. package/src/sync/sync.ts +7 -4
  297. package/src/sync/util.ts +0 -1
  298. package/src/system/ServiceContext.ts +68 -0
  299. package/src/system/system-index.ts +1 -1
  300. package/src/util/config/compound-config-collector.ts +31 -31
  301. package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
  302. package/src/util/config/types.ts +7 -5
  303. package/src/util/config.ts +6 -23
  304. package/src/util/util-index.ts +3 -6
  305. package/src/util/utils.ts +48 -41
  306. package/test/src/__snapshots__/sync.test.ts.snap +14 -14
  307. package/test/src/auth.test.ts +7 -7
  308. package/test/src/broadcast_iterable.test.ts +1 -1
  309. package/test/src/compacting.test.ts +50 -40
  310. package/test/src/data_storage.test.ts +382 -202
  311. package/test/src/env.ts +1 -3
  312. package/test/src/merge_iterable.test.ts +1 -6
  313. package/test/src/routes/probes.integration.test.ts +235 -0
  314. package/test/src/routes/probes.test.ts +153 -0
  315. package/test/src/setup.ts +1 -1
  316. package/test/src/stream_utils.ts +42 -0
  317. package/test/src/sync.test.ts +115 -39
  318. package/test/src/util.ts +48 -51
  319. package/test/tsconfig.json +1 -1
  320. package/tsconfig.tsbuildinfo +1 -1
  321. package/vitest.config.ts +7 -1
  322. package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
  323. package/dist/auth/SupabaseKeyCollector.js +0 -61
  324. package/dist/auth/SupabaseKeyCollector.js.map +0 -1
  325. package/dist/replication/PgRelation.d.ts +0 -16
  326. package/dist/replication/PgRelation.js +0 -26
  327. package/dist/replication/PgRelation.js.map +0 -1
  328. package/dist/replication/WalConnection.d.ts +0 -34
  329. package/dist/replication/WalConnection.js +0 -190
  330. package/dist/replication/WalConnection.js.map +0 -1
  331. package/dist/replication/WalStream.d.ts +0 -57
  332. package/dist/replication/WalStream.js +0 -519
  333. package/dist/replication/WalStream.js.map +0 -1
  334. package/dist/replication/WalStreamManager.d.ts +0 -30
  335. package/dist/replication/WalStreamManager.js +0 -198
  336. package/dist/replication/WalStreamManager.js.map +0 -1
  337. package/dist/replication/WalStreamRunner.d.ts +0 -38
  338. package/dist/replication/WalStreamRunner.js +0 -155
  339. package/dist/replication/WalStreamRunner.js.map +0 -1
  340. package/dist/replication/util.d.ts +0 -9
  341. package/dist/replication/util.js +0 -62
  342. package/dist/replication/util.js.map +0 -1
  343. package/dist/system/CorePowerSyncSystem.d.ts +0 -23
  344. package/dist/system/CorePowerSyncSystem.js +0 -52
  345. package/dist/system/CorePowerSyncSystem.js.map +0 -1
  346. package/dist/util/PgManager.d.ts +0 -24
  347. package/dist/util/PgManager.js +0 -55
  348. package/dist/util/PgManager.js.map +0 -1
  349. package/dist/util/migration_lib.d.ts +0 -11
  350. package/dist/util/migration_lib.js +0 -64
  351. package/dist/util/migration_lib.js.map +0 -1
  352. package/dist/util/pgwire_utils.d.ts +0 -24
  353. package/dist/util/pgwire_utils.js +0 -117
  354. package/dist/util/pgwire_utils.js.map +0 -1
  355. package/dist/util/populate_test_data.d.ts +0 -8
  356. package/dist/util/populate_test_data.js +0 -65
  357. package/dist/util/populate_test_data.js.map +0 -1
  358. package/src/auth/SupabaseKeyCollector.ts +0 -67
  359. package/src/replication/PgRelation.ts +0 -42
  360. package/src/replication/WalConnection.ts +0 -227
  361. package/src/replication/WalStream.ts +0 -631
  362. package/src/replication/WalStreamManager.ts +0 -213
  363. package/src/replication/WalStreamRunner.ts +0 -180
  364. package/src/replication/util.ts +0 -76
  365. package/src/system/CorePowerSyncSystem.ts +0 -64
  366. package/src/util/PgManager.ts +0 -64
  367. package/src/util/migration_lib.ts +0 -79
  368. package/src/util/pgwire_utils.ts +0 -139
  369. package/src/util/populate_test_data.ts +0 -78
  370. package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
  371. package/test/src/large_batch.test.ts +0 -194
  372. package/test/src/pg_test.test.ts +0 -450
  373. package/test/src/schema_changes.test.ts +0 -545
  374. package/test/src/slow_tests.test.ts +0 -338
  375. package/test/src/validation.test.ts +0 -63
  376. package/test/src/wal_stream.test.ts +0 -319
  377. package/test/src/wal_stream_utils.ts +0 -156
@@ -1,12 +1,12 @@
1
+ import { SaveOperationTag } from '@/storage/storage-index.js';
1
2
  import { RequestTracker } from '@/sync/RequestTracker.js';
3
+ import { streamResponse, SyncStreamParameters } from '@/sync/sync.js';
2
4
  import { StreamingSyncLine } from '@/util/protocol-types.js';
3
- import { lsnMakeComparable } from '@powersync/service-jpgwire';
4
5
  import { JSONBig } from '@powersync/service-jsonbig';
5
6
  import { RequestParameters } from '@powersync/service-sync-rules';
6
7
  import * as timers from 'timers/promises';
7
8
  import { describe, expect, test } from 'vitest';
8
- import { streamResponse } from '../../src/sync/sync.js';
9
- import { makeTestTable, MONGO_STORAGE_FACTORY, StorageFactory } from './util.js';
9
+ import { BATCH_OPTIONS, makeTestTable, MONGO_STORAGE_FACTORY, PARSE_OPTIONS, StorageFactory } from './util.js';
10
10
 
11
11
  describe('sync - mongodb', function () {
12
12
  defineTests(MONGO_STORAGE_FACTORY);
@@ -31,29 +31,31 @@ function defineTests(factory: StorageFactory) {
31
31
  content: BASIC_SYNC_RULES
32
32
  });
33
33
 
34
- const storage = await f.getInstance(syncRules.parsed());
34
+ const storage = f.getInstance(syncRules);
35
35
  await storage.autoActivate();
36
36
 
37
- const result = await storage.startBatch({}, async (batch) => {
37
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
38
38
  await batch.save({
39
39
  sourceTable: TEST_TABLE,
40
- tag: 'insert',
40
+ tag: SaveOperationTag.INSERT,
41
41
  after: {
42
42
  id: 't1',
43
43
  description: 'Test 1'
44
- }
44
+ },
45
+ afterReplicaId: 't1'
45
46
  });
46
47
 
47
48
  await batch.save({
48
49
  sourceTable: TEST_TABLE,
49
- tag: 'insert',
50
+ tag: SaveOperationTag.INSERT,
50
51
  after: {
51
52
  id: 't2',
52
53
  description: 'Test 2'
53
- }
54
+ },
55
+ afterReplicaId: 't2'
54
56
  });
55
57
 
56
- await batch.commit(lsnMakeComparable('0/1'));
58
+ await batch.commit('0/1');
57
59
  });
58
60
 
59
61
  const stream = streamResponse({
@@ -63,6 +65,7 @@ function defineTests(factory: StorageFactory) {
63
65
  include_checksum: true,
64
66
  raw_data: true
65
67
  },
68
+ parseOptions: PARSE_OPTIONS,
66
69
  tracker,
67
70
  syncParams: new RequestParameters({ sub: '' }, {}),
68
71
  token: { exp: Date.now() / 1000 + 10 } as any
@@ -79,21 +82,22 @@ function defineTests(factory: StorageFactory) {
79
82
  content: BASIC_SYNC_RULES
80
83
  });
81
84
 
82
- const storage = await f.getInstance(syncRules.parsed());
85
+ const storage = await f.getInstance(syncRules);
83
86
  await storage.autoActivate();
84
87
 
85
- const result = await storage.startBatch({}, async (batch) => {
88
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
86
89
  await batch.save({
87
90
  sourceTable: TEST_TABLE,
88
- tag: 'insert',
91
+ tag: SaveOperationTag.INSERT,
89
92
  after: {
90
93
  id: 't1',
91
94
  description: 'Test\n"string"',
92
95
  large_num: 12345678901234567890n
93
- }
96
+ },
97
+ afterReplicaId: 't1'
94
98
  });
95
99
 
96
- await batch.commit(lsnMakeComparable('0/1'));
100
+ await batch.commit('0/1');
97
101
  });
98
102
 
99
103
  const stream = streamResponse({
@@ -103,6 +107,7 @@ function defineTests(factory: StorageFactory) {
103
107
  include_checksum: true,
104
108
  raw_data: false
105
109
  },
110
+ parseOptions: PARSE_OPTIONS,
106
111
  tracker,
107
112
  syncParams: new RequestParameters({ sub: '' }, {}),
108
113
  token: { exp: Date.now() / 1000 + 10 } as any
@@ -121,7 +126,7 @@ function defineTests(factory: StorageFactory) {
121
126
  content: BASIC_SYNC_RULES
122
127
  });
123
128
 
124
- const storage = await f.getInstance(syncRules.parsed());
129
+ const storage = await f.getInstance(syncRules);
125
130
  await storage.autoActivate();
126
131
 
127
132
  const stream = streamResponse({
@@ -131,6 +136,7 @@ function defineTests(factory: StorageFactory) {
131
136
  include_checksum: true,
132
137
  raw_data: true
133
138
  },
139
+ parseOptions: PARSE_OPTIONS,
134
140
  tracker,
135
141
  syncParams: new RequestParameters({ sub: '' }, {}),
136
142
  token: { exp: 0 } as any
@@ -147,7 +153,7 @@ function defineTests(factory: StorageFactory) {
147
153
  content: BASIC_SYNC_RULES
148
154
  });
149
155
 
150
- const storage = await f.getInstance(syncRules.parsed());
156
+ const storage = await f.getInstance(syncRules);
151
157
  await storage.autoActivate();
152
158
 
153
159
  const stream = streamResponse({
@@ -157,6 +163,7 @@ function defineTests(factory: StorageFactory) {
157
163
  include_checksum: true,
158
164
  raw_data: true
159
165
  },
166
+ parseOptions: PARSE_OPTIONS,
160
167
  tracker,
161
168
  syncParams: new RequestParameters({ sub: '' }, {}),
162
169
  token: { exp: Date.now() / 1000 + 10 } as any
@@ -165,32 +172,34 @@ function defineTests(factory: StorageFactory) {
165
172
 
166
173
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
167
174
 
168
- await storage.startBatch({}, async (batch) => {
175
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
169
176
  await batch.save({
170
177
  sourceTable: TEST_TABLE,
171
- tag: 'insert',
178
+ tag: SaveOperationTag.INSERT,
172
179
  after: {
173
180
  id: 't1',
174
181
  description: 'Test 1'
175
- }
182
+ },
183
+ afterReplicaId: 't1'
176
184
  });
177
185
 
178
- await batch.commit(lsnMakeComparable('0/1'));
186
+ await batch.commit('0/1');
179
187
  });
180
188
 
181
189
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
182
190
 
183
- await storage.startBatch({}, async (batch) => {
191
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
184
192
  await batch.save({
185
193
  sourceTable: TEST_TABLE,
186
- tag: 'insert',
194
+ tag: SaveOperationTag.INSERT,
187
195
  after: {
188
196
  id: 't2',
189
197
  description: 'Test 2'
190
- }
198
+ },
199
+ afterReplicaId: 't2'
191
200
  });
192
201
 
193
- await batch.commit(lsnMakeComparable('0/2'));
202
+ await batch.commit('0/2');
194
203
  });
195
204
 
196
205
  expect(await getCheckpointLines(iter)).toMatchSnapshot();
@@ -205,7 +214,7 @@ function defineTests(factory: StorageFactory) {
205
214
  content: BASIC_SYNC_RULES
206
215
  });
207
216
 
208
- const storage = await f.getInstance(syncRules.parsed());
217
+ const storage = await f.getInstance(syncRules);
209
218
  await storage.autoActivate();
210
219
 
211
220
  const exp = Date.now() / 1000 + 0.1;
@@ -217,6 +226,7 @@ function defineTests(factory: StorageFactory) {
217
226
  include_checksum: true,
218
227
  raw_data: true
219
228
  },
229
+ parseOptions: PARSE_OPTIONS,
220
230
  tracker,
221
231
  syncParams: new RequestParameters({ sub: '' }, {}),
222
232
  token: { exp: exp } as any
@@ -242,29 +252,31 @@ function defineTests(factory: StorageFactory) {
242
252
  content: BASIC_SYNC_RULES
243
253
  });
244
254
 
245
- const storage = await f.getInstance(syncRules.parsed());
255
+ const storage = await f.getInstance(syncRules);
246
256
  await storage.autoActivate();
247
257
 
248
- await storage.startBatch({}, async (batch) => {
258
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
249
259
  await batch.save({
250
260
  sourceTable: TEST_TABLE,
251
- tag: 'insert',
261
+ tag: SaveOperationTag.INSERT,
252
262
  after: {
253
263
  id: 't1',
254
264
  description: 'Test 1'
255
- }
265
+ },
266
+ afterReplicaId: 't1'
256
267
  });
257
268
 
258
269
  await batch.save({
259
270
  sourceTable: TEST_TABLE,
260
- tag: 'insert',
271
+ tag: SaveOperationTag.INSERT,
261
272
  after: {
262
273
  id: 't2',
263
274
  description: 'Test 2'
264
- }
275
+ },
276
+ afterReplicaId: 't2'
265
277
  });
266
278
 
267
- await batch.commit(lsnMakeComparable('0/1'));
279
+ await batch.commit('0/1');
268
280
  });
269
281
 
270
282
  const stream = streamResponse({
@@ -274,6 +286,7 @@ function defineTests(factory: StorageFactory) {
274
286
  include_checksum: true,
275
287
  raw_data: true
276
288
  },
289
+ parseOptions: PARSE_OPTIONS,
277
290
  tracker,
278
291
  syncParams: new RequestParameters({ sub: '' }, {}),
279
292
  token: { exp: Date.now() / 1000 + 10 } as any
@@ -293,26 +306,28 @@ function defineTests(factory: StorageFactory) {
293
306
  // Now we save additional data AND compact before continuing.
294
307
  // This invalidates the checkpoint we've received above.
295
308
 
296
- await storage.startBatch({}, async (batch) => {
309
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
297
310
  await batch.save({
298
311
  sourceTable: TEST_TABLE,
299
- tag: 'update',
312
+ tag: SaveOperationTag.UPDATE,
300
313
  after: {
301
314
  id: 't1',
302
315
  description: 'Test 1b'
303
- }
316
+ },
317
+ afterReplicaId: 't1'
304
318
  });
305
319
 
306
320
  await batch.save({
307
321
  sourceTable: TEST_TABLE,
308
- tag: 'update',
322
+ tag: SaveOperationTag.UPDATE,
309
323
  after: {
310
324
  id: 't2',
311
325
  description: 'Test 2b'
312
- }
326
+ },
327
+ afterReplicaId: 't2'
313
328
  });
314
329
 
315
- await batch.commit(lsnMakeComparable('0/2'));
330
+ await batch.commit('0/2');
316
331
  });
317
332
 
318
333
  await storage.compact();
@@ -366,6 +381,67 @@ function defineTests(factory: StorageFactory) {
366
381
  })
367
382
  });
368
383
  });
384
+
385
+ test('write checkpoint', async () => {
386
+ const f = await factory();
387
+
388
+ const syncRules = await f.updateSyncRules({
389
+ content: BASIC_SYNC_RULES
390
+ });
391
+
392
+ const storage = f.getInstance(syncRules);
393
+ await storage.autoActivate();
394
+
395
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
396
+ // <= the managed write checkpoint LSN below
397
+ await batch.commit('0/1');
398
+ });
399
+
400
+ const checkpoint = await storage.createManagedWriteCheckpoint({
401
+ user_id: 'test',
402
+ heads: { '1': '1/0' }
403
+ });
404
+
405
+ const params: SyncStreamParameters = {
406
+ storage: f,
407
+ params: {
408
+ buckets: [],
409
+ include_checksum: true,
410
+ raw_data: true
411
+ },
412
+ parseOptions: PARSE_OPTIONS,
413
+ tracker,
414
+ syncParams: new RequestParameters({ sub: 'test' }, {}),
415
+ token: { sub: 'test', exp: Date.now() / 1000 + 10 } as any
416
+ };
417
+ const stream1 = streamResponse(params);
418
+ const lines1 = await consumeCheckpointLines(stream1);
419
+
420
+ // If write checkpoints are not correctly filtered, this may already
421
+ // contain the write checkpoint.
422
+ expect(lines1[0]).toMatchObject({
423
+ checkpoint: expect.objectContaining({
424
+ last_op_id: '0',
425
+ write_checkpoint: undefined
426
+ })
427
+ });
428
+
429
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
430
+ // must be >= the managed write checkpoint LSN
431
+ await batch.commit('1/0');
432
+ });
433
+
434
+ // At this point the LSN has advanced, so the write checkpoint should be
435
+ // included in the next checkpoint message.
436
+ const stream2 = streamResponse(params);
437
+ const lines2 = await consumeCheckpointLines(stream2);
438
+ expect(lines2[0]).toMatchObject({
439
+ checkpoint: expect.objectContaining({
440
+ last_op_id: '0',
441
+ write_checkpoint: `${checkpoint}`
442
+ })
443
+ });
444
+ });
369
445
  }
370
446
 
371
447
  /**
package/test/src/util.ts CHANGED
@@ -1,16 +1,20 @@
1
- import * as pgwire from '@powersync/service-jpgwire';
2
- import { normalizeConnection } from '@powersync/service-types';
3
- import * as mongo from 'mongodb';
4
- import { BucketStorageFactory, SyncBucketDataBatch } from '../../src/storage/BucketStorage.js';
5
- import { MongoBucketStorage } from '../../src/storage/MongoBucketStorage.js';
6
- import { PowerSyncMongo } from '../../src/storage/mongo/db.js';
7
- import { escapeIdentifier } from '../../src/util/pgwire_utils.js';
8
- import { env } from './env.js';
9
1
  import { Metrics } from '@/metrics/Metrics.js';
10
- import { hashData } from '@/util/utils.js';
2
+ import {
3
+ BucketStorageFactory,
4
+ ParseSyncRulesOptions,
5
+ PersistedSyncRulesContent,
6
+ StartBatchOptions,
7
+ SyncBucketDataBatch
8
+ } from '@/storage/BucketStorage.js';
9
+ import { MongoBucketStorage } from '@/storage/MongoBucketStorage.js';
11
10
  import { SourceTable } from '@/storage/SourceTable.js';
12
- import * as bson from 'bson';
11
+ import { PowerSyncMongo } from '@/storage/mongo/db.js';
13
12
  import { SyncBucketData } from '@/util/protocol-types.js';
13
+ import { getUuidReplicaIdentityBson, hashData } from '@/util/utils.js';
14
+ import { SqlSyncRules } from '@powersync/service-sync-rules';
15
+ import * as bson from 'bson';
16
+ import * as mongo from 'mongodb';
17
+ import { env } from './env.js';
14
18
 
15
19
  // The metrics need to be initialised before they can be used
16
20
  await Metrics.initialise({
@@ -20,8 +24,6 @@ await Metrics.initialise({
20
24
  });
21
25
  Metrics.getInstance().resetCounters();
22
26
 
23
- export const TEST_URI = env.PG_TEST_URL;
24
-
25
27
  export interface StorageOptions {
26
28
  /**
27
29
  * By default, collections are only cleared/
@@ -41,45 +43,34 @@ export const MONGO_STORAGE_FACTORY: StorageFactory = async (options?: StorageOpt
41
43
  return new MongoBucketStorage(db, { slot_name_prefix: 'test_' });
42
44
  };
43
45
 
44
- export async function clearTestDb(db: pgwire.PgClient) {
45
- await db.query(
46
- "select pg_drop_replication_slot(slot_name) from pg_replication_slots where active = false and slot_name like 'test_%'"
47
- );
46
+ export const ZERO_LSN = '0/0';
48
47
 
49
- await db.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`);
50
- try {
51
- await db.query(`DROP PUBLICATION powersync`);
52
- } catch (e) {
53
- // Ignore
54
- }
48
+ export const PARSE_OPTIONS: ParseSyncRulesOptions = {
49
+ defaultSchema: 'public'
50
+ };
55
51
 
56
- await db.query(`CREATE PUBLICATION powersync FOR ALL TABLES`);
52
+ export const BATCH_OPTIONS: StartBatchOptions = {
53
+ ...PARSE_OPTIONS,
54
+ zeroLSN: ZERO_LSN,
55
+ storeCurrentData: true
56
+ };
57
57
 
58
- const tableRows = pgwire.pgwireRows(
59
- await db.query(`SELECT table_name FROM information_schema.tables where table_schema = 'public'`)
60
- );
61
- for (let row of tableRows) {
62
- const name = row.table_name;
63
- if (name.startsWith('test_')) {
64
- await db.query(`DROP TABLE public.${escapeIdentifier(name)}`);
58
+ export function testRules(content: string): PersistedSyncRulesContent {
59
+ return {
60
+ id: 1,
61
+ sync_rules_content: content,
62
+ slot_name: 'test',
63
+ parsed(options) {
64
+ return {
65
+ id: 1,
66
+ sync_rules: SqlSyncRules.fromYaml(content, options),
67
+ slot_name: 'test'
68
+ };
69
+ },
70
+ lock() {
71
+ throw new Error('Not implemented');
65
72
  }
66
- }
67
- }
68
-
69
- export const TEST_CONNECTION_OPTIONS = normalizeConnection({
70
- type: 'postgresql',
71
- uri: TEST_URI,
72
- sslmode: 'disable'
73
- });
74
-
75
- export async function connectPgWire(type?: 'replication' | 'standard') {
76
- const db = await pgwire.connectPgWire(TEST_CONNECTION_OPTIONS, { type });
77
- return db;
78
- }
79
-
80
- export function connectPgPool() {
81
- const db = pgwire.connectPgWirePool(TEST_CONNECTION_OPTIONS);
82
- return db;
73
+ };
83
74
  }
84
75
 
85
76
  export async function connectMongo() {
@@ -90,8 +81,7 @@ export async function connectMongo() {
90
81
  socketTimeoutMS: env.CI ? 15_000 : 5_000,
91
82
  serverSelectionTimeoutMS: env.CI ? 15_000 : 2_500
92
83
  });
93
- const db = new PowerSyncMongo(client);
94
- return db;
84
+ return new PowerSyncMongo(client);
95
85
  }
96
86
 
97
87
  export function makeTestTable(name: string, columns?: string[] | undefined) {
@@ -101,9 +91,9 @@ export function makeTestTable(name: string, columns?: string[] | undefined) {
101
91
  id,
102
92
  SourceTable.DEFAULT_TAG,
103
93
  relId,
104
- SourceTable.DEFAULT_SCHEMA,
94
+ 'public',
105
95
  name,
106
- (columns ?? ['id']).map((column) => ({ name: column, typeOid: 25 })),
96
+ (columns ?? ['id']).map((column) => ({ name: column, type: 'VARCHAR', typeId: 25 })),
107
97
  true
108
98
  );
109
99
  }
@@ -149,3 +139,10 @@ function getFirst(batch: SyncBucketData[] | SyncBucketDataBatch[] | SyncBucketDa
149
139
  return first as SyncBucketData;
150
140
  }
151
141
  }
142
+
143
+ /**
144
+ * Replica id in the old Postgres format, for backwards-compatible tests.
145
+ */
146
+ export function rid(id: string): bson.UUID {
147
+ return getUuidReplicaIdentityBson({ id: id }, [{ name: 'id', type: 'VARCHAR', typeId: 25 }]);
148
+ }
@@ -2,8 +2,8 @@
2
2
  "extends": "../../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
4
  "rootDir": "src",
5
- "noEmit": true,
6
5
  "baseUrl": "./",
6
+ "outDir": "dist",
7
7
  "esModuleInterop": true,
8
8
  "skipLibCheck": true,
9
9
  "sourceMap": true,