@powersync/service-core 0.0.0-dev-20240725112650 → 0.0.0-dev-20240918092408

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 (331) hide show
  1. package/CHANGELOG.md +80 -2
  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 +3 -2
  21. package/dist/entry/cli-entry.js.map +1 -1
  22. package/dist/entry/commands/compact-action.js +12 -8
  23. package/dist/entry/commands/compact-action.js.map +1 -1
  24. package/dist/entry/commands/migrate-action.js +4 -5
  25. package/dist/entry/commands/migrate-action.js.map +1 -1
  26. package/dist/entry/commands/teardown-action.js +2 -2
  27. package/dist/entry/commands/teardown-action.js.map +1 -1
  28. package/dist/index.d.ts +4 -2
  29. package/dist/index.js +4 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/metrics/Metrics.d.ts +2 -2
  32. package/dist/metrics/Metrics.js +5 -13
  33. package/dist/metrics/Metrics.js.map +1 -1
  34. package/dist/migrations/db/migrations/1684951997326-init.d.ts +2 -2
  35. package/dist/migrations/db/migrations/1684951997326-init.js +4 -2
  36. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
  37. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +2 -2
  38. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +4 -2
  39. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
  40. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +2 -2
  41. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +4 -2
  42. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
  43. package/dist/migrations/migrations.d.ts +8 -0
  44. package/dist/migrations/migrations.js +19 -7
  45. package/dist/migrations/migrations.js.map +1 -1
  46. package/dist/modules/AbstractModule.d.ts +26 -0
  47. package/dist/modules/AbstractModule.js +11 -0
  48. package/dist/modules/AbstractModule.js.map +1 -0
  49. package/dist/modules/ModuleManager.d.ts +11 -0
  50. package/dist/modules/ModuleManager.js +32 -0
  51. package/dist/modules/ModuleManager.js.map +1 -0
  52. package/dist/modules/modules-index.d.ts +2 -0
  53. package/dist/modules/modules-index.js +3 -0
  54. package/dist/modules/modules-index.js.map +1 -0
  55. package/dist/replication/AbstractReplicationJob.d.ts +38 -0
  56. package/dist/replication/AbstractReplicationJob.js +51 -0
  57. package/dist/replication/AbstractReplicationJob.js.map +1 -0
  58. package/dist/replication/AbstractReplicator.d.ts +53 -0
  59. package/dist/replication/AbstractReplicator.js +187 -0
  60. package/dist/replication/AbstractReplicator.js.map +1 -0
  61. package/dist/replication/ErrorRateLimiter.d.ts +0 -9
  62. package/dist/replication/ErrorRateLimiter.js +1 -42
  63. package/dist/replication/ErrorRateLimiter.js.map +1 -1
  64. package/dist/replication/ReplicationEngine.d.ts +18 -0
  65. package/dist/replication/ReplicationEngine.js +41 -0
  66. package/dist/replication/ReplicationEngine.js.map +1 -0
  67. package/dist/replication/ReplicationModule.d.ts +39 -0
  68. package/dist/replication/ReplicationModule.js +65 -0
  69. package/dist/replication/ReplicationModule.js.map +1 -0
  70. package/dist/replication/replication-index.d.ts +4 -6
  71. package/dist/replication/replication-index.js +4 -6
  72. package/dist/replication/replication-index.js.map +1 -1
  73. package/dist/routes/RouterEngine.d.ts +42 -0
  74. package/dist/routes/RouterEngine.js +80 -0
  75. package/dist/routes/RouterEngine.js.map +1 -0
  76. package/dist/routes/auth.d.ts +2 -2
  77. package/dist/routes/auth.js +11 -11
  78. package/dist/routes/auth.js.map +1 -1
  79. package/dist/routes/configure-fastify.d.ts +30 -176
  80. package/dist/routes/configure-fastify.js +10 -11
  81. package/dist/routes/configure-fastify.js.map +1 -1
  82. package/dist/routes/configure-rsocket.d.ts +3 -3
  83. package/dist/routes/configure-rsocket.js +6 -5
  84. package/dist/routes/configure-rsocket.js.map +1 -1
  85. package/dist/routes/endpoints/admin.d.ts +0 -34
  86. package/dist/routes/endpoints/admin.js +48 -89
  87. package/dist/routes/endpoints/admin.js.map +1 -1
  88. package/dist/routes/endpoints/checkpointing.d.ts +56 -16
  89. package/dist/routes/endpoints/checkpointing.js +33 -12
  90. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  91. package/dist/routes/endpoints/route-endpoints-index.d.ts +0 -1
  92. package/dist/routes/endpoints/route-endpoints-index.js +0 -1
  93. package/dist/routes/endpoints/route-endpoints-index.js.map +1 -1
  94. package/dist/routes/endpoints/socket-route.js +40 -25
  95. package/dist/routes/endpoints/socket-route.js.map +1 -1
  96. package/dist/routes/endpoints/sync-rules.d.ts +1 -1
  97. package/dist/routes/endpoints/sync-rules.js +32 -23
  98. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  99. package/dist/routes/endpoints/sync-stream.d.ts +10 -0
  100. package/dist/routes/endpoints/sync-stream.js +13 -8
  101. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  102. package/dist/routes/router-socket.d.ts +1 -0
  103. package/dist/routes/router-socket.js +2 -1
  104. package/dist/routes/router-socket.js.map +1 -1
  105. package/dist/routes/router.d.ts +6 -2
  106. package/dist/routes/router.js.map +1 -1
  107. package/dist/routes/routes-index.d.ts +1 -0
  108. package/dist/routes/routes-index.js +1 -0
  109. package/dist/routes/routes-index.js.map +1 -1
  110. package/dist/runner/teardown.js +47 -76
  111. package/dist/runner/teardown.js.map +1 -1
  112. package/dist/storage/BucketStorage.d.ts +30 -19
  113. package/dist/storage/BucketStorage.js +0 -10
  114. package/dist/storage/BucketStorage.js.map +1 -1
  115. package/dist/storage/MongoBucketStorage.d.ts +4 -4
  116. package/dist/storage/MongoBucketStorage.js +19 -24
  117. package/dist/storage/MongoBucketStorage.js.map +1 -1
  118. package/dist/storage/SourceEntity.d.ts +20 -0
  119. package/dist/storage/SourceEntity.js +2 -0
  120. package/dist/storage/SourceEntity.js.map +1 -0
  121. package/dist/storage/SourceTable.d.ts +4 -5
  122. package/dist/storage/SourceTable.js +3 -4
  123. package/dist/storage/SourceTable.js.map +1 -1
  124. package/dist/storage/StorageEngine.d.ts +24 -0
  125. package/dist/storage/StorageEngine.js +43 -0
  126. package/dist/storage/StorageEngine.js.map +1 -0
  127. package/dist/storage/StorageProvider.d.ts +21 -0
  128. package/dist/storage/StorageProvider.js +2 -0
  129. package/dist/storage/StorageProvider.js.map +1 -0
  130. package/dist/storage/mongo/MongoBucketBatch.d.ts +1 -1
  131. package/dist/storage/mongo/MongoBucketBatch.js +6 -7
  132. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
  133. package/dist/storage/mongo/MongoCompactor.js +2 -1
  134. package/dist/storage/mongo/MongoCompactor.js.map +1 -1
  135. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +2 -2
  136. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +2 -2
  137. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
  138. package/dist/storage/mongo/MongoStorageProvider.d.ts +5 -0
  139. package/dist/storage/mongo/MongoStorageProvider.js +26 -0
  140. package/dist/storage/mongo/MongoStorageProvider.js.map +1 -0
  141. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +7 -6
  142. package/dist/storage/mongo/MongoSyncBucketStorage.js +24 -15
  143. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
  144. package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
  145. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
  146. package/dist/storage/mongo/OperationBatch.d.ts +7 -3
  147. package/dist/storage/mongo/OperationBatch.js +16 -7
  148. package/dist/storage/mongo/OperationBatch.js.map +1 -1
  149. package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
  150. package/dist/storage/mongo/PersistedBatch.js +2 -2
  151. package/dist/storage/mongo/PersistedBatch.js.map +1 -1
  152. package/dist/storage/mongo/models.d.ts +13 -4
  153. package/dist/storage/mongo/models.js.map +1 -1
  154. package/dist/storage/mongo/util.d.ts +12 -1
  155. package/dist/storage/mongo/util.js +50 -2
  156. package/dist/storage/mongo/util.js.map +1 -1
  157. package/dist/storage/storage-index.d.ts +5 -2
  158. package/dist/storage/storage-index.js +5 -2
  159. package/dist/storage/storage-index.js.map +1 -1
  160. package/dist/sync/sync.d.ts +2 -1
  161. package/dist/sync/sync.js +36 -10
  162. package/dist/sync/sync.js.map +1 -1
  163. package/dist/sync/util.js.map +1 -1
  164. package/dist/system/ServiceContext.d.ts +37 -0
  165. package/dist/system/ServiceContext.js +48 -0
  166. package/dist/system/ServiceContext.js.map +1 -0
  167. package/dist/system/system-index.d.ts +1 -1
  168. package/dist/system/system-index.js +1 -1
  169. package/dist/system/system-index.js.map +1 -1
  170. package/dist/util/config/compound-config-collector.d.ts +9 -2
  171. package/dist/util/config/compound-config-collector.js +14 -23
  172. package/dist/util/config/compound-config-collector.js.map +1 -1
  173. package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
  174. package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
  175. package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
  176. package/dist/util/config/types.d.ts +6 -4
  177. package/dist/util/config/types.js.map +1 -1
  178. package/dist/util/config.d.ts +3 -4
  179. package/dist/util/config.js +5 -20
  180. package/dist/util/config.js.map +1 -1
  181. package/dist/util/protocol-types.d.ts +4 -0
  182. package/dist/util/protocol-types.js +5 -1
  183. package/dist/util/protocol-types.js.map +1 -1
  184. package/dist/util/util-index.d.ts +3 -6
  185. package/dist/util/util-index.js +3 -6
  186. package/dist/util/util-index.js.map +1 -1
  187. package/dist/util/utils.d.ts +10 -6
  188. package/dist/util/utils.js +45 -25
  189. package/dist/util/utils.js.map +1 -1
  190. package/package.json +5 -7
  191. package/src/api/RouteAPI.ts +78 -0
  192. package/src/api/api-index.ts +1 -0
  193. package/src/api/diagnostics.ts +16 -71
  194. package/src/api/schema.ts +13 -89
  195. package/src/auth/KeyStore.ts +9 -6
  196. package/src/auth/auth-index.ts +0 -1
  197. package/src/entry/cli-entry.ts +3 -2
  198. package/src/entry/commands/compact-action.ts +12 -9
  199. package/src/entry/commands/migrate-action.ts +5 -8
  200. package/src/entry/commands/teardown-action.ts +2 -2
  201. package/src/index.ts +5 -2
  202. package/src/metrics/Metrics.ts +6 -16
  203. package/src/migrations/db/migrations/1684951997326-init.ts +9 -4
  204. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -4
  205. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +6 -4
  206. package/src/migrations/migrations.ts +24 -8
  207. package/src/modules/AbstractModule.ts +37 -0
  208. package/src/modules/ModuleManager.ts +34 -0
  209. package/src/modules/modules-index.ts +2 -0
  210. package/src/replication/AbstractReplicationJob.ts +79 -0
  211. package/src/replication/AbstractReplicator.ts +227 -0
  212. package/src/replication/ErrorRateLimiter.ts +0 -44
  213. package/src/replication/ReplicationEngine.ts +43 -0
  214. package/src/replication/ReplicationModule.ts +101 -0
  215. package/src/replication/replication-index.ts +4 -6
  216. package/src/routes/RouterEngine.ts +120 -0
  217. package/src/routes/auth.ts +21 -12
  218. package/src/routes/configure-fastify.ts +13 -14
  219. package/src/routes/configure-rsocket.ts +9 -8
  220. package/src/routes/endpoints/admin.ts +74 -100
  221. package/src/routes/endpoints/checkpointing.ts +46 -12
  222. package/src/routes/endpoints/route-endpoints-index.ts +0 -1
  223. package/src/routes/endpoints/socket-route.ts +44 -27
  224. package/src/routes/endpoints/sync-rules.ts +41 -25
  225. package/src/routes/endpoints/sync-stream.ts +13 -8
  226. package/src/routes/router-socket.ts +2 -1
  227. package/src/routes/router.ts +6 -3
  228. package/src/routes/routes-index.ts +1 -0
  229. package/src/runner/teardown.ts +50 -88
  230. package/src/storage/BucketStorage.ts +38 -25
  231. package/src/storage/MongoBucketStorage.ts +23 -26
  232. package/src/storage/SourceEntity.ts +22 -0
  233. package/src/storage/SourceTable.ts +4 -6
  234. package/src/storage/StorageEngine.ts +55 -0
  235. package/src/storage/StorageProvider.ts +27 -0
  236. package/src/storage/mongo/MongoBucketBatch.ts +8 -8
  237. package/src/storage/mongo/MongoCompactor.ts +2 -1
  238. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +3 -3
  239. package/src/storage/mongo/MongoStorageProvider.ts +31 -0
  240. package/src/storage/mongo/MongoSyncBucketStorage.ts +39 -20
  241. package/src/storage/mongo/MongoSyncRulesLock.ts +1 -1
  242. package/src/storage/mongo/OperationBatch.ts +18 -11
  243. package/src/storage/mongo/PersistedBatch.ts +6 -5
  244. package/src/storage/mongo/models.ts +13 -4
  245. package/src/storage/mongo/util.ts +49 -4
  246. package/src/storage/storage-index.ts +5 -2
  247. package/src/sync/sync.ts +46 -11
  248. package/src/sync/util.ts +0 -1
  249. package/src/system/ServiceContext.ts +68 -0
  250. package/src/system/system-index.ts +1 -1
  251. package/src/util/config/compound-config-collector.ts +30 -31
  252. package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
  253. package/src/util/config/types.ts +6 -5
  254. package/src/util/config.ts +6 -23
  255. package/src/util/protocol-types.ts +6 -1
  256. package/src/util/util-index.ts +3 -6
  257. package/src/util/utils.ts +55 -39
  258. package/test/src/__snapshots__/sync.test.ts.snap +7 -7
  259. package/test/src/auth.test.ts +7 -7
  260. package/test/src/broadcast_iterable.test.ts +1 -1
  261. package/test/src/checksum_cache.test.ts +3 -3
  262. package/test/src/compacting.test.ts +26 -17
  263. package/test/src/data_storage.test.ts +258 -146
  264. package/test/src/env.ts +1 -3
  265. package/test/src/merge_iterable.test.ts +1 -6
  266. package/test/src/setup.ts +1 -1
  267. package/test/src/stream_utils.ts +42 -0
  268. package/test/src/sync.test.ts +52 -31
  269. package/test/src/util.ts +48 -51
  270. package/test/tsconfig.json +1 -1
  271. package/tsconfig.tsbuildinfo +1 -1
  272. package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
  273. package/dist/auth/SupabaseKeyCollector.js +0 -61
  274. package/dist/auth/SupabaseKeyCollector.js.map +0 -1
  275. package/dist/replication/PgRelation.d.ts +0 -16
  276. package/dist/replication/PgRelation.js +0 -26
  277. package/dist/replication/PgRelation.js.map +0 -1
  278. package/dist/replication/WalConnection.d.ts +0 -34
  279. package/dist/replication/WalConnection.js +0 -190
  280. package/dist/replication/WalConnection.js.map +0 -1
  281. package/dist/replication/WalStream.d.ts +0 -57
  282. package/dist/replication/WalStream.js +0 -515
  283. package/dist/replication/WalStream.js.map +0 -1
  284. package/dist/replication/WalStreamManager.d.ts +0 -30
  285. package/dist/replication/WalStreamManager.js +0 -198
  286. package/dist/replication/WalStreamManager.js.map +0 -1
  287. package/dist/replication/WalStreamRunner.d.ts +0 -38
  288. package/dist/replication/WalStreamRunner.js +0 -155
  289. package/dist/replication/WalStreamRunner.js.map +0 -1
  290. package/dist/replication/util.d.ts +0 -9
  291. package/dist/replication/util.js +0 -62
  292. package/dist/replication/util.js.map +0 -1
  293. package/dist/routes/endpoints/dev.d.ts +0 -312
  294. package/dist/routes/endpoints/dev.js +0 -172
  295. package/dist/routes/endpoints/dev.js.map +0 -1
  296. package/dist/system/CorePowerSyncSystem.d.ts +0 -23
  297. package/dist/system/CorePowerSyncSystem.js +0 -52
  298. package/dist/system/CorePowerSyncSystem.js.map +0 -1
  299. package/dist/util/PgManager.d.ts +0 -24
  300. package/dist/util/PgManager.js +0 -55
  301. package/dist/util/PgManager.js.map +0 -1
  302. package/dist/util/migration_lib.d.ts +0 -11
  303. package/dist/util/migration_lib.js +0 -64
  304. package/dist/util/migration_lib.js.map +0 -1
  305. package/dist/util/pgwire_utils.d.ts +0 -24
  306. package/dist/util/pgwire_utils.js +0 -117
  307. package/dist/util/pgwire_utils.js.map +0 -1
  308. package/dist/util/populate_test_data.d.ts +0 -8
  309. package/dist/util/populate_test_data.js +0 -65
  310. package/dist/util/populate_test_data.js.map +0 -1
  311. package/src/auth/SupabaseKeyCollector.ts +0 -67
  312. package/src/replication/PgRelation.ts +0 -42
  313. package/src/replication/WalConnection.ts +0 -227
  314. package/src/replication/WalStream.ts +0 -624
  315. package/src/replication/WalStreamManager.ts +0 -213
  316. package/src/replication/WalStreamRunner.ts +0 -180
  317. package/src/replication/util.ts +0 -76
  318. package/src/routes/endpoints/dev.ts +0 -199
  319. package/src/system/CorePowerSyncSystem.ts +0 -64
  320. package/src/util/PgManager.ts +0 -64
  321. package/src/util/migration_lib.ts +0 -79
  322. package/src/util/pgwire_utils.ts +0 -139
  323. package/src/util/populate_test_data.ts +0 -78
  324. package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
  325. package/test/src/large_batch.test.ts +0 -194
  326. package/test/src/pg_test.test.ts +0 -450
  327. package/test/src/schema_changes.test.ts +0 -545
  328. package/test/src/slow_tests.test.ts +0 -338
  329. package/test/src/validation.test.ts +0 -63
  330. package/test/src/wal_stream.test.ts +0 -319
  331. package/test/src/wal_stream_utils.ts +0 -156
