@novu/react 2.0.0 → 2.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.
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React$1 from 'react';
2
+ import React$1, { ReactNode } from 'react';
3
3
  import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab, RouterPush } from '@novu/js/ui';
4
4
  export { Notification } from '@novu/js/ui';
5
+ import { Novu, NovuOptions, Notification as Notification$1, NovuError, Preference, NotificationFilter } from '@novu/js';
5
6
 
6
7
  type NotificationsRenderer = (notification: Notification) => React.ReactNode;
7
8
  type BellRenderer = (unreadCount: number) => React.ReactNode;
@@ -38,6 +39,7 @@ declare const Bell: React$1.MemoExoticComponent<(props: BellProps) => react_jsx_
38
39
 
39
40
  type InboxProps = DefaultProps | WithChildrenProps;
40
41
  declare const Inbox: React$1.MemoExoticComponent<(props: InboxProps) => react_jsx_runtime.JSX.Element>;
42
+ declare const InboxChild: React$1.MemoExoticComponent<(props: InboxProps) => react_jsx_runtime.JSX.Element>;
41
43
 
42
44
  declare const Preferences: () => react_jsx_runtime.JSX.Element;
43
45
 
@@ -49,4 +51,72 @@ type NotificationProps = {
49
51
  };
50
52
  declare const Notifications: React$1.MemoExoticComponent<(props: NotificationProps) => react_jsx_runtime.JSX.Element>;
51
53
 
52
- export { type BaseProps, Bell, type BellProps, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, type InboxProps, type NotificationProps, Notifications, type NotificationsRenderer, Preferences, type WithChildrenProps };
54
+ type NovuProviderProps = NovuOptions & {
55
+ children: ReactNode;
56
+ };
57
+ declare const NovuProvider: ({ children, applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache, }: NovuProviderProps) => react_jsx_runtime.JSX.Element;
58
+ declare const useNovu: () => Novu;
59
+ declare const useUnsafeNovu: () => Novu | undefined;
60
+
61
+ type UseNotificationsProps = {
62
+ tags?: string[];
63
+ read?: boolean;
64
+ archived?: boolean;
65
+ limit?: number;
66
+ onSuccess?: (data: Notification$1[]) => void;
67
+ onError?: (error: NovuError) => void;
68
+ };
69
+ declare const useNotifications: (props?: UseNotificationsProps) => {
70
+ readAll: () => Promise<{
71
+ data?: void | undefined;
72
+ error?: NovuError | undefined;
73
+ }>;
74
+ archiveAll: () => Promise<{
75
+ data?: void | undefined;
76
+ error?: NovuError | undefined;
77
+ }>;
78
+ archiveAllRead: () => Promise<{
79
+ data?: void | undefined;
80
+ error?: NovuError | undefined;
81
+ }>;
82
+ notifications: Notification$1[] | undefined;
83
+ error: NovuError | undefined;
84
+ isLoading: boolean;
85
+ isFetching: boolean;
86
+ refetch: () => Promise<void>;
87
+ fetchMore: () => Promise<void>;
88
+ hasMore: boolean;
89
+ };
90
+
91
+ type UsePreferencesProps = {
92
+ onSuccess?: (data: Preference[]) => void;
93
+ onError?: (error: NovuError) => void;
94
+ };
95
+ type UsePreferencesResult = {
96
+ preferences?: Preference[];
97
+ error?: NovuError;
98
+ isLoading: boolean;
99
+ isFetching: boolean;
100
+ refetch: () => Promise<void>;
101
+ };
102
+ declare const usePreferences: (props?: UsePreferencesProps) => UsePreferencesResult;
103
+
104
+ type Count = {
105
+ count: number;
106
+ filter: NotificationFilter;
107
+ };
108
+ type UseCountsProps = {
109
+ filters: NotificationFilter[];
110
+ onSuccess?: (data: Count[]) => void;
111
+ onError?: (error: NovuError) => void;
112
+ };
113
+ type UseCountsResult = {
114
+ counts?: Count[];
115
+ error?: NovuError;
116
+ isLoading: boolean;
117
+ isFetching: boolean;
118
+ refetch: () => Promise<void>;
119
+ };
120
+ declare const useCounts: (props: UseCountsProps) => UseCountsResult;
121
+
122
+ export { type BaseProps, Bell, type BellProps, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, InboxChild, type InboxProps, type NotificationProps, Notifications, type NotificationsRenderer, NovuProvider, Preferences, type UseNotificationsProps, type WithChildrenProps, useCounts, useNotifications, useNovu, usePreferences, useUnsafeNovu };
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React$1 from 'react';
2
+ import React$1, { ReactNode } from 'react';
3
3
  import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab, RouterPush } from '@novu/js/ui';
