@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.
Files changed (234) hide show
  1. package/dist/cache/index.d.ts +1 -0
  2. package/dist/cache/index.js +3 -1
  3. package/dist/cache/index.js.map +1 -1
  4. package/dist/cache/memoryCache.d.ts +1 -1
  5. package/dist/cache/nullCache.d.ts +14 -0
  6. package/dist/cache/nullCache.js +37 -0
  7. package/dist/cache/nullCache.js.map +1 -0
  8. package/dist/config.d.ts +16 -1
  9. package/dist/config.js +1 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/crypto/openPGPCrypto.js +2 -0
  12. package/dist/crypto/openPGPCrypto.js.map +1 -1
  13. package/dist/diagnostic/eventsGenerator.d.ts +14 -0
  14. package/dist/diagnostic/eventsGenerator.js +49 -0
  15. package/dist/diagnostic/eventsGenerator.js.map +1 -0
  16. package/dist/diagnostic/httpClient.d.ts +16 -0
  17. package/dist/diagnostic/httpClient.js +81 -0
  18. package/dist/diagnostic/httpClient.js.map +1 -0
  19. package/dist/diagnostic/index.d.ts +10 -0
  20. package/dist/diagnostic/index.js +35 -0
  21. package/dist/diagnostic/index.js.map +1 -0
  22. package/dist/diagnostic/integrityVerificationStream.d.ts +21 -0
  23. package/dist/diagnostic/integrityVerificationStream.js +56 -0
  24. package/dist/diagnostic/integrityVerificationStream.js.map +1 -0
  25. package/dist/diagnostic/interface.d.ts +102 -0
  26. package/dist/diagnostic/interface.js +3 -0
  27. package/dist/diagnostic/interface.js.map +1 -0
  28. package/dist/diagnostic/sdkDiagnostic.d.ts +22 -0
  29. package/dist/diagnostic/sdkDiagnostic.js +216 -0
  30. package/dist/diagnostic/sdkDiagnostic.js.map +1 -0
  31. package/dist/diagnostic/sdkDiagnosticFull.d.ts +18 -0
  32. package/dist/diagnostic/sdkDiagnosticFull.js +35 -0
  33. package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -0
  34. package/dist/diagnostic/telemetry.d.ts +25 -0
  35. package/dist/diagnostic/telemetry.js +70 -0
  36. package/dist/diagnostic/telemetry.js.map +1 -0
  37. package/dist/diagnostic/zipGenerators.d.ts +9 -0
  38. package/dist/diagnostic/zipGenerators.js +64 -0
  39. package/dist/diagnostic/zipGenerators.js.map +1 -0
  40. package/dist/diagnostic/zipGenerators.test.js +144 -0
  41. package/dist/diagnostic/zipGenerators.test.js.map +1 -0
  42. package/dist/errors.d.ts +2 -1
  43. package/dist/errors.js +3 -1
  44. package/dist/errors.js.map +1 -1
  45. package/dist/interface/config.d.ts +26 -0
  46. package/dist/interface/config.js +3 -0
  47. package/dist/interface/config.js.map +1 -0
  48. package/dist/interface/download.d.ts +2 -2
  49. package/dist/interface/events.d.ts +60 -20
  50. package/dist/interface/events.js +11 -1
  51. package/dist/interface/events.js.map +1 -1
  52. package/dist/interface/httpClient.d.ts +0 -14
  53. package/dist/interface/index.d.ts +8 -4
  54. package/dist/interface/index.js +2 -1
  55. package/dist/interface/index.js.map +1 -1
  56. package/dist/interface/nodes.d.ts +9 -0
  57. package/dist/interface/nodes.js.map +1 -1
  58. package/dist/interface/sharing.d.ts +1 -0
  59. package/dist/interface/upload.d.ts +6 -0
  60. package/dist/internal/download/apiService.js +32 -31
  61. package/dist/internal/download/apiService.js.map +1 -1
  62. package/dist/internal/download/fileDownloader.d.ts +2 -2
  63. package/dist/internal/download/fileDownloader.js.map +1 -1
  64. package/dist/internal/events/apiService.d.ts +4 -6
  65. package/dist/internal/events/apiService.js +15 -22
  66. package/dist/internal/events/apiService.js.map +1 -1
  67. package/dist/internal/events/coreEventManager.d.ts +7 -10
  68. package/dist/internal/events/coreEventManager.js +19 -36
  69. package/dist/internal/events/coreEventManager.js.map +1 -1
  70. package/dist/internal/events/coreEventManager.test.js +87 -0
  71. package/dist/internal/events/coreEventManager.test.js.map +1 -0
  72. package/dist/internal/events/eventManager.d.ts +11 -36
  73. package/dist/internal/events/eventManager.js +59 -105
  74. package/dist/internal/events/eventManager.js.map +1 -1
  75. package/dist/internal/events/eventManager.test.js +167 -82
  76. package/dist/internal/events/eventManager.test.js.map +1 -1
  77. package/dist/internal/events/index.d.ts +13 -33
  78. package/dist/internal/events/index.js +56 -72
  79. package/dist/internal/events/index.js.map +1 -1
  80. package/dist/internal/events/interface.d.ts +59 -14
  81. package/dist/internal/events/interface.js +13 -3
  82. package/dist/internal/events/interface.js.map +1 -1
  83. package/dist/internal/events/volumeEventManager.d.ts +7 -17
  84. package/dist/internal/events/volumeEventManager.js +58 -45
  85. package/dist/internal/events/volumeEventManager.js.map +1 -1
  86. package/dist/internal/events/volumeEventManager.test.d.ts +1 -0
  87. package/dist/internal/events/volumeEventManager.test.js +203 -0
  88. package/dist/internal/events/volumeEventManager.test.js.map +1 -0
  89. package/dist/internal/nodes/cache.d.ts +10 -1
  90. package/dist/internal/nodes/cache.js +17 -0
  91. package/dist/internal/nodes/cache.js.map +1 -1
  92. package/dist/internal/nodes/cryptoService.d.ts +1 -1
  93. package/dist/internal/nodes/cryptoService.js.map +1 -1
  94. package/dist/internal/nodes/events.d.ts +7 -83
  95. package/dist/internal/nodes/events.js +43 -217
  96. package/dist/internal/nodes/events.js.map +1 -1
  97. package/dist/internal/nodes/events.test.js +27 -277
  98. package/dist/internal/nodes/events.test.js.map +1 -1
  99. package/dist/internal/nodes/index.d.ts +3 -4
  100. package/dist/internal/nodes/index.js +5 -5
  101. package/dist/internal/nodes/index.js.map +1 -1
  102. package/dist/internal/nodes/nodesAccess.d.ts +15 -0
  103. package/dist/internal/nodes/nodesAccess.js +37 -0
  104. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  105. package/dist/internal/nodes/nodesAccess.test.js +131 -93
  106. package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
  107. package/dist/internal/nodes/nodesManagement.d.ts +1 -3
  108. package/dist/internal/nodes/nodesManagement.js +12 -26
  109. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  110. package/dist/internal/nodes/nodesManagement.test.js +35 -14
  111. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  112. package/dist/internal/shares/cache.d.ts +2 -0
  113. package/dist/internal/shares/cache.js +2 -0
  114. package/dist/internal/shares/cache.js.map +1 -1
  115. package/dist/internal/shares/manager.d.ts +1 -0
  116. package/dist/internal/shares/manager.js +3 -0
  117. package/dist/internal/shares/manager.js.map +1 -1
  118. package/dist/internal/sharing/apiService.js +1 -0
  119. package/dist/internal/sharing/apiService.js.map +1 -1
  120. package/dist/internal/sharing/cryptoService.js +1 -0
  121. package/dist/internal/sharing/cryptoService.js.map +1 -1
  122. package/dist/internal/sharing/events.d.ts +23 -55
  123. package/dist/internal/sharing/events.js +46 -138
  124. package/dist/internal/sharing/events.js.map +1 -1
  125. package/dist/internal/sharing/events.test.js +77 -180
  126. package/dist/internal/sharing/events.test.js.map +1 -1
  127. package/dist/internal/sharing/index.d.ts +4 -5
  128. package/dist/internal/sharing/index.js +5 -5
  129. package/dist/internal/sharing/index.js.map +1 -1
  130. package/dist/internal/sharing/interface.d.ts +3 -0
  131. package/dist/internal/sharing/sharingManagement.d.ts +2 -3
  132. package/dist/internal/sharing/sharingManagement.js +7 -9
  133. package/dist/internal/sharing/sharingManagement.js.map +1 -1
  134. package/dist/internal/sharing/sharingManagement.test.js +9 -39
  135. package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
  136. package/dist/internal/upload/apiService.d.ts +2 -3
  137. package/dist/internal/upload/apiService.js +7 -4
  138. package/dist/internal/upload/apiService.js.map +1 -1
  139. package/dist/internal/upload/index.d.ts +2 -2
  140. package/dist/internal/upload/index.js +3 -3
  141. package/dist/internal/upload/index.js.map +1 -1
  142. package/dist/internal/upload/interface.d.ts +2 -0
  143. package/dist/internal/upload/manager.d.ts +5 -5
  144. package/dist/internal/upload/manager.js +19 -50
  145. package/dist/internal/upload/manager.js.map +1 -1
  146. package/dist/internal/upload/manager.test.js +68 -44
  147. package/dist/internal/upload/manager.test.js.map +1 -1
  148. package/dist/internal/upload/streamUploader.js +1 -2
  149. package/dist/internal/upload/streamUploader.js.map +1 -1
  150. package/dist/internal/upload/streamUploader.test.js +1 -1
  151. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  152. package/dist/protonDriveClient.d.ts +19 -162
  153. package/dist/protonDriveClient.js +26 -190
  154. package/dist/protonDriveClient.js.map +1 -1
  155. package/dist/protonDrivePhotosClient.js +3 -2
  156. package/dist/protonDrivePhotosClient.js.map +1 -1
  157. package/package.json +3 -3
  158. package/src/cache/index.ts +1 -0
  159. package/src/cache/memoryCache.ts +1 -1
  160. package/src/cache/nullCache.ts +38 -0
  161. package/src/config.ts +17 -2
  162. package/src/crypto/openPGPCrypto.ts +2 -0
  163. package/src/diagnostic/eventsGenerator.ts +48 -0
  164. package/src/diagnostic/httpClient.ts +80 -0
  165. package/src/diagnostic/index.ts +38 -0
  166. package/src/diagnostic/integrityVerificationStream.ts +56 -0
  167. package/src/diagnostic/interface.ts +158 -0
  168. package/src/diagnostic/sdkDiagnostic.ts +238 -0
  169. package/src/diagnostic/sdkDiagnosticFull.ts +40 -0
  170. package/src/diagnostic/telemetry.ts +71 -0
  171. package/src/diagnostic/zipGenerators.test.ts +177 -0
  172. package/src/diagnostic/zipGenerators.ts +70 -0
  173. package/src/errors.ts +4 -1
  174. package/src/interface/config.ts +28 -0
  175. package/src/interface/download.ts +2 -2
  176. package/src/interface/events.ts +66 -21
  177. package/src/interface/httpClient.ts +0 -16
  178. package/src/interface/index.ts +8 -4
  179. package/src/interface/nodes.ts +21 -12
  180. package/src/interface/sharing.ts +1 -0
  181. package/src/interface/upload.ts +6 -0
  182. package/src/internal/download/apiService.ts +11 -8
  183. package/src/internal/download/fileDownloader.ts +2 -2
  184. package/src/internal/events/apiService.ts +25 -28
  185. package/src/internal/events/coreEventManager.test.ts +101 -0
  186. package/src/internal/events/coreEventManager.ts +20 -45
  187. package/src/internal/events/eventManager.test.ts +201 -88
  188. package/src/internal/events/eventManager.ts +69 -115
  189. package/src/internal/events/index.ts +54 -84
  190. package/src/internal/events/interface.ts +70 -15
  191. package/src/internal/events/volumeEventManager.test.ts +243 -0
  192. package/src/internal/events/volumeEventManager.ts +55 -53
  193. package/src/internal/nodes/cache.ts +20 -2
  194. package/src/internal/nodes/cryptoService.ts +1 -1
  195. package/src/internal/nodes/events.test.ts +29 -335
  196. package/src/internal/nodes/events.ts +45 -253
  197. package/src/internal/nodes/index.ts +6 -8
  198. package/src/internal/nodes/interface.ts +2 -2
  199. package/src/internal/nodes/nodesAccess.test.ts +132 -91
  200. package/src/internal/nodes/nodesAccess.ts +40 -1
  201. package/src/internal/nodes/nodesManagement.test.ts +39 -15
  202. package/src/internal/nodes/nodesManagement.ts +12 -30
  203. package/src/internal/shares/cache.ts +4 -2
  204. package/src/internal/shares/manager.ts +9 -5
  205. package/src/internal/sharing/apiService.ts +1 -0
  206. package/src/internal/sharing/cache.ts +1 -1
  207. package/src/internal/sharing/cryptoService.ts +1 -0
  208. package/src/internal/sharing/events.test.ts +89 -195
  209. package/src/internal/sharing/events.ts +42 -156
  210. package/src/internal/sharing/index.ts +6 -9
  211. package/src/internal/sharing/interface.ts +6 -2
  212. package/src/internal/sharing/sharingManagement.test.ts +10 -40
  213. package/src/internal/sharing/sharingManagement.ts +7 -11
  214. package/src/internal/upload/apiService.ts +5 -6
  215. package/src/internal/upload/index.ts +5 -5
  216. package/src/internal/upload/interface.ts +2 -0
  217. package/src/internal/upload/manager.test.ts +75 -45
  218. package/src/internal/upload/manager.ts +24 -54
  219. package/src/internal/upload/streamUploader.test.ts +0 -1
  220. package/src/internal/upload/streamUploader.ts +0 -2
  221. package/src/protonDriveClient.ts +75 -244
  222. package/src/protonDrivePhotosClient.ts +4 -3
  223. package/dist/internal/events/cache.d.ts +0 -28
  224. package/dist/internal/events/cache.js +0 -67
  225. package/dist/internal/events/cache.js.map +0 -1
  226. package/dist/internal/events/cache.test.js +0 -43
  227. package/dist/internal/events/cache.test.js.map +0 -1
  228. package/dist/internal/nodes/index.test.js +0 -114
  229. package/dist/internal/nodes/index.test.js.map +0 -1
  230. package/src/internal/events/cache.test.ts +0 -47
  231. package/src/internal/events/cache.ts +0 -80
  232. package/src/internal/nodes/index.test.ts +0 -137
  233. /package/dist/{internal/events/cache.test.d.ts → diagnostic/zipGenerators.test.d.ts} +0 -0
  234. /package/dist/internal/{nodes/index.test.d.ts → events/coreEventManager.test.d.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ import { Logger } from "../../interface";
1
2
  /**
2
3
  * Callback that accepts list of Drive events and flag whether no
3
4
  * event should be processed, but rather full cache refresh should be
@@ -5,14 +6,23 @@
5
6
  *
6
7
  * @param fullRefreshVolumeId - ID of the volume that should be fully refreshed.
7
8
  */
8
- export type DriveListener = (events: DriveEvent[], fullRefreshVolumeId?: string) => Promise<void>;
9
+ export type DriveListener = (event: DriveEvent) => Promise<void>;
10
+ export interface Event {
11
+ eventId: string;
12
+ }
13
+ export interface EventSubscription {
14
+ dispose(): void;
15
+ }
16
+ export interface LatestEventIdProvider {
17
+ getLatestEventId(treeEventScopeId: string): string | null;
18
+ }
9
19
  /**
10
20
  * Generic internal event interface representing a list of events
11
21
  * with metadata about the last event ID, whether there are more
12
22
  * events to fetch, or whether the listener should refresh its state.
13
23
  */
14
- export type Events<T> = {
15
- lastEventId: string;
24
+ export type EventsListWithStatus<T> = {
25
+ latestEventId: string;
16
26
  more: boolean;
17
27
  refresh: boolean;
18
28
  events: T[];
@@ -20,28 +30,63 @@ export type Events<T> = {
20
30
  /**
21
31
  * Internal event interface representing a list of specific Drive events.
22
32
  */
23
- export type DriveEvents = Events<DriveEvent>;
24
- export type DriveEvent = {
25
- type: DriveEventType.NodeCreated | DriveEventType.NodeUpdated | DriveEventType.NodeUpdatedMetadata;
33
+ export type DriveEventsListWithStatus = EventsListWithStatus<DriveEvent>;
34
+ type NodeCruEventType = DriveEventType.NodeCreated | DriveEventType.NodeUpdated;
35
+ export type NodeEventType = NodeCruEventType | DriveEventType.NodeDeleted;
36
+ export type NodeEvent = {
37
+ type: NodeCruEventType;
26
38
  nodeUid: string;
27
39
  parentNodeUid?: string;
28
40
  isTrashed: boolean;
29
41
  isShared: boolean;
30
- isOwnVolume: boolean;
42
+ treeEventScopeId: string;
43
+ eventId: string;
31
44
  } | {
32
45
  type: DriveEventType.NodeDeleted;
33
46
  nodeUid: string;
34
47
  parentNodeUid?: string;
35
- isTrashed?: boolean;
36
- isShared?: boolean;
37
- isOwnVolume: boolean;
38
- } | {
39
- type: DriveEventType.ShareWithMeUpdated;
48
+ treeEventScopeId: string;
49
+ eventId: string;
50
+ };
51
+ export type FastForwardEvent = {
52
+ type: DriveEventType.FastForward;
53
+ treeEventScopeId: string;
54
+ eventId: string;
55
+ };
56
+ export type TreeRefreshEvent = {
57
+ type: DriveEventType.TreeRefresh;
58
+ treeEventScopeId: string;
59
+ eventId: string;
40
60
  };
61
+ export type TreeRemovalEvent = {
62
+ type: DriveEventType.TreeRemove;
63
+ treeEventScopeId: string;
64
+ eventId: 'none';
65
+ };
66
+ export type SharedWithMeUpdated = {
67
+ type: DriveEventType.SharedWithMeUpdated;
68
+ eventId: string;
69
+ treeEventScopeId: 'core';
70
+ };
71
+ export type DriveEvent = NodeEvent | FastForwardEvent | TreeRefreshEvent | TreeRemovalEvent | FastForwardEvent | SharedWithMeUpdated;
41
72
  export declare enum DriveEventType {
42
73
  NodeCreated = "node_created",
43
74
  NodeUpdated = "node_updated",
44
- NodeUpdatedMetadata = "node_updated_metadata",
45
75
  NodeDeleted = "node_deleted",
46
- ShareWithMeUpdated = "share_with_me_updated"
76
+ SharedWithMeUpdated = "shared_with_me_updated",
77
+ TreeRefresh = "tree_refresh",
78
+ TreeRemove = "tree_remove",
79
+ FastForward = "fast_forward"
80
+ }
81
+ /**
82
+ * This can happen if all shared nodes in that volume where unshared or if the
83
+ * volume was deleted.
84
+ */
85
+ export declare class UnsubscribeFromEventsSourceError extends Error {
86
+ }
87
+ export interface EventManagerInterface<T> {
88
+ getLatestEventId(): Promise<string>;
89
+ getEvents(eventId: string): AsyncIterable<T>;
90
+ getLogger(): Logger;
47
91
  }
92
+ export {};
@@ -1,12 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DriveEventType = void 0;
3
+ exports.UnsubscribeFromEventsSourceError = exports.DriveEventType = void 0;
4
4
  var DriveEventType;
5
5
  (function (DriveEventType) {
6
6
  DriveEventType["NodeCreated"] = "node_created";
7
7
  DriveEventType["NodeUpdated"] = "node_updated";
8
- DriveEventType["NodeUpdatedMetadata"] = "node_updated_metadata";
9
8
  DriveEventType["NodeDeleted"] = "node_deleted";
10
- DriveEventType["ShareWithMeUpdated"] = "share_with_me_updated";
9
+ DriveEventType["SharedWithMeUpdated"] = "shared_with_me_updated";
10
+ DriveEventType["TreeRefresh"] = "tree_refresh";
11
+ DriveEventType["TreeRemove"] = "tree_remove";
12
+ DriveEventType["FastForward"] = "fast_forward";
11
13
  })(DriveEventType || (exports.DriveEventType = DriveEventType = {}));
14
+ /**
15
+ * This can happen if all shared nodes in that volume where unshared or if the
16
+ * volume was deleted.
17
+ */
18
+ class UnsubscribeFromEventsSourceError extends Error {
19
+ }
20
+ exports.UnsubscribeFromEventsSourceError = UnsubscribeFromEventsSourceError;
21
+ ;
12
22
  //# sourceMappingURL=interface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/internal/events/interface.ts"],"names":[],"mappings":";;;AA4CA,IAAY,cAMX;AAND,WAAY,cAAc;IACtB,8CAA4B,CAAA;IAC5B,8CAA4B,CAAA;IAC5B,+DAA6C,CAAA;IAC7C,8CAA4B,CAAA;IAC5B,8DAA4C,CAAA;AAChD,CAAC,EANW,cAAc,8BAAd,cAAc,QAMzB"}
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/internal/events/interface.ts"],"names":[],"mappings":";;;AAqFA,IAAY,cAQX;AARD,WAAY,cAAc;IACtB,8CAA4B,CAAA;IAC5B,8CAA4B,CAAA;IAC5B,8CAA4B,CAAA;IAC5B,gEAA8C,CAAA;IAC9C,8CAA4B,CAAA;IAC5B,4CAA0B,CAAA;IAC1B,8CAA4B,CAAA;AAChC,CAAC,EARW,cAAc,8BAAd,cAAc,QAQzB;AAED;;;GAGG;AACH,MAAa,gCAAiC,SAAQ,KAAK;CAAG;AAA9D,4EAA8D;AAAA,CAAC"}
@@ -1,27 +1,17 @@
1
1
  import { Logger } from "../../interface";
2
2
  import { EventsAPIService } from "./apiService";
3
- import { EventsCache } from "./cache";
4
- import { DriveListener } from "./interface";
3
+ import { DriveEvent, EventManagerInterface } from "./interface";
5
4
  /**
6
5
  * Combines API and event manager to provide a service for listening to
7
6
  * volume events. Volume events are all about nodes updates. Whenever
8
7
  * there is update to the node metadata or content, the event is emitted.
9
8
  */
10
- export declare class VolumeEventManager {
9
+ export declare class VolumeEventManager implements EventManagerInterface<DriveEvent> {
10
+ private logger;
11
11
  private apiService;
12
- private cache;
13
12
  private volumeId;
14
- private manager;
15
- constructor(logger: Logger, apiService: EventsAPIService, cache: EventsCache, volumeId: string, isOwnVolume: boolean);
16
- private getLastEventId;
17
- /**
18
- * There is a limit how many volume subscribtions can be active at
19
- * the same time. The manager of all volume managers should set the
20
- * intervals for each volume accordingly depending on the volume
21
- * type or the total number of subscriptions.
22
- */
23
- setPollingInterval(pollingIntervalInSeconds: number): void;
24
- startSubscription(): Promise<void>;
25
- stopSubscription(): Promise<void>;
26
- addListener(callback: DriveListener): void;
13
+ constructor(logger: Logger, apiService: EventsAPIService, volumeId: string);
14
+ getLogger(): Logger;
15
+ getEvents(eventId: string): AsyncIterable<DriveEvent>;
16
+ getLatestEventId(): Promise<string>;
27
17
  }
@@ -2,67 +2,80 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VolumeEventManager = void 0;
4
4
  const telemetry_1 = require("../../telemetry");
5
- const eventManager_1 = require("./eventManager");
5
+ const interface_1 = require("./interface");
6
+ const apiService_1 = require("../apiService");
6
7
  /**
7
8
  * Combines API and event manager to provide a service for listening to
8
9
  * volume events. Volume events are all about nodes updates. Whenever
9
10
  * there is update to the node metadata or content, the event is emitted.
10
11
  */
11
12
  class VolumeEventManager {
13
+ logger;
12
14
  apiService;
13
- cache;
14
15
  volumeId;
15
- manager;
16
- constructor(logger, apiService, cache, volumeId, isOwnVolume) {
16
+ constructor(logger, apiService, volumeId) {
17
+ this.logger = logger;
17
18
  this.apiService = apiService;
18
- this.cache = cache;
19
19
  this.volumeId = volumeId;
20
20
  this.apiService = apiService;
21
21
  this.volumeId = volumeId;
22
- this.manager = new eventManager_1.EventManager(new telemetry_1.LoggerWithPrefix(logger, `volume ${volumeId}`), () => this.getLastEventId(), (eventId) => this.apiService.getVolumeEvents(volumeId, eventId, isOwnVolume), (lastEventId) => this.cache.setLastEventId(volumeId, {
23
- lastEventId,
24
- pollingIntervalInSeconds: this.manager.pollingIntervalInSeconds,
25
- isOwnVolume
26
- }));
27
- this.cache.getPollingIntervalInSeconds(volumeId)
28
- .then((pollingIntervalInSeconds) => {
29
- if (pollingIntervalInSeconds) {
30
- this.manager.pollingIntervalInSeconds = pollingIntervalInSeconds;
31
- }
32
- })
33
- .catch(() => { });
34
- }
35
- async getLastEventId() {
36
- const lastEventId = await this.cache.getLastEventId(this.volumeId);
37
- if (lastEventId) {
38
- return lastEventId;
39
- }
40
- return this.apiService.getVolumeLatestEventId(this.volumeId);
22
+ this.logger = new telemetry_1.LoggerWithPrefix(logger, `volume ${volumeId}`);
41
23
  }
42
- /**
43
- * There is a limit how many volume subscribtions can be active at
44
- * the same time. The manager of all volume managers should set the
45
- * intervals for each volume accordingly depending on the volume
46
- * type or the total number of subscriptions.
47
- */
48
- setPollingInterval(pollingIntervalInSeconds) {
49
- this.manager.pollingIntervalInSeconds = pollingIntervalInSeconds;
24
+ getLogger() {
25
+ return this.logger;
50
26
  }
51
- async startSubscription() {
52
- await this.manager.start();
53
- }
54
- async stopSubscription() {
55
- await this.manager.stop();
56
- }
57
- addListener(callback) {
58
- this.manager.addListener(async (events, fullRefresh) => {
59
- if (fullRefresh) {
60
- await callback([], this.volumeId);
27
+ async *getEvents(eventId) {
28
+ try {
29
+ let events;
30
+ let more = true;
31
+ while (more) {
32
+ events = await this.apiService.getVolumeEvents(this.volumeId, eventId);
33
+ more = events.more;
34
+ if (events.refresh) {
35
+ yield {
36
+ type: interface_1.DriveEventType.TreeRefresh,
37
+ treeEventScopeId: this.volumeId,
38
+ eventId: events.latestEventId,
39
+ };
40
+ break;
41
+ }
42
+ // Update to the latest eventId to avoid inactive volumes from getting out of sync
43
+ if (events.events.length === 0 && events.latestEventId !== eventId) {
44
+ yield {
45
+ type: interface_1.DriveEventType.FastForward,
46
+ treeEventScopeId: this.volumeId,
47
+ eventId: events.latestEventId,
48
+ };
49
+ break;
50
+ }
51
+ yield* events.events;
52
+ eventId = events.latestEventId;
61
53
  }
62
- else {
63
- await callback(events);
54
+ }
55
+ catch (error) {
56
+ if (error instanceof apiService_1.NotFoundAPIError) {
57
+ this.logger.info(`Volume events no longer accessible`);
58
+ yield {
59
+ type: interface_1.DriveEventType.TreeRemove,
60
+ treeEventScopeId: this.volumeId,
61
+ // After a TreeRemoval event, polling should stop.
62
+ eventId: 'none',
63
+ };
64
64
  }
65
- });
65
+ throw error;
66
+ }
67
+ }
68
+ async getLatestEventId() {
69
+ try {
70
+ return await this.apiService.getVolumeLatestEventId(this.volumeId);
71
+ }
72
+ catch (error) {
73
+ if (error instanceof apiService_1.NotFoundAPIError) {
74
+ this.logger.info(`Volume events no longer accessible`);
75
+ throw new interface_1.UnsubscribeFromEventsSourceError(error.message);
76
+ }
77
+ throw error;
78
+ }
66
79
  }
67
80
  }
68
81
  exports.VolumeEventManager = VolumeEventManager;
@@ -1 +1 @@
1
- {"version":3,"file":"volumeEventManager.js","sourceRoot":"","sources":["../../../src/internal/events/volumeEventManager.ts"],"names":[],"mappings":";;;AACA,+CAAmD;AAInD,iDAA8C;AAE9C;;;;GAIG;AACH,MAAa,kBAAkB;IAGS;IAAsC;IAA4B;IAF9F,OAAO,CAA2B;IAE1C,YAAY,MAAc,EAAU,UAA4B,EAAU,KAAkB,EAAU,QAAgB,EAAE,WAAoB;QAAxG,eAAU,GAAV,UAAU,CAAkB;QAAU,UAAK,GAAL,KAAK,CAAa;QAAU,aAAQ,GAAR,QAAQ,CAAQ;QAClH,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,IAAI,CAAC,OAAO,GAAG,IAAI,2BAAY,CAC3B,IAAI,4BAAgB,CAAC,MAAM,EAAE,UAAU,QAAQ,EAAE,CAAC,EAClD,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAC3B,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,EAC5E,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE;YACjD,WAAW;YACX,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,wBAAwB;YAC/D,WAAW;SACd,CAAC,CACL,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,QAAQ,CAAC;aAC3C,IAAI,CAAC,CAAC,wBAAwB,EAAE,EAAE;YAC/B,IAAI,wBAAwB,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,wBAAwB,GAAG,wBAAwB,CAAC;YACrE,CAAC;QACL,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,cAAc;QACxB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,IAAI,WAAW,EAAE,CAAC;YACd,OAAO,WAAW,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,wBAAgC;QAC/C,IAAI,CAAC,OAAO,CAAC,wBAAwB,GAAG,wBAAwB,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,iBAAiB;QACnB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,QAAuB;QAC/B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;YACnD,IAAI,WAAW,EAAE,CAAC;gBACd,MAAM,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACJ,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AA7DD,gDA6DC"}
1
+ {"version":3,"file":"volumeEventManager.js","sourceRoot":"","sources":["../../../src/internal/events/volumeEventManager.ts"],"names":[],"mappings":";;;AACA,+CAAmD;AAEnD,2CAA6I;AAC7I,8CAAiD;AAEjD;;;;GAIG;AACH,MAAa,kBAAkB;IAEP;IAAwB;IAAsC;IAAlF,YAAoB,MAAc,EAAU,UAA4B,EAAU,QAAgB;QAA9E,WAAM,GAAN,MAAM,CAAQ;QAAU,eAAU,GAAV,UAAU,CAAkB;QAAU,aAAQ,GAAR,QAAQ,CAAQ;QAC9F,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,4BAAgB,CAAC,MAAM,EAAE,UAAU,QAAQ,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,CAAE,SAAS,CAAC,OAAe;QAC7B,IAAI,CAAC;YACD,IAAI,MAAiC,CAAC;YACtC,IAAI,IAAI,GAAG,IAAI,CAAC;YAChB,OAAO,IAAI,EAAE,CAAC;gBACV,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;gBACnB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,MAAM;wBACF,IAAI,EAAE,0BAAc,CAAC,WAAW;wBAChC,gBAAgB,EAAE,IAAI,CAAC,QAAQ;wBAC/B,OAAO,EAAE,MAAM,CAAC,aAAa;qBAChC,CAAC;oBACF,MAAM;gBACV,CAAC;gBACD,kFAAkF;gBAClF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;oBACjE,MAAM;wBACF,IAAI,EAAE,0BAAc,CAAC,WAAW;wBAChC,gBAAgB,EAAE,IAAI,CAAC,QAAQ;wBAC/B,OAAO,EAAE,MAAM,CAAC,aAAa;qBAChC,CAAC;oBACF,MAAM;gBACV,CAAC;gBACD,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;gBACrB,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC;YACnC,CAAC;QACL,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,KAAK,YAAY,6BAAgB,EAAE,CAAC;gBACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;gBACvD,MAAM;oBACF,IAAI,EAAE,0BAAc,CAAC,UAAU;oBAC/B,gBAAgB,EAAE,IAAI,CAAC,QAAQ;oBAC/B,kDAAkD;oBAClD,OAAO,EAAE,MAAM;iBAClB,CAAC;YACN,CAAC;YACD,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,IAAI,CAAC;YACD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,KAAK,YAAY,6BAAgB,EAAE,CAAC;gBACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;gBACvD,MAAM,IAAI,4CAAgC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;CACJ;AAhED,gDAgEC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const logger_1 = require("../../tests/logger");
4
+ const apiService_1 = require("../apiService");
5
+ const volumeEventManager_1 = require("./volumeEventManager");
6
+ const interface_1 = require("./interface");
7
+ jest.mock("./apiService");
8
+ describe("VolumeEventManager", () => {
9
+ let manager;
10
+ let mockEventsAPIService;
11
+ const mockLogger = (0, logger_1.getMockLogger)();
12
+ const volumeId = "volumeId123";
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockEventsAPIService = {
16
+ getVolumeLatestEventId: jest.fn(),
17
+ getVolumeEvents: jest.fn(),
18
+ getCoreLatestEventId: jest.fn(),
19
+ getCoreEvents: jest.fn(),
20
+ };
21
+ manager = new volumeEventManager_1.VolumeEventManager(mockLogger, mockEventsAPIService, volumeId);
22
+ });
23
+ describe("getLatestEventId", () => {
24
+ it("should return the latest event ID from API", async () => {
25
+ const expectedEventId = "eventId123";
26
+ mockEventsAPIService.getVolumeLatestEventId.mockResolvedValue(expectedEventId);
27
+ const result = await manager.getLatestEventId();
28
+ expect(result).toBe(expectedEventId);
29
+ expect(mockEventsAPIService.getVolumeLatestEventId).toHaveBeenCalledWith(volumeId);
30
+ });
31
+ it("should throw UnsubscribeFromEventsSourceError when API returns NotFoundAPIError", async () => {
32
+ const notFoundError = new apiService_1.NotFoundAPIError("Event not found", 2501);
33
+ mockEventsAPIService.getVolumeLatestEventId.mockRejectedValue(notFoundError);
34
+ await expect(manager.getLatestEventId()).rejects.toThrow("Event not found");
35
+ });
36
+ it("should rethrow other errors", async () => {
37
+ const networkError = new Error("Network error");
38
+ mockEventsAPIService.getVolumeLatestEventId.mockRejectedValue(networkError);
39
+ await expect(manager.getLatestEventId()).rejects.toThrow("Network error");
40
+ });
41
+ });
42
+ describe("getEvents", () => {
43
+ it("should yield events from API response", async () => {
44
+ const mockEventsResponse = {
45
+ latestEventId: "eventId456",
46
+ more: false,
47
+ refresh: false,
48
+ events: [
49
+ {
50
+ type: interface_1.DriveEventType.NodeCreated,
51
+ nodeUid: "node1",
52
+ parentNodeUid: "parent1",
53
+ isTrashed: false,
54
+ isShared: false,
55
+ treeEventScopeId: volumeId,
56
+ eventId: "eventId456",
57
+ }
58
+ ],
59
+ };
60
+ mockEventsAPIService.getVolumeEvents.mockResolvedValue(mockEventsResponse);
61
+ const events = [];
62
+ for await (const event of manager.getEvents("startEventId")) {
63
+ events.push(event);
64
+ }
65
+ expect(events).toEqual(mockEventsResponse.events);
66
+ expect(mockEventsAPIService.getVolumeEvents).toHaveBeenCalledWith(volumeId, "startEventId");
67
+ });
68
+ it("should continue fetching when more events are available", async () => {
69
+ const firstResponse = {
70
+ latestEventId: "eventId2",
71
+ more: true,
72
+ refresh: false,
73
+ events: [
74
+ {
75
+ type: interface_1.DriveEventType.NodeCreated,
76
+ nodeUid: "node1",
77
+ parentNodeUid: "parent1",
78
+ isTrashed: false,
79
+ isShared: false,
80
+ treeEventScopeId: volumeId,
81
+ eventId: "eventId2",
82
+ }
83
+ ],
84
+ };
85
+ const secondResponse = {
86
+ latestEventId: "eventId3",
87
+ more: false,
88
+ refresh: false,
89
+ events: [
90
+ {
91
+ type: interface_1.DriveEventType.NodeUpdated,
92
+ nodeUid: "node2",
93
+ parentNodeUid: "parent1",
94
+ isTrashed: false,
95
+ isShared: false,
96
+ treeEventScopeId: volumeId,
97
+ eventId: "eventId3",
98
+ }
99
+ ],
100
+ };
101
+ mockEventsAPIService.getVolumeEvents
102
+ .mockResolvedValueOnce(firstResponse)
103
+ .mockResolvedValueOnce(secondResponse);
104
+ const events = [];
105
+ for await (const event of manager.getEvents("startEventId")) {
106
+ events.push(event);
107
+ }
108
+ expect(events).toHaveLength(2);
109
+ expect(events[0]).toEqual(firstResponse.events[0]);
110
+ expect(events[1]).toEqual(secondResponse.events[0]);
111
+ expect(mockEventsAPIService.getVolumeEvents).toHaveBeenCalledTimes(2);
112
+ expect(mockEventsAPIService.getVolumeEvents).toHaveBeenNthCalledWith(1, volumeId, "startEventId");
113
+ expect(mockEventsAPIService.getVolumeEvents).toHaveBeenNthCalledWith(2, volumeId, "eventId2");
114
+ });
115
+ it("should yield TreeRefresh event when refresh is true", async () => {
116
+ const mockEventsResponse = {
117
+ latestEventId: "eventId789",
118
+ more: false,
119
+ refresh: true,
120
+ events: [],
121
+ };
122
+ mockEventsAPIService.getVolumeEvents.mockResolvedValue(mockEventsResponse);
123
+ const events = [];
124
+ for await (const event of manager.getEvents("startEventId")) {
125
+ events.push(event);
126
+ }
127
+ expect(events).toHaveLength(1);
128
+ expect(events[0]).toEqual({
129
+ type: interface_1.DriveEventType.TreeRefresh,
130
+ treeEventScopeId: volumeId,
131
+ eventId: "eventId789",
132
+ });
133
+ });
134
+ it("should yield FastForward event when no events but eventId changed", async () => {
135
+ const mockEventsResponse = {
136
+ latestEventId: "newEventId",
137
+ more: false,
138
+ refresh: false,
139
+ events: [],
140
+ };
141
+ mockEventsAPIService.getVolumeEvents.mockResolvedValue(mockEventsResponse);
142
+ const events = [];
143
+ for await (const event of manager.getEvents("oldEventId")) {
144
+ events.push(event);
145
+ }
146
+ expect(events).toHaveLength(1);
147
+ expect(events[0]).toEqual({
148
+ type: interface_1.DriveEventType.FastForward,
149
+ treeEventScopeId: volumeId,
150
+ eventId: "newEventId",
151
+ });
152
+ });
153
+ it("should yield TreeRemove event when API returns NotFoundAPIError", async () => {
154
+ const notFoundError = new apiService_1.NotFoundAPIError("Volume not found", 2501);
155
+ mockEventsAPIService.getVolumeEvents.mockRejectedValue(notFoundError);
156
+ const events = [];
157
+ try {
158
+ for await (const event of manager.getEvents("startEventId")) {
159
+ events.push(event);
160
+ }
161
+ }
162
+ catch (error) {
163
+ // The error should be re-thrown, but first it should yield a TreeRemove event
164
+ expect(error).toBe(notFoundError);
165
+ }
166
+ expect(events).toHaveLength(1);
167
+ expect(events[0]).toEqual({
168
+ type: interface_1.DriveEventType.TreeRemove,
169
+ treeEventScopeId: volumeId,
170
+ eventId: 'none',
171
+ });
172
+ });
173
+ it("should rethrow non-NotFoundAPIError errors", async () => {
174
+ const networkError = new Error("Network error");
175
+ mockEventsAPIService.getVolumeEvents.mockRejectedValue(networkError);
176
+ const eventGenerator = manager.getEvents("startEventId");
177
+ const eventIterator = eventGenerator[Symbol.asyncIterator]();
178
+ await expect(eventIterator.next()).rejects.toThrow("Network error");
179
+ });
180
+ it("should not yield events when events array is empty and eventId unchanged", async () => {
181
+ const mockEventsResponse = {
182
+ latestEventId: "sameEventId",
183
+ more: false,
184
+ refresh: false,
185
+ events: [],
186
+ };
187
+ mockEventsAPIService.getVolumeEvents.mockResolvedValue(mockEventsResponse);
188
+ const events = [];
189
+ for await (const event of manager.getEvents("sameEventId")) {
190
+ events.push(event);
191
+ }
192
+ expect(events).toHaveLength(0);
193
+ });
194
+ });
195
+ describe("getLogger", () => {
196
+ it("should return logger with prefix", () => {
197
+ const logger = manager.getLogger();
198
+ expect(logger).toBeDefined();
199
+ // The logger should be wrapped with LoggerWithPrefix, but we can't easily test the prefix
200
+ });
201
+ });
202
+ });
203
+ //# sourceMappingURL=volumeEventManager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volumeEventManager.test.js","sourceRoot":"","sources":["../../../src/internal/events/volumeEventManager.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
+ import { EntityResult } from "../../cache";
1
2
  import { ProtonDriveEntitiesCache, Logger } from "../../interface";
2
3
  import { DecryptedNode } from "./interface";
3
4
  export declare enum CACHE_TAG_KEYS {
4
5
  ParentUid = "nodeParentUid",
5
- Trashed = "nodeTrashed"
6
+ Trashed = "nodeTrashed",
7
+ Roots = "nodeRoot"
6
8
  }
7
9
  type DecryptedNodeResult = ({
8
10
  uid: string;
@@ -33,6 +35,12 @@ export declare class NodesCache {
33
35
  * which nodes were up-to-date anymore.
34
36
  */
35
37
  setNodesStaleFromVolume(volumeId: string): Promise<void>;
38
+ /**
39
+ * Remove all entries associated with a volume.
40
+ *
41
+ * This is needed when a user looses access to a volume.
42
+ */
43
+ removeVolume(volumeId: string): Promise<void>;
36
44
  /**
37
45
  * Remove corrupted node never throws, but it logs so we can know
38
46
  * about issues and fix them. It is crucial to remove corrupted
@@ -44,6 +52,7 @@ export declare class NodesCache {
44
52
  private getRecursiveChildrenCacheUids;
45
53
  iterateNodes(nodeUids: string[]): AsyncGenerator<DecryptedNodeResult>;
46
54
  iterateChildren(parentNodeUid: string): AsyncGenerator<DecryptedNodeResult>;
55
+ iterateRootNodeUids(volumeId: string): AsyncGenerator<EntityResult<string>>;
47
56
  iterateTrashedNodes(): AsyncGenerator<DecryptedNodeResult>;
48
57
  /**
49
58
  * Converts result from the cache with cache UID and data to result of node
@@ -7,6 +7,7 @@ var CACHE_TAG_KEYS;
7
7
  (function (CACHE_TAG_KEYS) {
8
8
  CACHE_TAG_KEYS["ParentUid"] = "nodeParentUid";
9
9
  CACHE_TAG_KEYS["Trashed"] = "nodeTrashed";
10
+ CACHE_TAG_KEYS["Roots"] = "nodeRoot";
10
11
  })(CACHE_TAG_KEYS || (exports.CACHE_TAG_KEYS = CACHE_TAG_KEYS = {}));
11
12
  /**
12
13
  * Provides caching for nodes metadata.
@@ -33,6 +34,9 @@ class NodesCache {
33
34
  if (node.parentUid) {
34
35
  tags.push(`${CACHE_TAG_KEYS.ParentUid}:${node.parentUid}`);
35
36
  }
37
+ else {
38
+ tags.push(`${CACHE_TAG_KEYS.Roots}:${volumeId}`);
39
+ }
36
40
  if (node.trashTime) {
37
41
  tags.push(`${CACHE_TAG_KEYS.Trashed}`);
38
42
  }
@@ -67,6 +71,16 @@ class NodesCache {
67
71
  await this.driveCache.removeEntities([result.key]);
68
72
  }
69
73
  }
74
+ /**
75
+ * Remove all entries associated with a volume.
76
+ *
77
+ * This is needed when a user looses access to a volume.
78
+ */
79
+ async removeVolume(volumeId) {
80
+ for await (const result of this.iterateRootNodeUids(volumeId)) {
81
+ await this.removeNodes([result.key]);
82
+ }
83
+ }
70
84
  /**
71
85
  * Remove corrupted node never throws, but it logs so we can know
72
86
  * about issues and fix them. It is crucial to remove corrupted
@@ -133,6 +147,9 @@ class NodesCache {
133
147
  }
134
148
  }
135
149
  }
150
+ async *iterateRootNodeUids(volumeId) {
151
+ yield* this.driveCache.iterateEntitiesByTag(`${CACHE_TAG_KEYS.Roots}:${volumeId}`);
152
+ }
136
153
  async *iterateTrashedNodes() {
137
154
  for await (const result of this.driveCache.iterateEntitiesByTag(CACHE_TAG_KEYS.Trashed)) {
138
155
  const node = await this.convertCacheResult(result);