@powersync/service-core 1.15.8 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/events/EventsEngine.d.ts +14 -0
- package/dist/events/EventsEngine.js +33 -0
- package/dist/events/EventsEngine.js.map +1 -0
- package/dist/routes/configure-fastify.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +15 -2
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.js +19 -2
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/router.d.ts +3 -3
- package/dist/storage/BucketStorageFactory.d.ts +2 -0
- package/dist/storage/ReportStorage.d.ts +36 -0
- package/dist/storage/ReportStorage.js +2 -0
- package/dist/storage/ReportStorage.js.map +1 -0
- package/dist/storage/StorageEngine.d.ts +2 -2
- package/dist/storage/StorageEngine.js.map +1 -1
- package/dist/storage/StorageProvider.d.ts +3 -1
- package/dist/storage/storage-index.d.ts +1 -0
- package/dist/storage/storage-index.js +1 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/system/ServiceContext.d.ts +3 -0
- package/dist/system/ServiceContext.js +10 -1
- package/dist/system/ServiceContext.js.map +1 -1
- package/package.json +6 -6
- package/src/events/EventsEngine.ts +38 -0
- package/src/routes/configure-fastify.ts +0 -1
- package/src/routes/endpoints/socket-route.ts +16 -3
- package/src/routes/endpoints/sync-stream.ts +19 -2
- package/src/routes/router.ts +3 -3
- package/src/storage/BucketStorageFactory.ts +2 -0
- package/src/storage/ReportStorage.ts +39 -0
- package/src/storage/StorageEngine.ts +3 -3
- package/src/storage/StorageProvider.ts +3 -1
- package/src/storage/storage-index.ts +1 -0
- package/src/system/ServiceContext.ts +13 -1
- package/test/src/routes/mocks.ts +2 -0
- package/test/src/routes/stream.test.ts +14 -6
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @powersync/service-core
|
|
2
2
|
|
|
3
|
+
## 1.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 80fd68b: Add SDK usage reporting support.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 88982d9: Migrate to trusted publishing
|
|
12
|
+
- Updated dependencies [b4fa979]
|
|
13
|
+
- Updated dependencies [80fd68b]
|
|
14
|
+
- Updated dependencies [c2bd0b0]
|
|
15
|
+
- Updated dependencies [0268858]
|
|
16
|
+
- Updated dependencies [88982d9]
|
|
17
|
+
- @powersync/service-sync-rules@0.29.6
|
|
18
|
+
- @powersync/lib-services-framework@0.7.9
|
|
19
|
+
- @powersync/service-types@0.13.1
|
|
20
|
+
- @powersync/service-jsonbig@0.17.12
|
|
21
|
+
- @powersync/service-rsocket-router@0.2.6
|
|
22
|
+
|
|
3
23
|
## 1.15.8
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { event_types } from '@powersync/service-types';
|
|
2
|
+
export declare class EventsEngine {
|
|
3
|
+
private emitter;
|
|
4
|
+
private events;
|
|
5
|
+
constructor();
|
|
6
|
+
/**
|
|
7
|
+
* All new events added need to be subscribed to be used.
|
|
8
|
+
* @example engine.subscribe(new MyNewEvent(storageEngine));
|
|
9
|
+
*/
|
|
10
|
+
subscribe<K extends event_types.EventsEngineEventType>(event: event_types.EmitterEvent<K>): void;
|
|
11
|
+
get listEvents(): event_types.EventsEngineEventType[];
|
|
12
|
+
emit<K extends keyof event_types.SubscribeEvents>(event: K, data: event_types.SubscribeEvents[K]): void;
|
|
13
|
+
shutDown(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
2
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
3
|
+
export class EventsEngine {
|
|
4
|
+
emitter;
|
|
5
|
+
events = new Set();
|
|
6
|
+
constructor() {
|
|
7
|
+
this.emitter = new EventEmitter({ captureRejections: true });
|
|
8
|
+
this.emitter.on('error', (error) => {
|
|
9
|
+
logger.error(error.message);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* All new events added need to be subscribed to be used.
|
|
14
|
+
* @example engine.subscribe(new MyNewEvent(storageEngine));
|
|
15
|
+
*/
|
|
16
|
+
subscribe(event) {
|
|
17
|
+
if (!this.events.has(event.event)) {
|
|
18
|
+
this.events.add(event.event);
|
|
19
|
+
}
|
|
20
|
+
this.emitter.on(event.event, event.handler.bind(event));
|
|
21
|
+
}
|
|
22
|
+
get listEvents() {
|
|
23
|
+
return Array.from(this.events.values());
|
|
24
|
+
}
|
|
25
|
+
emit(event, data) {
|
|
26
|
+
this.emitter.emit(event, data);
|
|
27
|
+
}
|
|
28
|
+
shutDown() {
|
|
29
|
+
logger.info(`Shutting down EmitterEngine and removing all listeners for ${this.listEvents.join(', ')}.`);
|
|
30
|
+
this.emitter.removeAllListeners();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=EventsEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventsEngine.js","sourceRoot":"","sources":["../../src/events/EventsEngine.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAG3D,MAAM,OAAO,YAAY;IACf,OAAO,CAAe;IACtB,MAAM,GAA2C,IAAI,GAAG,EAAE,CAAC;IACnE;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YACxC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,SAAS,CAA8C,KAAkC;QACvF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAA8C,KAAQ,EAAE,IAAoC;QAC9F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,IAAI,CAAC,8DAA8D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure-fastify.js","sourceRoot":"","sources":["../../src/routes/configure-fastify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configure-fastify.js","sourceRoot":"","sources":["../../src/routes/configure-fastify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAI5F,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAA4B,MAAM,YAAY,CAAC;AA0B9E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,GAAG,EAAE;QACH,MAAM,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,GAAG,aAAa,CAAC;QACvF,aAAa,EAAE;YACb,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,EAAE;SACpB;KACF;IACD,WAAW,EAAE;QACX,MAAM,EAAE,CAAC,GAAG,kBAAkB,CAAC;QAC/B,aAAa,EAAE;YACb,WAAW,EAAE,GAAG;YAChB,eAAe,EAAE,CAAC;SACnB;KACF;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA+B,EAAE,OAA4B;IAClG,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,qBAAqB,EAAE,GAAG,OAAO,CAAC;IAEpE,MAAM,eAAe,GAAoB,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAClE,OAAO;YACL,OAAO,EAAE,SAAS;YAClB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC,CAAC;IAEF;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW,YAAY;QAC1C,qBAAqB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,IAAI,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7G,8BAA8B,CAAC,YAAY,CAAC,CAAC;QAE7C,uCAAuC;QACvC,YAAY,CAAC,OAAO,CAClB,WAAW,EACX,sBAAsB,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,IAAI,qBAAqB,CAAC,GAAG,CAAC,aAAa,CAAC,CAC7F,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,qDAAqD;IACrD,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW,YAAY;QAC1C,qBAAqB,CACnB,YAAY,EACZ,eAAe,EACf,MAAM,CAAC,WAAW,EAAE,MAAM,IAAI,qBAAqB,CAAC,WAAW,CAAC,MAAM,CACvE,CAAC;QACF,uCAAuC;QACvC,YAAY,CAAC,OAAO,CAClB,WAAW,EACX,sBAAsB,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,IAAI,qBAAqB,CAAC,WAAW,CAAC,aAAa,CAAC,CAC7G,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -2,19 +2,27 @@ import { ErrorCode, errors, schema } from '@powersync/lib-services-framework';
|
|
|
2
2
|
import * as sync from '../../sync/sync-index.js';
|
|
3
3
|
import * as util from '../../util/util-index.js';
|
|
4
4
|
import { SyncRoutes } from './sync-stream.js';
|
|
5
|
-
import { APIMetric } from '@powersync/service-types';
|
|
5
|
+
import { APIMetric, event_types } from '@powersync/service-types';
|
|
6
6
|
export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.STREAM, {
|
|
7
7
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
8
8
|
handler: async ({ context, params, responder, observer, initialN, signal: upstreamSignal, connection }) => {
|
|
9
9
|
const { service_context, logger } = context;
|
|
10
10
|
const { routerEngine, metricsEngine, syncContext } = service_context;
|
|
11
|
+
const streamStart = Date.now();
|
|
11
12
|
logger.defaultMeta = {
|
|
12
13
|
...logger.defaultMeta,
|
|
13
14
|
user_id: context.token_payload?.sub,
|
|
14
15
|
client_id: params.client_id,
|
|
15
16
|
user_agent: context.user_agent
|
|
16
17
|
};
|
|
17
|
-
const
|
|
18
|
+
const sdkData = {
|
|
19
|
+
client_id: params.client_id ?? '',
|
|
20
|
+
user_id: context.user_id,
|
|
21
|
+
user_agent: context.user_agent,
|
|
22
|
+
// At this point the token_payload is guaranteed to be present
|
|
23
|
+
jwt_exp: new Date(context.token_payload.exp * 1000),
|
|
24
|
+
connected_at: new Date(streamStart)
|
|
25
|
+
};
|
|
18
26
|
// Best effort guess on why the stream was closed.
|
|
19
27
|
// We use the `??=` operator everywhere, so that we catch the first relevant
|
|
20
28
|
// event, which is usually the most specific.
|
|
@@ -61,6 +69,7 @@ export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.S
|
|
|
61
69
|
controller.abort();
|
|
62
70
|
});
|
|
63
71
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
|
|
72
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_CONNECT_EVENT, sdkData);
|
|
64
73
|
const tracker = new sync.RequestTracker(metricsEngine);
|
|
65
74
|
if (connection.tracker.encoding) {
|
|
66
75
|
// Must be set before we start the stream
|
|
@@ -152,6 +161,10 @@ export const syncStreamReactive = (router) => router.reactiveStream(SyncRoutes.S
|
|
|
152
161
|
close_reason: closeReason ?? 'unknown'
|
|
153
162
|
});
|
|
154
163
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
|
|
164
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
|
|
165
|
+
...sdkData,
|
|
166
|
+
disconnected_at: new Date()
|
|
167
|
+
});
|
|
155
168
|
}
|
|
156
169
|
}
|
|
157
170
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-route.js","sourceRoot":"","sources":["../../../src/routes/endpoints/socket-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"socket-route.js","sourceRoot":"","sources":["../../../src/routes/endpoints/socket-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import * as sync from '../../sync/sync-index.js';
|
|
|
5
5
|
import * as util from '../../util/util-index.js';
|
|
6
6
|
import { authUser } from '../auth.js';
|
|
7
7
|
import { routeDefinition } from '../router.js';
|
|
8
|
-
import { APIMetric } from '@powersync/service-types';
|
|
8
|
+
import { APIMetric, event_types } from '@powersync/service-types';
|
|
9
9
|
import { maybeCompressResponseStream } from '../compression.js';
|
|
10
10
|
export var SyncRoutes;
|
|
11
11
|
(function (SyncRoutes) {
|
|
@@ -20,7 +20,7 @@ export const syncStreamed = routeDefinition({
|
|
|
20
20
|
authorize: authUser,
|
|
21
21
|
validator: schema.createTsCodecValidator(util.StreamingSyncRequest, { allowAdditional: true }),
|
|
22
22
|
handler: async (payload) => {
|
|
23
|
-
const { service_context, logger } = payload.context;
|
|
23
|
+
const { service_context, logger, token_payload } = payload.context;
|
|
24
24
|
const { routerEngine, storageEngine, metricsEngine, syncContext } = service_context;
|
|
25
25
|
const headers = payload.request.headers;
|
|
26
26
|
const userAgent = headers['x-user-agent'] ?? headers['user-agent'];
|
|
@@ -38,6 +38,14 @@ export const syncStreamed = routeDefinition({
|
|
|
38
38
|
user_id: payload.context.user_id,
|
|
39
39
|
bson: useBson
|
|
40
40
|
};
|
|
41
|
+
const sdkData = {
|
|
42
|
+
client_id: clientId ?? '',
|
|
43
|
+
user_id: payload.context.user_id,
|
|
44
|
+
user_agent: userAgent,
|
|
45
|
+
// At this point the token_payload is guaranteed to be present
|
|
46
|
+
jwt_exp: new Date(token_payload.exp * 1000),
|
|
47
|
+
connected_at: new Date(streamStart)
|
|
48
|
+
};
|
|
41
49
|
if (routerEngine.closed) {
|
|
42
50
|
throw new errors.ServiceError({
|
|
43
51
|
status: 503,
|
|
@@ -58,6 +66,7 @@ export const syncStreamed = routeDefinition({
|
|
|
58
66
|
const tracker = new sync.RequestTracker(metricsEngine);
|
|
59
67
|
try {
|
|
60
68
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
|
|
69
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_CONNECT_EVENT, sdkData);
|
|
61
70
|
const syncLines = sync.streamResponse({
|
|
62
71
|
syncContext: syncContext,
|
|
63
72
|
bucketStorage,
|
|
@@ -116,6 +125,10 @@ export const syncStreamed = routeDefinition({
|
|
|
116
125
|
}
|
|
117
126
|
controller.abort();
|
|
118
127
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
|
|
128
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
|
|
129
|
+
...sdkData,
|
|
130
|
+
disconnected_at: new Date()
|
|
131
|
+
});
|
|
119
132
|
logger.info(`Sync stream complete`, {
|
|
120
133
|
...tracker.getLogMeta(),
|
|
121
134
|
stream_ms: Date.now() - streamStart,
|
|
@@ -127,6 +140,10 @@ export const syncStreamed = routeDefinition({
|
|
|
127
140
|
catch (ex) {
|
|
128
141
|
controller.abort();
|
|
129
142
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
|
|
143
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
|
|
144
|
+
...sdkData,
|
|
145
|
+
disconnected_at: new Date()
|
|
146
|
+
});
|
|
130
147
|
}
|
|
131
148
|
}
|
|
132
149
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AACtF,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,IAAI,MAAM,0BAA0B,CAAC;AACjD,OAAO,KAAK,IAAI,MAAM,0BAA0B,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-stream.js","sourceRoot":"","sources":["../../../src/routes/endpoints/sync-stream.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/router.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Logger, router } 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
|
/**
|
|
@@ -23,10 +23,10 @@ export type BasicRouterRequest = {
|
|
|
23
23
|
protocol: string;
|
|
24
24
|
hostname: string;
|
|
25
25
|
};
|
|
26
|
-
export type
|
|
26
|
+
export type ContextProviderOptions = {
|
|
27
27
|
logger: Logger;
|
|
28
28
|
};
|
|
29
|
-
export type ContextProvider = (request: BasicRouterRequest, options:
|
|
29
|
+
export type ContextProvider = (request: BasicRouterRequest, options: ContextProviderOptions) => Promise<Context>;
|
|
30
30
|
export type RequestEndpoint<I, O, C = Context, Payload = RequestEndpointHandlerPayload<I, C, BasicRouterRequest>> = router.Endpoint<I, O, C, Payload> & {};
|
|
31
31
|
export type RequestEndpointHandlerPayload<I = any, C = Context, Request = BasicRouterRequest> = router.EndpointHandlerPayload<I, C> & {
|
|
32
32
|
request: Request;
|
|
@@ -3,6 +3,7 @@ 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';
|
|
6
7
|
/**
|
|
7
8
|
* Represents a configured storage provider.
|
|
8
9
|
*
|
|
@@ -143,3 +144,4 @@ export interface TestStorageOptions {
|
|
|
143
144
|
doNotClear?: boolean;
|
|
144
145
|
}
|
|
145
146
|
export type TestStorageFactory = (options?: TestStorageOptions) => Promise<BucketStorageFactory>;
|
|
147
|
+
export type TestReportStorageFactory = (options?: TestStorageOptions) => Promise<ReportStorage>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { event_types } from '@powersync/service-types';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a configured report storage.
|
|
4
|
+
*
|
|
5
|
+
* Report storage is used for storing localized data for the instance.
|
|
6
|
+
* Data can then be used for reporting purposes.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export interface ReportStorage extends AsyncDisposable {
|
|
10
|
+
/**
|
|
11
|
+
* Report a client connection.
|
|
12
|
+
*/
|
|
13
|
+
reportClientConnection(data: event_types.ClientConnectionBucketData): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Report a client disconnection.
|
|
16
|
+
*/
|
|
17
|
+
reportClientDisconnection(data: event_types.ClientDisconnectionEventData): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Get currently connected clients.
|
|
20
|
+
* This will return any short or long term connected clients.
|
|
21
|
+
* Clients that have no disconnected_at timestamp and that have a valid jwt_exp timestamp are considered connected.
|
|
22
|
+
*/
|
|
23
|
+
getConnectedClients(): Promise<event_types.ClientConnectionReportResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* Get a report of client connections over a day, week or month.
|
|
26
|
+
* This is internally used to generate reports over it always returns the previous day, week or month.
|
|
27
|
+
* Usually this is call on the start of the new day, week or month. It will return all unique completed connections
|
|
28
|
+
* as well as uniques currently connected clients.
|
|
29
|
+
*/
|
|
30
|
+
getClientConnectionReports(data: event_types.ClientConnectionReportRequest): Promise<event_types.ClientConnectionReportResponse>;
|
|
31
|
+
/**
|
|
32
|
+
* Delete old connection data based on a specific date.
|
|
33
|
+
* This is used to clean up old connection data that is no longer needed.
|
|
34
|
+
*/
|
|
35
|
+
deleteOldConnectionData(data: event_types.DeleteOldConnectionData): Promise<void>;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReportStorage.js","sourceRoot":"","sources":["../../src/storage/ReportStorage.ts"],"names":[],"mappings":""}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseObserver, 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,
|
|
4
|
+
import { ActiveStorage, StorageProvider } from './StorageProvider.js';
|
|
5
5
|
export type StorageEngineOptions = {
|
|
6
6
|
configuration: ResolvedPowerSyncConfig;
|
|
7
7
|
};
|
|
@@ -20,7 +20,7 @@ export declare class StorageEngine extends BaseObserver<StorageEngineListener> {
|
|
|
20
20
|
* Register a provider which generates a {@link BucketStorageFactory}
|
|
21
21
|
* given the matching config specified in the loaded {@link ResolvedPowerSyncConfig}
|
|
22
22
|
*/
|
|
23
|
-
registerProvider(provider:
|
|
23
|
+
registerProvider(provider: StorageProvider): void;
|
|
24
24
|
start(): Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Shutdown the storage engine, safely shutting down any activated storage providers.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageEngine.js","sourceRoot":"","sources":["../../src/storage/StorageEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAgB,MAAM,mCAAmC,CAAC;AAcvF,MAAM,OAAO,aAAc,SAAQ,YAAmC;IAKhD;IAJpB,yFAAyF;IACjF,gBAAgB,
|
|
1
|
+
{"version":3,"file":"StorageEngine.js","sourceRoot":"","sources":["../../src/storage/StorageEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAgB,MAAM,mCAAmC,CAAC;AAcvF,MAAM,OAAO,aAAc,SAAQ,YAAmC;IAKhD;IAJpB,yFAAyF;IACjF,gBAAgB,GAAiC,IAAI,GAAG,EAAE,CAAC;IAC3D,oBAAoB,GAAyB,IAAI,CAAC;IAE1D,YAAoB,OAA6B;QAC/C,KAAK,EAAE,CAAC;QADU,YAAO,GAAP,OAAO,CAAsB;IAEjD,CAAC;IAED,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;IACpC,CAAC;IAED,IAAI,aAAa;QACf,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,QAAyB;QACxC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC1C,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,oBAAoB,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAE,CAAC,UAAU,CAAC;YAClG,cAAc,EAAE,aAAa;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;YACjD,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,mCAAmC,aAAa,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QAC9E,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,oBAAoB,EAAE,QAAQ,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -1,8 +1,10 @@
|
|
|
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';
|
|
4
5
|
export interface ActiveStorage {
|
|
5
6
|
storage: BucketStorageFactory;
|
|
7
|
+
reportStorage: ReportStorage;
|
|
6
8
|
shutDown(): Promise<void>;
|
|
7
9
|
/**
|
|
8
10
|
* Tear down / drop the storage permanently
|
|
@@ -16,7 +18,7 @@ export interface GetStorageOptions {
|
|
|
16
18
|
/**
|
|
17
19
|
* Represents a provider that can create a storage instance for a specific storage type from configuration.
|
|
18
20
|
*/
|
|
19
|
-
export interface
|
|
21
|
+
export interface StorageProvider {
|
|
20
22
|
/**
|
|
21
23
|
* The storage type that this provider provides.
|
|
22
24
|
* The type should match the `type` field in the config.
|
|
@@ -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,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;AACrC,cAAc,oBAAoB,CAAC"}
|
|
@@ -6,6 +6,7 @@ import * as routes from '../routes/routes-index.js';
|
|
|
6
6
|
import * as storage from '../storage/storage-index.js';
|
|
7
7
|
import { SyncContext } from '../sync/SyncContext.js';
|
|
8
8
|
import * as utils from '../util/util-index.js';
|
|
9
|
+
import { EventsEngine } from '../events/EventsEngine.js';
|
|
9
10
|
export interface ServiceContext {
|
|
10
11
|
configuration: utils.ResolvedPowerSyncConfig;
|
|
11
12
|
lifeCycleEngine: LifeCycledSystem;
|
|
@@ -16,6 +17,7 @@ export interface ServiceContext {
|
|
|
16
17
|
migrations: PowerSyncMigrationManager;
|
|
17
18
|
syncContext: SyncContext;
|
|
18
19
|
serviceMode: ServiceContextMode;
|
|
20
|
+
eventsEngine: EventsEngine;
|
|
19
21
|
}
|
|
20
22
|
export declare enum ServiceContextMode {
|
|
21
23
|
API = "api",
|
|
@@ -39,6 +41,7 @@ export declare class ServiceContextContainer implements ServiceContext {
|
|
|
39
41
|
configuration: utils.ResolvedPowerSyncConfig;
|
|
40
42
|
lifeCycleEngine: LifeCycledSystem;
|
|
41
43
|
storageEngine: storage.StorageEngine;
|
|
44
|
+
eventsEngine: EventsEngine;
|
|
42
45
|
syncContext: SyncContext;
|
|
43
46
|
routerEngine: routes.RouterEngine;
|
|
44
47
|
serviceMode: ServiceContextMode;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifeCycledSystem, MigrationManager
|
|
1
|
+
import { container, LifeCycledSystem, MigrationManager } from '@powersync/lib-services-framework';
|
|
2
2
|
import { framework } from '../index.js';
|
|
3
3
|
import * as metrics from '../metrics/MetricsEngine.js';
|
|
4
4
|
import * as replication from '../replication/replication-index.js';
|
|
@@ -6,6 +6,7 @@ import * as routes from '../routes/routes-index.js';
|
|
|
6
6
|
import * as storage from '../storage/storage-index.js';
|
|
7
7
|
import { SyncContext } from '../sync/SyncContext.js';
|
|
8
8
|
import * as utils from '../util/util-index.js';
|
|
9
|
+
import { EventsEngine } from '../events/EventsEngine.js';
|
|
9
10
|
export var ServiceContextMode;
|
|
10
11
|
(function (ServiceContextMode) {
|
|
11
12
|
ServiceContextMode["API"] = "api";
|
|
@@ -25,6 +26,7 @@ export class ServiceContextContainer {
|
|
|
25
26
|
configuration;
|
|
26
27
|
lifeCycleEngine;
|
|
27
28
|
storageEngine;
|
|
29
|
+
eventsEngine;
|
|
28
30
|
syncContext;
|
|
29
31
|
routerEngine;
|
|
30
32
|
serviceMode;
|
|
@@ -42,6 +44,10 @@ export class ServiceContextContainer {
|
|
|
42
44
|
this.lifeCycleEngine.stopWithError(error);
|
|
43
45
|
}
|
|
44
46
|
});
|
|
47
|
+
this.eventsEngine = new EventsEngine();
|
|
48
|
+
this.lifeCycleEngine.withLifecycle(this.eventsEngine, {
|
|
49
|
+
stop: (emitterEngine) => emitterEngine.shutDown()
|
|
50
|
+
});
|
|
45
51
|
this.lifeCycleEngine.withLifecycle(this.storageEngine, {
|
|
46
52
|
start: (storageEngine) => storageEngine.start(),
|
|
47
53
|
stop: (storageEngine) => storageEngine.shutDown()
|
|
@@ -61,6 +67,9 @@ export class ServiceContextContainer {
|
|
|
61
67
|
// Migrations should be executed before the system starts
|
|
62
68
|
start: () => migrationManager[Symbol.asyncDispose]()
|
|
63
69
|
});
|
|
70
|
+
this.lifeCycleEngine.withLifecycle(this.eventsEngine, {
|
|
71
|
+
stop: (emitterEngine) => emitterEngine.shutDown()
|
|
72
|
+
});
|
|
64
73
|
}
|
|
65
74
|
get replicationEngine() {
|
|
66
75
|
return container.getOptional(replication.ReplicationEngine);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceContext.js","sourceRoot":"","sources":["../../src/system/ServiceContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAqB,
|
|
1
|
+
{"version":3,"file":"ServiceContext.js","sourceRoot":"","sources":["../../src/system/ServiceContext.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.16.0",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-ALv2",
|
|
11
11
|
"type": "module",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"uuid": "^11.1.0",
|
|
34
34
|
"winston": "^3.13.0",
|
|
35
35
|
"yaml": "^2.3.2",
|
|
36
|
-
"@powersync/lib-services-framework": "0.7.
|
|
37
|
-
"@powersync/service-jsonbig": "0.17.
|
|
38
|
-
"@powersync/service-rsocket-router": "0.2.
|
|
39
|
-
"@powersync/service-
|
|
40
|
-
"@powersync/service-
|
|
36
|
+
"@powersync/lib-services-framework": "0.7.9",
|
|
37
|
+
"@powersync/service-jsonbig": "0.17.12",
|
|
38
|
+
"@powersync/service-rsocket-router": "0.2.6",
|
|
39
|
+
"@powersync/service-sync-rules": "0.29.6",
|
|
40
|
+
"@powersync/service-types": "0.13.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/async": "^3.2.24",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
2
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
3
|
+
import { event_types } from '@powersync/service-types';
|
|
4
|
+
|
|
5
|
+
export class EventsEngine {
|
|
6
|
+
private emitter: EventEmitter;
|
|
7
|
+
private events: Set<event_types.EventsEngineEventType> = new Set();
|
|
8
|
+
constructor() {
|
|
9
|
+
this.emitter = new EventEmitter({ captureRejections: true });
|
|
10
|
+
this.emitter.on('error', (error: Error) => {
|
|
11
|
+
logger.error(error.message);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* All new events added need to be subscribed to be used.
|
|
17
|
+
* @example engine.subscribe(new MyNewEvent(storageEngine));
|
|
18
|
+
*/
|
|
19
|
+
subscribe<K extends event_types.EventsEngineEventType>(event: event_types.EmitterEvent<K>): void {
|
|
20
|
+
if (!this.events.has(event.event)) {
|
|
21
|
+
this.events.add(event.event);
|
|
22
|
+
}
|
|
23
|
+
this.emitter.on(event.event, event.handler.bind(event));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get listEvents(): event_types.EventsEngineEventType[] {
|
|
27
|
+
return Array.from(this.events.values());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
emit<K extends keyof event_types.SubscribeEvents>(event: K, data: event_types.SubscribeEvents[K]): void {
|
|
31
|
+
this.emitter.emit(event, data);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
shutDown(): void {
|
|
35
|
+
logger.info(`Shutting down EmitterEngine and removing all listeners for ${this.listEvents.join(', ')}.`);
|
|
36
|
+
this.emitter.removeAllListeners();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { ErrorCode, errors, schema } from '@powersync/lib-services-framework';
|
|
2
|
-
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
3
2
|
|
|
4
3
|
import * as sync from '../../sync/sync-index.js';
|
|
5
4
|
import * as util from '../../util/util-index.js';
|
|
6
5
|
import { SocketRouteGenerator } from '../router-socket.js';
|
|
7
6
|
import { SyncRoutes } from './sync-stream.js';
|
|
8
7
|
|
|
9
|
-
import { APIMetric } from '@powersync/service-types';
|
|
8
|
+
import { APIMetric, event_types } from '@powersync/service-types';
|
|
10
9
|
|
|
11
10
|
export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
12
11
|
router.reactiveStream<util.StreamingSyncRequest, any>(SyncRoutes.STREAM, {
|
|
@@ -14,6 +13,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
14
13
|
handler: async ({ context, params, responder, observer, initialN, signal: upstreamSignal, connection }) => {
|
|
15
14
|
const { service_context, logger } = context;
|
|
16
15
|
const { routerEngine, metricsEngine, syncContext } = service_context;
|
|
16
|
+
const streamStart = Date.now();
|
|
17
17
|
|
|
18
18
|
logger.defaultMeta = {
|
|
19
19
|
...logger.defaultMeta,
|
|
@@ -21,7 +21,15 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
21
21
|
client_id: params.client_id,
|
|
22
22
|
user_agent: context.user_agent
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
const sdkData: event_types.ConnectedUserData & event_types.ClientConnectionEventData = {
|
|
26
|
+
client_id: params.client_id ?? '',
|
|
27
|
+
user_id: context.user_id!,
|
|
28
|
+
user_agent: context.user_agent,
|
|
29
|
+
// At this point the token_payload is guaranteed to be present
|
|
30
|
+
jwt_exp: new Date(context.token_payload!.exp * 1000),
|
|
31
|
+
connected_at: new Date(streamStart)
|
|
32
|
+
};
|
|
25
33
|
|
|
26
34
|
// Best effort guess on why the stream was closed.
|
|
27
35
|
// We use the `??=` operator everywhere, so that we catch the first relevant
|
|
@@ -83,6 +91,7 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
83
91
|
});
|
|
84
92
|
|
|
85
93
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(1);
|
|
94
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_CONNECT_EVENT, sdkData);
|
|
86
95
|
const tracker = new sync.RequestTracker(metricsEngine);
|
|
87
96
|
if (connection.tracker.encoding) {
|
|
88
97
|
// Must be set before we start the stream
|
|
@@ -174,6 +183,10 @@ export const syncStreamReactive: SocketRouteGenerator = (router) =>
|
|
|
174
183
|
close_reason: closeReason ?? 'unknown'
|
|
175
184
|
});
|
|
176
185
|
metricsEngine.getUpDownCounter(APIMetric.CONCURRENT_CONNECTIONS).add(-1);
|
|
186
|
+
service_context.eventsEngine.emit(event_types.EventsEngineEventType.SDK_DISCONNECT_EVENT, {
|
|
187
|
+
...sdkData,
|
|
188
|
+
disconnected_at: new Date()
|
|
189
|
+
});
|
|
177
190
|
}
|
|
178
191
|
}
|
|
179
192
|
});
|