@powersync/service-core 0.0.0-dev-20240620165206

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 (454) hide show
  1. package/.probes/.gitkeep +0 -0
  2. package/CHANGELOG.md +82 -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 +25 -0
  72. package/dist/index.js +28 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/locks/LockManager.d.ts +10 -0
  75. package/dist/locks/LockManager.js +7 -0
  76. package/dist/locks/LockManager.js.map +1 -0
  77. package/dist/locks/MongoLocks.d.ts +36 -0
  78. package/dist/locks/MongoLocks.js +81 -0
  79. package/dist/locks/MongoLocks.js.map +1 -0
  80. package/dist/locks/locks-index.d.ts +2 -0
  81. package/dist/locks/locks-index.js +3 -0
  82. package/dist/locks/locks-index.js.map +1 -0
  83. package/dist/metrics/Metrics.d.ts +30 -0
  84. package/dist/metrics/Metrics.js +176 -0
  85. package/dist/metrics/Metrics.js.map +1 -0
  86. package/dist/migrations/db/migrations/1684951997326-init.d.ts +3 -0
  87. package/dist/migrations/db/migrations/1684951997326-init.js +31 -0
  88. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -0
  89. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.d.ts +2 -0
  90. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +5 -0
  91. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -0
  92. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +3 -0
  93. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +54 -0
  94. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -0
  95. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +3 -0
  96. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +27 -0
  97. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -0
  98. package/dist/migrations/definitions.d.ts +18 -0
  99. package/dist/migrations/definitions.js +6 -0
  100. package/dist/migrations/definitions.js.map +1 -0
  101. package/dist/migrations/executor.d.ts +16 -0
  102. package/dist/migrations/executor.js +64 -0
  103. package/dist/migrations/executor.js.map +1 -0
  104. package/dist/migrations/migrations-index.d.ts +3 -0
  105. package/dist/migrations/migrations-index.js +4 -0
  106. package/dist/migrations/migrations-index.js.map +1 -0
  107. package/dist/migrations/migrations.d.ts +10 -0
  108. package/dist/migrations/migrations.js +90 -0
  109. package/dist/migrations/migrations.js.map +1 -0
  110. package/dist/migrations/store/migration-store.d.ts +11 -0
  111. package/dist/migrations/store/migration-store.js +46 -0
  112. package/dist/migrations/store/migration-store.js.map +1 -0
  113. package/dist/replication/ErrorRateLimiter.d.ts +17 -0
  114. package/dist/replication/ErrorRateLimiter.js +43 -0
  115. package/dist/replication/ErrorRateLimiter.js.map +1 -0
  116. package/dist/replication/PgRelation.d.ts +16 -0
  117. package/dist/replication/PgRelation.js +26 -0
  118. package/dist/replication/PgRelation.js.map +1 -0
  119. package/dist/replication/WalConnection.d.ts +34 -0
  120. package/dist/replication/WalConnection.js +190 -0
  121. package/dist/replication/WalConnection.js.map +1 -0
  122. package/dist/replication/WalStream.d.ts +57 -0
  123. package/dist/replication/WalStream.js +515 -0
  124. package/dist/replication/WalStream.js.map +1 -0
  125. package/dist/replication/WalStreamManager.d.ts +30 -0
  126. package/dist/replication/WalStreamManager.js +198 -0
  127. package/dist/replication/WalStreamManager.js.map +1 -0
  128. package/dist/replication/WalStreamRunner.d.ts +38 -0
  129. package/dist/replication/WalStreamRunner.js +155 -0
  130. package/dist/replication/WalStreamRunner.js.map +1 -0
  131. package/dist/replication/replication-index.d.ts +7 -0
  132. package/dist/replication/replication-index.js +8 -0
  133. package/dist/replication/replication-index.js.map +1 -0
  134. package/dist/replication/util.d.ts +9 -0
  135. package/dist/replication/util.js +62 -0
  136. package/dist/replication/util.js.map +1 -0
  137. package/dist/routes/auth.d.ts +56 -0
  138. package/dist/routes/auth.js +182 -0
  139. package/dist/routes/auth.js.map +1 -0
  140. package/dist/routes/endpoints/admin.d.ts +1011 -0
  141. package/dist/routes/endpoints/admin.js +207 -0
  142. package/dist/routes/endpoints/admin.js.map +1 -0
  143. package/dist/routes/endpoints/checkpointing.d.ts +76 -0
  144. package/dist/routes/endpoints/checkpointing.js +36 -0
  145. package/dist/routes/endpoints/checkpointing.js.map +1 -0
  146. package/dist/routes/endpoints/dev.d.ts +312 -0
  147. package/dist/routes/endpoints/dev.js +172 -0
  148. package/dist/routes/endpoints/dev.js.map +1 -0
  149. package/dist/routes/endpoints/route-endpoints-index.d.ts +6 -0
  150. package/dist/routes/endpoints/route-endpoints-index.js +7 -0
  151. package/dist/routes/endpoints/route-endpoints-index.js.map +1 -0
  152. package/dist/routes/endpoints/socket-route.d.ts +2 -0
  153. package/dist/routes/endpoints/socket-route.js +119 -0
  154. package/dist/routes/endpoints/socket-route.js.map +1 -0
  155. package/dist/routes/endpoints/sync-rules.d.ts +174 -0
  156. package/dist/routes/endpoints/sync-rules.js +202 -0
  157. package/dist/routes/endpoints/sync-rules.js.map +1 -0
  158. package/dist/routes/endpoints/sync-stream.d.ts +132 -0
  159. package/dist/routes/endpoints/sync-stream.js +83 -0
  160. package/dist/routes/endpoints/sync-stream.js.map +1 -0
  161. package/dist/routes/hooks.d.ts +10 -0
  162. package/dist/routes/hooks.js +32 -0
  163. package/dist/routes/hooks.js.map +1 -0
  164. package/dist/routes/route-register.d.ts +10 -0
  165. package/dist/routes/route-register.js +87 -0
  166. package/dist/routes/route-register.js.map +1 -0
  167. package/dist/routes/router-socket.d.ts +10 -0
  168. package/dist/routes/router-socket.js +5 -0
  169. package/dist/routes/router-socket.js.map +1 -0
  170. package/dist/routes/router.d.ts +26 -0
  171. package/dist/routes/router.js +7 -0
  172. package/dist/routes/router.js.map +1 -0
  173. package/dist/routes/routes-index.d.ts +6 -0
  174. package/dist/routes/routes-index.js +7 -0
  175. package/dist/routes/routes-index.js.map +1 -0
  176. package/dist/runner/teardown.d.ts +2 -0
  177. package/dist/runner/teardown.js +94 -0
  178. package/dist/runner/teardown.js.map +1 -0
  179. package/dist/storage/BucketStorage.d.ts +307 -0
  180. package/dist/storage/BucketStorage.js +25 -0
  181. package/dist/storage/BucketStorage.js.map +1 -0
  182. package/dist/storage/ChecksumCache.d.ts +50 -0
  183. package/dist/storage/ChecksumCache.js +234 -0
  184. package/dist/storage/ChecksumCache.js.map +1 -0
  185. package/dist/storage/MongoBucketStorage.d.ts +52 -0
  186. package/dist/storage/MongoBucketStorage.js +409 -0
  187. package/dist/storage/MongoBucketStorage.js.map +1 -0
  188. package/dist/storage/SourceTable.d.ts +39 -0
  189. package/dist/storage/SourceTable.js +50 -0
  190. package/dist/storage/SourceTable.js.map +1 -0
  191. package/dist/storage/mongo/MongoBucketBatch.d.ts +48 -0
  192. package/dist/storage/mongo/MongoBucketBatch.js +581 -0
  193. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -0
  194. package/dist/storage/mongo/MongoIdSequence.d.ts +12 -0
  195. package/dist/storage/mongo/MongoIdSequence.js +21 -0
  196. package/dist/storage/mongo/MongoIdSequence.js.map +1 -0
  197. package/dist/storage/mongo/MongoPersistedSyncRules.d.ts +9 -0
  198. package/dist/storage/mongo/MongoPersistedSyncRules.js +9 -0
  199. package/dist/storage/mongo/MongoPersistedSyncRules.js.map +1 -0
  200. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +20 -0
  201. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +26 -0
  202. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -0
  203. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +29 -0
  204. package/dist/storage/mongo/MongoSyncBucketStorage.js +391 -0
  205. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -0
  206. package/dist/storage/mongo/MongoSyncRulesLock.d.ts +16 -0
  207. package/dist/storage/mongo/MongoSyncRulesLock.js +65 -0
  208. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -0
  209. package/dist/storage/mongo/OperationBatch.d.ts +26 -0
  210. package/dist/storage/mongo/OperationBatch.js +101 -0
  211. package/dist/storage/mongo/OperationBatch.js.map +1 -0
  212. package/dist/storage/mongo/PersistedBatch.d.ts +46 -0
  213. package/dist/storage/mongo/PersistedBatch.js +213 -0
  214. package/dist/storage/mongo/PersistedBatch.js.map +1 -0
  215. package/dist/storage/mongo/db.d.ts +26 -0
  216. package/dist/storage/mongo/db.js +35 -0
  217. package/dist/storage/mongo/db.js.map +1 -0
  218. package/dist/storage/mongo/models.d.ts +140 -0
  219. package/dist/storage/mongo/models.js +27 -0
  220. package/dist/storage/mongo/models.js.map +1 -0
  221. package/dist/storage/mongo/util.d.ts +26 -0
  222. package/dist/storage/mongo/util.js +81 -0
  223. package/dist/storage/mongo/util.js.map +1 -0
  224. package/dist/storage/storage-index.d.ts +14 -0
  225. package/dist/storage/storage-index.js +15 -0
  226. package/dist/storage/storage-index.js.map +1 -0
  227. package/dist/sync/BroadcastIterable.d.ts +38 -0
  228. package/dist/sync/BroadcastIterable.js +153 -0
  229. package/dist/sync/BroadcastIterable.js.map +1 -0
  230. package/dist/sync/LastValueSink.d.ts +25 -0
  231. package/dist/sync/LastValueSink.js +84 -0
  232. package/dist/sync/LastValueSink.js.map +1 -0
  233. package/dist/sync/merge.d.ts +39 -0
  234. package/dist/sync/merge.js +175 -0
  235. package/dist/sync/merge.js.map +1 -0
  236. package/dist/sync/safeRace.d.ts +1 -0
  237. package/dist/sync/safeRace.js +91 -0
  238. package/dist/sync/safeRace.js.map +1 -0
  239. package/dist/sync/sync-index.d.ts +6 -0
  240. package/dist/sync/sync-index.js +7 -0
  241. package/dist/sync/sync-index.js.map +1 -0
  242. package/dist/sync/sync.d.ts +18 -0
  243. package/dist/sync/sync.js +259 -0
  244. package/dist/sync/sync.js.map +1 -0
  245. package/dist/sync/util.d.ts +26 -0
  246. package/dist/sync/util.js +73 -0
  247. package/dist/sync/util.js.map +1 -0
  248. package/dist/system/CorePowerSyncSystem.d.ts +23 -0
  249. package/dist/system/CorePowerSyncSystem.js +52 -0
  250. package/dist/system/CorePowerSyncSystem.js.map +1 -0
  251. package/dist/system/system-index.d.ts +1 -0
  252. package/dist/system/system-index.js +2 -0
  253. package/dist/system/system-index.js.map +1 -0
  254. package/dist/util/Mutex.d.ts +47 -0
  255. package/dist/util/Mutex.js +132 -0
  256. package/dist/util/Mutex.js.map +1 -0
  257. package/dist/util/PgManager.d.ts +24 -0
  258. package/dist/util/PgManager.js +55 -0
  259. package/dist/util/PgManager.js.map +1 -0
  260. package/dist/util/alerting.d.ts +2 -0
  261. package/dist/util/alerting.js +8 -0
  262. package/dist/util/alerting.js.map +1 -0
  263. package/dist/util/config/collectors/config-collector.d.ts +29 -0
  264. package/dist/util/config/collectors/config-collector.js +116 -0
  265. package/dist/util/config/collectors/config-collector.js.map +1 -0
  266. package/dist/util/config/collectors/impl/base64-config-collector.d.ts +6 -0
  267. package/dist/util/config/collectors/impl/base64-config-collector.js +15 -0
  268. package/dist/util/config/collectors/impl/base64-config-collector.js.map +1 -0
  269. package/dist/util/config/collectors/impl/fallback-config-collector.d.ts +11 -0
  270. package/dist/util/config/collectors/impl/fallback-config-collector.js +19 -0
  271. package/dist/util/config/collectors/impl/fallback-config-collector.js.map +1 -0
  272. package/dist/util/config/collectors/impl/filesystem-config-collector.d.ts +6 -0
  273. package/dist/util/config/collectors/impl/filesystem-config-collector.js +37 -0
  274. package/dist/util/config/collectors/impl/filesystem-config-collector.js.map +1 -0
  275. package/dist/util/config/compound-config-collector.d.ts +32 -0
  276. package/dist/util/config/compound-config-collector.js +130 -0
  277. package/dist/util/config/compound-config-collector.js.map +1 -0
  278. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.d.ts +7 -0
  279. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js +17 -0
  280. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -0
  281. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.d.ts +7 -0
  282. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js +21 -0
  283. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -0
  284. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.d.ts +7 -0
  285. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js +17 -0
  286. package/dist/util/config/sync-rules/impl/inline-sync-rules-collector.js.map +1 -0
  287. package/dist/util/config/sync-rules/sync-collector.d.ts +6 -0
  288. package/dist/util/config/sync-rules/sync-collector.js +3 -0
  289. package/dist/util/config/sync-rules/sync-collector.js.map +1 -0
  290. package/dist/util/config/types.d.ts +57 -0
  291. package/dist/util/config/types.js +7 -0
  292. package/dist/util/config/types.js.map +1 -0
  293. package/dist/util/config.d.ts +7 -0
  294. package/dist/util/config.js +35 -0
  295. package/dist/util/config.js.map +1 -0
  296. package/dist/util/env.d.ts +9 -0
  297. package/dist/util/env.js +26 -0
  298. package/dist/util/env.js.map +1 -0
  299. package/dist/util/memory-tracking.d.ts +7 -0
  300. package/dist/util/memory-tracking.js +58 -0
  301. package/dist/util/memory-tracking.js.map +1 -0
  302. package/dist/util/migration_lib.d.ts +11 -0
  303. package/dist/util/migration_lib.js +64 -0
  304. package/dist/util/migration_lib.js.map +1 -0
  305. package/dist/util/pgwire_utils.d.ts +24 -0
  306. package/dist/util/pgwire_utils.js +117 -0
  307. package/dist/util/pgwire_utils.js.map +1 -0
  308. package/dist/util/populate_test_data.d.ts +8 -0
  309. package/dist/util/populate_test_data.js +65 -0
  310. package/dist/util/populate_test_data.js.map +1 -0
  311. package/dist/util/protocol-types.d.ts +182 -0
  312. package/dist/util/protocol-types.js +42 -0
  313. package/dist/util/protocol-types.js.map +1 -0
  314. package/dist/util/secs.d.ts +2 -0
  315. package/dist/util/secs.js +49 -0
  316. package/dist/util/secs.js.map +1 -0
  317. package/dist/util/util-index.d.ts +22 -0
  318. package/dist/util/util-index.js +23 -0
  319. package/dist/util/util-index.js.map +1 -0
  320. package/dist/util/utils.d.ts +17 -0
  321. package/dist/util/utils.js +92 -0
  322. package/dist/util/utils.js.map +1 -0
  323. package/package.json +59 -0
  324. package/src/api/api-index.ts +2 -0
  325. package/src/api/diagnostics.ts +221 -0
  326. package/src/api/schema.ts +99 -0
  327. package/src/auth/CachedKeyCollector.ts +132 -0
  328. package/src/auth/CompoundKeyCollector.ts +33 -0
  329. package/src/auth/JwtPayload.ts +11 -0
  330. package/src/auth/KeyCollector.ts +27 -0
  331. package/src/auth/KeySpec.ts +67 -0
  332. package/src/auth/KeyStore.ts +156 -0
  333. package/src/auth/LeakyBucket.ts +66 -0
  334. package/src/auth/RemoteJWKSCollector.ts +130 -0
  335. package/src/auth/StaticKeyCollector.ts +21 -0
  336. package/src/auth/SupabaseKeyCollector.ts +67 -0
  337. package/src/auth/auth-index.ts +10 -0
  338. package/src/db/db-index.ts +1 -0
  339. package/src/db/mongo.ts +72 -0
  340. package/src/entry/cli-entry.ts +40 -0
  341. package/src/entry/commands/config-command.ts +36 -0
  342. package/src/entry/commands/migrate-action.ts +25 -0
  343. package/src/entry/commands/start-action.ts +24 -0
  344. package/src/entry/commands/teardown-action.ts +23 -0
  345. package/src/entry/entry-index.ts +5 -0
  346. package/src/index.ts +40 -0
  347. package/src/locks/LockManager.ts +16 -0
  348. package/src/locks/MongoLocks.ts +142 -0
  349. package/src/locks/locks-index.ts +2 -0
  350. package/src/metrics/Metrics.ts +265 -0
  351. package/src/migrations/db/migrations/1684951997326-init.ts +33 -0
  352. package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +5 -0
  353. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +99 -0
  354. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +32 -0
  355. package/src/migrations/definitions.ts +21 -0
  356. package/src/migrations/executor.ts +87 -0
  357. package/src/migrations/migrations-index.ts +3 -0
  358. package/src/migrations/migrations.ts +118 -0
  359. package/src/migrations/store/migration-store.ts +63 -0
  360. package/src/replication/ErrorRateLimiter.ts +50 -0
  361. package/src/replication/PgRelation.ts +42 -0
  362. package/src/replication/WalConnection.ts +227 -0
  363. package/src/replication/WalStream.ts +624 -0
  364. package/src/replication/WalStreamManager.ts +213 -0
  365. package/src/replication/WalStreamRunner.ts +180 -0
  366. package/src/replication/replication-index.ts +7 -0
  367. package/src/replication/util.ts +76 -0
  368. package/src/routes/auth.ts +215 -0
  369. package/src/routes/endpoints/admin.ts +237 -0
  370. package/src/routes/endpoints/checkpointing.ts +41 -0
  371. package/src/routes/endpoints/dev.ts +199 -0
  372. package/src/routes/endpoints/route-endpoints-index.ts +6 -0
  373. package/src/routes/endpoints/socket-route.ts +135 -0
  374. package/src/routes/endpoints/sync-rules.ts +227 -0
  375. package/src/routes/endpoints/sync-stream.ts +101 -0
  376. package/src/routes/hooks.ts +46 -0
  377. package/src/routes/route-register.ts +104 -0
  378. package/src/routes/router-socket.ts +13 -0
  379. package/src/routes/router.ts +46 -0
  380. package/src/routes/routes-index.ts +6 -0
  381. package/src/runner/teardown.ts +108 -0
  382. package/src/storage/BucketStorage.ts +396 -0
  383. package/src/storage/ChecksumCache.ts +294 -0
  384. package/src/storage/MongoBucketStorage.ts +519 -0
  385. package/src/storage/SourceTable.ts +60 -0
  386. package/src/storage/mongo/MongoBucketBatch.ts +752 -0
  387. package/src/storage/mongo/MongoIdSequence.ts +24 -0
  388. package/src/storage/mongo/MongoPersistedSyncRules.ts +16 -0
  389. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +47 -0
  390. package/src/storage/mongo/MongoSyncBucketStorage.ts +533 -0
  391. package/src/storage/mongo/MongoSyncRulesLock.ts +81 -0
  392. package/src/storage/mongo/OperationBatch.ts +115 -0
  393. package/src/storage/mongo/PersistedBatch.ts +268 -0
  394. package/src/storage/mongo/db.ts +73 -0
  395. package/src/storage/mongo/models.ts +162 -0
  396. package/src/storage/mongo/util.ts +88 -0
  397. package/src/storage/storage-index.ts +15 -0
  398. package/src/sync/BroadcastIterable.ts +161 -0
  399. package/src/sync/LastValueSink.ts +100 -0
  400. package/src/sync/merge.ts +200 -0
  401. package/src/sync/safeRace.ts +99 -0
  402. package/src/sync/sync-index.ts +6 -0
  403. package/src/sync/sync.ts +319 -0
  404. package/src/sync/util.ts +98 -0
  405. package/src/system/CorePowerSyncSystem.ts +64 -0
  406. package/src/system/system-index.ts +1 -0
  407. package/src/util/Mutex.ts +159 -0
  408. package/src/util/PgManager.ts +64 -0
  409. package/src/util/alerting.ts +9 -0
  410. package/src/util/config/collectors/config-collector.ts +143 -0
  411. package/src/util/config/collectors/impl/base64-config-collector.ts +18 -0
  412. package/src/util/config/collectors/impl/fallback-config-collector.ts +22 -0
  413. package/src/util/config/collectors/impl/filesystem-config-collector.ts +43 -0
  414. package/src/util/config/compound-config-collector.ts +176 -0
  415. package/src/util/config/sync-rules/impl/base64-sync-rules-collector.ts +21 -0
  416. package/src/util/config/sync-rules/impl/filesystem-sync-rules-collector.ts +26 -0
  417. package/src/util/config/sync-rules/impl/inline-sync-rules-collector.ts +21 -0
  418. package/src/util/config/sync-rules/sync-collector.ts +8 -0
  419. package/src/util/config/types.ts +66 -0
  420. package/src/util/config.ts +39 -0
  421. package/src/util/env.ts +30 -0
  422. package/src/util/memory-tracking.ts +67 -0
  423. package/src/util/migration_lib.ts +79 -0
  424. package/src/util/pgwire_utils.ts +139 -0
  425. package/src/util/populate_test_data.ts +78 -0
  426. package/src/util/protocol-types.ts +228 -0
  427. package/src/util/secs.ts +54 -0
  428. package/src/util/util-index.ts +25 -0
  429. package/src/util/utils.ts +122 -0
  430. package/test/src/__snapshots__/pg_test.test.ts.snap +256 -0
  431. package/test/src/__snapshots__/sync.test.ts.snap +247 -0
  432. package/test/src/auth.test.ts +342 -0
  433. package/test/src/broadcast_iterable.test.ts +156 -0
  434. package/test/src/checksum_cache.test.ts +436 -0
  435. package/test/src/data_storage.test.ts +1176 -0
  436. package/test/src/env.ts +8 -0
  437. package/test/src/large_batch.test.ts +194 -0
  438. package/test/src/merge_iterable.test.ts +355 -0
  439. package/test/src/pg_test.test.ts +450 -0
  440. package/test/src/schema_changes.test.ts +545 -0
  441. package/test/src/setup.ts +7 -0
  442. package/test/src/slow_tests.test.ts +257 -0
  443. package/test/src/sql_functions.test.ts +254 -0
  444. package/test/src/sql_operators.test.ts +132 -0
  445. package/test/src/sync.test.ts +293 -0
  446. package/test/src/sync_rules.test.ts +1053 -0
  447. package/test/src/util.ts +76 -0
  448. package/test/src/validation.test.ts +63 -0
  449. package/test/src/wal_stream.test.ts +319 -0
  450. package/test/src/wal_stream_utils.ts +147 -0
  451. package/test/tsconfig.json +20 -0
  452. package/tsconfig.json +31 -0
  453. package/tsconfig.tsbuildinfo +1 -0
  454. package/vitest.config.ts +9 -0
