@powersync/service-core 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214

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 (230) hide show
  1. package/CHANGELOG.md +152 -4
  2. package/dist/api/RouteAPI.d.ts +42 -14
  3. package/dist/api/diagnostics.d.ts +12 -1
  4. package/dist/api/diagnostics.js +36 -22
  5. package/dist/api/diagnostics.js.map +1 -1
  6. package/dist/entry/commands/compact-action.js +30 -22
  7. package/dist/entry/commands/compact-action.js.map +1 -1
  8. package/dist/metrics/metrics-interfaces.d.ts +5 -1
  9. package/dist/metrics/metrics-interfaces.js.map +1 -1
  10. package/dist/metrics/open-telemetry/MetricAttributeFilteringExporter.d.ts +36 -0
  11. package/dist/metrics/open-telemetry/MetricAttributeFilteringExporter.js +70 -0
  12. package/dist/metrics/open-telemetry/MetricAttributeFilteringExporter.js.map +1 -0
  13. package/dist/metrics/open-telemetry/OpenTelemetryMetricsFactory.js +6 -1
  14. package/dist/metrics/open-telemetry/OpenTelemetryMetricsFactory.js.map +1 -1
  15. package/dist/metrics/open-telemetry/util.js +7 -3
  16. package/dist/metrics/open-telemetry/util.js.map +1 -1
  17. package/dist/modules/AbstractModule.d.ts +6 -2
  18. package/dist/modules/AbstractModule.js.map +1 -1
  19. package/dist/replication/AbstractReplicator.d.ts +31 -7
  20. package/dist/replication/AbstractReplicator.js +168 -74
  21. package/dist/replication/AbstractReplicator.js.map +1 -1
  22. package/dist/replication/ReplicationModule.d.ts +3 -3
  23. package/dist/replication/ReplicationModule.js.map +1 -1
  24. package/dist/routes/RouterEngine.d.ts +1 -0
  25. package/dist/routes/RouterEngine.js +6 -1
  26. package/dist/routes/RouterEngine.js.map +1 -1
  27. package/dist/routes/configure-fastify.d.ts +104 -56
  28. package/dist/routes/configure-fastify.js +15 -2
  29. package/dist/routes/configure-fastify.js.map +1 -1
  30. package/dist/routes/endpoints/admin.d.ts +42 -24
  31. package/dist/routes/endpoints/admin.js +49 -36
  32. package/dist/routes/endpoints/admin.js.map +1 -1
  33. package/dist/routes/endpoints/checkpointing.d.ts +62 -0
  34. package/dist/routes/endpoints/checkpointing.js +65 -7
  35. package/dist/routes/endpoints/checkpointing.js.map +1 -1
  36. package/dist/routes/endpoints/socket-route.js +3 -2
  37. package/dist/routes/endpoints/socket-route.js.map +1 -1
  38. package/dist/routes/endpoints/sync-rules.js +25 -14
  39. package/dist/routes/endpoints/sync-rules.js.map +1 -1
  40. package/dist/routes/endpoints/sync-stream.js +1 -1
  41. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  42. package/dist/runner/teardown.js +8 -8
  43. package/dist/runner/teardown.js.map +1 -1
  44. package/dist/storage/BucketStorageBatch.d.ts +64 -17
  45. package/dist/storage/BucketStorageBatch.js.map +1 -1
  46. package/dist/storage/BucketStorageFactory.d.ts +50 -31
  47. package/dist/storage/BucketStorageFactory.js +10 -20
  48. package/dist/storage/BucketStorageFactory.js.map +1 -1
  49. package/dist/storage/CheckpointChecksumInvalidatedError.d.ts +12 -0
  50. package/dist/storage/CheckpointChecksumInvalidatedError.js +17 -0
  51. package/dist/storage/CheckpointChecksumInvalidatedError.js.map +1 -0
  52. package/dist/storage/ChecksumCache.d.ts +11 -6
  53. package/dist/storage/ChecksumCache.js +5 -4
  54. package/dist/storage/ChecksumCache.js.map +1 -1
  55. package/dist/storage/ParsedSyncConfigSet.d.ts +23 -0
  56. package/dist/storage/ParsedSyncConfigSet.js +2 -0
  57. package/dist/storage/ParsedSyncConfigSet.js.map +1 -0
  58. package/dist/storage/PersistedReplicationStream.d.ts +32 -0
  59. package/dist/storage/PersistedReplicationStream.js +26 -0
  60. package/dist/storage/PersistedReplicationStream.js.map +1 -0
  61. package/dist/storage/PersistedSyncConfigContent.d.ts +65 -0
  62. package/dist/storage/PersistedSyncConfigContent.js +138 -0
  63. package/dist/storage/PersistedSyncConfigContent.js.map +1 -0
  64. package/dist/storage/PersistedSyncConfigStatus.d.ts +13 -0
  65. package/dist/storage/PersistedSyncConfigStatus.js +2 -0
  66. package/dist/storage/PersistedSyncConfigStatus.js.map +1 -0
  67. package/dist/storage/ReplicationEventPayload.d.ts +6 -1
  68. package/dist/storage/SourceEntity.d.ts +13 -2
  69. package/dist/storage/SourceTable.d.ts +53 -4
  70. package/dist/storage/SourceTable.js +62 -7
  71. package/dist/storage/SourceTable.js.map +1 -1
  72. package/dist/storage/SourceTableReconciler.d.ts +83 -0
  73. package/dist/storage/SourceTableReconciler.js +95 -0
  74. package/dist/storage/SourceTableReconciler.js.map +1 -0
  75. package/dist/storage/StorageVersionConfig.d.ts +4 -0
  76. package/dist/storage/StorageVersionConfig.js +10 -1
  77. package/dist/storage/StorageVersionConfig.js.map +1 -1
  78. package/dist/storage/SyncRulesBucketStorage.d.ts +162 -26
  79. package/dist/storage/SyncRulesBucketStorage.js +3 -0
  80. package/dist/storage/SyncRulesBucketStorage.js.map +1 -1
  81. package/dist/storage/WriteCheckpointAPI.d.ts +85 -6
  82. package/dist/storage/WriteCheckpointAPI.js +33 -0
  83. package/dist/storage/WriteCheckpointAPI.js.map +1 -1
  84. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +133 -0
  85. package/dist/storage/implementation/BucketDefinitionMapping.js +351 -0
  86. package/dist/storage/implementation/BucketDefinitionMapping.js.map +1 -0
  87. package/dist/storage/implementation/IncrementalReprocessingCompatibility.d.ts +6 -0
  88. package/dist/storage/implementation/IncrementalReprocessingCompatibility.js +31 -0
  89. package/dist/storage/implementation/IncrementalReprocessingCompatibility.js.map +1 -0
  90. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.d.ts +17 -0
  91. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.js +70 -0
  92. package/dist/storage/implementation/IncrementalReprocessingSyncConfigLog.js.map +1 -0
  93. package/dist/storage/implementation/ReplicationStreamStorageIds.d.ts +15 -0
  94. package/dist/storage/implementation/ReplicationStreamStorageIds.js +20 -0
  95. package/dist/storage/implementation/ReplicationStreamStorageIds.js.map +1 -0
  96. package/dist/storage/storage-index.d.ts +10 -1
  97. package/dist/storage/storage-index.js +10 -1
  98. package/dist/storage/storage-index.js.map +1 -1
  99. package/dist/storage/storage-metrics.js +120 -4
  100. package/dist/storage/storage-metrics.js.map +1 -1
  101. package/dist/sync/BucketChecksumState.d.ts +12 -2
  102. package/dist/sync/BucketChecksumState.js +69 -21
  103. package/dist/sync/BucketChecksumState.js.map +1 -1
  104. package/dist/sync/RequestTracker.d.ts +7 -0
  105. package/dist/sync/RequestTracker.js +12 -0
  106. package/dist/sync/RequestTracker.js.map +1 -1
  107. package/dist/sync/sync.js +184 -43
  108. package/dist/sync/sync.js.map +1 -1
  109. package/dist/sync/util.d.ts +5 -0
  110. package/dist/sync/util.js +19 -1
  111. package/dist/sync/util.js.map +1 -1
  112. package/dist/system/ServiceContext.d.ts +2 -0
  113. package/dist/system/ServiceContext.js +2 -0
  114. package/dist/system/ServiceContext.js.map +1 -1
  115. package/dist/tracing/PerformanceTracer.d.ts +23 -1
  116. package/dist/tracing/PerformanceTracer.js +11 -0
  117. package/dist/tracing/PerformanceTracer.js.map +1 -1
  118. package/dist/util/checkpointing.d.ts +4 -8
  119. package/dist/util/checkpointing.js +1 -16
  120. package/dist/util/checkpointing.js.map +1 -1
  121. package/dist/util/config/compound-config-collector.js +23 -2
  122. package/dist/util/config/compound-config-collector.js.map +1 -1
  123. package/dist/util/config/defaults.d.ts +2 -0
  124. package/dist/util/config/defaults.js +2 -0
  125. package/dist/util/config/defaults.js.map +1 -1
  126. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js +1 -0
  127. package/dist/util/config/sync-rules/impl/base64-sync-rules-collector.js.map +1 -1
  128. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js +1 -0
  129. package/dist/util/config/sync-rules/impl/filesystem-sync-rules-collector.js.map +1 -1
  130. package/dist/util/config/sync-rules/sync-rules-provider.d.ts +2 -0
  131. package/dist/util/config/sync-rules/sync-rules-provider.js +3 -0
  132. package/dist/util/config/sync-rules/sync-rules-provider.js.map +1 -1
  133. package/dist/util/config/types.d.ts +4 -1
  134. package/dist/util/lsn.d.ts +4 -0
  135. package/dist/util/lsn.js +10 -0
  136. package/dist/util/lsn.js.map +1 -1
  137. package/dist/util/protocol-types.d.ts +4 -4
  138. package/dist/util/protocol-types.js +3 -2
  139. package/dist/util/protocol-types.js.map +1 -1
  140. package/dist/util/util-index.d.ts +1 -0
  141. package/dist/util/util-index.js +1 -0
  142. package/dist/util/util-index.js.map +1 -1
  143. package/dist/util/utils.d.ts +3 -2
  144. package/dist/util/utils.js +17 -2
  145. package/dist/util/utils.js.map +1 -1
  146. package/dist/util/write-checkpoint-batcher.d.ts +19 -0
  147. package/dist/util/write-checkpoint-batcher.js +100 -0
  148. package/dist/util/write-checkpoint-batcher.js.map +1 -0
  149. package/package.json +7 -7
  150. package/src/api/RouteAPI.ts +43 -14
  151. package/src/api/diagnostics.ts +45 -26
  152. package/src/entry/commands/compact-action.ts +37 -23
  153. package/src/metrics/metrics-interfaces.ts +6 -1
  154. package/src/metrics/open-telemetry/MetricAttributeFilteringExporter.ts +85 -0
  155. package/src/metrics/open-telemetry/OpenTelemetryMetricsFactory.ts +7 -2
  156. package/src/metrics/open-telemetry/util.ts +7 -3
  157. package/src/modules/AbstractModule.ts +6 -2
  158. package/src/replication/AbstractReplicator.ts +212 -78
  159. package/src/replication/ReplicationModule.ts +2 -3
  160. package/src/routes/RouterEngine.ts +7 -1
  161. package/src/routes/configure-fastify.ts +25 -2
  162. package/src/routes/endpoints/admin.ts +75 -51
  163. package/src/routes/endpoints/checkpointing.ts +79 -8
  164. package/src/routes/endpoints/socket-route.ts +3 -2
  165. package/src/routes/endpoints/sync-rules.ts +26 -14
  166. package/src/routes/endpoints/sync-stream.ts +1 -1
  167. package/src/runner/teardown.ts +8 -8
  168. package/src/storage/BucketStorageBatch.ts +65 -18
  169. package/src/storage/BucketStorageFactory.ts +73 -46
  170. package/src/storage/CheckpointChecksumInvalidatedError.ts +17 -0
  171. package/src/storage/ChecksumCache.ts +27 -14
  172. package/src/storage/ParsedSyncConfigSet.ts +25 -0
  173. package/src/storage/PersistedReplicationStream.ts +55 -0
  174. package/src/storage/PersistedSyncConfigContent.ts +207 -0
  175. package/src/storage/PersistedSyncConfigStatus.ts +14 -0
  176. package/src/storage/ReplicationEventPayload.ts +6 -1
  177. package/src/storage/SourceEntity.ts +12 -2
  178. package/src/storage/SourceTable.ts +96 -8
  179. package/src/storage/SourceTableReconciler.ts +188 -0
  180. package/src/storage/StorageVersionConfig.ts +11 -1
  181. package/src/storage/SyncRulesBucketStorage.ts +189 -27
  182. package/src/storage/WriteCheckpointAPI.ts +140 -6
  183. package/src/storage/implementation/BucketDefinitionMapping.ts +539 -0
  184. package/src/storage/implementation/IncrementalReprocessingCompatibility.ts +41 -0
  185. package/src/storage/implementation/IncrementalReprocessingSyncConfigLog.ts +126 -0
  186. package/src/storage/implementation/ReplicationStreamStorageIds.ts +21 -0
  187. package/src/storage/storage-index.ts +11 -1
  188. package/src/storage/storage-metrics.ts +154 -8
  189. package/src/sync/BucketChecksumState.ts +105 -21
  190. package/src/sync/RequestTracker.ts +20 -0
  191. package/src/sync/sync.ts +214 -50
  192. package/src/sync/util.ts +33 -8
  193. package/src/system/ServiceContext.ts +7 -0
  194. package/src/tracing/PerformanceTracer.ts +41 -1
  195. package/src/util/checkpointing.ts +4 -22
  196. package/src/util/config/compound-config-collector.ts +31 -1
  197. package/src/util/config/defaults.ts +2 -0
  198. package/src/util/config/sync-rules/impl/base64-sync-rules-collector.ts +1 -0
  199. package/src/util/config/sync-rules/impl/filesystem-sync-rules-collector.ts +1 -0
  200. package/src/util/config/sync-rules/sync-rules-provider.ts +5 -0
  201. package/src/util/config/types.ts +4 -1
  202. package/src/util/lsn.ts +9 -0
  203. package/src/util/protocol-types.ts +3 -2
  204. package/src/util/util-index.ts +1 -0
  205. package/src/util/utils.ts +16 -2
  206. package/src/util/write-checkpoint-batcher.ts +142 -0
  207. package/test/src/AbstractReplicator.test.ts +177 -0
  208. package/test/src/MetricAttributeFilteringExporter.test.ts +96 -0
  209. package/test/src/PersistedSyncConfigContent.test.ts +152 -0
  210. package/test/src/checksum_cache.test.ts +22 -0
  211. package/test/src/config.test.ts +142 -0
  212. package/test/src/diagnostics.test.ts +87 -34
  213. package/test/src/module-loader.test.ts +33 -1
  214. package/test/src/routes/admin.test.ts +188 -18
  215. package/test/src/routes/checkpointing.test.ts +54 -0
  216. package/test/src/routes/mocks.ts +6 -2
  217. package/test/src/routes/stream.test.ts +123 -2
  218. package/test/src/source-table-reconciler.test.ts +244 -0
  219. package/test/src/storage/SourceTable.test.ts +92 -0
  220. package/test/src/storage-metrics.test.ts +148 -0
  221. package/test/src/sync/BucketChecksumState.test.ts +98 -12
  222. package/test/src/sync/util.test.ts +28 -1
  223. package/test/src/util/checkpointing.test.ts +249 -0
  224. package/test/src/util/utils.test.ts +23 -0
  225. package/tsconfig.json +1 -4
  226. package/tsconfig.tsbuildinfo +1 -1
  227. package/dist/storage/PersistedSyncRulesContent.d.ts +0 -59
  228. package/dist/storage/PersistedSyncRulesContent.js +0 -100
  229. package/dist/storage/PersistedSyncRulesContent.js.map +0 -1
  230. package/src/storage/PersistedSyncRulesContent.ts +0 -174
