@powersync/service-core 0.0.0-dev-20250910154512 → 0.0.0-dev-20251030082344

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 (44) hide show
  1. package/CHANGELOG.md +30 -10
  2. package/dist/entry/commands/compact-action.js +1 -1
  3. package/dist/entry/commands/compact-action.js.map +1 -1
  4. package/dist/routes/configure-fastify.js.map +1 -1
  5. package/dist/routes/endpoints/socket-route.js +2 -15
  6. package/dist/routes/endpoints/socket-route.js.map +1 -1
  7. package/dist/routes/endpoints/sync-stream.js +2 -19
  8. package/dist/routes/endpoints/sync-stream.js.map +1 -1
  9. package/dist/routes/router.d.ts +3 -3
  10. package/dist/storage/BucketStorageFactory.d.ts +0 -2
  11. package/dist/storage/StorageEngine.d.ts +2 -2
  12. package/dist/storage/StorageEngine.js.map +1 -1
  13. package/dist/storage/StorageProvider.d.ts +1 -3
  14. package/dist/storage/SyncRulesBucketStorage.d.ts +12 -1
  15. package/dist/storage/SyncRulesBucketStorage.js.map +1 -1
  16. package/dist/storage/storage-index.d.ts +0 -1
  17. package/dist/storage/storage-index.js +0 -1
  18. package/dist/storage/storage-index.js.map +1 -1
  19. package/dist/system/ServiceContext.d.ts +0 -3
  20. package/dist/system/ServiceContext.js +1 -10
  21. package/dist/system/ServiceContext.js.map +1 -1
  22. package/package.json +7 -7
  23. package/src/entry/commands/compact-action.ts +1 -1
  24. package/src/routes/configure-fastify.ts +1 -0
  25. package/src/routes/endpoints/socket-route.ts +3 -16
  26. package/src/routes/endpoints/sync-stream.ts +2 -19
  27. package/src/routes/router.ts +3 -3
  28. package/src/storage/BucketStorageFactory.ts +0 -2
  29. package/src/storage/StorageEngine.ts +3 -3
  30. package/src/storage/StorageProvider.ts +1 -3
  31. package/src/storage/SyncRulesBucketStorage.ts +14 -1
  32. package/src/storage/storage-index.ts +0 -1
  33. package/src/system/ServiceContext.ts +1 -13
  34. package/test/src/routes/mocks.ts +0 -2
  35. package/test/src/routes/stream.test.ts +5 -13
  36. package/tsconfig.tsbuildinfo +1 -1
  37. package/dist/events/EventsEngine.d.ts +0 -14
  38. package/dist/events/EventsEngine.js +0 -33
  39. package/dist/events/EventsEngine.js.map +0 -1
  40. package/dist/storage/ReportStorage.d.ts +0 -36
  41. package/dist/storage/ReportStorage.js +0 -2
  42. package/dist/storage/ReportStorage.js.map +0 -1
  43. package/src/events/EventsEngine.ts +0 -38
  44. package/src/storage/ReportStorage.ts +0 -39
@@ -7,8 +7,8 @@ import * as util from '../../util/util-index.js';
7
7
 
8
8
  import { authUser } from '../auth.js';
9
9
  import { routeDefinition } from '../router.js';
10
- import { APIMetric, event_types } from '@powersync/service-types';
11
10
 
11
+ import { APIMetric } from '@powersync/service-types';
12
12
  import { maybeCompressResponseStream } from '../compression.js';
13
13
 