@@ -1,8 +1,25 @@
1
+ import {
2
+ BucketDataBatchOptions,
3
+ ParseSyncRulesOptions,
4
+ PersistedSyncRulesContent,
5
+ StartBatchOptions
6
+ } from '@/storage/BucketStorage.js';
1
7
  import { RequestParameters, SqlSyncRules } from '@powersync/service-sync-rules';
2
8
  import { describe, expect, test } from 'vitest';
3
- import { BucketDataBatchOptions } from '../../src/storage/BucketStorage.js';
4
- import { getBatchData, getBatchMeta, makeTestTable, MONGO_STORAGE_FACTORY, StorageFactory } from './util.js';
5
- import { fromAsync, oneFromAsync } from './wal_stream_utils.js';
9
+ import { fromAsync, oneFromAsync } from './stream_utils.js';
10
+ import {
11
+ BATCH_OPTIONS,
12
+ getBatchData,
13
+ getBatchMeta,
14
+ makeTestTable,
15
+ MONGO_STORAGE_FACTORY,
16
+ PARSE_OPTIONS,
17
+ rid,
18
+ StorageFactory,
19
+ testRules,
20
+ ZERO_LSN
21
+ } from './util.js';
22
+ import { getUuidReplicaIdentityBson } from '@/util/util-index.js';
6
23
 
