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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/CHANGELOG.md +80 -2
  2. package/dist/api/RouteAPI.d.ts +68 -0
  3. package/dist/api/RouteAPI.js +2 -0
  4. package/dist/api/RouteAPI.js.map +1 -0
  5. package/dist/api/api-index.d.ts +1 -0
  6. package/dist/api/api-index.js +1 -0
  7. package/dist/api/api-index.js.map +1 -1
  8. package/dist/api/diagnostics.d.ts +4 -4
  9. package/dist/api/diagnostics.js +11 -65
  10. package/dist/api/diagnostics.js.map +1 -1
  11. package/dist/api/schema.d.ts +3 -5
  12. package/dist/api/schema.js +9 -79
  13. package/dist/api/schema.js.map +1 -1
  14. package/dist/auth/KeyStore.d.ts +7 -4
  15. package/dist/auth/KeyStore.js +1 -1
  16. package/dist/auth/KeyStore.js.map +1 -1
  17. package/dist/auth/auth-index.d.ts +0 -1
  18. package/dist/auth/auth-index.js +0 -1
  19. package/dist/auth/auth-index.js.map +1 -1
  20. package/dist/entry/cli-entry.js +3 -2
  21. package/dist/entry/cli-entry.js.map +1 -1
  22. package/dist/entry/commands/compact-action.js +12 -8
  23. package/dist/entry/commands/compact-action.js.map +1 -1
  24. package/dist/entry/commands/migrate-action.js +4 -5
  25. package/dist/entry/commands/migrate-action.js.map +1 -1
  26. package/dist/entry/commands/teardown-action.js +2 -2
  27. package/dist/entry/commands/teardown-action.js.map +1 -1
  28. package/dist/index.d.ts +4 -2
  29. package/dist/index.js +4 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/metrics/Metrics.d.ts +2 -2
  32. package/dist/metrics/Metrics.js +5 -13
  33. package/dist/metrics/Metrics.js.map +1 -1
  34. package/dist/migrations/db/migrations/1684951997326-init.d.ts +2 -2
  35. package/dist/migrations/db/migrations/1684951997326-init.js +4 -2
  36. package/dist/migrations/db/migrations/1684951997326-init.js.map +1 -1
  37. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.d.ts +2 -2
  38. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +4 -2
  39. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
  40. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.d.ts +2 -2
  41. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js +4 -2
  42. package/dist/migrations/db/migrations/1711543888062-write-checkpoint-index.js.map +1 -1
  43. package/dist/migrations/migrations.d.ts +8 -0
  44. package/dist/migrations/migrations.js +19 -7
  45. package/dist/migrations/migrations.js.map +1 -1
  46. package/dist/modules/AbstractModule.d.ts +26 -0
  47. package/dist/modules/AbstractModule.js +11 -0
  48. package/dist/modules/AbstractModule.js.map +1 -0
  49. package/dist/modules/ModuleManager.d.ts +11 -0
  50. package/dist/modules/ModuleManager.js +32 -0
  51. package/dist/modules/ModuleManager.js.map +1 -0
  52. package/dist/modules/modules-index.d.ts +2 -0
  53. package/dist/modules/modules-index.js +3 -0
  54. package/dist/modules/modules-index.js.map +1 -0
  55. package/dist/replication/AbstractReplicationJob.d.ts +38 -0
  56. package/dist/replication/AbstractReplicationJob.js +51 -0
  57. package/dist/replication/AbstractReplicationJob.js.map +1 -0
  58. package/dist/replication/AbstractReplicator.d.ts +53 -0
  59. package/dist/replication/AbstractReplicator.js +187 -0
  60. package/dist/replication/AbstractReplicator.js.map +1 -0
  61. package/dist/replication/ErrorRateLimiter.d.ts +0 -9
  62. package/dist/replication/ErrorRateLimiter.js +1 -42
  63. package/dist/replication/ErrorRateLimiter.js.map +1 -1
  64. package/dist/replication/ReplicationEngine.d.ts +18 -0
  65. package/dist/replication/ReplicationEngine.js +41 -0
  66. package/dist/replication/ReplicationEngine.js.map +1 -0
  67. package/dist/replication/ReplicationModule.d.ts +39 -0
  68. package/dist/replication/ReplicationModule.js +65 -0
  69. package/dist/replication/ReplicationModule.js.map +1 -0
  70. package/dist/replication/replication-index.d.ts +4 -6
  71. package/dist/replication/replication-index.js +4 -6
  72. package/dist/replication/replication-index.js.map +1 -1
  73. package/dist/routes/RouterEngine.d.ts +42 -0
  74. package/dist/routes/RouterEngine.js +80 -0
  75. package/dist/routes/RouterEngine.js.map +1 -0
  76. package/dist/routes/auth.d.ts +2 -2
  77. package/dist/routes/auth.js +11 -11
  78. package/dist/routes/auth.js.map +1 -1
  79. package/dist/routes/configure-fastify.d.ts +30 -176
  80. package/dist/routes/configure-fastify.js +10 -11
  81. package/dist/routes/configure-fastify.js.map +1 -1
  82. package/dist/routes/configure-rsocket.d.ts +3 -3
  83. package/dist/routes/configure-rsocket.js +6 -5
  84. package/dist/routes/configure-rsocket.js.map +1 -1
  85. package/dist/routes/endpoints/admin.d.ts +0 -34
  86. package/dist/routes/endpoints/admin.js +48 -89
  87. package/dist/routes/endpoints/admin.js.map +1 -1
  88. package/dist/routes/endpoints/checkpointing.d.ts +56 -16
  89. package/dist/routes/endpoints/checkpointing.js +33 -12
  90. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  91. package/dist/routes/endpoints/route-endpoints-index.d.ts +0 -1
  92. package/dist/routes/endpoints/route-endpoints-index.js +0 -1
  93. package/dist/routes/endpoints/route-endpoints-index.js.map +1 -1
  94. package/dist/routes/endpoints/socket-route.js +40 -25
  95. package/dist/routes/endpoints/socket-route.js.map +1 -1
  96. package/dist/routes/endpoints/sync-rules.d.ts +1 -1
  97. package/dist/routes/endpoints/sync-rules.js +32 -23
  98. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  99. package/dist/routes/endpoints/sync-stream.d.ts +10 -0
  100. package/dist/routes/endpoints/sync-stream.js +13 -8
  101. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  102. package/dist/routes/router-socket.d.ts +1 -0
  103. package/dist/routes/router-socket.js +2 -1
  104. package/dist/routes/router-socket.js.map +1 -1
  105. package/dist/routes/router.d.ts +6 -2
  106. package/dist/routes/router.js.map +1 -1
  107. package/dist/routes/routes-index.d.ts +1 -0
  108. package/dist/routes/routes-index.js +1 -0
  109. package/dist/routes/routes-index.js.map +1 -1
  110. package/dist/runner/teardown.js +47 -76
  111. package/dist/runner/teardown.js.map +1 -1
  112. package/dist/storage/BucketStorage.d.ts +30 -19
  113. package/dist/storage/BucketStorage.js +0 -10
  114. package/dist/storage/BucketStorage.js.map +1 -1
  115. package/dist/storage/MongoBucketStorage.d.ts +4 -4
  116. package/dist/storage/MongoBucketStorage.js +19 -24
  117. package/dist/storage/MongoBucketStorage.js.map +1 -1
  118. package/dist/storage/SourceEntity.d.ts +20 -0
  119. package/dist/storage/SourceEntity.js +2 -0
  120. package/dist/storage/SourceEntity.js.map +1 -0
  121. package/dist/storage/SourceTable.d.ts +4 -5
  122. package/dist/storage/SourceTable.js +3 -4
  123. package/dist/storage/SourceTable.js.map +1 -1
  124. package/dist/storage/StorageEngine.d.ts +24 -0
  125. package/dist/storage/StorageEngine.js +43 -0
  126. package/dist/storage/StorageEngine.js.map +1 -0
  127. package/dist/storage/StorageProvider.d.ts +21 -0
  128. package/dist/storage/StorageProvider.js +2 -0
  129. package/dist/storage/StorageProvider.js.map +1 -0
  130. package/dist/storage/mongo/MongoBucketBatch.d.ts +1 -1
  131. package/dist/storage/mongo/MongoBucketBatch.js +6 -7
  132. package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
  133. package/dist/storage/mongo/MongoCompactor.js +2 -1
  134. package/dist/storage/mongo/MongoCompactor.js.map +1 -1
  135. package/dist/storage/mongo/MongoPersistedSyncRulesContent.d.ts +2 -2
  136. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js +2 -2
  137. package/dist/storage/mongo/MongoPersistedSyncRulesContent.js.map +1 -1
  138. package/dist/storage/mongo/MongoStorageProvider.d.ts +5 -0
  139. package/dist/storage/mongo/MongoStorageProvider.js +26 -0
  140. package/dist/storage/mongo/MongoStorageProvider.js.map +1 -0
  141. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +7 -6
  142. package/dist/storage/mongo/MongoSyncBucketStorage.js +24 -15
  143. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
  144. package/dist/storage/mongo/MongoSyncRulesLock.js +1 -1
  145. package/dist/storage/mongo/MongoSyncRulesLock.js.map +1 -1
  146. package/dist/storage/mongo/OperationBatch.d.ts +7 -3
  147. package/dist/storage/mongo/OperationBatch.js +16 -7
  148. package/dist/storage/mongo/OperationBatch.js.map +1 -1
  149. package/dist/storage/mongo/PersistedBatch.d.ts +3 -3
  150. package/dist/storage/mongo/PersistedBatch.js +2 -2
  151. package/dist/storage/mongo/PersistedBatch.js.map +1 -1
  152. package/dist/storage/mongo/models.d.ts +13 -4
  153. package/dist/storage/mongo/models.js.map +1 -1
  154. package/dist/storage/mongo/util.d.ts +12 -1
  155. package/dist/storage/mongo/util.js +50 -2
  156. package/dist/storage/mongo/util.js.map +1 -1
  157. package/dist/storage/storage-index.d.ts +5 -2
  158. package/dist/storage/storage-index.js +5 -2
  159. package/dist/storage/storage-index.js.map +1 -1
  160. package/dist/sync/sync.d.ts +2 -1
  161. package/dist/sync/sync.js +36 -10
  162. package/dist/sync/sync.js.map +1 -1
  163. package/dist/sync/util.js.map +1 -1
  164. package/dist/system/ServiceContext.d.ts +37 -0
  165. package/dist/system/ServiceContext.js +48 -0
  166. package/dist/system/ServiceContext.js.map +1 -0
  167. package/dist/system/system-index.d.ts +1 -1
  168. package/dist/system/system-index.js +1 -1
  169. package/dist/system/system-index.js.map +1 -1
  170. package/dist/util/config/compound-config-collector.d.ts +9 -2
  171. package/dist/util/config/compound-config-collector.js +14 -23
  172. package/dist/util/config/compound-config-collector.js.map +1 -1
  173. package/dist/util/config/sync-rules/sync-rules-provider.d.ts +9 -0
  174. package/dist/util/config/sync-rules/sync-rules-provider.js +15 -0
  175. package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -0
  176. package/dist/util/config/types.d.ts +6 -4
  177. package/dist/util/config/types.js.map +1 -1
  178. package/dist/util/config.d.ts +3 -4
  179. package/dist/util/config.js +5 -20
  180. package/dist/util/config.js.map +1 -1
  181. package/dist/util/protocol-types.d.ts +4 -0
  182. package/dist/util/protocol-types.js +5 -1
  183. package/dist/util/protocol-types.js.map +1 -1
  184. package/dist/util/util-index.d.ts +3 -6
  185. package/dist/util/util-index.js +3 -6
  186. package/dist/util/util-index.js.map +1 -1
  187. package/dist/util/utils.d.ts +10 -6
  188. package/dist/util/utils.js +45 -25
  189. package/dist/util/utils.js.map +1 -1
  190. package/package.json +5 -7
  191. package/src/api/RouteAPI.ts +78 -0
  192. package/src/api/api-index.ts +1 -0
  193. package/src/api/diagnostics.ts +16 -71
  194. package/src/api/schema.ts +13 -89
  195. package/src/auth/KeyStore.ts +9 -6
  196. package/src/auth/auth-index.ts +0 -1
  197. package/src/entry/cli-entry.ts +3 -2
  198. package/src/entry/commands/compact-action.ts +12 -9
  199. package/src/entry/commands/migrate-action.ts +5 -8
  200. package/src/entry/commands/teardown-action.ts +2 -2
  201. package/src/index.ts +5 -2
  202. package/src/metrics/Metrics.ts +6 -16
  203. package/src/migrations/db/migrations/1684951997326-init.ts +9 -4
  204. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -4
  205. package/src/migrations/db/migrations/1711543888062-write-checkpoint-index.ts +6 -4
  206. package/src/migrations/migrations.ts +24 -8
  207. package/src/modules/AbstractModule.ts +37 -0
  208. package/src/modules/ModuleManager.ts +34 -0
  209. package/src/modules/modules-index.ts +2 -0
  210. package/src/replication/AbstractReplicationJob.ts +79 -0
  211. package/src/replication/AbstractReplicator.ts +227 -0
  212. package/src/replication/ErrorRateLimiter.ts +0 -44
  213. package/src/replication/ReplicationEngine.ts +43 -0
  214. package/src/replication/ReplicationModule.ts +101 -0
  215. package/src/replication/replication-index.ts +4 -6
  216. package/src/routes/RouterEngine.ts +120 -0
  217. package/src/routes/auth.ts +21 -12
  218. package/src/routes/configure-fastify.ts +13 -14
  219. package/src/routes/configure-rsocket.ts +9 -8
  220. package/src/routes/endpoints/admin.ts +74 -100
  221. package/src/routes/endpoints/checkpointing.ts +46 -12
  222. package/src/routes/endpoints/route-endpoints-index.ts +0 -1
  223. package/src/routes/endpoints/socket-route.ts +44 -27
  224. package/src/routes/endpoints/sync-rules.ts +41 -25
  225. package/src/routes/endpoints/sync-stream.ts +13 -8
  226. package/src/routes/router-socket.ts +2 -1
  227. package/src/routes/router.ts +6 -3
  228. package/src/routes/routes-index.ts +1 -0
  229. package/src/runner/teardown.ts +50 -88
  230. package/src/storage/BucketStorage.ts +38 -25
  231. package/src/storage/MongoBucketStorage.ts +23 -26
  232. package/src/storage/SourceEntity.ts +22 -0
  233. package/src/storage/SourceTable.ts +4 -6
  234. package/src/storage/StorageEngine.ts +55 -0
  235. package/src/storage/StorageProvider.ts +27 -0
  236. package/src/storage/mongo/MongoBucketBatch.ts +8 -8
  237. package/src/storage/mongo/MongoCompactor.ts +2 -1
  238. package/src/storage/mongo/MongoPersistedSyncRulesContent.ts +3 -3
  239. package/src/storage/mongo/MongoStorageProvider.ts +31 -0
  240. package/src/storage/mongo/MongoSyncBucketStorage.ts +39 -20
  241. package/src/storage/mongo/MongoSyncRulesLock.ts +1 -1
  242. package/src/storage/mongo/OperationBatch.ts +18 -11
  243. package/src/storage/mongo/PersistedBatch.ts +6 -5
  244. package/src/storage/mongo/models.ts +13 -4
  245. package/src/storage/mongo/util.ts +49 -4
  246. package/src/storage/storage-index.ts +5 -2
  247. package/src/sync/sync.ts +46 -11
  248. package/src/sync/util.ts +0 -1
  249. package/src/system/ServiceContext.ts +68 -0
  250. package/src/system/system-index.ts +1 -1
  251. package/src/util/config/compound-config-collector.ts +30 -31
  252. package/src/util/config/sync-rules/sync-rules-provider.ts +18 -0
  253. package/src/util/config/types.ts +6 -5
  254. package/src/util/config.ts +6 -23
  255. package/src/util/protocol-types.ts +6 -1
  256. package/src/util/util-index.ts +3 -6
  257. package/src/util/utils.ts +55 -39
  258. package/test/src/__snapshots__/sync.test.ts.snap +7 -7
  259. package/test/src/auth.test.ts +7 -7
  260. package/test/src/broadcast_iterable.test.ts +1 -1
  261. package/test/src/checksum_cache.test.ts +3 -3
  262. package/test/src/compacting.test.ts +26 -17
  263. package/test/src/data_storage.test.ts +258 -146
  264. package/test/src/env.ts +1 -3
  265. package/test/src/merge_iterable.test.ts +1 -6
  266. package/test/src/setup.ts +1 -1
  267. package/test/src/stream_utils.ts +42 -0
  268. package/test/src/sync.test.ts +52 -31
  269. package/test/src/util.ts +48 -51
  270. package/test/tsconfig.json +1 -1
  271. package/tsconfig.tsbuildinfo +1 -1
  272. package/dist/auth/SupabaseKeyCollector.d.ts +0 -22
  273. package/dist/auth/SupabaseKeyCollector.js +0 -61
  274. package/dist/auth/SupabaseKeyCollector.js.map +0 -1
  275. package/dist/replication/PgRelation.d.ts +0 -16
  276. package/dist/replication/PgRelation.js +0 -26
  277. package/dist/replication/PgRelation.js.map +0 -1
  278. package/dist/replication/WalConnection.d.ts +0 -34
  279. package/dist/replication/WalConnection.js +0 -190
  280. package/dist/replication/WalConnection.js.map +0 -1
  281. package/dist/replication/WalStream.d.ts +0 -57
  282. package/dist/replication/WalStream.js +0 -515
  283. package/dist/replication/WalStream.js.map +0 -1
  284. package/dist/replication/WalStreamManager.d.ts +0 -30
  285. package/dist/replication/WalStreamManager.js +0 -198
  286. package/dist/replication/WalStreamManager.js.map +0 -1
  287. package/dist/replication/WalStreamRunner.d.ts +0 -38
  288. package/dist/replication/WalStreamRunner.js +0 -155
  289. package/dist/replication/WalStreamRunner.js.map +0 -1
  290. package/dist/replication/util.d.ts +0 -9
  291. package/dist/replication/util.js +0 -62
  292. package/dist/replication/util.js.map +0 -1
  293. package/dist/routes/endpoints/dev.d.ts +0 -312
  294. package/dist/routes/endpoints/dev.js +0 -172
  295. package/dist/routes/endpoints/dev.js.map +0 -1
  296. package/dist/system/CorePowerSyncSystem.d.ts +0 -23
  297. package/dist/system/CorePowerSyncSystem.js +0 -52
  298. package/dist/system/CorePowerSyncSystem.js.map +0 -1
  299. package/dist/util/PgManager.d.ts +0 -24
  300. package/dist/util/PgManager.js +0 -55
  301. package/dist/util/PgManager.js.map +0 -1
  302. package/dist/util/migration_lib.d.ts +0 -11
  303. package/dist/util/migration_lib.js +0 -64
  304. package/dist/util/migration_lib.js.map +0 -1
  305. package/dist/util/pgwire_utils.d.ts +0 -24
  306. package/dist/util/pgwire_utils.js +0 -117
  307. package/dist/util/pgwire_utils.js.map +0 -1
  308. package/dist/util/populate_test_data.d.ts +0 -8
  309. package/dist/util/populate_test_data.js +0 -65
  310. package/dist/util/populate_test_data.js.map +0 -1
  311. package/src/auth/SupabaseKeyCollector.ts +0 -67
  312. package/src/replication/PgRelation.ts +0 -42
  313. package/src/replication/WalConnection.ts +0 -227
  314. package/src/replication/WalStream.ts +0 -624
  315. package/src/replication/WalStreamManager.ts +0 -213
  316. package/src/replication/WalStreamRunner.ts +0 -180
  317. package/src/replication/util.ts +0 -76
  318. package/src/routes/endpoints/dev.ts +0 -199
  319. package/src/system/CorePowerSyncSystem.ts +0 -64
  320. package/src/util/PgManager.ts +0 -64
  321. package/src/util/migration_lib.ts +0 -79
  322. package/src/util/pgwire_utils.ts +0 -139
  323. package/src/util/populate_test_data.ts +0 -78
  324. package/test/src/__snapshots__/pg_test.test.ts.snap +0 -256
  325. package/test/src/large_batch.test.ts +0 -194
  326. package/test/src/pg_test.test.ts +0 -450
  327. package/test/src/schema_changes.test.ts +0 -545
  328. package/test/src/slow_tests.test.ts +0 -338
  329. package/test/src/validation.test.ts +0 -63
  330. package/test/src/wal_stream.test.ts +0 -319
  331. package/test/src/wal_stream_utils.ts +0 -156