14
14
  export enum SyncRoutes {
@@ -25,7 +25,7 @@ export const syncStreamed = routeDefinition({
25
25
  authorize: authUser,
26
26
  validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
27
27
  handler: async (payload) => {
28
- const { service_context, logger, token_payload } = payload.context;
28
+ const { service_context, logger } = payload.context;
29
29
  const { routerEngine, storageEngine, metricsEngine, syncContext } = service_context;
30
30
  const headers = payload.request.headers;
31
31
  const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
@@ -44,14 +44,6 @@ export const syncStreamed = routeDefinition({
44
44
  user_id: payload.context.user_id,
45
45
  bson: useBson
46
46
  };
47
- const sdkData: event_types.ConnectedUserData & event_types.ClientConnectionEventData = {
48
- client_id: clientId ?? '',
49
- user_id: payload.context.user_id!,
50
- user_agent: userAgent as string,
51
- // At this point the token_payload is guaranteed to be present
52
- jwt_exp: new Date(token_payload!.exp * 1000),
53
- connected_at: new Date(streamStart)
54
- };
55
47
 
56
48
  if (routerEngine.closed) {
57
49
  throw new errors.ServiceError({
@@ -77,7 +69,6 @@ export const syncStreamed = routeDefinition({
77
69
  const tracker = new sync.RequestTracker(metricsEngine);
78
70
  try {
79
71
  metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
80
- service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_CONNECT_EVENT, sdkData);
81
72
  const syncLines = sync.streamResponse({
82
73
  syncContext: syncContext,
83
74
  bucketStorage,
@@ -143,10 +134,6 @@ export const syncStreamed = routeDefinition({
143
134
  }
144
135
  controller.abort();
145
136
  metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
146
- service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
147
- ...sdkData,
148
- disconnected_at: new Date()
149
- });
150
137
  logger.info(`Sync stream complete`, {
151
138
  ...tracker.getLogMeta(),
152
139
  stream_ms: Date.now() - streamStart,
@@ -157,10 +144,6 @@ export const syncStreamed = routeDefinition({
157
144
  } catch (ex) {
158
145
  controller.abort();
159
146
  metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
160
- service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
161
- ...sdkData,
162
- disconnected_at: new Date()
163
- });
164
147
  }
165
148
  }
166
149
  });
@@ -1,4 +1,4 @@
1
- import { Logger, router } from '@powersync/lib-services-framework';
1
+ import { router, ServiceError, Logger } from '@powersync/lib-services-framework';
2
2
  import type { JwtPayload } from '../auth/auth-index.js';
3
3
  import { ServiceContext } from '../system/ServiceContext.js';
4
4
  import { RouterEngine } from './RouterEngine.js';
@@ -31,11 +31,11 @@ export type BasicRouterRequest = {
31
31
  hostname: string;
32
32
  };
33
33
 
34
- export type ContextProviderOptions = {
34
+ export type ConextProviderOptions = {
35
35
  logger: Logger;
36
36
  };
37
37
 
38
- export type ContextProvider = (request: BasicRouterRequest, options: ContextProviderOptions) => Promise<Context>;
38
+ export type ContextProvider = (request: BasicRouterRequest, options: ConextProviderOptions) => Promise<Context>;
39
39
 
40
40
  export type RequestEndpoint<
41
41
  I,
@@ -3,7 +3,6 @@ import { ParseSyncRulesOptions, PersistedSyncRules, PersistedSyncRulesContent }
3
3
  import { ReplicationEventPayload } from './ReplicationEventPayload.js';
4
4
  import { ReplicationLock } from './ReplicationLock.js';
5
5
  import { SyncRulesBucketStorage } from './SyncRulesBucketStorage.js';
6
- import { ReportStorage } from './ReportStorage.js';
7
6
 
8
7
  /**
9
8
  * Represents a configured storage provider.
@@ -165,4 +164,3 @@ export interface TestStorageOptions {
165
164
  doNotClear?: boolean;
166
165
  }
167
166
  export type TestStorageFactory = (options?: TestStorageOptions) => Promise<BucketStorageFactory>;
168
- export type TestReportStorageFactory = (options?: TestStorageOptions) => Promise<ReportStorage>;
@@ -1,7 +1,7 @@
1
1
  import { BaseObserver, logger, ServiceError } from '@powersync/lib-services-framework';
2
2
  import { ResolvedPowerSyncConfig } from '../util/util-index.js';
3
3
  import { BucketStorageFactory } from './BucketStorageFactory.js';
4
- import { ActiveStorage, StorageProvider } from './StorageProvider.js';
4
+ import { ActiveStorage, BucketStorageProvider } from './StorageProvider.js';
5
5
 
6
6
  export type StorageEngineOptions = {
7
7
  configuration: ResolvedPowerSyncConfig;
@@ -14,7 +14,7 @@ export interface StorageEngineListener {
14
14
 
15
15
  export class StorageEngine extends BaseObserver<StorageEngineListener> {
16
16
  // TODO: This will need to revisited when we actually support multiple storage providers.
17
- private storageProviders: Map<string, StorageProvider> = new Map();
17
+ private storageProviders: Map<string, BucketStorageProvider> = new Map();
18
18
  private currentActiveStorage: ActiveStorage | null = null;
19
19
 
20
20
  constructor(private options: StorageEngineOptions) {
@@ -37,7 +37,7 @@ export class StorageEngine extends BaseObserver<StorageEngineListener> {
37
37
  * Register a provider which generates a {@link BucketStorageFactory}
38
38
  * given the matching config specified in the loaded {@link ResolvedPowerSyncConfig}
39
39
  */
40
- registerProvider(provider: StorageProvider) {
40
+ registerProvider(provider: BucketStorageProvider) {
41
41
  this.storageProviders.set(provider.type, provider);
42
42
  }
43
43
 
@@ -1,11 +1,9 @@
1
1
  import { ServiceError } from '@powersync/lib-services-framework';
2
2
  import * as util from '../util/util-index.js';
3
3
  import { BucketStorageFactory } from './BucketStorageFactory.js';
4
- import { ReportStorage } from './ReportStorage.js';
5
4
 
6
5
  export interface ActiveStorage {
7
6
  storage: BucketStorageFactory;
8
- reportStorage: ReportStorage;
9
7
  shutDown(): Promise<void>;
10
8
 
11
9
  /**
@@ -24,7 +22,7 @@ export interface GetStorageOptions {
24
22
  /**
25
23
  * Represents a provider that can create a storage instance for a specific storage type from configuration.
26
24
  */
27
- export interface StorageProvider {
25
+ export interface BucketStorageProvider {
28
26
  /**
29
27
  * The storage type that this provider provides.
30
28
  * The type should match the `type` field in the config.
@@ -65,7 +65,7 @@ export interface SyncRulesBucketStorage
65
65
  /**
66
66
  * Lightweight "compact" process to populate the checksum cache, if any.
67
67
  */
68
- populatePersistentChecksumCache(options?: Pick<CompactOptions, 'signal' | 'maxOpId'>): Promise<void>;
68
+ populatePersistentChecksumCache(options: PopulateChecksumCacheOptions): Promise<PopulateChecksumCacheResults>;
69
69
 
70
70
  // ## Read operations
71
71
 
@@ -225,6 +225,19 @@ export interface CompactOptions {
225
225
  signal?: AbortSignal;
226
226
  }
227
227
 
228
+ export interface PopulateChecksumCacheOptions {
229
+ maxOpId: util.InternalOpId;
230
+ minBucketChanges?: number;
231
+ signal?: AbortSignal;
232
+ }
233
+
234
+ export interface PopulateChecksumCacheResults {
235
+ /**
236
+ * Number of buckets we have calculated checksums for.
237
+ */
238
+ buckets: number;
239
+ }
240
+
228
241
  export interface ClearStorageOptions {
229
242
  signal?: AbortSignal;
230
243
  }
@@ -13,4 +13,3 @@ export * from './BucketStorageBatch.js';
13
13
  export * from './SyncRulesBucketStorage.js';
14
14
  export * from './PersistedSyncRulesContent.js';
15
15
  export * from './ReplicationLock.js';
16
- export * from './ReportStorage.js';
@@ -1,4 +1,4 @@
1
- import { container, LifeCycledSystem, MigrationManager, ServiceIdentifier } from '@powersync/lib-services-framework';
1
+ import { LifeCycledSystem, MigrationManager, ServiceIdentifier, container } from '@powersync/lib-services-framework';
2
2
 
3
3
  import { framework } from '../index.js';
4
4
  import * as metrics from '../metrics/MetricsEngine.js';
@@ -8,7 +8,6 @@ import * as routes from '../routes/routes-index.js';
8
8
  import * as storage from '../storage/storage-index.js';
9
9
  import { SyncContext } from '../sync/SyncContext.js';
10
10
  import * as utils from '../util/util-index.js';
11
- import { EventsEngine } from '../events/EventsEngine.js';
12
11
 
13
12
  export interface ServiceContext {
14
13
  configuration: utils.ResolvedPowerSyncConfig;
@@ -20,7 +19,6 @@ export interface ServiceContext {
20
19
  migrations: PowerSyncMigrationManager;
21
20
  syncContext: SyncContext;
22
21
  serviceMode: ServiceContextMode;
23
- eventsEngine: EventsEngine;
24
22
  }
25
23
 
26
24
  export enum ServiceContextMode {
@@ -47,7 +45,6 @@ export class ServiceContextContainer implements ServiceContext {
47
45
  configuration: utils.ResolvedPowerSyncConfig;
48
46
  lifeCycleEngine: LifeCycledSystem;
49
47
  storageEngine: storage.StorageEngine;
50
- eventsEngine: EventsEngine;
51
48
  syncContext: SyncContext;
52
49
  routerEngine: routes.RouterEngine;
53
50
  serviceMode: ServiceContextMode;
@@ -69,11 +66,6 @@ export class ServiceContextContainer implements ServiceContext {
69
66
  }
70
67
  });
71
68
 
72
- this.eventsEngine = new EventsEngine();
73
- this.lifeCycleEngine.withLifecycle(this.eventsEngine, {
74
- stop: (emitterEngine) => emitterEngine.shutDown()
75
- });
76
-
77
69
  this.lifeCycleEngine.withLifecycle(this.storageEngine, {
78
70
  start: (storageEngine) => storageEngine.start(),
79
71
  stop: (storageEngine) => storageEngine.shutDown()
@@ -97,10 +89,6 @@ export class ServiceContextContainer implements ServiceContext {
97
89
  // Migrations should be executed before the system starts
98
90
  start: () => migrationManager[Symbol.asyncDispose]()
99
91
  });
100
-
101
- this.lifeCycleEngine.withLifecycle(this.eventsEngine, {
102
- stop: (emitterEngine) => emitterEngine.shutDown()
103
- });
104
92
  }
105
93
 
106
94
  get replicationEngine(): replication.ReplicationEngine | null {
@@ -11,7 +11,6 @@ import {
11
11
  SyncRulesBucketStorage
12
12
  } from '@/index.js';
13
13
  import { MeterProvider } from '@opentelemetry/sdk-metrics';
14
- import { EventsEngine } from '@/events/EventsEngine.js';
15
14
 
16
15
  export function mockServiceContext(storage: Partial<SyncRulesBucketStorage> | null) {
17
16
  // This is very incomplete - just enough to get the current tests passing.
@@ -35,7 +34,6 @@ export function mockServiceContext(storage: Partial<SyncRulesBucketStorage> | nu
35
34
  createCoreAPIMetrics(metricsEngine);
36
35
  const service_context: Partial<ServiceContext> = {
37
36
  syncContext: new SyncContext({ maxBuckets: 1, maxDataFetchConcurrency: 1, maxParameterQueryResults: 1 }),
38
- eventsEngine: new EventsEngine(),
39
37
  routerEngine: {
40
38
  getAPI() {
41
39
  return {
@@ -12,12 +12,7 @@ describe('Stream Route', () => {
12
12
  it('handles missing sync rules', async () => {
13
13
  const context: Context = {
14
14
  logger: logger,
15
- service_context: mockServiceContext(null),
16
- token_payload: {
17
- sub: '',
18
- exp: 0,
19
- iat: 0
20
- }
15
+ service_context: mockServiceContext(null)
21
16
  };
22
17
 
23
18
  const request: BasicRouterRequest = {
@@ -26,13 +21,10 @@ describe('Stream Route', () => {
26
21
  protocol: 'http'
27
22
  };
28
23
 
29
- const error = (await (
30
- syncStreamed.handler({
31
- context,
32
- params: {},
33
- request
34
- }) as Promise<RouterResponse>
35
- ).catch((e) => e)) as ServiceError;
24
+ const error = (await (syncStreamed.handler({ context, params: {}, request }) as Promise<RouterResponse>).catch(
25
+ (e) => e
26
+ )) as ServiceError;
27
+
36
28
  expect(error.errorData.status).toEqual(500);
37
29
  expect(error.errorData.code).toEqual('PSYNC_S2302');
38
30
  });