@powersync/service-core 0.0.2

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 (412) hide show
  1. package/.probes/.gitkeep +0 -0
  2. package/CHANGELOG.md +13 -0
  3. package/LICENSE +67 -0
  4. package/README.md +3 -0
  5. package/dist/api/api-index.d.ts +2 -0
  6. package/dist/api/api-index.js +3 -0
  7. package/dist/api/api-index.js.map +1 -0
  8. package/dist/api/diagnostics.d.ts +21 -0
  9. package/dist/api/diagnostics.js +183 -0
  10. package/dist/api/diagnostics.js.map +1 -0
  11. package/dist/api/schema.d.ts +5 -0
  12. package/dist/api/schema.js +88 -0
  13. package/dist/api/schema.js.map +1 -0
  14. package/dist/auth/CachedKeyCollector.d.ts +46 -0
  15. package/dist/auth/CachedKeyCollector.js +116 -0
  16. package/dist/auth/CachedKeyCollector.js.map +1 -0
  17. package/dist/auth/CompoundKeyCollector.d.ts +8 -0
  18. package/dist/auth/CompoundKeyCollector.js +23 -0
  19. package/dist/auth/CompoundKeyCollector.js.map +1 -0
  20. package/dist/auth/JwtPayload.d.ts +10 -0
  21. package/dist/auth/JwtPayload.js +2 -0
  22. package/dist/auth/JwtPayload.js.map +1 -0
  23. package/dist/auth/KeyCollector.d.ts +24 -0
  24. package/dist/auth/KeyCollector.js +2 -0
  25. package/dist/auth/KeyCollector.js.map +1 -0
  26. package/dist/auth/KeySpec.d.ts +26 -0
  27. package/dist/auth/KeySpec.js +49 -0
  28. package/dist/auth/KeySpec.js.map +1 -0
  29. package/dist/auth/KeyStore.d.ts +39 -0
  30. package/dist/auth/KeyStore.js +131 -0
  31. package/dist/auth/KeyStore.js.map +1 -0
  32. package/dist/auth/LeakyBucket.d.ts +39 -0
  33. package/dist/auth/LeakyBucket.js +57 -0
  34. package/dist/auth/LeakyBucket.js.map +1 -0
  35. package/dist/auth/RemoteJWKSCollector.d.ts +24 -0
  36. package/dist/auth/RemoteJWKSCollector.js +106 -0
  37. package/dist/auth/RemoteJWKSCollector.js.map +1 -0
  38. package/dist/auth/StaticKeyCollector.d.ts +14 -0
  39. package/dist/auth/StaticKeyCollector.js +19 -0
  40. package/dist/auth/StaticKeyCollector.js.map +1 -0
  41. package/dist/auth/SupabaseKeyCollector.d.ts +22 -0
  42. package/dist/auth/SupabaseKeyCollector.js +61 -0
  43. package/dist/auth/SupabaseKeyCollector.js.map +1 -0
  44. package/dist/auth/auth-index.d.ts +10 -0
  45. package/dist/auth/auth-index.js +11 -0
  46. package/dist/auth/auth-index.js.map +1 -0
  47. package/dist/db/db-index.d.ts +1 -0
  48. package/dist/db/db-index.js +2 -0
  49. package/dist/db/db-index.js.map +1 -0
  50. package/dist/db/mongo.d.ts +29 -0
  51. package/dist/db/mongo.js +65 -0
  52. package/dist/db/mongo.js.map +1 -0
  53. package/dist/entry/cli-entry.d.ts +15 -0
  54. package/dist/entry/cli-entry.js +36 -0
  55. package/dist/entry/cli-entry.js.map +1 -0
  56. package/dist/entry/commands/config-command.d.ts +10 -0
  57. package/dist/entry/commands/config-command.js +21 -0
  58. package/dist/entry/commands/config-command.js.map +1 -0
  59. package/dist/entry/commands/migrate-action.d.ts +2 -0
  60. package/dist/entry/commands/migrate-action.js +18 -0
  61. package/dist/entry/commands/migrate-action.js.map +1 -0
  62. package/dist/entry/commands/start-action.d.ts +3 -0
  63. package/dist/entry/commands/start-action.js +15 -0
  64. package/dist/entry/commands/start-action.js.map +1 -0
  65. package/dist/entry/commands/teardown-action.d.ts +2 -0
  66. package/dist/entry/commands/teardown-action.js +17 -0
  67. package/dist/entry/commands/teardown-action.js.map +1 -0
  68. package/dist/entry/entry-index.d.ts +5 -0
  69. package/dist/entry/entry-index.js +6 -0
  70. package/dist/entry/entry-index.js.map +1 -0
  71. package/dist/index.d.ts +24 -0
  72. package/dist/index.js +26 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/metrics/metrics.d.ts +16 -0
  75. package/dist/metrics/metrics.js +139 -0
  76. package/dist/metrics/metrics.js.map +1 -0
  77. package/dist/migrations/db/migrations/1684951997326-init.d.ts +3 -0
  78. package/dist/migrations/db/migrations/1684951997326-init.js +31 -0
  79. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -0
  80. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.d.ts +2 -0
  81. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +5 -0
  82. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -0
  83. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +3 -0
  84. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +54 -0
  85. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -0
  86. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +3 -0
  87. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +27 -0
  88. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -0
  89. package/dist/migrations/db/store.d.ts +3 -0
  90. package/dist/migrations/db/store.js +10 -0
  91. package/dist/migrations/db/store.js.map +1 -0
  92. package/dist/migrations/migrations.d.ts +10 -0
  93. package/dist/migrations/migrations.js +94 -0
  94. package/dist/migrations/migrations.js.map +1 -0
  95. package/dist/replication/ErrorRateLimiter.d.ts +17 -0
  96. package/dist/replication/ErrorRateLimiter.js +42 -0
  97. package/dist/replication/ErrorRateLimiter.js.map +1 -0
  98. package/dist/replication/PgRelation.d.ts +16 -0
  99. package/dist/replication/PgRelation.js +26 -0
  100. package/dist/replication/PgRelation.js.map +1 -0
  101. package/dist/replication/WalConnection.d.ts +34 -0
  102. package/dist/replication/WalConnection.js +190 -0
  103. package/dist/replication/WalConnection.js.map +1 -0
  104. package/dist/replication/WalStream.d.ts +58 -0
  105. package/dist/replication/WalStream.js +517 -0
  106. package/dist/replication/WalStream.js.map +1 -0
  107. package/dist/replication/WalStreamManager.d.ts +30 -0
  108. package/dist/replication/WalStreamManager.js +199 -0
  109. package/dist/replication/WalStreamManager.js.map +1 -0
  110. package/dist/replication/WalStreamRunner.d.ts +38 -0
  111. package/dist/replication/WalStreamRunner.js +155 -0
  112. package/dist/replication/WalStreamRunner.js.map +1 -0
  113. package/dist/replication/replication-index.d.ts +7 -0
  114. package/dist/replication/replication-index.js +8 -0
  115. package/dist/replication/replication-index.js.map +1 -0
  116. package/dist/replication/util.d.ts +9 -0
  117. package/dist/replication/util.js +62 -0
  118. package/dist/replication/util.js.map +1 -0
  119. package/dist/routes/admin.d.ts +7 -0
  120. package/dist/routes/admin.js +192 -0
  121. package/dist/routes/admin.js.map +1 -0
  122. package/dist/routes/auth.d.ts +58 -0
  123. package/dist/routes/auth.js +182 -0
  124. package/dist/routes/auth.js.map +1 -0
  125. package/dist/routes/checkpointing.d.ts +3 -0
  126. package/dist/routes/checkpointing.js +30 -0
  127. package/dist/routes/checkpointing.js.map +1 -0
  128. package/dist/routes/dev.d.ts +6 -0
  129. package/dist/routes/dev.js +163 -0
  130. package/dist/routes/dev.js.map +1 -0
  131. package/dist/routes/route-generators.d.ts +15 -0
  132. package/dist/routes/route-generators.js +32 -0
  133. package/dist/routes/route-generators.js.map +1 -0
  134. package/dist/routes/router-socket.d.ts +10 -0
  135. package/dist/routes/router-socket.js +5 -0
  136. package/dist/routes/router-socket.js.map +1 -0
  137. package/dist/routes/router.d.ts +13 -0
  138. package/dist/routes/router.js +2 -0
  139. package/dist/routes/router.js.map +1 -0
  140. package/dist/routes/routes-index.d.ts +4 -0
  141. package/dist/routes/routes-index.js +5 -0
  142. package/dist/routes/routes-index.js.map +1 -0
  143. package/dist/routes/socket-route.d.ts +2 -0
  144. package/dist/routes/socket-route.js +119 -0
  145. package/dist/routes/socket-route.js.map +1 -0
  146. package/dist/routes/sync-rules.d.ts +6 -0
  147. package/dist/routes/sync-rules.js +182 -0
  148. package/dist/routes/sync-rules.js.map +1 -0
  149. package/dist/routes/sync-stream.d.ts +5 -0
  150. package/dist/routes/sync-stream.js +74 -0
  151. package/dist/routes/sync-stream.js.map +1 -0
  152. package/dist/runner/teardown.d.ts +2 -0
  153. package/dist/runner/teardown.js +79 -0
  154. package/dist/runner/teardown.js.map +1 -0
  155. package/dist/storage/BucketStorage.d.ts +298 -0
  156. package/dist/storage/BucketStorage.js +25 -0
  157. package/dist/storage/BucketStorage.js.map +1 -0
  158. package/dist/storage/MongoBucketStorage.d.ts +51 -0
  159. package/dist/storage/MongoBucketStorage.js +388 -0
  160. package/dist/storage/MongoBucketStorage.js.map +1 -0
  161. package/dist/storage/SourceTable.d.ts +39 -0
  162. package/dist/storage/SourceTable.js +50 -0
  163. package/dist/storage/SourceTable.js.map +1 -0
  164. package/dist/storage/mongo/MongoBucketBatch.d.ts +48 -0
  165. package/dist/storage/mongo/MongoBucketBatch.js +584 -0
  166. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -0
  167. package/dist/storage/mongo/MongoIdSequence.d.ts +12 -0
  168. package/dist/storage/mongo/MongoIdSequence.js +21 -0
  169. package/dist/storage/mongo/MongoIdSequence.js.map +1 -0
  170. package/dist/storage/mongo/MongoPersistedSyncRules.d.ts +9 -0
  171. package/dist/storage/mongo/MongoPersistedSyncRules.js +9 -0
  172. package/dist/storage/mongo/MongoPersistedSyncRules.js.map +1 -0
  173. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +20 -0
  174. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +26 -0
  175. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -0
  176. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +27 -0
  177. package/dist/storage/mongo/MongoSyncBucketStorage.js +379 -0
  178. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -0
  179. package/dist/storage/mongo/MongoSyncRulesLock.d.ts +16 -0
  180. package/dist/storage/mongo/MongoSyncRulesLock.js +65 -0
  181. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -0
  182. package/dist/storage/mongo/OperationBatch.d.ts +26 -0
  183. package/dist/storage/mongo/OperationBatch.js +101 -0
  184. package/dist/storage/mongo/OperationBatch.js.map +1 -0
  185. package/dist/storage/mongo/PersistedBatch.d.ts +42 -0
  186. package/dist/storage/mongo/PersistedBatch.js +200 -0
  187. package/dist/storage/mongo/PersistedBatch.js.map +1 -0
  188. package/dist/storage/mongo/db.d.ts +23 -0
  189. package/dist/storage/mongo/db.js +34 -0
  190. package/dist/storage/mongo/db.js.map +1 -0
  191. package/dist/storage/mongo/models.d.ts +137 -0
  192. package/dist/storage/mongo/models.js +27 -0
  193. package/dist/storage/mongo/models.js.map +1 -0
  194. package/dist/storage/mongo/util.d.ts +26 -0
  195. package/dist/storage/mongo/util.js +81 -0
  196. package/dist/storage/mongo/util.js.map +1 -0
  197. package/dist/storage/storage-index.d.ts +14 -0
  198. package/dist/storage/storage-index.js +15 -0
  199. package/dist/storage/storage-index.js.map +1 -0
  200. package/dist/sync/BroadcastIterable.d.ts +38 -0
  201. package/dist/sync/BroadcastIterable.js +153 -0
  202. package/dist/sync/BroadcastIterable.js.map +1 -0
  203. package/dist/sync/LastValueSink.d.ts +25 -0
  204. package/dist/sync/LastValueSink.js +84 -0
  205. package/dist/sync/LastValueSink.js.map +1 -0
  206. package/dist/sync/merge.d.ts +39 -0
  207. package/dist/sync/merge.js +175 -0
  208. package/dist/sync/merge.js.map +1 -0
  209. package/dist/sync/safeRace.d.ts +1 -0
  210. package/dist/sync/safeRace.js +91 -0
  211. package/dist/sync/safeRace.js.map +1 -0
  212. package/dist/sync/sync-index.d.ts +6 -0
  213. package/dist/sync/sync-index.js +7 -0
  214. package/dist/sync/sync-index.js.map +1 -0
  215. package/dist/sync/sync.d.ts +18 -0
  216. package/dist/sync/sync.js +248 -0
  217. package/dist/sync/sync.js.map +1 -0
  218. package/dist/sync/util.d.ts +26 -0
  219. package/dist/sync/util.js +73 -0
  220. package/dist/sync/util.js.map +1 -0
  221. package/dist/system/CorePowerSyncSystem.d.ts +18 -0
  222. package/dist/system/CorePowerSyncSystem.js +28 -0
  223. package/dist/system/CorePowerSyncSystem.js.map +1 -0
  224. package/dist/util/Mutex.d.ts +47 -0
  225. package/dist/util/Mutex.js +132 -0
  226. package/dist/util/Mutex.js.map +1 -0
  227. package/dist/util/PgManager.d.ts +24 -0
  228. package/dist/util/PgManager.js +55 -0
  229. package/dist/util/PgManager.js.map +1 -0
  230. package/dist/util/alerting.d.ts +4 -0
  231. package/dist/util/alerting.js +14 -0
  232. package/dist/util/alerting.js.map +1 -0
  233. package/dist/util/config/collectors/config-collector.d.ts +29 -0
  234. package/dist/util/config/collectors/config-collector.js +116 -0
  235. package/dist/util/config/collectors/config-collector.js.map +1 -0
  236. package/dist/util/config/collectors/impl/base64-config-collector.d.ts +6 -0
  237. package/dist/util/config/collectors/impl/base64-config-collector.js +15 -0
  238. package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -0
  239. package/dist/util/config/collectors/impl/fallback-config-collector.d.ts +11 -0
  240. package/dist/util/config/collectors/impl/fallback-config-collector.js +19 -0
  241. package/dist/util/config/collectors/impl/fallback-config-collector.js.map +1 -0
  242. package/dist/util/config/collectors/impl/filesystem-config-collector.d.ts +6 -0
  243. package/dist/util/config/collectors/impl/filesystem-config-collector.js +35 -0
  244. package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -0
  245. package/dist/util/config/compound-config-collector.d.ts +32 -0
  246. package/dist/util/config/compound-config-collector.js +126 -0
  247. package/dist/util/config/compound-config-collector.js.map +1 -0
  248. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.d.ts +7 -0
  249. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js +17 -0
  250. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -0
  251. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.d.ts +7 -0
  252. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js +21 -0
  253. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -0
  254. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.d.ts +7 -0
  255. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js +17 -0
  256. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -0
  257. package/dist/util/config/sync-rules/sync-collector.d.ts +6 -0
  258. package/dist/util/config/sync-rules/sync-collector.js +3 -0
  259. package/dist/util/config/sync-rules/sync-collector.js.map +1 -0
  260. package/dist/util/config/types.d.ts +53 -0
  261. package/dist/util/config/types.js +7 -0
  262. package/dist/util/config/types.js.map +1 -0
  263. package/dist/util/config.d.ts +7 -0
  264. package/dist/util/config.js +35 -0
  265. package/dist/util/config.js.map +1 -0
  266. package/dist/util/env.d.ts +10 -0
  267. package/dist/util/env.js +25 -0
  268. package/dist/util/env.js.map +1 -0
  269. package/dist/util/memory-tracking.d.ts +7 -0
  270. package/dist/util/memory-tracking.js +58 -0
  271. package/dist/util/memory-tracking.js.map +1 -0
  272. package/dist/util/migration_lib.d.ts +11 -0
  273. package/dist/util/migration_lib.js +64 -0
  274. package/dist/util/migration_lib.js.map +1 -0
  275. package/dist/util/pgwire_utils.d.ts +24 -0
  276. package/dist/util/pgwire_utils.js +117 -0
  277. package/dist/util/pgwire_utils.js.map +1 -0
  278. package/dist/util/populate_test_data.d.ts +8 -0
  279. package/dist/util/populate_test_data.js +65 -0
  280. package/dist/util/populate_test_data.js.map +1 -0
  281. package/dist/util/protocol-types.d.ts +178 -0
  282. package/dist/util/protocol-types.js +38 -0
  283. package/dist/util/protocol-types.js.map +1 -0
  284. package/dist/util/secs.d.ts +2 -0
  285. package/dist/util/secs.js +49 -0
  286. package/dist/util/secs.js.map +1 -0
  287. package/dist/util/util-index.d.ts +22 -0
  288. package/dist/util/util-index.js +23 -0
  289. package/dist/util/util-index.js.map +1 -0
  290. package/dist/util/utils.d.ts +14 -0
  291. package/dist/util/utils.js +75 -0
  292. package/dist/util/utils.js.map +1 -0
  293. package/package.json +55 -0
  294. package/src/api/api-index.ts +2 -0
  295. package/src/api/diagnostics.ts +221 -0
  296. package/src/api/schema.ts +99 -0
  297. package/src/auth/CachedKeyCollector.ts +132 -0
  298. package/src/auth/CompoundKeyCollector.ts +33 -0
  299. package/src/auth/JwtPayload.ts +11 -0
  300. package/src/auth/KeyCollector.ts +27 -0
  301. package/src/auth/KeySpec.ts +67 -0
  302. package/src/auth/KeyStore.ts +156 -0
  303. package/src/auth/LeakyBucket.ts +66 -0
  304. package/src/auth/RemoteJWKSCollector.ts +130 -0
  305. package/src/auth/StaticKeyCollector.ts +21 -0
  306. package/src/auth/SupabaseKeyCollector.ts +67 -0
  307. package/src/auth/auth-index.ts +10 -0
  308. package/src/db/db-index.ts +1 -0
  309. package/src/db/mongo.ts +72 -0
  310. package/src/entry/cli-entry.ts +41 -0
  311. package/src/entry/commands/config-command.ts +36 -0
  312. package/src/entry/commands/migrate-action.ts +25 -0
  313. package/src/entry/commands/start-action.ts +24 -0
  314. package/src/entry/commands/teardown-action.ts +23 -0
  315. package/src/entry/entry-index.ts +5 -0
  316. package/src/index.ts +37 -0
  317. package/src/metrics/metrics.ts +169 -0
  318. package/src/migrations/db/migrations/1684951997326-init.ts +33 -0
  319. package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +5 -0
  320. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +99 -0
  321. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +32 -0
  322. package/src/migrations/db/store.ts +11 -0
  323. package/src/migrations/migrations.ts +122 -0
  324. package/src/replication/ErrorRateLimiter.ts +49 -0
  325. package/src/replication/PgRelation.ts +42 -0
  326. package/src/replication/WalConnection.ts +227 -0
  327. package/src/replication/WalStream.ts +626 -0
  328. package/src/replication/WalStreamManager.ts +214 -0
  329. package/src/replication/WalStreamRunner.ts +180 -0
  330. package/src/replication/replication-index.ts +7 -0
  331. package/src/replication/util.ts +76 -0
  332. package/src/routes/admin.ts +229 -0
  333. package/src/routes/auth.ts +209 -0
  334. package/src/routes/checkpointing.ts +38 -0
  335. package/src/routes/dev.ts +194 -0
  336. package/src/routes/route-generators.ts +39 -0
  337. package/src/routes/router-socket.ts +13 -0
  338. package/src/routes/router.ts +17 -0
  339. package/src/routes/routes-index.ts +5 -0
  340. package/src/routes/socket-route.ts +131 -0
  341. package/src/routes/sync-rules.ts +210 -0
  342. package/src/routes/sync-stream.ts +92 -0
  343. package/src/runner/teardown.ts +91 -0
  344. package/src/storage/BucketStorage.ts +386 -0
  345. package/src/storage/MongoBucketStorage.ts +493 -0
  346. package/src/storage/SourceTable.ts +60 -0
  347. package/src/storage/mongo/MongoBucketBatch.ts +756 -0
  348. package/src/storage/mongo/MongoIdSequence.ts +24 -0
  349. package/src/storage/mongo/MongoPersistedSyncRules.ts +16 -0
  350. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +47 -0
  351. package/src/storage/mongo/MongoSyncBucketStorage.ts +517 -0
  352. package/src/storage/mongo/MongoSyncRulesLock.ts +81 -0
  353. package/src/storage/mongo/OperationBatch.ts +115 -0
  354. package/src/storage/mongo/PersistedBatch.ts +245 -0
  355. package/src/storage/mongo/db.ts +69 -0
  356. package/src/storage/mongo/models.ts +157 -0
  357. package/src/storage/mongo/util.ts +88 -0
  358. package/src/storage/storage-index.ts +15 -0
  359. package/src/sync/BroadcastIterable.ts +161 -0
  360. package/src/sync/LastValueSink.ts +100 -0
  361. package/src/sync/merge.ts +200 -0
  362. package/src/sync/safeRace.ts +99 -0
  363. package/src/sync/sync-index.ts +6 -0
  364. package/src/sync/sync.ts +312 -0
  365. package/src/sync/util.ts +98 -0
  366. package/src/system/CorePowerSyncSystem.ts +43 -0
  367. package/src/util/Mutex.ts +159 -0
  368. package/src/util/PgManager.ts +64 -0
  369. package/src/util/alerting.ts +17 -0
  370. package/src/util/config/collectors/config-collector.ts +141 -0
  371. package/src/util/config/collectors/impl/base64-config-collector.ts +18 -0
  372. package/src/util/config/collectors/impl/fallback-config-collector.ts +22 -0
  373. package/src/util/config/collectors/impl/filesystem-config-collector.ts +41 -0
  374. package/src/util/config/compound-config-collector.ts +171 -0
  375. package/src/util/config/sync-rules/impl/base64-sync-rules-collector.ts +21 -0
  376. package/src/util/config/sync-rules/impl/filesystem-sync-rules-collector.ts +26 -0
  377. package/src/util/config/sync-rules/impl/inline-sync-rules-collector.ts +21 -0
  378. package/src/util/config/sync-rules/sync-collector.ts +8 -0
  379. package/src/util/config/types.ts +60 -0
  380. package/src/util/config.ts +39 -0
  381. package/src/util/env.ts +28 -0
  382. package/src/util/memory-tracking.ts +67 -0
  383. package/src/util/migration_lib.ts +79 -0
  384. package/src/util/pgwire_utils.ts +139 -0
  385. package/src/util/populate_test_data.ts +78 -0
  386. package/src/util/protocol-types.ts +223 -0
  387. package/src/util/secs.ts +54 -0
  388. package/src/util/util-index.ts +25 -0
  389. package/src/util/utils.ts +102 -0
  390. package/test/src/__snapshots__/pg_test.test.ts.snap +256 -0
  391. package/test/src/__snapshots__/sync.test.ts.snap +235 -0
  392. package/test/src/auth.test.ts +340 -0
  393. package/test/src/broadcast_iterable.test.ts +156 -0
  394. package/test/src/data_storage.test.ts +1176 -0
  395. package/test/src/env.ts +8 -0
  396. package/test/src/large_batch.test.ts +194 -0
  397. package/test/src/merge_iterable.test.ts +355 -0
  398. package/test/src/pg_test.test.ts +432 -0
  399. package/test/src/schema_changes.test.ts +545 -0
  400. package/test/src/slow_tests.test.ts +257 -0
  401. package/test/src/sql_functions.test.ts +254 -0
  402. package/test/src/sql_operators.test.ts +132 -0
  403. package/test/src/sync.test.ts +293 -0
  404. package/test/src/sync_rules.test.ts +1051 -0
  405. package/test/src/util.ts +67 -0
  406. package/test/src/validation.test.ts +63 -0
  407. package/test/src/wal_stream.test.ts +310 -0
  408. package/test/src/wal_stream_utils.ts +147 -0
  409. package/test/tsconfig.json +20 -0
  410. package/tsconfig.json +20 -0
  411. package/tsconfig.tsbuildinfo +1 -0
  412. package/vitest.config.ts +11 -0
