@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
@@ -0,0 +1,101 @@
1
+ import * as util from '../../util/util-index.js';
2
+ /**
3
+ * Maximum number of operations in a batch.
4
+ */
5
+ const MAX_BATCH_COUNT = 2000;
6
+ /**
7
+ * Maximum size of operations in the batch (estimated).
8
+ */
9
+ const MAX_RECORD_BATCH_SIZE = 14000000;
10
+ /**
11
+ * Maximum size of size of current_data documents we lookup at a time.
12
+ */
13
+ const MAX_CURRENT_DATA_BATCH_SIZE = 16000000;
14
+ /**
15
+ * Batch of input operations.
16
+ *
17
+ * We accumulate operations up to MAX_RECORD_BATCH_SIZE,
18
+ * then further split into sub-batches if MAX_CURRENT_DATA_BATCH_SIZE is exceeded.
19
+ */
20
+ export class OperationBatch {
21
+ constructor() {
22
+ this.batch = [];
23
+ this.currentSize = 0;
24
+ }
25
+ get length() {
26
+ return this.batch.length;
27
+ }
28
+ push(op) {
29
+ this.batch.push(op);
30
+ this.currentSize += op.estimatedSize;
31
+ }
32
+ shouldFlush() {
33
+ return this.batch.length >= MAX_BATCH_COUNT || this.currentSize > MAX_RECORD_BATCH_SIZE;
34
+ }
35
+ *batched(sizes) {
36
+ let currentBatch = [];
37
+ let currentBatchSize = 0;
38
+ for (let op of this.batch) {
39
+ const key = op.internalBeforeKey;
40
+ const size = sizes.get(key) ?? 0;
41
+ if (currentBatchSize + size > MAX_CURRENT_DATA_BATCH_SIZE && currentBatch.length > 0) {
42
+ yield currentBatch;
43
+ currentBatch = [];
44
+ currentBatchSize = 0;
45
+ }
46
+ currentBatchSize += size;
47
+ currentBatch.push(op);
48
+ }
49
+ if (currentBatch.length > 0) {
50
+ yield currentBatch;
51
+ }
52
+ }
53
+ }
54
+ export class RecordOperation {
55
+ constructor(record) {
56
+ this.record = record;
57
+ const after = record.after;
58
+ const afterId = after ? util.getUuidReplicaIdentityBson(after, record.sourceTable.replicaIdColumns) : null;
59
+ const beforeId = record.before
60
+ ? util.getUuidReplicaIdentityBson(record.before, record.sourceTable.replicaIdColumns)
61
+ : afterId;
62
+ this.afterId = afterId;
63
+ this.beforeId = beforeId;
64
+ this.internalBeforeKey = cacheKey(record.sourceTable.id, beforeId);
65
+ this.internalAfterKey = afterId ? cacheKey(record.sourceTable.id, afterId) : null;
66
+ this.estimatedSize = estimateRowSize(record.before) + estimateRowSize(record.after);
67
+ }
68
+ }
69
+ export function cacheKey(table, id) {
70
+ return `${table.toHexString()}.${id.toHexString()}`;
71
+ }
72
+ /**
73
+ * Estimate in-memory size of row.
74
+ */
75
+ function estimateRowSize(record) {
76
+ if (record == null) {
77
+ return 12;
78
+ }
79
+ let size = 0;
80
+ for (let [key, value] of Object.entries(record)) {
81
+ size += 12 + key.length;
82
+ // number | string | null | bigint | Uint8Array
83
+ if (value == null) {
84
+ size += 4;
85
+ }
86
+ else if (typeof value == 'number') {
87
+ size += 8;
88
+ }
89
+ else if (typeof value == 'bigint') {
90
+ size += 8;
91
+ }
92
+ else if (typeof value == 'string') {
93
+ size += value.length;
94
+ }
95
+ else if (value instanceof Uint8Array) {
96
+ size += value.byteLength;
97
+ }
98
+ }
99
+ return size;
100
+ }
101
+ //# sourceMappingURL=OperationBatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperationBatch.js","sourceRoot":"","sources":["../../../src/storage/mongo/OperationBatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { EvaluatedParameters, EvaluatedRow } from '@powersync/service-sync-rules';
2
+ import * as bson from 'bson';
3
+ import * as mongo from 'mongodb';
4
+ import { SourceTable } from '../SourceTable.js';
5
+ import { MongoIdSequence } from './MongoIdSequence.js';
6
+ import { PowerSyncMongo } from './db.js';
7
+ import { BucketDataDocument, BucketParameterDocument, CurrentBucket, CurrentDataDocument, SourceKey } from './models.js';
8
+ /**
9
+ * Keeps track of bulkwrite operations within a transaction.
10
+ *
11
+ * There may be multiple of these batches per transaction, but it may not span
12
+ * multiple transactions.
13
+ */
14
+ export declare class PersistedBatch {
15
+ private group_id;
16
+ bucketData: mongo.AnyBulkWriteOperation<BucketDataDocument>[];
17
+ bucketParameters: mongo.AnyBulkWriteOperation<BucketParameterDocument>[];
18
+ currentData: mongo.AnyBulkWriteOperation<CurrentDataDocument>[];
19
+ /**
20
+ * Very rough estimate of transaction size.
21
+ */
22
+ currentSize: number;
23
+ constructor(group_id: number, writtenSize: number);
24
+ saveBucketData(options: {
25
+ op_seq: MongoIdSequence;
26
+ sourceKey: bson.UUID;
27
+ table: SourceTable;
28
+ evaluated: EvaluatedRow[];
29
+ before_buckets: CurrentBucket[];
30
+ }): void;
31
+ saveParameterData(data: {
32
+ op_seq: MongoIdSequence;
33
+ sourceKey: bson.UUID;
34
+ sourceTable: SourceTable;
35
+ evaluated: EvaluatedParameters[];
36
+ existing_lookups: bson.Binary[];
37
+ }): void;
38
+ deleteCurrentData(id: SourceKey): void;
39
+ upsertCurrentData(id: SourceKey, values: Partial<CurrentDataDocument>): void;
40
+ shouldFlushTransaction(): boolean;
41
+ flush(db: PowerSyncMongo, session: mongo.ClientSession): Promise<void>;
42
+ }
@@ -0,0 +1,200 @@
1
+ import { JSONBig } from '@powersync/service-jsonbig';
2
+ import * as util from '../../util/util-index.js';
3
+ import { currentBucketKey } from './MongoBucketBatch.js';
4
+ import { serializeLookup } from './util.js';
5
+ /**
6
+ * Maximum size of operations we write in a single transaction.
7
+ *
8
+ * It's tricky to find the exact limit, but from experience, over 100MB
9
+ * can cause an error:
10
+ * > transaction is too large and will not fit in the storage engine cache
11
+ *
12
+ * Additionally, unbounded size here can balloon our memory usage in some edge
13
+ * cases.
14
+ *
15
+ * When we reach this threshold, we commit the transaction and start a new one.
16
+ */
17
+ const MAX_TRANSACTION_BATCH_SIZE = 30000000;
18
+ /**
19
+ * Keeps track of bulkwrite operations within a transaction.
20
+ *
21
+ * There may be multiple of these batches per transaction, but it may not span
22
+ * multiple transactions.
23
+ */
24
+ export class PersistedBatch {
25
+ constructor(group_id, writtenSize) {
26
+ this.group_id = group_id;
27
+ this.bucketData = [];
28
+ this.bucketParameters = [];
29
+ this.currentData = [];
30
+ /**
31
+ * Very rough estimate of transaction size.
32
+ */
33
+ this.currentSize = 0;
34
+ this.currentSize = writtenSize;
35
+ }
36
+ saveBucketData(options) {
37
+ const remaining_buckets = new Map();
38
+ for (let b of options.before_buckets) {
39
+ const key = currentBucketKey(b);
40
+ remaining_buckets.set(key, b);
41
+ }
42
+ const dchecksum = util.hashDelete(`${options.table.id}/${options.sourceKey}`);
43
+ for (let k of options.evaluated) {
44
+ const key = currentBucketKey(k);
45
+ remaining_buckets.delete(key);
46
+ // INSERT
47
+ const recordData = JSONBig.stringify(k.data);
48
+ const checksum = util.hashData(k.table, k.id, recordData);
49
+ this.currentSize += recordData.length + 200;
50
+ this.bucketData.push({
51
+ insertOne: {
52
+ document: {
53
+ _id: {
54
+ g: this.group_id,
55
+ b: k.bucket,
56
+ o: options.op_seq.next()
57
+ },
58
+ op: 'PUT',
59
+ source_table: options.table.id,
60
+ source_key: options.sourceKey,
61
+ table: k.table,
62
+ row_id: k.id,
63
+ checksum: checksum,
64
+ data: recordData
65
+ }
66
+ }
67
+ });
68
+ }
69
+ for (let bd of remaining_buckets.values()) {
70
+ // REMOVE
71
+ this.bucketData.push({
72
+ insertOne: {
73
+ document: {
74
+ _id: {
75
+ g: this.group_id,
76
+ b: bd.bucket,
77
+ o: options.op_seq.next()
78
+ },
79
+ op: 'REMOVE',
80
+ source_table: options.table.id,
81
+ source_key: options.sourceKey,
82
+ table: bd.table,
83
+ row_id: bd.id,
84
+ checksum: dchecksum,
85
+ data: null
86
+ }
87
+ }
88
+ });
89
+ this.currentSize += 200;
90
+ }
91
+ }
92
+ saveParameterData(data) {
93
+ // This is similar to saving bucket data.
94
+ // A key difference is that we don't need to keep the history intact.
95
+ // We do need to keep track of recent history though - enough that we can get consistent data for any specific checkpoint.
96
+ // Instead of storing per bucket id, we store per "lookup".
97
+ // A key difference is that we don't need to store or keep track of anything per-bucket - the entire record is
98
+ // either persisted or removed.
99
+ // We also don't need to keep history intact.
100
+ const { sourceTable, sourceKey, evaluated } = data;
101
+ const remaining_lookups = new Map();
102
+ for (let l of data.existing_lookups) {
103
+ remaining_lookups.set(l.toString('base64'), l);
104
+ }
105
+ // 1. Insert new entries
106
+ for (let result of evaluated) {
107
+ const binLookup = serializeLookup(result.lookup);
108
+ const hex = binLookup.toString('base64');
109
+ remaining_lookups.delete(hex);
110
+ const op_id = data.op_seq.next();
111
+ this.bucketParameters.push({
112
+ insertOne: {
113
+ document: {
114
+ _id: op_id,
115
+ key: {
116
+ g: this.group_id,
117
+ t: sourceTable.id,
118
+ k: sourceKey
119
+ },
120
+ lookup: binLookup,
121
+ bucket_parameters: result.bucket_parameters
122
+ }
123
+ }
124
+ });
125
+ this.currentSize += 200;
126
+ }
127
+ // 2. "REMOVE" entries for any lookup not touched.
128
+ for (let lookup of remaining_lookups.values()) {
129
+ const op_id = data.op_seq.next();
130
+ this.bucketParameters.push({
131
+ insertOne: {
132
+ document: {
133
+ _id: op_id,
134
+ key: {
135
+ g: this.group_id,
136
+ t: sourceTable.id,
137
+ k: sourceKey
138
+ },
139
+ lookup: lookup,
140
+ bucket_parameters: []
141
+ }
142
+ }
143
+ });
144
+ this.currentSize += 200;
145
+ }
146
+ }
147
+ deleteCurrentData(id) {
148
+ const op = {
149
+ deleteOne: {
150
+ filter: { _id: id }
151
+ }
152
+ };
153
+ this.currentData.push(op);
154
+ this.currentSize += 50;
155
+ }
156
+ upsertCurrentData(id, values) {
157
+ const op = {
158
+ updateOne: {
159
+ filter: { _id: id },
160
+ update: {
161
+ $set: values
162
+ },
163
+ upsert: true
164
+ }
165
+ };
166
+ this.currentData.push(op);
167
+ this.currentSize += (values.data?.length() ?? 0) + 100;
168
+ }
169
+ shouldFlushTransaction() {
170
+ return this.currentSize >= MAX_TRANSACTION_BATCH_SIZE;
171
+ }
172
+ async flush(db, session) {
173
+ if (this.bucketData.length > 0) {
174
+ await db.bucket_data.bulkWrite(this.bucketData, {
175
+ session,
176
+ // inserts only - order doesn't matter
177
+ ordered: false
178
+ });
179
+ }
180
+ if (this.bucketParameters.length > 0) {
181
+ await db.bucket_parameters.bulkWrite(this.bucketParameters, {
182
+ session,
183
+ // inserts only - order doesn't matter
184
+ ordered: false
185
+ });
186
+ }
187
+ if (this.currentData.length > 0) {
188
+ await db.current_data.bulkWrite(this.currentData, {
189
+ session,
190
+ // may update and delete data within the same batch - order matters
191
+ ordered: true
192
+ });
193
+ }
194
+ this.bucketData = [];
195
+ this.bucketParameters = [];
196
+ this.currentData = [];
197
+ this.currentSize = 0;
198
+ }
199
+ }
200
+ //# sourceMappingURL=PersistedBatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedBatch.js","sourceRoot":"","sources":["../../../src/storage/mongo/PersistedBatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import * as mongo from 'mongodb';
2
+ import { BucketDataDocument, BucketParameterDocument, CurrentDataDocument, IdSequenceDocument, SourceTableDocument, SyncRuleDocument, WriteCheckpointDocument } from './models.js';
3
+ import { configFile } from '@powersync/service-types';
4
+ export interface PowerSyncMongoOptions {
5
+ /**
6
+ * Optional - uses the database from the MongoClient connection URI if not specified.
7
+ */
8
+ database?: string;
9
+ }
10
+ export declare function createPowerSyncMongo(config: configFile.PowerSyncConfig['storage']): PowerSyncMongo;
11
+ export declare class PowerSyncMongo {
12
+ readonly current_data: mongo.Collection<CurrentDataDocument>;
13
+ readonly bucket_data: mongo.Collection<BucketDataDocument>;
14
+ readonly bucket_parameters: mongo.Collection<BucketParameterDocument>;
15
+ readonly op_id_sequence: mongo.Collection<IdSequenceDocument>;
16
+ readonly sync_rules: mongo.Collection<SyncRuleDocument>;
17
+ readonly source_tables: mongo.Collection<SourceTableDocument>;
18
+ readonly write_checkpoints: mongo.Collection<WriteCheckpointDocument>;
19
+ readonly client: mongo.MongoClient;
20
+ readonly db: mongo.Db;
21
+ constructor(client: mongo.MongoClient, options?: PowerSyncMongoOptions);
22
+ clear(): Promise<void>;
23
+ }
@@ -0,0 +1,34 @@
1
+ import * as db from '../../db/db-index.js';
2
+ import { BSON_DESERIALIZE_OPTIONS } from './util.js';
3
+ export function createPowerSyncMongo(config) {
4
+ return new PowerSyncMongo(db.mongo.createMongoClient(config), { database: config.database });
5
+ }
6
+ export class PowerSyncMongo {
7
+ constructor(client, options) {
8
+ this.client = client;
9
+ const db = client.db(options?.database, {
10
+ // Note this issue with useBigInt64: https://jira.mongodb.org/browse/NODE-6165
11
+ // Unfortunately there is no workaround if we want to continue using bigint.
12
+ // We selectively disable this in individual queries where we don't need that.
13
+ ...BSON_DESERIALIZE_OPTIONS
14
+ });
15
+ this.db = db;
16
+ this.current_data = db.collection('current_data');
17
+ this.bucket_data = db.collection('bucket_data');
18
+ this.bucket_parameters = db.collection('bucket_parameters');
19
+ this.op_id_sequence = db.collection('op_id_sequence');
20
+ this.sync_rules = db.collection('sync_rules');
21
+ this.source_tables = db.collection('source_tables');
22
+ this.write_checkpoints = db.collection('write_checkpoints');
23
+ }
24
+ async clear() {
25
+ await this.current_data.deleteMany({});
26
+ await this.bucket_data.deleteMany({});
27
+ await this.bucket_parameters.deleteMany({});
28
+ await this.op_id_sequence.deleteMany({});
29
+ await this.sync_rules.deleteMany({});
30
+ await this.source_tables.deleteMany({});
31
+ await this.write_checkpoints.deleteMany({});
32
+ }
33
+ }
34
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/mongo/db.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAUrD,MAAM,UAAU,oBAAoB,CAAC,MAA6C;IAChF,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,OAAO,cAAc;IAYzB,YAAY,MAAyB,EAAE,OAA+B;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE;YACtC,8EAA8E;YAC9E,4EAA4E;YAC5E,8EAA8E;YAC9E,GAAG,wBAAwB;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,UAAU,CAAsB,cAAc,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,137 @@
1
+ import * as bson from 'bson';
2
+ import { SqliteJsonValue } from '@powersync/service-sync-rules';
3
+ export interface SourceKey {
4
+ /** group_id */
5
+ g: number;
6
+ /** source table id */
7
+ t: bson.ObjectId;
8
+ /** source key */
9
+ k: bson.UUID;
10
+ }
11
+ export interface BucketDataKey {
12
+ /** group_id */
13
+ g: number;
14
+ /** bucket name */
15
+ b: string;
16
+ /** op_id */
17
+ o: bigint;
18
+ }
19
+ export interface CurrentDataDocument {
20
+ _id: SourceKey;
21
+ data: bson.Binary;
22
+ buckets: CurrentBucket[];
23
+ lookups: bson.Binary[];
24
+ }
25
+ export interface CurrentBucket {
26
+ bucket: string;
27
+ table: string;
28
+ id: string;
29
+ }
30
+ export interface BucketParameterDocument {
31
+ _id: bigint;
32
+ key: SourceKey;
33
+ lookup: bson.Binary;
34
+ bucket_parameters: Record<string, SqliteJsonValue>[];
35
+ }
36
+ export interface BucketDataDocument {
37
+ _id: BucketDataKey;
38
+ op: OpType;
39
+ source_table: bson.ObjectId;
40
+ source_key: bson.UUID;
41
+ table: string;
42
+ row_id: string;
43
+ checksum: number;
44
+ data: string | null;
45
+ }
46
+ export type OpType = 'PUT' | 'REMOVE' | 'MOVE' | 'CLEAR';
47
+ export interface SourceTableDocument {
48
+ _id: bson.ObjectId;
49
+ group_id: number;
50
+ connection_id: number;
51
+ relation_id: number | undefined;
52
+ schema_name: string;
53
+ table_name: string;
54
+ replica_id_columns: string[] | null;
55
+ replica_id_columns2: {
56
+ name: string;
57
+ type_oid: number;
58
+ }[] | undefined;
59
+ snapshot_done: boolean | undefined;
60
+ }
61
+ export interface IdSequenceDocument {
62
+ _id: string;
63
+ op_id: bigint;
64
+ }
65
+ export declare enum SyncRuleState {
66
+ /**
67
+ * New sync rules - needs to be processed (initial replication).
68
+ *
69
+ * While multiple sets of sync rules _can_ be in PROCESSING,
70
+ * it's generally pointless, so we only keep one in that state.
71
+ */
72
+ PROCESSING = "PROCESSING",
73
+ /**
74
+ * Sync rule processing is done, and can be used for sync.
75
+ *
76
+ * Only one set of sync rules should be in ACTIVE state.
77
+ */
78
+ ACTIVE = "ACTIVE",
79
+ /**
80
+ * This state is used when the sync rules has been replaced,
81
+ * and replication is or should be stopped.
82
+ */
83
+ STOP = "STOP",
84
+ /**
85
+ * After sync rules have been stopped, the data needs to be
86
+ * deleted. Once deleted, the state is TERMINATED.
87
+ */
88
+ TERMINATED = "TERMINATED"
89
+ }
90
+ export interface SyncRuleDocument {
91
+ _id: number;
92
+ state: SyncRuleState;
93
+ /**
94
+ * True if initial snapshot has been replicated.
95
+ *
96
+ * Can only be false if state == PROCESSING.
97
+ */
98
+ snapshot_done: boolean;
99
+ /**
100
+ * The last consistent checkpoint.
101
+ *
102
+ * There may be higher OpIds used in the database if we're in the middle of replicating a large transaction.
103
+ */
104
+ last_checkpoint: bigint | null;
105
+ /**
106
+ * The LSN associated with the last consistent checkpoint.
107
+ */
108
+ last_checkpoint_lsn: string | null;
109
+ /**
110
+ * If set, no new checkpoints may be created < this value.
111
+ */
112
+ no_checkpoint_before: string | null;
113
+ slot_name: string | null;
114
+ /**
115
+ * Last time we persisted a checkpoint.
116
+ *
117
+ * This may be old if no data is incoming.
118
+ */
119
+ last_checkpoint_ts: Date | null;
120
+ /**
121
+ * Last time we persisted a checkpoint or keepalive.
122
+ *
123
+ * This should stay fairly current while replicating.
124
+ */
125
+ last_keepalive_ts: Date | null;
126
+ /**
127
+ * If an error is stopping replication, it will be stored here.
128
+ */
129
+ last_fatal_error: string | null;
130
+ content: string;
131
+ }
132
+ export interface WriteCheckpointDocument {
133
+ _id: bson.ObjectId;
134
+ user_id: string;
135
+ lsns: Record<string, string>;
136
+ client_id: bigint;
137
+ }
@@ -0,0 +1,27 @@
1
+ export var SyncRuleState;
2
+ (function (SyncRuleState) {
3
+ /**
4
+ * New sync rules - needs to be processed (initial replication).
5
+ *
6
+ * While multiple sets of sync rules _can_ be in PROCESSING,
7
+ * it's generally pointless, so we only keep one in that state.
8
+ */
9
+ SyncRuleState["PROCESSING"] = "PROCESSING";
10
+ /**
11
+ * Sync rule processing is done, and can be used for sync.
12
+ *
13
+ * Only one set of sync rules should be in ACTIVE state.
14
+ */
15
+ SyncRuleState["ACTIVE"] = "ACTIVE";
16
+ /**
17
+ * This state is used when the sync rules has been replaced,
18
+ * and replication is or should be stopped.
19
+ */
20
+ SyncRuleState["STOP"] = "STOP";
21
+ /**
22
+ * After sync rules have been stopped, the data needs to be
23
+ * deleted. Once deleted, the state is TERMINATED.
24
+ */
25
+ SyncRuleState["TERMINATED"] = "TERMINATED";
26
+ })(SyncRuleState || (SyncRuleState = {}));
27
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/storage/mongo/models.ts"],"names":[],"mappings":"AAuEA,MAAM,CAAN,IAAY,aAyBX;AAzBD,WAAY,aAAa;IACvB;;;;;OAKG;IACH,0CAAyB,CAAA;IAEzB;;;;OAIG;IACH,kCAAiB,CAAA;IACjB;;;OAGG;IACH,8BAAa,CAAA;IACb;;;OAGG;IACH,0CAAyB,CAAA;AAC3B,CAAC,EAzBW,aAAa,KAAb,aAAa,QAyBxB"}
@@ -0,0 +1,26 @@
1
+ import { SqliteJsonValue } from '@powersync/service-sync-rules';
2
+ import * as bson from 'bson';
3
+ import * as mongo from 'mongodb';
4
+ /**
5
+ * Lookup serialization must be number-agnostic. I.e. normalize numbers, instead of preserving numbers.
6
+ * @param lookup
7
+ */
8
+ export declare function serializeLookup(lookup: SqliteJsonValue[]): bson.Binary;
9
+ export declare function idPrefixFilter<T>(prefix: Partial<T>, rest: (keyof T)[]): mongo.Condition<T>;
10
+ export declare function generateSlotName(prefix: string, sync_rules_id: number): string;
11
+ /**
12
+ * Read a single batch of data from a cursor, then close it.
13
+ *
14
+ * We do our best to avoid MongoDB fetching any more data than this single batch.
15
+ *
16
+ * This is similar to using `singleBatch: true` in find options.
17
+ * However, that makes `has_more` detection very difficult, since the cursor is always closed
18
+ * after the first batch. Instead, we do a workaround to only fetch a single batch below.
19
+ *
20
+ * For this to be effective, set batchSize = limit in the find command.
21
+ */
22
+ export declare function readSingleBatch<T>(cursor: mongo.FindCursor<T>): Promise<{
23
+ data: T[];
24
+ hasMore: boolean;
25
+ }>;
26
+ export declare const BSON_DESERIALIZE_OPTIONS: bson.DeserializeOptions;