@powersync/service-module-postgres-storage 0.12.0 → 0.13.1

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 (66) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/@types/migrations/scripts/1771424826685-current-data-pending-deletes.d.ts +3 -0
  4. package/dist/@types/storage/PostgresBucketStorageFactory.d.ts +4 -0
  5. package/dist/@types/storage/PostgresCompactor.d.ts +8 -2
  6. package/dist/@types/storage/PostgresSyncRulesStorage.d.ts +10 -4
  7. package/dist/@types/storage/batch/OperationBatch.d.ts +2 -2
  8. package/dist/@types/storage/batch/PostgresBucketBatch.d.ts +13 -9
  9. package/dist/@types/storage/batch/PostgresPersistedBatch.d.ts +17 -5
  10. package/dist/@types/storage/current-data-store.d.ts +85 -0
  11. package/dist/@types/storage/current-data-table.d.ts +9 -0
  12. package/dist/@types/storage/table-id.d.ts +2 -0
  13. package/dist/@types/types/models/CurrentData.d.ts +18 -3
  14. package/dist/@types/utils/bson.d.ts +1 -1
  15. package/dist/@types/utils/test-utils.d.ts +1 -1
  16. package/dist/migrations/scripts/1771424826685-current-data-pending-deletes.js +8 -0
  17. package/dist/migrations/scripts/1771424826685-current-data-pending-deletes.js.map +1 -0
  18. package/dist/storage/PostgresBucketStorageFactory.js +41 -4
  19. package/dist/storage/PostgresBucketStorageFactory.js.map +1 -1
  20. package/dist/storage/PostgresCompactor.js +14 -6
  21. package/dist/storage/PostgresCompactor.js.map +1 -1
  22. package/dist/storage/PostgresSyncRulesStorage.js +98 -24
  23. package/dist/storage/PostgresSyncRulesStorage.js.map +1 -1
  24. package/dist/storage/batch/OperationBatch.js +2 -1
  25. package/dist/storage/batch/OperationBatch.js.map +1 -1
  26. package/dist/storage/batch/PostgresBucketBatch.js +295 -213
  27. package/dist/storage/batch/PostgresBucketBatch.js.map +1 -1
  28. package/dist/storage/batch/PostgresPersistedBatch.js +86 -81
  29. package/dist/storage/batch/PostgresPersistedBatch.js.map +1 -1
  30. package/dist/storage/current-data-store.js +270 -0
  31. package/dist/storage/current-data-store.js.map +1 -0
  32. package/dist/storage/current-data-table.js +22 -0
  33. package/dist/storage/current-data-table.js.map +1 -0
  34. package/dist/storage/table-id.js +8 -0
  35. package/dist/storage/table-id.js.map +1 -0
  36. package/dist/types/models/CurrentData.js +11 -2
  37. package/dist/types/models/CurrentData.js.map +1 -1
  38. package/dist/utils/bson.js.map +1 -1
  39. package/dist/utils/db.js +9 -0
  40. package/dist/utils/db.js.map +1 -1
  41. package/dist/utils/test-utils.js +13 -6
  42. package/dist/utils/test-utils.js.map +1 -1
  43. package/package.json +8 -8
  44. package/src/migrations/scripts/1771424826685-current-data-pending-deletes.ts +10 -0
  45. package/src/storage/PostgresBucketStorageFactory.ts +53 -5
  46. package/src/storage/PostgresCompactor.ts +17 -8
  47. package/src/storage/PostgresSyncRulesStorage.ts +47 -31
  48. package/src/storage/batch/OperationBatch.ts +4 -3
  49. package/src/storage/batch/PostgresBucketBatch.ts +316 -238
  50. package/src/storage/batch/PostgresPersistedBatch.ts +92 -84
  51. package/src/storage/current-data-store.ts +326 -0
  52. package/src/storage/current-data-table.ts +26 -0
  53. package/src/storage/table-id.ts +9 -0
  54. package/src/types/models/CurrentData.ts +17 -4
  55. package/src/utils/bson.ts +1 -1
  56. package/src/utils/db.ts +10 -0
  57. package/src/utils/test-utils.ts +14 -7
  58. package/test/src/__snapshots__/storage.test.ts.snap +151 -0
  59. package/test/src/__snapshots__/storage_compacting.test.ts.snap +17 -0
  60. package/test/src/__snapshots__/storage_sync.test.ts.snap +1111 -16
  61. package/test/src/env.ts +1 -1
  62. package/test/src/migrations.test.ts +1 -1
  63. package/test/src/storage.test.ts +138 -131
  64. package/test/src/storage_compacting.test.ts +80 -11
  65. package/test/src/storage_sync.test.ts +57 -54
  66. package/test/src/util.ts +4 -4
