1 import { queryLatestModelEventID, queryModelEvents } from '@proton/shared/lib/api/calendars';
2 import createEventManager, { EVENT_ID_KEYS, EventManager } from '@proton/shared/lib/eventManager/eventManager';
3 import type { Api, SimpleMap } from '@proton/shared/lib/interfaces';
5 type SubscribeCallback = (data: any) => void;
7 export interface CalendarModelEventManager {
8 start: (calendarIDs: string[]) => void[];
9 stop: (calendarIDs: string[]) => void[];
10 reset: (calendarIDs: string[]) => void[];
11 call: (calendarIDs: string[]) => Promise<void[]>;
12 subscribe: (calendarIDs: string[], cb: SubscribeCallback) => () => void;
16 const createCalendarEventManagerById = async (api: Api, calendarID: string) => {
17 const { CalendarModelEventID } = await api<{ CalendarModelEventID: string }>(queryLatestModelEventID(calendarID));
18 const eventManager = createEventManager({
20 eventID: CalendarModelEventID,
21 query: (eventId: string) => queryModelEvents(calendarID, eventId),
22 eventIDKey: EVENT_ID_KEYS.CALENDAR,
28 const getOrSetRecord = (calendarID: string, eventManagers: SimpleMap<EventManagerCacheRecord>, api: Api) => {
29 const cachedValue = eventManagers[calendarID];
30 if (!cachedValue || (cachedValue.eventManager === undefined && cachedValue.promise === undefined)) {
31 const promise = createCalendarEventManagerById(api, calendarID)
32 .then((eventManager) => {
33 eventManagers[calendarID] = {
40 delete eventManagers[calendarID];
43 const record = { promise, eventManager: undefined };
44 eventManagers[calendarID] = record;
50 type EventManagerCacheRecord =
52 eventManager: EventManager;
56 promise: Promise<EventManager | undefined>;
57 eventManager: undefined;
60 export const createCalendarModelEventManager = ({ api }: { api: Api }): CalendarModelEventManager => {
61 let eventManagers: SimpleMap<EventManagerCacheRecord> = {};
64 Object.values(eventManagers).forEach((record) => {
69 record.promise.then((eventManager) => {
77 if (record.eventManager) {
78 record.eventManager.stop();
79 record.eventManager.reset();
85 const start = (calendarIDs: string[]) => {
86 return calendarIDs.map((calendarID) => {
87 return eventManagers[calendarID]?.eventManager?.start();
91 const stop = (calendarIDs: string[]) => {
92 return calendarIDs.map((calendarID) => {
93 return eventManagers[calendarID]?.eventManager?.stop();
97 const reset = (calendarIDs: string[]) => {
98 return calendarIDs.map((calendarID) => {
99 return eventManagers[calendarID]?.eventManager?.reset();
103 const call = (calendarIDs: string[]) => {
105 calendarIDs.map((calendarID) => {
106 return eventManagers[calendarID]?.eventManager?.call();
111 const subscribe = (calendarIDs: string[], cb: SubscribeCallback) => {
113 const notify = (data: any) => {
117 const unsubscribes = calendarIDs.reduce<(() => void)[]>((acc, calendarID) => {
118 const record = getOrSetRecord(calendarID, eventManagers, api);
119 if (record.promise) {
120 record.promise.then((eventManager) => {
121 if (!isActive || !eventManager) {
124 acc.push(eventManager.subscribe(notify));
128 acc.push(record.eventManager.subscribe(notify));
133 unsubscribes.forEach((unsub) => unsub?.());