package/src/api/schema.ts CHANGED
@@ -1,99 +1,23 @@
1
- import type * as pgwire from '@powersync/service-jpgwire';
2
- import { pgwireRows } from '@powersync/service-jpgwire';
3
- import { DatabaseSchema, internal_routes } from '@powersync/service-types';
1
+ import { internal_routes } from '@powersync/service-types';
4
2
 
5
- import * as util from '../util/util-index.js';
6
- import { CorePowerSyncSystem } from '../system/CorePowerSyncSystem.js';
3
+ import * as api from '../api/api-index.js';
7
4
 
8
- export async function getConnectionsSchema(system: CorePowerSyncSystem): Promise<internal_routes.GetSchemaResponse> {
9
- if (system.config.connection == null) {
10
- return { connections: [] };
5
+ export async function getConnectionsSchema(api: api.RouteAPI): Promise<internal_routes.GetSchemaResponse> {
6
+ if (!api) {
7
+ return {
8
+ connections: []
9
+ };
11
10
  }
12
- const schemas = await getConnectionSchema(system.requirePgPool());
11
+
12
+ const baseConfig = await api.getSourceConfig();
13
+
13
14
  return {
14
15
  connections: [
15
16
  {
16
- schemas,
17
- tag: system.config.connection!.tag,
18
- id: system.config.connection!.id
17
+ schemas: await api.getConnectionSchema(),
18
+ tag: baseConfig.tag!,
19
+ id: baseConfig.id
19
20
  }
20
21
  ]
21
22
  };
22
23
  }
23
-
24
- export async function getConnectionSchema(db: pgwire.PgClient): Promise<DatabaseSchema[]> {
25
- // https://github.com/Borvik/vscode-postgres/blob/88ec5ed061a0c9bced6c5d4ec122d0759c3f3247/src/language/server.ts
26
- const results = await util.retriedQuery(
27
- db,
28
- `SELECT
29
- tbl.schemaname,
30
- tbl.tablename,
31
- tbl.quoted_name,
32
- json_agg(a ORDER BY attnum) as columns
33
- FROM
34
- (
35
- SELECT
36
- n.nspname as schemaname,
37
- c.relname as tablename,
38
- (quote_ident(n.nspname) || '.' || quote_ident(c.relname)) as quoted_name
39
- FROM
40
- pg_catalog.pg_class c
41
- JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
42
- WHERE
43
- c.relkind = 'r'
44
- AND n.nspname not in ('information_schema', 'pg_catalog', 'pg_toast')
45
- AND n.nspname not like 'pg_temp_%'
46
- AND n.nspname not like 'pg_toast_temp_%'
47
- AND c.relnatts > 0
48
- AND has_schema_privilege(n.oid, 'USAGE') = true
49
- AND has_table_privilege(quote_ident(n.nspname) || '.' || quote_ident(c.relname), 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') = true
50
- ) as tbl
51
- LEFT JOIN (
52
- SELECT
53
- attrelid,
54
- attname,
55
- format_type(atttypid, atttypmod) as data_type,
56
- (SELECT typname FROM pg_catalog.pg_type WHERE oid = atttypid) as pg_type,
57
- attnum,
58
- attisdropped
59
- FROM
60
- pg_attribute
61
- ) as a ON (
62
- a.attrelid = tbl.quoted_name::regclass
63
- AND a.attnum > 0
64
- AND NOT a.attisdropped
65
- AND has_column_privilege(tbl.quoted_name, a.attname, 'SELECT, INSERT, UPDATE, REFERENCES')
66
- )
67
- GROUP BY schemaname, tablename, quoted_name`
68
- );
69
- const rows = pgwireRows(results);
70
-
71
- let schemas: Record<string, any> = {};
72
-
73
- for (let row of rows) {
74
- const schema = (schemas[row.schemaname] ??= {
75
- name: row.schemaname,
76
- tables: []
77
- });
78
- const table = {
79
- name: row.tablename,
80
- columns: [] as any[]
81
- };
82
- schema.tables.push(table);
83
-
84
- const columnInfo = JSON.parse(row.columns);
85
- for (let column of columnInfo) {
86
- let pg_type = column.pg_type as string;
87
- if (pg_type.startsWith('_')) {
88
- pg_type = `${pg_type.substring(1)}[]`;
89
- }
90
- table.columns.push({
91
- name: column.attname,
92
- type: column.data_type,
93
- pg_type: pg_type
94
- });
95
- }
96
- }
97
-
98
- return Object.values(schemas);
99
- }
@@ -1,9 +1,9 @@
1
+ import { logger } from '@powersync/lib-services-framework';
1
2
  import * as jose from 'jose';
2
3
  import secs from '../util/secs.js';
3
- import { KeyOptions, KeySpec, SUPPORTED_ALGORITHMS } from './KeySpec.js';
4
- import { KeyCollector } from './KeyCollector.js';
5
4
  import { JwtPayload } from './JwtPayload.js';
6
- import { logger } from '@powersync/lib-services-framework';
5
+ import { KeyCollector } from './KeyCollector.js';
6
+ import { KeyOptions, KeySpec, SUPPORTED_ALGORITHMS } from './KeySpec.js';
7
7
 
8
8
  /**
9
9
  * KeyStore to get keys and verify tokens.
@@ -32,10 +32,13 @@ import { logger } from '@powersync/lib-services-framework';
32
32
  * If we have a matching kid, we can generally get a detailed error (e.g. signature verification failed, invalid algorithm, etc).
33
33
  * If we don't have a matching kid, we'll generally just get an error "Could not find an appropriate key...".
34
34
  */
35
- export class KeyStore {
36
- private collector: KeyCollector;
35
+ export class KeyStore<Collector extends KeyCollector = KeyCollector> {
36
+ /**
37
+ * @internal
38
+ */
39
+ collector: Collector;
37
40
 
38
- constructor(collector: KeyCollector) {
41
+ constructor(collector: Collector) {
39
42
  this.collector = collector;
40
43
  }
41
44
 
@@ -7,4 +7,3 @@ export * from './KeyStore.js';
7
7
  export * from './LeakyBucket.js';
8
8
  export * from './RemoteJWKSCollector.js';
9
9
  export * from './StaticKeyCollector.js';
10
- export * from './SupabaseKeyCollector.js';
@@ -1,10 +1,11 @@
1
1
  import { Command } from 'commander';
2
2
 
3
+ import { logger } from '@powersync/lib-services-framework';
3
4
  import * as utils from '../util/util-index.js';
5
+ import { registerCompactAction } from './commands/compact-action.js';
4
6
  import { registerMigrationAction } from './commands/migrate-action.js';
7
+ import { registerStartAction } from './commands/start-action.js';
5
8
  import { registerTearDownAction } from './commands/teardown-action.js';
6
- import { registerCompactAction, registerStartAction } from './entry-index.js';
7
- import { logger } from '@powersync/lib-services-framework';
8
9
 
9
10
  /**
10
11
  * Generates a Commander program which serves as the entry point
@@ -2,8 +2,8 @@ import { Command } from 'commander';
2
2
 
3
3
  import { logger } from '@powersync/lib-services-framework';
4
4
  import * as v8 from 'v8';
5
- import { createPowerSyncMongo, MongoBucketStorage } from '../../storage/storage-index.js';
6
- import { loadConfig } from '../../util/config.js';
5
+ import * as storage from '../../storage/storage-index.js';
6
+ import * as utils from '../../util/util-index.js';
7
7
  import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
8
8
 
9
9
  const COMMAND_NAME = 'compact';
@@ -26,23 +26,26 @@ export function registerCompactAction(program: Command) {
26
26
  wrapConfigCommand(compactCommand);
27
27
 
28
28
  return compactCommand.description('Compact storage').action(async (options) => {
29
+ logger.info('Compacting storage...');
29
30
  const runnerConfig = extractRunnerOptions(options);
30
-
31
- const config = await loadConfig(runnerConfig);
32
- const { storage } = config;
33
- const psdb = createPowerSyncMongo(storage);
31
+ const configuration = await utils.loadConfig(runnerConfig);
32
+ logger.info('Successfully loaded configuration...');
33
+ const { storage: storageConfig } = configuration;
34
+ logger.info('Connecting to storage...');
35
+ const psdb = storage.createPowerSyncMongo(storageConfig);
34
36
  const client = psdb.client;
35
37
  await client.connect();
36
38
  try {
37
- const bucketStorage = new MongoBucketStorage(psdb, { slot_name_prefix: config.slot_name_prefix });
38
- const active = await bucketStorage.getActiveSyncRules();
39
+ const bucketStorage = new storage.MongoBucketStorage(psdb, { slot_name_prefix: configuration.slot_name_prefix });
40
+ const active = await bucketStorage.getActiveSyncRulesContent();
39
41
  if (active == null) {
40
42
  logger.info('No active instance to compact');
41
43
  return;
42
44
  }
43
45
  const p = bucketStorage.getInstance(active);
46
+ logger.info('Performing compaction...');
44
47
  await p.compact({ memoryLimitMB: COMPACT_MEMORY_LIMIT_MB });
45
- logger.info('done');
48
+ logger.info('Successfully compacted storage.');
46
49
  } catch (e) {
47
50
  logger.error(`Failed to compact: ${e.toString()}`);
48
51
  process.exit(1);
@@ -1,9 +1,8 @@
1
+ import { logger } from '@powersync/lib-services-framework';
1
2
  import { Command } from 'commander';
2
3
 
4
+ import * as migrations from '../../migrations/migrations-index.js';
3
5
  import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
4
- import { migrate } from '../../migrations/migrations.js';
5
- import { Direction } from '../../migrations/definitions.js';
6
- import { logger } from '@powersync/lib-services-framework';
7
6
 
8
7
  const COMMAND_NAME = 'migrate';
9
8
 
@@ -15,13 +14,11 @@ export function registerMigrationAction(program: Command) {
15
14
  return migrationCommand
16
15
  .description('Run migrations')
17
16
  .argument('<direction>', 'Migration direction. `up` or `down`')
18
- .action(async (direction: Direction, options) => {
19
- const runnerConfig = extractRunnerOptions(options);
20
-
17
+ .action(async (direction: migrations.Direction, options) => {
21
18
  try {
22
- await migrate({
19
+ await migrations.migrate({
23
20
  direction,
24
- runner_config: runnerConfig
21
+ runner_config: extractRunnerOptions(options)
25
22
  });
26
23
 
27
24
  process.exit(0);
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
 
3
- import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
4
3
  import { teardown } from '../../runner/teardown.js';
4
+ import { extractRunnerOptions, wrapConfigCommand } from './config-command.js';
5
5
 
6
6
  const COMMAND_NAME = 'teardown';
7
7
 
@@ -12,7 +12,7 @@ export function registerTearDownAction(program: Command) {
12
12
 
13
13
  return teardownCommand
14
14
  .argument('[ack]', 'Type `TEARDOWN` to confirm teardown should occur')
15
- .description('Terminate all replicating sync rules, deleting the replication slots')
15
+ .description('Terminate all replicating sync rules, clear remote configuration and remove all data')
16
16
  .action(async (ack, options) => {
17
17
  if (ack !== 'TEARDOWN') {
18
18
  throw new Error('TEARDOWN was not acknowledged.');
package/src/index.ts CHANGED
@@ -18,8 +18,11 @@ export * as framework from '@powersync/lib-services-framework';
18
18
  export * from './metrics/Metrics.js';
19
19
  export * as metrics from './metrics/Metrics.js';
20
20
 
21
- export * from './migrations/migrations.js';
22
21
  export * as migrations from './migrations/migrations-index.js';
22
+ export * from './migrations/migrations.js';
23
+
24
+ export * from './modules/modules-index.js';
25
+ export * as modules from './modules/modules-index.js';
23
26
 
24
27
  export * from './replication/replication-index.js';
25
28
  export * as replication from './replication/replication-index.js';
@@ -33,7 +36,7 @@ export * as storage from './storage/storage-index.js';
33
36
  export * from './sync/sync-index.js';
34
37
  export * as sync from './sync/sync-index.js';
35
38
 
36
- export * from './system/CorePowerSyncSystem.js';
39
+ export * from './system/system-index.js';
37
40
  export * as system from './system/system-index.js';
38
41
 
39
42
  export * from './util/util-index.js';
@@ -1,13 +1,11 @@
1
1
  import { Attributes, Counter, ObservableGauge, UpDownCounter, ValueType } from '@opentelemetry/api';
2
- import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
3
- import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
4
2
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
5
- import * as jpgwire from '@powersync/service-jpgwire';
6
- import * as util from '../util/util-index.js';
7
- import * as storage from '../storage/storage-index.js';
8
- import { CorePowerSyncSystem } from '../system/CorePowerSyncSystem.js';
3
+ import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
9
4
  import { Resource } from '@opentelemetry/resources';
5
+ import { MeterProvider, MetricReader, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
10
6
  import { logger } from '@powersync/lib-services-framework';
7
+ import * as storage from '../storage/storage-index.js';
8
+ import * as util from '../util/util-index.js';
11
9
 
12
10
  export interface MetricsOptions {
13
11
  disable_telemetry_sharing: boolean;
@@ -202,7 +200,7 @@ Anonymous telemetry is currently: ${options.disable_telemetry_sharing ? 'disable
202
200
  this.concurrent_connections.add(0);
203
201
  }
204
202
 
205
- public configureReplicationMetrics(system: CorePowerSyncSystem) {
203
+ public configureReplicationMetrics(bucketStorage: storage.BucketStorageFactory) {
206
204
  // Rate limit collection of these stats, since it may be an expensive query
207
205
  const MINIMUM_INTERVAL = 60_000;
208
206
 
@@ -211,7 +209,7 @@ Anonymous telemetry is currently: ${options.disable_telemetry_sharing ? 'disable
211
209
 
212
210
  function getMetrics() {
213
211
  if (cachedRequest == null || Date.now() - cacheTimestamp > MINIMUM_INTERVAL) {
214
- cachedRequest = system.storage.getStorageMetrics().catch((e) => {
212
+ cachedRequest = bucketStorage.getStorageMetrics().catch((e) => {
215
213
  logger.error(`Failed to get storage metrics`, e);
216
214
  return null;
217
215
  });
@@ -240,14 +238,6 @@ Anonymous telemetry is currently: ${options.disable_telemetry_sharing ? 'disable
240
238
  result.observe(metrics.replication_size_bytes);
241
239
  }
242
240
  });
243
-
244
- const class_scoped_data_replicated_bytes = this.data_replicated_bytes;
245
- // Record replicated bytes using global jpgwire metrics.
246
- jpgwire.setMetricsRecorder({
247
- addBytesRead(bytes) {
248
- class_scoped_data_replicated_bytes.add(bytes);
249
- }
250
- });
251
241
  }
252
242
 
253
243
  public async getMetricValueForTests(name: string): Promise<number | undefined> {
@@ -2,8 +2,11 @@ import * as mongo from '../../../db/mongo.js';
2
2
  import * as storage from '../../../storage/storage-index.js';
3
3
  import * as utils from '../../../util/util-index.js';
4
4
 
5
- export const up = async (context?: utils.MigrationContext) => {
6
- const config = await utils.loadConfig(context?.runner_config);
5
+ export const up = async (context: utils.MigrationContext) => {
6
+ const { runner_config } = context;
7
+
8
+ const config = await utils.loadConfig(runner_config);
9
+
7
10
  const database = storage.createPowerSyncMongo(config.storage);
8
11
  await mongo.waitForAuth(database.db);
9
12
  try {
@@ -20,8 +23,10 @@ export const up = async (context?: utils.MigrationContext) => {
20
23
  }
21
24
  };
22
25
 
23
- export const down = async (context?: utils.MigrationContext) => {
24
- const config = await utils.loadConfig(context?.runner_config);
26
+ export const down = async (context: utils.MigrationContext) => {
27
+ const { runner_config } = context;
28
+ const config = await utils.loadConfig(runner_config);
29
+
25
30
  const database = storage.createPowerSyncMongo(config.storage);
26
31
  try {
27
32
  if (await database.bucket_parameters.indexExists('lookup')) {
@@ -23,9 +23,11 @@ interface LegacySyncRulesDocument extends storage.SyncRuleDocument {
23
23
  auto_activate?: boolean;
24
24
  }
25
25
 
26
- export const up = async (context?: utils.MigrationContext) => {
27
- const config = await utils.loadConfig(context?.runner_config);
26
+ export const up = async (context: utils.MigrationContext) => {
27
+ const { runner_config } = context;
28
+ const config = await utils.loadConfig(runner_config);
28
29
  const db = storage.createPowerSyncMongo(config.storage);
30
+
29
31
  await mongo.waitForAuth(db.db);
30
32
  try {
31
33
  // We keep the old flags for existing deployments still shutting down.
@@ -68,8 +70,9 @@ export const up = async (context?: utils.MigrationContext) => {
68
70
  }
69
71
  };
70
72
 
71
- export const down = async (context?: utils.MigrationContext) => {
72
- const config = await utils.loadConfig(context?.runner_config);
73
+ export const down = async (context: utils.MigrationContext) => {
74
+ const { runner_config } = context;
75
+ const config = await utils.loadConfig(runner_config);
73
76
 
74
77
  const db = storage.createPowerSyncMongo(config.storage);
75
78
  try {
@@ -1,8 +1,9 @@
1
1
  import * as storage from '../../../storage/storage-index.js';
2
2
  import * as utils from '../../../util/util-index.js';
3
3
 
4
- export const up = async (context?: utils.MigrationContext) => {
5
- const config = await utils.loadConfig(context?.runner_config);
4
+ export const up = async (context: utils.MigrationContext) => {
5
+ const { runner_config } = context;
6
+ const config = await utils.loadConfig(runner_config);
6
7
  const db = storage.createPowerSyncMongo(config.storage);
7
8
 
8
9
  try {
@@ -17,8 +18,9 @@ export const up = async (context?: utils.MigrationContext) => {
17
18
  }
18
19
  };
19
20
 
20
- export const down = async (context?: utils.MigrationContext) => {
21
- const config = await utils.loadConfig(context?.runner_config);
21
+ export const down = async (context: utils.MigrationContext) => {
22
+ const { runner_config } = context;
23
+ const config = await utils.loadConfig(runner_config);
22
24
 
23
25
  const db = storage.createPowerSyncMongo(config.storage);
24
26
 
@@ -2,13 +2,13 @@ import * as fs from 'fs/promises';
2
2
  import * as path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
 
5
+ import { logger } from '@powersync/lib-services-framework';
5
6
  import * as db from '../db/db-index.js';
6
- import * as util from '../util/util-index.js';
7
7
  import * as locks from '../locks/locks-index.js';
8
+ import * as util from '../util/util-index.js';
8
9
  import { Direction } from './definitions.js';
9
- import { createMongoMigrationStore } from './store/migration-store.js';
10
10
  import { execute, writeLogsToStore } from './executor.js';
11
- import { logger } from '@powersync/lib-services-framework';
11
+ import { createMongoMigrationStore } from './store/migration-store.js';
12
12
 
13
13
  const DEFAULT_MONGO_LOCK_COLLECTION = 'locks';
14
14
  const MONGO_LOCK_PROCESS = 'migrations';
@@ -23,18 +23,23 @@ export type MigrationOptions = {
23
23
  runner_config: util.RunnerConfig;
24
24
  };
25
25
 
26
+ export type AutomaticMigrationParams = {
27
+ config: util.ResolvedPowerSyncConfig;
28
+ runner_config: util.RunnerConfig;
29
+ };
30
+
26
31
  /**
27
32
  * Loads migrations and injects a custom context for loading the specified
28
33
  * runner configuration.
29
34
  */
30
- const loadMigrations = async (dir: string, runner_config: util.RunnerConfig) => {
35
+ const loadMigrations = async (dir: string, runnerConfig: util.RunnerConfig) => {
31
36
  const files = await fs.readdir(dir);
32
37
  const migrations = files.filter((file) => {
33
38
  return path.extname(file) === '.js';
34
39
  });
35
40
 
36
41
  const context: util.MigrationContext = {
37
- runner_config
42
+ runner_config: runnerConfig
38
43
  };
39
44
 
40
45
  return await Promise.all(
@@ -55,14 +60,13 @@ const loadMigrations = async (dir: string, runner_config: util.RunnerConfig) =>
55
60
  export const migrate = async (options: MigrationOptions) => {
56
61
  const { direction, runner_config } = options;
57
62
 
63
+ const config = await util.loadConfig(runner_config);
64
+ const { storage } = config;
58
65
  /**
59
66
  * Try and get Mongo from config file.
60
67
  * But this might not be available in Journey Micro as we use the standard Mongo.
61
68
  */
62
69
 
63
- const config = await util.loadConfig(runner_config);
64
- const { storage } = config;
65
-
66
70
  const client = db.mongo.createMongoClient(storage);
67
71
  logger.info('Connecting to MongoDB');
68
72
  await client.connect();
@@ -124,3 +128,15 @@ export const migrate = async (options: MigrationOptions) => {
124
128
  logger.info('Done with migrations');
125
129
  }
126
130
  };
131
+
132
+ /**
133
+ * Ensures automatic migrations are executed
134
+ */
135
+ export const ensureAutomaticMigrations = async (params: AutomaticMigrationParams) => {
136
+ if (!params.config.migrations?.disable_auto_migration) {
137
+ await migrate({
138
+ direction: Direction.Up,
139
+ runner_config: params.runner_config
140
+ });
141
+ }
142
+ };
@@ -0,0 +1,37 @@
1
+ import { ServiceContextContainer } from '../system/ServiceContext.js';
2
+ import { logger } from '@powersync/lib-services-framework';
3
+ import winston from 'winston';
4
+ import { PersistedSyncRulesContent } from '../storage/BucketStorage.js';
5
+
6
+ export interface TearDownOptions {
7
+ /**
8
+ * If required, tear down any configuration/state for the specific sync rules
9
+ */
10
+ syncRules?: PersistedSyncRulesContent[];
11
+ }
12
+
13
+ export interface AbstractModuleOptions {
14
+ name: string;
15
+ }
16
+
17
+ export abstract class AbstractModule {
18
+ protected logger: winston.Logger;
19
+
20
+ protected constructor(protected options: AbstractModuleOptions) {
21
+ this.logger = logger.child({ name: `Module:${options.name}` });
22
+ }
23
+
24
+ /**
25
+ * Initialize the module using any required services from the ServiceContext
26
+ */
27
+ public abstract initialize(context: ServiceContextContainer): Promise<void>;
28
+
29
+ /**
30
+ * Permanently clean up and dispose of any configuration or state for this module.
31
+ */
32
+ public abstract teardown(options: TearDownOptions): Promise<void>;
33
+
34
+ public get name() {
35
+ return this.options.name;
36
+ }
37
+ }
@@ -0,0 +1,34 @@
1
+ import { logger } from '@powersync/lib-services-framework';
2
+ import * as system from '../system/system-index.js';
3
+ import { AbstractModule, TearDownOptions } from './AbstractModule.js';
4
+ /**
5
+ * The module manager keeps track of activated modules
6
+ */
7
+ export class ModuleManager {
8
+ private readonly modules: Map<string, AbstractModule> = new Map();
9
+
10
+ public register(modules: AbstractModule[]) {
11
+ for (const module of modules) {
12
+ if (this.modules.has(module.name)) {
13
+ logger.warn(`Module ${module.name} already registered, skipping.`);
14
+ continue;
15
+ }
16
+ this.modules.set(module.name, module);
17
+ logger.info(`Successfully registered Module ${module.name}.`);
18
+ }
19
+ }
20
+
21
+ async initialize(serviceContext: system.ServiceContextContainer) {
22
+ logger.info(`Initializing modules...`);
23
+ for (const module of this.modules.values()) {
24
+ await module.initialize(serviceContext);
25
+ }
26
+ logger.info(`Successfully Initialized modules.`);
27
+ }
28
+
29
+ async tearDown(options: TearDownOptions) {
30
+ for (const module of this.modules.values()) {
31
+ await module.teardown(options);
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ModuleManager.js';
2
+ export * from './AbstractModule.js';
@@ -0,0 +1,79 @@
1
+ import * as storage from '../storage/storage-index.js';
2
+ import { ErrorRateLimiter } from './ErrorRateLimiter.js';
3
+ import { container, logger } from '@powersync/lib-services-framework';
4
+ import winston from 'winston';
5
+
6
+ export interface AbstractReplicationJobOptions {
7
+ id: string;
8
+ storage: storage.SyncRulesBucketStorage;
9
+ lock: storage.ReplicationLock;
10
+ rateLimiter: ErrorRateLimiter;
11
+ }
12
+
13
+ export abstract class AbstractReplicationJob {
14
+ protected logger: winston.Logger;
15
+ protected abortController = new AbortController();
16
+ protected isReplicatingPromise: Promise<void> | null = null;
17
+
18
+ protected constructor(protected options: AbstractReplicationJobOptions) {
19
+ this.logger = logger.child({ name: `ReplicationJob: ${options.id}` });
20
+ }
21
+
22
+ /**
23
+ * Copy the initial data set from the data source if required and then keep it in sync.
24
+ */
25
+ abstract replicate(): Promise<void>;
26
+
27
+ /**
28
+ * Ensure the connection to the data source remains active
29
+ */
30
+ abstract keepAlive(): Promise<void>;
31
+
32
+ /**
33
+ * Start the replication process
34
+ */
35
+ public async start(): Promise<void> {
36
+ this.isReplicatingPromise = this.replicate()
37
+ .catch((ex) => {
38
+ container.reporter.captureException(ex, {
39
+ metadata: {
40
+ replicator: this.id
41
+ }
42
+ });
43
+ this.logger.error(`Replication failed.`, ex);
44
+ })
45
+ .finally(async () => {
46
+ this.abortController.abort();
47
+ await this.options.lock.release();
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Safely stop the replication process
53
+ */
54
+ public async stop(): Promise<void> {
55
+ this.logger.info(`Stopping ${this.id} replication job for sync rule iteration: ${this.storage.group_id}`);
56
+ this.abortController.abort();
57
+ await this.isReplicatingPromise;
58
+ }
59
+
60
+ public get id() {
61
+ return this.options.id;
62
+ }
63
+
64
+ public get storage() {
65
+ return this.options.storage;
66
+ }
67
+
68
+ protected get lock() {
69
+ return this.options.lock;
70
+ }
71
+
72
+ protected get rateLimiter() {
73
+ return this.options.rateLimiter;
74
+ }
75
+
76
+ public get isStopped(): boolean {
77
+ return this.abortController.signal.aborted;
78
+ }
79
+ }