@novu/react 3.10.0 → 3.11.0-rc.1

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.
package/README.md CHANGED
@@ -124,9 +124,9 @@ function Novu() {
124
124
 
125
125
  When Novu's user adds the Inbox component to their application, developers need to provide a subscriber prop with the value of their customer's subscriberId, along with an application identifier that serves as a public key for API communication.
126
126
 
127
- A malicious actor can access the user feed by accessing the API and passing another `subscriberId` using the public application identifier.
127
+ A malicious actor can access the user feed by accessing the API and passing another `subscriberId` using the public application identifier.
128
128
 
129
- HMAC encryption will make sure that a `subscriberId` is encrypted using the secret API key, and those will prevent malicious actors from impersonating users.
129
+ HMAC encryption will make sure that a `subscriberId` is encrypted using the secret API key, and those will prevent malicious actors from impersonating users.
130
130
 
131
131
  ### Enabling HMAC Encryption
132
132
 
@@ -136,15 +136,17 @@ In order to enable Hash-Based Message Authentication Codes, you need to visit th
136
136
  <img src="/images/notification-center/client/react/get-started/hmac-encryption-enable.png" />
137
137
  </Frame> -->
138
138
 
139
- 1. Next step would be to generate an HMAC encrypted subscriberId on your backend:
139
+ #### Subscriber HMAC
140
+
141
+ 1. Generate an HMAC encrypted subscriberId on your backend:
140
142
 
141
143
  ```jsx
142
144
  import { createHmac } from 'crypto';
143
145
 
144
- const hmacHash = createHmac('sha256', process.env.NOVU_API_KEY).update(subscriberId).digest('hex');
146
+ const subscriberHash = createHmac('sha256', process.env.NOVU_API_KEY).update(subscriberId).digest('hex');
145
147
  ```
146
148
 
147
- 2. Then pass the created HMAC to your client side application forward it to the component:
149
+ 2. Pass the created HMAC to your client side application:
148
150
 
149
151
  ```jsx
150
152
  <Inbox
@@ -156,3 +158,33 @@ const hmacHash = createHmac('sha256', process.env.NOVU_API_KEY).update(subscribe
156
158
 
157
159
  > Note: If HMAC encryption is active in In-App provider settings and `subscriberHash`
158
160
  > along with `subscriberId` is not provided, then Inbox will not load
161
+
162
+ #### Context HMAC (Optional)
163
+
164
+ If you're using the `context` prop to pass additional data (e.g., tenant information, environment, etc.), you should also generate a `contextHash` to prevent context tampering:
165
+
166
+ 1. Generate an HMAC for the context on your backend:
167
+
168
+ ```jsx
169
+ import { createHmac } from 'crypto';
170
+ import { canonicalize } from '@tufjs/canonical-json';
171
+
172
+ const context = { tenant: 'acme', app: 'dashboard' };
173
+ const contextHash = createHmac('sha256', process.env.NOVU_API_KEY)
174
+ .update(canonicalize(context))
175
+ .digest('hex');
176
+ ```
177
+
178
+ 2. Pass both the context and contextHash to the component:
179
+
180
+ ```jsx
181
+ <Inbox
182
+ subscriber={'SUBSCRIBER_ID_PLAIN_VALUE'}
183
+ subscriberHash={'SUBSCRIBER_ID_HASH_VALUE'}
184
+ context={{ tenant: 'acme', app: 'dashboard' }}
185
+ contextHash={'CONTEXT_HASH_VALUE'}
186
+ applicationIdentifier={'APPLICATION_IDENTIFIER'}
187
+ />
188
+ ```
189
+
190
+ > Note: When HMAC encryption is enabled and `context` is provided, the `contextHash` is required. The hash is order-independent, so `{a:1, b:2}` produces the same hash as `{b:2, a:1}`.
@@ -124,10 +124,12 @@ var Inbox = import_react.default.memo((props) => {
124
124
  const providerProps = {
125
125
  applicationIdentifier,
126
126
  subscriberHash: props.subscriberHash,
127
+ contextHash: props.contextHash,
127
128
  backendUrl: props.backendUrl,
128
129
  socketUrl: props.socketUrl,
129
130
  subscriber,
130
- defaultSchedule: props.defaultSchedule
131
+ defaultSchedule: props.defaultSchedule,
132
+ context: props.context
131
133
  };
132
134
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_NovuProvider.InternalNovuProvider, { ...providerProps, userAgentType: "components", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InboxChild, { ...propsWithoutSubscriberId, applicationIdentifier, subscriber }) });
133
135
  });
@@ -145,10 +147,12 @@ var InboxChild = (0, import_Renderer.withRenderer)(
145
147
  // for keyless we provide an empty string, the api will generate a identifier
146
148
  subscriberId,
147
149
  subscriberHash,
150
+ contextHash,
148
151
  backendUrl,
149
152
  socketUrl,
150
153
  subscriber,
151
- defaultSchedule
154
+ defaultSchedule,
155
+ context
152
156
  } = props;
153
157
  const novu = (0, import_NovuProvider.useNovu)();
154
158
  const options = (0, import_react.useMemo)(() => {
@@ -163,10 +167,12 @@ var InboxChild = (0, import_Renderer.withRenderer)(
163
167
  options: {
164
168
  applicationIdentifier,
165
169
  subscriberHash,
170
+ contextHash,
166
171
  backendUrl,
167
172
  socketUrl,
168
173
  subscriber: (0, import_internal.buildSubscriber)({ subscriberId, subscriber }),
169
- defaultSchedule
174
+ defaultSchedule,
175
+ context
170
176
  }
171
177
  };
172
178
  }, [
@@ -179,9 +185,11 @@ var InboxChild = (0, import_Renderer.withRenderer)(
179
185
  applicationIdentifier,
180
186
  subscriberId,
181
187
  subscriberHash,
188
+ contextHash,
182
189
  backendUrl,
183
190
  socketUrl,
184
- subscriber
191
+ subscriber,
192
+ context
185
193
  ]);
186
194
  if (isWithChildrenProps(props)) {
187
195
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_NovuUI.NovuUI, { options, novu, children: props.children });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import { StandardNovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport React, { useMemo } from 'react';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { DefaultInboxProps, DefaultProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst DefaultInbox = (props: DefaultInboxProps) => {\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placement,\n placementOffset,\n } = props;\n const { novuUI } = useNovuUI();\n const { mountElement } = useRenderer();\n\n const mount = React.useCallback(\n (element: HTMLElement) => {\n if (renderNotification) {\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderNotification: renderNotification\n ? (el, notification) => mountElement(el, renderNotification(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n }\n\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderAvatar: renderAvatar ? (el, notification) => mountElement(el, renderAvatar(notification)) : undefined,\n renderSubject: renderSubject\n ? (el, notification) => mountElement(el, renderSubject(notification))\n : undefined,\n renderBody: renderBody ? (el, notification) => mountElement(el, renderBody(notification)) : undefined,\n renderDefaultActions: renderDefaultActions\n ? (el, notification) => mountElement(el, renderDefaultActions(notification))\n : undefined,\n renderCustomActions: renderCustomActions\n ? (el, notification) => mountElement(el, renderCustomActions(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n },\n [\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n\nexport const Inbox = React.memo((props: InboxProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriber = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = props.applicationIdentifier ? props.applicationIdentifier : ''; // for keyless we provide an empty string, the api will generate a identifier\n const novu = useUnsafeNovu();\n\n if (novu) {\n return (\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n );\n }\n\n const providerProps = {\n applicationIdentifier,\n subscriberHash: props.subscriberHash,\n backendUrl: props.backendUrl,\n socketUrl: props.socketUrl,\n subscriber,\n defaultSchedule: props.defaultSchedule,\n } satisfies StandardNovuOptions;\n\n return (\n <InternalNovuProvider {...providerProps} userAgentType=\"components\">\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n </InternalNovuProvider>\n );\n});\n\nconst InboxChild = withRenderer(\n React.memo((props: InboxProps) => {\n const {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n applicationIdentifier = '', // for keyless we provide an empty string, the api will generate a identifier\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber,\n defaultSchedule,\n } = props;\n const novu = useNovu();\n\n const options = useMemo(() => {\n return {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n options: {\n applicationIdentifier,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber: buildSubscriber({ subscriberId, subscriber }),\n defaultSchedule,\n },\n };\n }, [\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber,\n ]);\n\n if (isWithChildrenProps(props)) {\n return (\n <NovuUI options={options} novu={novu}>\n {props.children}\n </NovuUI>\n );\n }\n\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n } = props;\n\n return (\n <NovuUI options={options} novu={novu}>\n <DefaultInbox\n open={open}\n renderNotification={renderNotification}\n renderAvatar={renderAvatar}\n renderSubject={renderSubject}\n renderBody={renderBody}\n renderDefaultActions={renderDefaultActions}\n renderCustomActions={renderCustomActions}\n renderBell={renderBell}\n onNotificationClick={onNotificationClick}\n onPrimaryActionClick={onPrimaryActionClick}\n onSecondaryActionClick={onSecondaryActionClick}\n placement={placement}\n placementOffset={placementOffset}\n />\n </NovuUI>\n );\n })\n);\n\nfunction isWithChildrenProps(props: InboxProps): props is WithChildrenProps {\n return 'children' in props;\n}\n"],"mappings":"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","names":["React"]}
1
+ {"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import { StandardNovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport React, { useMemo } from 'react';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { DefaultInboxProps, DefaultProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst DefaultInbox = (props: DefaultInboxProps) => {\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placement,\n placementOffset,\n } = props;\n const { novuUI } = useNovuUI();\n const { mountElement } = useRenderer();\n\n const mount = React.useCallback(\n (element: HTMLElement) => {\n if (renderNotification) {\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderNotification: renderNotification\n ? (el, notification) => mountElement(el, renderNotification(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n }\n\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderAvatar: renderAvatar ? (el, notification) => mountElement(el, renderAvatar(notification)) : undefined,\n renderSubject: renderSubject\n ? (el, notification) => mountElement(el, renderSubject(notification))\n : undefined,\n renderBody: renderBody ? (el, notification) => mountElement(el, renderBody(notification)) : undefined,\n renderDefaultActions: renderDefaultActions\n ? (el, notification) => mountElement(el, renderDefaultActions(notification))\n : undefined,\n renderCustomActions: renderCustomActions\n ? (el, notification) => mountElement(el, renderCustomActions(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n },\n [\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n\nexport const Inbox = React.memo((props: InboxProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriber = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = props.applicationIdentifier ? props.applicationIdentifier : ''; // for keyless we provide an empty string, the api will generate a identifier\n const novu = useUnsafeNovu();\n\n if (novu) {\n return (\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n );\n }\n\n const providerProps = {\n applicationIdentifier,\n subscriberHash: props.subscriberHash,\n contextHash: props.contextHash,\n backendUrl: props.backendUrl,\n socketUrl: props.socketUrl,\n subscriber,\n defaultSchedule: props.defaultSchedule,\n context: props.context,\n } satisfies StandardNovuOptions;\n\n return (\n <InternalNovuProvider {...providerProps} userAgentType=\"components\">\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n </InternalNovuProvider>\n );\n});\n\nconst InboxChild = withRenderer(\n React.memo((props: InboxProps) => {\n const {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n applicationIdentifier = '', // for keyless we provide an empty string, the api will generate a identifier\n subscriberId,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber,\n defaultSchedule,\n context,\n } = props;\n const novu = useNovu();\n\n const options = useMemo(() => {\n return {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n options: {\n applicationIdentifier,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber: buildSubscriber({ subscriberId, subscriber }),\n defaultSchedule,\n context,\n },\n };\n }, [\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber,\n context,\n ]);\n\n if (isWithChildrenProps(props)) {\n return (\n <NovuUI options={options} novu={novu}>\n {props.children}\n </NovuUI>\n );\n }\n\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n } = props;\n\n return (\n <NovuUI options={options} novu={novu}>\n <DefaultInbox\n open={open}\n renderNotification={renderNotification}\n renderAvatar={renderAvatar}\n renderSubject={renderSubject}\n renderBody={renderBody}\n renderDefaultActions={renderDefaultActions}\n renderCustomActions={renderCustomActions}\n renderBell={renderBell}\n onNotificationClick={onNotificationClick}\n onPrimaryActionClick={onPrimaryActionClick}\n onSecondaryActionClick={onSecondaryActionClick}\n placement={placement}\n placementOffset={placementOffset}\n />\n </NovuUI>\n );\n })\n);\n\nfunction isWithChildrenProps(props: InboxProps): props is WithChildrenProps {\n return 'children' in props;\n}\n"],"mappings":"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","names":["React"]}
@@ -30,7 +30,7 @@ var import_js = require("@novu/js");
30
30
  var import_internal = require("@novu/js/internal");
31
31
  var import_react = require("react");
32
32
  var import_jsx_runtime = require("react/jsx-runtime");
33
- var version = "3.10.0";
33
+ var version = "3.11.0-rc.1";
34
34
  var name = "@novu/react";
35
35
  var baseUserAgent = `${name}@${version}`;
36
36
  var NovuContext = (0, import_react.createContext)(void 0);
@@ -50,28 +50,31 @@ var InternalNovuProvider = (props) => {
50
50
  const subscriberObj = (0, import_internal.buildSubscriber)({ subscriberId: props.subscriberId, subscriber: props.subscriber });
51
51
  const {
52
52
  children,
53
- subscriberId,
54
53
  subscriberHash,
54
+ contextHash,
55
55
  backendUrl,
56
56
  apiUrl,
57
57
  socketUrl,
58
58
  useCache,
59
59
  userAgentType,
60
- defaultSchedule
60
+ defaultSchedule,
61
+ context
61
62
  } = props;
62
63
  const novu = (0, import_react.useMemo)(
63
64
  () => new import_js.Novu({
64
65
  applicationIdentifier,
65
66
  subscriberHash,
67
+ contextHash,
66
68
  backendUrl,
67
69
  apiUrl,
68
70
  socketUrl,
69
71
  useCache,
70
72
  __userAgent: `${baseUserAgent} ${userAgentType}`,
71
73
  subscriber: subscriberObj,
72
- defaultSchedule
74
+ defaultSchedule,
75
+ context
73
76
  }),
74
- [applicationIdentifier, subscriberHash, backendUrl, apiUrl, socketUrl, useCache, userAgentType]
77
+ [applicationIdentifier, backendUrl, apiUrl, socketUrl, useCache, userAgentType]
75
78
  );
76
79
  (0, import_react.useEffect)(() => {
77
80
  novu.changeSubscriber({
@@ -79,6 +82,14 @@ var InternalNovuProvider = (props) => {
79
82
  subscriberHash: props.subscriberHash
80
83
  });
81
84
  }, [subscriberObj.subscriberId, props.subscriberHash, novu]);
85
+ (0, import_react.useEffect)(() => {
86
+ if (context && contextHash) {
87
+ novu.changeContext({
88
+ context,
89
+ contextHash
90
+ });
91
+ }
92
+ }, [context, contextHash, novu]);
82
93
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NovuContext.Provider, { value: novu, children });
83
94
  };
84
95
  var useNovu = () => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/NovuProvider.tsx"],"sourcesContent":["import { Novu, NovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport { createContext, ReactNode, useContext, useEffect, useMemo } from 'react';\n\n// @ts-expect-error\nconst version = PACKAGE_VERSION;\n// @ts-expect-error\nconst name = PACKAGE_NAME;\nconst baseUserAgent = `${name}@${version}`;\n\nexport type NovuProviderProps = NovuOptions & {\n children: ReactNode;\n};\n\nconst NovuContext = createContext<Novu | undefined>(undefined);\n\nexport const NovuProvider = (props: NovuProviderProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriberObj = buildSubscriber({ subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = propsWithoutSubscriberId.applicationIdentifier\n ? propsWithoutSubscriberId.applicationIdentifier\n : '';\n\n const providerProps: NovuProviderProps = {\n ...propsWithoutSubscriberId,\n applicationIdentifier,\n subscriber: subscriberObj,\n };\n\n return (\n <InternalNovuProvider {...providerProps} applicationIdentifier={applicationIdentifier} userAgentType=\"hooks\">\n {props.children}\n </InternalNovuProvider>\n );\n};\n\n/**\n * @internal Should be used internally not to be exposed outside of the library\n * This is needed to differentiate between the hooks and components user agents\n * Better to use this internally to avoid confusion.\n */\nexport const InternalNovuProvider = (props: NovuProviderProps & { userAgentType: 'components' | 'hooks' }) => {\n const applicationIdentifier = props.applicationIdentifier || '';\n const subscriberObj = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n\n const {\n children,\n subscriberId,\n subscriberHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n userAgentType,\n defaultSchedule,\n } = props;\n\n const novu = useMemo(\n () =>\n new Novu({\n applicationIdentifier,\n subscriberHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n __userAgent: `${baseUserAgent} ${userAgentType}`,\n subscriber: subscriberObj,\n defaultSchedule,\n }),\n [applicationIdentifier, subscriberHash, backendUrl, apiUrl, socketUrl, useCache, userAgentType]\n );\n\n useEffect(() => {\n novu.changeSubscriber({\n subscriber: subscriberObj,\n subscriberHash: props.subscriberHash,\n });\n }, [subscriberObj.subscriberId, props.subscriberHash, novu]);\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAkC;AAClC,sBAAgC;AAChC,mBAAyE;AA4BrE;AAzBJ,IAAM,UAAU;AAEhB,IAAM,OAAO;AACb,IAAM,gBAAgB,GAAG,IAAI,IAAI,OAAO;AAMxC,IAAM,kBAAc,4BAAgC,MAAS;AAEtD,IAAM,eAAe,CAAC,UAA6B;AACxD,QAAM,EAAE,cAAc,GAAG,yBAAyB,IAAI;AACtD,QAAM,oBAAgB,iCAAgB,EAAE,cAAc,YAAY,MAAM,WAAW,CAAC;AACpF,QAAM,wBAAwB,yBAAyB,wBACnD,yBAAyB,wBACzB;AAEJ,QAAM,gBAAmC;AAAA,IACvC,GAAG;AAAA,IACH;AAAA,IACA,YAAY;AAAA,EACd;AAEA,SACE,4CAAC,wBAAsB,GAAG,eAAe,uBAA8C,eAAc,SAClG,gBAAM,UACT;AAEJ;AAOO,IAAM,uBAAuB,CAAC,UAAyE;AAC5G,QAAM,wBAAwB,MAAM,yBAAyB;AAC7D,QAAM,oBAAgB,iCAAgB,EAAE,cAAc,MAAM,cAAc,YAAY,MAAM,WAAW,CAAC;AAExG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,WAAO;AAAA,IACX,MACE,IAAI,eAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,GAAG,aAAa,IAAI,aAAa;AAAA,MAC9C,YAAY;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,IACH,CAAC,uBAAuB,gBAAgB,YAAY,QAAQ,WAAW,UAAU,aAAa;AAAA,EAChG;AAEA,8BAAU,MAAM;AACd,SAAK,iBAAiB;AAAA,MACpB,YAAY;AAAA,MACZ,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,cAAc,MAAM,gBAAgB,IAAI,CAAC;AAE3D,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AACtD;AAEO,IAAM,UAAU,MAAM;AAC3B,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,IAAM,gBAAgB,MAAM;AACjC,QAAM,cAAU,yBAAW,WAAW;AAEtC,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/NovuProvider.tsx"],"sourcesContent":["import { Novu, NovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport { createContext, ReactNode, useContext, useEffect, useMemo } from 'react';\n\n// @ts-expect-error\nconst version = PACKAGE_VERSION;\n// @ts-expect-error\nconst name = PACKAGE_NAME;\nconst baseUserAgent = `${name}@${version}`;\n\nexport type NovuProviderProps = NovuOptions & {\n children: ReactNode;\n};\n\nconst NovuContext = createContext<Novu | undefined>(undefined);\n\nexport const NovuProvider = (props: NovuProviderProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriberObj = buildSubscriber({ subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = propsWithoutSubscriberId.applicationIdentifier\n ? propsWithoutSubscriberId.applicationIdentifier\n : '';\n\n const providerProps: NovuProviderProps = {\n ...propsWithoutSubscriberId,\n applicationIdentifier,\n subscriber: subscriberObj,\n };\n\n return (\n <InternalNovuProvider {...providerProps} applicationIdentifier={applicationIdentifier} userAgentType=\"hooks\">\n {props.children}\n </InternalNovuProvider>\n );\n};\n\n/**\n * @internal Should be used internally not to be exposed outside of the library\n * This is needed to differentiate between the hooks and components user agents\n * Better to use this internally to avoid confusion.\n */\nexport const InternalNovuProvider = (props: NovuProviderProps & { userAgentType: 'components' | 'hooks' }) => {\n const applicationIdentifier = props.applicationIdentifier || '';\n const subscriberObj = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n\n const {\n children,\n subscriberHash,\n contextHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n userAgentType,\n defaultSchedule,\n context,\n } = props;\n\n const novu = useMemo(\n () =>\n new Novu({\n applicationIdentifier,\n subscriberHash,\n contextHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n __userAgent: `${baseUserAgent} ${userAgentType}`,\n subscriber: subscriberObj,\n defaultSchedule,\n context,\n }),\n [applicationIdentifier, backendUrl, apiUrl, socketUrl, useCache, userAgentType]\n );\n\n useEffect(() => {\n novu.changeSubscriber({\n subscriber: subscriberObj,\n subscriberHash: props.subscriberHash,\n });\n }, [subscriberObj.subscriberId, props.subscriberHash, novu]);\n\n useEffect(() => {\n if (context && contextHash) {\n novu.changeContext({\n context,\n contextHash,\n });\n }\n }, [context, contextHash, novu]);\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAkC;AAClC,sBAAgC;AAChC,mBAAyE;AA4BrE;AAzBJ,IAAM,UAAU;AAEhB,IAAM,OAAO;AACb,IAAM,gBAAgB,GAAG,IAAI,IAAI,OAAO;AAMxC,IAAM,kBAAc,4BAAgC,MAAS;AAEtD,IAAM,eAAe,CAAC,UAA6B;AACxD,QAAM,EAAE,cAAc,GAAG,yBAAyB,IAAI;AACtD,QAAM,oBAAgB,iCAAgB,EAAE,cAAc,YAAY,MAAM,WAAW,CAAC;AACpF,QAAM,wBAAwB,yBAAyB,wBACnD,yBAAyB,wBACzB;AAEJ,QAAM,gBAAmC;AAAA,IACvC,GAAG;AAAA,IACH;AAAA,IACA,YAAY;AAAA,EACd;AAEA,SACE,4CAAC,wBAAsB,GAAG,eAAe,uBAA8C,eAAc,SAClG,gBAAM,UACT;AAEJ;AAOO,IAAM,uBAAuB,CAAC,UAAyE;AAC5G,QAAM,wBAAwB,MAAM,yBAAyB;AAC7D,QAAM,oBAAgB,iCAAgB,EAAE,cAAc,MAAM,cAAc,YAAY,MAAM,WAAW,CAAC;AAExG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,WAAO;AAAA,IACX,MACE,IAAI,eAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,GAAG,aAAa,IAAI,aAAa;AAAA,MAC9C,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,CAAC,uBAAuB,YAAY,QAAQ,WAAW,UAAU,aAAa;AAAA,EAChF;AAEA,8BAAU,MAAM;AACd,SAAK,iBAAiB;AAAA,MACpB,YAAY;AAAA,MACZ,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,cAAc,MAAM,gBAAgB,IAAI,CAAC;AAE3D,8BAAU,MAAM;AACd,QAAI,WAAW,aAAa;AAC1B,WAAK,cAAc;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,SAAS,aAAa,IAAI,CAAC;AAE/B,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AACtD;AAEO,IAAM,UAAU,MAAM;AAC3B,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,IAAM,gBAAgB,MAAM;AACjC,QAAM,cAAU,yBAAW,WAAW;AAEtC,SAAO;AACT;","names":[]}
@@ -32,7 +32,7 @@ var useWebSocketEvent = ({
32
32
  eventHandler: onMessage
33
33
  }) => {
34
34
  const novu = (0, import_NovuProvider.useNovu)();
35
- const channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:e=${webSocketEvent}`;
35
+ const channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:c=${novu.contextKey}:e=${webSocketEvent}`;
36
36
  const { postMessage } = (0, import_useBrowserTabsChannel.useBrowserTabsChannel)({
37
37
  channelName,
38
38
  onMessage
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { requestLock } from '../../utils/requestLock';\nimport { useNovu } from '../NovuProvider';\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 channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:e=${webSocketEvent}`;\n\n const { postMessage } = useBrowserTabsChannel({\n channelName,\n onMessage,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n let cleanup: () => void;\n const resolveLock = requestLock(channelName, () => {\n cleanup = novu.on(webSocketEvent, updateReadCount);\n });\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n\n resolveLock();\n };\n }, []);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA0B;AAC1B,yBAA4B;AAC5B,0BAAwB;AACxB,mCAAsC;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAChB,MAGM;AACJ,QAAM,WAAO,6BAAQ;AACrB,QAAM,cAAc,sBAAsB,KAAK,qBAAqB,MAAM,KAAK,YAAY,MAAM,cAAc;AAE/G,QAAM,EAAE,YAAY,QAAI,oDAAsB;AAAA,IAC5C;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,8BAAU,MAAM;AACd,QAAI;AACJ,UAAM,kBAAc,gCAAY,aAAa,MAAM;AACjD,gBAAU,KAAK,GAAG,gBAAgB,eAAe;AAAA,IACnD,CAAC;AAED,WAAO,MAAM;AACX,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV;AAEA,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AACP;","names":[]}
1
+ {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { requestLock } from '../../utils/requestLock';\nimport { useNovu } from '../NovuProvider';\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 channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:c=${novu.contextKey}:e=${webSocketEvent}`;\n\n const { postMessage } = useBrowserTabsChannel({\n channelName,\n onMessage,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n let cleanup: () => void;\n const resolveLock = requestLock(channelName, () => {\n cleanup = novu.on(webSocketEvent, updateReadCount);\n });\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n\n resolveLock();\n };\n }, []);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA0B;AAC1B,yBAA4B;AAC5B,0BAAwB;AACxB,mCAAsC;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAChB,MAGM;AACJ,QAAM,WAAO,6BAAQ;AACrB,QAAM,cAAc,sBAAsB,KAAK,qBAAqB,MAAM,KAAK,YAAY,MAAM,KAAK,UAAU,MAAM,cAAc;AAEpI,QAAM,EAAE,YAAY,QAAI,oDAAsB;AAAA,IAC5C;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,8BAAU,MAAM;AACd,QAAI;AACJ,UAAM,kBAAc,gCAAY,aAAa,MAAM;AACjD,gBAAU,KAAK,GAAG,gBAAgB,eAAe;AAAA,IACnD,CAAC;AAED,WAAO,MAAM;AACX,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV;AAEA,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AACP;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/types.ts"],"sourcesContent":["import type { DefaultSchedule, Subscriber, UnreadCount } from '@novu/js';\nimport type {\n IconKey,\n InboxProps,\n Theme as JsTheme,\n Localization,\n Notification,\n NotificationActionClickHandler,\n NotificationClickHandler,\n PreferenceGroups,\n PreferencesFilter,\n PreferencesSort,\n RouterPush,\n Tab,\n} from '@novu/js/ui';\nimport type { ReactNode } from 'react';\n\nexport type NotificationsRenderer = (notification: Notification) => React.ReactNode;\nexport type AvatarRenderer = (notification: Notification) => React.ReactNode;\nexport type SubjectRenderer = (notification: Notification) => React.ReactNode;\nexport type BodyRenderer = (notification: Notification) => React.ReactNode;\nexport type DefaultActionsRenderer = (notification: Notification) => React.ReactNode;\nexport type CustomActionsRenderer = (notification: Notification) => React.ReactNode;\nexport type BellRenderer = (unreadCount: UnreadCount) => React.ReactNode;\n\nexport type ReactIconRendererProps = { class?: string };\nexport type ReactIconRenderer = (props: ReactIconRendererProps) => ReactNode;\n\nexport type ReactIconOverrides = {\n [key in IconKey]?: ReactIconRenderer;\n};\n\nexport type ReactTheme = Omit<JsTheme, 'icons'> & {\n icons?: ReactIconOverrides;\n};\n\nexport type ReactAppearance = ReactTheme & {\n baseTheme?: JsTheme | JsTheme[];\n};\n\nexport type DefaultInboxProps = {\n open?: boolean;\n renderNotification?: NotificationsRenderer;\n renderAvatar?: AvatarRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderDefaultActions?: DefaultActionsRenderer;\n renderCustomActions?: CustomActionsRenderer;\n renderBell?: BellRenderer;\n onNotificationClick?: NotificationClickHandler;\n onPrimaryActionClick?: NotificationActionClickHandler;\n onSecondaryActionClick?: NotificationActionClickHandler;\n placement?: InboxProps['placement'];\n placementOffset?: InboxProps['placementOffset'];\n};\n\ntype StandardBaseProps = {\n subscriberHash?: string;\n backendUrl?: string;\n socketUrl?: string;\n appearance?: ReactAppearance;\n localization?: Localization;\n tabs?: Array<Tab>;\n preferencesFilter?: PreferencesFilter;\n preferenceGroups?: PreferenceGroups;\n preferencesSort?: PreferencesSort;\n defaultSchedule?: DefaultSchedule;\n routerPush?: RouterPush;\n} & (\n | {\n // TODO: Backward compatibility support - remove in future versions (see NV-5801)\n /** @deprecated Use subscriber prop instead */\n subscriberId: string;\n subscriber?: never;\n applicationIdentifier: string;\n }\n | {\n subscriber: Subscriber | string;\n subscriberId?: never;\n applicationIdentifier: string;\n }\n | {\n // Keyless mode - no subscriber or subscriberId or applicationIdentifier\n subscriber?: never;\n subscriberId?: never;\n applicationIdentifier?: never;\n }\n);\n\nexport type BaseProps = StandardBaseProps;\n\nexport type NotificationRendererProps = {\n renderNotification: NotificationsRenderer;\n renderAvatar?: never;\n renderSubject?: never;\n renderBody?: never;\n renderDefaultActions?: never;\n renderCustomActions?: never;\n};\n\nexport type SubjectBodyRendererProps = {\n renderNotification?: never;\n renderAvatar?: AvatarRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderDefaultActions?: DefaultActionsRenderer;\n renderCustomActions?: CustomActionsRenderer;\n};\n\nexport type NoRendererProps = {\n renderNotification?: undefined;\n renderAvatar?: undefined;\n renderSubject?: undefined;\n renderBody?: undefined;\n renderDefaultActions?: undefined;\n renderCustomActions?: undefined;\n};\n\nexport type DefaultProps = BaseProps &\n DefaultInboxProps & {\n children?: never;\n } & (NotificationRendererProps | SubjectBodyRendererProps | NoRendererProps);\n\nexport type WithChildrenProps = BaseProps & {\n children: React.ReactNode;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/types.ts"],"sourcesContent":["import type { Context, DefaultSchedule, Subscriber, UnreadCount } from '@novu/js';\nimport type {\n IconKey,\n InboxProps,\n Theme as JsTheme,\n Localization,\n Notification,\n NotificationActionClickHandler,\n NotificationClickHandler,\n PreferenceGroups,\n PreferencesFilter,\n PreferencesSort,\n RouterPush,\n Tab,\n} from '@novu/js/ui';\nimport type { ReactNode } from 'react';\n\nexport type NotificationsRenderer = (notification: Notification) => React.ReactNode;\nexport type AvatarRenderer = (notification: Notification) => React.ReactNode;\nexport type SubjectRenderer = (notification: Notification) => React.ReactNode;\nexport type BodyRenderer = (notification: Notification) => React.ReactNode;\nexport type DefaultActionsRenderer = (notification: Notification) => React.ReactNode;\nexport type CustomActionsRenderer = (notification: Notification) => React.ReactNode;\nexport type BellRenderer = (unreadCount: UnreadCount) => React.ReactNode;\n\nexport type ReactIconRendererProps = { class?: string };\nexport type ReactIconRenderer = (props: ReactIconRendererProps) => ReactNode;\n\nexport type ReactIconOverrides = {\n [key in IconKey]?: ReactIconRenderer;\n};\n\nexport type ReactTheme = Omit<JsTheme, 'icons'> & {\n icons?: ReactIconOverrides;\n};\n\nexport type ReactAppearance = ReactTheme & {\n baseTheme?: JsTheme | JsTheme[];\n};\n\nexport type DefaultInboxProps = {\n open?: boolean;\n renderNotification?: NotificationsRenderer;\n renderAvatar?: AvatarRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderDefaultActions?: DefaultActionsRenderer;\n renderCustomActions?: CustomActionsRenderer;\n renderBell?: BellRenderer;\n onNotificationClick?: NotificationClickHandler;\n onPrimaryActionClick?: NotificationActionClickHandler;\n onSecondaryActionClick?: NotificationActionClickHandler;\n placement?: InboxProps['placement'];\n placementOffset?: InboxProps['placementOffset'];\n};\n\ntype StandardBaseProps = {\n subscriberHash?: string;\n contextHash?: string;\n backendUrl?: string;\n socketUrl?: string;\n appearance?: ReactAppearance;\n localization?: Localization;\n tabs?: Array<Tab>;\n preferencesFilter?: PreferencesFilter;\n preferenceGroups?: PreferenceGroups;\n preferencesSort?: PreferencesSort;\n defaultSchedule?: DefaultSchedule;\n routerPush?: RouterPush;\n context?: Context;\n} & (\n | {\n // TODO: Backward compatibility support - remove in future versions (see NV-5801)\n /** @deprecated Use subscriber prop instead */\n subscriberId: string;\n subscriber?: never;\n applicationIdentifier: string;\n }\n | {\n subscriber: Subscriber | string;\n subscriberId?: never;\n applicationIdentifier: string;\n }\n | {\n // Keyless mode - no subscriber or subscriberId or applicationIdentifier\n subscriber?: never;\n subscriberId?: never;\n applicationIdentifier?: never;\n }\n);\n\nexport type BaseProps = StandardBaseProps;\n\nexport type NotificationRendererProps = {\n renderNotification: NotificationsRenderer;\n renderAvatar?: never;\n renderSubject?: never;\n renderBody?: never;\n renderDefaultActions?: never;\n renderCustomActions?: never;\n};\n\nexport type SubjectBodyRendererProps = {\n renderNotification?: never;\n renderAvatar?: AvatarRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderDefaultActions?: DefaultActionsRenderer;\n renderCustomActions?: CustomActionsRenderer;\n};\n\nexport type NoRendererProps = {\n renderNotification?: undefined;\n renderAvatar?: undefined;\n renderSubject?: undefined;\n renderBody?: undefined;\n renderDefaultActions?: undefined;\n renderCustomActions?: undefined;\n};\n\nexport type DefaultProps = BaseProps &\n DefaultInboxProps & {\n children?: never;\n } & (NotificationRendererProps | SubjectBodyRendererProps | NoRendererProps);\n\nexport type WithChildrenProps = BaseProps & {\n children: React.ReactNode;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,4 +1,4 @@
1
- import { UnreadCount, DefaultSchedule, Subscriber } from '@novu/js';
1
+ import { UnreadCount, DefaultSchedule, Context, Subscriber } from '@novu/js';
2
2
  import { Notification, IconKey, Theme, NotificationClickHandler, NotificationActionClickHandler, InboxProps, Localization, Tab, PreferencesFilter, PreferenceGroups, PreferencesSort, RouterPush } from '@novu/js/ui';
3
3
  import { ReactNode } from 'react';
4
4
 
@@ -39,6 +39,7 @@ type DefaultInboxProps = {
39
39
  };
40
40
  type StandardBaseProps = {
41
41
  subscriberHash?: string;
42
+ contextHash?: string;
42
43
  backendUrl?: string;
43
44
  socketUrl?: string;
44
45
  appearance?: ReactAppearance;
@@ -49,6 +50,7 @@ type StandardBaseProps = {
49
50
  preferencesSort?: PreferencesSort;
50
51
  defaultSchedule?: DefaultSchedule;
51
52
  routerPush?: RouterPush;
53
+ context?: Context;
52
54
  } & ({
53
55
  /** @deprecated Use subscriber prop instead */
54
56
  subscriberId: string;
@@ -90,10 +90,12 @@ var Inbox = React.memo((props) => {
90
90
  const providerProps = {
91
91
  applicationIdentifier,
92
92
  subscriberHash: props.subscriberHash,
93
+ contextHash: props.contextHash,
93
94
  backendUrl: props.backendUrl,
94
95
  socketUrl: props.socketUrl,
95
96
  subscriber,
96
- defaultSchedule: props.defaultSchedule
97
+ defaultSchedule: props.defaultSchedule,
98
+ context: props.context
97
99
  };
98
100
  return /* @__PURE__ */ jsx(InternalNovuProvider, { ...providerProps, userAgentType: "components", children: /* @__PURE__ */ jsx(InboxChild, { ...propsWithoutSubscriberId, applicationIdentifier, subscriber }) });
99
101
  });
@@ -111,10 +113,12 @@ var InboxChild = withRenderer(
111
113
  // for keyless we provide an empty string, the api will generate a identifier
112
114
  subscriberId,
113
115
  subscriberHash,
116
+ contextHash,
114
117
  backendUrl,
115
118
  socketUrl,
116
119
  subscriber,
117
- defaultSchedule
120
+ defaultSchedule,
121
+ context
118
122
  } = props;
119
123
  const novu = useNovu();
120
124
  const options = useMemo(() => {
@@ -129,10 +133,12 @@ var InboxChild = withRenderer(
129
133
  options: {
130
134
  applicationIdentifier,
131
135
  subscriberHash,
136
+ contextHash,
132
137
  backendUrl,
133
138
  socketUrl,
134
139
  subscriber: buildSubscriber({ subscriberId, subscriber }),
135
- defaultSchedule
140
+ defaultSchedule,
141
+ context
136
142
  }
137
143
  };
138
144
  }, [
@@ -145,9 +151,11 @@ var InboxChild = withRenderer(
145
151
  applicationIdentifier,
146
152
  subscriberId,
147
153
  subscriberHash,
154
+ contextHash,
148
155
  backendUrl,
149
156
  socketUrl,
150
- subscriber
157
+ subscriber,
158
+ context
151
159
  ]);
152
160
  if (isWithChildrenProps(props)) {
153
161
  return /* @__PURE__ */ jsx(NovuUI, { options, novu, children: props.children });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import { StandardNovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport React, { useMemo } from 'react';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { DefaultInboxProps, DefaultProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst DefaultInbox = (props: DefaultInboxProps) => {\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placement,\n placementOffset,\n } = props;\n const { novuUI } = useNovuUI();\n const { mountElement } = useRenderer();\n\n const mount = React.useCallback(\n (element: HTMLElement) => {\n if (renderNotification) {\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderNotification: renderNotification\n ? (el, notification) => mountElement(el, renderNotification(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n }\n\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderAvatar: renderAvatar ? (el, notification) => mountElement(el, renderAvatar(notification)) : undefined,\n renderSubject: renderSubject\n ? (el, notification) => mountElement(el, renderSubject(notification))\n : undefined,\n renderBody: renderBody ? (el, notification) => mountElement(el, renderBody(notification)) : undefined,\n renderDefaultActions: renderDefaultActions\n ? (el, notification) => mountElement(el, renderDefaultActions(notification))\n : undefined,\n renderCustomActions: renderCustomActions\n ? (el, notification) => mountElement(el, renderCustomActions(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n },\n [\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n\nexport const Inbox = React.memo((props: InboxProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriber = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = props.applicationIdentifier ? props.applicationIdentifier : ''; // for keyless we provide an empty string, the api will generate a identifier\n const novu = useUnsafeNovu();\n\n if (novu) {\n return (\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n );\n }\n\n const providerProps = {\n applicationIdentifier,\n subscriberHash: props.subscriberHash,\n backendUrl: props.backendUrl,\n socketUrl: props.socketUrl,\n subscriber,\n defaultSchedule: props.defaultSchedule,\n } satisfies StandardNovuOptions;\n\n return (\n <InternalNovuProvider {...providerProps} userAgentType=\"components\">\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n </InternalNovuProvider>\n );\n});\n\nconst InboxChild = withRenderer(\n React.memo((props: InboxProps) => {\n const {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n applicationIdentifier = '', // for keyless we provide an empty string, the api will generate a identifier\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber,\n defaultSchedule,\n } = props;\n const novu = useNovu();\n\n const options = useMemo(() => {\n return {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n options: {\n applicationIdentifier,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber: buildSubscriber({ subscriberId, subscriber }),\n defaultSchedule,\n },\n };\n }, [\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber,\n ]);\n\n if (isWithChildrenProps(props)) {\n return (\n <NovuUI options={options} novu={novu}>\n {props.children}\n </NovuUI>\n );\n }\n\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n } = props;\n\n return (\n <NovuUI options={options} novu={novu}>\n <DefaultInbox\n open={open}\n renderNotification={renderNotification}\n renderAvatar={renderAvatar}\n renderSubject={renderSubject}\n renderBody={renderBody}\n renderDefaultActions={renderDefaultActions}\n renderCustomActions={renderCustomActions}\n renderBell={renderBell}\n onNotificationClick={onNotificationClick}\n onPrimaryActionClick={onPrimaryActionClick}\n onSecondaryActionClick={onSecondaryActionClick}\n placement={placement}\n placementOffset={placementOffset}\n />\n </NovuUI>\n );\n })\n);\n\nfunction isWithChildrenProps(props: InboxProps): props is WithChildrenProps {\n return 'children' in props;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import { StandardNovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport React, { useMemo } from 'react';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { DefaultInboxProps, DefaultProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst DefaultInbox = (props: DefaultInboxProps) => {\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placement,\n placementOffset,\n } = props;\n const { novuUI } = useNovuUI();\n const { mountElement } = useRenderer();\n\n const mount = React.useCallback(\n (element: HTMLElement) => {\n if (renderNotification) {\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderNotification: renderNotification\n ? (el, notification) => mountElement(el, renderNotification(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n }\n\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderAvatar: renderAvatar ? (el, notification) => mountElement(el, renderAvatar(notification)) : undefined,\n renderSubject: renderSubject\n ? (el, notification) => mountElement(el, renderSubject(notification))\n : undefined,\n renderBody: renderBody ? (el, notification) => mountElement(el, renderBody(notification)) : undefined,\n renderDefaultActions: renderDefaultActions\n ? (el, notification) => mountElement(el, renderDefaultActions(notification))\n : undefined,\n renderCustomActions: renderCustomActions\n ? (el, notification) => mountElement(el, renderCustomActions(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n },\n [\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n\nexport const Inbox = React.memo((props: InboxProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriber = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = props.applicationIdentifier ? props.applicationIdentifier : ''; // for keyless we provide an empty string, the api will generate a identifier\n const novu = useUnsafeNovu();\n\n if (novu) {\n return (\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n );\n }\n\n const providerProps = {\n applicationIdentifier,\n subscriberHash: props.subscriberHash,\n contextHash: props.contextHash,\n backendUrl: props.backendUrl,\n socketUrl: props.socketUrl,\n subscriber,\n defaultSchedule: props.defaultSchedule,\n context: props.context,\n } satisfies StandardNovuOptions;\n\n return (\n <InternalNovuProvider {...providerProps} userAgentType=\"components\">\n <InboxChild {...propsWithoutSubscriberId} applicationIdentifier={applicationIdentifier} subscriber={subscriber} />\n </InternalNovuProvider>\n );\n});\n\nconst InboxChild = withRenderer(\n React.memo((props: InboxProps) => {\n const {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n applicationIdentifier = '', // for keyless we provide an empty string, the api will generate a identifier\n subscriberId,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber,\n defaultSchedule,\n context,\n } = props;\n const novu = useNovu();\n\n const options = useMemo(() => {\n return {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n routerPush,\n options: {\n applicationIdentifier,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber: buildSubscriber({ subscriberId, subscriber }),\n defaultSchedule,\n context,\n },\n };\n }, [\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n preferencesSort,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n contextHash,\n backendUrl,\n socketUrl,\n subscriber,\n context,\n ]);\n\n if (isWithChildrenProps(props)) {\n return (\n <NovuUI options={options} novu={novu}>\n {props.children}\n </NovuUI>\n );\n }\n\n const {\n open,\n renderNotification,\n renderAvatar,\n renderSubject,\n renderBody,\n renderDefaultActions,\n renderCustomActions,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n } = props;\n\n return (\n <NovuUI options={options} novu={novu}>\n <DefaultInbox\n open={open}\n renderNotification={renderNotification}\n renderAvatar={renderAvatar}\n renderSubject={renderSubject}\n renderBody={renderBody}\n renderDefaultActions={renderDefaultActions}\n renderCustomActions={renderCustomActions}\n renderBell={renderBell}\n onNotificationClick={onNotificationClick}\n onPrimaryActionClick={onPrimaryActionClick}\n onSecondaryActionClick={onSecondaryActionClick}\n placement={placement}\n placementOffset={placementOffset}\n />\n </NovuUI>\n );\n })\n);\n\nfunction isWithChildrenProps(props: InboxProps): props is WithChildrenProps {\n return 'children' in props;\n}\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import { Novu } from "@novu/js";
3
3
  import { buildSubscriber } from "@novu/js/internal";
4
4
  import { createContext, useContext, useEffect, useMemo } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
- var version = "3.10.0";
6
+ var version = "3.11.0-rc.1";
7
7
  var name = "@novu/react";
8
8
  var baseUserAgent = `${name}@${version}`;
9
9
  var NovuContext = createContext(void 0);
@@ -23,28 +23,31 @@ var InternalNovuProvider = (props) => {
23
23
  const subscriberObj = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });
24
24
  const {
25
25
  children,
26
- subscriberId,
27
26
  subscriberHash,
27
+ contextHash,
28
28
  backendUrl,
29
29
  apiUrl,
30
30
  socketUrl,
31
31
  useCache,
32
32
  userAgentType,
33
- defaultSchedule
33
+ defaultSchedule,
34
+ context
34
35
  } = props;
35
36
  const novu = useMemo(
36
37
  () => new Novu({
37
38
  applicationIdentifier,
38
39
  subscriberHash,
40
+ contextHash,
39
41
  backendUrl,
40
42
  apiUrl,
41
43
  socketUrl,
42
44
  useCache,
43
45
  __userAgent: `${baseUserAgent} ${userAgentType}`,
44
46
  subscriber: subscriberObj,
45
- defaultSchedule
47
+ defaultSchedule,
48
+ context
46
49
  }),
47
- [applicationIdentifier, subscriberHash, backendUrl, apiUrl, socketUrl, useCache, userAgentType]
50
+ [applicationIdentifier, backendUrl, apiUrl, socketUrl, useCache, userAgentType]
48
51
  );
49
52
  useEffect(() => {
50
53
  novu.changeSubscriber({
@@ -52,6 +55,14 @@ var InternalNovuProvider = (props) => {
52
55
  subscriberHash: props.subscriberHash
53
56
  });
54
57
  }, [subscriberObj.subscriberId, props.subscriberHash, novu]);
58
+ useEffect(() => {
59
+ if (context && contextHash) {
60
+ novu.changeContext({
61
+ context,
62
+ contextHash
63
+ });
64
+ }
65
+ }, [context, contextHash, novu]);
55
66
  return /* @__PURE__ */ jsx(NovuContext.Provider, { value: novu, children });
56
67
  };
57
68
  var useNovu = () => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/NovuProvider.tsx"],"sourcesContent":["import { Novu, NovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport { createContext, ReactNode, useContext, useEffect, useMemo } from 'react';\n\n// @ts-expect-error\nconst version = PACKAGE_VERSION;\n// @ts-expect-error\nconst name = PACKAGE_NAME;\nconst baseUserAgent = `${name}@${version}`;\n\nexport type NovuProviderProps = NovuOptions & {\n children: ReactNode;\n};\n\nconst NovuContext = createContext<Novu | undefined>(undefined);\n\nexport const NovuProvider = (props: NovuProviderProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriberObj = buildSubscriber({ subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = propsWithoutSubscriberId.applicationIdentifier\n ? propsWithoutSubscriberId.applicationIdentifier\n : '';\n\n const providerProps: NovuProviderProps = {\n ...propsWithoutSubscriberId,\n applicationIdentifier,\n subscriber: subscriberObj,\n };\n\n return (\n <InternalNovuProvider {...providerProps} applicationIdentifier={applicationIdentifier} userAgentType=\"hooks\">\n {props.children}\n </InternalNovuProvider>\n );\n};\n\n/**\n * @internal Should be used internally not to be exposed outside of the library\n * This is needed to differentiate between the hooks and components user agents\n * Better to use this internally to avoid confusion.\n */\nexport const InternalNovuProvider = (props: NovuProviderProps & { userAgentType: 'components' | 'hooks' }) => {\n const applicationIdentifier = props.applicationIdentifier || '';\n const subscriberObj = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n\n const {\n children,\n subscriberId,\n subscriberHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n userAgentType,\n defaultSchedule,\n } = props;\n\n const novu = useMemo(\n () =>\n new Novu({\n applicationIdentifier,\n subscriberHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n __userAgent: `${baseUserAgent} ${userAgentType}`,\n subscriber: subscriberObj,\n defaultSchedule,\n }),\n [applicationIdentifier, subscriberHash, backendUrl, apiUrl, socketUrl, useCache, userAgentType]\n );\n\n useEffect(() => {\n novu.changeSubscriber({\n subscriber: subscriberObj,\n subscriberHash: props.subscriberHash,\n });\n }, [subscriberObj.subscriberId, props.subscriberHash, novu]);\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"],"mappings":";AAAA,SAAS,YAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,eAA0B,YAAY,WAAW,eAAe;AA4BrE;AAzBJ,IAAM,UAAU;AAEhB,IAAM,OAAO;AACb,IAAM,gBAAgB,GAAG,IAAI,IAAI,OAAO;AAMxC,IAAM,cAAc,cAAgC,MAAS;AAEtD,IAAM,eAAe,CAAC,UAA6B;AACxD,QAAM,EAAE,cAAc,GAAG,yBAAyB,IAAI;AACtD,QAAM,gBAAgB,gBAAgB,EAAE,cAAc,YAAY,MAAM,WAAW,CAAC;AACpF,QAAM,wBAAwB,yBAAyB,wBACnD,yBAAyB,wBACzB;AAEJ,QAAM,gBAAmC;AAAA,IACvC,GAAG;AAAA,IACH;AAAA,IACA,YAAY;AAAA,EACd;AAEA,SACE,oBAAC,wBAAsB,GAAG,eAAe,uBAA8C,eAAc,SAClG,gBAAM,UACT;AAEJ;AAOO,IAAM,uBAAuB,CAAC,UAAyE;AAC5G,QAAM,wBAAwB,MAAM,yBAAyB;AAC7D,QAAM,gBAAgB,gBAAgB,EAAE,cAAc,MAAM,cAAc,YAAY,MAAM,WAAW,CAAC;AAExG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,OAAO;AAAA,IACX,MACE,IAAI,KAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,GAAG,aAAa,IAAI,aAAa;AAAA,MAC9C,YAAY;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,IACH,CAAC,uBAAuB,gBAAgB,YAAY,QAAQ,WAAW,UAAU,aAAa;AAAA,EAChG;AAEA,YAAU,MAAM;AACd,SAAK,iBAAiB;AAAA,MACpB,YAAY;AAAA,MACZ,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,cAAc,MAAM,gBAAgB,IAAI,CAAC;AAE3D,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AACtD;AAEO,IAAM,UAAU,MAAM;AAC3B,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,IAAM,gBAAgB,MAAM;AACjC,QAAM,UAAU,WAAW,WAAW;AAEtC,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/NovuProvider.tsx"],"sourcesContent":["import { Novu, NovuOptions } from '@novu/js';\nimport { buildSubscriber } from '@novu/js/internal';\nimport { createContext, ReactNode, useContext, useEffect, useMemo } from 'react';\n\n// @ts-expect-error\nconst version = PACKAGE_VERSION;\n// @ts-expect-error\nconst name = PACKAGE_NAME;\nconst baseUserAgent = `${name}@${version}`;\n\nexport type NovuProviderProps = NovuOptions & {\n children: ReactNode;\n};\n\nconst NovuContext = createContext<Novu | undefined>(undefined);\n\nexport const NovuProvider = (props: NovuProviderProps) => {\n const { subscriberId, ...propsWithoutSubscriberId } = props;\n const subscriberObj = buildSubscriber({ subscriberId, subscriber: props.subscriber });\n const applicationIdentifier = propsWithoutSubscriberId.applicationIdentifier\n ? propsWithoutSubscriberId.applicationIdentifier\n : '';\n\n const providerProps: NovuProviderProps = {\n ...propsWithoutSubscriberId,\n applicationIdentifier,\n subscriber: subscriberObj,\n };\n\n return (\n <InternalNovuProvider {...providerProps} applicationIdentifier={applicationIdentifier} userAgentType=\"hooks\">\n {props.children}\n </InternalNovuProvider>\n );\n};\n\n/**\n * @internal Should be used internally not to be exposed outside of the library\n * This is needed to differentiate between the hooks and components user agents\n * Better to use this internally to avoid confusion.\n */\nexport const InternalNovuProvider = (props: NovuProviderProps & { userAgentType: 'components' | 'hooks' }) => {\n const applicationIdentifier = props.applicationIdentifier || '';\n const subscriberObj = buildSubscriber({ subscriberId: props.subscriberId, subscriber: props.subscriber });\n\n const {\n children,\n subscriberHash,\n contextHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n userAgentType,\n defaultSchedule,\n context,\n } = props;\n\n const novu = useMemo(\n () =>\n new Novu({\n applicationIdentifier,\n subscriberHash,\n contextHash,\n backendUrl,\n apiUrl,\n socketUrl,\n useCache,\n __userAgent: `${baseUserAgent} ${userAgentType}`,\n subscriber: subscriberObj,\n defaultSchedule,\n context,\n }),\n [applicationIdentifier, backendUrl, apiUrl, socketUrl, useCache, userAgentType]\n );\n\n useEffect(() => {\n novu.changeSubscriber({\n subscriber: subscriberObj,\n subscriberHash: props.subscriberHash,\n });\n }, [subscriberObj.subscriberId, props.subscriberHash, novu]);\n\n useEffect(() => {\n if (context && contextHash) {\n novu.changeContext({\n context,\n contextHash,\n });\n }\n }, [context, contextHash, novu]);\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"],"mappings":";AAAA,SAAS,YAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,eAA0B,YAAY,WAAW,eAAe;AA4BrE;AAzBJ,IAAM,UAAU;AAEhB,IAAM,OAAO;AACb,IAAM,gBAAgB,GAAG,IAAI,IAAI,OAAO;AAMxC,IAAM,cAAc,cAAgC,MAAS;AAEtD,IAAM,eAAe,CAAC,UAA6B;AACxD,QAAM,EAAE,cAAc,GAAG,yBAAyB,IAAI;AACtD,QAAM,gBAAgB,gBAAgB,EAAE,cAAc,YAAY,MAAM,WAAW,CAAC;AACpF,QAAM,wBAAwB,yBAAyB,wBACnD,yBAAyB,wBACzB;AAEJ,QAAM,gBAAmC;AAAA,IACvC,GAAG;AAAA,IACH;AAAA,IACA,YAAY;AAAA,EACd;AAEA,SACE,oBAAC,wBAAsB,GAAG,eAAe,uBAA8C,eAAc,SAClG,gBAAM,UACT;AAEJ;AAOO,IAAM,uBAAuB,CAAC,UAAyE;AAC5G,QAAM,wBAAwB,MAAM,yBAAyB;AAC7D,QAAM,gBAAgB,gBAAgB,EAAE,cAAc,MAAM,cAAc,YAAY,MAAM,WAAW,CAAC;AAExG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,OAAO;AAAA,IACX,MACE,IAAI,KAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,GAAG,aAAa,IAAI,aAAa;AAAA,MAC9C,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,CAAC,uBAAuB,YAAY,QAAQ,WAAW,UAAU,aAAa;AAAA,EAChF;AAEA,YAAU,MAAM;AACd,SAAK,iBAAiB;AAAA,MACpB,YAAY;AAAA,MACZ,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,cAAc,MAAM,gBAAgB,IAAI,CAAC;AAE3D,YAAU,MAAM;AACd,QAAI,WAAW,aAAa;AAC1B,WAAK,cAAc;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,SAAS,aAAa,IAAI,CAAC;AAE/B,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AACtD;AAEO,IAAM,UAAU,MAAM;AAC3B,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,IAAM,gBAAgB,MAAM;AACjC,QAAM,UAAU,WAAW,WAAW;AAEtC,SAAO;AACT;","names":[]}
@@ -8,7 +8,7 @@ var useWebSocketEvent = ({
8
8
  eventHandler: onMessage
9
9
  }) => {
10
10
  const novu = useNovu();
11
- const channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:e=${webSocketEvent}`;
11
+ const channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:c=${novu.contextKey}:e=${webSocketEvent}`;
12
12
  const { postMessage } = useBrowserTabsChannel({
13
13
  channelName,
14
14
  onMessage
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { requestLock } from '../../utils/requestLock';\nimport { useNovu } from '../NovuProvider';\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 channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:e=${webSocketEvent}`;\n\n const { postMessage } = useBrowserTabsChannel({\n channelName,\n onMessage,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n let cleanup: () => void;\n const resolveLock = requestLock(channelName, () => {\n cleanup = novu.on(webSocketEvent, updateReadCount);\n });\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n\n resolveLock();\n };\n }, []);\n};\n"],"mappings":";AACA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,6BAA6B;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAChB,MAGM;AACJ,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,sBAAsB,KAAK,qBAAqB,MAAM,KAAK,YAAY,MAAM,cAAc;AAE/G,QAAM,EAAE,YAAY,IAAI,sBAAsB;AAAA,IAC5C;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,YAAU,MAAM;AACd,QAAI;AACJ,UAAM,cAAc,YAAY,aAAa,MAAM;AACjD,gBAAU,KAAK,GAAG,gBAAgB,eAAe;AAAA,IACnD,CAAC;AAED,WAAO,MAAM;AACX,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV;AAEA,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AACP;","names":[]}
1
+ {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { requestLock } from '../../utils/requestLock';\nimport { useNovu } from '../NovuProvider';\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 channelName = `nv_ws_connection:a=${novu.applicationIdentifier}:s=${novu.subscriberId}:c=${novu.contextKey}:e=${webSocketEvent}`;\n\n const { postMessage } = useBrowserTabsChannel({\n channelName,\n onMessage,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n let cleanup: () => void;\n const resolveLock = requestLock(channelName, () => {\n cleanup = novu.on(webSocketEvent, updateReadCount);\n });\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n\n resolveLock();\n };\n }, []);\n};\n"],"mappings":";AACA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,6BAA6B;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAChB,MAGM;AACJ,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,sBAAsB,KAAK,qBAAqB,MAAM,KAAK,YAAY,MAAM,KAAK,UAAU,MAAM,cAAc;AAEpI,QAAM,EAAE,YAAY,IAAI,sBAAsB;AAAA,IAC5C;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,YAAU,MAAM;AACd,QAAI;AACJ,UAAM,cAAc,YAAY,aAAa,MAAM;AACjD,gBAAU,KAAK,GAAG,gBAAgB,eAAe;AAAA,IACnD,CAAC;AAED,WAAO,MAAM;AACX,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV;AAEA,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AACP;","names":[]}
@@ -1,4 +1,4 @@
1
- import { UnreadCount, DefaultSchedule, Subscriber } from '@novu/js';
1
+ import { UnreadCount, DefaultSchedule, Context, Subscriber } from '@novu/js';
2
2
  import { Notification, IconKey, Theme, NotificationClickHandler, NotificationActionClickHandler, InboxProps, Localization, Tab, PreferencesFilter, PreferenceGroups, PreferencesSort, RouterPush } from '@novu/js/ui';
3
3
  import { ReactNode } from 'react';
4
4
 
@@ -39,6 +39,7 @@ type DefaultInboxProps = {
39
39
  };
40
40
  type StandardBaseProps = {
41
41
  subscriberHash?: string;
42
+ contextHash?: string;
42
43
  backendUrl?: string;
43
44
  socketUrl?: string;
44
45
  appearance?: ReactAppearance;
@@ -49,6 +50,7 @@ type StandardBaseProps = {
49
50
  preferencesSort?: PreferencesSort;
50
51
  defaultSchedule?: DefaultSchedule;
51
52
  routerPush?: RouterPush;
53
+ context?: Context;
52
54
  } & ({
53
55
  /** @deprecated Use subscriber prop instead */
54
56
  subscriberId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novu/react",
3
- "version": "3.10.0",
3
+ "version": "3.11.0-rc.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/novuhq/novu",
@@ -121,7 +121,7 @@
121
121
  }
122
122
  },
123
123
  "dependencies": {
124
- "@novu/js": "3.10.0"
124
+ "@novu/js": "3.11.0-rc.1"
125
125
  },
126
126
  "nx": {
127
127
  "tags": [