@notificationapi/react 1.6.2 → 1.7.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,3 +1,2 @@
1
1
  import { ReactNode } from 'react';
2
-
3
2
  export declare const DefaultEmptyComponent: ReactNode;
@@ -2,7 +2,6 @@ import { default as React } from 'react';
2
2
  import { InboxHeaderProps } from './InboxHeader';
3
3
  import { NotificationPopupProps } from './NotificationPopup';
4
4
  import { InAppNotification } from '@notificationapi/core/dist/interfaces';
5
-
6
5
  export type InboxProps = {
7
6
  pagination: unknown;
8
7
  maxHeight: number;
@@ -1,6 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { InAppNotification } from '@notificationapi/core/dist/interfaces';
3
-
4
3
  export type NotificationProps = {
5
4
  notifications: InAppNotification[];
6
5
  markAsArchived: (ids: string[] | 'ALL') => void;
@@ -1,6 +1,5 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { UnreadBadgeProps } from './UnreadBadge';
3
-
4
3
  export type NotificationCounterProps = Omit<UnreadBadgeProps, 'count'> & {
5
4
  count?: UnreadBadgeProps['count'];
6
5
  };
@@ -2,7 +2,6 @@ import { NotificationProps } from './Notification';
2
2
  import { InboxHeaderProps } from './InboxHeader';
3
3
  import { InAppNotification } from '@notificationapi/core/dist/interfaces';
4
4
  import { Filter, Pagination } from './interface';
5
-
6
5
  export type NotificationFeedProps = {
7
6
  pagination?: keyof typeof Pagination;
8
7
  pageSize?: number;
@@ -1,6 +1,5 @@
1
1
  import { NotificationPopupProps } from './NotificationPopup';
2
2
  import { Position } from './interface';
3
-
4
3
  type NotificationLaucherProps = NotificationPopupProps & {
5
4
  position?: keyof typeof Position;
6
5
  offsetX?: number | string;
@@ -4,7 +4,6 @@ import { NotificationProps } from './Notification';
4
4
  import { InAppNotification } from '@notificationapi/core/dist/interfaces';
5
5
  import { InboxHeaderProps } from './InboxHeader';
6
6
  import { Filter, Pagination } from './interface';
7
-
8
7
  export type NotificationPopupProps = {
9
8
  buttonIcon?: React.ReactNode;
10
9
  buttonIconSize?: number;
@@ -2,7 +2,6 @@ import { PropsWithChildren } from 'react';
2
2
  import { NotificationPopupProps } from './NotificationPopup';
3
3
  import { InAppNotification } from '@notificationapi/core/dist/interfaces';
4
4
  import { COUNT_TYPE } from './interface';
5
-
6
5
  export type UnreadBadgeProps = {
7
6
  dot?: boolean;
8
7
  showZero?: boolean;
@@ -1,6 +1,5 @@
1
1
  import { BaseDeliveryOptions, DeliveryOptionsForEmail, DeliveryOptionsForInappWeb, GetPreferencesResponse } from '@notificationapi/core/dist/interfaces';
2
2
  import { Channels } from '../Notifications/interface';
3
-
4
3
  type Props = {
5
4
  preferences: GetPreferencesResponse['preferences'];
6
5
  notification: GetPreferencesResponse['notifications'][0];
@@ -1,4 +1,3 @@
1
1
  import { Channels } from '../Notifications/interface';
2
-
3
2
  export declare const getChannelLabel: (c: Channels) => string;
4
3
  export declare const getChannelIcon: (channel: Channels) => React.ReactElement;
@@ -1,6 +1,5 @@
1
1
  import { NotificationAPIClientSDK } from '@notificationapi/core';
2
2
  import { BaseDeliveryOptions, Channels, DeliveryOptionsForEmail, DeliveryOptionsForInappWeb, GetPreferencesResponse, InAppNotification, UserAccountMetadata } from '@notificationapi/core/dist/interfaces';
3
-
4
3
  export type Context = {
5
4
  notifications?: InAppNotification[];
6
5
  preferences?: GetPreferencesResponse;
@@ -1,8 +1,7 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { NotificationAPIClientSDK } from '@notificationapi/core';
3
- import { User, API_REGION, WS_REGION } from '@notificationapi/core/dist/interfaces';
3
+ import { InAppNotification, User, API_REGION, WS_REGION } from '@notificationapi/core/dist/interfaces';
4
4
  import { Context } from './context';
5
-
6
5
  type Props = ({
7
6
  userId: string;
8
7
  } | {
@@ -20,6 +19,7 @@ type Props = ({
20
19
  webPushOptInMessage?: 'AUTOMATIC' | boolean;
21
20
  customServiceWorkerPath?: string;
22
21
  debug?: boolean;
22
+ onNewNotifications?: (notifications: InAppNotification[]) => void;
23
23
  };
24
24
  export declare const NotificationAPIProvider: React.FunctionComponent<PropsWithChildren<Props>> & {
25
25
  useNotificationAPIContext: typeof useNotificationAPIContext;
@@ -1,9 +1,9 @@
1
- import { jsx as oe } from "react/jsx-runtime";
2
- import { useMemo as K, useState as k, useCallback as A, useRef as F, useEffect as E, useContext as ie } from "react";
3
- import { NotificationAPIContext as B } from "./context.js";
4
- import { createDebugLogger as ne, formatApiCall as C } from "../../utils/debug.js";
5
- const re = async (o, e, d, a, c, p, I, l) => {
6
- const h = se(a, c, p), b = `https://${e}/${a}/users/${encodeURIComponent(
1
+ import { jsx as ie } from "react/jsx-runtime";
2
+ import { useMemo as J, useState as N, useCallback as k, useRef as x, useEffect as E, useContext as re } from "react";
3
+ import { NotificationAPIContext as _ } from "./context.js";
4
+ import { createDebugLogger as se, formatApiCall as C } from "../../utils/debug.js";
5
+ const ae = async (o, e, d, a, c, p, I, l) => {
6
+ const h = ce(a, c, p), b = `https://${e}/${a}/users/${encodeURIComponent(
7
7
  c
8
8
  )}/${d}`, w = {
9
9
  Authorization: `Basic ${h}`
@@ -14,7 +14,7 @@ const re = async (o, e, d, a, c, p, I, l) => {
14
14
  url: b,
15
15
  body: I
16
16
  });
17
- const N = Date.now();
17
+ const v = Date.now();
18
18
  try {
19
19
  const m = await fetch(b, {
20
20
  method: o,
@@ -30,7 +30,7 @@ const re = async (o, e, d, a, c, p, I, l) => {
30
30
  return;
31
31
  }
32
32
  } catch (m) {
33
- const P = Date.now() - N;
33
+ const P = Date.now() - v;
34
34
  throw l && l.error("HTTP Request Failed:", {
35
35
  error: m,
36
36
  url: b,
@@ -38,8 +38,8 @@ const re = async (o, e, d, a, c, p, I, l) => {
38
38
  duration: `${P}ms`
39
39
  }), m;
40
40
  }
41
- }, se = (o, e, d) => btoa(d ? o + ":" + e + ":" + d : o + ":" + e);
42
- class G {
41
+ }, ce = (o, e, d) => btoa(d ? o + ":" + e + ":" + d : o + ":" + e);
42
+ class B {
43
43
  constructor(e = !1) {
44
44
  this.debug = e;
45
45
  }
@@ -53,7 +53,7 @@ class G {
53
53
  this.debug && console.error("[NotificationAPI js core SDK Debug]", ...e);
54
54
  }
55
55
  }
56
- const J = {
56
+ const V = {
57
57
  host: "api.notificationapi.com",
58
58
  websocketHost: "ws.notificationapi.com",
59
59
  userId: "",
@@ -68,11 +68,11 @@ const J = {
68
68
  // 24 hours
69
69
  debug: !1,
70
70
  sdkDevMode: !1
71
- }, n = {
72
- config: J,
73
- logger: new G(!1),
71
+ }, i = {
72
+ config: V,
73
+ logger: new B(!1),
74
74
  init: function(o) {
75
- return this.config = { ...J, ...o }, this.logger = new G(this.config.debug), this.logger.log("Initialized with config:", {
75
+ return this.config = { ...V, ...o }, this.logger = new B(this.config.debug), this.logger.log("Initialized with config:", {
76
76
  userId: this.config.userId,
77
77
  clientId: this.config.clientId,
78
78
  host: this.config.host,
@@ -85,91 +85,91 @@ const J = {
85
85
  },
86
86
  rest: {
87
87
  generic: function(o, e, d) {
88
- return n.logger.log(
88
+ return i.logger.log(
89
89
  `API Call: ${o} ${e}`,
90
90
  d ? { body: d } : ""
91
- ), re(
91
+ ), ae(
92
92
  o,
93
- n.config.host,
93
+ i.config.host,
94
94
  e,
95
- n.config.clientId,
96
- n.config.userId,
97
- n.config.hashedUserId,
95
+ i.config.clientId,
96
+ i.config.userId,
97
+ i.config.hashedUserId,
98
98
  d,
99
- n.logger
99
+ i.logger
100
100
  );
101
101
  },
102
102
  // The functions below are nice wrappers over the generic
103
103
  // rest api function above. They must follow REST API naming:
104
104
  // Method + Resource, representing the end-point.
105
105
  getNotifications: function(o, e) {
106
- return n.rest.generic(
106
+ return i.rest.generic(
107
107
  "GET",
108
108
  `notifications/INAPP_WEB?count=${e}&before=${o}`
109
109
  );
110
110
  },
111
111
  patchNotifications: function(o) {
112
- return n.rest.generic(
112
+ return i.rest.generic(
113
113
  "PATCH",
114
114
  "notifications/INAPP_WEB",
115
115
  o
116
116
  );
117
117
  },
118
118
  getPreferences: function() {
119
- return n.rest.generic("GET", "preferences");
119
+ return i.rest.generic("GET", "preferences");
120
120
  },
121
121
  postPreferences: function(o) {
122
- return n.rest.generic(
122
+ return i.rest.generic(
123
123
  "POST",
124
124
  "preferences",
125
125
  o
126
126
  );
127
127
  },
128
128
  postUser: function(o) {
129
- return n.rest.generic("POST", "", o);
129
+ return i.rest.generic("POST", "", o);
130
130
  },
131
131
  getUserAccountMetadata: function() {
132
- return n.rest.generic("GET", "account_metadata");
132
+ return i.rest.generic("GET", "account_metadata");
133
133
  }
134
134
  },
135
135
  websocket: {
136
136
  object: void 0,
137
137
  connect: function() {
138
- let o = `wss://${n.config.websocketHost}?userId=${encodeURIComponent(n.config.userId)}&envId=${n.config.clientId}`;
139
- return n.config.hashedUserId && (o += `&userIdHash=${encodeURIComponent(n.config.hashedUserId)}`), n.logger.log("WebSocket connecting to:", o), n.websocket.object = new WebSocket(o), n.websocket.object.onopen = () => {
140
- n.logger.log("WebSocket connection opened");
141
- }, n.websocket.object.onclose = (e) => {
142
- n.logger.log("WebSocket connection closed:", {
138
+ let o = `wss://${i.config.websocketHost}?userId=${encodeURIComponent(i.config.userId)}&envId=${i.config.clientId}`;
139
+ return i.config.hashedUserId && (o += `&userIdHash=${encodeURIComponent(i.config.hashedUserId)}`), i.logger.log("WebSocket connecting to:", o), i.websocket.object = new WebSocket(o), i.websocket.object.onopen = () => {
140
+ i.logger.log("WebSocket connection opened");
141
+ }, i.websocket.object.onclose = (e) => {
142
+ i.logger.log("WebSocket connection closed:", {
143
143
  code: e.code,
144
144
  reason: e.reason,
145
145
  wasClean: e.wasClean
146
146
  });
147
- }, n.websocket.object.onerror = (e) => {
148
- n.logger.error("WebSocket error:", e);
149
- }, n.websocket.object.onmessage = (e) => {
150
- n.logger.log(
147
+ }, i.websocket.object.onerror = (e) => {
148
+ i.logger.error("WebSocket error:", e);
149
+ }, i.websocket.object.onmessage = (e) => {
150
+ i.logger.log(
151
151
  "WebSocket message received:",
152
152
  e.data
153
153
  );
154
154
  const d = JSON.parse(e.data);
155
155
  if (!(!d || !d.route) && d.route === "inapp_web/new_notifications") {
156
156
  const a = d;
157
- n.logger.log(
157
+ i.logger.log(
158
158
  "New notifications received:",
159
159
  a.payload.notifications
160
- ), n.config.onNewInAppNotifications && n.config.onNewInAppNotifications(
160
+ ), i.config.onNewInAppNotifications && i.config.onNewInAppNotifications(
161
161
  a.payload.notifications
162
162
  );
163
163
  }
164
- }, n.websocket.object;
164
+ }, i.websocket.object;
165
165
  },
166
166
  disconnect: function(o) {
167
167
  var e;
168
- n.websocket.object && (n.logger.log("WebSocket disconnecting"), (e = n.websocket.object) == null || e.close(), o && o(n.websocket.object));
168
+ i.websocket.object && (i.logger.log("WebSocket disconnecting"), (e = i.websocket.object) == null || e.close(), o && o(i.websocket.object));
169
169
  }
170
170
  },
171
171
  openWebSocket: function() {
172
- return n.websocket.connect(() => {
172
+ return i.websocket.connect(() => {
173
173
  setTimeout(
174
174
  () => {
175
175
  this.websocket.disconnect(() => {
@@ -184,30 +184,30 @@ const J = {
184
184
  // They may or may not do additional tasks.
185
185
  // e.g. identify simply maps to postUsers
186
186
  getInAppNotifications: async (o) => {
187
- n.logger.log(
187
+ i.logger.log(
188
188
  "getInAppNotifications called with params:",
189
189
  o
190
190
  );
191
- const e = o.maxCountNeeded || n.config.getInAppDefaultCount, d = o.oldestNeeded || n.config.getInAppDefaultOldest;
192
- n.logger.log("Fetching notifications with:", {
191
+ const e = o.maxCountNeeded || i.config.getInAppDefaultCount, d = o.oldestNeeded || i.config.getInAppDefaultOldest;
192
+ i.logger.log("Fetching notifications with:", {
193
193
  maxCountNeeded: e,
194
194
  oldestNeeded: d,
195
195
  before: o.before
196
196
  });
197
197
  let a = [], c = o.before, p = !0, I = !0;
198
198
  for (; I; ) {
199
- const l = (await n.rest.getNotifications(
199
+ const l = (await i.rest.getNotifications(
200
200
  c,
201
201
  e
202
202
  )).notifications, h = l.filter(
203
203
  (b) => !a.find((w) => w.id === b.id)
204
204
  );
205
- n.logger.log(
205
+ i.logger.log(
206
206
  `Received ${l.length} notifications, ${h.length} unique`
207
207
  ), c = h.reduce(
208
208
  (b, w) => b < w.date ? b : w.date,
209
209
  o.before
210
- ), a = [...a, ...h], p = h.length > 0, I = !0, (!p || a.length >= e || c < d) && (I = !1, n.logger.log("Stopping fetch loop:", {
210
+ ), a = [...a, ...h], p = h.length > 0, I = !0, (!p || a.length >= e || c < d) && (I = !1, i.logger.log("Stopping fetch loop:", {
211
211
  hasMore: p,
212
212
  totalResults: a.length,
213
213
  maxCountNeeded: e,
@@ -215,7 +215,7 @@ const J = {
215
215
  oldestNeeded: d
216
216
  }));
217
217
  }
218
- return n.logger.log("getInAppNotifications completed:", {
218
+ return i.logger.log("getInAppNotifications completed:", {
219
219
  totalItems: a.length,
220
220
  hasMore: p,
221
221
  oldestReceived: c
@@ -226,54 +226,54 @@ const J = {
226
226
  };
227
227
  },
228
228
  updateInAppNotifications: async (o) => {
229
- n.logger.log(
229
+ i.logger.log(
230
230
  "updateInAppNotifications called with params:",
231
231
  o
232
232
  );
233
233
  const e = {
234
234
  trackingIds: o.ids
235
235
  };
236
- return o.archived === !0 ? e.archived = (/* @__PURE__ */ new Date()).toISOString() : o.archived === !1 && (e.archived = null), o.clicked === !0 ? e.clicked = (/* @__PURE__ */ new Date()).toISOString() : o.clicked === !1 && (e.clicked = null), o.opened === !0 ? e.opened = (/* @__PURE__ */ new Date()).toISOString() : o.opened === !1 && (e.opened = null), n.logger.log(
236
+ return o.archived === !0 ? e.archived = (/* @__PURE__ */ new Date()).toISOString() : o.archived === !1 && (e.archived = null), o.clicked === !0 ? e.clicked = (/* @__PURE__ */ new Date()).toISOString() : o.clicked === !1 && (e.clicked = null), o.opened === !0 ? e.opened = (/* @__PURE__ */ new Date()).toISOString() : o.opened === !1 && (e.opened = null), i.logger.log(
237
237
  "Updating notifications with body:",
238
238
  e
239
- ), n.rest.patchNotifications(e);
239
+ ), i.rest.patchNotifications(e);
240
240
  },
241
- getPreferences: async () => n.rest.getPreferences(),
242
- updateDeliveryOption: async (o) => n.rest.postPreferences([o]),
241
+ getPreferences: async () => i.rest.getPreferences(),
242
+ updateDeliveryOption: async (o) => i.rest.postPreferences([o]),
243
243
  identify: async (o) => {
244
- if (o.id && o.id !== n.config.userId)
244
+ if (o.id && o.id !== i.config.userId)
245
245
  throw new Error(
246
246
  "The id in the parameters does not match the initialized userId."
247
247
  );
248
- return n.rest.postUser(o);
248
+ return i.rest.postUser(o);
249
249
  },
250
- getUserAccountMetadata: async () => n.rest.getUserAccountMetadata(),
250
+ getUserAccountMetadata: async () => i.rest.getUserAccountMetadata(),
251
251
  user: {
252
- get: async () => n.rest.generic("GET", "")
252
+ get: async () => i.rest.generic("GET", "")
253
253
  },
254
254
  slack: {
255
255
  getOAuthUrl: (o) => {
256
- const e = n.config.sdkDevMode ? "localhost:3001" : n.config.host.replace("api.", "app."), d = (o == null ? void 0 : o.destinationUrl) || window.location.href, a = encodeURIComponent(
256
+ const e = i.config.sdkDevMode ? "localhost:3001" : i.config.host.replace("api.", "app."), d = (o == null ? void 0 : o.destinationUrl) || window.location.href, a = encodeURIComponent(
257
257
  JSON.stringify({
258
258
  destination: d,
259
- userId: n.config.userId,
260
- clientId: n.config.clientId,
261
- hashedUserId: n.config.hashedUserId
259
+ userId: i.config.userId,
260
+ clientId: i.config.clientId,
261
+ hashedUserId: i.config.hashedUserId
262
262
  })
263
263
  );
264
264
  return `https://slack.com/oauth/v2/authorize?client_id=1146598856352.8825220259395&scope=chat:write,channels:read,channels:join,chat:write.customize,chat:write.public,groups:read,im:read,users:read&redirect_uri=https://${e}/slack/oauth/callback&state=${a}`;
265
265
  },
266
- getChannels: async () => await n.rest.generic(
266
+ getChannels: async () => await i.rest.generic(
267
267
  "GET",
268
268
  "slack/channels"
269
269
  ),
270
- setChannel: async (o) => n.identify({
270
+ setChannel: async (o) => i.identify({
271
271
  slackChannel: o
272
272
  })
273
273
  }
274
- }, V = typeof window < "u", ae = (o) => {
275
- const e = K(
276
- () => ne(o.debug || !1),
274
+ }, Q = typeof window < "u", de = (o) => {
275
+ const e = J(
276
+ () => se(o.debug || !1),
277
277
  [o.debug]
278
278
  );
279
279
  e.log("NotificationAPI Provider initializing", {
@@ -297,7 +297,7 @@ const J = {
297
297
  user: "userId" in o ? { id: o.userId } : o.user
298
298
  };
299
299
  e.log("Configuration loaded", a);
300
- const [c, p] = k(), [I, l] = k(), [h, b] = k(), [w, N] = k(!1), [m, P] = k((/* @__PURE__ */ new Date()).toISOString()), [U, x] = k(!0), [v, y] = k(a.webPushOptInMessage), [M, _] = k(!1), $ = A(() => {
300
+ const [c, p] = N(), [I, l] = N(), [h, b] = N(), [w, v] = N(!1), [m, P] = N((/* @__PURE__ */ new Date()).toISOString()), [U, $] = N(!0), [y, S] = N(a.webPushOptInMessage), [M, X] = N(!1), j = k(() => {
301
301
  a.playSoundOnNewNotification && (e.log("Playing notification sound", {
302
302
  soundPath: a.newNotificationSoundPath
303
303
  }), new Audio(a.newNotificationSoundPath).play().catch((r) => {
@@ -307,30 +307,30 @@ const J = {
307
307
  a.newNotificationSoundPath,
308
308
  a.playSoundOnNewNotification,
309
309
  e
310
- ]), O = A(
310
+ ]), O = k(
311
311
  (t) => {
312
312
  e.group("Adding notifications to state"), e.log("Received notifications", {
313
313
  count: (t == null ? void 0 : t.length) || 0,
314
314
  notifications: t
315
315
  });
316
316
  const r = (/* @__PURE__ */ new Date()).toISOString();
317
- p((i) => {
318
- const s = (i == null ? void 0 : i.length) || 0;
317
+ p((n) => {
318
+ const s = (n == null ? void 0 : n.length) || 0;
319
319
  e.log("Current notifications count", s), t = Array.isArray(t) ? t : [], t = t.filter((g) => {
320
- const S = g.expDate && new Date(g.expDate).toISOString() > r, L = new Date(g.date).getTime() > new Date(r).getTime() + 1e3, z = !S && !L;
321
- return z || e.log("Filtering out notification", {
320
+ const A = g.expDate && new Date(g.expDate).toISOString() > r, F = new Date(g.date).getTime() > new Date(r).getTime() + 1e3, G = !A && !F;
321
+ return G || e.log("Filtering out notification", {
322
322
  id: g.id,
323
- reason: S ? "expired" : "future",
323
+ reason: A ? "expired" : "future",
324
324
  expDate: g.expDate,
325
325
  date: g.date
326
- }), z;
327
- }), i = Array.isArray(i) ? i : [];
326
+ }), G;
327
+ }), n = Array.isArray(n) ? n : [];
328
328
  const u = [
329
329
  ...t.filter((g) => {
330
- const S = i.find((L) => L.id === g.id);
331
- return S && e.log("Filtering out duplicate notification", { id: g.id }), !S;
330
+ const A = n.find((F) => F.id === g.id);
331
+ return A && e.log("Filtering out duplicate notification", { id: g.id }), !A;
332
332
  }),
333
- ...i
333
+ ...n
334
334
  ];
335
335
  return e.log("State updated", {
336
336
  previousCount: s,
@@ -340,7 +340,17 @@ const J = {
340
340
  });
341
341
  },
342
342
  [e]
343
- ), f = K(() => {
343
+ ), { onNewNotifications: D } = o, q = k(
344
+ (t) => {
345
+ e.log("Received new in-app notifications via WebSocket", {
346
+ count: (t == null ? void 0 : t.length) || 0,
347
+ notifications: t
348
+ }), j(), O(t), D && (e.log("Calling onNewNotifications callback", {
349
+ count: (t == null ? void 0 : t.length) || 0
350
+ }), D(t));
351
+ },
352
+ [j, O, D, e]
353
+ ), f = J(() => {
344
354
  e.group("Initializing NotificationAPI client");
345
355
  const t = {
346
356
  clientId: a.clientId,
@@ -351,19 +361,14 @@ const J = {
351
361
  debug: a.debug
352
362
  };
353
363
  e.log("Client configuration", t);
354
- const r = o.client ? o.client : n.init({
364
+ const r = o.client ? o.client : i.init({
355
365
  ...t,
356
- onNewInAppNotifications: (s) => {
357
- e.log("Received new in-app notifications via WebSocket", {
358
- count: (s == null ? void 0 : s.length) || 0,
359
- notifications: s
360
- }), $(), O(s);
361
- }
362
- }), i = {
366
+ onNewInAppNotifications: q
367
+ }), n = {
363
368
  email: a.user.email,
364
369
  number: a.user.number
365
370
  };
366
- return e.log("Identifying user", i), r.identify(i), e.groupEnd(), r;
371
+ return e.log("Identifying user", n), r.identify(n), e.groupEnd(), r;
367
372
  }, [
368
373
  a.clientId,
369
374
  a.user.id,
@@ -371,15 +376,14 @@ const J = {
371
376
  a.user.number,
372
377
  a.hashedUserId,
373
378
  a.debug,
374
- O,
375
- $,
379
+ q,
376
380
  o.client,
377
381
  a.apiURL,
378
382
  a.wsURL,
379
383
  e
380
- ]), j = A(
384
+ ]), H = k(
381
385
  async (t, r) => {
382
- var i;
386
+ var n;
383
387
  e.group("Fetching notifications"), e.log(
384
388
  "Fetch parameters",
385
389
  C("GET", "/notifications", { date: t, count: r })
@@ -387,76 +391,76 @@ const J = {
387
391
  try {
388
392
  const s = await f.rest.getNotifications(t, r);
389
393
  e.log("Fetch successful", {
390
- notificationsCount: ((i = s.notifications) == null ? void 0 : i.length) || 0,
394
+ notificationsCount: ((n = s.notifications) == null ? void 0 : n.length) || 0,
391
395
  oldestReceived: s.oldestReceived,
392
396
  couldLoadMore: s.couldLoadMore
393
- }), P(s.oldestReceived), x(s.couldLoadMore), O(s.notifications), e.groupEnd();
397
+ }), P(s.oldestReceived), $(s.couldLoadMore), O(s.notifications), e.groupEnd();
394
398
  } catch (s) {
395
399
  throw e.error("Failed to fetch notifications", s, { date: t, count: r }), e.groupEnd(), s;
396
400
  }
397
401
  },
398
402
  [O, f.rest, e]
399
- ), D = F(U), T = F(w), q = F(m);
403
+ ), T = x(U), W = x(w), z = x(m);
400
404
  E(() => {
401
- D.current = U, T.current = w, q.current = m;
405
+ T.current = U, W.current = w, z.current = m;
402
406
  }, [U, w, m]);
403
- const W = A(
407
+ const R = k(
404
408
  async (t) => {
405
409
  if (e.group(`Loading notifications (${t ? "initial" : "more"})`), e.log("Load conditions", {
406
410
  initial: t,
407
- hasMore: D.current,
408
- loading: T.current
409
- }), !t && (!D.current || T.current)) {
411
+ hasMore: T.current,
412
+ loading: W.current
413
+ }), !t && (!T.current || W.current)) {
410
414
  e.log("Skipping load - conditions not met"), e.groupEnd();
411
415
  return;
412
416
  }
413
- N(!0), e.log("Loading started");
417
+ v(!0), e.log("Loading started");
414
418
  try {
415
- await j(
416
- t ? (/* @__PURE__ */ new Date()).toISOString() : q.current,
419
+ await H(
420
+ t ? (/* @__PURE__ */ new Date()).toISOString() : z.current,
417
421
  t ? a.initialLoadMaxCount : 1e3
418
422
  ), e.log("Loading completed successfully");
419
423
  } catch (r) {
420
424
  throw e.error("Loading failed", r), r;
421
425
  } finally {
422
- N(!1), e.groupEnd();
426
+ v(!1), e.groupEnd();
423
427
  }
424
428
  },
425
- [a.initialLoadMaxCount, j, e]
426
- ), Q = async (t) => {
429
+ [a.initialLoadMaxCount, H, e]
430
+ ), Y = async (t) => {
427
431
  if (e.group("Marking notifications as clicked"), e.log("Requested IDs", t), !c) {
428
432
  e.warn("No notifications available"), e.groupEnd();
429
433
  return;
430
434
  }
431
- const r = (/* @__PURE__ */ new Date()).toISOString(), i = c.filter((s) => t.includes(s.id) && !s.clicked).map((s) => s.id);
435
+ const r = (/* @__PURE__ */ new Date()).toISOString(), n = c.filter((s) => t.includes(s.id) && !s.clicked).map((s) => s.id);
432
436
  if (e.log("Filtered IDs for update", {
433
437
  requestedCount: t.length,
434
- actualCount: i.length,
435
- ids: i
436
- }), i.length === 0) {
438
+ actualCount: n.length,
439
+ ids: n
440
+ }), n.length === 0) {
437
441
  e.log("No notifications to update"), e.groupEnd();
438
442
  return;
439
443
  }
440
444
  try {
441
445
  e.log(
442
446
  "Updating notifications via API",
443
- C("PUT", "/notifications/clicked", { ids: i })
444
- ), f.updateInAppNotifications({ ids: i, clicked: !0 }), p((s) => {
447
+ C("PUT", "/notifications/clicked", { ids: n })
448
+ ), f.updateInAppNotifications({ ids: n, clicked: !0 }), p((s) => {
445
449
  if (!s) return [];
446
450
  const u = [...s];
447
- return u.filter((g) => i.includes(g.id)).forEach((g) => {
451
+ return u.filter((g) => n.includes(g.id)).forEach((g) => {
448
452
  g.clicked = r;
449
- }), e.log("Local state updated", { updatedCount: i.length }), u;
453
+ }), e.log("Local state updated", { updatedCount: n.length }), u;
450
454
  }), e.groupEnd();
451
455
  } catch (s) {
452
- throw e.error("Failed to mark notifications as clicked", s, { ids: i }), e.groupEnd(), s;
456
+ throw e.error("Failed to mark notifications as clicked", s, { ids: n }), e.groupEnd(), s;
453
457
  }
454
- }, X = async () => {
458
+ }, Z = async () => {
455
459
  if (e.group("Marking notifications as opened"), !c) {
456
460
  e.warn("No notifications available"), e.groupEnd();
457
461
  return;
458
462
  }
459
- const t = (/* @__PURE__ */ new Date()).toISOString(), r = c.filter((i) => !i.opened || !i.seen).map((i) => i.id);
463
+ const t = (/* @__PURE__ */ new Date()).toISOString(), r = c.filter((n) => !n.opened || !n.seen).map((n) => n.id);
460
464
  if (e.log("Notifications to mark as opened", { count: r.length, ids: r }), r.length === 0) {
461
465
  e.log("All notifications already opened"), e.groupEnd();
462
466
  return;
@@ -468,22 +472,22 @@ const J = {
468
472
  ), f.updateInAppNotifications({
469
473
  ids: r,
470
474
  opened: !0
471
- }), p((i) => {
472
- if (!i) return [];
473
- const s = [...i];
475
+ }), p((n) => {
476
+ if (!n) return [];
477
+ const s = [...n];
474
478
  return s.filter((u) => r.includes(u.id)).forEach((u) => {
475
479
  u.opened = t, u.seen = !0;
476
480
  }), e.log("Local state updated", { updatedCount: r.length }), s;
477
481
  }), e.groupEnd();
478
- } catch (i) {
479
- throw e.error("Failed to mark notifications as opened", i, { ids: r }), e.groupEnd(), i;
482
+ } catch (n) {
483
+ throw e.error("Failed to mark notifications as opened", n, { ids: r }), e.groupEnd(), n;
480
484
  }
481
- }, Y = async (t) => {
485
+ }, ee = async (t) => {
482
486
  if (e.group("Marking notifications as unarchived"), e.log("Requested operation", { ids: t }), !c) {
483
487
  e.warn("No notifications available"), e.groupEnd();
484
488
  return;
485
489
  }
486
- const r = c.filter((i) => i.archived && (t === "ALL" || t.includes(i.id))).map((i) => i.id);
490
+ const r = c.filter((n) => n.archived && (t === "ALL" || t.includes(n.id))).map((n) => n.id);
487
491
  if (e.log("Filtered notifications for unarchiving", {
488
492
  count: r.length,
489
493
  ids: r
@@ -498,65 +502,65 @@ const J = {
498
502
  ), f.updateInAppNotifications({
499
503
  ids: r,
500
504
  archived: !1
501
- }), p((i) => {
502
- if (!i) return [];
503
- const s = [...i];
505
+ }), p((n) => {
506
+ if (!n) return [];
507
+ const s = [...n];
504
508
  return s.filter((u) => r.includes(u.id)).forEach((u) => {
505
509
  u.archived = void 0;
506
510
  }), e.log("Local state updated", { unarchivedCount: r.length }), s;
507
511
  }), e.groupEnd();
508
- } catch (i) {
509
- throw e.error("Failed to unarchive notifications", i, { ids: r }), e.groupEnd(), i;
512
+ } catch (n) {
513
+ throw e.error("Failed to unarchive notifications", n, { ids: r }), e.groupEnd(), n;
510
514
  }
511
- }, Z = async (t) => {
515
+ }, te = async (t) => {
512
516
  if (e.group("Marking notifications as archived"), e.log("Requested operation", { ids: t }), !c) {
513
517
  e.warn("No notifications available"), e.groupEnd();
514
518
  return;
515
519
  }
516
- const r = (/* @__PURE__ */ new Date()).toISOString(), i = c.filter((s) => !s.archived && (t === "ALL" || t.includes(s.id))).map((s) => s.id);
520
+ const r = (/* @__PURE__ */ new Date()).toISOString(), n = c.filter((s) => !s.archived && (t === "ALL" || t.includes(s.id))).map((s) => s.id);
517
521
  if (e.log("Filtered notifications for archiving", {
518
- count: i.length,
519
- ids: i
520
- }), i.length === 0) {
522
+ count: n.length,
523
+ ids: n
524
+ }), n.length === 0) {
521
525
  e.log("No unarchived notifications to archive"), e.groupEnd();
522
526
  return;
523
527
  }
524
528
  try {
525
529
  e.log(
526
530
  "Updating notifications via API",
527
- C("PUT", "/notifications/archived", { ids: i })
528
- ), f.updateInAppNotifications({ ids: i, archived: !0 }), p((s) => {
531
+ C("PUT", "/notifications/archived", { ids: n })
532
+ ), f.updateInAppNotifications({ ids: n, archived: !0 }), p((s) => {
529
533
  if (!s) return [];
530
534
  const u = [...s];
531
- return u.filter((g) => i.includes(g.id)).forEach((g) => {
535
+ return u.filter((g) => n.includes(g.id)).forEach((g) => {
532
536
  g.archived = r;
533
- }), e.log("Local state updated", { archivedCount: i.length }), u;
537
+ }), e.log("Local state updated", { archivedCount: n.length }), u;
534
538
  }), e.groupEnd();
535
539
  } catch (s) {
536
- throw e.error("Failed to archive notifications", s, { ids: i }), e.groupEnd(), s;
540
+ throw e.error("Failed to archive notifications", s, { ids: n }), e.groupEnd(), s;
537
541
  }
538
- }, ee = (t, r, i, s) => (e.log("Updating single delivery preference", {
542
+ }, oe = (t, r, n, s) => (e.log("Updating single delivery preference", {
539
543
  notificationId: t,
540
544
  channel: r,
541
- delivery: i,
545
+ delivery: n,
542
546
  subNotificationId: s
543
- }), H([
547
+ }), K([
544
548
  {
545
549
  notificationId: t,
546
550
  channel: r,
547
- delivery: i,
551
+ delivery: n,
548
552
  subNotificationId: s
549
553
  }
550
- ])), H = (t) => {
554
+ ])), K = (t) => {
551
555
  e.group("Updating delivery preferences"), e.log("Preference updates", { count: t.length, params: t });
552
556
  try {
553
557
  f.rest.postPreferences(t).then(() => {
554
558
  e.log(
555
559
  "Preferences updated successfully, fetching latest preferences"
556
560
  ), f.getPreferences().then((r) => {
557
- var i, s, u;
561
+ var n, s, u;
558
562
  e.log("Latest preferences fetched", {
559
- preferencesCount: ((i = r.preferences) == null ? void 0 : i.length) || 0,
563
+ preferencesCount: ((n = r.preferences) == null ? void 0 : n.length) || 0,
560
564
  notificationsCount: ((s = r.notifications) == null ? void 0 : s.length) || 0,
561
565
  subNotificationsCount: ((u = r.subNotifications) == null ? void 0 : u.length) || 0
562
566
  }), l(r), e.groupEnd();
@@ -569,23 +573,23 @@ const J = {
569
573
  } catch (r) {
570
574
  throw e.error("Error in updateDeliveries", r, { params: t }), e.groupEnd(), r;
571
575
  }
572
- }, R = A(() => {
576
+ }, L = k(() => {
573
577
  e.group("Requesting web push permission"), e.log("Service worker support check", {
574
578
  supported: "serviceWorker" in navigator,
575
579
  customServiceWorkerPath: a.customServiceWorkerPath
576
580
  }), "serviceWorker" in navigator ? (e.log("Registering service worker"), navigator.serviceWorker.register(a.customServiceWorkerPath).then(async (t) => {
577
- e.log("Service worker registered successfully"), y(!1), de().then(async (r) => {
581
+ e.log("Service worker registered successfully"), S(!1), le().then(async (r) => {
578
582
  e.log("Notification permission result", { permission: r }), r === "granted" ? (e.log("Permission granted, subscribing to push manager"), await t.pushManager.subscribe({
579
583
  userVisibleOnly: !0,
580
584
  applicationServerKey: h == null ? void 0 : h.userAccountMetadata.environmentVapidPublicKey
581
- }).then(async (i) => {
585
+ }).then(async (n) => {
582
586
  e.log("Push subscription successful");
583
587
  const s = {
584
588
  webPushTokens: [
585
589
  {
586
590
  sub: {
587
- endpoint: i.toJSON().endpoint,
588
- keys: i.toJSON().keys
591
+ endpoint: n.toJSON().endpoint,
592
+ keys: n.toJSON().keys
589
593
  }
590
594
  }
591
595
  ]
@@ -620,78 +624,78 @@ const J = {
620
624
  e
621
625
  ]);
622
626
  E(() => {
623
- e.group("Provider initialization effect"), e.log("Resetting state and loading initial data"), p([]), N(!1), l(void 0), P((/* @__PURE__ */ new Date()).toISOString()), x(!0), W(!0), e.log("Opening WebSocket connection"), f.openWebSocket(), e.log("Fetching user preferences"), f.getPreferences().then((t) => {
624
- var r, i, s;
627
+ e.group("Provider initialization effect"), e.log("Resetting state and loading initial data"), p([]), v(!1), l(void 0), P((/* @__PURE__ */ new Date()).toISOString()), $(!0), R(!0), e.log("Opening WebSocket connection"), f.openWebSocket(), e.log("Fetching user preferences"), f.getPreferences().then((t) => {
628
+ var r, n, s;
625
629
  e.log("Initial preferences loaded", {
626
630
  preferencesCount: ((r = t.preferences) == null ? void 0 : r.length) || 0,
627
- notificationsCount: ((i = t.notifications) == null ? void 0 : i.length) || 0,
631
+ notificationsCount: ((n = t.notifications) == null ? void 0 : n.length) || 0,
628
632
  subNotificationsCount: ((s = t.subNotifications) == null ? void 0 : s.length) || 0
629
633
  }), l(t), e.groupEnd();
630
634
  }).catch((t) => {
631
635
  e.error("Failed to fetch initial preferences", t), e.groupEnd();
632
636
  });
633
- }, [f, W, R, e]), E(() => {
637
+ }, [f, R, L, e]), E(() => {
634
638
  e.group("Fetching user account metadata"), f.getUserAccountMetadata().then((t) => {
635
639
  e.log("User account metadata loaded", {
636
640
  hasWebPushEnabled: t.userAccountMetadata.hasWebPushEnabled,
637
641
  environmentVapidPublicKey: t.userAccountMetadata.environmentVapidPublicKey ? "present" : "missing"
638
- }), b(t), V && "Notification" in window && typeof Notification.requestPermission == "function" ? (e.log("Browser notification support detected", {
642
+ }), b(t), Q && "Notification" in window && typeof Notification.requestPermission == "function" ? (e.log("Browser notification support detected", {
639
643
  permission: Notification.permission
640
644
  }), Notification.permission !== "default" && (e.log(
641
645
  "Setting webPushOptInMessage to false (permission already set)"
642
- ), y(!1))) : (e.log(
646
+ ), S(!1))) : (e.log(
643
647
  "Browser notification not supported, using server setting",
644
648
  {
645
649
  hasWebPushEnabled: t.userAccountMetadata.hasWebPushEnabled
646
650
  }
647
- ), y(t.userAccountMetadata.hasWebPushEnabled)), e.groupEnd();
651
+ ), S(t.userAccountMetadata.hasWebPushEnabled)), e.groupEnd();
648
652
  }).catch((t) => {
649
653
  e.error("Failed to fetch user account metadata", t), e.groupEnd();
650
654
  });
651
655
  }, [f, e]), E(() => {
652
- if (e.group("Handling webPushOptInMessage state"), e.log("webPushOptInMessage value", v), v === "AUTOMATIC") {
656
+ if (e.group("Handling webPushOptInMessage state"), e.log("webPushOptInMessage value", y), y === "AUTOMATIC") {
653
657
  const t = localStorage.getItem("hideWebPushOptInMessage") === "true";
654
658
  e.log("Automatic mode - checking localStorage", {
655
659
  hideMessage: t,
656
660
  shouldShow: !t
657
- }), y(!t);
661
+ }), S(!t);
658
662
  }
659
663
  e.groupEnd();
660
- }, [v, e]), E(() => {
661
- e.group("Handling webPushOptIn state"), e.log("webPushOptIn state", M), M && (e.log("User opted in for web push, requesting permission"), R()), e.groupEnd();
662
- }, [M, R, e]);
663
- const te = {
664
+ }, [y, e]), E(() => {
665
+ e.group("Handling webPushOptIn state"), e.log("webPushOptIn state", M), M && (e.log("User opted in for web push, requesting permission"), L()), e.groupEnd();
666
+ }, [M, L, e]);
667
+ const ne = {
664
668
  notifications: c,
665
669
  preferences: I,
666
670
  userAccountMetaData: h,
667
- webPushOptInMessage: v,
668
- loadNotifications: W,
669
- markAsOpened: X,
670
- markAsArchived: Z,
671
- markAsUnarchived: Y,
672
- markAsClicked: Q,
673
- updateDelivery: ee,
674
- updateDeliveries: H,
671
+ webPushOptInMessage: y,
672
+ loadNotifications: R,
673
+ markAsOpened: Z,
674
+ markAsArchived: te,
675
+ markAsUnarchived: ee,
676
+ markAsClicked: Y,
677
+ updateDelivery: oe,
678
+ updateDeliveries: K,
675
679
  getClient: () => f,
676
- setWebPushOptInMessage: y,
677
- setWebPushOptIn: _
680
+ setWebPushOptInMessage: S,
681
+ setWebPushOptIn: X
678
682
  };
679
683
  return e.log("NotificationAPI Provider rendering", {
680
684
  notificationsCount: (c == null ? void 0 : c.length) || 0,
681
685
  hasPreferences: !!I,
682
686
  hasUserAccountMetaData: !!h,
683
- webPushOptInMessage: v,
687
+ webPushOptInMessage: y,
684
688
  webPushOptIn: M
685
- }), /* @__PURE__ */ oe(B.Provider, { value: te, children: o.children });
686
- }, ce = () => {
687
- const o = ie(B);
689
+ }), /* @__PURE__ */ ie(_.Provider, { value: ne, children: o.children });
690
+ }, ue = () => {
691
+ const o = re(_);
688
692
  if (!o)
689
693
  throw new Error("useMyContext must be used within a MyProvider");
690
694
  return o;
691
695
  };
692
- ae.useNotificationAPIContext = ce;
693
- const de = async () => {
694
- if (V && "Notification" in window && typeof Notification.requestPermission == "function")
696
+ de.useNotificationAPIContext = ue;
697
+ const le = async () => {
698
+ if (Q && "Notification" in window && typeof Notification.requestPermission == "function")
695
699
  try {
696
700
  return await Notification.requestPermission();
697
701
  } catch (o) {
@@ -701,5 +705,5 @@ const de = async () => {
701
705
  return console.warn("Web Push Notifications are not supported in this browser."), "default";
702
706
  };
703
707
  export {
704
- ae as NotificationAPIProvider
708
+ de as NotificationAPIProvider
705
709
  };
@@ -1,5 +1,4 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  interface WebPushOptInMessageProps {
4
3
  hideAfterInteraction?: boolean;
5
4
  alertContainerStyle?: React.CSSProperties;
package/dist/main.d.ts CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  export { NotificationFeed, NotificationPopup, NotificationLauncher, NotificationCounter } from './components/Notifications';
3
2
  export { NotificationPreferencesInline, NotificationPreferencesPopup } from './components/Preferences';
4
3
  export { NotificationAPIProvider } from './components/Provider';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@notificationapi/react",
3
3
  "private": false,
4
- "version": "1.6.2",
4
+ "version": "1.7.0",
5
5
  "type": "module",
6
6
  "overrides": {
7
7
  "esbuild": "^0.25.0",
@@ -48,11 +48,11 @@
48
48
  "eslint-plugin-react-hooks": "^4.6.0",
49
49
  "eslint-plugin-react-refresh": "^0.4.6",
50
50
  "faker-js": "^1.0.0",
51
- "glob": "^10.4.1",
51
+ "glob": "^11.1.0",
52
52
  "prettier": "^3.3.3",
53
53
  "typescript": "^5.2.2",
54
54
  "vite": "^5.4.21",
55
- "vite-plugin-dts": "^3.9.1",
55
+ "vite-plugin-dts": "^4.5.4",
56
56
  "vite-plugin-lib-inject-css": "^2.1.1"
57
57
  },
58
58
  "main": "dist/main.js",
@@ -61,6 +61,10 @@
61
61
  "dist"
62
62
  ],
63
63
  "sideEffects": false,
64
+ "repository": {
65
+ "type": "git",
66
+ "url": "https://github.com/notificationapi-com/notificationapi-react-client-sdk"
67
+ },
64
68
  "dependencies": {
65
69
  "@emotion/react": "^11.14.0",
66
70
  "@emotion/styled": "^11.14.0",