@novu/react 2.0.0-canary.3 → 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.
@@ -0,0 +1,326 @@
1
+ // src/hooks/useNotifications.ts
2
+ import { useState, useEffect, useRef } from "react";
3
+ import { isSameFilter } from "@novu/js";
4
+
5
+ // src/hooks/NovuProvider.tsx
6
+ import { Novu } from "@novu/js";
7
+ import { createContext, useContext, useMemo } from "react";
8
+ import { jsx } from "react/jsx-runtime";
9
+ var NovuContext = createContext(void 0);
10
+ var NovuProvider = ({
11
+ children,
12
+ applicationIdentifier,
13
+ subscriberId,
14
+ subscriberHash,
15
+ backendUrl,
16
+ socketUrl,
17
+ useCache
18
+ }) => {
19
+ const novu = useMemo(
20
+ () => new Novu({ applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache }),
21
+ [applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache]
22
+ );
23
+ return /* @__PURE__ */ jsx(NovuContext.Provider, { value: novu, children });
24
+ };
25
+ var useNovu = () => {
26
+ const context = useContext(NovuContext);
27
+ if (!context) {
28
+ throw new Error("useNovu must be used within a <NovuProvider />");
29
+ }
30
+ return context;
31
+ };
32
+
33
+ // src/hooks/useNotifications.ts
34
+ var useNotifications = (props) => {
35
+ const { tags, read, archived = false, limit, onSuccess, onError } = props || {};
36
+ const filterRef = useRef(void 0);
37
+ const { notifications, on, off } = useNovu();
38
+ const [data, setData] = useState();
39
+ const [error, setError] = useState();
40
+ const [isLoading, setIsLoading] = useState(true);
41
+ const [isFetching, setIsFetching] = useState(false);
42
+ const [hasMore, setHasMore] = useState(false);
43
+ const length = data?.length;
44
+ const after = length ? data[length - 1].id : void 0;
45
+ const sync = (event) => {
46
+ if (!event.data || filterRef.current && !isSameFilter(filterRef.current, event.data.filter)) {
47
+ return;
48
+ }
49
+ setData(event.data.notifications);
50
+ setHasMore(event.data.hasMore);
51
+ };
52
+ useEffect(() => {
53
+ on("notifications.list.updated", sync);
54
+ return () => {
55
+ off("notifications.list.updated", sync);
56
+ };
57
+ }, []);
58
+ useEffect(() => {
59
+ const newFilter = { tags, read, archived };
60
+ if (filterRef.current && isSameFilter(filterRef.current, newFilter)) {
61
+ return;
62
+ }
63
+ notifications.clearCache({ filter: filterRef.current });
64
+ filterRef.current = newFilter;
65
+ fetchNotifications({ refetch: true });
66
+ }, [tags, read, archived]);
67
+ const fetchNotifications = async (options) => {
68
+ if (options?.refetch) {
69
+ setError(void 0);
70
+ setIsLoading(true);
71
+ setIsFetching(false);
72
+ }
73
+ setIsFetching(true);
74
+ const response = await notifications.list({
75
+ tags,
76
+ read,
77
+ archived,
78
+ limit,
79
+ after: options?.refetch ? void 0 : after
80
+ });
81
+ if (response.error) {
82
+ setError(response.error);
83
+ onError?.(response.error);
84
+ } else {
85
+ onSuccess?.(response.data.notifications);
86
+ setData(response.data.notifications);
87
+ setHasMore(response.data.hasMore);
88
+ }
89
+ setIsLoading(false);
90
+ setIsFetching(false);
91
+ };
92
+ const refetch = () => {
93
+ notifications.clearCache({ filter: { tags, read, archived } });
94
+ return fetchNotifications({ refetch: true });
95
+ };
96
+ const fetchMore = async () => {
97
+ if (!hasMore || isFetching) return;
98
+ return fetchNotifications();
99
+ };
100
+ const readAll = async () => {
101
+ return await notifications.readAll({ tags });
102
+ };
103
+ const archiveAll = async () => {
104
+ return await notifications.archiveAll({ tags });
105
+ };
106
+ const archiveAllRead = async () => {
107
+ return await notifications.archiveAllRead({ tags });
108
+ };
109
+ return {
110
+ readAll,
111
+ archiveAll,
112
+ archiveAllRead,
113
+ notifications: data,
114
+ error,
115
+ isLoading,
116
+ isFetching,
117
+ refetch,
118
+ fetchMore,
119
+ hasMore
120
+ };
121
+ };
122
+
123
+ // src/hooks/usePreferences.ts
124
+ import { useEffect as useEffect2, useState as useState2 } from "react";
125
+ var usePreferences = (props) => {
126
+ const { onSuccess, onError } = props || {};
127
+ const [data, setData] = useState2();
128
+ const { preferences, on, off } = useNovu();
129
+ const [error, setError] = useState2();
130
+ const [isLoading, setIsLoading] = useState2(true);
131
+ const [isFetching, setIsFetching] = useState2(false);
132
+ const sync = (event) => {
133
+ if (!event.data) {
134
+ return;
135
+ }
136
+ setData(event.data);
137
+ };
138
+ useEffect2(() => {
139
+ fetchPreferences();
140
+ on("preferences.list.updated", sync);
141
+ on("preferences.list.pending", sync);
142
+ on("preferences.list.resolved", sync);
143
+ return () => {
144
+ off("preferences.list.updated", sync);
145
+ off("preferences.list.pending", sync);
146
+ off("preferences.list.resolved", sync);
147
+ };
148
+ }, []);
149
+ const fetchPreferences = async () => {
150
+ setIsFetching(true);
151
+ const response = await preferences.list();
152
+ if (response.error) {
153
+ setError(response.error);
154
+ onError?.(response.error);
155
+ } else {
156
+ onSuccess?.(response.data);
157
+ }
158
+ setIsLoading(false);
159
+ setIsFetching(false);
160
+ };
161
+ const refetch = () => {
162
+ preferences.cache.clearAll();
163
+ return fetchPreferences();
164
+ };
165
+ return {
166
+ preferences: data,
167
+ error,
168
+ isLoading,
169
+ isFetching,
170
+ refetch
171
+ };
172
+ };
173
+
174
+ // src/hooks/useCounts.ts
175
+ import { useEffect as useEffect5, useState as useState4 } from "react";
176
+ import { areTagsEqual } from "@novu/js";
177
+
178
+ // src/hooks/internal/useWebsocketEvent.ts
179
+ import { useEffect as useEffect4 } from "react";
180
+
181
+ // src/utils/requestLock.ts
182
+ function requestLock(id, cb) {
183
+ if (!("locks" in navigator)) {
184
+ cb(id);
185
+ return () => {
186
+ };
187
+ }
188
+ let isFulfilled = false;
189
+ let promiseResolve;
190
+ const promise = new Promise((resolve) => {
191
+ promiseResolve = resolve;
192
+ });
193
+ navigator.locks.request(id, () => {
194
+ if (!isFulfilled) {
195
+ cb(id);
196
+ }
197
+ return promise;
198
+ });
199
+ return () => {
200
+ isFulfilled = true;
201
+ promiseResolve();
202
+ };
203
+ }
204
+
205
+ // src/hooks/internal/useBrowserTabsChannel.ts
206
+ import { useEffect as useEffect3, useState as useState3 } from "react";
207
+ var useBrowserTabsChannel = ({
208
+ channelName,
209
+ onMessage
210
+ }) => {
211
+ const [tabsChannel] = useState3(
212
+ typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelName) : void 0
213
+ );
214
+ const postMessage = (data) => {
215
+ tabsChannel?.postMessage(data);
216
+ };
217
+ useEffect3(() => {
218
+ const listener = (event) => {
219
+ onMessage(event.data);
220
+ };
221
+ tabsChannel?.addEventListener("message", listener);
222
+ return () => {
223
+ tabsChannel?.removeEventListener("message", listener);
224
+ };
225
+ }, []);
226
+ return { postMessage };
227
+ };
228
+
229
+ // src/hooks/internal/useWebsocketEvent.ts
230
+ var useWebSocketEvent = ({
231
+ event: webSocketEvent,
232
+ eventHandler: onMessage
233
+ }) => {
234
+ const novu = useNovu();
235
+ const { postMessage } = useBrowserTabsChannel({ channelName: `nv.${webSocketEvent}`, onMessage });
236
+ const updateReadCount = (data) => {
237
+ onMessage(data);
238
+ postMessage(data);
239
+ };
240
+ useEffect4(() => {
241
+ const resolveLock = requestLock(`nv.${webSocketEvent}`, () => {
242
+ novu.on(webSocketEvent, updateReadCount);
243
+ });
244
+ return () => {
245
+ novu.off(webSocketEvent, updateReadCount);
246
+ resolveLock();
247
+ };
248
+ }, []);
249
+ };
250
+
251
+ // src/hooks/useCounts.ts
252
+ var useCounts = (props) => {
253
+ const { filters, onSuccess, onError } = props;
254
+ const { notifications } = useNovu();
255
+ const [error, setError] = useState4();
256
+ const [counts, setCounts] = useState4();
257
+ const [isLoading, setIsLoading] = useState4(true);
258
+ const [isFetching, setIsFetching] = useState4(false);
259
+ const sync = async (notification) => {
260
+ const existingCounts = counts ?? new Array(filters.length).fill(void 0);
261
+ let countFiltersToFetch = [];
262
+ if (notification) {
263
+ for (let i = 0; i < existingCounts.length; i++) {
264
+ const filter = filters[i];
265
+ if (areTagsEqual(filter.tags, notification.tags)) {
266
+ countFiltersToFetch.push(filter);
267
+ }
268
+ }
269
+ } else {
270
+ countFiltersToFetch = filters;
271
+ }
272
+ if (countFiltersToFetch.length === 0) {
273
+ return;
274
+ }
275
+ setIsFetching(true);
276
+ const countsRes = await notifications.count({ filters: countFiltersToFetch });
277
+ setIsFetching(false);
278
+ setIsLoading(false);
279
+ if (countsRes.error) {
280
+ setError(countsRes.error);
281
+ onError?.(countsRes.error);
282
+ return;
283
+ }
284
+ const data = countsRes.data;
285
+ onSuccess?.(data.counts);
286
+ setCounts((oldCounts) => {
287
+ const newCounts = [];
288
+ const countsReceived = data.counts;
289
+ for (let i = 0; i < existingCounts.length; i++) {
290
+ const countReceived = countsReceived.find((c) => areTagsEqual(c.filter.tags, existingCounts[i]?.filter.tags));
291
+ newCounts.push(countReceived || oldCounts[i]);
292
+ }
293
+ return newCounts;
294
+ });
295
+ };
296
+ useWebSocketEvent({
297
+ event: "notifications.notification_received",
298
+ eventHandler: (data) => {
299
+ sync(data.result);
300
+ }
301
+ });
302
+ useWebSocketEvent({
303
+ event: "notifications.unread_count_changed",
304
+ eventHandler: () => {
305
+ sync();
306
+ }
307
+ });
308
+ useEffect5(() => {
309
+ setError(void 0);
310
+ setIsLoading(true);
311
+ setIsFetching(false);
312
+ sync();
313
+ }, [JSON.stringify(filters)]);
314
+ const refetch = async () => {
315
+ await sync();
316
+ };
317
+ return { counts, error, refetch, isLoading, isFetching };
318
+ };
319
+ export {
320
+ NovuProvider,
321
+ useCounts,
322
+ useNotifications,
323
+ useNovu,
324
+ usePreferences
325
+ };
326
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/useNotifications.ts","../../src/hooks/NovuProvider.tsx","../../src/hooks/usePreferences.ts","../../src/hooks/useCounts.ts","../../src/hooks/internal/useWebsocketEvent.ts","../../src/utils/requestLock.ts","../../src/hooks/internal/useBrowserTabsChannel.ts"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { ListNotificationsResponse, Notification, NovuError, isSameFilter, NotificationFilter } from '@novu/js';\nimport { useNovu } from './NovuProvider';\n\nexport type UseNotificationsProps = {\n tags?: string[];\n read?: boolean;\n archived?: boolean;\n limit?: number;\n onSuccess?: (data: Notification[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport const useNotifications = (props?: UseNotificationsProps) => {\n const { tags, read, archived = false, limit, onSuccess, onError } = props || {};\n const filterRef = useRef<NotificationFilter | undefined>(undefined);\n const { notifications, on, off } = useNovu();\n const [data, setData] = useState<Array<Notification>>();\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const length = data?.length;\n const after = length ? data[length - 1].id : undefined;\n\n const sync = (event: { data?: ListNotificationsResponse }) => {\n if (!event.data || (filterRef.current && !isSameFilter(filterRef.current, event.data.filter))) {\n return;\n }\n setData(event.data.notifications);\n setHasMore(event.data.hasMore);\n };\n\n useEffect(() => {\n on('notifications.list.updated', sync);\n\n return () => {\n off('notifications.list.updated', sync);\n };\n }, []);\n\n useEffect(() => {\n const newFilter = { tags, read, archived };\n if (filterRef.current && isSameFilter(filterRef.current, newFilter)) {\n return;\n }\n\n notifications.clearCache({ filter: filterRef.current });\n filterRef.current = newFilter;\n\n fetchNotifications({ refetch: true });\n }, [tags, read, archived]);\n\n const fetchNotifications = async (options?: { refetch: boolean }) => {\n if (options?.refetch) {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n }\n setIsFetching(true);\n const response = await notifications.list({\n tags,\n read,\n archived,\n limit,\n after: options?.refetch ? undefined : after,\n });\n if (response.error) {\n setError(response.error);\n onError?.(response.error);\n } else {\n onSuccess?.(response.data!.notifications);\n setData(response.data!.notifications);\n setHasMore(response.data!.hasMore);\n }\n setIsLoading(false);\n setIsFetching(false);\n };\n\n const refetch = () => {\n notifications.clearCache({ filter: { tags, read, archived } });\n\n return fetchNotifications({ refetch: true });\n };\n\n const fetchMore = async () => {\n if (!hasMore || isFetching) return;\n\n return fetchNotifications();\n };\n\n const readAll = async () => {\n return await notifications.readAll({ tags });\n };\n\n const archiveAll = async () => {\n return await notifications.archiveAll({ tags });\n };\n\n const archiveAllRead = async () => {\n return await notifications.archiveAllRead({ tags });\n };\n\n return {\n readAll,\n archiveAll,\n archiveAllRead,\n notifications: data,\n error,\n isLoading,\n isFetching,\n refetch,\n fetchMore,\n hasMore,\n };\n};\n","import { Novu, NovuOptions } from '@novu/js';\nimport { ReactNode, createContext, useContext, useMemo } from 'react';\n\ntype NovuProviderProps = NovuOptions & {\n children: ReactNode;\n};\n\nconst NovuContext = createContext<Novu | undefined>(undefined);\n\nexport const NovuProvider = ({\n children,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n useCache,\n}: NovuProviderProps) => {\n const novu = useMemo(\n () => new Novu({ applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache }),\n [applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache]\n );\n\n return <NovuContext.Provider value={novu}>{children}</NovuContext.Provider>;\n};\n\nexport const useNovu = () => {\n const context = useContext(NovuContext);\n if (!context) {\n throw new Error('useNovu must be used within a <NovuProvider />');\n }\n\n return context;\n};\n\nexport const useUnsafeNovu = () => {\n const context = useContext(NovuContext);\n\n return context;\n};\n","import { NovuError, Preference } from '@novu/js';\nimport { useEffect, useState } from 'react';\nimport { useNovu } from './NovuProvider';\n\ntype UsePreferencesProps = {\n onSuccess?: (data: Preference[]) => void;\n onError?: (error: NovuError) => void;\n};\n\ntype UsePreferencesResult = {\n preferences?: Preference[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const usePreferences = (props?: UsePreferencesProps): UsePreferencesResult => {\n const { onSuccess, onError } = props || {};\n const [data, setData] = useState<Preference[]>();\n const { preferences, on, off } = useNovu();\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = (event: { data?: Preference[] }) => {\n if (!event.data) {\n return;\n }\n setData(event.data);\n };\n\n useEffect(() => {\n fetchPreferences();\n\n on('preferences.list.updated', sync);\n on('preferences.list.pending', sync);\n on('preferences.list.resolved', sync);\n\n return () => {\n off('preferences.list.updated', sync);\n off('preferences.list.pending', sync);\n off('preferences.list.resolved', sync);\n };\n }, []);\n\n const fetchPreferences = async () => {\n setIsFetching(true);\n const response = await preferences.list();\n if (response.error) {\n setError(response.error);\n onError?.(response.error);\n } else {\n onSuccess?.(response.data!);\n }\n setIsLoading(false);\n setIsFetching(false);\n };\n\n const refetch = () => {\n preferences.cache.clearAll();\n return fetchPreferences();\n };\n\n return {\n preferences: data,\n error,\n isLoading,\n isFetching,\n refetch,\n };\n};\n","import { useEffect, useState } from 'react';\nimport { Notification, NotificationFilter, NovuError, areTagsEqual } from '@novu/js';\nimport { useNovu } from './NovuProvider';\nimport { useWebSocketEvent } from './internal/useWebsocketEvent';\n\ntype Count = {\n count: number;\n filter: NotificationFilter;\n};\n\ntype UseCountsProps = {\n filters: NotificationFilter[];\n onSuccess?: (data: Count[]) => void;\n onError?: (error: NovuError) => void;\n};\n\ntype UseCountsResult = {\n counts?: Count[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const useCounts = (props: UseCountsProps): UseCountsResult => {\n const { filters, onSuccess, onError } = props;\n const { notifications } = useNovu();\n const [error, setError] = useState<NovuError>();\n const [counts, setCounts] = useState<Count[]>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = async (notification?: Notification) => {\n const existingCounts = counts ?? (new Array(filters.length).fill(undefined) as (Count | undefined)[]);\n let countFiltersToFetch: NotificationFilter[] = [];\n if (notification) {\n // eslint-disable-next-line no-plusplus\n for (let i = 0; i < existingCounts.length; i++) {\n const filter = filters[i];\n if (areTagsEqual(filter.tags, notification.tags)) {\n countFiltersToFetch.push(filter);\n }\n }\n } else {\n countFiltersToFetch = filters;\n }\n\n if (countFiltersToFetch.length === 0) {\n return;\n }\n\n setIsFetching(true);\n const countsRes = await notifications.count({ filters: countFiltersToFetch });\n setIsFetching(false);\n setIsLoading(false);\n if (countsRes.error) {\n setError(countsRes.error);\n onError?.(countsRes.error);\n\n return;\n }\n const data = countsRes.data!;\n onSuccess?.(data.counts);\n\n setCounts((oldCounts) => {\n const newCounts: Count[] = [];\n const countsReceived = data.counts;\n\n // eslint-disable-next-line no-plusplus\n for (let i = 0; i < existingCounts.length; i++) {\n const countReceived = countsReceived.find((c) => areTagsEqual(c.filter.tags, existingCounts[i]?.filter.tags));\n\n newCounts.push(countReceived || oldCounts![i]);\n }\n\n return newCounts;\n });\n };\n\n useWebSocketEvent({\n event: 'notifications.notification_received',\n eventHandler: (data) => {\n sync(data.result);\n },\n });\n\n useWebSocketEvent({\n event: 'notifications.unread_count_changed',\n eventHandler: () => {\n sync();\n },\n });\n\n useEffect(() => {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n sync();\n }, [JSON.stringify(filters)]);\n\n const refetch = async () => {\n await sync();\n };\n\n return { counts, error, refetch, isLoading, isFetching };\n};\n","import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { useNovu } from '../NovuProvider';\nimport { requestLock } from '../../utils/requestLock';\nimport { useBrowserTabsChannel } from './useBrowserTabsChannel';\n\nexport const useWebSocketEvent = <E extends SocketEventNames>({\n event: webSocketEvent,\n eventHandler: onMessage,\n}: {\n event: E;\n eventHandler: (args: Events[E]) => void;\n}) => {\n const novu = useNovu();\n const { postMessage } = useBrowserTabsChannel({ channelName: `nv.${webSocketEvent}`, onMessage });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n const resolveLock = requestLock(`nv.${webSocketEvent}`, () => {\n novu.on(webSocketEvent, updateReadCount);\n });\n\n return () => {\n novu.off(webSocketEvent, updateReadCount);\n resolveLock();\n };\n }, []);\n};\n","export function requestLock(id: string, cb: (id: string) => void) {\n // Check if the Lock API is available\n if (!('locks' in navigator)) {\n // If Lock API is not available, immediately invoke the callback and return a no-op function\n cb(id);\n return () => {};\n }\n\n let isFulfilled = false;\n let promiseResolve: () => void;\n\n const promise = new Promise<void>((resolve) => {\n promiseResolve = resolve;\n });\n\n navigator.locks.request(id, () => {\n if (!isFulfilled) {\n cb(id);\n }\n\n return promise;\n });\n\n return () => {\n isFulfilled = true;\n promiseResolve();\n };\n}\n","import { useEffect, useState } from 'react';\n\nexport const useBrowserTabsChannel = <T = unknown>({\n channelName,\n onMessage,\n}: {\n channelName: string;\n onMessage: (args: T) => void;\n}) => {\n const [tabsChannel] = useState(\n typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(channelName) : undefined\n );\n\n const postMessage = (data: T) => {\n tabsChannel?.postMessage(data);\n };\n\n useEffect(() => {\n const listener = (event: MessageEvent<T>) => {\n onMessage(event.data);\n };\n\n tabsChannel?.addEventListener('message', listener);\n\n return () => {\n tabsChannel?.removeEventListener('message', listener);\n };\n }, []);\n\n return { postMessage };\n};\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","useEffect","useState","useEffect","useEffect","useState","useEffect","useState","useEffect"]}
@@ -1,5 +1,8 @@
1
- import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab } from '@novu/js/ui';
1
+ import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab, RouterPush } from '@novu/js/ui';
2
2
  export { Notification } from '@novu/js/ui';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Novu, NovuOptions, Notification as Notification$1, NovuError, Preference, NotificationFilter } from '@novu/js';