4
4
  export { Notification } from '@novu/js/ui';
5
+ import { Novu, NovuOptions, Notification as Notification$1, NovuError, Preference, NotificationFilter } from '@novu/js';
5
6
 
6
7
  type NotificationsRenderer = (notification: Notification) => React.ReactNode;
7
8
  type BellRenderer = (unreadCount: number) => React.ReactNode;
@@ -38,6 +39,7 @@ declare const Bell: React$1.MemoExoticComponent<(props: BellProps) => react_jsx_
38
39
 
39
40
  type InboxProps = DefaultProps | WithChildrenProps;
40
41
  declare const Inbox: React$1.MemoExoticComponent<(props: InboxProps) => react_jsx_runtime.JSX.Element>;
42
+ declare const InboxChild: React$1.MemoExoticComponent<(props: InboxProps) => react_jsx_runtime.JSX.Element>;
41
43
 
42
44
  declare const Preferences: () => react_jsx_runtime.JSX.Element;
43
45
 
@@ -49,4 +51,72 @@ type NotificationProps = {
49
51
  };
50
52
  declare const Notifications: React$1.MemoExoticComponent<(props: NotificationProps) => react_jsx_runtime.JSX.Element>;
51
53
 
52
- export { type BaseProps, Bell, type BellProps, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, type InboxProps, type NotificationProps, Notifications, type NotificationsRenderer, Preferences, type WithChildrenProps };
54
+ type NovuProviderProps = NovuOptions & {
55
+ children: ReactNode;
56
+ };
57
+ declare const NovuProvider: ({ children, applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache, }: NovuProviderProps) => react_jsx_runtime.JSX.Element;
58
+ declare const useNovu: () => Novu;
59
+ declare const useUnsafeNovu: () => Novu | undefined;
60
+
61
+ type UseNotificationsProps = {
62
+ tags?: string[];
63
+ read?: boolean;
64
+ archived?: boolean;
65
+ limit?: number;
66
+ onSuccess?: (data: Notification$1[]) => void;
67
+ onError?: (error: NovuError) => void;
68
+ };
69
+ declare const useNotifications: (props?: UseNotificationsProps) => {
70
+ readAll: () => Promise<{
71
+ data?: void | undefined;
72
+ error?: NovuError | undefined;
73
+ }>;
74
+ archiveAll: () => Promise<{
75
+ data?: void | undefined;
76
+ error?: NovuError | undefined;
77
+ }>;
78
+ archiveAllRead: () => Promise<{
79
+ data?: void | undefined;
80
+ error?: NovuError | undefined;
81
+ }>;
82
+ notifications: Notification$1[] | undefined;
83
+ error: NovuError | undefined;
84
+ isLoading: boolean;
85
+ isFetching: boolean;
86
+ refetch: () => Promise<void>;
87
+ fetchMore: () => Promise<void>;
88
+ hasMore: boolean;
89
+ };
90
+
91
+ type UsePreferencesProps = {
92
+ onSuccess?: (data: Preference[]) => void;
93
+ onError?: (error: NovuError) => void;
94
+ };
95
+ type UsePreferencesResult = {
96
+ preferences?: Preference[];
97
+ error?: NovuError;
98
+ isLoading: boolean;
99
+ isFetching: boolean;
100
+ refetch: () => Promise<void>;
101
+ };
102
+ declare const usePreferences: (props?: UsePreferencesProps) => UsePreferencesResult;
103
+
104
+ type Count = {
105
+ count: number;
106
+ filter: NotificationFilter;
107
+ };
108
+ type UseCountsProps = {
109
+ filters: NotificationFilter[];
110
+ onSuccess?: (data: Count[]) => void;
111
+ onError?: (error: NovuError) => void;
112
+ };
113
+ type UseCountsResult = {
114
+ counts?: Count[];
115
+ error?: NovuError;
116
+ isLoading: boolean;
117
+ isFetching: boolean;
118
+ refetch: () => Promise<void>;
119
+ };
120
+ declare const useCounts: (props: UseCountsProps) => UseCountsResult;
121
+
122
+ export { type BaseProps, Bell, type BellProps, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, InboxChild, type InboxProps, type NotificationProps, Notifications, type NotificationsRenderer, NovuProvider, Preferences, type UseNotificationsProps, type WithChildrenProps, useCounts, useNotifications, useNovu, usePreferences, useUnsafeNovu };
@@ -32,8 +32,15 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  Bell: () => Bell,
34
34
  Inbox: () => Inbox,
