@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
@@ -1,64 +0,0 @@
1
- import * as pgwire from '@powersync/service-jpgwire';
2
- import { LifeCycledSystem, container, logger } from '@powersync/lib-services-framework';
3
-
4
- import * as storage from '../storage/storage-index.js';
5
- import * as utils from '../util/util-index.js';
6
-
7
- export abstract class CorePowerSyncSystem extends LifeCycledSystem {
8
- abstract storage: storage.BucketStorageFactory;
9
- abstract pgwire_pool?: pgwire.PgClient;
10
- closed: boolean;
11
-
12
- protected stopHandlers: Set<() => void> = new Set();
13
-
14
- constructor(public config: utils.ResolvedPowerSyncConfig) {
15
- super();
16
- this.closed = false;
17
- }
18
-
19
- get client_keystore() {
20
- return this.config.client_keystore;
21
- }
22
-
23
- get dev_client_keystore() {
24
- return this.config.dev_client_keystore;
25
- }
26
-
27
- /**
28
- * Adds a termination handler which will call handlers registered via
29
- * [addStopHandler].
30
- * This should be called after the server is started and it's termination handler is added.
31
- * This is so that the handler is run before the server's handler, allowing streams to be interrupted on exit
32
- */
33
- addTerminationHandler() {
34
- container.terminationHandler.handleTerminationSignal(async () => {
35
- // Close open streams, so that they don't block the server from closing.
36
- // Note: This does not work well when streaming requests are queued. In that case, the server still doesn't
37
- // close in the 30-second timeout.
38
- this.closed = true;
39
- logger.info(`Closing ${this.stopHandlers.size} streams`);
40
- for (let handler of this.stopHandlers) {
41
- handler();
42
- }
43
- });
44
- }
45
-
46
- addStopHandler(handler: () => void): () => void {
47
- if (this.closed) {
48
- handler();
49
- return () => {};
50
- }
51
- this.stopHandlers.add(handler);
52
- return () => {
53
- this.stopHandlers.delete(handler);
54
- };
55
- }
56
-
57
- requirePgPool() {
58
- if (this.pgwire_pool == null) {
59
- throw new Error('No source connection configured');
60
- } else {
61
- return this.pgwire_pool!;
62
- }
63
- }
64
- }
@@ -1,64 +0,0 @@
1
- import * as pgwire from '@powersync/service-jpgwire';
2
- import { NormalizedPostgresConnection } from '@powersync/service-types';
3
-
4
- export class PgManager {
5
- /**
6
- * Do not use this for any transactions.
7
- */
8
- public readonly pool: pgwire.PgClient;
9
-
10
- private connectionPromises: Promise<pgwire.PgConnection>[] = [];
11
-
12
- constructor(public options: NormalizedPostgresConnection, public poolOptions: pgwire.PgPoolOptions) {
13
- // The pool is lazy - no connections are opened until a query is performed.
14
- this.pool = pgwire.connectPgWirePool(this.options, poolOptions);
15
- }
16
-
17
- /**
18
- * Create a new replication connection.
19
- */
20
- async replicationConnection(): Promise<pgwire.PgConnection> {
21
- const p = pgwire.connectPgWire(this.options, { type: 'replication' });
22
- this.connectionPromises.push(p);
23
- return await p;
24
- }
25
-
26
- /**
27
- * Create a new standard connection, used for initial snapshot.
28
- *
29
- * This connection must not be shared between multiple async contexts.
30
- */
31
- async snapshotConnection(): Promise<pgwire.PgConnection> {
32
- const p = pgwire.connectPgWire(this.options, { type: 'standard' });
33
- this.connectionPromises.push(p);
34
- return await p;
35
- }
36
-
37
- async end() {
38
- for (let result of await Promise.allSettled([
39
- this.pool.end(),
40
- ...this.connectionPromises.map((promise) => {
41
- return promise.then((connection) => connection.end());
42
- })
43
- ])) {
44
- // Throw the first error, if any
45
- if (result.status == 'rejected') {
46
- throw result.reason;
47
- }
48
- }
49
- }
50
-
51
- async destroy() {
52
- this.pool.destroy();
53
- for (let result of await Promise.allSettled([
54
- ...this.connectionPromises.map((promise) => {
55
- return promise.then((connection) => connection.destroy());
56
- })
57
- ])) {
58
- // Throw the first error, if any
59
- if (result.status == 'rejected') {
60
- throw result.reason;
61
- }
62
- }
63
- }
64
- }
@@ -1,79 +0,0 @@
1
- import * as pgwire from '@powersync/service-jpgwire';
2
-
3
- export type MigrationFunction = (db: pgwire.PgConnection) => Promise<void>;
4
-
5
- interface Migration {
6
- id: number;
7
- name: string;
8
- up: MigrationFunction;
9
- }
10
-
11
- // Very loosely based on https://github.com/porsager/postgres-shift/
12
- export class Migrations {
13
- private migrations: Migration[] = [];
14
-
15
- add(id: number, name: string, up: MigrationFunction) {
16
- if (this.migrations.length > 0 && this.migrations[this.migrations.length - 1].id >= id) {
17
- throw new Error('Migration ids must be strictly incrementing');
18
- }
19
- this.migrations.push({ id, up, name });
20
- }
21
-
22
- async up(db: pgwire.PgConnection) {
23
- await db.query('BEGIN');
24
- try {
25
- await this.ensureMigrationsTable(db);
26
- const current = await this.getCurrentMigration(db);
27
- let currentId = current ? current.id : 0;
28
-
29
- for (let migration of this.migrations) {
30
- if (migration.id <= currentId) {
31
- continue;
32
- }
33
- await migration.up(db);
34
-
35
- await db.query({
36
- statement: `
37
- insert into migrations (
38
- migration_id,
39
- name
40
- ) values (
41
- $1,
42
- $2
43
- )
44
- `,
45
- params: [
46
- { type: 'int4', value: migration.id },
47
- { type: 'varchar', value: migration.name }
48
- ]
49
- });
50
- }
51
-
52
- await db.query('COMMIT');
53
- } catch (e) {
54
- await db.query('ROLLBACK');
55
- throw e;
56
- }
57
- }
58
-
59
- getCurrentMigration(db: pgwire.PgConnection) {
60
- return db
61
- .query(
62
- `
63
- select migration_id as id from migrations
64
- order by migration_id desc
65
- limit 1
66
- `
67
- )
68
- .then((results) => ({ id: results.rows[0][0] as number }));
69
- }
70
-
71
- async ensureMigrationsTable(db: pgwire.PgConnection) {
72
- await db.query(`create table if not exists migrations (
73
- migration_id serial primary key,
74
- created_at timestamp with time zone not null default now(),
75
- name text
76
- )
77
- `);
78
- }
79
- }
@@ -1,139 +0,0 @@
1
- // Adapted from https://github.com/kagis/pgwire/blob/0dc927f9f8990a903f238737326e53ba1c8d094f/mod.js#L2218
2
-
3
- import * as bson from 'bson';
4
- import * as uuid from 'uuid';
5
- import * as pgwire from '@powersync/service-jpgwire';
6
- import { SqliteJsonValue, SqliteRow, ToastableSqliteRow, toSyncRulesRow } from '@powersync/service-sync-rules';
7
-
8
- import * as replication from '../replication/replication-index.js';
9
- import { logger } from '@powersync/lib-services-framework';
10
-
11
- /**
12
- * pgwire message -> SQLite row.
13
- * @param message
14
- */
15
- export function constructAfterRecord(message: pgwire.PgoutputInsert | pgwire.PgoutputUpdate): SqliteRow {
16
- const rawData = (message as any).afterRaw;
17
-
18
- const record = pgwire.decodeTuple(message.relation, rawData);
19
- return toSyncRulesRow(record);
20
- }
21
-
22
- export function hasToastedValues(row: ToastableSqliteRow) {
23
- for (let key in row) {
24
- if (typeof row[key] == 'undefined') {
25
- return true;
26
- }
27
- }
28
- return false;
29
- }
30
-
31
- export function isCompleteRow(row: ToastableSqliteRow): row is SqliteRow {
32
- return !hasToastedValues(row);
33
- }
34
-
35
- /**
36
- * pgwire message -> SQLite row.
37
- * @param message
38
- */
39
- export function constructBeforeRecord(message: pgwire.PgoutputDelete | pgwire.PgoutputUpdate): SqliteRow | undefined {
40
- const rawData = (message as any).beforeRaw;
41
- if (rawData == null) {
42
- return undefined;
43
- }
44
- const record = pgwire.decodeTuple(message.relation, rawData);
45
- return toSyncRulesRow(record);
46
- }
47
-
48
- function getRawReplicaIdentity(
49
- tuple: ToastableSqliteRow,
50
- columns: replication.ReplicationColumn[]
51
- ): Record<string, any> {
52
- let result: Record<string, any> = {};
53
- for (let column of columns) {
54
- const name = column.name;
55
- result[name] = tuple[name];
56
- }
57
- return result;
58
- }
59
- const ID_NAMESPACE = 'a396dd91-09fc-4017-a28d-3df722f651e9';
60
-
61
- export function getUuidReplicaIdentityString(
62
- tuple: ToastableSqliteRow,
63
- columns: replication.ReplicationColumn[]
64
- ): string {
65
- const rawIdentity = getRawReplicaIdentity(tuple, columns);
66
-
67
- return uuidForRow(rawIdentity);
68
- }
69
-
70
- export function uuidForRow(row: SqliteRow): string {
71
- // Important: This must not change, since it will affect how ids are generated.
72
- // Use BSON so that it's a well-defined format without encoding ambiguities.
73
- const repr = bson.serialize(row);
74
- return uuid.v5(repr, ID_NAMESPACE);
75
- }
76
-
77
- export function getUuidReplicaIdentityBson(
78
- tuple: ToastableSqliteRow,
79
- columns: replication.ReplicationColumn[]
80
- ): bson.UUID {
81
- if (columns.length == 0) {
82
- // REPLICA IDENTITY NOTHING - generate random id
83
- return new bson.UUID(uuid.v4());
84
- }
85
- const rawIdentity = getRawReplicaIdentity(tuple, columns);
86
-
87
- return uuidForRowBson(rawIdentity);
88
- }
89
-
90
- export function uuidForRowBson(row: SqliteRow): bson.UUID {
91
- // Important: This must not change, since it will affect how ids are generated.
92
- // Use BSON so that it's a well-defined format without encoding ambiguities.
93
- const repr = bson.serialize(row);
94
- const buffer = Buffer.alloc(16);
95
- return new bson.UUID(uuid.v5(repr, ID_NAMESPACE, buffer));
96
- }
97
-
98
- export function escapeIdentifier(identifier: string) {
99
- return `"${identifier.replace(/"/g, '""').replace(/\./g, '"."')}"`;
100
- }
101
-
102
- export function autoParameter(arg: SqliteJsonValue | boolean): pgwire.StatementParam {
103
- if (arg == null) {
104
- return { type: 'varchar', value: null };
105
- } else if (typeof arg == 'string') {
106
- return { type: 'varchar', value: arg };
107
- } else if (typeof arg == 'number') {
108
- if (Number.isInteger(arg)) {
109
- return { type: 'int8', value: arg };
110
- } else {
111
- return { type: 'float8', value: arg };
112
- }
113
- } else if (typeof arg == 'boolean') {
114
- return { type: 'bool', value: arg };
115
- } else if (typeof arg == 'bigint') {
116
- return { type: 'int8', value: arg };
117
- } else {
118
- throw new Error(`Unsupported query parameter: ${typeof arg}`);
119
- }
120
- }
121
-
122
- export async function retriedQuery(db: pgwire.PgClient, ...statements: pgwire.Statement[]): Promise<pgwire.PgResult>;
123
- export async function retriedQuery(db: pgwire.PgClient, query: string): Promise<pgwire.PgResult>;
124
-
125
- /**
126
- * Retry a simple query - up to 2 attempts total.
127
- */
128
- export async function retriedQuery(db: pgwire.PgClient, ...args: any[]) {
129
- for (let tries = 2; ; tries--) {
130
- try {
131
- return await db.query(...args);
132
- } catch (e) {
133
- if (tries == 1) {
134
- throw e;
135
- }
136
- logger.warn('Query error, retrying', e);
137
- }
138
- }
139
- }
@@ -1,78 +0,0 @@
1
- import * as crypto from 'crypto';
2
- import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';
3
-
4
- import { connectPgWire } from '@powersync/service-jpgwire';
5
- import { NormalizedPostgresConnection } from '@powersync/service-types';
6
-
7
- // This util is actually for tests only, but we need it compiled to JS for the service to work, so it's placed in the service.
8
-
9
- export interface PopulateDataOptions {
10
- connection: NormalizedPostgresConnection;
11
- num_transactions: number;
12
- per_transaction: number;
13
- size: number;
14
- }
15
-
16
- if (isMainThread || parentPort == null) {
17
- // Not a worker - ignore
18
- } else {
19
- try {
20
- const options = workerData as PopulateDataOptions;
21
-
22
- const result = await populateDataInner(options);
23
- parentPort.postMessage(result);
24
- process.exit(0);
25
- } catch (e) {
26
- // This is a bug, not a connection issue
27
- console.error(e);
28
- // Only closes the Worker thread
29
- process.exit(2);
30
- }
31
- }
32
-
33
- async function populateDataInner(options: PopulateDataOptions) {
34
- // Dedicated connection so we can release the memory easily
35
- const initialDb = await connectPgWire(options.connection, { type: 'standard' });
36
- const largeDescription = crypto.randomBytes(options.size / 2).toString('hex');
37
- let operation_count = 0;
38
- for (let i = 0; i < options.num_transactions; i++) {
39
- const prefix = `test${i}K`;
40
-
41
- await initialDb.query({
42
- statement: `INSERT INTO test_data(id, description, other) SELECT $1 || i, $2, 'foo' FROM generate_series(1, $3) i`,
43
- params: [
44
- { type: 'varchar', value: prefix },
45
- { type: 'varchar', value: largeDescription },
46
- { type: 'int4', value: options.per_transaction }
47
- ]
48
- });
49
- operation_count += options.per_transaction;
50
- }
51
- await initialDb.end();
52
- return operation_count;
53
- }
54
-
55
- export async function populateData(options: PopulateDataOptions) {
56
- const WORKER_TIMEOUT = 30_000;
57
-
58
- const worker = new Worker(new URL('./populate_test_data.js', import.meta.url), {
59
- workerData: options
60
- });
61
- const timeout = setTimeout(() => {
62
- // Exits with code 1 below
63
- worker.terminate();
64
- }, WORKER_TIMEOUT);
65
- try {
66
- return await new Promise<number>((resolve, reject) => {
67
- worker.on('message', resolve);
68
- worker.on('error', reject);
69
- worker.on('exit', (code) => {
70
- if (code !== 0) {
71
- reject(new Error(`Populating data failed with exit code ${code}`));
72
- }
73
- });
74
- });
75
- } finally {
76
- clearTimeout(timeout);
77
- }
78
- }
@@ -1,256 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`pg data types > schema 1`] = `
4
- [
5
- {
6
- "name": "public",
7
- "tables": [
8
- {
9
- "columns": [
10
- {
11
- "name": "id",
12
- "pg_type": "int4",
13
- "type": "integer",
14
- },
15
- {
16
- "name": "text",
17
- "pg_type": "text",
18
- "type": "text",
19
- },
20
- {
21
- "name": "uuid",
22
- "pg_type": "uuid",
23
- "type": "uuid",
24
- },
25
- {
26
- "name": "varchar",
27
- "pg_type": "varchar",
28
- "type": "character varying(255)",
29
- },
30
- {
31
- "name": "bool",
32
- "pg_type": "bool",
33
- "type": "boolean",
34
- },
35
- {
36
- "name": "bytea",
37
- "pg_type": "bytea",
38
- "type": "bytea",
39
- },
40
- {
41
- "name": "int2",
42
- "pg_type": "int2",
43
- "type": "smallint",
44
- },
45
- {
46
- "name": "int4",
47
- "pg_type": "int4",
48
- "type": "integer",
49
- },
50
- {
51
- "name": "int8",
52
- "pg_type": "int8",
53
- "type": "bigint",
54
- },
55
- {
56
- "name": "float4",
57
- "pg_type": "float4",
58
- "type": "real",
59
- },
60
- {
61
- "name": "float8",
62
- "pg_type": "float8",
63
- "type": "double precision",
64
- },
65
- {
66
- "name": "numeric",
67
- "pg_type": "numeric",
68
- "type": "numeric",
69
- },
70
- {
71
- "name": "json",
72
- "pg_type": "json",
73
- "type": "json",
74
- },
75
- {
76
- "name": "jsonb",
77
- "pg_type": "jsonb",
78
- "type": "jsonb",
79
- },
80
- {
81
- "name": "pg_lsn",
82
- "pg_type": "pg_lsn",
83
- "type": "pg_lsn",
84
- },
85
- {
86
- "name": "date",
87
- "pg_type": "date",
88
- "type": "date",
89
- },
90
- {
91
- "name": "time",
92
- "pg_type": "time",
93
- "type": "time without time zone",
94
- },
95
- {
96
- "name": "timestamp",
97
- "pg_type": "timestamp",
98
- "type": "timestamp without time zone",
99
- },
100
- {
101
- "name": "timestamptz",
102
- "pg_type": "timestamptz",
103
- "type": "timestamp with time zone",
104
- },
105
- {
106
- "name": "interval",
107
- "pg_type": "interval",
108
- "type": "interval",
109
- },
110
- {
111
- "name": "macaddr",
112
- "pg_type": "macaddr",
113
- "type": "macaddr",
114
- },
115
- {
116
- "name": "inet",
117
- "pg_type": "inet",
118
- "type": "inet",
119
- },
120
- {
121
- "name": "oid",
122
- "pg_type": "oid",
123
- "type": "oid",
124
- },
125
- ],
126
- "name": "test_data",
127
- },
128
- {
129
- "columns": [
130
- {
131
- "name": "id",
132
- "pg_type": "int4",
133
- "type": "integer",
134
- },
135
- {
136
- "name": "text",
137
- "pg_type": "text[]",
138
- "type": "text[]",
139
- },
140
- {
141
- "name": "uuid",
142
- "pg_type": "uuid[]",
143
- "type": "uuid[]",
144
- },
145
- {
146
- "name": "varchar",
147
- "pg_type": "varchar[]",
148
- "type": "character varying(255)[]",
149
- },
150
- {
151
- "name": "bool",
152
- "pg_type": "bool[]",
153
- "type": "boolean[]",
154
- },
155
- {
156
- "name": "bytea",
157
- "pg_type": "bytea[]",
158
- "type": "bytea[]",
159
- },
160
- {
161
- "name": "int2",
162
- "pg_type": "int2[]",
163
- "type": "smallint[]",
164
- },
165
- {
166
- "name": "int4",
167
- "pg_type": "int4[]",
168
- "type": "integer[]",
169
- },
170
- {
171
- "name": "int8",
172
- "pg_type": "int8[]",
173
- "type": "bigint[]",
174
- },
175
- {
176
- "name": "float4",
177
- "pg_type": "float4[]",
178
- "type": "real[]",
179
- },
180
- {
181
- "name": "float8",
182
- "pg_type": "float8[]",
183
- "type": "double precision[]",
184
- },
185
- {
186
- "name": "numeric",
187
- "pg_type": "numeric[]",
188
- "type": "numeric[]",
189
- },
190
- {
191
- "name": "json",
192
- "pg_type": "json[]",
193
- "type": "json[]",
194
- },
195
- {
196
- "name": "jsonb",
197
- "pg_type": "jsonb[]",
198
- "type": "jsonb[]",
199
- },
200
- {
201
- "name": "pg_lsn",
202
- "pg_type": "pg_lsn[]",
203
- "type": "pg_lsn[]",
204
- },
205
- {
206
- "name": "date",
207
- "pg_type": "date[]",
208
- "type": "date[]",
209
- },
210
- {
211
- "name": "time",
212
- "pg_type": "time[]",
213
- "type": "time without time zone[]",
214
- },
215
- {
216
- "name": "timestamp",
217
- "pg_type": "timestamp[]",
218
- "type": "timestamp without time zone[]",
219
- },
220
- {
221
- "name": "timestamptz",
222
- "pg_type": "timestamptz[]",
223
- "type": "timestamp with time zone[]",
224
- },
225
- {
226
- "name": "interval",
227
- "pg_type": "interval[]",
228
- "type": "interval[]",
229
- },
230
- {
231
- "name": "macaddr",
232
- "pg_type": "macaddr[]",
233
- "type": "macaddr[]",
234
- },
235
- {
236
- "name": "inet",
237
- "pg_type": "inet[]",
238
- "type": "inet[]",
239
- },
240
- {
241
- "name": "oid",
242
- "pg_type": "oid[]",
243
- "type": "oid[]",
244
- },
245
- {
246
- "name": "multidimensional",
247
- "pg_type": "text[]",
248
- "type": "text[]",
249
- },
250
- ],
251
- "name": "test_data_arrays",
252
- },
253
- ],
254
- },
255
- ]
256
- `;