5
+ import { ReactNode } from 'react';
3
6
 
4
7
  type NotificationsRenderer = (notification: Notification) => React.ReactNode;
5
8
  type BellRenderer = (unreadCount: number) => React.ReactNode;
@@ -20,6 +23,7 @@ type BaseProps = {
20
23
  appearance?: Appearance;
21
24
  localization?: Localization;
22
25
  tabs?: Array<Tab>;
26
+ routerPush?: RouterPush;
23
27
  };
24
28
  type DefaultProps = BaseProps & DefaultInboxProps & {
25
29
  children?: never;
@@ -28,6 +32,73 @@ type WithChildrenProps = BaseProps & {
28
32
  children: React.ReactNode;
29
33
  };
30
34
 
35
+ type NovuProviderProps = NovuOptions & {
36
+ children: ReactNode;
37
+ };
38
+ declare const NovuProvider: ({ children, applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache, }: NovuProviderProps) => react_jsx_runtime.JSX.Element;
39
+ declare const useNovu: () => Novu;
40
+
41
+ type UseNotificationsProps = {
42
+ tags?: string[];
43
+ read?: boolean;
44
+ archived?: boolean;
45
+ limit?: number;
46
+ onSuccess?: (data: Notification$1[]) => void;
47
+ onError?: (error: NovuError) => void;
48
+ };
49
+ declare const useNotifications: (props?: UseNotificationsProps) => {
50
+ readAll: () => Promise<{
51
+ data?: void | undefined;
52
+ error?: NovuError | undefined;
53
+ }>;
54
+ archiveAll: () => Promise<{
55
+ data?: void | undefined;
56
+ error?: NovuError | undefined;
57
+ }>;
58
+ archiveAllRead: () => Promise<{
59
+ data?: void | undefined;
60
+ error?: NovuError | undefined;
61
+ }>;
62
+ notifications: Notification$1[] | undefined;
63
+ error: NovuError | undefined;
64
+ isLoading: boolean;
65
+ isFetching: boolean;
66
+ refetch: () => Promise<void>;
67
+ fetchMore: () => Promise<void>;
68
+ hasMore: boolean;
69
+ };
70
+
71
+ type UsePreferencesProps = {
72
+ onSuccess?: (data: Preference[]) => void;
73
+ onError?: (error: NovuError) => void;
74
+ };
75
+ type UsePreferencesResult = {
76
+ preferences?: Preference[];
77
+ error?: NovuError;
78
+ isLoading: boolean;
79
+ isFetching: boolean;
80
+ refetch: () => Promise<void>;
81
+ };
82
+ declare const usePreferences: (props?: UsePreferencesProps) => UsePreferencesResult;
83
+
84
+ type Count = {
85
+ count: number;
86
+ filter: NotificationFilter;
87
+ };
88
+ type UseCountsProps = {
89
+ filters: NotificationFilter[];
90
+ onSuccess?: (data: Count[]) => void;
91
+ onError?: (error: NovuError) => void;
92
+ };
93
+ type UseCountsResult = {
94
+ counts?: Count[];
95
+ error?: NovuError;
96
+ isLoading: boolean;
97
+ isFetching: boolean;
98
+ refetch: () => Promise<void>;
99
+ };
100
+ declare const useCounts: (props: UseCountsProps) => UseCountsResult;
101
+
31
102
  /**
32
103
  * Exporting all components from the components folder
33
104
  * as empty functions to fix build errors in SSR
@@ -39,4 +110,4 @@ declare function Notifications(): void;
39
110
  declare function Preferences(): void;
40
111
  declare function Bell(): void;
41
112
 
42
- export { type BaseProps, Bell, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, Notifications, type NotificationsRenderer, Preferences, type WithChildrenProps };
113
+ export { type BaseProps, Bell, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, Notifications, type NotificationsRenderer, NovuProvider, Preferences, type UseNotificationsProps, type WithChildrenProps, useCounts, useNotifications, useNovu, usePreferences };
@@ -1,5 +1,8 @@
1
- import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab } from '@novu/js/ui';
1
+ import { Notification, NotificationClickHandler, NotificationActionClickHandler, Appearance, Localization, Tab, RouterPush } from '@novu/js/ui';
2
2
  export { Notification } from '@novu/js/ui';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Novu, NovuOptions, Notification as Notification$1, NovuError, Preference, NotificationFilter } from '@novu/js';
5
+ import { ReactNode } from 'react';
3
6
 
4
7
  type NotificationsRenderer = (notification: Notification) => React.ReactNode;
5
8
  type BellRenderer = (unreadCount: number) => React.ReactNode;
@@ -20,6 +23,7 @@ type BaseProps = {
20
23
  appearance?: Appearance;
21
24
  localization?: Localization;
22
25
  tabs?: Array<Tab>;
26
+ routerPush?: RouterPush;
23
27
  };
24
28
  type DefaultProps = BaseProps & DefaultInboxProps & {
25
29
  children?: never;
@@ -28,6 +32,73 @@ type WithChildrenProps = BaseProps & {
28
32
  children: React.ReactNode;
29
33
  };
30
34
 
35
+ type NovuProviderProps = NovuOptions & {
36
+ children: ReactNode;
37
+ };
38
+ declare const NovuProvider: ({ children, applicationIdentifier, subscriberId, subscriberHash, backendUrl, socketUrl, useCache, }: NovuProviderProps) => react_jsx_runtime.JSX.Element;
39
+ declare const useNovu: () => Novu;
40
+
41
+ type UseNotificationsProps = {
42
+ tags?: string[];
43
+ read?: boolean;
44
+ archived?: boolean;
45
+ limit?: number;
46
+ onSuccess?: (data: Notification$1[]) => void;
47
+ onError?: (error: NovuError) => void;
48
+ };
49
+ declare const useNotifications: (props?: UseNotificationsProps) => {
50
+ readAll: () => Promise<{
51
+ data?: void | undefined;
52
+ error?: NovuError | undefined;
53
+ }>;
54
+ archiveAll: () => Promise<{
55
+ data?: void | undefined;
56
+ error?: NovuError | undefined;
57
+ }>;
58
+ archiveAllRead: () => Promise<{
59
+ data?: void | undefined;
60
+ error?: NovuError | undefined;
61
+ }>;
62
+ notifications: Notification$1[] | undefined;
63
+ error: NovuError | undefined;
64
+ isLoading: boolean;
65
+ isFetching: boolean;
66
+ refetch: () => Promise<void>;
67
+ fetchMore: () => Promise<void>;
68
+ hasMore: boolean;
69
+ };
70
+
71
+ type UsePreferencesProps = {
72
+ onSuccess?: (data: Preference[]) => void;
73
+ onError?: (error: NovuError) => void;
74
+ };
75
+ type UsePreferencesResult = {
76
+ preferences?: Preference[];
77
+ error?: NovuError;
78
+ isLoading: boolean;
79
+ isFetching: boolean;
80
+ refetch: () => Promise<void>;
81
+ };
82
+ declare const usePreferences: (props?: UsePreferencesProps) => UsePreferencesResult;
83
+
84
+ type Count = {
85
+ count: number;
86
+ filter: NotificationFilter;
87
+ };
88
+ type UseCountsProps = {
89
+ filters: NotificationFilter[];
90
+ onSuccess?: (data: Count[]) => void;
91
+ onError?: (error: NovuError) => void;
92
+ };
93
+ type UseCountsResult = {
94
+ counts?: Count[];
95
+ error?: NovuError;
96
+ isLoading: boolean;
97
+ isFetching: boolean;
98
+ refetch: () => Promise<void>;
99
+ };
100
+ declare const useCounts: (props: UseCountsProps) => UseCountsResult;
101
+
31
102
  /**
32
103
  * Exporting all components from the components folder
33
104
  * as empty functions to fix build errors in SSR
@@ -39,4 +110,4 @@ declare function Notifications(): void;
39
110
  declare function Preferences(): void;
40
111
  declare function Bell(): void;
41
112
 
42
- export { type BaseProps, Bell, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, Notifications, type NotificationsRenderer, Preferences, type WithChildrenProps };
113
+ export { type BaseProps, Bell, type BellRenderer, type DefaultInboxProps, type DefaultProps, Inbox, Notifications, type NotificationsRenderer, NovuProvider, Preferences, type UseNotificationsProps, type WithChildrenProps, useCounts, useNotifications, useNovu, usePreferences };