@powersync/service-module-postgres-storage 0.0.0-dev-20260203155513 → 0.0.0-dev-20260223080959

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 (40) hide show
  1. package/CHANGELOG.md +55 -9
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/@types/migrations/scripts/1771232439485-storage-version.d.ts +3 -0
  4. package/dist/@types/storage/PostgresBucketStorageFactory.d.ts +2 -10
  5. package/dist/@types/storage/PostgresReportStorage.d.ts +1 -5
  6. package/dist/@types/storage/sync-rules/PostgresPersistedSyncRulesContent.d.ts +1 -10
  7. package/dist/@types/types/models/SyncRules.d.ts +3 -2
  8. package/dist/@types/utils/db.d.ts +9 -0
  9. package/dist/migrations/scripts/1771232439485-storage-version.js +111 -0
  10. package/dist/migrations/scripts/1771232439485-storage-version.js.map +1 -0
  11. package/dist/storage/PostgresBucketStorageFactory.js +8 -55
  12. package/dist/storage/PostgresBucketStorageFactory.js.map +1 -1
  13. package/dist/storage/PostgresReportStorage.js +0 -12
  14. package/dist/storage/PostgresReportStorage.js.map +1 -1
  15. package/dist/storage/batch/PostgresBucketBatch.js +4 -3
  16. package/dist/storage/batch/PostgresBucketBatch.js.map +1 -1
  17. package/dist/storage/sync-rules/PostgresPersistedSyncRulesContent.js +13 -30
  18. package/dist/storage/sync-rules/PostgresPersistedSyncRulesContent.js.map +1 -1
  19. package/dist/types/models/SyncRules.js +1 -0
  20. package/dist/types/models/SyncRules.js.map +1 -1
  21. package/dist/utils/db.js +32 -0
  22. package/dist/utils/db.js.map +1 -1
  23. package/dist/utils/test-utils.js +39 -10
  24. package/dist/utils/test-utils.js.map +1 -1
  25. package/package.json +8 -8
  26. package/src/migrations/scripts/1771232439485-storage-version.ts +44 -0
  27. package/src/storage/PostgresBucketStorageFactory.ts +9 -63
  28. package/src/storage/PostgresReportStorage.ts +3 -16
  29. package/src/storage/batch/PostgresBucketBatch.ts +10 -3
  30. package/src/storage/sync-rules/PostgresPersistedSyncRulesContent.ts +19 -33
  31. package/src/types/models/SyncRules.ts +1 -0
  32. package/src/utils/db.ts +37 -0
  33. package/src/utils/test-utils.ts +30 -10
  34. package/test/src/__snapshots__/storage_sync.test.ts.snap +1116 -21
  35. package/test/src/migrations.test.ts +8 -1
  36. package/test/src/storage.test.ts +11 -11
  37. package/test/src/storage_sync.test.ts +146 -4
  38. package/test/src/util.ts +3 -0
  39. package/test/tsconfig.json +2 -6
  40. package/test/src/__snapshots__/storage.test.ts.snap +0 -9
package/src/utils/db.ts CHANGED
@@ -9,6 +9,9 @@ export const NOTIFICATION_CHANNEL = 'powersynccheckpoints';
9
9
  */
10
10
  export const sql = lib_postgres.sql;
11
11
 