7
24
  const TEST_TABLE = makeTestTable('test', ['id']);
8
25
 
@@ -12,7 +29,7 @@ describe('store - mongodb', function () {
12
29
 
13
30
  function defineDataStorageTests(factory: StorageFactory) {
14
31
  test('save and load parameters', async () => {
15
- const sync_rules = SqlSyncRules.fromYaml(`
32
+ const sync_rules = testRules(`
16
33
  bucket_definitions:
17
34
  mybucket:
18
35
  parameters:
@@ -20,9 +37,9 @@ bucket_definitions:
20
37
  data: []
21
38
  `);
22
39
 
23
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
40
+ const storage = (await factory()).getInstance(sync_rules);
24
41
 
25
- const result = await storage.startBatch({}, async (batch) => {
42
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
26
43
  await batch.save({
27
44
  sourceTable: TEST_TABLE,
28
45
  tag: 'insert',
@@ -31,7 +48,8 @@ bucket_definitions:
31
48
  id1: 'user3',
32
49
  id2: 'user4',
33
50
  group_id: 'group2a'
34
- }
51
+ },
52
+ afterReplicaId: rid('t2')
35
53
  });
36
54
 
37
55
  await batch.save({
@@ -42,7 +60,8 @@ bucket_definitions:
42
60
  id1: 'user1',
43
61
  id2: 'user2',
44
62
  group_id: 'group1a'
45
- }
63
+ },
64
+ afterReplicaId: rid('t1')
46
65
  });
47
66
  });
48
67
 
@@ -55,34 +74,38 @@ bucket_definitions:
55
74
  });
56
75
 
57
76
  test('it should use the latest version', async () => {
58
- const sync_rules = SqlSyncRules.fromYaml(`
77
+ const sync_rules = testRules(
78
+ `
59
79
  bucket_definitions:
60
80
  mybucket:
61
81
  parameters:
62
82
  - SELECT group_id FROM test WHERE id = token_parameters.user_id
63
83
  data: []
64
- `);
84
+ `
85
+ );
65
86
 
66
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
87
+ const storage = (await factory()).getInstance(sync_rules);
67
88
 
68
- const result1 = await storage.startBatch({}, async (batch) => {
89
+ const result1 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
69
90
  await batch.save({
70
91
  sourceTable: TEST_TABLE,
71
92
  tag: 'insert',
72
93
  after: {
73
94
  id: 'user1',
74
95
  group_id: 'group1'
75
- }
96
+ },
97
+ afterReplicaId: rid('user1')
76
98
  });
77
99
  });
78
- const result2 = await storage.startBatch({}, async (batch) => {
100
+ const result2 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
79
101
  await batch.save({
80
102
  sourceTable: TEST_TABLE,
81
103
  tag: 'insert',
82
104
  after: {
83
105
  id: 'user1',
84
106
  group_id: 'group2'
85
- }
107
+ },
108
+ afterReplicaId: rid('user1')
86
109
  });
87
110
  });
88
111
 
@@ -103,17 +126,19 @@ bucket_definitions:
103
126
  });
104
127
 
105
128
  test('save and load parameters with different number types', async () => {
106
- const sync_rules = SqlSyncRules.fromYaml(`
129
+ const sync_rules = testRules(
130
+ `
107
131
  bucket_definitions:
108
132
  mybucket:
109
133
  parameters:
110
134
  - SELECT group_id FROM test WHERE n1 = token_parameters.n1 and f2 = token_parameters.f2 and f3 = token_parameters.f3
111
135
  data: []
112
- `);
136
+ `
137
+ );
113
138
 
114
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
139
+ const storage = (await factory()).getInstance(sync_rules);
115
140
 
116
- const result = await storage.startBatch({}, async (batch) => {
141
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
117
142
  await batch.save({
118
143
  sourceTable: TEST_TABLE,
119
144
  tag: 'insert',
@@ -123,7 +148,8 @@ bucket_definitions:
123
148
  n1: 314n,
124
149
  f2: 314,
125
150
  f3: 3.14
126
- }
151
+ },
152
+ afterReplicaId: rid('t1')
127
153
  });
128
154
  });
129
155
 
@@ -144,17 +170,19 @@ bucket_definitions:
144
170
  // This specific case tested here cannot happen with postgres in practice, but we still
145
171
  // test this to ensure correct deserialization.
146
172
 
147
- const sync_rules = SqlSyncRules.fromYaml(`
173
+ const sync_rules = testRules(
174
+ `
148
175
  bucket_definitions:
149
176
  mybucket:
150
177
  parameters:
151
178
  - SELECT group_id FROM test WHERE n1 = token_parameters.n1
152
179
  data: []
153
- `);
180
+ `
181
+ );
154
182
 
155
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
183
+ const storage = (await factory()).getInstance(sync_rules);
156
184
 
157
- const result = await storage.startBatch({}, async (batch) => {
185
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
158
186
  await batch.save({
159
187
  sourceTable: TEST_TABLE,
160
188
  tag: 'insert',
@@ -162,7 +190,8 @@ bucket_definitions:
162
190
  id: 't1',
163
191
  group_id: 'group1',
164
192
  n1: 1152921504606846976n // 2^60
165
- }
193
+ },
194
+ afterReplicaId: rid('t1')
166
195
  });
167
196
 
168
197
  await batch.save({
@@ -174,7 +203,8 @@ bucket_definitions:
174
203
  // Simulate a TOAST value, even though it can't happen for values like this
175
204
  // in practice.
176
205
  n1: undefined
177
- }
206
+ },
207
+ afterReplicaId: rid('t1')
178
208
  });
179
209
  });
180
210
 
@@ -187,15 +217,17 @@ bucket_definitions:
187
217
  });
188
218
 
189
219
  test('removing row', async () => {
190
- const sync_rules = SqlSyncRules.fromYaml(`
220
+ const sync_rules = testRules(
221
+ `
191
222
  bucket_definitions:
192
223
  global:
193
224
  data:
194
225
  - SELECT id, description FROM "%"
195
- `);
196
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
226
+ `
227
+ );
228
+ const storage = (await factory()).getInstance(sync_rules);
197
229
 
198
- const result = await storage.startBatch({}, async (batch) => {
230
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
199
231
  const sourceTable = TEST_TABLE;
200
232
 
201
233
  await batch.save({
@@ -204,14 +236,13 @@ bucket_definitions:
204
236
  after: {
205
237
  id: 'test1',
206
238
  description: 'test1'
207
- }
239
+ },
240
+ afterReplicaId: rid('test1')
208
241
  });
209
242
  await batch.save({
210
243
  sourceTable,
211
244
  tag: 'delete',
212
- before: {
213
- id: 'test1'
214
- }
245
+ beforeReplicaId: rid('test1')
215
246
  });
216
247
  });
217
248
 
@@ -247,25 +278,29 @@ bucket_definitions:
247
278
  test('save and load parameters with workspaceId', async () => {
248
279
  const WORKSPACE_TABLE = makeTestTable('workspace', ['id']);
249
280
 
250
- const sync_rules = SqlSyncRules.fromYaml(`
281
+ const sync_rules_content = testRules(
282
+ `
251
283
  bucket_definitions:
252
284
  by_workspace:
253
285
  parameters:
254
286
  - SELECT id as workspace_id FROM workspace WHERE
255
287
  workspace."userId" = token_parameters.user_id
256
288
  data: []
257
- `);
289
+ `
290
+ );
291
+ const sync_rules = sync_rules_content.parsed(PARSE_OPTIONS).sync_rules;
258
292
 
259
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
293
+ const storage = (await factory()).getInstance(sync_rules_content);
260
294
 
261
- const result = await storage.startBatch({}, async (batch) => {
295
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
262
296
  await batch.save({
263
297
  sourceTable: WORKSPACE_TABLE,
264
298
  tag: 'insert',
265
299
  after: {
266
300
  id: 'workspace1',
267
301
  userId: 'u1'
268
- }
302
+ },
303
+ afterReplicaId: rid('workspace1')
269
304
  });
270
305
  });
271
306
 
@@ -293,25 +328,29 @@ bucket_definitions:
293
328
  test('save and load parameters with dynamic global buckets', async () => {
294
329
  const WORKSPACE_TABLE = makeTestTable('workspace');
295
330
 
296
- const sync_rules = SqlSyncRules.fromYaml(`
331
+ const sync_rules_content = testRules(
332
+ `
297
333
  bucket_definitions:
298
334
  by_public_workspace:
299
335
  parameters:
300
336
  - SELECT id as workspace_id FROM workspace WHERE
301
337
  workspace.visibility = 'public'
302
338
  data: []
303
- `);
339
+ `
340
+ );
341
+ const sync_rules = sync_rules_content.parsed(PARSE_OPTIONS).sync_rules;
304
342
 
305
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
343
+ const storage = (await factory()).getInstance(sync_rules_content);
306
344
 
307
- const result = await storage.startBatch({}, async (batch) => {
345
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
308
346
  await batch.save({
309
347
  sourceTable: WORKSPACE_TABLE,
310
348
  tag: 'insert',
311
349
  after: {
312
350
  id: 'workspace1',
313
351
  visibility: 'public'
314
- }
352
+ },
353
+ afterReplicaId: rid('workspace1')
315
354
  });
316
355
 
317
356
  await batch.save({
@@ -320,7 +359,8 @@ bucket_definitions:
320
359
  after: {
321
360
  id: 'workspace2',
322
361
  visibility: 'private'
323
- }
362
+ },
363
+ afterReplicaId: rid('workspace2')
324
364
  });
325
365
 
326
366
  await batch.save({
@@ -329,7 +369,8 @@ bucket_definitions:
329
369
  after: {
330
370
  id: 'workspace3',
331
371
  visibility: 'public'
332
- }
372
+ },
373
+ afterReplicaId: rid('workspace3')
333
374
  });
334
375
  });
335
376
 
@@ -359,7 +400,8 @@ bucket_definitions:
359
400
  test('multiple parameter queries', async () => {
360
401
  const WORKSPACE_TABLE = makeTestTable('workspace');
361
402
 
362
- const sync_rules = SqlSyncRules.fromYaml(`
403
+ const sync_rules_content = testRules(
404
+ `
363
405
  bucket_definitions:
364
406
  by_workspace:
365
407
  parameters:
@@ -368,18 +410,21 @@ bucket_definitions:
368
410
  - SELECT id as workspace_id FROM workspace WHERE
369
411
  workspace.user_id = token_parameters.user_id
370
412
  data: []
371
- `);
413
+ `
414
+ );
415
+ const sync_rules = sync_rules_content.parsed(PARSE_OPTIONS).sync_rules;
372
416
 
373
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
417
+ const storage = (await factory()).getInstance(sync_rules_content);
374
418
 
375
- const result = await storage.startBatch({}, async (batch) => {
419
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
376
420
  await batch.save({
377
421
  sourceTable: WORKSPACE_TABLE,
378
422
  tag: 'insert',
379
423
  after: {
380
424
  id: 'workspace1',
381
425
  visibility: 'public'
382
- }
426
+ },
427
+ afterReplicaId: rid('workspace1')
383
428
  });
384
429
 
385
430
  await batch.save({
@@ -388,7 +433,8 @@ bucket_definitions:
388
433
  after: {
389
434
  id: 'workspace2',
390
435
  visibility: 'private'
391
- }
436
+ },
437
+ afterReplicaId: rid('workspace2')
392
438
  });
393
439
 
394
440
  await batch.save({
@@ -398,7 +444,8 @@ bucket_definitions:
398
444
  id: 'workspace3',
399
445
  user_id: 'u1',
400
446
  visibility: 'private'
401
- }
447
+ },
448
+ afterReplicaId: rid('workspace3')
402
449
  });
403
450
 
404
451
  await batch.save({
@@ -408,7 +455,8 @@ bucket_definitions:
408
455
  id: 'workspace4',
409
456
  user_id: 'u2',
410
457
  visibility: 'private'
411
- }
458
+ },
459
+ afterReplicaId: rid('workspace4')
412
460
  });
413
461
  });
414
462
 
@@ -445,16 +493,18 @@ bucket_definitions:
445
493
  });
446
494
 
447
495
  test('changing client ids', async () => {
448
- const sync_rules = SqlSyncRules.fromYaml(`
496
+ const sync_rules = testRules(
497
+ `
449
498
  bucket_definitions:
450
499
  global:
451
500
  data:
452
501
  - SELECT client_id as id, description FROM "%"
453
- `);
454
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
502
+ `
503
+ );
504
+ const storage = (await factory()).getInstance(sync_rules);
455
505
 
456
506
  const sourceTable = TEST_TABLE;
457
- const result = await storage.startBatch({}, async (batch) => {
507
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
458
508
  await batch.save({
459
509
  sourceTable,
460
510
  tag: 'insert',
@@ -462,7 +512,8 @@ bucket_definitions:
462
512
  id: 'test1',
463
513
  client_id: 'client1a',
464
514
  description: 'test1a'
465
- }
515
+ },
516
+ afterReplicaId: rid('test1')
466
517
  });
467
518
  await batch.save({
468
519
  sourceTable,
@@ -471,7 +522,8 @@ bucket_definitions:
471
522
  id: 'test1',
472
523
  client_id: 'client1b',
473
524
  description: 'test1b'
474
- }
525
+ },
526
+ afterReplicaId: rid('test1')
475
527
  });
476
528
 
477
529
  await batch.save({
@@ -481,7 +533,8 @@ bucket_definitions:
481
533
  id: 'test2',
482
534
  client_id: 'client2',
483
535
  description: 'test2'
484
- }
536
+ },
537
+ afterReplicaId: rid('test2')
485
538
  });
486
539
  });
487
540
  const checkpoint = result!.flushed_op;
@@ -502,15 +555,17 @@ bucket_definitions:
502
555
  });
503
556
 
504
557
  test('re-apply delete', async () => {
505
- const sync_rules = SqlSyncRules.fromYaml(`
558
+ const sync_rules = testRules(
559
+ `
506
560
  bucket_definitions:
507
561
  global:
508
562
  data:
509
563
  - SELECT id, description FROM "%"
510
- `);
511
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
564
+ `
565
+ );
566
+ const storage = (await factory()).getInstance(sync_rules);
512
567
 
513
- await storage.startBatch({}, async (batch) => {
568
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
514
569
  const sourceTable = TEST_TABLE;
515
570
 
516
571
  await batch.save({
@@ -519,31 +574,28 @@ bucket_definitions:
519
574
  after: {
520
575
  id: 'test1',
521
576
  description: 'test1'
522
- }
577
+ },
578
+ afterReplicaId: rid('test1')
523
579
  });
524
580
  });
525
581
 
526
- await storage.startBatch({}, async (batch) => {
582
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
527
583
  const sourceTable = TEST_TABLE;
528
584
 
529
585
  await batch.save({
530
586
  sourceTable,
531
587
  tag: 'delete',
532
- before: {
533
- id: 'test1'
534
- }
588
+ beforeReplicaId: rid('test1')
535
589
  });
536
590
  });
537
591
 
538
- const result = await storage.startBatch({}, async (batch) => {
592
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
539
593
  const sourceTable = TEST_TABLE;
540
594
 
541
595
  await batch.save({
542
596
  sourceTable,
543
597
  tag: 'delete',
544
- before: {
545
- id: 'test1'
546
- }
598
+ beforeReplicaId: rid('test1')
547
599
  });
548
600
  });
549
601
 
@@ -577,15 +629,17 @@ bucket_definitions:
577
629
  });
578
630
 
579
631
  test('re-apply update + delete', async () => {
580
- const sync_rules = SqlSyncRules.fromYaml(`
632
+ const sync_rules = testRules(
633
+ `
581
634
  bucket_definitions:
582
635
  global:
583
636
  data:
584
637
  - SELECT id, description FROM "%"
585
- `);
586
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
638
+ `
639
+ );
640
+ const storage = (await factory()).getInstance(sync_rules);
587
641
 
588
- await storage.startBatch({}, async (batch) => {
642
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
589
643
  const sourceTable = TEST_TABLE;
590
644
 
591
645
  await batch.save({
@@ -594,11 +648,12 @@ bucket_definitions:
594
648
  after: {
595
649
  id: 'test1',
596
650
  description: 'test1'
597
- }
651
+ },
652
+ afterReplicaId: rid('test1')
598
653
  });
599
654
  });
600
655
 
601
- await storage.startBatch({}, async (batch) => {
656
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
602
657
  const sourceTable = TEST_TABLE;
603
658
 
604
659
  await batch.save({
@@ -607,7 +662,8 @@ bucket_definitions:
607
662
  after: {
608
663
  id: 'test1',
609
664
  description: undefined
610
- }
665
+ },
666
+ afterReplicaId: rid('test1')
611
667
  });
612
668
 
613
669
  await batch.save({
@@ -616,19 +672,18 @@ bucket_definitions:
616
672
  after: {
617
673
  id: 'test1',
618
674
  description: undefined
619
- }
675
+ },
676
+ afterReplicaId: rid('test1')
620
677
  });
621
678
 
622
679
  await batch.save({
623
680
  sourceTable,
624
681
  tag: 'delete',
625
- before: {
626
- id: 'test1'
627
- }
682
+ beforeReplicaId: rid('test1')
628
683
  });
629
684
  });
630
685
 
631
- const result = await storage.startBatch({}, async (batch) => {
686
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
632
687
  const sourceTable = TEST_TABLE;
633
688
 
634
689
  await batch.save({
@@ -637,7 +692,8 @@ bucket_definitions:
637
692
  after: {
638
693
  id: 'test1',
639
694
  description: undefined
640
- }
695
+ },
696
+ afterReplicaId: rid('test1')
641
697
  });
642
698
 
643
699
  await batch.save({
@@ -646,15 +702,14 @@ bucket_definitions:
646
702
  after: {
647
703
  id: 'test1',
648
704
  description: undefined
649
- }
705
+ },
706
+ afterReplicaId: rid('test1')
650
707
  });
651
708
 
652
709
  await batch.save({
653
710
  sourceTable,
654
711
  tag: 'delete',
655
- before: {
656
- id: 'test1'
657
- }
712
+ beforeReplicaId: rid('test1')
658
713
  });
659
714
  });
660
715
 
@@ -691,17 +746,19 @@ bucket_definitions:
691
746
  });
692
747
 
693
748
  test('truncate parameters', async () => {
694
- const sync_rules = SqlSyncRules.fromYaml(`
749
+ const sync_rules = testRules(
750
+ `
695
751
  bucket_definitions:
696
752
  mybucket:
697
753
  parameters:
698
754
  - SELECT group_id FROM test WHERE id1 = token_parameters.user_id OR id2 = token_parameters.user_id
699
755
  data: []
700
- `);
756
+ `
757
+ );
701
758
 
702
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
759
+ const storage = (await factory()).getInstance(sync_rules);
703
760
 
704
- await storage.startBatch({}, async (batch) => {
761
+ await storage.startBatch(BATCH_OPTIONS, async (batch) => {
705
762
  await batch.save({
706
763
  sourceTable: TEST_TABLE,
707
764
  tag: 'insert',
@@ -710,7 +767,8 @@ bucket_definitions:
710
767
  id1: 'user3',
711
768
  id2: 'user4',
712
769
  group_id: 'group2a'
713
- }
770
+ },
771
+ afterReplicaId: rid('t2')
714
772
  });
715
773
 
716
774
  await batch.truncate([TEST_TABLE]);
@@ -731,16 +789,18 @@ bucket_definitions:
731
789
  // 1. Not getting the correct "current_data" state for each operation.
732
790
  // 2. Output order not being correct.
733
791
 
734
- const sync_rules = SqlSyncRules.fromYaml(`
792
+ const sync_rules = testRules(
793
+ `
735
794
  bucket_definitions:
736
795
  global:
737
796
  data:
738
797
  - SELECT id, description FROM "test"
739
- `);
740
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
798
+ `
799
+ );
800
+ const storage = (await factory()).getInstance(sync_rules);
741
801
 
742
802
  // Pre-setup
743
- const result1 = await storage.startBatch({}, async (batch) => {
803
+ const result1 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
744
804
  const sourceTable = TEST_TABLE;
745
805
 
746
806
  await batch.save({
@@ -749,7 +809,8 @@ bucket_definitions:
749
809
  after: {
750
810
  id: 'test1',
751
811
  description: 'test1a'
752
- }
812
+ },
813
+ afterReplicaId: rid('test1')
753
814
  });
754
815
 
755
816
  await batch.save({
@@ -758,14 +819,15 @@ bucket_definitions:
758
819
  after: {
759
820
  id: 'test2',
760
821
  description: 'test2a'
761
- }
822
+ },
823
+ afterReplicaId: rid('test2')
762
824
  });
763
825
  });
764
826
 
765
827
  const checkpoint1 = result1?.flushed_op ?? '0';
766
828
 
767
829
  // Test batch
768
- const result2 = await storage.startBatch({}, async (batch) => {
830
+ const result2 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
769
831
  const sourceTable = TEST_TABLE;
770
832
  // b
771
833
  await batch.save({
@@ -774,7 +836,8 @@ bucket_definitions:
774
836
  after: {
775
837
  id: 'test1',
776
838
  description: 'test1b'
777
- }
839
+ },
840
+ afterReplicaId: rid('test1')
778
841
  });
779
842
 
780
843
  await batch.save({
@@ -783,10 +846,12 @@ bucket_definitions:
783
846
  before: {
784
847
  id: 'test1'
785
848
  },
849
+ beforeReplicaId: rid('test1'),
786
850
  after: {
787
851
  id: 'test2',
788
852
  description: 'test2b'
789
- }
853
+ },
854
+ afterReplicaId: rid('test2')
790
855
  });
791
856
 
792
857
  await batch.save({
@@ -795,10 +860,13 @@ bucket_definitions:
795
860
  before: {
796
861
  id: 'test2'
797
862
  },
863
+ beforeReplicaId: rid('test2'),
798
864
  after: {
799
865
  id: 'test3',
800
866
  description: 'test3b'
801
- }
867
+ },
868
+
869
+ afterReplicaId: rid('test3')
802
870
  });
803
871
 
804
872
  // c
@@ -808,7 +876,8 @@ bucket_definitions:
808
876
  after: {
809
877
  id: 'test2',
810
878
  description: 'test2c'
811
- }
879
+ },
880
+ afterReplicaId: rid('test2')
812
881
  });
813
882
 
814
883
  // d
@@ -818,7 +887,8 @@ bucket_definitions:
818
887
  after: {
819
888
  id: 'test4',
820
889
  description: 'test4d'
821
- }
890
+ },
891
+ afterReplicaId: rid('test4')
822
892
  });
823
893
 
824
894
  await batch.save({
@@ -827,10 +897,12 @@ bucket_definitions:
827
897
  before: {
828
898
  id: 'test4'
829
899
  },
900
+ beforeReplicaId: rid('test4'),
830
901
  after: {
831
902
  id: 'test5',
832
903
  description: 'test5d'
833
- }
904
+ },
905
+ afterReplicaId: rid('test5')
834
906
  });
835
907
  });
836
908
 
@@ -865,31 +937,40 @@ bucket_definitions:
865
937
  });
866
938
 
867
939
  test('changed data with replica identity full', async () => {
868
- const sync_rules = SqlSyncRules.fromYaml(`
940
+ const sync_rules = testRules(
941
+ `
869
942
  bucket_definitions:
870
943
  global:
871
944
  data:
872
945
  - SELECT id, description FROM "test"
873
- `);
874
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
946
+ `
947
+ );
948
+ function rid2(id: string, description: string) {
949
+ return getUuidReplicaIdentityBson({ id, description }, [
950
+ { name: 'id', type: 'VARCHAR', typeId: 25 },
951
+ { name: 'description', type: 'VARCHAR', typeId: 25 }
952
+ ]);
953
+ }
954
+ const storage = (await factory()).getInstance(sync_rules);
875
955
 
876
956
  const sourceTable = makeTestTable('test', ['id', 'description']);
877
957
 
878
958
  // Pre-setup
879
- const result1 = await storage.startBatch({}, async (batch) => {
959
+ const result1 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
880
960
  await batch.save({
881
961
  sourceTable,
882
962
  tag: 'insert',
883
963
  after: {
884
964
  id: 'test1',
885
965
  description: 'test1a'
886
- }
966
+ },
967
+ afterReplicaId: rid2('test1', 'test1a')
887
968
  });
888
969
  });
889
970
 
890
971
  const checkpoint1 = result1?.flushed_op ?? '0';
891
972
 
892
- const result2 = await storage.startBatch({}, async (batch) => {
973
+ const result2 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
893
974
  // Unchanged, but has a before id
894
975
  await batch.save({
895
976
  sourceTable,
@@ -898,14 +979,16 @@ bucket_definitions:
898
979
  id: 'test1',
899
980
  description: 'test1a'
900
981
  },
982
+ beforeReplicaId: rid2('test1', 'test1a'),
901
983
  after: {
902
984
  id: 'test1',
903
985
  description: 'test1b'
904
- }
986
+ },
987
+ afterReplicaId: rid2('test1', 'test1b')
905
988
  });
906
989
  });
907
990
 
908
- const result3 = await storage.startBatch({}, async (batch) => {
991
+ const result3 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
909
992
  // Delete
910
993
  await batch.save({
911
994
  sourceTable,
@@ -914,6 +997,7 @@ bucket_definitions:
914
997
  id: 'test1',
915
998
  description: 'test1b'
916
999
  },
1000
+ beforeReplicaId: rid2('test1', 'test1b'),
917
1001
  after: undefined
918
1002
  });
919
1003
  });
@@ -957,31 +1041,41 @@ bucket_definitions:
957
1041
  });
958
1042
 
959
1043
  test('unchanged data with replica identity full', async () => {
960
- const sync_rules = SqlSyncRules.fromYaml(`
1044
+ const sync_rules = testRules(
1045
+ `
961
1046
  bucket_definitions:
962
1047
  global:
963
1048
  data:
964
1049
  - SELECT id, description FROM "test"
965
- `);
966
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
1050
+ `
1051
+ );
1052
+ function rid2(id: string, description: string) {
1053
+ return getUuidReplicaIdentityBson({ id, description }, [
1054
+ { name: 'id', type: 'VARCHAR', typeId: 25 },
1055
+ { name: 'description', type: 'VARCHAR', typeId: 25 }
1056
+ ]);
1057
+ }
1058
+
1059
+ const storage = (await factory()).getInstance(sync_rules);
967
1060
 
968
1061
  const sourceTable = makeTestTable('test', ['id', 'description']);
969
1062
 
970
1063
  // Pre-setup
971
- const result1 = await storage.startBatch({}, async (batch) => {
1064
+ const result1 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
972
1065
  await batch.save({
973
1066
  sourceTable,
974
1067
  tag: 'insert',
975
1068
  after: {
976
1069
  id: 'test1',
977
1070
  description: 'test1a'
978
- }
1071
+ },
1072
+ afterReplicaId: rid2('test1', 'test1a')
979
1073
  });
980
1074
  });
981
1075
 
982
1076
  const checkpoint1 = result1?.flushed_op ?? '0';
983
1077
 
984
- const result2 = await storage.startBatch({}, async (batch) => {
1078
+ const result2 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
985
1079
  // Unchanged, but has a before id
986
1080
  await batch.save({
987
1081
  sourceTable,
@@ -990,14 +1084,16 @@ bucket_definitions:
990
1084
  id: 'test1',
991
1085
  description: 'test1a'
992
1086
  },
1087
+ beforeReplicaId: rid2('test1', 'test1a'),
993
1088
  after: {
994
1089
  id: 'test1',
995
1090
  description: 'test1a'
996
- }
1091
+ },
1092
+ afterReplicaId: rid2('test1', 'test1a')
997
1093
  });
998
1094
  });
999
1095
 
1000
- const result3 = await storage.startBatch({}, async (batch) => {
1096
+ const result3 = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
1001
1097
  // Delete
1002
1098
  await batch.save({
1003
1099
  sourceTable,
@@ -1006,6 +1102,7 @@ bucket_definitions:
1006
1102
  id: 'test1',
1007
1103
  description: 'test1a'
1008
1104
  },
1105
+ beforeReplicaId: rid2('test1', 'test1a'),
1009
1106
  after: undefined
1010
1107
  });
1011
1108
  });
@@ -1046,15 +1143,17 @@ bucket_definitions:
1046
1143
  // but large enough in size to be split over multiple returned batches.
1047
1144
  // The specific batch splits is an implementation detail of the storage driver,
1048
1145
  // and the test will have to updated when other implementations are added.
1049
- const sync_rules = SqlSyncRules.fromYaml(`
1146
+ const sync_rules = testRules(
1147
+ `
1050
1148
  bucket_definitions:
1051
1149
  global:
1052
1150
  data:
1053
1151
  - SELECT id, description FROM "%"
1054
- `);
1055
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
1152
+ `
1153
+ );
1154
+ const storage = (await factory()).getInstance(sync_rules);
1056
1155
 
1057
- const result = await storage.startBatch({}, async (batch) => {
1156
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
1058
1157
  const sourceTable = TEST_TABLE;
1059
1158
 
1060
1159
  const largeDescription = '0123456789'.repeat(12_000_00);
@@ -1065,7 +1164,8 @@ bucket_definitions:
1065
1164
  after: {
1066
1165
  id: 'test1',
1067
1166
  description: 'test1'
1068
- }
1167
+ },
1168
+ afterReplicaId: rid('test1')
1069
1169
  });
1070
1170
 
1071
1171
  await batch.save({
@@ -1074,7 +1174,8 @@ bucket_definitions:
1074
1174
  after: {
1075
1175
  id: 'large1',
1076
1176
  description: largeDescription
1077
- }
1177
+ },
1178
+ afterReplicaId: rid('large1')
1078
1179
  });
1079
1180
 
1080
1181
  // Large enough to split the returned batch
@@ -1084,7 +1185,8 @@ bucket_definitions:
1084
1185
  after: {
1085
1186
  id: 'large2',
1086
1187
  description: largeDescription
1087
- }
1188
+ },
1189
+ afterReplicaId: rid('large2')
1088
1190
  });
1089
1191
 
1090
1192
  await batch.save({
@@ -1093,7 +1195,8 @@ bucket_definitions:
1093
1195
  after: {
1094
1196
  id: 'test3',
1095
1197
  description: 'test3'
1096
- }
1198
+ },
1199
+ afterReplicaId: rid('test3')
1097
1200
  });
1098
1201
  });
1099
1202
 
@@ -1138,15 +1241,17 @@ bucket_definitions:
1138
1241
  // Test syncing a batch of data that is small in count,
1139
1242
  // but large enough in size to be split over multiple returned chunks.
1140
1243
  // Similar to the above test, but splits over 1MB chunks.
1141
- const sync_rules = SqlSyncRules.fromYaml(`
1244
+ const sync_rules = testRules(
1245
+ `
1142
1246
  bucket_definitions:
1143
1247
  global:
1144
1248
  data:
1145
1249
  - SELECT id, description FROM "%"
1146
- `);
1147
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
1250
+ `
1251
+ );
1252
+ const storage = (await factory()).getInstance(sync_rules);
1148
1253
 
1149
- const result = await storage.startBatch({}, async (batch) => {
1254
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
1150
1255
  const sourceTable = TEST_TABLE;
1151
1256
 
1152
1257
  const largeDescription = '0123456789'.repeat(2_000_00);
@@ -1157,7 +1262,8 @@ bucket_definitions:
1157
1262
  after: {
1158
1263
  id: 'test1',
1159
1264
  description: 'test1'
1160
- }
1265
+ },
1266
+ afterReplicaId: rid('test1')
1161
1267
  });
1162
1268
 
1163
1269
  await batch.save({
@@ -1166,7 +1272,8 @@ bucket_definitions:
1166
1272
  after: {
1167
1273
  id: 'large1',
1168
1274
  description: largeDescription
1169
- }
1275
+ },
1276
+ afterReplicaId: rid('large1')
1170
1277
  });
1171
1278
 
1172
1279
  // Large enough to split the returned batch
@@ -1176,7 +1283,8 @@ bucket_definitions:
1176
1283
  after: {
1177
1284
  id: 'large2',
1178
1285
  description: largeDescription
1179
- }
1286
+ },
1287
+ afterReplicaId: rid('large2')
1180
1288
  });
1181
1289
 
1182
1290
  await batch.save({
@@ -1185,7 +1293,8 @@ bucket_definitions:
1185
1293
  after: {
1186
1294
  id: 'test3',
1187
1295
  description: 'test3'
1188
- }
1296
+ },
1297
+ afterReplicaId: rid('test3')
1189
1298
  });
1190
1299
  });
1191
1300
 
@@ -1227,15 +1336,17 @@ bucket_definitions:
1227
1336
 
1228
1337
  test('long batch', async () => {
1229
1338
  // Test syncing a batch of data that is limited by count.
1230
- const sync_rules = SqlSyncRules.fromYaml(`
1339
+ const sync_rules = testRules(
1340
+ `
1231
1341
  bucket_definitions:
1232
1342
  global:
1233
1343
  data:
1234
1344
  - SELECT id, description FROM "%"
1235
- `);
1236
- const storage = (await factory()).getInstance({ id: 1, sync_rules, slot_name: 'test' });
1345
+ `
1346
+ );
1347
+ const storage = (await factory()).getInstance(sync_rules);
1237
1348
 
1238
- const result = await storage.startBatch({}, async (batch) => {
1349
+ const result = await storage.startBatch(BATCH_OPTIONS, async (batch) => {
1239
1350
  const sourceTable = TEST_TABLE;
1240
1351
 
1241
1352
  for (let i = 1; i <= 6; i++) {
@@ -1245,7 +1356,8 @@ bucket_definitions:
1245
1356
  after: {
1246
1357
  id: `test${i}`,
1247
1358
  description: `test${i}`
1248
- }
1359
+ },
1360
+ afterReplicaId: `test${i}`
1249
1361
  });
1250
1362
  }
1251
1363
  });