@protontech/drive-sdk 0.0.13 → 0.1.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/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +3 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/memoryCache.d.ts +1 -1
- package/dist/cache/nullCache.d.ts +14 -0
- package/dist/cache/nullCache.js +37 -0
- package/dist/cache/nullCache.js.map +1 -0
- package/dist/config.d.ts +16 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/crypto/openPGPCrypto.js +2 -0
- package/dist/crypto/openPGPCrypto.js.map +1 -1
- package/dist/diagnostic/eventsGenerator.d.ts +14 -0
- package/dist/diagnostic/eventsGenerator.js +49 -0
- package/dist/diagnostic/eventsGenerator.js.map +1 -0
- package/dist/diagnostic/httpClient.d.ts +16 -0
- package/dist/diagnostic/httpClient.js +81 -0
- package/dist/diagnostic/httpClient.js.map +1 -0
- package/dist/diagnostic/index.d.ts +10 -0
- package/dist/diagnostic/index.js +35 -0
- package/dist/diagnostic/index.js.map +1 -0
- package/dist/diagnostic/integrityVerificationStream.d.ts +21 -0
- package/dist/diagnostic/integrityVerificationStream.js +56 -0
- package/dist/diagnostic/integrityVerificationStream.js.map +1 -0
- package/dist/diagnostic/interface.d.ts +102 -0
- package/dist/diagnostic/interface.js +3 -0
- package/dist/diagnostic/interface.js.map +1 -0
- package/dist/diagnostic/sdkDiagnostic.d.ts +22 -0
- package/dist/diagnostic/sdkDiagnostic.js +216 -0
- package/dist/diagnostic/sdkDiagnostic.js.map +1 -0
- package/dist/diagnostic/sdkDiagnosticFull.d.ts +18 -0
- package/dist/diagnostic/sdkDiagnosticFull.js +35 -0
- package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -0
- package/dist/diagnostic/telemetry.d.ts +25 -0
- package/dist/diagnostic/telemetry.js +70 -0
- package/dist/diagnostic/telemetry.js.map +1 -0
- package/dist/diagnostic/zipGenerators.d.ts +9 -0
- package/dist/diagnostic/zipGenerators.js +64 -0
- package/dist/diagnostic/zipGenerators.js.map +1 -0
- package/dist/diagnostic/zipGenerators.test.js +144 -0
- package/dist/diagnostic/zipGenerators.test.js.map +1 -0
- package/dist/errors.d.ts +2 -1
- package/dist/errors.js +3 -1
- package/dist/errors.js.map +1 -1
- package/dist/interface/config.d.ts +26 -0
- package/dist/interface/config.js +3 -0
- package/dist/interface/config.js.map +1 -0
- package/dist/interface/download.d.ts +2 -2
- package/dist/interface/events.d.ts +60 -20
- package/dist/interface/events.js +11 -1
- package/dist/interface/events.js.map +1 -1
- package/dist/interface/httpClient.d.ts +0 -14
- package/dist/interface/index.d.ts +8 -4
- package/dist/interface/index.js +2 -1
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/nodes.d.ts +9 -0
- package/dist/interface/nodes.js.map +1 -1
- package/dist/interface/sharing.d.ts +1 -0
- package/dist/interface/upload.d.ts +6 -0
- package/dist/internal/download/apiService.js +32 -31
- package/dist/internal/download/apiService.js.map +1 -1
- package/dist/internal/download/fileDownloader.d.ts +2 -2
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/events/apiService.d.ts +4 -6
- package/dist/internal/events/apiService.js +15 -22
- package/dist/internal/events/apiService.js.map +1 -1
- package/dist/internal/events/coreEventManager.d.ts +7 -10
- package/dist/internal/events/coreEventManager.js +19 -36
- package/dist/internal/events/coreEventManager.js.map +1 -1
- package/dist/internal/events/coreEventManager.test.js +87 -0
- package/dist/internal/events/coreEventManager.test.js.map +1 -0
- package/dist/internal/events/eventManager.d.ts +11 -36
- package/dist/internal/events/eventManager.js +59 -105
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +167 -82
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +13 -33
- package/dist/internal/events/index.js +56 -72
- package/dist/internal/events/index.js.map +1 -1
- package/dist/internal/events/interface.d.ts +59 -14
- package/dist/internal/events/interface.js +13 -3
- package/dist/internal/events/interface.js.map +1 -1
- package/dist/internal/events/volumeEventManager.d.ts +7 -17
- package/dist/internal/events/volumeEventManager.js +58 -45
- package/dist/internal/events/volumeEventManager.js.map +1 -1
- package/dist/internal/events/volumeEventManager.test.d.ts +1 -0
- package/dist/internal/events/volumeEventManager.test.js +203 -0
- package/dist/internal/events/volumeEventManager.test.js.map +1 -0
- package/dist/internal/nodes/cache.d.ts +10 -1
- package/dist/internal/nodes/cache.js +17 -0
- package/dist/internal/nodes/cache.js.map +1 -1
- package/dist/internal/nodes/cryptoService.d.ts +1 -1
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/events.d.ts +7 -83
- package/dist/internal/nodes/events.js +43 -217
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/nodes/events.test.js +27 -277
- package/dist/internal/nodes/events.test.js.map +1 -1
- package/dist/internal/nodes/index.d.ts +3 -4
- package/dist/internal/nodes/index.js +5 -5
- package/dist/internal/nodes/index.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.d.ts +15 -0
- package/dist/internal/nodes/nodesAccess.js +37 -0
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.test.js +131 -93
- package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +1 -3
- package/dist/internal/nodes/nodesManagement.js +12 -26
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +35 -14
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/shares/cache.d.ts +2 -0
- package/dist/internal/shares/cache.js +2 -0
- package/dist/internal/shares/cache.js.map +1 -1
- package/dist/internal/shares/manager.d.ts +1 -0
- package/dist/internal/shares/manager.js +3 -0
- package/dist/internal/shares/manager.js.map +1 -1
- package/dist/internal/sharing/apiService.js +1 -0
- package/dist/internal/sharing/apiService.js.map +1 -1
- package/dist/internal/sharing/cryptoService.js +1 -0
- package/dist/internal/sharing/cryptoService.js.map +1 -1
- package/dist/internal/sharing/events.d.ts +23 -55
- package/dist/internal/sharing/events.js +46 -138
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +77 -180
- package/dist/internal/sharing/events.test.js.map +1 -1
- package/dist/internal/sharing/index.d.ts +4 -5
- package/dist/internal/sharing/index.js +5 -5
- package/dist/internal/sharing/index.js.map +1 -1
- package/dist/internal/sharing/interface.d.ts +3 -0
- package/dist/internal/sharing/sharingManagement.d.ts +2 -3
- package/dist/internal/sharing/sharingManagement.js +7 -9
- package/dist/internal/sharing/sharingManagement.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.test.js +9 -39
- package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
- package/dist/internal/upload/apiService.d.ts +2 -3
- package/dist/internal/upload/apiService.js +7 -4
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/index.d.ts +2 -2
- package/dist/internal/upload/index.js +3 -3
- package/dist/internal/upload/index.js.map +1 -1
- package/dist/internal/upload/interface.d.ts +2 -0
- package/dist/internal/upload/manager.d.ts +5 -5
- package/dist/internal/upload/manager.js +19 -50
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +68 -44
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.js +1 -2
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +1 -1
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/protonDriveClient.d.ts +19 -162
- package/dist/protonDriveClient.js +26 -190
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePhotosClient.js +3 -2
- package/dist/protonDrivePhotosClient.js.map +1 -1
- package/package.json +3 -3
- package/src/cache/index.ts +1 -0
- package/src/cache/memoryCache.ts +1 -1
- package/src/cache/nullCache.ts +38 -0
- package/src/config.ts +17 -2
- package/src/crypto/openPGPCrypto.ts +2 -0
- package/src/diagnostic/eventsGenerator.ts +48 -0
- package/src/diagnostic/httpClient.ts +80 -0
- package/src/diagnostic/index.ts +38 -0
- package/src/diagnostic/integrityVerificationStream.ts +56 -0
- package/src/diagnostic/interface.ts +158 -0
- package/src/diagnostic/sdkDiagnostic.ts +238 -0
- package/src/diagnostic/sdkDiagnosticFull.ts +40 -0
- package/src/diagnostic/telemetry.ts +71 -0
- package/src/diagnostic/zipGenerators.test.ts +177 -0
- package/src/diagnostic/zipGenerators.ts +70 -0
- package/src/errors.ts +4 -1
- package/src/interface/config.ts +28 -0
- package/src/interface/download.ts +2 -2
- package/src/interface/events.ts +66 -21
- package/src/interface/httpClient.ts +0 -16
- package/src/interface/index.ts +8 -4
- package/src/interface/nodes.ts +21 -12
- package/src/interface/sharing.ts +1 -0
- package/src/interface/upload.ts +6 -0
- package/src/internal/download/apiService.ts +11 -8
- package/src/internal/download/fileDownloader.ts +2 -2
- package/src/internal/events/apiService.ts +25 -28
- package/src/internal/events/coreEventManager.test.ts +101 -0
- package/src/internal/events/coreEventManager.ts +20 -45
- package/src/internal/events/eventManager.test.ts +201 -88
- package/src/internal/events/eventManager.ts +69 -115
- package/src/internal/events/index.ts +54 -84
- package/src/internal/events/interface.ts +70 -15
- package/src/internal/events/volumeEventManager.test.ts +243 -0
- package/src/internal/events/volumeEventManager.ts +55 -53
- package/src/internal/nodes/cache.ts +20 -2
- package/src/internal/nodes/cryptoService.ts +1 -1
- package/src/internal/nodes/events.test.ts +29 -335
- package/src/internal/nodes/events.ts +45 -253
- package/src/internal/nodes/index.ts +6 -8
- package/src/internal/nodes/interface.ts +2 -2
- package/src/internal/nodes/nodesAccess.test.ts +132 -91
- package/src/internal/nodes/nodesAccess.ts +40 -1
- package/src/internal/nodes/nodesManagement.test.ts +39 -15
- package/src/internal/nodes/nodesManagement.ts +12 -30
- package/src/internal/shares/cache.ts +4 -2
- package/src/internal/shares/manager.ts +9 -5
- package/src/internal/sharing/apiService.ts +1 -0
- package/src/internal/sharing/cache.ts +1 -1
- package/src/internal/sharing/cryptoService.ts +1 -0
- package/src/internal/sharing/events.test.ts +89 -195
- package/src/internal/sharing/events.ts +42 -156
- package/src/internal/sharing/index.ts +6 -9
- package/src/internal/sharing/interface.ts +6 -2
- package/src/internal/sharing/sharingManagement.test.ts +10 -40
- package/src/internal/sharing/sharingManagement.ts +7 -11
- package/src/internal/upload/apiService.ts +5 -6
- package/src/internal/upload/index.ts +5 -5
- package/src/internal/upload/interface.ts +2 -0
- package/src/internal/upload/manager.test.ts +75 -45
- package/src/internal/upload/manager.ts +24 -54
- package/src/internal/upload/streamUploader.test.ts +0 -1
- package/src/internal/upload/streamUploader.ts +0 -2
- package/src/protonDriveClient.ts +75 -244
- package/src/protonDrivePhotosClient.ts +4 -3
- package/dist/internal/events/cache.d.ts +0 -28
- package/dist/internal/events/cache.js +0 -67
- package/dist/internal/events/cache.js.map +0 -1
- package/dist/internal/events/cache.test.js +0 -43
- package/dist/internal/events/cache.test.js.map +0 -1
- package/dist/internal/nodes/index.test.js +0 -114
- package/dist/internal/nodes/index.test.js.map +0 -1
- package/src/internal/events/cache.test.ts +0 -47
- package/src/internal/events/cache.ts +0 -80
- package/src/internal/nodes/index.test.ts +0 -137
- /package/dist/{internal/events/cache.test.d.ts → diagnostic/zipGenerators.test.d.ts} +0 -0
- /package/dist/internal/{nodes/index.test.d.ts → events/coreEventManager.test.d.ts} +0 -0
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CoreEventManager = void 0;
|
|
4
4
|
const telemetry_1 = require("../../telemetry");
|
|
5
5
|
const interface_1 = require("./interface");
|
|
6
|
-
const eventManager_1 = require("./eventManager");
|
|
7
6
|
/**
|
|
8
7
|
* Combines API and event manager to provide a service for listening to
|
|
9
8
|
* core events. Core events are events that are not specific to any volume.
|
|
@@ -16,47 +15,31 @@ const eventManager_1 = require("./eventManager");
|
|
|
16
15
|
* with own implementation.
|
|
17
16
|
*/
|
|
18
17
|
class CoreEventManager {
|
|
18
|
+
logger;
|
|
19
19
|
apiService;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
constructor(logger, apiService, cache) {
|
|
20
|
+
constructor(logger, apiService) {
|
|
21
|
+
this.logger = logger;
|
|
23
22
|
this.apiService = apiService;
|
|
24
|
-
this.cache = cache;
|
|
25
23
|
this.apiService = apiService;
|
|
26
|
-
this.
|
|
27
|
-
lastEventId,
|
|
28
|
-
pollingIntervalInSeconds: this.manager.pollingIntervalInSeconds,
|
|
29
|
-
isOwnVolume: false,
|
|
30
|
-
}));
|
|
24
|
+
this.logger = new telemetry_1.LoggerWithPrefix(logger, `core`);
|
|
31
25
|
}
|
|
32
|
-
async
|
|
33
|
-
|
|
34
|
-
if (lastEventId) {
|
|
35
|
-
return lastEventId;
|
|
36
|
-
}
|
|
37
|
-
return this.apiService.getCoreLatestEventId();
|
|
38
|
-
}
|
|
39
|
-
async startSubscription() {
|
|
40
|
-
await this.manager.start();
|
|
26
|
+
async getLatestEventId() {
|
|
27
|
+
return await this.apiService.getCoreLatestEventId();
|
|
41
28
|
}
|
|
42
|
-
async
|
|
43
|
-
await this.
|
|
29
|
+
async *getEvents(eventId) {
|
|
30
|
+
const events = await this.apiService.getCoreEvents(eventId);
|
|
31
|
+
if (events.events.length === 0 && events.latestEventId !== eventId) {
|
|
32
|
+
yield {
|
|
33
|
+
type: interface_1.DriveEventType.SharedWithMeUpdated,
|
|
34
|
+
treeEventScopeId: 'core',
|
|
35
|
+
eventId: events.latestEventId,
|
|
36
|
+
};
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
yield* events.events;
|
|
44
40
|
}
|
|
45
|
-
|
|
46
|
-
this.
|
|
47
|
-
if (events) {
|
|
48
|
-
await callback(events);
|
|
49
|
-
}
|
|
50
|
-
if (fullRefresh) {
|
|
51
|
-
// Because only updates about shares that are shared with me
|
|
52
|
-
// are listened to from core events, in the case of core full
|
|
53
|
-
// refresh, we don't have to refresh anything more than this
|
|
54
|
-
// one specific event.
|
|
55
|
-
await callback([{
|
|
56
|
-
type: interface_1.DriveEventType.ShareWithMeUpdated,
|
|
57
|
-
}]);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
41
|
+
getLogger() {
|
|
42
|
+
return this.logger;
|
|
60
43
|
}
|
|
61
44
|
}
|
|
62
45
|
exports.CoreEventManager = CoreEventManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coreEventManager.js","sourceRoot":"","sources":["../../../src/internal/events/coreEventManager.ts"],"names":[],"mappings":";;;AACA,+CAAmD;
|
|
1
|
+
{"version":3,"file":"coreEventManager.js","sourceRoot":"","sources":["../../../src/internal/events/coreEventManager.ts"],"names":[],"mappings":";;;AACA,+CAAmD;AAEnD,2CAAgF;AAEhF;;;;;;;;;;GAUG;AACH,MAAa,gBAAgB;IACL;IAAwB;IAA5C,YAAoB,MAAc,EAAU,UAA4B;QAApD,WAAM,GAAN,MAAM,CAAQ;QAAU,eAAU,GAAV,UAAU,CAAkB;QACpE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,IAAI,CAAC,MAAM,GAAG,IAAI,4BAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,CAAE,SAAS,CAAC,OAAe;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;YACjE,MAAM;gBACF,IAAI,EAAE,0BAAc,CAAC,mBAAmB;gBACxC,gBAAgB,EAAE,MAAM;gBACxB,OAAO,EAAE,MAAM,CAAC,aAAa;aAChC,CAAC;YACF,OAAO;QACX,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;CACJ;AA3BD,4CA2BC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const logger_1 = require("../../tests/logger");
|
|
4
|
+
const interface_1 = require("./interface");
|
|
5
|
+
const coreEventManager_1 = require("./coreEventManager");
|
|
6
|
+
describe("CoreEventManager", () => {
|
|
7
|
+
let mockApiService;
|
|
8
|
+
let coreEventManager;
|
|
9
|
+
const mockLogger = (0, logger_1.getMockLogger)();
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
// Reset mocks
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
mockApiService = {
|
|
14
|
+
getCoreLatestEventId: jest.fn(),
|
|
15
|
+
getCoreEvents: jest.fn(),
|
|
16
|
+
getVolumeLatestEventId: jest.fn(),
|
|
17
|
+
getVolumeEvents: jest.fn(),
|
|
18
|
+
};
|
|
19
|
+
coreEventManager = new coreEventManager_1.CoreEventManager(mockLogger, mockApiService);
|
|
20
|
+
});
|
|
21
|
+
describe("getLatestEventId", () => {
|
|
22
|
+
it("should return the latest event ID from API service", async () => {
|
|
23
|
+
const expectedEventId = "event-123";
|
|
24
|
+
mockApiService.getCoreLatestEventId.mockResolvedValue(expectedEventId);
|
|
25
|
+
const result = await coreEventManager.getLatestEventId();
|
|
26
|
+
expect(result).toBe(expectedEventId);
|
|
27
|
+
expect(mockApiService.getCoreLatestEventId).toHaveBeenCalledTimes(1);
|
|
28
|
+
});
|
|
29
|
+
it("should handle API service errors", async () => {
|
|
30
|
+
const error = new Error("API error");
|
|
31
|
+
mockApiService.getCoreLatestEventId.mockRejectedValue(error);
|
|
32
|
+
await expect(coreEventManager.getLatestEventId()).rejects.toThrow("API error");
|
|
33
|
+
expect(mockApiService.getCoreLatestEventId).toHaveBeenCalledTimes(1);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe("getEvents", () => {
|
|
37
|
+
const eventId = "event1";
|
|
38
|
+
const latestEventId = "event2";
|
|
39
|
+
it("should yield ShareWithMeUpdated event when refresh is true", async () => {
|
|
40
|
+
const mockEvents = {
|
|
41
|
+
latestEventId,
|
|
42
|
+
more: false,
|
|
43
|
+
refresh: true,
|
|
44
|
+
events: [],
|
|
45
|
+
};
|
|
46
|
+
mockApiService.getCoreEvents.mockResolvedValue(mockEvents);
|
|
47
|
+
const events = [];
|
|
48
|
+
for await (const event of coreEventManager.getEvents(eventId)) {
|
|
49
|
+
events.push(event);
|
|
50
|
+
}
|
|
51
|
+
expect(events).toHaveLength(1);
|
|
52
|
+
expect(events[0]).toEqual({
|
|
53
|
+
type: interface_1.DriveEventType.SharedWithMeUpdated,
|
|
54
|
+
treeEventScopeId: 'core',
|
|
55
|
+
eventId: latestEventId,
|
|
56
|
+
});
|
|
57
|
+
expect(mockApiService.getCoreEvents).toHaveBeenCalledWith(eventId);
|
|
58
|
+
});
|
|
59
|
+
it("should yield all events when there are actual events", async () => {
|
|
60
|
+
const mockEvent1 = {
|
|
61
|
+
type: interface_1.DriveEventType.SharedWithMeUpdated,
|
|
62
|
+
eventId: "event-1",
|
|
63
|
+
treeEventScopeId: 'core',
|
|
64
|
+
};
|
|
65
|
+
const mockEvent2 = {
|
|
66
|
+
type: interface_1.DriveEventType.SharedWithMeUpdated,
|
|
67
|
+
eventId: "event-2",
|
|
68
|
+
treeEventScopeId: 'core',
|
|
69
|
+
};
|
|
70
|
+
const mockEvents = {
|
|
71
|
+
latestEventId,
|
|
72
|
+
more: false,
|
|
73
|
+
refresh: false,
|
|
74
|
+
events: [mockEvent1, mockEvent2],
|
|
75
|
+
};
|
|
76
|
+
mockApiService.getCoreEvents.mockResolvedValue(mockEvents);
|
|
77
|
+
const events = [];
|
|
78
|
+
for await (const event of coreEventManager.getEvents(eventId)) {
|
|
79
|
+
events.push(event);
|
|
80
|
+
}
|
|
81
|
+
expect(events).toHaveLength(2);
|
|
82
|
+
expect(events[0]).toEqual(mockEvent1);
|
|
83
|
+
expect(events[1]).toEqual(mockEvent2);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=coreEventManager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coreEventManager.test.js","sourceRoot":"","sources":["../../../src/internal/events/coreEventManager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* `fullRefresh` is true when the event manager has requested a full
|
|
5
|
-
* refresh of the data. That can happen if there is too many events
|
|
6
|
-
* to be processed or the last event ID is too old.
|
|
7
|
-
*/
|
|
8
|
-
type Listener<T> = (events: T[], fullRefresh: boolean) => Promise<void>;
|
|
1
|
+
import { EventManagerInterface, Event, EventSubscription } from "./interface";
|
|
2
|
+
type Listener<T> = (event: T) => Promise<void>;
|
|
9
3
|
/**
|
|
10
4
|
* Event manager general helper that is responsible for fetching events
|
|
11
5
|
* from the server and notifying listeners about the events.
|
|
@@ -18,45 +12,26 @@ type Listener<T> = (events: T[], fullRefresh: boolean) => Promise<void>;
|
|
|
18
12
|
* called. Once started, the manager will fetch events in a loop with
|
|
19
13
|
* a timeout between each fetch. The default timeout is 30 seconds and
|
|
20
14
|
* additional jitter is used in case of failure.
|
|
21
|
-
*
|
|
22
|
-
* Example of usage:
|
|
23
|
-
*
|
|
24
|
-
* ```typescript
|
|
25
|
-
* const manager = new EventManager(
|
|
26
|
-
* logger,
|
|
27
|
-
* () => apiService.getLatestEventId(),
|
|
28
|
-
* (eventId) => apiService.getEvents(eventId),
|
|
29
|
-
* );
|
|
30
|
-
*
|
|
31
|
-
* manager.addListener((events, fullRefresh) => {
|
|
32
|
-
* // Process the events
|
|
33
|
-
* });
|
|
34
|
-
*
|
|
35
|
-
* manager.start();
|
|
36
|
-
* ```
|
|
37
15
|
*/
|
|
38
|
-
export declare class EventManager<T> {
|
|
16
|
+
export declare class EventManager<T extends Event> {
|
|
17
|
+
private specializedEventManager;
|
|
18
|
+
private pollingIntervalInSeconds;
|
|
39
19
|
private logger;
|
|
40
|
-
private getLatestEventId;
|
|
41
|
-
private getEvents;
|
|
42
|
-
private updateLatestEventId;
|
|
43
20
|
private latestEventId?;
|
|
44
21
|
private timeoutHandle?;
|
|
45
22
|
private processPromise?;
|
|
46
23
|
private listeners;
|
|
47
24
|
private retryIndex;
|
|
48
|
-
pollingIntervalInSeconds: number;
|
|
49
|
-
constructor(logger: Logger, getLatestEventId: () => Promise<string>, getEvents: (eventId: string) => Promise<Events<T>>, updateLatestEventId: (lastEventId: string) => Promise<void>);
|
|
50
|
-
addListener(callback: Listener<T>): void;
|
|
25
|
+
constructor(specializedEventManager: EventManagerInterface<T>, pollingIntervalInSeconds: number, latestEventId: string | null);
|
|
51
26
|
start(): Promise<void>;
|
|
52
|
-
|
|
27
|
+
addListener(callback: Listener<T>): EventSubscription;
|
|
28
|
+
setPollingInterval(pollingIntervalInSeconds: number): void;
|
|
29
|
+
stop(): Promise<void>;
|
|
53
30
|
private notifyListeners;
|
|
31
|
+
private processEvents;
|
|
54
32
|
/**
|
|
55
33
|
* Polling timeout is using exponential backoff with Fibonacci sequence.
|
|
56
|
-
*
|
|
57
|
-
* The timeout is public for testing purposes only.
|
|
58
34
|
*/
|
|
59
|
-
get nextPollTimeout()
|
|
60
|
-
stop(): Promise<void>;
|
|
35
|
+
private get nextPollTimeout();
|
|
61
36
|
}
|
|
62
37
|
export {};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EventManager = void 0;
|
|
4
|
-
const apiService_1 = require("../apiService");
|
|
5
|
-
const DEFAULT_POLLING_INTERVAL_IN_SECONDS = 30;
|
|
6
4
|
const FIBONACCI_LIST = [1, 1, 2, 3, 5, 8, 13];
|
|
7
5
|
/**
|
|
8
6
|
* Event manager general helper that is responsible for fetching events
|
|
@@ -16,144 +14,100 @@ const FIBONACCI_LIST = [1, 1, 2, 3, 5, 8, 13];
|
|
|
16
14
|
* called. Once started, the manager will fetch events in a loop with
|
|
17
15
|
* a timeout between each fetch. The default timeout is 30 seconds and
|
|
18
16
|
* additional jitter is used in case of failure.
|
|
19
|
-
*
|
|
20
|
-
* Example of usage:
|
|
21
|
-
*
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const manager = new EventManager(
|
|
24
|
-
* logger,
|
|
25
|
-
* () => apiService.getLatestEventId(),
|
|
26
|
-
* (eventId) => apiService.getEvents(eventId),
|
|
27
|
-
* );
|
|
28
|
-
*
|
|
29
|
-
* manager.addListener((events, fullRefresh) => {
|
|
30
|
-
* // Process the events
|
|
31
|
-
* });
|
|
32
|
-
*
|
|
33
|
-
* manager.start();
|
|
34
|
-
* ```
|
|
35
17
|
*/
|
|
36
18
|
class EventManager {
|
|
19
|
+
specializedEventManager;
|
|
20
|
+
pollingIntervalInSeconds;
|
|
37
21
|
logger;
|
|
38
|
-
getLatestEventId;
|
|
39
|
-
getEvents;
|
|
40
|
-
updateLatestEventId;
|
|
41
22
|
latestEventId;
|
|
42
23
|
timeoutHandle;
|
|
43
24
|
processPromise;
|
|
44
25
|
listeners = [];
|
|
45
26
|
retryIndex = 0;
|
|
46
|
-
pollingIntervalInSeconds
|
|
47
|
-
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
this.logger =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.
|
|
27
|
+
constructor(specializedEventManager, pollingIntervalInSeconds, latestEventId) {
|
|
28
|
+
this.specializedEventManager = specializedEventManager;
|
|
29
|
+
this.pollingIntervalInSeconds = pollingIntervalInSeconds;
|
|
30
|
+
if (latestEventId !== null) {
|
|
31
|
+
this.latestEventId = latestEventId;
|
|
32
|
+
}
|
|
33
|
+
this.logger = specializedEventManager.getLogger();
|
|
34
|
+
}
|
|
35
|
+
async start() {
|
|
36
|
+
if (this.latestEventId === undefined) {
|
|
37
|
+
this.latestEventId = await this.specializedEventManager.getLatestEventId();
|
|
38
|
+
}
|
|
39
|
+
this.processPromise = this.processEvents();
|
|
56
40
|
}
|
|
57
41
|
addListener(callback) {
|
|
58
42
|
this.listeners.push(callback);
|
|
43
|
+
return {
|
|
44
|
+
dispose: () => {
|
|
45
|
+
const index = this.listeners.indexOf(callback);
|
|
46
|
+
this.listeners.splice(index, 1);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
59
49
|
}
|
|
60
|
-
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
setPollingInterval(pollingIntervalInSeconds) {
|
|
51
|
+
this.pollingIntervalInSeconds = pollingIntervalInSeconds;
|
|
52
|
+
}
|
|
53
|
+
async stop() {
|
|
54
|
+
if (this.processPromise) {
|
|
55
|
+
this.logger.info(`Stopping event manager`);
|
|
56
|
+
try {
|
|
57
|
+
await this.processPromise;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
this.logger.warn(`Failed to stop cleanly: ${error instanceof Error ? error.message : error}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!this.timeoutHandle) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
clearTimeout(this.timeoutHandle);
|
|
67
|
+
this.timeoutHandle = undefined;
|
|
68
|
+
}
|
|
69
|
+
async notifyListeners(event) {
|
|
70
|
+
for (const listener of this.listeners) {
|
|
71
|
+
await listener(event);
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
74
|
async processEvents() {
|
|
75
|
+
let listenerError;
|
|
66
76
|
try {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
else {
|
|
72
|
-
while (true) {
|
|
73
|
-
let result;
|
|
74
|
-
try {
|
|
75
|
-
result = await this.getEvents(this.latestEventId);
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
// If last event ID is not found, we need to refresh the data.
|
|
79
|
-
// Caller is notified via standard event update with refresh flag.
|
|
80
|
-
if (error instanceof apiService_1.NotFoundAPIError) {
|
|
81
|
-
this.logger.warn(`Last event ID not found, refreshing data`);
|
|
82
|
-
result = {
|
|
83
|
-
lastEventId: await this.getLatestEventId(),
|
|
84
|
-
more: false,
|
|
85
|
-
refresh: true,
|
|
86
|
-
events: [],
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// Any other error is considered as a failure and we will retry
|
|
91
|
-
// with backoff policy.
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
await this.notifyListeners(result);
|
|
96
|
-
if (result.lastEventId !== this.latestEventId) {
|
|
97
|
-
await this.updateLatestEventId(result.lastEventId);
|
|
98
|
-
this.latestEventId = result.lastEventId;
|
|
99
|
-
}
|
|
100
|
-
if (!result.more) {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
77
|
+
const events = this.specializedEventManager.getEvents(this.latestEventId);
|
|
78
|
+
for await (const event of events) {
|
|
79
|
+
try {
|
|
80
|
+
await this.notifyListeners(event);
|
|
103
81
|
}
|
|
82
|
+
catch (internalListenerError) {
|
|
83
|
+
listenerError = internalListenerError;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
this.latestEventId = event.eventId;
|
|
104
87
|
}
|
|
105
88
|
this.retryIndex = 0;
|
|
106
89
|
}
|
|
107
90
|
catch (error) {
|
|
91
|
+
// This could be improved to catch api specific errors and let the listener errors bubble up directly
|
|
108
92
|
this.logger.error(`Failed to process events: ${error instanceof Error ? error.message : error} (retry ${this.retryIndex}, last event ID: ${this.latestEventId})`);
|
|
109
93
|
this.retryIndex++;
|
|
110
94
|
}
|
|
95
|
+
if (listenerError) {
|
|
96
|
+
throw listenerError;
|
|
97
|
+
}
|
|
111
98
|
this.timeoutHandle = setTimeout(() => {
|
|
112
99
|
this.processPromise = this.processEvents();
|
|
113
100
|
}, this.nextPollTimeout);
|
|
114
101
|
}
|
|
115
102
|
;
|
|
116
|
-
async notifyListeners(result) {
|
|
117
|
-
if (result.events.length === 0 && !result.refresh) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
if (!this.listeners.length) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
this.logger.debug(`Notifying listeners about ${result.events.length} events`);
|
|
124
|
-
for (const listener of this.listeners) {
|
|
125
|
-
try {
|
|
126
|
-
await listener(result.events, result.refresh);
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
this.logger.error(`Failed to process events: ${error instanceof Error ? error.message : error} (last event ID: ${result.lastEventId}, refresh: ${result.refresh})`);
|
|
130
|
-
throw error;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
103
|
/**
|
|
135
104
|
* Polling timeout is using exponential backoff with Fibonacci sequence.
|
|
136
|
-
*
|
|
137
|
-
* The timeout is public for testing purposes only.
|
|
138
105
|
*/
|
|
139
106
|
get nextPollTimeout() {
|
|
140
107
|
const retryIndex = Math.min(this.retryIndex, FIBONACCI_LIST.length - 1);
|
|
108
|
+
// FIXME jitter
|
|
141
109
|
return this.pollingIntervalInSeconds * 1000 * FIBONACCI_LIST[retryIndex];
|
|
142
110
|
}
|
|
143
|
-
async stop() {
|
|
144
|
-
if (this.processPromise) {
|
|
145
|
-
this.logger.info(`Stopping event manager`);
|
|
146
|
-
try {
|
|
147
|
-
await this.processPromise;
|
|
148
|
-
}
|
|
149
|
-
catch { }
|
|
150
|
-
}
|
|
151
|
-
if (!this.timeoutHandle) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
clearTimeout(this.timeoutHandle);
|
|
155
|
-
this.timeoutHandle = undefined;
|
|
156
|
-
}
|
|
157
111
|
}
|
|
158
112
|
exports.EventManager = EventManager;
|
|
159
113
|
//# sourceMappingURL=eventManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eventManager.js","sourceRoot":"","sources":["../../../src/internal/events/eventManager.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"eventManager.js","sourceRoot":"","sources":["../../../src/internal/events/eventManager.ts"],"names":[],"mappings":"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"}
|