@@ -0,0 +1,519 @@
1
+ import * as mongo from 'mongodb';
2
+ import * as timers from 'timers/promises';
3
+ import { LRUCache } from 'lru-cache/min';
4
+ import { SqlSyncRules } from '@powersync/service-sync-rules';
5
+ import { wrapWithAbort } from 'ix/asynciterable/operators/withabort.js';
6
+
7
+ import * as replication from '../replication/replication-index.js';
8
+ import * as sync from '../sync/sync-index.js';
9
+ import * as util from '../util/util-index.js';
10
+ import * as locks from '../locks/locks-index.js';
11
+
12
+ import {
13
+ ActiveCheckpoint,
14
+ BucketStorageFactory,
15
+ PersistedSyncRules,
16
+ PersistedSyncRulesContent,
17
+ StorageMetrics,
18
+ UpdateSyncRulesOptions,
19
+ WriteCheckpoint
20
+ } from './BucketStorage.js';
21
+ import { MongoPersistedSyncRulesContent } from './mongo/MongoPersistedSyncRulesContent.js';
22
+ import { MongoSyncBucketStorage } from './mongo/MongoSyncBucketStorage.js';
23
+ import { PowerSyncMongo, PowerSyncMongoOptions } from './mongo/db.js';
24
+ import { SyncRuleDocument, SyncRuleState } from './mongo/models.js';
25
+ import { generateSlotName } from './mongo/util.js';
26
+ import { v4 as uuid } from 'uuid';
27
+ import { logger } from '@powersync/lib-services-framework';
28
+
29
+ export interface MongoBucketStorageOptions extends PowerSyncMongoOptions {}
30
+
31
+ export class MongoBucketStorage implements BucketStorageFactory {
32
+ private readonly client: mongo.MongoClient;
33
+ private readonly session: mongo.ClientSession;
34
+ public readonly slot_name_prefix: string;
35
+
36
+ private readonly storageCache = new LRUCache<number, MongoSyncBucketStorage>({
37
+ max: 3,
38
+ fetchMethod: async (id) => {
39
+ const doc2 = await this.db.sync_rules.findOne(
40
+ {
41
+ _id: id
42
+ },
43
+ { limit: 1 }
44
+ );
45
+ if (doc2 == null) {
46
+ // Deleted in the meantime?
47
+ return undefined;
48
+ }
49
+ const rules = new MongoPersistedSyncRulesContent(this.db, doc2);
50
+ const storage = this.getInstance(rules.parsed());
51
+ return storage;
52
+ }
53
+ });
54
+
55
+ public readonly db: PowerSyncMongo;
56
+
57
+ constructor(db: PowerSyncMongo, options: { slot_name_prefix: string }) {
58
+ this.client = db.client;
59
+ this.db = db;
60
+ this.session = this.client.startSession();
61
+ this.slot_name_prefix = options.slot_name_prefix;
62
+ }
63
+
64
+ getInstance(options: PersistedSyncRules): MongoSyncBucketStorage {
65
+ let { id, sync_rules, slot_name } = options;
66
+ if ((typeof id as any) == 'bigint') {
67
+ id = Number(id);
68
+ }
69
+ return new MongoSyncBucketStorage(this, id, sync_rules, slot_name);
70
+ }
71
+
72
+ async configureSyncRules(sync_rules: string, options?: { lock?: boolean }) {
73
+ const next = await this.getNextSyncRulesContent();
74
+ const active = await this.getActiveSyncRulesContent();
75
+
76
+ if (next?.sync_rules_content == sync_rules) {
77
+ logger.info('Sync rules from configuration unchanged');
78
+ return { updated: false };
79
+ } else if (next == null && active?.sync_rules_content == sync_rules) {
80
+ logger.info('Sync rules from configuration unchanged');
81
+ return { updated: false };
82
+ } else {
83
+ logger.info('Sync rules updated from configuration');
84
+ const persisted_sync_rules = await this.updateSyncRules({
85
+ content: sync_rules,
86
+ lock: options?.lock
87
+ });
88
+ return { updated: true, persisted_sync_rules, lock: persisted_sync_rules.current_lock ?? undefined };
89
+ }
90
+ }
91
+
92
+ async slotRemoved(slot_name: string) {
93
+ const next = await this.getNextSyncRulesContent();
94
+ const active = await this.getActiveSyncRulesContent();
95
+
96
+ // In both the below cases, we create a new sync rules instance.
97
+ // The current one will continue erroring until the next one has finished processing.
98
+ // TODO: Update
99
+ if (next != null && next.slot_name == slot_name) {
100
+ // We need to redo the "next" sync rules
101
+ await this.updateSyncRules({
102
+ content: next.sync_rules_content
103
+ });
104
+ // Pro-actively stop replicating
105
+ await this.db.sync_rules.updateOne(
106
+ {
107
+ _id: next.id,
108
+ state: SyncRuleState.PROCESSING
109
+ },
110
+ {
111
+ $set: {
112
+ state: SyncRuleState.STOP
113
+ }
114
+ }
115
+ );
116
+ } else if (next == null && active?.slot_name == slot_name) {
117
+ // Slot removed for "active" sync rules, while there is no "next" one.
118
+ await this.updateSyncRules({
119
+ content: active.sync_rules_content
120
+ });
121
+
122
+ // Pro-actively stop replicating
123
+ await this.db.sync_rules.updateOne(
124
+ {
125
+ _id: active.id,
126
+ state: SyncRuleState.ACTIVE
127
+ },
128
+ {
129
+ $set: {
130
+ state: SyncRuleState.STOP
131
+ }
132
+ }
133
+ );
134
+ }
135
+ }
136
+
137
+ async updateSyncRules(options: UpdateSyncRulesOptions): Promise<MongoPersistedSyncRulesContent> {
138
+ // Parse and validate before applying any changes
139
+ const parsed = SqlSyncRules.fromYaml(options.content);
140
+
141
+ let rules: MongoPersistedSyncRulesContent | undefined = undefined;
142
+
143
+ await this.session.withTransaction(async () => {
144
+ // Only have a single set of sync rules with PROCESSING.
145
+ await this.db.sync_rules.updateMany(
146
+ {
147
+ state: SyncRuleState.PROCESSING
148
+ },
149
+ { $set: { state: SyncRuleState.STOP } }
150
+ );
151
+
152
+ const id_doc = await this.db.op_id_sequence.findOneAndUpdate(
153
+ {
154
+ _id: 'sync_rules'
155
+ },
156
+ {
157
+ $inc: {
158
+ op_id: 1n
159
+ }
160
+ },
161
+ {
162
+ upsert: true,
163
+ returnDocument: 'after'
164
+ }
165
+ );
166
+
167
+ const id = Number(id_doc!.op_id);
168
+ const slot_name = generateSlotName(this.slot_name_prefix, id);
169
+
170
+ const doc: SyncRuleDocument = {
171
+ _id: id,
172
+ content: options.content,
173
+ last_checkpoint: null,
174
+ last_checkpoint_lsn: null,
175
+ no_checkpoint_before: null,
176
+ snapshot_done: false,
177
+ state: SyncRuleState.PROCESSING,
178
+ slot_name: slot_name,
179
+ last_checkpoint_ts: null,
180
+ last_fatal_error: null,
181
+ last_keepalive_ts: null
182
+ };
183
+ await this.db.sync_rules.insertOne(doc);
184
+ rules = new MongoPersistedSyncRulesContent(this.db, doc);
185
+ if (options.lock) {
186
+ const lock = await rules.lock();
187
+ }
188
+ });
189
+
190
+ return rules!;
191
+ }
192
+
193
+ async getActiveSyncRulesContent(): Promise<MongoPersistedSyncRulesContent | null> {
194
+ const doc = await this.db.sync_rules.findOne(
195
+ {
196
+ state: SyncRuleState.ACTIVE
197
+ },
198
+ { sort: { _id: -1 }, limit: 1 }
199
+ );
200
+ if (doc == null) {
201
+ return null;
202
+ }
203
+
204
+ return new MongoPersistedSyncRulesContent(this.db, doc);
205
+ }
206
+
207
+ async getActiveSyncRules(): Promise<PersistedSyncRules | null> {
208
+ const content = await this.getActiveSyncRulesContent();
209
+ return content?.parsed() ?? null;
210
+ }
211
+
212
+ async getNextSyncRulesContent(): Promise<MongoPersistedSyncRulesContent | null> {
213
+ const doc = await this.db.sync_rules.findOne(
214
+ {
215
+ state: SyncRuleState.PROCESSING
216
+ },
217
+ { sort: { _id: -1 }, limit: 1 }
218
+ );
219
+ if (doc == null) {
220
+ return null;
221
+ }
222
+
223
+ return new MongoPersistedSyncRulesContent(this.db, doc);
224
+ }
225
+
226
+ async getNextSyncRules(): Promise<PersistedSyncRules | null> {
227
+ const content = await this.getNextSyncRulesContent();
228
+ return content?.parsed() ?? null;
229
+ }
230
+
231
+ async getReplicatingSyncRules(): Promise<PersistedSyncRulesContent[]> {
232
+ const docs = await this.db.sync_rules
233
+ .find({
234
+ $or: [{ state: SyncRuleState.ACTIVE }, { state: SyncRuleState.PROCESSING }]
235
+ })
236
+ .toArray();
237
+
238
+ return docs.map((doc) => {
239
+ return new MongoPersistedSyncRulesContent(this.db, doc);
240
+ });
241
+ }
242
+
243
+ async getStoppedSyncRules(): Promise<PersistedSyncRulesContent[]> {
244
+ const docs = await this.db.sync_rules
245
+ .find({
246
+ state: SyncRuleState.STOP
247
+ })
248
+ .toArray();
249
+
250
+ return docs.map((doc) => {
251
+ return new MongoPersistedSyncRulesContent(this.db, doc);
252
+ });
253
+ }
254
+
255
+ async createWriteCheckpoint(user_id: string, lsns: Record<string, string>): Promise<bigint> {
256
+ const doc = await this.db.write_checkpoints.findOneAndUpdate(
257
+ {
258
+ user_id: user_id
259
+ },
260
+ {
261
+ $set: {
262
+ lsns: lsns
263
+ },
264
+ $inc: {
265
+ client_id: 1n
266
+ }
267
+ },
268
+ { upsert: true, returnDocument: 'after' }
269
+ );
270
+ return doc!.client_id;
271
+ }
272
+
273
+ async lastWriteCheckpoint(user_id: string, lsn: string): Promise<bigint | null> {
274
+ const lastWriteCheckpoint = await this.db.write_checkpoints.findOne({
275
+ user_id: user_id,
276
+ 'lsns.1': { $lte: lsn }
277
+ });
278
+ return lastWriteCheckpoint?.client_id ?? null;
279
+ }
280
+
281
+ async getActiveCheckpoint(): Promise<ActiveCheckpoint> {
282
+ const doc = await this.db.sync_rules.findOne(
283
+ {
284
+ state: SyncRuleState.ACTIVE
285
+ },
286
+ {
287
+ sort: { _id: -1 },
288
+ limit: 1,
289
+ projection: { _id: 1, last_checkpoint: 1, last_checkpoint_lsn: 1 }
290
+ }
291
+ );
292
+
293
+ return this.makeActiveCheckpoint(doc);
294
+ }
295
+
296
+ async getStorageMetrics(): Promise<StorageMetrics> {
297
+ const active_sync_rules = await this.getActiveSyncRules();
298
+ if (active_sync_rules == null) {
299
+ return {
300
+ operations_size_bytes: 0,
301
+ parameters_size_bytes: 0,
302
+ replication_size_bytes: 0
303
+ };
304
+ }
305
+ const operations_aggregate = await this.db.bucket_data
306
+
307
+ .aggregate([
308
+ {
309
+ $collStats: {
310
+ storageStats: {},
311
+ count: {}
312
+ }
313
+ }
314
+ ])
315
+ .toArray();
316
+
317
+ const parameters_aggregate = await this.db.bucket_parameters
318
+ .aggregate([
319
+ {
320
+ $collStats: {
321
+ storageStats: {},
322
+ count: {}
323
+ }
324
+ }
325
+ ])
326
+ .toArray();
327
+
328
+ const replication_aggregate = await this.db.current_data
329
+ .aggregate([
330
+ {
331
+ $collStats: {
332
+ storageStats: {},
333
+ count: {}
334
+ }
335
+ }
336
+ ])
337
+ .toArray();
338
+
339
+ return {
340
+ operations_size_bytes: operations_aggregate[0].storageStats.size,
341
+ parameters_size_bytes: parameters_aggregate[0].storageStats.size,
342
+ replication_size_bytes: replication_aggregate[0].storageStats.size
343
+ };
344
+ }
345
+
346
+ async getPowerSyncInstanceId(): Promise<string> {
347
+ let instance = await this.db.instance.findOne({
348
+ _id: { $exists: true }
349
+ });
350
+
351
+ if (!instance) {
352
+ const manager = locks.createMongoLockManager(this.db.locks, {
353
+ name: `instance-id-insertion-lock`
354
+ });
355
+
356
+ await manager.lock(async () => {
357
+ await this.db.instance.insertOne({
358
+ _id: uuid()
359
+ });
360
+ });
361
+
362
+ instance = await this.db.instance.findOne({
363
+ _id: { $exists: true }
364
+ });
365
+ }
366
+
367
+ return instance!._id;
368
+ }
369
+
370
+ private makeActiveCheckpoint(doc: SyncRuleDocument | null) {
371
+ return {
372
+ checkpoint: util.timestampToOpId(doc?.last_checkpoint ?? 0n),
373
+ lsn: doc?.last_checkpoint_lsn ?? replication.ZERO_LSN,
374
+ hasSyncRules() {
375
+ return doc != null;
376
+ },
377
+ getBucketStorage: async () => {
378
+ if (doc == null) {
379
+ return null;
380
+ }
381
+ return (await this.storageCache.fetch(doc._id)) ?? null;
382
+ }
383
+ };
384
+ }
385
+
386
+ /**
387
+ * Instance-wide watch on the latest available checkpoint (op_id + lsn).
388
+ */
389
+ private async *watchActiveCheckpoint(signal: AbortSignal): AsyncIterable<ActiveCheckpoint> {
390
+ const pipeline: mongo.Document[] = [
391
+ {
392
+ $match: {
393
+ 'fullDocument.state': 'ACTIVE',
394
+ operationType: { $in: ['insert', 'update'] }
395
+ }
396
+ },
397
+ {
398
+ $project: {
399
+ operationType: 1,
400
+ 'fullDocument._id': 1,
401
+ 'fullDocument.last_checkpoint': 1,
402
+ 'fullDocument.last_checkpoint_lsn': 1
403
+ }
404
+ }
405
+ ];
406
+
407
+ // Use this form instead of (doc: SyncRuleDocument | null = null),
408
+ // otherwise we get weird "doc: never" issues.
409
+ let doc = null as SyncRuleDocument | null;
410
+ let clusterTime = null as mongo.Timestamp | null;
411
+
412
+ await this.client.withSession(async (session) => {
413
+ doc = await this.db.sync_rules.findOne(
414
+ {
415
+ state: SyncRuleState.ACTIVE
416
+ },
417
+ {
418
+ session,
419
+ sort: { _id: -1 },
420
+ limit: 1,
421
+ projection: {
422
+ _id: 1,
423
+ last_checkpoint: 1,
424
+ last_checkpoint_lsn: 1
425
+ }
426
+ }
427
+ );
428
+ const time = session.clusterTime?.clusterTime ?? null;
429
+ clusterTime = time;
430
+ });
431
+ if (clusterTime == null) {
432
+ throw new Error('Could not get clusterTime');
433
+ }
434
+
435
+ if (signal.aborted) {
436
+ return;
437
+ }
438
+
439
+ if (doc) {
440
+ yield this.makeActiveCheckpoint(doc);
441
+ }
442
+
443
+ const stream = this.db.sync_rules.watch(pipeline, {
444
+ fullDocument: 'updateLookup',
445
+ // Start at the cluster time where we got the initial doc, to make sure
446
+ // we don't skip any updates.
447
+ // This may result in the first operation being a duplicate, but we filter
448
+ // it out anyway.
449
+ startAtOperationTime: clusterTime
450
+ });
451
+
452
+ signal.addEventListener(
453
+ 'abort',
454
+ () => {
455
+ stream.close();
456
+ },
457
+ { once: true }
458
+ );
459
+
460
+ let lastOp: ActiveCheckpoint | null = null;
461
+
462
+ for await (const update of stream.stream()) {
463
+ if (signal.aborted) {
464
+ break;
465
+ }
466
+ if (update.operationType != 'insert' && update.operationType != 'update') {
467
+ continue;
468
+ }
469
+ const doc = update.fullDocument!;
470
+ if (doc == null) {
471
+ continue;
472
+ }
473
+ const op = this.makeActiveCheckpoint(doc);
474
+ // Check for LSN / checkpoint changes - ignore other metadata changes
475
+ if (lastOp == null || op.lsn != lastOp.lsn || op.checkpoint != lastOp.checkpoint) {
476
+ lastOp = op;
477
+ yield op;
478
+ }
479
+ }
480
+ }
481
+
482
+ // Nothing is done here until a subscriber starts to iterate
483
+ private readonly sharedIter = new sync.BroadcastIterable((signal) => {
484
+ return this.watchActiveCheckpoint(signal);
485
+ });
486
+
487
+ /**
488
+ * User-specific watch on the latest checkpoint and/or write checkpoint.
489
+ */
490
+ async *watchWriteCheckpoint(user_id: string, signal: AbortSignal): AsyncIterable<WriteCheckpoint> {
491
+ let lastCheckpoint: util.OpId | null = null;
492
+ let lastWriteCheckpoint: bigint | null = null;
493
+
494
+ const iter = wrapWithAbort(this.sharedIter, signal);
495
+ for await (const cp of iter) {
496
+ const { checkpoint, lsn } = cp;
497
+
498
+ // lsn changes are not important by itself.
499
+ // What is important is:
500
+ // 1. checkpoint (op_id) changes.
501
+ // 2. write checkpoint changes for the specific user
502
+
503
+ const currentWriteCheckpoint = await this.lastWriteCheckpoint(user_id, lsn ?? '');
504
+
505
+ if (currentWriteCheckpoint == lastWriteCheckpoint && checkpoint == lastCheckpoint) {
506
+ // No change - wait for next one
507
+ // In some cases, many LSNs may be produced in a short time.
508
+ // Add a delay to throttle the write checkpoint lookup a bit.
509
+ await timers.setTimeout(20 + 10 * Math.random());
510
+ continue;
511
+ }
512
+
513
+ lastWriteCheckpoint = currentWriteCheckpoint;
514
+ lastCheckpoint = checkpoint;
515
+
516
+ yield { base: cp, writeCheckpoint: currentWriteCheckpoint };
517
+ }
518
+ }
519
+ }
@@ -0,0 +1,60 @@
1
+ import { DEFAULT_SCHEMA, DEFAULT_TAG } from '@powersync/service-sync-rules';
2
+
3
+ import * as replication from '../replication/replication-index.js';
4
+ import * as util from '../util/util-index.js';
5
+
6
+ export class SourceTable {
7
+ static readonly DEFAULT_SCHEMA = DEFAULT_SCHEMA;
8
+ static readonly DEFAULT_TAG = DEFAULT_TAG;
9
+
10
+ /**
11
+ * True if the table is used in sync rules for data queries.
12
+ *
13
+ * This value is resolved externally, and cached here.
14
+ *
15
+ * Defaults to true for tests.
16
+ */
17
+ public syncData = true;
18
+
19
+ /**
20
+ * True if the table is used in sync rules for data queries.
21
+ *
22
+ * This value is resolved externally, and cached here.
23
+ *
24
+ * Defaults to true for tests.
25
+ */
26
+ public syncParameters = true;
27
+
28
+ constructor(
29
+ public readonly id: any,
30
+ public readonly connectionTag: string,
31
+ public readonly relationId: number,
32
+ public readonly schema: string,
33
+ public readonly table: string,
34
+
35
+ public readonly replicaIdColumns: replication.ReplicationColumn[],
36
+ public readonly snapshotComplete: boolean
37
+ ) {}
38
+
39
+ get hasReplicaIdentity() {
40
+ return this.replicaIdColumns.length > 0;
41
+ }
42
+
43
+ /**
44
+ * Usage: db.query({statement: `SELECT $1::regclass`, params: [{type: 'varchar', value: table.qualifiedName}]})
45
+ */
46
+ get qualifiedName() {
47
+ return this.escapedIdentifier;
48
+ }
49
+
50
+ /**
51
+ * Usage: db.query(`SELECT * FROM ${table.escapedIdentifier}`)
52
+ */
53
+ get escapedIdentifier() {
54
+ return `${util.escapeIdentifier(this.schema)}.${util.escapeIdentifier(this.table)}`;
55
+ }
56
+
57
+ get syncAny() {
58
+ return this.syncData || this.syncParameters;
59
+ }
60
+ }