35
+ InboxChild: () => InboxChild,
35
36
  Notifications: () => Notifications,
36
- Preferences: () => Preferences
37
+ NovuProvider: () => NovuProvider,
38
+ Preferences: () => Preferences,
39
+ useCounts: () => useCounts,
40
+ useNotifications: () => useNotifications,
41
+ useNovu: () => useNovu,
42
+ usePreferences: () => usePreferences,
43
+ useUnsafeNovu: () => useUnsafeNovu
37
44
  });
38
45
  module.exports = __toCommonJS(src_exports);
39
46
 
@@ -119,7 +126,7 @@ var import_react5 = require("react");
119
126
  var import_react_dom = __toESM(require("react-dom"));
120
127
  var import_ui = require("@novu/js/ui");
121
128
 
122
- // src/hooks/useDataRef.ts
129
+ // src/hooks/internal/useDataRef.ts
123
130
  var import_react4 = require("react");
124
131
  var useDataRef = (data) => {
125
132
  const ref = (0, import_react4.useRef)(data);
@@ -129,8 +136,8 @@ var useDataRef = (data) => {
129
136
 
130
137
  // src/components/Renderer.tsx
131
138
  var import_jsx_runtime4 = require("react/jsx-runtime");
132
- var Renderer = ({ options, children }) => {
133
- const optionsRef = useDataRef(options);
139
+ var Renderer = ({ options, novu, children }) => {
140
+ const optionsRef = useDataRef({ ...options, novu });
134
141
  const [novuUI, setNovuUI] = (0, import_react5.useState)();
135
142
  const [mountedElements, setMountedElements] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
136
143
  const mountElement = (0, import_react5.useCallback)(
@@ -151,10 +158,10 @@ var Renderer = ({ options, children }) => {
151
158
  [setMountedElements]
152
159
  );
153
160
  (0, import_react5.useEffect)(() => {
154
- const novu = new import_ui.NovuUI(optionsRef.current);
155
- setNovuUI(novu);
161
+ const novu2 = new import_ui.NovuUI(optionsRef.current);
162
+ setNovuUI(novu2);
156
163
  return () => {
157
- novu.unmount();
164
+ novu2.unmount();
158
165
  };
159
166
  }, []);
160
167
  (0, import_react5.useEffect)(() => {
@@ -203,6 +210,24 @@ var DefaultInbox = (props) => {
203
210
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Mounter, { mount });
204
211
  };
205
212
  var Inbox = import_react6.default.memo((props) => {
213
+ const { applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl } = props;
214
+ const novu = useUnsafeNovu();
215
+ if (novu) {
216
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InboxChild, { ...props });
217
+ }
218
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
219
+ NovuProvider,
220
+ {
221
+ applicationIdentifier,
222
+ subscriberId,
223
+ subscriberHash,
224
+ backendUrl,
225
+ socketUrl,
226
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InboxChild, { ...props })
227
+ }
228
+ );
229
+ });
230
+ var InboxChild = import_react6.default.memo((props) => {
206
231
  const {
207
232
  localization,
208
233
  appearance,
@@ -214,6 +239,7 @@ var Inbox = import_react6.default.memo((props) => {
214
239
  backendUrl,
215
240
  socketUrl
216
241
  } = props;
242
+ const novu = useNovu();
217
243
  const options = (0, import_react6.useMemo)(() => {
218
244
  return {
219
245
  localization,
@@ -224,10 +250,10 @@ var Inbox = import_react6.default.memo((props) => {
224
250
  };
225
251
  }, [localization, appearance, tabs, applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl]);
226
252
  if (isWithChildrenProps(props)) {
227
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Renderer, { options, children: props.children });
253
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Renderer, { options, novu, children: props.children });
228
254
  }
229
255
  const { open, renderNotification, renderBell, onNotificationClick, onPrimaryActionClick, onSecondaryActionClick } = props;
230
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Renderer, { options, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
256
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Renderer, { options, novu, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
231
257
  DefaultInbox,
232
258
  {
233
259
  open,
@@ -280,4 +306,325 @@ var Notifications = import_react8.default.memo((props) => {
280
306
  );
281
307
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Mounter, { mount });
282
308
  });
309
+
310
+ // src/hooks/NovuProvider.tsx
311
+ var import_js = require("@novu/js");
312
+ var import_react9 = require("react");
313
+ var import_jsx_runtime8 = require("react/jsx-runtime");
314
+ var NovuContext = (0, import_react9.createContext)(void 0);
315
+ var NovuProvider = ({
316
+ children,
317
+ applicationIdentifier,
318
+ subscriberId,
319
+ subscriberHash,
320
+ backendUrl,
321
+ socketUrl,
322
+ useCache
323
+ }) => {
324
+ const novu = (0, import_react9.useMemo)(
325
+ () => new import_js.Novu({ applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache }),
326
+ [applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache]
327
+ );
328
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NovuContext.Provider, { value: novu, children });
329
+ };
330
+ var useNovu = () => {
331
+ const context = (0, import_react9.useContext)(NovuContext);
332
+ if (!context) {
333
+ throw new Error("useNovu must be used within a <NovuProvider />");
334
+ }
335
+ return context;
336
+ };
337
+ var useUnsafeNovu = () => {
338
+ const context = (0, import_react9.useContext)(NovuContext);
339
+ return context;
340
+ };
341
+
342
+ // src/hooks/useNotifications.ts
343
+ var import_react10 = require("react");
344
+ var import_js2 = require("@novu/js");
345
+ var useNotifications = (props) => {
346
+ const { tags, read, archived = false, limit, onSuccess, onError } = props || {};
347
+ const filterRef = (0, import_react10.useRef)(void 0);
348
+ const { notifications, on, off } = useNovu();
349
+ const [data, setData] = (0, import_react10.useState)();
350
+ const [error, setError] = (0, import_react10.useState)();
351
+ const [isLoading, setIsLoading] = (0, import_react10.useState)(true);
352
+ const [isFetching, setIsFetching] = (0, import_react10.useState)(false);
353
+ const [hasMore, setHasMore] = (0, import_react10.useState)(false);
354
+ const length = data?.length;
355
+ const after = length ? data[length - 1].id : void 0;
356
+ const sync = (event) => {
357
+ if (!event.data || filterRef.current && !(0, import_js2.isSameFilter)(filterRef.current, event.data.filter)) {
358
+ return;
359
+ }
360
+ setData(event.data.notifications);
361
+ setHasMore(event.data.hasMore);
362
+ };
363
+ (0, import_react10.useEffect)(() => {
364
+ on("notifications.list.updated", sync);
365
+ return () => {
366
+ off("notifications.list.updated", sync);
367
+ };
368
+ }, []);
369
+ (0, import_react10.useEffect)(() => {
370
+ const newFilter = { tags, read, archived };
371
+ if (filterRef.current && (0, import_js2.isSameFilter)(filterRef.current, newFilter)) {
372
+ return;
373
+ }
374
+ notifications.clearCache({ filter: filterRef.current });
375
+ filterRef.current = newFilter;
376
+ fetchNotifications({ refetch: true });
377
+ }, [tags, read, archived]);
378
+ const fetchNotifications = async (options) => {
379
+ if (options?.refetch) {
380
+ setError(void 0);
381
+ setIsLoading(true);
382
+ setIsFetching(false);
383
+ }
384
+ setIsFetching(true);
385
+ const response = await notifications.list({
386
+ tags,
387
+ read,
388
+ archived,
389
+ limit,
390
+ after: options?.refetch ? void 0 : after
391
+ });
392
+ if (response.error) {
393
+ setError(response.error);
394
+ onError?.(response.error);
395
+ } else {
396
+ onSuccess?.(response.data.notifications);
397
+ setData(response.data.notifications);
398
+ setHasMore(response.data.hasMore);
399
+ }
400
+ setIsLoading(false);
401
+ setIsFetching(false);
402
+ };
403
+ const refetch = () => {
404
+ notifications.clearCache({ filter: { tags, read, archived } });
405
+ return fetchNotifications({ refetch: true });
406
+ };
407
+ const fetchMore = async () => {
408
+ if (!hasMore || isFetching) return;
409
+ return fetchNotifications();
410
+ };
411
+ const readAll = async () => {
412
+ return await notifications.readAll({ tags });
413
+ };
414
+ const archiveAll = async () => {
415
+ return await notifications.archiveAll({ tags });
416
+ };
417
+ const archiveAllRead = async () => {
418
+ return await notifications.archiveAllRead({ tags });
419
+ };
420
+ return {
421
+ readAll,
422
+ archiveAll,
423
+ archiveAllRead,
424
+ notifications: data,
425
+ error,
426
+ isLoading,
427
+ isFetching,
428
+ refetch,
429
+ fetchMore,
430
+ hasMore
431
+ };
432
+ };
433
+
434
+ // src/hooks/usePreferences.ts
435
+ var import_react11 = require("react");
436
+ var usePreferences = (props) => {
437
+ const { onSuccess, onError } = props || {};
438
+ const [data, setData] = (0, import_react11.useState)();
439
+ const { preferences, on, off } = useNovu();
440
+ const [error, setError] = (0, import_react11.useState)();
441
+ const [isLoading, setIsLoading] = (0, import_react11.useState)(true);
442
+ const [isFetching, setIsFetching] = (0, import_react11.useState)(false);
443
+ const sync = (event) => {
444
+ if (!event.data) {
445
+ return;
446
+ }
447
+ setData(event.data);
448
+ };
449
+ (0, import_react11.useEffect)(() => {
450
+ fetchPreferences();
451
+ on("preferences.list.updated", sync);
452
+ on("preferences.list.pending", sync);
453
+ on("preferences.list.resolved", sync);
454
+ return () => {
455
+ off("preferences.list.updated", sync);
456
+ off("preferences.list.pending", sync);
457
+ off("preferences.list.resolved", sync);
458
+ };
459
+ }, []);
460
+ const fetchPreferences = async () => {
461
+ setIsFetching(true);
462
+ const response = await preferences.list();
463
+ if (response.error) {
464
+ setError(response.error);
465
+ onError?.(response.error);
466
+ } else {
467
+ onSuccess?.(response.data);
468
+ }
469
+ setIsLoading(false);
470
+ setIsFetching(false);
471
+ };
472
+ const refetch = () => {
473
+ preferences.cache.clearAll();
474
+ return fetchPreferences();
475
+ };
476
+ return {
477
+ preferences: data,
478
+ error,
479
+ isLoading,
480
+ isFetching,
481
+ refetch
482
+ };
483
+ };
484
+
485
+ // src/hooks/useCounts.ts
486
+ var import_react14 = require("react");
487
+ var import_js3 = require("@novu/js");
488
+
489
+ // src/hooks/internal/useWebsocketEvent.ts
490
+ var import_react13 = require("react");
491
+
492
+ // src/utils/requestLock.ts
493
+ function requestLock(id, cb) {
494
+ if (!("locks" in navigator)) {
495
+ cb(id);
496
+ return () => {
497
+ };
498
+ }
499
+ let isFulfilled = false;
500
+ let promiseResolve;
501
+ const promise = new Promise((resolve) => {
502
+ promiseResolve = resolve;
503
+ });
504
+ navigator.locks.request(id, () => {
505
+ if (!isFulfilled) {
506
+ cb(id);
507
+ }
508
+ return promise;
509
+ });
510
+ return () => {
511
+ isFulfilled = true;
512
+ promiseResolve();
513
+ };
514
+ }
515
+
516
+ // src/hooks/internal/useBrowserTabsChannel.ts
517
+ var import_react12 = require("react");
518
+ var useBrowserTabsChannel = ({
519
+ channelName,
520
+ onMessage
521
+ }) => {
522
+ const [tabsChannel] = (0, import_react12.useState)(
523
+ typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelName) : void 0
524
+ );
525
+ const postMessage = (data) => {
526
+ tabsChannel?.postMessage(data);
527
+ };
528
+ (0, import_react12.useEffect)(() => {
529
+ const listener = (event) => {
530
+ onMessage(event.data);
531
+ };
532
+ tabsChannel?.addEventListener("message", listener);
533
+ return () => {
534
+ tabsChannel?.removeEventListener("message", listener);
535
+ };
536
+ }, []);
537
+ return { postMessage };
538
+ };
539
+
540
+ // src/hooks/internal/useWebsocketEvent.ts
541
+ var useWebSocketEvent = ({
542
+ event: webSocketEvent,
543
+ eventHandler: onMessage
544
+ }) => {
545
+ const novu = useNovu();
546
+ const { postMessage } = useBrowserTabsChannel({ channelName: `nv.${webSocketEvent}`, onMessage });
547
+ const updateReadCount = (data) => {
548
+ onMessage(data);
549
+ postMessage(data);
550
+ };
551
+ (0, import_react13.useEffect)(() => {
552
+ const resolveLock = requestLock(`nv.${webSocketEvent}`, () => {
553
+ novu.on(webSocketEvent, updateReadCount);
554
+ });
555
+ return () => {
556
+ novu.off(webSocketEvent, updateReadCount);
557
+ resolveLock();
558
+ };
559
+ }, []);
560
+ };
561
+
562
+ // src/hooks/useCounts.ts
563
+ var useCounts = (props) => {
564
+ const { filters, onSuccess, onError } = props;
565
+ const { notifications } = useNovu();
566
+ const [error, setError] = (0, import_react14.useState)();
567
+ const [counts, setCounts] = (0, import_react14.useState)();
568
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
569
+ const [isFetching, setIsFetching] = (0, import_react14.useState)(false);
570
+ const sync = async (notification) => {
571
+ const existingCounts = counts ?? new Array(filters.length).fill(void 0);
572
+ let countFiltersToFetch = [];
573
+ if (notification) {
574
+ for (let i = 0; i < existingCounts.length; i++) {
575
+ const filter = filters[i];
576
+ if ((0, import_js3.areTagsEqual)(filter.tags, notification.tags)) {
577
+ countFiltersToFetch.push(filter);
578
+ }
579
+ }
580
+ } else {
581
+ countFiltersToFetch = filters;
582
+ }
583
+ if (countFiltersToFetch.length === 0) {
584
+ return;
585
+ }
586
+ setIsFetching(true);
587
+ const countsRes = await notifications.count({ filters: countFiltersToFetch });
588
+ setIsFetching(false);
589
+ setIsLoading(false);
590
+ if (countsRes.error) {
591
+ setError(countsRes.error);
592
+ onError?.(countsRes.error);
593
+ return;
594
+ }
595
+ const data = countsRes.data;
596
+ onSuccess?.(data.counts);
597
+ setCounts((oldCounts) => {
598
+ const newCounts = [];
599
+ const countsReceived = data.counts;
600
+ for (let i = 0; i < existingCounts.length; i++) {
601
+ const countReceived = countsReceived.find((c) => (0, import_js3.areTagsEqual)(c.filter.tags, existingCounts[i]?.filter.tags));
602
+ newCounts.push(countReceived || oldCounts[i]);
603
+ }
604
+ return newCounts;
605
+ });
606
+ };
607
+ useWebSocketEvent({
608
+ event: "notifications.notification_received",
609
+ eventHandler: (data) => {
610
+ sync(data.result);
611
+ }
612
+ });
613
+ useWebSocketEvent({
614
+ event: "notifications.unread_count_changed",
615
+ eventHandler: () => {
616
+ sync();
617
+ }
618
+ });
619
+ (0, import_react14.useEffect)(() => {
620
+ setError(void 0);
621
+ setIsLoading(true);
622
+ setIsFetching(false);
623
+ sync();
624
+ }, [JSON.stringify(filters)]);
625
+ const refetch = async () => {
626
+ await sync();
627
+ };
628
+ return { counts, error, refetch, isLoading, isFetching };
629
+ };
283
630
  //# sourceMappingURL=index.js.map