12
+ /**
13
+ * Drop all Postgres storage tables used by the service, including migrations.
14
+ */
12
15
  export const dropTables = async (client: lib_postgres.DatabaseClient) => {
13
16
  // Lock a connection for automatic schema search paths
14
17
  await client.lockConnection(async (db) => {
@@ -23,5 +26,39 @@ export const dropTables = async (client: lib_postgres.DatabaseClient) => {
23
26
  await db.sql`DROP TABLE IF EXISTS custom_write_checkpoints`.execute();
24
27
  await db.sql`DROP SEQUENCE IF EXISTS op_id_sequence`.execute();
25
28
  await db.sql`DROP SEQUENCE IF EXISTS sync_rules_id_sequence`.execute();
29
+ await db.sql`DROP TABLE IF EXISTS migrations`.execute();
26
30
  });
27
31
  };
32
+
33
+ /**
34
+ * Clear all Postgres storage tables and reset sequences.
35
+ *
36
+ * Does not clear migration state.
37
+ */
38
+ export const truncateTables = async (db: lib_postgres.DatabaseClient) => {
39
+ // Lock a connection for automatic schema search paths
40
+ await db.query(
41
+ {
42
+ statement: `TRUNCATE TABLE bucket_data,
43
+ bucket_parameters,
44
+ sync_rules,
45
+ instance,
46
+ current_data,
47
+ source_tables,
48
+ write_checkpoints,
49
+ custom_write_checkpoints,
50
+ connection_report_events RESTART IDENTITY CASCADE
51
+ `
52
+ },
53
+ {
54
+ statement: `ALTER SEQUENCE IF EXISTS op_id_sequence RESTART
55
+ WITH
56
+ 1`
57
+ },
58
+ {
59
+ statement: `ALTER SEQUENCE IF EXISTS sync_rules_id_sequence RESTART
60
+ WITH
61
+ 1`
62
+ }
63
+ );
64
+ };
@@ -3,6 +3,7 @@ import { PostgresMigrationAgent } from '../migrations/PostgresMigrationAgent.js'
3
3
  import { normalizePostgresStorageConfig, PostgresStorageConfigDecoded } from '../types/types.js';
4
4
  import { PostgresReportStorage } from '../storage/PostgresReportStorage.js';
5
5
  import { PostgresBucketStorageFactory } from '../storage/PostgresBucketStorageFactory.js';
6
+ import { truncateTables } from './db.js';
6
7
 
7
8
  export type PostgresTestStorageOptions = {
8
9
  url: string;
@@ -22,7 +23,7 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
22
23
 
23
24
  const TEST_CONNECTION_OPTIONS = normalizePostgresStorageConfig(BASE_CONFIG);
24
25
 
25
- const migrate = async (direction: framework.migrations.Direction) => {
26
+ const runMigrations = async (options: { down: boolean; up: boolean }) => {
26
27
  await using migrationManager: PowerSyncMigrationManager = new framework.MigrationManager();
27
28
  await using migrationAgent = factoryOptions.migrationAgent
28
29
  ? factoryOptions.migrationAgent(BASE_CONFIG)
@@ -31,14 +32,16 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
31
32
 
32
33
  const mockServiceContext = { configuration: { storage: BASE_CONFIG } } as unknown as ServiceContext;
33
34
 
34
- await migrationManager.migrate({
35
- direction: framework.migrations.Direction.Down,
36
- migrationContext: {
37
- service_context: mockServiceContext
38
- }
39
- });
35
+ if (options.down) {
36
+ await migrationManager.migrate({
37
+ direction: framework.migrations.Direction.Down,
38
+ migrationContext: {
39
+ service_context: mockServiceContext
40
+ }
41
+ });
42
+ }
40
43
 
41
- if (direction == framework.migrations.Direction.Up) {
44
+ if (options.up) {
42
45
  await migrationManager.migrate({
43
46
  direction: framework.migrations.Direction.Up,
44
47
  migrationContext: {
@@ -48,11 +51,28 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
48
51
  }
49
52
  };
50
53
 
54
+ const migrate = async (direction: framework.migrations.Direction) => {
55
+ await runMigrations({
56
+ down: true,
57
+ up: direction == framework.migrations.Direction.Up
58
+ });
59
+ };
60
+
61
+ const clearStorage = async () => {
62
+ await runMigrations({ down: false, up: true });
63
+
64
+ await using storageFactory = new PostgresBucketStorageFactory({
65
+ config: TEST_CONNECTION_OPTIONS,
66
+ slot_name_prefix: 'test_'
67
+ });
68
+ await truncateTables(storageFactory.db);
69
+ };
70
+
51
71
  return {
52
72
  reportFactory: async (options?: TestStorageOptions) => {
53
73
  try {
54
74
  if (!options?.doNotClear) {
55
- await migrate(framework.migrations.Direction.Up);
75
+ await clearStorage();
56
76
  }
57
77
 
58
78
  return new PostgresReportStorage({
@@ -67,7 +87,7 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
67
87
  factory: async (options?: TestStorageOptions) => {
68
88
  try {
69
89
  if (!options?.doNotClear) {
70
- await migrate(framework.migrations.Direction.Up);
90
+ await clearStorage();
71
91
  }
72
92
 
73
93
  return new PostgresBucketStorageFactory({