@powersync/service-core 1.21.0 → 1.23.0

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 (151) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/api/RouteAPI.d.ts +2 -2
  3. package/dist/api/diagnostics.d.ts +12 -1
  4. package/dist/api/diagnostics.js +34 -22
  5. package/dist/api/diagnostics.js.map +1 -1
  6. package/dist/auth/RemoteJWKSCollector.js +3 -2
  7. package/dist/auth/RemoteJWKSCollector.js.map +1 -1
  8. package/dist/entry/commands/compact-action.js +1 -1
  9. package/dist/entry/commands/compact-action.js.map +1 -1
  10. package/dist/modules/AbstractModule.d.ts +6 -2
  11. package/dist/modules/AbstractModule.js.map +1 -1
  12. package/dist/replication/AbstractReplicator.d.ts +2 -2
  13. package/dist/replication/AbstractReplicator.js +24 -23
  14. package/dist/replication/AbstractReplicator.js.map +1 -1
  15. package/dist/replication/RelationCache.d.ts +9 -2
  16. package/dist/replication/RelationCache.js +21 -2
  17. package/dist/replication/RelationCache.js.map +1 -1
  18. package/dist/replication/ReplicationModule.d.ts +3 -3
  19. package/dist/replication/ReplicationModule.js.map +1 -1
  20. package/dist/routes/configure-fastify.d.ts +12 -12
  21. package/dist/routes/configure-fastify.js +3 -1
  22. package/dist/routes/configure-fastify.js.map +1 -1
  23. package/dist/routes/endpoints/admin.d.ts +24 -24
  24. package/dist/routes/endpoints/admin.js +49 -35
  25. package/dist/routes/endpoints/admin.js.map +1 -1
  26. package/dist/routes/endpoints/checkpointing.js +1 -1
  27. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  28. package/dist/routes/endpoints/socket-route.js +1 -1
  29. package/dist/routes/endpoints/socket-route.js.map +1 -1
  30. package/dist/routes/endpoints/sync-rules.js +22 -13
  31. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  32. package/dist/routes/endpoints/sync-stream.js +1 -1
  33. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  34. package/dist/routes/route-register.d.ts +2 -0
  35. package/dist/routes/route-register.js +65 -3
  36. package/dist/routes/route-register.js.map +1 -1
  37. package/dist/runner/teardown.js +8 -8
  38. package/dist/runner/teardown.js.map +1 -1
  39. package/dist/storage/BucketStorageBatch.d.ts +29 -6
  40. package/dist/storage/BucketStorageBatch.js.map +1 -1
  41. package/dist/storage/BucketStorageFactory.d.ts +26 -27
  42. package/dist/storage/BucketStorageFactory.js +5 -19
  43. package/dist/storage/BucketStorageFactory.js.map +1 -1
  44. package/dist/storage/ParsedSyncConfigSet.d.ts +23 -0
  45. package/dist/storage/ParsedSyncConfigSet.js +2 -0
  46. package/dist/storage/ParsedSyncConfigSet.js.map +1 -0
  47. package/dist/storage/PersistedReplicationStream.d.ts +32 -0
  48. package/dist/storage/PersistedReplicationStream.js +26 -0
  49. package/dist/storage/PersistedReplicationStream.js.map +1 -0
  50. package/dist/storage/PersistedSyncConfigContent.d.ts +60 -0
  51. package/dist/storage/PersistedSyncConfigContent.js +123 -0
  52. package/dist/storage/PersistedSyncConfigContent.js.map +1 -0
  53. package/dist/storage/PersistedSyncConfigStatus.d.ts +13 -0
  54. package/dist/storage/PersistedSyncConfigStatus.js +2 -0
  55. package/dist/storage/PersistedSyncConfigStatus.js.map +1 -0
  56. package/dist/storage/SourceEntity.d.ts +8 -1
  57. package/dist/storage/SourceTable.d.ts +37 -10
  58. package/dist/storage/SourceTable.js +50 -14
  59. package/dist/storage/SourceTable.js.map +1 -1
  60. package/dist/storage/SyncRulesBucketStorage.d.ts +80 -24
  61. package/dist/storage/SyncRulesBucketStorage.js.map +1 -1
  62. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +117 -0
  63. package/dist/storage/implementation/BucketDefinitionMapping.js +277 -0
  64. package/dist/storage/implementation/BucketDefinitionMapping.js.map +1 -0
  65. package/dist/storage/implementation/IncrementalReprocessingCompatibility.d.ts +6 -0
  66. package/dist/storage/implementation/IncrementalReprocessingCompatibility.js +31 -0
  67. package/dist/storage/implementation/IncrementalReprocessingCompatibility.js.map +1 -0
  68. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.d.ts +17 -0
  69. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.js +62 -0
  70. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.js.map +1 -0
  71. package/dist/storage/implementation/ReplicationStreamStorageIds.d.ts +15 -0
  72. package/dist/storage/implementation/ReplicationStreamStorageIds.js +20 -0
  73. package/dist/storage/implementation/ReplicationStreamStorageIds.js.map +1 -0
  74. package/dist/storage/storage-index.d.ts +8 -1
  75. package/dist/storage/storage-index.js +8 -1
  76. package/dist/storage/storage-index.js.map +1 -1
  77. package/dist/sync/BucketChecksumState.d.ts +4 -4
  78. package/dist/sync/BucketChecksumState.js +1 -1
  79. package/dist/sync/BucketChecksumState.js.map +1 -1
  80. package/dist/sync/sync.d.ts +2 -2
  81. package/dist/sync/sync.js +5 -0
  82. package/dist/sync/sync.js.map +1 -1
  83. package/dist/tracing/PerformanceTracer.d.ts +17 -1
  84. package/dist/tracing/PerformanceTracer.js +3 -0
  85. package/dist/tracing/PerformanceTracer.js.map +1 -1
  86. package/dist/util/checkpointing.js +1 -1
  87. package/dist/util/checkpointing.js.map +1 -1
  88. package/dist/util/config/types.d.ts +1 -1
  89. package/dist/util/lsn.d.ts +4 -0
  90. package/dist/util/lsn.js +10 -0
  91. package/dist/util/lsn.js.map +1 -1
  92. package/dist/util/util-index.d.ts +1 -0
  93. package/dist/util/util-index.js +1 -0
  94. package/dist/util/util-index.js.map +1 -1
  95. package/dist/util/utils.d.ts +5 -0
  96. package/dist/util/utils.js +7 -0
  97. package/dist/util/utils.js.map +1 -1
  98. package/package.json +6 -7
  99. package/src/api/RouteAPI.ts +2 -2
  100. package/src/api/diagnostics.ts +45 -28
  101. package/src/auth/RemoteJWKSCollector.ts +3 -1
  102. package/src/entry/commands/compact-action.ts +1 -1
  103. package/src/modules/AbstractModule.ts +6 -2
  104. package/src/replication/AbstractReplicator.ts +27 -26
  105. package/src/replication/RelationCache.ts +23 -4
  106. package/src/replication/ReplicationModule.ts +2 -3
  107. package/src/routes/configure-fastify.ts +8 -1
  108. package/src/routes/endpoints/admin.ts +75 -49
  109. package/src/routes/endpoints/checkpointing.ts +1 -1
  110. package/src/routes/endpoints/socket-route.ts +1 -1
  111. package/src/routes/endpoints/sync-rules.ts +23 -13
  112. package/src/routes/endpoints/sync-stream.ts +1 -1
  113. package/src/routes/route-register.ts +73 -4
  114. package/src/runner/teardown.ts +8 -8
  115. package/src/storage/BucketStorageBatch.ts +32 -7
  116. package/src/storage/BucketStorageFactory.ts +36 -40
  117. package/src/storage/ParsedSyncConfigSet.ts +25 -0
  118. package/src/storage/PersistedReplicationStream.ts +55 -0
  119. package/src/storage/PersistedSyncConfigContent.ts +188 -0
  120. package/src/storage/PersistedSyncConfigStatus.ts +14 -0
  121. package/src/storage/SourceEntity.ts +9 -1
  122. package/src/storage/SourceTable.ts +72 -21
  123. package/src/storage/SyncRulesBucketStorage.ts +87 -26
  124. package/src/storage/implementation/BucketDefinitionMapping.ts +436 -0
  125. package/src/storage/implementation/IncrementalReprocessingCompatibility.ts +41 -0
  126. package/src/storage/implementation/IncrementalReprocessingSyncConfigLog.ts +109 -0
  127. package/src/storage/implementation/ReplicationStreamStorageIds.ts +21 -0
  128. package/src/storage/storage-index.ts +9 -1
  129. package/src/sync/BucketChecksumState.ts +5 -5
  130. package/src/sync/sync.ts +8 -3
  131. package/src/tracing/PerformanceTracer.ts +24 -1
  132. package/src/util/checkpointing.ts +1 -1
  133. package/src/util/config/types.ts +1 -1
  134. package/src/util/lsn.ts +9 -0
  135. package/src/util/util-index.ts +1 -0
  136. package/src/util/utils.ts +8 -0
  137. package/test/src/auth.test.ts +11 -0
  138. package/test/src/diagnostics.test.ts +64 -33
  139. package/test/src/module-loader.test.ts +33 -1
  140. package/test/src/routes/admin.test.ts +180 -18
  141. package/test/src/routes/error-handler.integration.test.ts +275 -0
  142. package/test/src/routes/mocks.ts +6 -2
  143. package/test/src/routes/stream.test.ts +15 -4
  144. package/test/src/storage/SourceTable.test.ts +89 -0
  145. package/test/src/sync/BucketChecksumState.test.ts +25 -17
  146. package/tsconfig.json +1 -4
  147. package/tsconfig.tsbuildinfo +1 -1
  148. package/dist/storage/PersistedSyncRulesContent.d.ts +0 -59
  149. package/dist/storage/PersistedSyncRulesContent.js +0 -100
  150. package/dist/storage/PersistedSyncRulesContent.js.map +0 -1
  151. package/src/storage/PersistedSyncRulesContent.ts +0 -174