@@ -16,6 +16,10 @@ export const STORAGE_VERSION_2 = 2;
16
16
  * This is used to build towards incremental reprocessing.
17
17
  */
18
18
  export const STORAGE_VERSION_3 = 3;
19
+ /**
20
+ * Same as version 3, but marked as stable.
21
+ */
22
+ export const STORAGE_VERSION_4 = 4;
19
23
  /**
20
24
  * Oldest supported storage version.
21
25
  */
@@ -29,7 +33,7 @@ export const CURRENT_STORAGE_VERSION = STORAGE_VERSION_2;
29
33
  *
30
34
  * This includes unstable versions.
31
35
  */
32
- export const SUPPORTED_STORAGE_VERSIONS = [STORAGE_VERSION_1, STORAGE_VERSION_2, STORAGE_VERSION_3];
36
+ export const SUPPORTED_STORAGE_VERSIONS = [STORAGE_VERSION_1, STORAGE_VERSION_2, STORAGE_VERSION_3, STORAGE_VERSION_4];
33
37
  /**
34
38
  * Shared storage-version behavior across storage implementations.
35
39
  */
@@ -48,6 +52,11 @@ export const STORAGE_VERSION_CONFIG = {
48
52
  version: STORAGE_VERSION_3,
49
53
  versionedBuckets: true,
50
54
  softDeleteCurrentData: true
55
+ },
56
+ [STORAGE_VERSION_4]: {
57
+ version: STORAGE_VERSION_4,
58
+ versionedBuckets: true,
59
+ softDeleteCurrentData: true
51
60
  }