package/src/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ // Provides global and namespaced exports
2
+
3
+ export * from './api/api-index.js';
4
+ export * as api from './api/api-index.js';
5
+
6
+ export * from './auth/auth-index.js';
7
+ export * as auth from './auth/auth-index.js';
8
+
9
+ export * from './db/db-index.js';
10
+ export * as db from './db/db-index.js';
11
+
12
+ export * from './entry/entry-index.js';
13
+ export * as entry from './entry/entry-index.js';
14
+
15
+ export * from './metrics/metrics.js';
16
+ export * as metrics from './metrics/metrics.js';
17
+
18
+ export * from './migrations/migrations.js';
19
+ export * as migrations from './migrations/migrations.js';
20
+
21
+ export * from './replication/replication-index.js';
22
+ export * as replication from './replication/replication-index.js';
23
+
24
+ export * from './routes/routes-index.js';
25
+ export * as routes from './routes/routes-index.js';
26
+
27
+ export * from './storage/storage-index.js';
28
+ export * as storage from './storage/storage-index.js';
29
+
30
+ export * from './sync/sync-index.js';
31
+ export * as sync from './sync/sync-index.js';
32
+
33
+ export * from './system/CorePowerSyncSystem.js';
34
+ export * as system from './system/CorePowerSyncSystem.js';
35
+
36
+ export * from './util/util-index.js';
37
+ export * as utils from './util/util-index.js';
@@ -0,0 +1,169 @@
1
+ import * as micro from '@journeyapps-platform/micro';
2
+ import { ValueType } from '@opentelemetry/api';
3
+ import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
4
+ import { MeterProvider } from '@opentelemetry/sdk-metrics';
5
+ import * as jpgwire from '@powersync/service-jpgwire';
6
+
7
+ import * as util from '@/util/util-index.js';
8
+ import * as storage from '@/storage/storage-index.js';
9
+ import { CorePowerSyncSystem } from '../system/CorePowerSyncSystem.js';
10
+
11
+ const meterProvider = new MeterProvider();
12
+
13
+ const port: number = util.env.METRICS_PORT ?? 0;
14
+
15
+ // Expose a pull-based metrics exporter on a prometheus endpoint.
16
+ // This is not quite the standard approach of opentelemetry or journey-micro.
17
+ // However, it avoids the need for running a separate sidecar that uses additional resources.
18
+ // We can consider switching to the standard push-based architecture if needed later.
19
+
20
+ export const exporter = new PrometheusExporter({ port: port, preventServerStart: true });
21
+ meterProvider.addMetricReader(exporter);
22
+
23
+ if (port > 0) {
24
+ exporter.startServer();
25
+ }
26
+
27
+ const meter = meterProvider.getMeter('powersync');
28
+
29
+ // 1. Data processing / month
30
+
31
+ // 1a. Postgres -> PowerSync
32
+ // Record on replication pod
33
+ export const data_replicated_bytes = meter.createCounter('powersync_data_replicated_bytes_total', {
34
+ description: 'Uncompressed size of replicated data',
35
+ unit: 'bytes',
36
+ valueType: ValueType.INT
37
+ });
38
+
39
+ // 1b. PowerSync -> clients
40
+ // Record on API pod
41
+ export const data_synced_bytes = meter.createCounter('powersync_data_synced_bytes_total', {
42
+ description: 'Uncompressed size of synced data',
43
+ unit: 'bytes',
44
+ valueType: ValueType.INT
45
+ });
46
+
47
+ // Unused for pricing
48
+ // Record on replication pod
49
+ export const rows_replicated_total = meter.createCounter('powersync_rows_replicated_total', {
50
+ description: 'Total number of replicated rows',
51
+ valueType: ValueType.INT
52
+ });
53
+
54
+ // Unused for pricing
55
+ // Record on replication pod
56
+ export const transactions_replicated_total = meter.createCounter('powersync_transactions_replicated_total', {
57
+ description: 'Total number of replicated transactions',
58
+ valueType: ValueType.INT
59
+ });
60
+
61
+ // Unused for pricing
62
+ // Record on replication pod
63
+ export const chunks_replicated_total = meter.createCounter('powersync_chunks_replicated_total', {
64
+ description: 'Total number of replication chunks',
65
+ valueType: ValueType.INT
66
+ });
67
+
68
+ // 2. Sync operations / month
69
+ // Record on API pod
70
+ export const operations_synced_total = meter.createCounter('powersync_operations_synced_total', {
71
+ description: 'Number of operations synced',
72
+ valueType: ValueType.INT
73
+ });
74
+
75
+ // 3. Data hosted on PowerSync sync service
76
+ // Record on replication pod
77
+
78
+ // 3a. Replication storage -> raw data as received from Postgres.
79
+ export const replication_storage_size_bytes = meter.createObservableGauge('powersync_replication_storage_size_bytes', {
80
+ description: 'Size of current data stored in PowerSync',
81
+ unit: 'bytes',
82
+ valueType: ValueType.INT
83
+ });
84
+
85
+ // 3b. Operations storage -> transformed history, as will be synced to clients
86
+ export const operation_storage_size_bytes = meter.createObservableGauge('powersync_operation_storage_size_bytes', {
87
+ description: 'Size of operations stored in PowerSync',
88
+ unit: 'bytes',
89
+ valueType: ValueType.INT
90
+ });
91
+
92
+ // 3c. Parameter storage -> used for parameter queries
93
+ export const parameter_storage_size_bytes = meter.createObservableGauge('powersync_parameter_storage_size_bytes', {
94
+ description: 'Size of parameter data stored in PowerSync',
95
+ unit: 'bytes',
96
+ valueType: ValueType.INT
97
+ });
98
+
99
+ // 4. Peak concurrent connections
100
+ // Record on API pod
101
+
102
+ export const concurrent_connections = meter.createUpDownCounter('powersync_concurrent_connections', {
103
+ description: 'Number of concurrent sync connections',
104
+ valueType: ValueType.INT
105
+ });
106
+
107
+ export function configureApiMetrics() {
108
+ // Initialize the metric, so that it reports a value before connections
109
+ // have been opened.
110
+ concurrent_connections.add(0);
111
+ }
112
+
113
+ export function configureReplicationMetrics(system: CorePowerSyncSystem) {
114
+ // Rate limit collection of these stats, since it may be an expensive query
115
+ const MINIMUM_INTERVAL = 60_000;
116
+
117
+ let cachedRequest: Promise<storage.StorageMetrics | null> | undefined = undefined;
118
+ let cacheTimestamp = 0;
119
+
120
+ function getMetrics() {
121
+ if (cachedRequest == null || Date.now() - cacheTimestamp > MINIMUM_INTERVAL) {
122
+ cachedRequest = system.storage.getStorageMetrics().catch((e) => {
123
+ micro.logger.error(`Failed to get storage metrics`, e);
124
+ return null;
125
+ });
126
+ cacheTimestamp = Date.now();
127
+ }
128
+ return cachedRequest;
129
+ }
130
+
131
+ operation_storage_size_bytes.addCallback(async (result) => {
132
+ const metrics = await getMetrics();
133
+ if (metrics) {
134
+ result.observe(metrics.operations_size_bytes);
135
+ }
136
+ });
137
+
138
+ parameter_storage_size_bytes.addCallback(async (result) => {
139
+ const metrics = await getMetrics();
140
+ if (metrics) {
141
+ result.observe(metrics.parameters_size_bytes);
142
+ }
143
+ });
144
+
145
+ replication_storage_size_bytes.addCallback(async (result) => {
146
+ const metrics = await getMetrics();
147
+ if (metrics) {
148
+ result.observe(metrics.replication_size_bytes);
149
+ }
150
+ });
151
+
152
+ // Record replicated bytes using global jpgwire metrics.
153
+ jpgwire.setMetricsRecorder({
154
+ addBytesRead(bytes) {
155
+ data_replicated_bytes.add(bytes);
156
+ }
157
+ });
158
+ }
159
+
160
+ export async function getMetricValueForTests(name: string): Promise<number | undefined> {
161
+ const metrics = await exporter.collect();
162
+ const scoped = metrics.resourceMetrics.scopeMetrics[0].metrics;
163
+ const metric = scoped.find((metric) => metric.descriptor.name == name);
164
+ if (metric == null) {
165
+ throw new Error(`Cannot find metric ${name}. Options: ${scoped.map((metric) => metric.descriptor.name).join(',')}`);
166
+ }
167
+ const point = metric.dataPoints[metric.dataPoints.length - 1];
168
+ return point?.value as number;
169
+ }
@@ -0,0 +1,33 @@
1
+ import * as mongo from '@/db/mongo.js';
2
+ import * as storage from '@/storage/storage-index.js';
3
+ import * as utils from '@/util/util-index.js';
4
+
5
+ export const up = async (context?: utils.MigrationContext) => {
6
+ const config = await utils.loadConfig(context?.runner_config);
7
+ const database = storage.createPowerSyncMongo(config.storage);
8
+ await mongo.waitForAuth(database.db);
9
+ try {
10
+ await database.bucket_parameters.createIndex(
11
+ {
12
+ 'key.g': 1,
13
+ lookup: 1,
14
+ _id: 1
15
+ },
16
+ { name: 'lookup1' }
17
+ );
18
+ } finally {
19
+ await database.client.close();
20
+ }
21
+ };
22
+
23
+ export const down = async (context?: utils.MigrationContext) => {
24
+ const config = await utils.loadConfig(context?.runner_config);
25
+ const database = storage.createPowerSyncMongo(config.storage);
26
+ try {
27
+ if (await database.bucket_parameters.indexExists('lookup')) {
28
+ await database.bucket_parameters.dropIndex('lookup1');
29
+ }
30
+ } finally {
31
+ await database.client.close();
32
+ }
33
+ };
@@ -0,0 +1,5 @@
1
+ export const up = async () => {
2
+ // No-op - we don't auto-create sync rules anymore
3
+ };
4
+
5
+ export const down = async () => {};
@@ -0,0 +1,99 @@
1
+ import * as mongo from '@/db/mongo.js';
2
+ import * as storage from '@/storage/storage-index.js';
3
+ import * as utils from '@/util/util-index.js';
4
+
5
+ interface LegacySyncRulesDocument extends storage.SyncRuleDocument {
6
+ /**
7
+ * True if this is the active sync rules.
8
+ * requires `snapshot_done == true` and `replicating == true`.
9
+ */
10
+ active?: boolean;
11
+
12
+ /**
13
+ * True if this sync rules should be used for replication.
14
+ *
15
+ * During reprocessing, there is one sync rules with `replicating = true, active = true`,
16
+ * and one with `replicating = true, active = false, auto_activate = true`.
17
+ */
18
+ replicating?: boolean;
19
+
20
+ /**
21
+ * True if the sync rules should set `active = true` when `snapshot_done` = true.
22
+ */
23
+ auto_activate?: boolean;
24
+ }
25
+
26
+ export const up = async (context?: utils.MigrationContext) => {
27
+ const config = await utils.loadConfig(context?.runner_config);
28
+ const db = storage.createPowerSyncMongo(config.storage);
29
+ await mongo.waitForAuth(db.db);
30
+ try {
31
+ // We keep the old flags for existing deployments still shutting down.
32
+
33
+ // 1. New sync rules: `active = false, snapshot_done = false, replicating = true, auto_activate = true`
34
+ await db.sync_rules.updateMany(
35
+ {
36
+ active: { $ne: true },
37
+ replicating: true,
38
+ auto_activate: true
39
+ },
40
+ { $set: { state: storage.SyncRuleState.PROCESSING } }
41
+ );
42
+
43
+ // 2. Snapshot done: `active = true, snapshot_done = true, replicating = true, auto_activate = false`
44
+ await db.sync_rules.updateMany(
45
+ {
46
+ active: true
47
+ },
48
+ { $set: { state: storage.SyncRuleState.ACTIVE } }
49
+ );
50
+
51
+ // 3. Stopped: `active = false, snapshot_done = true, replicating = false, auto_activate = false`.
52
+ await db.sync_rules.updateMany(
53
+ {
54
+ active: { $ne: true },
55
+ replicating: { $ne: true },
56
+ auto_activate: { $ne: true }
57
+ },
58
+ { $set: { state: storage.SyncRuleState.STOP } }
59
+ );
60
+
61
+ const remaining = await db.sync_rules.find({ state: null as any }).toArray();
62
+ if (remaining.length > 0) {
63
+ const slots = remaining.map((doc) => doc.slot_name).join(', ');
64
+ throw new Error(`Invalid state for sync rules: ${slots}`);
65
+ }
66
+ } finally {
67
+ await db.client.close();
68
+ }
69
+ };
70
+
71
+ export const down = async (context?: utils.MigrationContext) => {
72
+ const config = await utils.loadConfig(context?.runner_config);
73
+
74
+ const db = storage.createPowerSyncMongo(config.storage);
75
+ try {
76
+ await db.sync_rules.updateMany(
77
+ {
78
+ state: storage.SyncRuleState.ACTIVE
79
+ },
80
+ { $set: { active: true, replicating: true } }
81
+ );
82
+
83
+ await db.sync_rules.updateMany(
84
+ {
85
+ state: storage.SyncRuleState.PROCESSING
86
+ },
87
+ { $set: { active: false, replicating: true, auto_activate: true } }
88
+ );
89
+
90
+ await db.sync_rules.updateMany(
91
+ {
92
+ $or: [{ state: storage.SyncRuleState.STOP }, { state: storage.SyncRuleState.TERMINATED }]
93
+ },
94
+ { $set: { active: false, replicating: false, auto_activate: false } }
95
+ );
96
+ } finally {
97
+ await db.client.close();
98
+ }
99
+ };
@@ -0,0 +1,32 @@
1
+ import * as storage from '@/storage/storage-index.js';
2
+ import * as utils from '@/util/util-index.js';
3
+
4
+ export const up = async (context?: utils.MigrationContext) => {
5
+ const config = await utils.loadConfig(context?.runner_config);
6
+ const db = storage.createPowerSyncMongo(config.storage);
7
+
8
+ try {
9
+ await db.write_checkpoints.createIndex(
10
+ {
11
+ user_id: 1
12
+ },
13
+ { name: 'user_id' }
14
+ );
15
+ } finally {
16
+ await db.client.close();
17
+ }
18
+ };
19
+
20
+ export const down = async (context?: utils.MigrationContext) => {
21
+ const config = await utils.loadConfig(context?.runner_config);
22
+
23
+ const db = storage.createPowerSyncMongo(config.storage);
24
+
25
+ try {
26
+ if (await db.write_checkpoints.indexExists('user_id')) {
27
+ await db.write_checkpoints.dropIndex('user_id');
28
+ }
29
+ } finally {
30
+ await db.client.close();
31
+ }
32
+ };
@@ -0,0 +1,11 @@
1
+ import * as micro_migrate from '@journeyapps-platform/micro-migrate';
2
+ import * as utils from '@/util/util-index.js';
3
+
4
+ const config = await utils.loadConfig();
5
+
6
+ export default micro_migrate.createMongoMigrationStore({
7
+ uri: config.storage.uri,
8
+ database: config.storage.database,
9
+ username: config.storage.username,
10
+ password: config.storage.password
11
+ });
@@ -0,0 +1,122 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ import { Lock, createMongoLockManager } from '@journeyapps-platform/micro-locks';
6
+ import { Direction, createMongoMigrationStore, execute, writeLogsToStore } from '@journeyapps-platform/micro-migrate';
7
+
8
+ import * as db from '@/db/db-index.js';
9
+ import * as util from '@/util/util-index.js';
10
+
11
+ const DEFAULT_MONGO_LOCK_COLLECTION = 'locks';
12
+ const MONGO_LOCK_PROCESS = 'migrations';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+
17
+ const MIGRATIONS_DIR = path.join(__dirname, '/db/migrations');
18
+
19
+ export type MigrationOptions = {
20
+ direction: Direction;
21
+ runner_config: util.RunnerConfig;
22
+ };
23
+
24
+ /**
25
+ * Loads migrations and injects a custom context for loading the specified
26
+ * runner configuration.
27
+ */
28
+ const loadMigrations = async (dir: string, runner_config: util.RunnerConfig) => {
29
+ const files = await fs.readdir(dir);
30
+ const migrations = files.filter((file) => {
31
+ return path.extname(file) === '.js';
32
+ });
33
+
34
+ const context: util.MigrationContext = {
35
+ runner_config
36
+ };
37
+
38
+ return await Promise.all(
39
+ migrations.map(async (migration) => {
40
+ const module = await import(path.resolve(dir, migration));
41
+ return {
42
+ name: path.basename(migration).replace(path.extname(migration), ''),
43
+ up: () => module.up(context),
44
+ down: () => module.down(context)
45
+ };
46
+ })
47
+ );
48
+ };
49
+
50
+ /**
51
+ * Runs migration scripts exclusively using Mongo locks
52
+ */
53
+ export const migrate = async (options: MigrationOptions) => {
54
+ const { direction, runner_config } = options;
55
+
56
+ /**
57
+ * Try and get Mongo from config file.
58
+ * But this might not be available in Journey Micro as we use the standard Mongo.
59
+ */
60
+
61
+ const config = await util.loadConfig(runner_config);
62
+ const { storage } = config;
63
+
64
+ const client = db.mongo.createMongoClient(storage);
65
+ await client.connect();
66
+
67
+ const clientDB = client.db(storage.database);
68
+ const collection = clientDB.collection<Lock>(DEFAULT_MONGO_LOCK_COLLECTION);
69
+
70
+ const manager = createMongoLockManager(collection, {
71
+ name: MONGO_LOCK_PROCESS
72
+ });
73
+
74
+ // Only one process should execute this at a time.
75
+ const lockId = await manager.acquire();
76
+
77
+ if (!lockId) {
78
+ throw new Error('Could not acquire lock_id');
79
+ }
80
+
81
+ let isReleased = false;
82
+ const releaseLock = async () => {
83
+ if (isReleased) {
84
+ return;
85
+ }
86
+ await manager.release(lockId);
87
+ isReleased = true;
88
+ };
89
+
90
+ // For the case where the migration is terminated
91
+ process.addListener('beforeExit', releaseLock);
92
+
93
+ try {
94
+ const migrations = await loadMigrations(MIGRATIONS_DIR, runner_config);
95
+
96
+ // Use the provided config to connect to Mongo
97
+ const store = createMongoMigrationStore({
98
+ uri: storage.uri,
99
+ database: storage.database,
100
+ username: storage.username,
101
+ password: storage.password
102
+ });
103
+
104
+ const state = await store.load();
105
+
106
+ const logStream = execute({
107
+ direction: direction,
108
+ migrations,
109
+ state
110
+ });
111
+
112
+ await writeLogsToStore({
113
+ log_stream: logStream,
114
+ store,
115
+ state
116
+ });
117
+ } finally {
118
+ await releaseLock();
119
+ await client.close(true);
120
+ process.removeListener('beforeExit', releaseLock);
121
+ }
122
+ };
@@ -0,0 +1,49 @@
1
+ import { setTimeout } from 'timers/promises';
2
+
3
+ export interface ErrorRateLimiter {
4
+ waitUntilAllowed(options?: { signal?: AbortSignal }): Promise<void>;
5
+ reportError(e: any): void;
6
+
7
+ mayPing(): boolean;
8
+ }
9
+
10
+ export class DefaultErrorRateLimiter implements ErrorRateLimiter {
11
+ nextAllowed: number = Date.now();
12
+
13
+ async waitUntilAllowed(options?: { signal?: AbortSignal | undefined } | undefined): Promise<void> {
14
+ const delay = Math.max(0, this.nextAllowed - Date.now());
15
+ this.setDelay(5_000);
16
+ await setTimeout(delay, undefined, { signal: options?.signal });
17
+ }
18
+
19
+ mayPing(): boolean {
20
+ return Date.now() >= this.nextAllowed;
21
+ }
22
+
23
+ reportError(e: any): void {
24
+ const message = (e.message as string) ?? '';
25
+ if (message.includes('password authentication failed')) {
26
+ // Wait 15 minutes, to avoid triggering Supabase's fail2ban
27
+ this.setDelay(900_000);
28
+ } else if (message.includes('ENOTFOUND')) {
29
+ // DNS lookup issue - incorrect URI or deleted instance
30
+ this.setDelay(120_000);
31
+ } else if (message.includes('ECONNREFUSED')) {
32
+ // Could be fail2ban or similar
33
+ this.setDelay(120_000);
34
+ } else if (
35
+ message.includes('Unable to do postgres query on ended pool') ||
36
+ message.includes('Postgres unexpectedly closed connection')
37
+ ) {
38
+ // Connection timed out - ignore / immediately retry
39
+ // We don't explicitly set the delay to 0, since there could have been another error that
40
+ // we need to respect.
41
+ } else {
42
+ this.setDelay(30_000);
43
+ }
44
+ }
45
+
46
+ private setDelay(delay: number) {
47
+ this.nextAllowed = Math.max(this.nextAllowed, Date.now() + delay);
48
+ }
49
+ }
@@ -0,0 +1,42 @@
1
+ import { PgoutputRelation } from '@powersync/service-jpgwire';
2
+
3
+ export interface PgRelation {
4
+ readonly relationId: number;
5
+ readonly schema: string;
6
+ readonly name: string;
7
+ readonly replicaIdentity: ReplicationIdentity;
8
+ readonly replicationColumns: ReplicationColumn[];
9
+ }
10
+
11
+ export type ReplicationIdentity = 'default' | 'nothing' | 'full' | 'index';
12
+
13
+ export interface ReplicationColumn {
14
+ readonly name: string;
15
+ readonly typeOid: number;
16
+ }
17
+
18
+ export function getReplicaIdColumns(relation: PgoutputRelation): ReplicationColumn[] {
19
+ if (relation.replicaIdentity == 'nothing') {
20
+ return [];
21
+ } else {
22
+ return relation.columns.filter((c) => (c.flags & 0b1) != 0).map((c) => ({ name: c.name, typeOid: c.typeOid }));
23
+ }
24
+ }
25
+ export function getRelId(source: PgoutputRelation): number {
26
+ // Source types are wrong here
27
+ const relId = (source as any).relationOid as number;
28
+ if (relId == null || typeof relId != 'number') {
29
+ throw new Error(`No relation id!`);
30
+ }
31
+ return relId;
32
+ }
33
+
34
+ export function getPgOutputRelation(source: PgoutputRelation): PgRelation {
35
+ return {
36
+ name: source.name,
37
+ schema: source.schema,
38
+ relationId: getRelId(source),
39
+ replicaIdentity: source.replicaIdentity,
40
+ replicationColumns: getReplicaIdColumns(source)
41
+ };
42
+ }