@powersync/service-core 0.0.0-dev-20250317122913 → 0.0.0-dev-20250326092547

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 (108) hide show
  1. package/CHANGELOG.md +18 -4
  2. package/dist/api/api-index.d.ts +1 -0
  3. package/dist/api/api-index.js +1 -0
  4. package/dist/api/api-index.js.map +1 -1
  5. package/dist/api/api-metrics.d.ts +11 -0
  6. package/dist/api/api-metrics.js +30 -0
  7. package/dist/api/api-metrics.js.map +1 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +2 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/metrics/MetricsEngine.d.ts +21 -0
  12. package/dist/metrics/MetricsEngine.js +79 -0
  13. package/dist/metrics/MetricsEngine.js.map +1 -0
  14. package/dist/metrics/metrics-index.d.ts +5 -0
  15. package/dist/metrics/metrics-index.js +6 -0
  16. package/dist/metrics/metrics-index.js.map +1 -0
  17. package/dist/metrics/metrics-interfaces.d.ts +36 -0
  18. package/dist/metrics/metrics-interfaces.js +6 -0
  19. package/dist/metrics/metrics-interfaces.js.map +1 -0
  20. package/dist/metrics/open-telemetry/OpenTelemetryMetricsFactory.d.ts +10 -0
  21. package/dist/metrics/open-telemetry/OpenTelemetryMetricsFactory.js +51 -0
  22. package/dist/metrics/open-telemetry/OpenTelemetryMetricsFactory.js.map +1 -0
  23. package/dist/metrics/open-telemetry/util.d.ts +6 -0
  24. package/dist/metrics/open-telemetry/util.js +56 -0
  25. package/dist/metrics/open-telemetry/util.js.map +1 -0
  26. package/dist/metrics/register-metrics.d.ts +11 -0
  27. package/dist/metrics/register-metrics.js +44 -0
  28. package/dist/metrics/register-metrics.js.map +1 -0
  29. package/dist/replication/AbstractReplicationJob.d.ts +2 -0
  30. package/dist/replication/AbstractReplicationJob.js.map +1 -1
  31. package/dist/replication/AbstractReplicator.d.ts +3 -0
  32. package/dist/replication/AbstractReplicator.js +3 -0
  33. package/dist/replication/AbstractReplicator.js.map +1 -1
  34. package/dist/replication/ReplicationModule.d.ts +7 -0
  35. package/dist/replication/ReplicationModule.js +1 -0
  36. package/dist/replication/ReplicationModule.js.map +1 -1
  37. package/dist/replication/replication-index.d.ts +1 -0
  38. package/dist/replication/replication-index.js +1 -0
  39. package/dist/replication/replication-index.js.map +1 -1
  40. package/dist/replication/replication-metrics.d.ts +11 -0
  41. package/dist/replication/replication-metrics.js +39 -0
  42. package/dist/replication/replication-metrics.js.map +1 -0
  43. package/dist/routes/configure-fastify.d.ts +1 -1
  44. package/dist/routes/endpoints/probes.d.ts +2 -2
  45. package/dist/routes/endpoints/probes.js +16 -2
  46. package/dist/routes/endpoints/probes.js.map +1 -1
  47. package/dist/routes/endpoints/socket-route.js +5 -5
  48. package/dist/routes/endpoints/socket-route.js.map +1 -1
  49. package/dist/routes/endpoints/sync-stream.js +6 -6
  50. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  51. package/dist/storage/SyncRulesBucketStorage.d.ts +11 -1
  52. package/dist/storage/SyncRulesBucketStorage.js +1 -1
  53. package/dist/storage/SyncRulesBucketStorage.js.map +1 -1
  54. package/dist/storage/WriteCheckpointAPI.d.ts +0 -2
  55. package/dist/storage/WriteCheckpointAPI.js.map +1 -1
  56. package/dist/storage/storage-index.d.ts +1 -0
  57. package/dist/storage/storage-index.js +1 -0
  58. package/dist/storage/storage-index.js.map +1 -1
  59. package/dist/storage/storage-metrics.d.ts +4 -0
  60. package/dist/storage/storage-metrics.js +56 -0
  61. package/dist/storage/storage-metrics.js.map +1 -0
  62. package/dist/sync/BucketChecksumState.d.ts +4 -2
  63. package/dist/sync/BucketChecksumState.js +17 -26
  64. package/dist/sync/BucketChecksumState.js.map +1 -1
  65. package/dist/sync/RequestTracker.d.ts +3 -0
  66. package/dist/sync/RequestTracker.js +8 -3
  67. package/dist/sync/RequestTracker.js.map +1 -1
  68. package/dist/sync/util.d.ts +10 -2
  69. package/dist/sync/util.js +25 -6
  70. package/dist/sync/util.js.map +1 -1
  71. package/dist/system/ServiceContext.d.ts +3 -3
  72. package/dist/system/ServiceContext.js +7 -3
  73. package/dist/system/ServiceContext.js.map +1 -1
  74. package/package.json +8 -8
  75. package/src/api/api-index.ts +1 -0
  76. package/src/api/api-metrics.ts +35 -0
  77. package/src/index.ts +2 -2
  78. package/src/metrics/MetricsEngine.ts +98 -0
  79. package/src/metrics/metrics-index.ts +5 -0
  80. package/src/metrics/metrics-interfaces.ts +41 -0
  81. package/src/metrics/open-telemetry/OpenTelemetryMetricsFactory.ts +66 -0
  82. package/src/metrics/open-telemetry/util.ts +74 -0
  83. package/src/metrics/register-metrics.ts +56 -0
  84. package/src/replication/AbstractReplicationJob.ts +2 -0
  85. package/src/replication/AbstractReplicator.ts +7 -0
  86. package/src/replication/ReplicationModule.ts +10 -0
  87. package/src/replication/replication-index.ts +1 -0
  88. package/src/replication/replication-metrics.ts +45 -0
  89. package/src/routes/endpoints/probes.ts +18 -2
  90. package/src/routes/endpoints/socket-route.ts +6 -5
  91. package/src/routes/endpoints/sync-stream.ts +7 -6
  92. package/src/storage/SyncRulesBucketStorage.ts +12 -2
  93. package/src/storage/WriteCheckpointAPI.ts +0 -2
  94. package/src/storage/storage-index.ts +1 -0
  95. package/src/storage/storage-metrics.ts +67 -0
  96. package/src/sync/BucketChecksumState.ts +25 -41
  97. package/src/sync/RequestTracker.ts +9 -3
  98. package/src/sync/util.ts +29 -8
  99. package/src/system/ServiceContext.ts +9 -4
  100. package/test/src/routes/probes.integration.test.ts +5 -5
  101. package/test/src/routes/probes.test.ts +5 -4
  102. package/test/src/sync/BucketChecksumState.test.ts +5 -5
  103. package/test/src/util.test.ts +48 -0
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/dist/metrics/Metrics.d.ts +0 -30
  106. package/dist/metrics/Metrics.js +0 -202
  107. package/dist/metrics/Metrics.js.map +0 -1
  108. package/src/metrics/Metrics.ts +0 -255