52
61
  };
53
62
  //# sourceMappingURL=StorageVersionConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StorageVersionConfig.js","sourceRoot":"","sources":["../../src/storage/StorageVersionConfig.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAEpG;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAqD;IACtF,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,KAAK;QACvB,qBAAqB,EAAE,KAAK;KAC7B;IACD,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,KAAK;KAC7B;IACD,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;CACF,CAAC"}
1
+ {"version":3,"file":"StorageVersionConfig.js","sourceRoot":"","sources":["../../src/storage/StorageVersionConfig.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAEvH;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAqD;IACtF,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,KAAK;QACvB,qBAAqB,EAAE,KAAK;KAC7B;IACD,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,KAAK;KAC7B;IACD,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;IACD,CAAC,iBAAiB,CAAC,EAAE;QACnB,OAAO,EAAE,iBAAiB;QAC1B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;CACF,CAAC"}
@@ -5,31 +5,55 @@ import { PerformanceTracer } from '../tracing/PerformanceTracer.js';
5
5
  import * as util from '../util/util-index.js';
6
6
  import { BucketStorageBatch, FlushedResult, SaveUpdate } from './BucketStorageBatch.js';
7
7
  import { BucketStorageFactory } from './BucketStorageFactory.js';
8
- import { ParseSyncRulesOptions } from './PersistedSyncRulesContent.js';
8
+ import { ParsedSyncConfigSet } from './ParsedSyncConfigSet.js';
9
+ import { ParseSyncConfigOptions } from './PersistedSyncConfigContent.js';
9
10
  import { SourceEntityDescriptor } from './SourceEntity.js';
10
11
  import { SourceTable } from './SourceTable.js';
12
+ import { SourceTableCandidateReconciler } from './SourceTableReconciler.js';
11
13
  import { StorageVersionConfig } from './StorageVersionConfig.js';
12
14
  import { SyncStorageWriteCheckpointAPI } from './WriteCheckpointAPI.js';
13
15
  /**
14
16
  * Storage for a specific replication stream.
17
+ *
18
+ * Replication writes source changes, source table metadata, snapshot progress,
19
+ * resume positions, and checkpoint boundaries through this interface. The sync
20
+ * API reads the same stream state as checkpoints, checksums, bucket data,
21
+ * parameter lookup rows, and write-checkpoint acknowledgements.
15
22
  */
16
23
  export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketStorageListener>, SyncStorageWriteCheckpointAPI {
17
- readonly group_id: number;
18
- readonly slot_name: string;
24
+ readonly replicationStreamId: number;
25
+ readonly replicationStreamName: string;
19
26
  readonly storageConfig: StorageVersionConfig;
20
27
  readonly factory: BucketStorageFactory;
21
28
  readonly logger: Logger;
22
29
  /**
23
- * Create a new writer.
30
+ * Create a writer for a source-specific unit of replication work.
24
31
  *
25
- * The writer must be flushed and disposed when done.
32
+ * The writer may be used for a long-running streaming attempt, a table
33
+ * snapshot, a page of snapshot work, or a short setup step. Pending work
34
+ * that should be persisted must be flushed, committed, or kept alive at the
35
+ * appropriate source boundary before the writer is disposed.
26
36
  */
27
37
  createWriter(options: CreateWriterOptions): Promise<BucketStorageBatch>;
28
38
  /**
39
+ * Callback wrapper around `createWriter()`.
40
+ *
29
41
  * @deprecated Use `createWriter()` with `await using` instead.
30
42
  */
31
43
  startBatch(options: CreateWriterOptions, callback: (batch: BucketStorageBatch) => Promise<void>): Promise<FlushedResult | null>;
32
- getParsedSyncRules(options: ParseSyncRulesOptions): HydratedSyncConfig;
44
+ /**
45
+ * Get the canonical parsed sync config set for the given parse options.
46
+ *
47
+ * Repeated calls with the same options return the same instance for the lifetime of
48
+ * this storage instance. This is the identity boundary for parsed sync config state:
49
+ * all operations against this storage instance must use parsed objects from sets
50
+ * returned here, never from an independent parse of the same content.
51
+ */
52
+ getParsedSyncConfigSet(options: ParseSyncConfigOptions): ParsedSyncConfigSet;
53
+ /**
54
+ * Shortcut for `getParsedSyncConfigSet(options).hydratedSyncConfig`.
55
+ */
56
+ getParsedSyncRules(options: ParseSyncConfigOptions): HydratedSyncConfig;
33
57
  /**
34
58
  * Terminate the replication stream.
35
59
  *
@@ -38,7 +62,7 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
38
62
  * Must only be called on stopped replication streams.
39
63
  */
40
64
  terminate(options?: TerminateOptions): Promise<void>;
41
- getStatus(): Promise<SyncRuleStatus>;
65
+ getStatus(): Promise<ReplicationStreamStatus>;
42
66
  /**
43
67
  * Clear the storage, without changing state.
44
68
  */
@@ -52,11 +76,18 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
52
76
  * Errors are cleared on flush.
53
77
  */
54
78
  reportError(e: any): Promise<void>;
79
+ /**
80
+ * Whether parameter compaction can run when {@link CompactOptions.incrementalOnly} is set.
81
+ *
82
+ * Storage implementations that do not support incremental parameter compaction must return
83
+ * false; the compact command will skip parameter compaction in that mode.
84
+ */
85
+ supportsIncrementalParameterCompaction(): boolean;
55
86
  compact(options?: CompactOptions): Promise<void>;
56
87
  /**
57
- * Lightweight "compact" process to populate the checksum cache, if any.
88
+ * Compact storage after initial replication, before the first checkpoint exists.
58
89
  */
59
- populatePersistentChecksumCache(options: PopulateChecksumCacheOptions): Promise<PopulateChecksumCacheResults>;
90
+ compactInitialReplication(options: CompactInitialReplicationOptions): Promise<CompactInitialReplicationResults>;
60
91
  getCheckpoint(): Promise<ReplicationCheckpoint>;
61
92
  /**
62
93
  * Given two checkpoints, return the changes in bucket data and parameters that may have occurred
@@ -64,7 +95,7 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
64
95
  *
65
96
  * This is a best-effort optimization:
66
97
  * 1. This may include more changes than what actually occurred.
67
- * 2. This may return invalidateDataBuckets or invalidateParameterBuckets instead of of returning
98
+ * 2. This may return invalidateDataBuckets or invalidateParameterBuckets instead of returning
68
99
  * specific changes.
69
100
  * @param options
70
101
  */
@@ -82,11 +113,18 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
82
113
  * 1. Separate buckets.
83
114
  * 2. Limit the size of each individual chunk according to options.batchSizeLimitBytes.
84
115
  *
116
+ * The batch may not contain all data for the checkpoint, if the checkpoint is large. The caller must
117
+ * continue querying if either:
118
+ * 1. The last chunk for any bucket has has_more = true.
119
+ * 2. A SyncBucketDataBatchEnd is returned with hasMore = true.
120
+ *
121
+ * The first check can be skipped if a SyncBucketDataBatchEnd is returned with hasMore = false.
122
+ *
85
123
  * @param checkpoint the checkpoint
86
124
  * @param dataBuckets current bucket states
87
125
  * @param options batch size options
88
126
  */
89
- getBucketDataBatch(checkpoint: util.InternalOpId, dataBuckets: BucketDataRequest[], options?: BucketDataBatchOptions): AsyncIterable<SyncBucketDataChunk>;
127
+ getBucketDataBatch(checkpoint: ReplicationCheckpoint, dataBuckets: BucketDataRequest[], options?: BucketDataBatchOptions): AsyncIterable<SyncBucketDataChunk | SyncBucketDataBatchEnd>;
90
128
  /**
91
129
  * Compute checksums for a given list of buckets.
92
130
  *
@@ -95,11 +133,16 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
95
133
  * This may be slow, depending on the size of the buckets.
96
134
  * The checksums are cached internally to compensate for this, but does not cover all cases.
97
135
  */
98
- getChecksums(checkpoint: util.InternalOpId, buckets: BucketChecksumRequest[]): Promise<util.ChecksumMap>;
136
+ getChecksums(checkpoint: ReplicationCheckpoint, buckets: BucketChecksumRequest[], options?: BucketChecksumOptions): Promise<util.ChecksumMap>;
99
137
  /**
100
138
  * Clear checksum cache. Primarily intended for tests.
101
139
  */
102
140
  clearChecksumCache(): void;
141
+ /**
142
+ * Optional storage-provider cleanup for sync configs that have been stopped
143
+ * inside this replication stream.
144
+ */
145
+ cleanupStoppedSyncConfigs?(options: CleanupStoppedSyncConfigsOptions): Promise<CleanupStoppedSyncConfigsResult>;
103
146
  }
104
147
  export interface SyncRulesBucketStorageListener {
105
148
  batchStarted: (batch: BucketStorageBatch) => void;
@@ -113,33 +156,57 @@ export interface BucketChecksumRequest {
113
156
  bucket: string;
114
157
  source: BucketDataSource;
115
158
  }
116
- export interface SyncRuleStatus {
117
- checkpoint_lsn: string | null;
118
- active: boolean;
119
- snapshot_done: boolean;
120
- snapshot_lsn: string | null;
159
+ export interface BucketChecksumOptions {
160
+ requestHint?: BucketRequestHint;
161
+ }
162
+ export type BucketRequestHint = 'bulk' | 'incremental';
163
+ export interface ReplicationStreamStatus {
164
+ /**
165
+ * Source position to resume replication from.
166
+ */
167
+ resumeLsn: string | null;
121
168
  /**
122
- * Last persisted operation that must be included in the next checkpoint once checkpointing is unblocked.
169
+ * True if _every_ active/processing sync config has a client-visible checkpoint.
123
170
  */
124
- keepalive_op: util.InternalOpId | null;
171
+ snapshotDone: boolean;
125
172
  }
126
173
  export interface ResolveTablesOptions {
127
174
  connection_id: number;
175
+ /**
176
+ * Source table or collection metadata discovered during snapshot or streaming.
177
+ */
128
178
  source: SourceEntityDescriptor;
179
+ /**
180
+ * Classifies overlapping persisted tables. Defaults to identity-based reconciliation.
181
+ * This may run inside a storage transaction and must not mutate storage.
182
+ */
183
+ reconcileSourceTables?: SourceTableCandidateReconciler;
129
184
  /**
130
185
  * For tests only - custom id generator for stable ids.
131
186
  */
132
187
  idGenerator?: () => string | bson.ObjectId;
133
188
  /**
134
- * For tests only - override the sync rules used.
189
+ * For tests only - override the parsed sync config set used.
135
190
  */
136
- syncRules?: HydratedSyncConfig;
191
+ parsedSyncConfig?: ParsedSyncConfigSet;
137
192
  }
138
193
  export interface ResolveTablesResult {
194
+ /**
195
+ * Current source table mappings that should receive replicated data.
196
+ */
139
197
  tables: SourceTable[];
198
+ /**
199
+ * Outdated source table mappings that should be removed by the connector.
200
+ */
140
201
  dropTables: SourceTable[];
141
202
  }
142
- export interface CreateWriterOptions extends ParseSyncRulesOptions {
203
+ /**
204
+ * Options for creating a storage writer.
205
+ */
206
+ export interface CreateWriterOptions extends ParseSyncConfigOptions {
207
+ /**
208
+ * Source-specific zero or empty replication position.
209
+ */
143
210
  zeroLSN: string;
144
211
  /**
145
212
  * Whether or not to store a copy of the current data.
@@ -166,6 +233,13 @@ export interface CreateWriterOptions extends ParseSyncRulesOptions {
166
233
  hooks?: StorageHooks;
167
234
  tracer?: PerformanceTracer<'storage' | 'evaluate'>;
168
235
  logger?: Logger;
236
+ /**
237
+ * Aborts long-running storage work started by this writer, such as uploads to object storage.
238
+ *
239
+ * This does not replace flushing or committing at the appropriate source boundary: it only
240
+ * cancels work that is still in flight when replication stops.
241
+ */
242
+ signal?: AbortSignal;
169
243
  }
170
244
  export interface StorageHooks {
171
245
  beforeBatchFlush?: (batch: BucketStorageBatch) => Promise<void>;
@@ -204,12 +278,28 @@ export interface CompactOptions {
204
278
  */
205
279
  compactBuckets?: string[];
206
280
  compactParameterData?: boolean;
281
+ /**
282
+ * Only perform compaction that can be done incrementally.
283
+ *
284
+ * This includes full bucket compaction on MongoDB V3 storage.
285
+ *
286
+ * On MongoDB v1 and Postgres storage, this makes compacting a no-op.
287
+ */
288
+ incrementalOnly?: boolean;
289
+ /**
290
+ * Delete client-requested write checkpoints created before this time.
291
+ *
292
+ * Generated write checkpoints are not affected.
293
+ */
294
+ deleteCheckpointRequestsBefore?: Date;
207
295
  /** Minimum of 2 */
208
296
  clearBatchLimit?: number;
209
297
  /** Minimum of 1 */
210
298
  moveBatchLimit?: number;
211
299
  /** Minimum of 1 */
212
300
  moveBatchQueryLimit?: number;
301
+ /** Byte cap per read batch for streaming compaction. Default 16MB. */
302
+ moveBatchByteLimit?: number;
213
303
  /**
214
304
  * Minimum number new operations in a bucket to trigger compaction of that bucket.
215
305
  *
@@ -222,6 +312,14 @@ export interface CompactOptions {
222
312
  * Number between 0 and 1, default of 0.1.
223
313
  */
224
314
  minChangeRatio?: number;
315
+ /** Minimum delay before a V3 bucket is checked for chunk compaction. Default: five minutes. */
316
+ minCompactChunkIntervalMs?: number;
317
+ /** Minimum elapsed write pressure before the v3 sliding-scale full compact. Default: two hours. */
318
+ minCompactFullIntervalMs?: number;
319
+ /** Maximum age of writes not covered by a v3 full compact. */
320
+ maxCompactFullIntervalMs?: number;
321
+ /** How long a v3 worker owns a claimed bucket before another worker may recover it. */
322
+ compactLeaseDurationMs?: number;
225
323
  /**
226
324
  * Internal/testing use: Cache size for compacting parameters.
227
325
  */
@@ -229,20 +327,43 @@ export interface CompactOptions {
229
327
  signal?: AbortSignal;
230
328
  logger?: Logger;
231
329
  }
232
- export interface PopulateChecksumCacheOptions {
233
- maxOpId: util.InternalOpId;
330
+ export interface CompactInitialReplicationOptions {
331
+ /**
332
+ * Compact data up to this op id.
333
+ *
334
+ * Defaults to the highest persisted op id for the replication stream, which covers
335
+ * the common case of compacting right after initial replication, before
336
+ * the first checkpoint exists.
337
+ */
338
+ maxOpId?: util.InternalOpId;
234
339
  minBucketChanges?: number;
235
340
  signal?: AbortSignal;
236
341
  }
237
- export interface PopulateChecksumCacheResults {
342
+ export interface CompactInitialReplicationResults {
238
343
  /**
239
- * Number of buckets we have calculated checksums for.
344
+ * Number of buckets processed.
240
345
  */
241
346
  buckets: number;
242
347
  }
243
348
  export interface ClearStorageOptions {
244
349
  signal?: AbortSignal;
245
350
  }
351
+ export interface CleanupStoppedSyncConfigsOptions {
352
+ signal?: AbortSignal;
353
+ logger?: Logger;
354
+ defaultSchema: string;
355
+ sourceConnectionTag: string;
356
+ }
357
+ export interface CleanupStoppedSyncConfigsResult {
358
+ stoppedSyncConfigsRemoved: number;
359
+ bucketDataCollectionsDropped: number;
360
+ parameterIndexCollectionsDropped: number;
361
+ /** Best-effort number, not accurate if the operation takes longer than the timeout. */
362
+ bucketStateDocumentsDeleted: number;
363
+ sourceRecordCollectionsDropped: number;
364
+ sourceTablesUpdated: number;
365
+ sourceTablesDeleted: number;
366
+ }
246
367
  export interface TerminateOptions extends ClearStorageOptions {
247
368
  /**
248
369
  * If true, also clear the storage before terminating.
@@ -250,6 +371,11 @@ export interface TerminateOptions extends ClearStorageOptions {
250
371
  clearStorage: boolean;
251
372
  }
252
373
  export interface BucketDataBatchOptions {
374
+ requestHint?: BucketRequestHint;
375
+ /** Abort any in-progress work for this batch, including object-storage downloads. */
376
+ signal?: AbortSignal;
377
+ /** Traces data reads performed by the storage implementation. */
378
+ tracer?: PerformanceTracer<string>;
253
379
  /** Limit number of documents returned. Defaults to 1000. */
254
380
  limit?: number;
255
381
  /**
@@ -267,6 +393,16 @@ export interface SyncBucketDataChunk {
267
393
  chunkData: util.SyncBucketData;
268
394
  targetOp: util.InternalOpId | null;
269
395
  }
396
+ export interface SyncBucketDataBatchEnd {
397
+ /**
398
+ * True if there may be more data for this checkpoint, and the caller should continue querying.
399
+ *
400
+ * This is different from `SyncBucketDataChunk.has_more`, which is per-bucket. This is a global signal for the
401
+ * entire request, and may be true even if there is no returned chunk with has_more: true.
402
+ */
403
+ hasMore: boolean;
404
+ }
405
+ export declare function isBatchEnd(chunk: SyncBucketDataChunk | SyncBucketDataBatchEnd): chunk is SyncBucketDataBatchEnd;
270
406
  export interface ReplicationCheckpoint {
271
407
  readonly checkpoint: util.InternalOpId;
272
408
  readonly lsn: string | null;
@@ -1,3 +1,6 @@
1
+ export function isBatchEnd(chunk) {
2
+ return chunk.hasMore !== undefined;
3
+ }
1
4
  /**
2
5
  * An exception thrown by {@link ReplicationCheckpoint} implementations if there are too many parameter results.
3
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SyncRulesBucketStorage.js","sourceRoot":"","sources":["../../src/storage/SyncRulesBucketStorage.ts"],"names":[],"mappings":"AA4VA;;;;GAIG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IAE5C;IACA;IAFX,YACW,KAAa,EACb,SAAyC;QAElD,KAAK,CAAC,yCAAyC,KAAK,GAAG,CAAC,CAAC;QAHhD,UAAK,GAAL,KAAK,CAAQ;QACb,cAAS,GAAT,SAAS,CAAgC;IAGpD,CAAC;CACF;AAqDD,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,kBAAkB,EAAE,IAAI,GAAG,EAAU;IACrC,qBAAqB,EAAE,IAAI;IAC3B,uBAAuB,EAAE,IAAI,GAAG,EAAU;IAC1C,0BAA0B,EAAE,IAAI;CACjC,CAAC"}
1
+ {"version":3,"file":"SyncRulesBucketStorage.js","sourceRoot":"","sources":["../../src/storage/SyncRulesBucketStorage.ts"],"names":[],"mappings":"AA2eA,MAAM,UAAU,UAAU,CAAC,KAAmD;IAC5E,OAAQ,KAAgC,CAAC,OAAO,KAAK,SAAS,CAAC;AACjE,CAAC;AAiBD;;;;GAIG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IAE5C;IACA;IAFX,YACW,KAAa,EACb,SAAyC;QAElD,KAAK,CAAC,yCAAyC,KAAK,GAAG,CAAC,CAAC;QAHhD,UAAK,GAAL,KAAK,CAAQ;QACb,cAAS,GAAT,SAAS,CAAgC;IAGpD,CAAC;CACF;AAqDD,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,kBAAkB,EAAE,IAAI,GAAG,EAAU;IACrC,qBAAqB,EAAE,IAAI;IAC3B,uBAAuB,EAAE,IAAI,GAAG,EAAU;IAC1C,0BAA0B,EAAE,IAAI;CACjC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { EventDefinitionId } from '@powersync/service-sync-rules';
1
2
  export declare enum WriteCheckpointMode {
2
3
  /**
3
4
  * Raw mappings of `user_id` to `write_checkpoint`s should
@@ -17,7 +18,19 @@ export interface BaseWriteCheckpointIdentifier {
17
18
  */
18
19
  user_id: string;
19
20
  }
20
- export interface CustomWriteCheckpointFilters extends BaseWriteCheckpointIdentifier {
21
+ export interface ClientRequestedCheckpointOptions {
22
+ /**
23
+ * Supplied for client-generated checkpoint requests.
24
+ *
25
+ * If omitted, storage creates or stores a regular write checkpoint.
26
+ * If supplied for managed write checkpoints, storage only uses it when it is
27
+ * greater than the stored id for the user_id. Same or lower supplied ids are
28
+ * no-ops, and storage returns the current stored id.
29
+ */
30
+ checkpoint_request_id?: bigint;
31
+ }
32
+ export type SyncStorageCustomWriteCheckpointFilters = BaseWriteCheckpointIdentifier;
33
+ export interface CustomWriteCheckpointFilters extends SyncStorageCustomWriteCheckpointFilters {
21
34
  /**
22
35
  * Replication stream which was active when this checkpoint was created.
23
36
  */
@@ -25,9 +38,25 @@ export interface CustomWriteCheckpointFilters extends BaseWriteCheckpointIdentif
25
38
  }
26
39
  export interface BatchedCustomWriteCheckpointOptions extends BaseWriteCheckpointIdentifier {
27
40
  /**
28
- * A supplied incrementing Write Checkpoint number
41
+ * A supplied incrementing checkpoint request id. This is still named
42
+ * "write checkpoint" in storage APIs for backwards compatibility.
29
43
  */
30
44
  checkpoint: bigint;
45
+ /**
46
+ * Compiled event definition which created the checkpoint.
47
+ *
48
+ * Incremental replication uses this to keep checkpoint records produced by
49
+ * active and processing sync configs separate. This is required by v3
50
+ * storage and unused by legacy storage versions.
51
+ */
52
+ event_id?: EventDefinitionId;
53
+ /**
54
+ * Required when this custom checkpoint was created from a client checkpoint
55
+ * request and should be eligible for checkpoint request retention cleanup.
56
+ * Omit or set to null for persistent custom checkpoints owned by the source
57
+ * or integration.
58
+ */
59
+ checkpoint_requested_at?: Date | null;
31
60
  }
32
61
  export interface CustomWriteCheckpointOptions extends BatchedCustomWriteCheckpointOptions {
33
62
  /**
@@ -44,13 +73,63 @@ export interface ManagedWriteCheckpointFilters extends BaseWriteCheckpointIdenti
44
73
  */
45
74
  heads: Record<string, string>;
46
75
  }
47
- export type ManagedWriteCheckpointOptions = ManagedWriteCheckpointFilters;
48
- export type SyncStorageLastWriteCheckpointFilters = BaseWriteCheckpointIdentifier | ManagedWriteCheckpointFilters;
76
+ export type ManagedWriteCheckpointOptions = ManagedWriteCheckpointFilters & ClientRequestedCheckpointOptions;
77
+ export interface CreateManagedWriteCheckpointsResult {
78
+ /**
79
+ * Current managed checkpoint id for each full user_id after applying the batch.
80
+ */
81
+ writeCheckpoints: Map<string, bigint>;
82
+ /**
83
+ * True when the source marker must be forced so replication observes the
84
+ * stored head. Callers use this to advance the source marker once for the
85
+ * whole batch.
86
+ *
87
+ * This must be true whenever a checkpoint in the batch has not yet been
88
+ * processed by replication - both freshly created/advanced checkpoints and
89
+ * existing checkpoints matched by a stale or duplicate request that are still
90
+ * pending. Already-processed checkpoints do not need a new marker.
91
+ *
92
+ * The case this guards against is a lost source marker on a stale retry. The
93
+ * source marker is forced after the checkpoint is persisted, so the two are
94
+ * not atomic (storage and source are usually different databases). Without
95
+ * this flag, the following sequence strands the checkpoint:
96
+ *
97
+ * 1. A client-supplied checkpoint id is persisted (write checkpoint stored,
98
+ * processed_at_lsn null).
99
+ * 2. Forcing the source marker fails, so the request errors and the client
100
+ * retries with the same id.
101
+ * 3. The retry is a no-op for the stored id (monotonic, not greater), so if
102
+ * we only advanced on "a row changed" we would skip the marker.
103
+ * 4. On an idle source nothing else moves replication past the stored head,
104
+ * so the checkpoint never gets acknowledged and the client waits forever.
105
+ *
106
+ * Reporting true while the checkpoint is still pending makes the retry re-force
107
+ * the marker, which resolves the wait.
108
+ *
109
+ * Backends that do not track a per-row processed indicator may conservatively
110
+ * report true whenever any checkpoint was matched.
111
+ */
112
+ shouldAdvance: boolean;
113
+ }
114
+ export declare function uniqueManagedWriteCheckpoints(checkpoints: ManagedWriteCheckpointOptions[]): ManagedWriteCheckpointOptions[];
115
+ export type SyncStorageLastWriteCheckpointFilters = SyncStorageCustomWriteCheckpointFilters | ManagedWriteCheckpointFilters;
49
116
  export type LastWriteCheckpointFilters = CustomWriteCheckpointFilters | ManagedWriteCheckpointFilters;
117
+ /** Configures checkpoint ownership and generation for a storage instance. */
118
+ export type WriteCheckpointModeConfig = {
119
+ mode: WriteCheckpointMode.CUSTOM;
120
+ /**
121
+ * Name of the event whose custom checkpoints are served. Storage resolves this name through the active sync
122
+ * config's persisted mapping; integrations must not construct or persist event ids themselves. Required by
123
+ * storage implementations that scope custom checkpoints by event definition.
124
+ */
125
+ eventName?: string;
126
+ } | {
127
+ mode: WriteCheckpointMode.MANAGED;
128
+ };
50
129
  export interface BaseWriteCheckpointAPI {
51
130
  readonly writeCheckpointMode: WriteCheckpointMode;
52
- setWriteCheckpointMode(mode: WriteCheckpointMode): void;
53
- createManagedWriteCheckpoint(checkpoint: ManagedWriteCheckpointOptions): Promise<bigint>;
131
+ setWriteCheckpointMode(config: WriteCheckpointModeConfig): void;
132
+ createManagedWriteCheckpoints(checkpoints: ManagedWriteCheckpointOptions[]): Promise<CreateManagedWriteCheckpointsResult>;
54
133
  }
55
134
  /**
56
135
  * Write Checkpoint API to be used in conjunction with a {@link SyncRulesBucketStorage}.
@@ -12,5 +12,38 @@ export var WriteCheckpointMode;
12
12
  */
13
13
  WriteCheckpointMode["MANAGED"] = "managed";
14
14
  })(WriteCheckpointMode || (WriteCheckpointMode = {}));
15
+ export function uniqueManagedWriteCheckpoints(checkpoints) {
16
+ const byUser = new Map();
17
+ for (const checkpoint of checkpoints) {
18
+ const existing = byUser.get(checkpoint.user_id);
19
+ // A batch can contain entries for many users, and different users may use
20
+ // different request types (generated vs client-supplied). For a single full
21
+ // user_id, though, all entries should be the same type - a batch can still
22
+ // hold multiple entries for that user (e.g. coalesced requests), so we
23
+ // collapse them to one. For client-supplied ids we keep the greatest
24
+ // requested value, so lower stale ids cannot hide the request that should
25
+ // advance storage. For generated ids the entries are equivalent, so any one
26
+ // is kept.
27
+ //
28
+ // Mixing generated and supplied entries for the same user_id is not expected;
29
+ // shouldReplaceManagedWriteCheckpoint still resolves it deterministically
30
+ // (supplied wins) if that invariant is ever violated.
31
+ if (existing == null || shouldReplaceManagedWriteCheckpoint(existing, checkpoint)) {
32
+ byUser.set(checkpoint.user_id, checkpoint);
33
+ }
34
+ }
35
+ return [...byUser.values()];
36
+ }
37
+ function shouldReplaceManagedWriteCheckpoint(existing, candidate) {
38
+ const existingRequestId = existing.checkpoint_request_id;
39
+ const candidateRequestId = candidate.checkpoint_request_id;
40
+ if (candidateRequestId == null) {
41
+ return existingRequestId == null;
42
+ }
43
+ if (existingRequestId == null) {
44
+ return true;
45
+ }
46
+ return candidateRequestId > existingRequestId;
47
+ }
15
48
  export const DEFAULT_WRITE_CHECKPOINT_MODE = WriteCheckpointMode.MANAGED;
16
49
  //# sourceMappingURL=WriteCheckpointAPI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WriteCheckpointAPI.js","sourceRoot":"","sources":["../../src/storage/WriteCheckpointAPI.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAYX;AAZD,WAAY,mBAAmB;IAC7B;;;OAGG;IACH,wCAAiB,CAAA;IACjB;;;;OAIG;IACH,0CAAmB,CAAA;AACrB,CAAC,EAZW,mBAAmB,KAAnB,mBAAmB,QAY9B;AAoED,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"WriteCheckpointAPI.js","sourceRoot":"","sources":["../../src/storage/WriteCheckpointAPI.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,mBAYX;AAZD,WAAY,mBAAmB;IAC7B;;;OAGG;IACH,wCAAiB,CAAA;IACjB;;;;OAIG;IACH,0CAAmB,CAAA;AACrB,CAAC,EAZW,mBAAmB,KAAnB,mBAAmB,QAY9B;AA8GD,MAAM,UAAU,6BAA6B,CAC3C,WAA4C;IAE5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEhE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAChD,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,uEAAuE;QACvE,qEAAqE;QACrE,0EAA0E;QAC1E,4EAA4E;QAC5E,WAAW;QACX,EAAE;QACF,8EAA8E;QAC9E,0EAA0E;QAC1E,sDAAsD;QACtD,IAAI,QAAQ,IAAI,IAAI,IAAI,mCAAmC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAClF,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,mCAAmC,CAC1C,QAAuC,EACvC,SAAwC;IAExC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,qBAAqB,CAAC;IACzD,MAAM,kBAAkB,GAAG,SAAS,CAAC,qBAAqB,CAAC;IAE3D,IAAI,kBAAkB,IAAI,IAAI,EAAE,CAAC;QAC/B,OAAO,iBAAiB,IAAI,IAAI,CAAC;IACnC,CAAC;IAED,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,kBAAkB,GAAG,iBAAiB,CAAC;AAChD,CAAC;AA+CD,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,OAAO,CAAC"}