@@ -1,5 +1,5 @@
1
1
  import * as t from 'ts-codec';
2
- import { hexBuffer, jsonb, pgwire_number } from '../codecs.js';
2
+ import { bigint, hexBuffer, jsonb, pgwire_number } from '../codecs.js';
3
3
 
4
4
  export const CurrentBucket = t.object({
5
5
  bucket: t.string,
@@ -10,7 +10,7 @@ export const CurrentBucket = t.object({
10
10
  export type CurrentBucket = t.Encoded<typeof CurrentBucket>;
11
11
  export type CurrentBucketDecoded = t.Decoded<typeof CurrentBucket>;
12
12
 
13
- export const CurrentData = t.object({
13
+ export const V1CurrentData = t.object({
14
14
  buckets: jsonb(t.array(CurrentBucket)),
15
15
  data: hexBuffer,
16
16
  group_id: pgwire_number,
@@ -19,5 +19,18 @@ export const CurrentData = t.object({
19
19
  source_table: t.string
20
20
  });
21
21
 
22
- export type CurrentData = t.Encoded<typeof CurrentData>;
23
- export type CurrentDataDecoded = t.Decoded<typeof CurrentData>;
22
+ export const V3CurrentData = t.object({
23
+ buckets: jsonb(t.array(CurrentBucket)),
24
+ data: hexBuffer,
25
+ group_id: pgwire_number,
26
+ lookups: t.array(hexBuffer),
27
+ source_key: hexBuffer,
28
+ source_table: t.string,
29
+ pending_delete: t.Null.or(bigint)
30
+ });
31
+
32
+ export type V1CurrentData = t.Encoded<typeof V1CurrentData>;
33
+ export type V1CurrentDataDecoded = t.Decoded<typeof V1CurrentData>;
34
+
35
+ export type V3CurrentData = t.Encoded<typeof V3CurrentData>;
36
+ export type V3CurrentDataDecoded = t.Decoded<typeof V3CurrentData>;
package/src/utils/bson.ts CHANGED
@@ -6,7 +6,7 @@ import * as uuid from 'uuid';
6
6
  * JSONB columns do not directly support storing binary data which could be required in future.
7
7
  */
8
8
 
9
- export function replicaIdToSubkey(tableId: string, id: storage.ReplicaId): string {
9
+ export function replicaIdToSubkey(tableId: storage.SourceTableId, id: storage.ReplicaId): string {
10
10
  // Hashed UUID from the table and id
11
11
  if (storage.isUUID(id)) {
12
12
  // Special case for UUID for backwards-compatiblity
package/src/utils/db.ts CHANGED
@@ -21,6 +21,7 @@ export const dropTables = async (client: lib_postgres.DatabaseClient) => {
21
21
  await db.sql`DROP TABLE IF EXISTS instance`.execute();
22
22
  await db.sql`DROP TABLE IF EXISTS bucket_data`.execute();
23
23
  await db.sql`DROP TABLE IF EXISTS current_data`.execute();
24
+ await db.sql`DROP TABLE IF EXISTS v3_current_data`.execute();
24
25
  await db.sql`DROP TABLE IF EXISTS source_tables`.execute();
25
26
  await db.sql`DROP TABLE IF EXISTS write_checkpoints`.execute();
26
27
  await db.sql`DROP TABLE IF EXISTS custom_write_checkpoints`.execute();
@@ -50,6 +51,15 @@ export const truncateTables = async (db: lib_postgres.DatabaseClient) => {
50
51
  connection_report_events RESTART IDENTITY CASCADE
51
52
  `
52
53
  },
54
+ {
55
+ // TRUNCATE if v3_current_data exists
56
+ statement: `DO $$
57
+ BEGIN
58
+ IF to_regclass('v3_current_data') IS NOT NULL THEN
59
+ EXECUTE 'TRUNCATE TABLE v3_current_data RESTART IDENTITY CASCADE';
60
+ END IF;
61
+ END $$;`
62
+ },
53
63
  {
54
64
  statement: `ALTER SEQUENCE IF EXISTS op_id_sequence RESTART
55
65
  WITH
@@ -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 { logger as defaultLogger, createLogger, transports } from '@powersync/lib-services-framework';
6
7
  import { truncateTables } from './db.js';
7
8
 
8
9
  export type PostgresTestStorageOptions = {
@@ -32,12 +33,20 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
32
33
 
33
34
  const mockServiceContext = { configuration: { storage: BASE_CONFIG } } as unknown as ServiceContext;
34
35
 
36
+ // Migration logs can get really verbose in tests, so only log warnings and up.
37
+ const logger = createLogger({
38
+ level: 'warn',
39
+ format: defaultLogger.format,
40
+ transports: [new transports.Console()]
41
+ });
42
+
35
43
  if (options.down) {
36
44
  await migrationManager.migrate({
37
45
  direction: framework.migrations.Direction.Down,
38
46
  migrationContext: {
39
47
  service_context: mockServiceContext
40
- }
48
+ },
49
+ logger
41
50
  });
42
51
  }
43
52
 
@@ -46,7 +55,8 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
46
55
  direction: framework.migrations.Direction.Up,
47
56
  migrationContext: {
48
57
  service_context: mockServiceContext
49
- }
58
+ },
59
+ logger
50
60
  });
51
61
  }
52
62
  };
@@ -100,10 +110,7 @@ export function postgresTestSetup(factoryOptions: PostgresTestStorageOptions) {
100
110
  throw ex;
101
111
  }
102
112
  },
103
- migrate
113
+ migrate,
114
+ tableIdStrings: true
104
115
  };
105
116
  }
106
-
107
- export function postgresTestStorageFactoryGenerator(factoryOptions: PostgresTestStorageOptions) {
108
- return postgresTestSetup(factoryOptions).factory;
109
- }
@@ -0,0 +1,151 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Postgres Sync Bucket Storage - Data > (insert, delete, insert), (delete) 1`] = `
4
+ [
5
+ {
6
+ "checksum": 2871785649,
7
+ "object_id": "test1",
8
+ "op": "PUT",
9
+ },
10
+ {
11
+ "checksum": 2872534815,
12
+ "object_id": "test1",
13
+ "op": "REMOVE",
14
+ },
15
+ {
16
+ "checksum": 2871785649,
17
+ "object_id": "test1",
18
+ "op": "PUT",
19
+ },
20
+ {
21
+ "checksum": 2872534815,
22
+ "object_id": "test1",
23
+ "op": "REMOVE",
24
+ },
25
+ ]
26
+ `;
27
+
28
+ exports[`Postgres Sync Bucket Storage - Data > (insert, delete, insert), (delete) 2`] = `
29
+ [
30
+ {
31
+ "checksum": 2871785649,
32
+ "object_id": "test1",
33
+ "op": "PUT",
34
+ },
35
+ {
36
+ "checksum": 2872534815,
37
+ "object_id": "test1",
38
+ "op": "REMOVE",
39
+ },
40
+ {
41
+ "checksum": 2871785649,
42
+ "object_id": "test1",
43
+ "op": "PUT",
44
+ },
45
+ {
46
+ "checksum": 2872534815,
47
+ "object_id": "test1",
48
+ "op": "REMOVE",
49
+ },
50
+ ]
51
+ `;
52
+
53
+ exports[`Postgres Sync Bucket Storage - Data > (insert, delete, insert), (delete) 3`] = `
54
+ [
55
+ {
56
+ "checksum": 2871785649,
57
+ "object_id": "test1",
58
+ "op": "PUT",
59
+ },
60
+ {
61
+ "checksum": 2872534815,
62
+ "object_id": "test1",
63
+ "op": "REMOVE",
64
+ },
65
+ {
66
+ "checksum": 2871785649,
67
+ "object_id": "test1",
68
+ "op": "PUT",
69
+ },
70
+ {
71
+ "checksum": 2872534815,
72
+ "object_id": "test1",
73
+ "op": "REMOVE",
74
+ },
75
+ ]
76
+ `;
77
+
78
+ exports[`Postgres Sync Bucket Storage - Data - v1 > (insert, delete, insert), (delete) 1`] = `
79
+ [
80
+ {
81
+ "checksum": 2871785649,
82
+ "object_id": "test1",
83
+ "op": "PUT",
84
+ },
85
+ {
86
+ "checksum": 2872534815,
87
+ "object_id": "test1",
88
+ "op": "REMOVE",
89
+ },
90
+ {
91
+ "checksum": 2871785649,
92
+ "object_id": "test1",
93
+ "op": "PUT",
94
+ },
95
+ {
96
+ "checksum": 2872534815,
97
+ "object_id": "test1",
98
+ "op": "REMOVE",
99
+ },
100
+ ]
101
+ `;
102
+
103
+ exports[`Postgres Sync Bucket Storage - Data - v2 > (insert, delete, insert), (delete) 1`] = `
104
+ [
105
+ {
106
+ "checksum": 2871785649,
107
+ "object_id": "test1",
108
+ "op": "PUT",
109
+ },
110
+ {
111
+ "checksum": 2872534815,
112
+ "object_id": "test1",
113
+ "op": "REMOVE",
114
+ },
115
+ {
116
+ "checksum": 2871785649,
117
+ "object_id": "test1",
118
+ "op": "PUT",
119
+ },
120
+ {
121
+ "checksum": 2872534815,
122
+ "object_id": "test1",
123
+ "op": "REMOVE",
124
+ },
125
+ ]
126
+ `;
127
+
128
+ exports[`Postgres Sync Bucket Storage - Data - v3 > (insert, delete, insert), (delete) 1`] = `
129
+ [
130
+ {
131
+ "checksum": 2871785649,
132
+ "object_id": "test1",
133
+ "op": "PUT",
134
+ },
135
+ {
136
+ "checksum": 2872534815,
137
+ "object_id": "test1",
138
+ "op": "REMOVE",
139
+ },
140
+ {
141
+ "checksum": 2871785649,
142
+ "object_id": "test1",
143
+ "op": "PUT",
144
+ },
145
+ {
146
+ "checksum": 2872534815,
147
+ "object_id": "test1",
148
+ "op": "REMOVE",
149
+ },
150
+ ]
151
+ `;
@@ -0,0 +1,17 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Postgres Sync Bucket Storage Compact > partial checksums after compacting (2) 1`] = `
4
+ {
5
+ "bucket": "1#global[]",
6
+ "checksum": 1196713877,
7
+ "count": 1,
8
+ }
9
+ `;
10
+
11
+ exports[`Postgres Sync Bucket Storage Compact > partial checksums after compacting 1`] = `
12
+ {
13
+ "bucket": "1#global[]",
14
+ "checksum": -134691003,
15
+ "count": 4,
16
+ }
17
+ `;