@@ -0,0 +1,26 @@
1
+ import { logger as defaultLogger, ErrorCode, ServiceError } from '@powersync/lib-services-framework';
2
+ import { STORAGE_VERSION_CONFIG } from './StorageVersionConfig.js';
3
+ export class PersistedReplicationStream {
4
+ replicationStreamId;
5
+ replicationJobId;
6
+ replicationStreamName;
7
+ state;
8
+ storageVersion;
9
+ logger;
10
+ constructor(data) {
11
+ this.replicationStreamId = data.replicationStreamId;
12
+ this.replicationJobId = data.replicationJobId ?? String(data.replicationStreamId);
13
+ this.replicationStreamName = data.replicationStreamName;
14
+ this.state = data.state;
15
+ this.storageVersion = data.storageVersion;
16
+ this.logger = defaultLogger.child({ prefix: `[${this.replicationStreamName}] ` });
17
+ }
18
+ getStorageConfig() {
19
+ const storageConfig = STORAGE_VERSION_CONFIG[this.storageVersion];
20
+ if (storageConfig == null) {
21
+ throw new ServiceError(ErrorCode.PSYNC_S1005, `Unsupported storage version ${this.storageVersion} for replication stream ${this.replicationStreamId}`);
22
+ }
23
+ return storageConfig;
24
+ }
25
+ }
26
+ //# sourceMappingURL=PersistedReplicationStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedReplicationStream.js","sourceRoot":"","sources":["../../src/storage/PersistedReplicationStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAMrG,OAAO,EAAE,sBAAsB,EAAwB,MAAM,2BAA2B,CAAC;AAEzF,MAAM,OAAgB,0BAA0B;IACrC,mBAAmB,CAAS;IAC5B,gBAAgB,CAAS;IACzB,qBAAqB,CAAS;IAC9B,KAAK,CAAgB;IACrB,cAAc,CAAS;IACvB,MAAM,CAAS;IAKxB,YAAY,IAAoC;QAC9C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACpD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClF,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,gBAAgB;QACd,MAAM,aAAa,GAAG,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;YAC1B,MAAM,IAAI,YAAY,CACpB,SAAS,CAAC,WAAW,EACrB,+BAA+B,IAAI,CAAC,cAAc,2BAA2B,IAAI,CAAC,mBAAmB,EAAE,CACxG,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;CAKF"}
@@ -0,0 +1,60 @@
1
+ import { SyncConfigWithErrors } from '@powersync/service-sync-rules';
2
+ import { Logger } from 'winston';
3
+ import { SerializedSyncPlan, UpdateSyncRulesOptions } from './BucketStorageFactory.js';
4
+ import { ParsedSyncConfigSet } from './ParsedSyncConfigSet.js';
5
+ import { PersistedSyncConfigStatus } from './PersistedSyncConfigStatus.js';
6
+ import { StorageVersionConfig } from './StorageVersionConfig.js';
7
+ export interface ParsePersistedSyncConfigContentOptions {
8
+ content: string;
9
+ compiledPlan: SerializedSyncPlan | null;
10
+ storageVersion: number;
11
+ parseOptions: ParseSyncConfigOptions;
12
+ }
13
+ export declare function parsePersistedSyncConfigContent(options: ParsePersistedSyncConfigContentOptions): SyncConfigWithErrors;
14
+ /**
15
+ * Immutable sync config content for one sync config inside a replication stream.
16
+ *
17
+ * This represents the persisted config content. Fetch per-config status with
18
+ * {@link getSyncConfigStatus}. Use {@link PersistedReplicationStream} for stream
19
+ * lifecycle concerns such as locking and termination.
20
+ */
21
+ export declare abstract class PersistedSyncConfigContent implements PersistedSyncConfigContentData {
22
+ readonly replicationStreamId: number;
23
+ readonly sync_rules_content: string;
24
+ readonly compiled_plan: SerializedSyncPlan | null;
25
+ readonly replicationStreamName: string;
26
+ readonly storageVersion: number;
27
+ readonly logger: Logger;
28
+ readonly syncConfigId: PersistedSyncConfigId | null;
29
+ constructor(data: PersistedSyncConfigContentData);
30
+ /**
31
+ * Load the storage config.
32
+ *
33
+ * This may throw if the persisted storage version is not supported.
34
+ */
35
+ getStorageConfig(): StorageVersionConfig;
36
+ /**
37
+ * Parse only this config's content into a single {@link SyncConfigWithErrors}.
38
+ *
39
+ * This does not depend on any other configs in the same replication stream.
40
+ */
41
+ protected parseSingleConfig(options: ParseSyncConfigOptions): SyncConfigWithErrors;
42
+ parsed(options: ParseSyncConfigOptions): ParsedSyncConfigSet;
43
+ asUpdateOptions(options?: Omit<UpdateSyncRulesOptions, 'config'>): UpdateSyncRulesOptions;
44
+ /**
45
+ * Fetch the current persisted state for this exact sync config.
46
+ */
47
+ abstract getSyncConfigStatus(): Promise<PersistedSyncConfigStatus | null>;
48
+ }
49
+ export interface PersistedSyncConfigContentData {
50
+ readonly replicationStreamId: number;
51
+ readonly sync_rules_content: string;
52
+ readonly compiled_plan: SerializedSyncPlan | null;
53
+ readonly replicationStreamName: string;
54
+ readonly storageVersion: number;
55
+ readonly syncConfigId?: PersistedSyncConfigId | null;
56
+ }
57
+ export type PersistedSyncConfigId = string;
58
+ export interface ParseSyncConfigOptions {
59
+ defaultSchema: string;
60
+ }
@@ -0,0 +1,123 @@
1
+ import { logger as defaultLogger, ErrorCode, ServiceError } from '@powersync/lib-services-framework';
2
+ import { CompatibilityContext, CompatibilityOption, DEFAULT_HYDRATION_STATE, deserializeSyncPlan, nodeSqlite, PrecompiledSyncConfig, SqlEventDescriptor, SqlSyncRules, versionedHydrationState, YamlError } from '@powersync/service-sync-rules';
3
+ import * as sqlite from 'node:sqlite';
4
+ import { STORAGE_VERSION_CONFIG } from './StorageVersionConfig.js';
5
+ export function parsePersistedSyncConfigContent(options) {
6
+ const { content, compiledPlan, storageVersion, parseOptions } = options;
7
+ if (compiledPlan == null) {
8
+ // Fallback: Only parse from YAML if no compiled plan is available.
9
+ return SqlSyncRules.fromYaml(content, parseOptions);
10
+ }
11
+ const plan = deserializeSyncPlan(compiledPlan.plan);
12
+ const compatibility = CompatibilityContext.deserialize(compiledPlan.compatibility);
13
+ const eventDefinitions = [];
14
+ for (const [name, queries] of Object.entries(compiledPlan.eventDescriptors)) {
15
+ const descriptor = new SqlEventDescriptor(name, compatibility);
16
+ for (const query of queries) {
17
+ descriptor.addSourceQuery(query, parseOptions);
18
+ }
19
+ eventDefinitions.push(descriptor);
20
+ }
21
+ const precompiled = new PrecompiledSyncConfig(plan, compatibility, eventDefinitions, {
22
+ defaultSchema: parseOptions.defaultSchema,
23
+ sourceText: content
24
+ });
25
+ // Note: If the original content did not define a storage version, this will still set the storage version.
26
+ // This means asUpdateOptions will not change the storage version, even if the default changes.
27
+ precompiled.storageVersion = storageVersion;
28
+ const errors = [];
29
+ if (compiledPlan.errors) {
30
+ for (const error of compiledPlan.errors) {
31
+ const location = error.location && {
32
+ start: error.location.start_offset,
33
+ end: error.location.end_offset
34
+ };
35
+ const asYamlError = new YamlError(new Error(error.message), location);
36
+ asYamlError.type = error.level;
37
+ errors.push(asYamlError);
38
+ }
39
+ }
40
+ return { config: precompiled, errors };
41
+ }
42
+ /**
43
+ * Immutable sync config content for one sync config inside a replication stream.
44
+ *
45
+ * This represents the persisted config content. Fetch per-config status with
46
+ * {@link getSyncConfigStatus}. Use {@link PersistedReplicationStream} for stream
47
+ * lifecycle concerns such as locking and termination.
48
+ */
49
+ export class PersistedSyncConfigContent {
50
+ replicationStreamId;
51
+ sync_rules_content;
52
+ compiled_plan;
53
+ replicationStreamName;
54
+ storageVersion;
55
+ logger;
56
+ syncConfigId;
57
+ constructor(data) {
58
+ this.replicationStreamId = data.replicationStreamId;
59
+ this.sync_rules_content = data.sync_rules_content;
60
+ this.compiled_plan = data.compiled_plan;
61
+ this.replicationStreamName = data.replicationStreamName;
62
+ this.storageVersion = data.storageVersion;
63
+ this.syncConfigId = data.syncConfigId ?? null;
64
+ this.logger = defaultLogger.child({ prefix: `[${this.replicationStreamName}] ` });
65
+ }
66
+ /**
67
+ * Load the storage config.
68
+ *
69
+ * This may throw if the persisted storage version is not supported.
70
+ */
71
+ getStorageConfig() {
72
+ const storageConfig = STORAGE_VERSION_CONFIG[this.storageVersion];
73
+ if (storageConfig == null) {
74
+ throw new ServiceError(ErrorCode.PSYNC_S1005, `Unsupported storage version ${this.storageVersion} for replication stream ${this.replicationStreamId}`);
75
+ }
76
+ return storageConfig;
77
+ }
78
+ /**
79
+ * Parse only this config's content into a single {@link SyncConfigWithErrors}.
80
+ *
81
+ * This does not depend on any other configs in the same replication stream.
82
+ */
83
+ parseSingleConfig(options) {
84
+ return parsePersistedSyncConfigContent({
85
+ content: this.sync_rules_content,
86
+ compiledPlan: this.compiled_plan,
87
+ storageVersion: this.storageVersion,
88
+ parseOptions: options
89
+ });
90
+ }
91
+ parsed(options) {
92
+ let hydrationState;
93
+ const config = this.parseSingleConfig(options);
94
+ const storageConfig = this.getStorageConfig();
95
+ if (storageConfig.versionedBuckets ||
96
+ config.config.compatibility.isEnabled(CompatibilityOption.versionedBucketIds)) {
97
+ hydrationState = versionedHydrationState(this.replicationStreamId);
98
+ }
99
+ else {
100
+ hydrationState = DEFAULT_HYDRATION_STATE;
101
+ }
102
+ let hydrated;
103
+ return {
104
+ replicationStreamId: this.replicationStreamId,
105
+ replicationStreamName: this.replicationStreamName,
106
+ syncConfigs: [config],
107
+ hydrationState,
108
+ get hydratedSyncConfig() {
109
+ hydrated ??= config.config.hydrate({ hydrationState, sqlite: nodeSqlite(sqlite) });
110
+ return hydrated;
111
+ }
112
+ };
113
+ }
114
+ asUpdateOptions(options) {
115
+ // defaultSchema is not relevant for the parsed version here
116
+ const parsed = this.parseSingleConfig({ defaultSchema: 'not_applicable' });
117
+ return {
118
+ config: { yaml: this.sync_rules_content, plan: this.compiled_plan, parsed },
119
+ ...options
120
+ };
121
+ }
122
+ }
123
+ //# sourceMappingURL=PersistedSyncConfigContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedSyncConfigContent.js","sourceRoot":"","sources":["../../src/storage/PersistedSyncConfigContent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { SyncRuleState } from './BucketStorage.js';
2
+ import { PersistedSyncConfigId } from './PersistedSyncConfigContent.js';
3
+ export interface PersistedSyncConfigStatus {
4
+ readonly id: PersistedSyncConfigId;
5
+ readonly replicationStreamId: number;
6
+ readonly state: SyncRuleState;
7
+ readonly snapshot_done?: boolean;
8
+ readonly last_checkpoint_lsn: string | null;
9
+ readonly last_fatal_error?: string | null;
10
+ readonly last_fatal_error_ts?: Date | null;
11
+ readonly last_keepalive_ts?: Date | null;
12
+ readonly last_checkpoint_ts?: Date | null;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PersistedSyncConfigStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedSyncConfigStatus.js","sourceRoot":"","sources":["../../src/storage/PersistedSyncConfigStatus.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import { SourceTableRef } from '@powersync/service-sync-rules';
1
2
  export interface ColumnDescriptor {
2
3
  name: string;
3
4
  /**
@@ -9,7 +10,7 @@ export interface ColumnDescriptor {
9
10
  */
10
11
  typeId?: number;
11
12
  }
12
- export interface SourceEntityDescriptor {
13
+ export interface SourceEntityDescriptor extends SourceTableRef {
13
14
  /**
14
15
  * The internal id of the source entity structure in the database.
15
16
  * If undefined, the schema and name are used as the identifier.
@@ -22,4 +23,10 @@ export interface SourceEntityDescriptor {
22
23
  * The columns that are used to uniquely identify a record in the source entity.
23
24
  */
24
25
  replicaIdColumns: ColumnDescriptor[];
26
+ /**
27
+ * Whether the source always sends complete row data with each operation (e.g. Postgres REPLICA
28
+ * IDENTITY FULL). When true, no current_data copy is needed. Undefined means the source does not
29
+ * report this, in which case we default to keeping a copy.
30
+ */
31
+ sendsCompleteRows?: boolean;
25
32
  }
@@ -1,24 +1,33 @@
1
+ import { BucketDataSource, BucketDefinitionId, ParameterIndexId, ParameterIndexLookupCreator, SourceTableRef } from '@powersync/service-sync-rules';
1
2
  import { bson } from '../index.js';
2
- import { ColumnDescriptor, SourceEntityDescriptor } from './SourceEntity.js';
3
+ import { ColumnDescriptor } from './SourceEntity.js';
3
4
  /**
4
5
  * Format of the id depends on the bucket storage module. It should be consistent within the module.
5
6
  */
6
7
  export type SourceTableId = string | bson.ObjectId;
7
8
  export interface SourceTableOptions {
8
9
  id: SourceTableId;
9
- connectionTag: string;
10
+ ref: SourceTableRef;
10
11
  objectId: number | string | undefined;
11
- schema: string;
12
- name: string;
13
12
  replicaIdColumns: ColumnDescriptor[];
14
13
  snapshotComplete: boolean;
14
+ bucketDataSources: BucketDataSource[];
15
+ parameterLookupSources: ParameterIndexLookupCreator[];
16
+ bucketDataSourceIds?: Set<BucketDefinitionId>;
17
+ parameterLookupSourceIds?: Set<ParameterIndexId>;
15
18
  }
16
19
  export interface TableSnapshotStatus {
17
20
  totalEstimatedCount: number;
18
21
  replicatedCount: number;
19
22
  lastKey: Uint8Array | null;
20
23
  }
21
- export declare class SourceTable implements SourceEntityDescriptor {
24
+ /**
25
+ * Represents a resolved source table.
26
+ *
27
+ * There could be multiple of these for the same SourceTableRef.
28
+ * For that reason, we do not implement the SourceTableRef interface, to ensure that the two are not used interchangably.
29
+ */
30
+ export declare class SourceTable {
22
31
  readonly options: SourceTableOptions;
23
32
  static readonly DEFAULT_TAG = "default";
24
33
  /**
@@ -38,13 +47,27 @@ export declare class SourceTable implements SourceEntityDescriptor {
38
47
  */
39
48
  syncParameters: boolean;
40
49
  /**
41
- * True if the table is used in sync config for events.
50
+ * True if this table should fire events for row changes.
42
51
  *
43
- * This value is resolved externally, and cached here.
52
+ * This value is resolved externally, and cached here. When multiple SourceTables exist
53
+ * for the same SourceTableRef (v3 storage), resolveTables designates exactly one of them
54
+ * as the event carrier, so that a row change saved once per table fires each event once.
44
55
  *
45
56
  * Defaults to true for tests.
46
57
  */
47
58
  syncEvent: boolean;
59
+ /**
60
+ * True if raw data should be stored in current_data collection.
61
+ *
62
+ * This is needed when the source sends partial row data (e.g. TOAST values).
63
+ * When REPLICA IDENTITY FULL is configured, complete rows are always sent,
64
+ * so we don't need to store raw data.
65
+ *
66
+ * This value is resolved externally based on table configuration.
67
+ *
68
+ * Defaults to true for tests (conservative approach).
69
+ */
70
+ storeCurrentData: boolean;
48
71
  /**
49
72
  * Always undefined if snapshotComplete = true.
50
73
  *
@@ -54,14 +77,18 @@ export declare class SourceTable implements SourceEntityDescriptor {
54
77
  snapshotComplete: boolean;
55
78
  constructor(options: SourceTableOptions);
56
79
  get id(): SourceTableId;
57
- get connectionTag(): string;
58
80
  get objectId(): string | number | undefined;
59
81
  get schema(): string;
60
82
  get name(): string;
83
+ get ref(): SourceTableRef;
61
84
  get replicaIdColumns(): ColumnDescriptor[];
85
+ get bucketDataSources(): BucketDataSource[];
86
+ get parameterLookupSources(): ParameterIndexLookupCreator[];
87
+ get bucketDataSourceIds(): Set<string> | undefined;
88
+ get parameterLookupSourceIds(): Set<string> | undefined;
62
89
  /**
63
- * Sanitized name of the entity in the format of "{schema}.{entity name}"
64
- * Suitable for safe use in Postgres queries.
90
+ * Sanitized name of the entity in the format of "{schema}.{entity name}".
91
+ * Suitable for safe use in Postgres queries.
65
92
  */
66
93
  get qualifiedName(): string;
67
94
  get syncAny(): boolean;
@@ -1,5 +1,11 @@
1
1
  import { DEFAULT_TAG } from '@powersync/service-sync-rules';
2
2
  import * as util from '../util/util-index.js';
3
+ /**
4
+ * Represents a resolved source table.
5
+ *
6
+ * There could be multiple of these for the same SourceTableRef.
7
+ * For that reason, we do not implement the SourceTableRef interface, to ensure that the two are not used interchangably.
8
+ */
3
9
  export class SourceTable {
4
10
  options;
5
11
  static DEFAULT_TAG = DEFAULT_TAG;
@@ -20,13 +26,27 @@ export class SourceTable {
20
26
  */
21
27
  syncParameters = true;
22
28
  /**
23
- * True if the table is used in sync config for events.
29
+ * True if this table should fire events for row changes.
24
30
  *
25
- * This value is resolved externally, and cached here.
31
+ * This value is resolved externally, and cached here. When multiple SourceTables exist
32
+ * for the same SourceTableRef (v3 storage), resolveTables designates exactly one of them
33
+ * as the event carrier, so that a row change saved once per table fires each event once.
26
34
  *
27
35
  * Defaults to true for tests.
28
36
  */
29
37
  syncEvent = true;
38
+ /**
39
+ * True if raw data should be stored in current_data collection.
40
+ *
41
+ * This is needed when the source sends partial row data (e.g. TOAST values).
42
+ * When REPLICA IDENTITY FULL is configured, complete rows are always sent,
43
+ * so we don't need to store raw data.
44
+ *
45
+ * This value is resolved externally based on table configuration.
46
+ *
47
+ * Defaults to true for tests (conservative approach).
48
+ */
49
+ storeCurrentData = true;
30
50
  /**
31
51
  * Always undefined if snapshotComplete = true.
32
52
  *
@@ -41,27 +61,39 @@ export class SourceTable {
41
61
  get id() {
42
62
  return this.options.id;
43
63
  }
44
- get connectionTag() {
45
- return this.options.connectionTag;
46
- }
47
64
  get objectId() {
48
65
  return this.options.objectId;
49
66
  }
50
67
  get schema() {
51
- return this.options.schema;
68
+ return this.options.ref.schema;
52
69
  }
53
70
  get name() {
54
- return this.options.name;
71
+ return this.options.ref.name;
72
+ }
73
+ get ref() {
74
+ return this.options.ref;
55
75
  }
56
76
  get replicaIdColumns() {
57
77
  return this.options.replicaIdColumns;
58
78
  }
79
+ get bucketDataSources() {
80
+ return this.options.bucketDataSources;
81
+ }
82
+ get parameterLookupSources() {
83
+ return this.options.parameterLookupSources;
84
+ }
85
+ get bucketDataSourceIds() {
86
+ return this.options.bucketDataSourceIds;
87
+ }
88
+ get parameterLookupSourceIds() {
89
+ return this.options.parameterLookupSourceIds;
90
+ }
59
91
  /**
60
- * Sanitized name of the entity in the format of "{schema}.{entity name}"
61
- * Suitable for safe use in Postgres queries.
92
+ * Sanitized name of the entity in the format of "{schema}.{entity name}".
93
+ * Suitable for safe use in Postgres queries.
62
94
  */
63
95
  get qualifiedName() {
64
- return `${util.escapeIdentifier(this.schema)}.${util.escapeIdentifier(this.name)}`;
96
+ return util.qualifiedName(this.ref);
65
97
  }
66
98
  get syncAny() {
67
99
  return this.syncData || this.syncParameters || this.syncEvent;
@@ -72,15 +104,19 @@ export class SourceTable {
72
104
  clone() {
73
105
  const copy = new SourceTable({
74
106
  id: this.id,
75
- connectionTag: this.connectionTag,
107
+ ref: this.options.ref,
76
108
  objectId: this.objectId,
77
- schema: this.schema,
78
- name: this.name,
79
109
  replicaIdColumns: this.replicaIdColumns,
80
- snapshotComplete: this.snapshotComplete
110
+ snapshotComplete: this.snapshotComplete,
111
+ bucketDataSources: this.bucketDataSources,
112
+ parameterLookupSources: this.parameterLookupSources,
113
+ bucketDataSourceIds: this.bucketDataSourceIds == null ? undefined : new Set(this.bucketDataSourceIds),
114
+ parameterLookupSourceIds: this.parameterLookupSourceIds == null ? undefined : new Set(this.parameterLookupSourceIds)
81
115
  });
82
116
  copy.syncData = this.syncData;
83
117
  copy.syncParameters = this.syncParameters;
118
+ copy.syncEvent = this.syncEvent;
119
+ copy.storeCurrentData = this.storeCurrentData;
84
120
  copy.snapshotStatus = this.snapshotStatus;
85
121
  return copy;
86
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SourceTable.js","sourceRoot":"","sources":["../../src/storage/SourceTable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAwB9C,MAAM,OAAO,WAAW;IAuCM;IAtC5B,MAAM,CAAU,WAAW,GAAG,WAAW,CAAC;IAE1C;;;;;;OAMG;IACI,QAAQ,GAAG,IAAI,CAAC;IAEvB;;;;;;OAMG;IACI,cAAc,GAAG,IAAI,CAAC;IAE7B;;;;;;OAMG;IACI,SAAS,GAAG,IAAI,CAAC;IAExB;;;;OAIG;IACI,cAAc,GAAoC,SAAS,CAAC;IAE5D,gBAAgB,CAAU;IAEjC,YAA4B,OAA2B;QAA3B,YAAO,GAAP,OAAO,CAAoB;QACrD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IACnD,CAAC;IAED,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IACpC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IACD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,IAAI,aAAa;QACf,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACrF,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sBAAsB;QACpB,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;YACzD,oBAAoB;YACpB,OAAO,GAAG,CAAC;QACb,CAAC;aAAM,IAAI,IAAI,CAAC,cAAc,CAAC,mBAAmB,GAAG,CAAC,EAAE,CAAC;YACvD,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,IAAI,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,KAAK,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC;QAC9F,CAAC;IACH,CAAC"}
1
+ {"version":3,"file":"SourceTable.js","sourceRoot":"","sources":["../../src/storage/SourceTable.ts"],"names":[],"mappings":"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"}