@@ -1 +1 @@
1
- {"version":3,"file":"ReplicationModule.js","sourceRoot":"","sources":["../../src/replication/ReplicationModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAElD,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AA2BvD;;;GAGG;AACH,MAAM,OAAgB,iBACpB,SAAQ,OAAO,CAAC,cAAc;IAGpB,IAAI,CAAS;IACb,YAAY,CAAa;IACzB,aAAa,CAAsB;IAE7C;;;OAGG;IACH,YAAsB,OAAiC;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;IAeD;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,OAA8B;QACpD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;YACvC,gEAAgE;YAChE,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/G,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;YAC3B,6CAA6C;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,CACjB,iCAAiC,IAAI,CAAC,IAAI,2DAA2D,CACtG,CAAC;QACJ,CAAC;QAED,MAAM,kBAAkB,GAAG,cAAc,CAAC,CAAC,CAAY,CAAC;QACxD,yEAAyE;QACzE,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;QAEtC,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAClE,CAAC;IAES,YAAY,CAAC,MAAe;QACpC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAEO,cAAc,CAAC,MAAe;QACpC,MAAM,SAAS,GAAG,MAAM;aACrB,eAAe;QACd,4DAA4D;QAC5D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE;YACtC,eAAe,EAAE,IAAI;YACrB,OAAO,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;SACvC,CAAC,CACH;aACA,SAAS,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEzC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,IAAI,mBAAmB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAES,YAAY,CAAC,cAAsB;QAC3C,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;IAC1C,CAAC;CACF"}
1
+ {"version":3,"file":"ReplicationModule.js","sourceRoot":"","sources":["../../src/replication/ReplicationModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAElD,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAC;AA2BvD;;;GAGG;AACH,MAAM,OAAgB,iBACpB,SAAQ,OAAO,CAAC,cAAc;IAGpB,IAAI,CAAS;IACb,YAAY,CAAa;IACzB,aAAa,CAAsB;IAE7C;;;OAGG;IACH,YAAsB,OAAiC;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;IAuBD;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,OAA8B;QACpD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;YACvC,gEAAgE;YAChE,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/G,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;YAC3B,6CAA6C;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,CACjB,iCAAiC,IAAI,CAAC,IAAI,2DAA2D,CACtG,CAAC;QACJ,CAAC;QAED,MAAM,kBAAkB,GAAG,cAAc,CAAC,CAAC,CAAY,CAAC;QACxD,yEAAyE;QACzE,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;QAEtC,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAEhE,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAES,YAAY,CAAC,MAAe;QACpC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAEO,cAAc,CAAC,MAAe;QACpC,MAAM,SAAS,GAAG,MAAM;aACrB,eAAe;QACd,4DAA4D;QAC5D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE;YACtC,eAAe,EAAE,IAAI;YACrB,OAAO,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;SACvC,CAAC,CACH;aACA,SAAS,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEzC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,IAAI,mBAAmB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAES,YAAY,CAAC,cAAsB;QAC3C,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;IAC1C,CAAC;CACF"}
@@ -3,3 +3,4 @@ export * from './AbstractReplicator.js';
3
3
  export * from './ErrorRateLimiter.js';
4
4
  export * from './ReplicationEngine.js';
5
5
  export * from './ReplicationModule.js';
6
+ export * from './replication-metrics.js';
@@ -3,4 +3,5 @@ export * from './AbstractReplicator.js';
3
3
  export * from './ErrorRateLimiter.js';
4
4
  export * from './ReplicationEngine.js';
5
5
  export * from './ReplicationModule.js';
6
+ export * from './replication-metrics.js';
6
7
  //# sourceMappingURL=replication-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { MetricsEngine } from '../metrics/metrics-index.js';
2
+ /**
3
+ * Create and register the core replication metrics.
4
+ * @param engine
5
+ */
6
+ export declare function createCoreReplicationMetrics(engine: MetricsEngine): void;
7
+ /**
8
+ * Initialise the core replication metrics. This should be called after the metrics have been created.
9
+ * @param engine
10
+ */
11
+ export declare function initializeCoreReplicationMetrics(engine: MetricsEngine): void;
@@ -0,0 +1,39 @@
1
+ import { ReplicationMetric } from '@powersync/service-types';
2
+ /**
3
+ * Create and register the core replication metrics.
4
+ * @param engine
5
+ */
6
+ export function createCoreReplicationMetrics(engine) {
7
+ engine.createCounter({
8
+ name: ReplicationMetric.DATA_REPLICATED_BYTES,
9
+ description: 'Uncompressed size of replicated data',
10
+ unit: 'bytes'
11
+ });
12
+ engine.createCounter({
13
+ name: ReplicationMetric.ROWS_REPLICATED,
14
+ description: 'Total number of replicated rows'
15
+ });
16
+ engine.createCounter({
17
+ name: ReplicationMetric.TRANSACTIONS_REPLICATED,
18
+ description: 'Total number of replicated transactions'
19
+ });
20
+ engine.createCounter({
21
+ name: ReplicationMetric.CHUNKS_REPLICATED,
22
+ description: 'Total number of replication chunks'
23
+ });
24
+ }
25
+ /**
26
+ * Initialise the core replication metrics. This should be called after the metrics have been created.
27
+ * @param engine
28
+ */
29
+ export function initializeCoreReplicationMetrics(engine) {
30
+ const data_replicated_bytes = engine.getCounter(ReplicationMetric.DATA_REPLICATED_BYTES);
31
+ const rows_replicated_total = engine.getCounter(ReplicationMetric.ROWS_REPLICATED);
32
+ const transactions_replicated_total = engine.getCounter(ReplicationMetric.TRANSACTIONS_REPLICATED);
33
+ const chunks_replicated_total = engine.getCounter(ReplicationMetric.CHUNKS_REPLICATED);
34
+ data_replicated_bytes.add(0);
35
+ rows_replicated_total.add(0);
36
+ transactions_replicated_total.add(0);
37
+ chunks_replicated_total.add(0);
38
+ }
39
+ //# sourceMappingURL=replication-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replication-metrics.js","sourceRoot":"","sources":["../../src/replication/replication-metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAqB;IAChE,MAAM,CAAC,aAAa,CAAC;QACnB,IAAI,EAAE,iBAAiB,CAAC,qBAAqB;QAC7C,WAAW,EAAE,sCAAsC;QACnD,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC;QACnB,IAAI,EAAE,iBAAiB,CAAC,eAAe;QACvC,WAAW,EAAE,iCAAiC;KAC/C,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC;QACnB,IAAI,EAAE,iBAAiB,CAAC,uBAAuB;QAC/C,WAAW,EAAE,yCAAyC;KACvD,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC;QACnB,IAAI,EAAE,iBAAiB,CAAC,iBAAiB;QACzC,WAAW,EAAE,oCAAoC;KAClD,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAAqB;IACpE,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;IACzF,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IACnF,MAAM,6BAA6B,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;IACnG,MAAM,uBAAuB,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAEvF,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7B,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7B,6BAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -591,7 +591,7 @@ export declare const DEFAULT_ROUTE_OPTIONS: {
591
591
  }>>> & {
592
592
  path: import("./endpoints/probes.js").ProbeRoutes;
593
593
  method: import("@powersync/lib-services-framework").HTTPMethod.GET;
594
- handler: () => Promise<import("@powersync/lib-services-framework").RouterResponse<{
594
+ handler: (params: import("./router.js").RequestEndpointHandlerPayload<unknown, import("./router.js").Context, import("./router.js").BasicRouterRequest>) => Promise<import("@powersync/lib-services-framework").RouterResponse<{
595
595
  ready: boolean;
596
596
  started: boolean;
597
597
  touched_at: Date;
@@ -32,7 +32,7 @@ export declare const livenessCheck: router.Endpoint<unknown, router.RouterRespon
32
32
  }>>> & {
33
33
  path: ProbeRoutes;
34
34
  method: router.HTTPMethod.GET;
35
- handler: () => Promise<router.RouterResponse<{
35
+ handler: (params: import("../router.js").RequestEndpointHandlerPayload<unknown, import("../router.js").Context, import("../router.js").BasicRouterRequest>) => Promise<router.RouterResponse<{
36
36
  ready: boolean;
37
37
  started: boolean;
38
38
  touched_at: Date;
@@ -66,7 +66,7 @@ export declare const PROBES_ROUTES: (router.Endpoint<unknown, router.RouterRespo
66
66
  }>>> & {
67
67
  path: ProbeRoutes;
68
68
  method: router.HTTPMethod.GET;
69
- handler: () => Promise<router.RouterResponse<{
69
+ handler: (params: import("../router.js").RequestEndpointHandlerPayload<unknown, import("../router.js").Context, import("../router.js").BasicRouterRequest>) => Promise<router.RouterResponse<{
70
70
  ready: boolean;
71
71
  started: boolean;
72
72
  touched_at: Date;
@@ -22,10 +22,24 @@ export const startupCheck = routeDefinition({
22
22
  export const livenessCheck = routeDefinition({
23
23
  path: ProbeRoutes.LIVENESS,
24
24
  method: router.HTTPMethod.GET,
25
- handler: async () => {
25
+ handler: async (params) => {
26
26
  const state = container.probes.state();
27
+ /**
28
+ * The HTTP probes currently only function in the API and UNIFIED
29
+ * modes.
30
+ *
31
+ * For the API mode, we don't really touch the state, but any response from
32
+ * the request indicates the service is alive.
33
+ *
34
+ * For the UNIFIED mode we update the touched_at time while the Replicator engine is running.
35
+ * If the replication engine is present and the timeDifference from the last
36
+ * touched_at is large, we report that the service is not live.
37
+ *
38
+ * This is only an incremental improvement. In future these values should be configurable.
39
+ */
40
+ const isAPIOnly = !params.context.service_context.replicationEngine;
27
41
  const timeDifference = Date.now() - state.touched_at.getTime();
28
- const status = timeDifference < 10000 ? 200 : 400;
42
+ const status = isAPIOnly ? 200 : timeDifference < 10000 ? 200 : 400;
29
43
  return new router.RouterResponse({
30
44
  status,
31
45
  data: {
@@ -1 +1 @@
1
- {"version":3,"file":"probes.js","sourceRoot":"","sources":["../../../src/routes/endpoints/probes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,0CAA2B,CAAA;IAC3B,4CAA6B,CAAA;IAC7B,8CAA+B,CAAA;AACjC,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;IAC1C,IAAI,EAAE,WAAW,CAAC,OAAO;IACzB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YACjC,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;IAC3C,IAAI,EAAE,WAAW,CAAC,QAAQ;IAC1B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAElD,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM;YACN,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;IAC5C,IAAI,EAAE,WAAW,CAAC,SAAS;IAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YAC/B,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"probes.js","sourceRoot":"","sources":["../../../src/routes/endpoints/probes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,0CAA2B,CAAA;IAC3B,4CAA6B,CAAA;IAC7B,8CAA+B,CAAA;AACjC,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;IAC1C,IAAI,EAAE,WAAW,CAAC,OAAO;IACzB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YACjC,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;IAC3C,IAAI,EAAE,WAAW,CAAC,QAAQ;IAC1B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC;;;;;;;;;;;;WAYG;QAEH,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC;QACpE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAE/D,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAEpE,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM;YACN,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;IAC5C,IAAI,EAAE,WAAW,CAAC,SAAS;IAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG;IAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEvC,OAAO,IAAI,MAAM,CAAC,cAAc,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YAC/B,IAAI,EAAE;gBACJ,GAAG,KAAK;aACT;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC"}
@@ -1,15 +1,15 @@
1
1
  import { ErrorCode, errors, logger, schema } from '@powersync/lib-services-framework';
2
2
  import { RequestParameters } from '@powersync/service-sync-rules';
3
3
  import { serialize } from 'bson';
4
- import { Metrics } from '../../metrics/Metrics.js';
5
4
  import * as sync from '../../sync/sync-index.js';
6
5
  import * as util from '../../util/util-index.js';
7
6
  import { SyncRoutes } from './sync-stream.js';
7
+ import { APIMetric } from '@powersync/service-types';
8
8
  export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.STREAM, {
9
9
  validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
10
10
  handler: async ({ context, params, responder, observer, initialN, signal: upstreamSignal }) => {
11
11
  const { service_context } = context;
12
- const { routerEngine, syncContext } = service_context;
12
+ const { routerEngine, metricsEngine, syncContext } = service_context;
13
13
  // Create our own controller that we can abort directly
14
14
  const controller = new AbortController();
15
15
  upstreamSignal.addEventListener('abort', () => {
@@ -50,8 +50,8 @@ export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.S
50
50
  const removeStopHandler = routerEngine.addStopHandler(() => {
51
51
  controller.abort();
52
52
  });
53
- Metrics.getInstance().concurrent_connections.add(1);
54
- const tracker = new sync.RequestTracker();
53
+ metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
54
+ const tracker = new sync.RequestTracker(metricsEngine);
55
55
  try {
56
56
  for await (const data of sync.streamResponse({
57
57
  syncContext: syncContext,
@@ -129,7 +129,7 @@ export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.S
129
129
  operations_synced: tracker.operationsSynced,
130
130
  data_synced_bytes: tracker.dataSyncedBytes
131
131
  });
132
- Metrics.getInstance().concurrent_connections.add(-1);
132
+ metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
133
133
  }
134
134
  }
135
135
  });
@@ -1 +1 @@
1
- {"version":3,"file":"socket-route.js","sourceRoot":"","sources":["../../../src/routes/endpoints/socket-route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket-route.js","sourceRoot":"","sources":["../../../src/routes/endpoints/socket-route.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,9 @@ import { RequestParameters } from '@powersync/service-sync-rules';
3
3
  import { Readable } from 'stream';
4
4
  import * as sync from '../../sync/sync-index.js';
5
5
  import * as util from '../../util/util-index.js';
6
- import { Metrics } from '../../metrics/Metrics.js';
7
6
  import { authUser } from '../auth.js';
8
7
  import { routeDefinition } from '../router.js';
8
+ import { APIMetric } from '@powersync/service-types';
9
9
  export var SyncRoutes;
10
10
  (function (SyncRoutes) {
11
11
  SyncRoutes["STREAM"] = "/sync/stream";
@@ -17,7 +17,7 @@ export const syncStreamed = routeDefinition({
17
17
  validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
18
18
  handler: async (payload) => {
19
19
  const { service_context } = payload.context;
20
- const { routerEngine, storageEngine, syncContext } = service_context;
20
+ const { routerEngine, storageEngine, metricsEngine, syncContext } = service_context;
21
21
  const headers = payload.request.headers;
22
22
  const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
23
23
  const clientId = payload.params.client_id;
@@ -40,9 +40,9 @@ export const syncStreamed = routeDefinition({
40
40
  }
41
41
  const syncRules = bucketStorage.getParsedSyncRules(routerEngine.getAPI().getParseSyncRulesOptions());
42
42
  const controller = new AbortController();
43
- const tracker = new sync.RequestTracker();
43
+ const tracker = new sync.RequestTracker(metricsEngine);
44
44
  try {
45
- Metrics.getInstance().concurrent_connections.add(1);
45
+ metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
46
46
  const stream = Readable.from(sync.transformToBytesTracked(sync.ndjson(sync.streamResponse({
47
47
  syncContext: syncContext,
48
48
  bucketStorage,
@@ -76,7 +76,7 @@ export const syncStreamed = routeDefinition({
76
76
  data: stream,
77
77
  afterSend: async () => {
78
78
  controller.abort();
79
- Metrics.getInstance().concurrent_connections.add(-1);
79
+ metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
80
80
  logger.info(`Sync stream complete`, {
81
81
  user_id: syncParams.user_id,
82
82
  client_id: clientId,
@@ -89,7 +89,7 @@ export const syncStreamed = routeDefinition({
89
89
  }
90
90
  catch (ex) {
91
91
  controller.abort();
92
- Metrics.getInstance().concurrent_connections.add(-1);
92
+ metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
93
93
  }
94
94
  }
95
95
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"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"}
@@ -52,6 +52,16 @@ export interface SyncRulesBucketStorage extends ObserverClient<SyncRulesBucketSt
52
52
  * Used to resolve "dynamic" parameter queries.
53
53
  */
54
54
  getParameterSets(checkpoint: util.InternalOpId, lookups: ParameterLookup[]): Promise<SqliteJsonRow[]>;
55
+ /**
56
+ * Given two checkpoints, return the changes in bucket data and parameters that may have occurred
57
+ * in that period.
58
+ *
59
+ * This is a best-effort optimization:
60
+ * 1. This may include more changes than what actually occurred.
61
+ * 2. This may return invalidateDataBuckets or invalidateParameterBuckets instead of of returning
62
+ * specific changes.
63
+ * @param options
64
+ */
55
65
  getCheckpointChanges(options: GetCheckpointChangesOptions): Promise<CheckpointChanges>;
56
66
  /**
57
67
  * Yields the latest user write checkpoint whenever the sync checkpoint updates.
@@ -199,7 +209,7 @@ export interface GetCheckpointChangesOptions {
199
209
  nextCheckpoint: util.InternalOpId;
200
210
  }
201
211
  export interface CheckpointChanges {
202
- updatedDataBuckets: string[];
212
+ updatedDataBuckets: Set<string>;
203
213
  invalidateDataBuckets: boolean;
204
214
  /** Serialized using JSONBig */
205
215
  updatedParameterLookups: Set<string>;
@@ -1,5 +1,5 @@
1
1
  export const CHECKPOINT_INVALIDATE_ALL = {
2
- updatedDataBuckets: [],
2
+ updatedDataBuckets: new Set(),
3
3
  invalidateDataBuckets: true,
4
4
  updatedParameterLookups: new Set(),
5
5
  invalidateParameterBuckets: true
@@ -1 +1 @@
1
- {"version":3,"file":"SyncRulesBucketStorage.js","sourceRoot":"","sources":["../../src/storage/SyncRulesBucketStorage.ts"],"names":[],"mappings":"AAoQA,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,kBAAkB,EAAE,EAAE;IACtB,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":"AA8QA,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"}
@@ -82,7 +82,6 @@ export interface BaseWriteCheckpointAPI {
82
82
  */
83
83
  export interface SyncStorageWriteCheckpointAPI extends BaseWriteCheckpointAPI {
84
84
  batchCreateCustomWriteCheckpoints(checkpoints: BatchedCustomWriteCheckpointOptions[]): Promise<void>;
85
- createCustomWriteCheckpoint(checkpoint: BatchedCustomWriteCheckpointOptions): Promise<bigint>;
86
85
  lastWriteCheckpoint(filters: SyncStorageLastWriteCheckpointFilters): Promise<bigint | null>;
87
86
  }
88
87
  /**
@@ -91,7 +90,6 @@ export interface SyncStorageWriteCheckpointAPI extends BaseWriteCheckpointAPI {
91
90
  */
92
91
  export interface WriteCheckpointAPI extends BaseWriteCheckpointAPI {
93
92
  batchCreateCustomWriteCheckpoints(checkpoints: CustomWriteCheckpointOptions[]): Promise<void>;
94
- createCustomWriteCheckpoint(checkpoint: CustomWriteCheckpointOptions): Promise<bigint>;
95
93
  lastWriteCheckpoint(filters: LastWriteCheckpointFilters): Promise<bigint | null>;
96
94
  watchUserWriteCheckpoint(options: WatchUserWriteCheckpointOptions): AsyncIterable<WriteCheckpointResult>;
97
95
  }
@@ -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;AAoGD,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,OAAO,CAAC"}
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;AAkGD,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,OAAO,CAAC"}
@@ -6,6 +6,7 @@ export * from './SourceEntity.js';
6
6
  export * from './SourceTable.js';
7
7
  export * from './StorageEngine.js';
8
8
  export * from './StorageProvider.js';
9
+ export * from './storage-metrics.js';
9
10
  export * from './WriteCheckpointAPI.js';
10
11
  export * from './BucketStorageFactory.js';
11
12
  export * from './BucketStorageBatch.js';
@@ -6,6 +6,7 @@ export * from './SourceEntity.js';
6
6
  export * from './SourceTable.js';
7
7
  export * from './StorageEngine.js';
8
8
  export * from './StorageProvider.js';
9
+ export * from './storage-metrics.js';
9
10
  export * from './WriteCheckpointAPI.js';
10
11
  export * from './BucketStorageFactory.js';
11
12
  export * from './BucketStorageBatch.js';
@@ -1 +1 @@
1
- {"version":3,"file":"storage-index.js","sourceRoot":"","sources":["../../src/storage/storage-index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"storage-index.js","sourceRoot":"","sources":["../../src/storage/storage-index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { MetricsEngine } from '../metrics/MetricsEngine.js';
2
+ import { BucketStorageFactory } from './BucketStorageFactory.js';
3
+ export declare function createCoreStorageMetrics(engine: MetricsEngine): void;
4
+ export declare function initializeCoreStorageMetrics(engine: MetricsEngine, storage: BucketStorageFactory): void;
@@ -0,0 +1,56 @@
1
+ import { logger } from '@powersync/lib-services-framework';
2
+ import { StorageMetric } from '@powersync/service-types';
3
+ export function createCoreStorageMetrics(engine) {
4
+ engine.createObservableGauge({
5
+ name: StorageMetric.REPLICATION_SIZE_BYTES,
6
+ description: 'Size of current data stored in PowerSync',
7
+ unit: 'bytes'
8
+ });
9
+ engine.createObservableGauge({
10
+ name: StorageMetric.OPERATION_SIZE_BYTES,
11
+ description: 'Size of operations stored in PowerSync',
12
+ unit: 'bytes'
13
+ });
14
+ engine.createObservableGauge({
15
+ name: StorageMetric.PARAMETER_SIZE_BYTES,
16
+ description: 'Size of parameter data stored in PowerSync',
17
+ unit: 'bytes'
18
+ });
19
+ }
20
+ export function initializeCoreStorageMetrics(engine, storage) {
21
+ const replication_storage_size_bytes = engine.getObservableGauge(StorageMetric.REPLICATION_SIZE_BYTES);
22
+ const operation_storage_size_bytes = engine.getObservableGauge(StorageMetric.OPERATION_SIZE_BYTES);
23
+ const parameter_storage_size_bytes = engine.getObservableGauge(StorageMetric.PARAMETER_SIZE_BYTES);
24
+ const MINIMUM_INTERVAL = 60_000;
25
+ let cachedRequest = undefined;
26
+ let cacheTimestamp = 0;
27
+ const getMetrics = () => {
28
+ if (cachedRequest == null || Date.now() - cacheTimestamp > MINIMUM_INTERVAL) {
29
+ cachedRequest = storage.getStorageMetrics().catch((e) => {
30
+ logger.error(`Failed to get storage metrics`, e);
31
+ return null;
32
+ });
33
+ cacheTimestamp = Date.now();
34
+ }
35
+ return cachedRequest;
36
+ };
37
+ replication_storage_size_bytes.setValueProvider(async () => {
38
+ const metrics = await getMetrics();
39
+ if (metrics) {
40
+ return metrics.replication_size_bytes;
41
+ }
42
+ });
43
+ operation_storage_size_bytes.setValueProvider(async () => {
44
+ const metrics = await getMetrics();
45
+ if (metrics) {
46
+ return metrics.operations_size_bytes;
47
+ }
48
+ });
49
+ parameter_storage_size_bytes.setValueProvider(async () => {
50
+ const metrics = await getMetrics();
51
+ if (metrics) {
52
+ return metrics.parameters_size_bytes;
53
+ }
54
+ });
55
+ }
56
+ //# sourceMappingURL=storage-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-metrics.js","sourceRoot":"","sources":["../../src/storage/storage-metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,UAAU,wBAAwB,CAAC,MAAqB;IAC5D,MAAM,CAAC,qBAAqB,CAAC;QAC3B,IAAI,EAAE,aAAa,CAAC,sBAAsB;QAC1C,WAAW,EAAE,0CAA0C;QACvD,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IAEH,MAAM,CAAC,qBAAqB,CAAC;QAC3B,IAAI,EAAE,aAAa,CAAC,oBAAoB;QACxC,WAAW,EAAE,wCAAwC;QACrD,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IAEH,MAAM,CAAC,qBAAqB,CAAC;QAC3B,IAAI,EAAE,aAAa,CAAC,oBAAoB;QACxC,WAAW,EAAE,4CAA4C;QACzD,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAAqB,EAAE,OAA6B;IAC/F,MAAM,8BAA8B,GAAG,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IACvG,MAAM,4BAA4B,GAAG,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACnG,MAAM,4BAA4B,GAAG,MAAM,CAAC,kBAAkB,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAEnG,MAAM,gBAAgB,GAAG,MAAM,CAAC;IAEhC,IAAI,aAAa,GAA+C,SAAS,CAAC;IAC1E,IAAI,cAAc,GAAG,CAAC,CAAC;IAEvB,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,GAAG,gBAAgB,EAAE,CAAC;YAC5E,aAAa,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACtD,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC,CAAC;IAEF,8BAA8B,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;QACzD,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,sBAAsB,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4BAA4B,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;QACvD,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,qBAAqB,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4BAA4B,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;QACvD,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,qBAAqB,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -58,6 +58,7 @@ export declare class BucketChecksumState {
58
58
  hasMore: boolean;
59
59
  }): void;
60
60
  }
61
+ declare const INVALIDATE_ALL_BUCKETS: unique symbol;
61
62
  export interface CheckpointUpdate {
62
63
  /**
63
64
  * All buckets forming part of the checkpoint.
@@ -68,7 +69,7 @@ export interface CheckpointUpdate {
68
69
  *
69
70
  * If null, assume that any bucket in `buckets` may have been updated.
70
71
  */
71
- updatedBuckets: Set<string> | null;
72
+ updatedBuckets: Set<string> | typeof INVALIDATE_ALL_BUCKETS;
72
73
  }
73
74
  export declare class BucketParameterState {
74
75
  private readonly context;
@@ -81,7 +82,7 @@ export declare class BucketParameterState {
81
82
  private cachedDynamicBucketSet;
82
83
  private readonly lookups;
83
84
  constructor(context: SyncContext, bucketStorage: BucketChecksumStateStorage, syncRules: SqlSyncRules, syncParams: RequestParameters);
84
- getCheckpointUpdate(checkpoint: storage.StorageCheckpointUpdate): Promise<CheckpointUpdate | null>;
85
+ getCheckpointUpdate(checkpoint: storage.StorageCheckpointUpdate): Promise<CheckpointUpdate>;
85
86
  /**
86
87
  * For static buckets, we can keep track of which buckets have been updated.
87
88
  */
@@ -96,3 +97,4 @@ export interface CheckpointLine {
96
97
  bucketsToFetch: BucketDescription[];
97
98
  }
98
99
  export type BucketChecksumStateStorage = Pick<storage.SyncRulesBucketStorage, 'getChecksums' | 'getParameterSets'>;
100
+ export {};
@@ -1,7 +1,7 @@
1
1
  import * as util from '../util/util-index.js';
2
2
  import { ErrorCode, logger, ServiceAssertionError, ServiceError } from '@powersync/lib-services-framework';
3
3
  import { JSONBig } from '@powersync/service-jsonbig';
4
- import { hasIntersection } from './util.js';
4
+ import { getIntersection, hasIntersection } from './util.js';
5
5
  /**
6
6
  * Represents the state of the checksums and data for a specific connection.
7
7
  *
@@ -40,7 +40,7 @@ export class BucketChecksumState {
40
40
  const user_id = this.parameterState.syncParams.user_id;
41
41
  const storage = this.bucketStorage;
42
42
  const update = await this.parameterState.getCheckpointUpdate(next);
43
- if (update == null) {
43
+ if (update == null && this.lastWriteCheckpoint == writeCheckpoint) {
44
44
  return null;
45
45
  }
46
46
  const { buckets: allBuckets, updatedBuckets } = update;
@@ -56,7 +56,7 @@ export class BucketChecksumState {
56
56
  throw new ServiceError(ErrorCode.PSYNC_S2305, `Too many buckets: ${dataBucketsNew.size} (limit of ${this.context.maxBuckets})`);
57
57
  }
58
58
  let checksumMap;
59
- if (updatedBuckets != null) {
59
+ if (updatedBuckets != INVALIDATE_ALL_BUCKETS) {
60
60
  if (this.lastChecksums == null) {
61
61
  throw new ServiceAssertionError(`Bucket diff received without existing checksums`);
62
62
  }
@@ -77,9 +77,11 @@ export class BucketChecksumState {
77
77
  checksumLookups.push(bucket);
78
78
  }
79
79
  }
80
- let updatedChecksums = await storage.getChecksums(base.checkpoint, checksumLookups);
81
- for (let [bucket, value] of updatedChecksums.entries()) {
82
- newChecksums.set(bucket, value);
80
+ if (checksumLookups.length > 0) {
81
+ let updatedChecksums = await storage.getChecksums(base.checkpoint, checksumLookups);
82
+ for (let [bucket, value] of updatedChecksums.entries()) {
83
+ newChecksums.set(bucket, value);
84
+ }
83
85
  }
84
86
  checksumMap = newChecksums;
85
87
  }
@@ -199,6 +201,7 @@ export class BucketChecksumState {
199
201
  }
200
202
  }
201
203
  }
204
+ const INVALIDATE_ALL_BUCKETS = Symbol('INVALIDATE_ALL_BUCKETS');
202
205
  export class BucketParameterState {
203
206
  context;
204
207
  bucketStorage;
@@ -227,9 +230,6 @@ export class BucketParameterState {
227
230
  else {
228
231
  update = await this.getCheckpointUpdateStatic(checkpoint);
229
232
  }
230
- if (update == null) {
231
- return null;
232
- }
233
233
  if (update.buckets.length > this.context.maxParameterQueryResults) {
234
234
  // TODO: Limit number of results even before we get to this point
235
235
  // This limit applies _before_ we get the unique set
@@ -252,19 +252,10 @@ export class BucketParameterState {
252
252
  if (update.invalidateDataBuckets) {
253
253
  return {
254
254
  buckets: querier.staticBuckets,
255
- updatedBuckets: null
255
+ updatedBuckets: INVALIDATE_ALL_BUCKETS
256
256
  };
257
257
  }
258
- let updatedBuckets = new Set();
259
- for (let bucket of update.updatedDataBuckets ?? []) {
260
- if (this.staticBuckets.has(bucket)) {
261
- updatedBuckets.add(bucket);
262
- }
263
- }
264
- if (updatedBuckets.size == 0) {
265
- // No change - skip this checkpoint
266
- return null;
267
- }
258
+ const updatedBuckets = new Set(getIntersection(this.staticBuckets, update.updatedDataBuckets));
268
259
  return {
269
260
  buckets: querier.staticBuckets,
270
261
  updatedBuckets
@@ -309,11 +300,11 @@ export class BucketParameterState {
309
300
  else {
310
301
  dynamicBuckets = this.cachedDynamicBuckets;
311
302
  if (!invalidateDataBuckets) {
312
- // TODO: Do set intersection instead
313
- for (let bucket of update.updatedDataBuckets ?? []) {
314
- if (this.staticBuckets.has(bucket) || this.cachedDynamicBucketSet.has(bucket)) {
315
- updatedBuckets.add(bucket);
316
- }
303
+ for (let bucket of getIntersection(this.staticBuckets, update.updatedDataBuckets)) {
304
+ updatedBuckets.add(bucket);
305
+ }
306
+ for (let bucket of getIntersection(this.cachedDynamicBucketSet, update.updatedDataBuckets)) {
307
+ updatedBuckets.add(bucket);
317
308
  }
318
309
  }
319
310
  }
@@ -322,7 +313,7 @@ export class BucketParameterState {
322
313
  return {
323
314
  buckets: allBuckets,
324
315
  // We cannot track individual bucket updates for dynamic lookups yet
325
- updatedBuckets: null
316
+ updatedBuckets: INVALIDATE_ALL_BUCKETS
326
317
  };
327
318
  }
328
319
  else {