@novu/react 3.18.0 → 3.18.2

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.
Files changed (45) hide show
  1. package/dist/cjs/components/slack-connect-button/DefaultSlackConnectButton.cjs +3 -0
  2. package/dist/cjs/components/slack-connect-button/DefaultSlackConnectButton.cjs.map +1 -1
  3. package/dist/cjs/components/slack-connect-button/DefaultSlackConnectButton.d.cts +1 -1
  4. package/dist/cjs/components/telegram-connect-button/DefaultTelegramConnectButton.cjs +3 -0
  5. package/dist/cjs/components/telegram-connect-button/DefaultTelegramConnectButton.cjs.map +1 -1
  6. package/dist/cjs/components/telegram-connect-button/DefaultTelegramConnectButton.d.cts +1 -1
  7. package/dist/cjs/hooks/index.cjs +4 -0
  8. package/dist/cjs/hooks/index.cjs.map +1 -1
  9. package/dist/cjs/hooks/index.d.cts +2 -0
  10. package/dist/cjs/hooks/internal/useWebsocketEvent.cjs +4 -1
  11. package/dist/cjs/hooks/internal/useWebsocketEvent.cjs.map +1 -1
  12. package/dist/cjs/hooks/useChannelEndpoints.cjs +93 -0
  13. package/dist/cjs/hooks/useChannelEndpoints.cjs.map +1 -0
  14. package/dist/cjs/hooks/useChannelEndpoints.d.cts +24 -0
  15. package/dist/cjs/hooks/useCounts.cjs +1 -3
  16. package/dist/cjs/hooks/useCounts.cjs.map +1 -1
  17. package/dist/cjs/hooks/useDeleteChannelConnection.cjs +69 -0
  18. package/dist/cjs/hooks/useDeleteChannelConnection.cjs.map +1 -0
  19. package/dist/cjs/hooks/useDeleteChannelConnection.d.cts +21 -0
  20. package/dist/cjs/utils/requestLock.cjs +6 -1
  21. package/dist/cjs/utils/requestLock.cjs.map +1 -1
  22. package/dist/cjs/utils/requestLock.d.cts +2 -1
  23. package/dist/esm/components/slack-connect-button/DefaultSlackConnectButton.d.ts +1 -1
  24. package/dist/esm/components/slack-connect-button/DefaultSlackConnectButton.js +3 -0
  25. package/dist/esm/components/slack-connect-button/DefaultSlackConnectButton.js.map +1 -1
  26. package/dist/esm/components/telegram-connect-button/DefaultTelegramConnectButton.d.ts +1 -1
  27. package/dist/esm/components/telegram-connect-button/DefaultTelegramConnectButton.js +3 -0
  28. package/dist/esm/components/telegram-connect-button/DefaultTelegramConnectButton.js.map +1 -1
  29. package/dist/esm/hooks/index.d.ts +2 -0
  30. package/dist/esm/hooks/index.js +2 -0
  31. package/dist/esm/hooks/index.js.map +1 -1
  32. package/dist/esm/hooks/internal/useWebsocketEvent.js +5 -2
  33. package/dist/esm/hooks/internal/useWebsocketEvent.js.map +1 -1
  34. package/dist/esm/hooks/useChannelEndpoints.d.ts +24 -0
  35. package/dist/esm/hooks/useChannelEndpoints.js +68 -0
  36. package/dist/esm/hooks/useChannelEndpoints.js.map +1 -0
  37. package/dist/esm/hooks/useCounts.js +6 -4
  38. package/dist/esm/hooks/useCounts.js.map +1 -1
  39. package/dist/esm/hooks/useDeleteChannelConnection.d.ts +21 -0
  40. package/dist/esm/hooks/useDeleteChannelConnection.js +43 -0
  41. package/dist/esm/hooks/useDeleteChannelConnection.js.map +1 -0
  42. package/dist/esm/utils/requestLock.d.ts +2 -1
  43. package/dist/esm/utils/requestLock.js +5 -1
  44. package/dist/esm/utils/requestLock.js.map +1 -1
  45. package/package.json +2 -2
@@ -33,6 +33,7 @@ var DefaultSlackConnectButton = (props) => {
33
33
  connectionIdentifier,
34
34
  subscriberId,
35
35
  context,
36
+ contextHash,
36
37
  scope,
37
38
  connectionMode,
38
39
  autoLinkUser,
@@ -53,6 +54,7 @@ var DefaultSlackConnectButton = (props) => {
53
54
  connectionIdentifier,
54
55
  subscriberId,
55
56
  context,
57
+ contextHash,
56
58
  scope,
57
59
  connectionMode,
58
60
  autoLinkUser,
@@ -72,6 +74,7 @@ var DefaultSlackConnectButton = (props) => {
72
74
  connectionIdentifier,
73
75
  subscriberId,
74
76
  context,
77
+ contextHash,
75
78
  scope,
76
79
  connectionMode,
77
80
  autoLinkUser,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/slack-connect-button/DefaultSlackConnectButton.tsx"],"sourcesContent":["import { SlackConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultSlackConnectButtonProps = Pick<\n SlackConnectButtonProps,\n | 'integrationIdentifier'\n | 'connectionIdentifier'\n | 'subscriberId'\n | 'context'\n | 'scope'\n | 'connectionMode'\n | 'autoLinkUser'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultSlackConnectButton = (props: DefaultSlackConnectButtonProps) => {\n const {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'SlackConnectButton',\n props: {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA4B;AAC5B,2BAA0B;AAC1B,qBAAwB;AA6Ef;AA1DF,IAAM,4BAA4B,CAAC,UAA0C;AAClF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,QAAI,gCAAU;AAE7B,QAAM,YAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,4CAAC,0BAAQ,OAAc;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/slack-connect-button/DefaultSlackConnectButton.tsx"],"sourcesContent":["import { SlackConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultSlackConnectButtonProps = Pick<\n SlackConnectButtonProps,\n | 'integrationIdentifier'\n | 'connectionIdentifier'\n | 'subscriberId'\n | 'context'\n | 'contextHash'\n | 'scope'\n | 'connectionMode'\n | 'autoLinkUser'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultSlackConnectButton = (props: DefaultSlackConnectButtonProps) => {\n const {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'SlackConnectButton',\n props: {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA4B;AAC5B,2BAA0B;AAC1B,qBAAwB;AAiFf;AA7DF,IAAM,4BAA4B,CAAC,UAA0C;AAClF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,QAAI,gCAAU;AAE7B,QAAM,YAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,4CAAC,0BAAQ,OAAc;AAChC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { SlackConnectButtonProps } from '@novu/js/ui';
3
3
 
4
- type DefaultSlackConnectButtonProps = Pick<SlackConnectButtonProps, 'integrationIdentifier' | 'connectionIdentifier' | 'subscriberId' | 'context' | 'scope' | 'connectionMode' | 'autoLinkUser' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
4
+ type DefaultSlackConnectButtonProps = Pick<SlackConnectButtonProps, 'integrationIdentifier' | 'connectionIdentifier' | 'subscriberId' | 'context' | 'contextHash' | 'scope' | 'connectionMode' | 'autoLinkUser' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
5
5
  declare const DefaultSlackConnectButton: (props: DefaultSlackConnectButtonProps) => react_jsx_runtime.JSX.Element;
6
6
 
7
7
  export { DefaultSlackConnectButton, type DefaultSlackConnectButtonProps };
@@ -31,6 +31,7 @@ var DefaultTelegramConnectButton = (props) => {
31
31
  const {
32
32
  integrationIdentifier,
33
33
  subscriberId,
34
+ context,
34
35
  onConnectSuccess,
35
36
  onConnectError,
36
37
  onDisconnectSuccess,
@@ -46,6 +47,7 @@ var DefaultTelegramConnectButton = (props) => {
46
47
  props: {
47
48
  integrationIdentifier,
48
49
  subscriberId,
50
+ context,
49
51
  onConnectSuccess,
50
52
  onConnectError,
51
53
  onDisconnectSuccess,
@@ -60,6 +62,7 @@ var DefaultTelegramConnectButton = (props) => {
60
62
  novuUI,
61
63
  integrationIdentifier,
62
64
  subscriberId,
65
+ context,
63
66
  onConnectSuccess,
64
67
  onConnectError,
65
68
  onDisconnectSuccess,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/telegram-connect-button/DefaultTelegramConnectButton.tsx"],"sourcesContent":["import { TelegramConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultTelegramConnectButtonProps = Pick<\n TelegramConnectButtonProps,\n | 'integrationIdentifier'\n | 'subscriberId'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultTelegramConnectButton = (props: DefaultTelegramConnectButtonProps) => {\n const {\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'TelegramConnectButton',\n props: {\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA4B;AAC5B,2BAA0B;AAC1B,qBAAwB;AAyDf;AA3CF,IAAM,+BAA+B,CAAC,UAA6C;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,QAAI,gCAAU;AAE7B,QAAM,YAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,4CAAC,0BAAQ,OAAc;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/telegram-connect-button/DefaultTelegramConnectButton.tsx"],"sourcesContent":["import { TelegramConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultTelegramConnectButtonProps = Pick<\n TelegramConnectButtonProps,\n | 'integrationIdentifier'\n | 'subscriberId'\n | 'context'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultTelegramConnectButton = (props: DefaultTelegramConnectButtonProps) => {\n const {\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'TelegramConnectButton',\n props: {\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA4B;AAC5B,2BAA0B;AAC1B,qBAAwB;AA6Df;AA9CF,IAAM,+BAA+B,CAAC,UAA6C;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,QAAI,gCAAU;AAE7B,QAAM,YAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,4CAAC,0BAAQ,OAAc;AAChC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { TelegramConnectButtonProps } from '@novu/js/ui';
3
3
 
4
- type DefaultTelegramConnectButtonProps = Pick<TelegramConnectButtonProps, 'integrationIdentifier' | 'subscriberId' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
4
+ type DefaultTelegramConnectButtonProps = Pick<TelegramConnectButtonProps, 'integrationIdentifier' | 'subscriberId' | 'context' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
5
5
  declare const DefaultTelegramConnectButton: (props: DefaultTelegramConnectButtonProps) => react_jsx_runtime.JSX.Element;
6
6
 
7
7
  export { DefaultTelegramConnectButton, type DefaultTelegramConnectButtonProps };
@@ -33,9 +33,11 @@ var import_NovuProvider = require("./NovuProvider.cjs");
33
33
  __reExport(hooks_exports, require("./useChannelConnection.cjs"), module.exports);
34
34
  __reExport(hooks_exports, require("./useChannelConnections.cjs"), module.exports);
35
35
  __reExport(hooks_exports, require("./useChannelEndpoint.cjs"), module.exports);
36
+ __reExport(hooks_exports, require("./useChannelEndpoints.cjs"), module.exports);
36
37
  __reExport(hooks_exports, require("./useCounts.cjs"), module.exports);
37
38
  __reExport(hooks_exports, require("./useCreateChannelEndpoint.cjs"), module.exports);
38
39
  __reExport(hooks_exports, require("./useCreateSubscription.cjs"), module.exports);
40
+ __reExport(hooks_exports, require("./useDeleteChannelConnection.cjs"), module.exports);
39
41
  __reExport(hooks_exports, require("./useDeleteChannelEndpoint.cjs"), module.exports);
40
42
  __reExport(hooks_exports, require("./useNotifications.cjs"), module.exports);
41
43
  __reExport(hooks_exports, require("./usePreferences.cjs"), module.exports);
@@ -55,9 +57,11 @@ __reExport(hooks_exports, require("./useUpdateSubscription.cjs"), module.exports
55
57
  ...require("./useChannelConnection.cjs"),
56
58
  ...require("./useChannelConnections.cjs"),
57
59
  ...require("./useChannelEndpoint.cjs"),
60
+ ...require("./useChannelEndpoints.cjs"),
58
61
  ...require("./useCounts.cjs"),
59
62
  ...require("./useCreateChannelEndpoint.cjs"),
60
63
  ...require("./useCreateSubscription.cjs"),
64
+ ...require("./useDeleteChannelConnection.cjs"),
61
65
  ...require("./useDeleteChannelEndpoint.cjs"),
62
66
  ...require("./useNotifications.cjs"),
63
67
  ...require("./usePreferences.cjs"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export type * from '@novu/js';\nexport { PreferenceLevel, SeverityLevelEnum, WorkflowCriticalityEnum } from '@novu/js';\nexport { NovuProvider, useNovu } from './NovuProvider';\nexport * from './useChannelConnection';\nexport * from './useChannelConnections';\nexport * from './useChannelEndpoint';\nexport * from './useCounts';\nexport * from './useCreateChannelEndpoint';\nexport * from './useCreateSubscription';\nexport * from './useDeleteChannelEndpoint';\nexport * from './useNotifications';\nexport * from './usePreferences';\nexport * from './useRemoveSubscription';\nexport * from './useSchedule';\nexport * from './useSubscription';\nexport * from './useSubscriptions';\nexport * from './useTelegramSubscriberLink';\nexport * from './useUpdateSubscription';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAA4E;AAC5E,0BAAsC;AACtC,0BAAc,uCAHd;AAIA,0BAAc,wCAJd;AAKA,0BAAc,qCALd;AAMA,0BAAc,4BANd;AAOA,0BAAc,2CAPd;AAQA,0BAAc,wCARd;AASA,0BAAc,2CATd;AAUA,0BAAc,mCAVd;AAWA,0BAAc,iCAXd;AAYA,0BAAc,wCAZd;AAaA,0BAAc,8BAbd;AAcA,0BAAc,kCAdd;AAeA,0BAAc,mCAfd;AAgBA,0BAAc,4CAhBd;AAiBA,0BAAc,wCAjBd;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export type * from '@novu/js';\nexport { PreferenceLevel, SeverityLevelEnum, WorkflowCriticalityEnum } from '@novu/js';\nexport { NovuProvider, useNovu } from './NovuProvider';\nexport * from './useChannelConnection';\nexport * from './useChannelConnections';\nexport * from './useChannelEndpoint';\nexport * from './useChannelEndpoints';\nexport * from './useCounts';\nexport * from './useCreateChannelEndpoint';\nexport * from './useCreateSubscription';\nexport * from './useDeleteChannelConnection';\nexport * from './useDeleteChannelEndpoint';\nexport * from './useNotifications';\nexport * from './usePreferences';\nexport * from './useRemoveSubscription';\nexport * from './useSchedule';\nexport * from './useSubscription';\nexport * from './useSubscriptions';\nexport * from './useTelegramSubscriberLink';\nexport * from './useUpdateSubscription';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAA4E;AAC5E,0BAAsC;AACtC,0BAAc,uCAHd;AAIA,0BAAc,wCAJd;AAKA,0BAAc,qCALd;AAMA,0BAAc,sCANd;AAOA,0BAAc,4BAPd;AAQA,0BAAc,2CARd;AASA,0BAAc,wCATd;AAUA,0BAAc,6CAVd;AAWA,0BAAc,2CAXd;AAYA,0BAAc,mCAZd;AAaA,0BAAc,iCAbd;AAcA,0BAAc,wCAdd;AAeA,0BAAc,8BAfd;AAgBA,0BAAc,kCAhBd;AAiBA,0BAAc,mCAjBd;AAkBA,0BAAc,4CAlBd;AAmBA,0BAAc,wCAnBd;","names":[]}
@@ -4,9 +4,11 @@ export { NovuProvider, useNovu } from './NovuProvider.cjs';
4
4
  export { UseChannelConnectionProps, UseChannelConnectionResult, useChannelConnection } from './useChannelConnection.cjs';
5
5
  export { UseChannelConnectionsProps, UseChannelConnectionsResult, useChannelConnections } from './useChannelConnections.cjs';
6
6
  export { UseChannelEndpointProps, UseChannelEndpointResult, useChannelEndpoint } from './useChannelEndpoint.cjs';
7
+ export { UseChannelEndpointsProps, UseChannelEndpointsResult, useChannelEndpoints } from './useChannelEndpoints.cjs';
7
8
  export { UseCountsProps, UseCountsResult, useCounts } from './useCounts.cjs';
8
9
  export { UseCreateChannelEndpointProps, UseCreateChannelEndpointResult, useCreateChannelEndpoint } from './useCreateChannelEndpoint.cjs';
9
10
  export { UseCreateSubscriptionProps, UseCreateSubscriptionResult, useCreateSubscription } from './useCreateSubscription.cjs';
11
+ export { UseDeleteChannelConnectionProps, UseDeleteChannelConnectionResult, useDeleteChannelConnection } from './useDeleteChannelConnection.cjs';
10
12
  export { UseDeleteChannelEndpointProps, UseDeleteChannelEndpointResult, useDeleteChannelEndpoint } from './useDeleteChannelEndpoint.cjs';
11
13
  export { UseNotificationsProps, UseNotificationsResult, useNotifications } from './useNotifications.cjs';
12
14
  export { UsePreferencesProps, UsePreferencesResult, usePreferences } from './usePreferences.cjs';
@@ -39,9 +39,12 @@ var useWebSocketEvent = ({
39
39
  onMessage,
40
40
  enabled
41
41
  });
42
+ const shouldBroadcast = (0, import_requestLock.isWebLocksSupported)();
42
43
  const updateReadCount = (data) => {
43
44
  onMessage(data);
44
- postMessage(data);
45
+ if (shouldBroadcast) {
46
+ postMessage(data);
47
+ }
45
48
  };
46
49
  (0, import_react.useEffect)(() => {
47
50
  if (!enabled) return;
@@ -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 enabled = true,\n}: {\n event: E;\n eventHandler: (args: Events[E]) => void;\n enabled?: boolean;\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 enabled,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n if (!enabled) return;\n\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 }, [enabled]);\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;AAAA,EACd,UAAU;AACZ,MAIM;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,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,8BAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,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,OAAO,CAAC;AACd;","names":[]}
1
+ {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { isWebLocksSupported, 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 enabled = true,\n}: {\n event: E;\n eventHandler: (args: Events[E]) => void;\n enabled?: boolean;\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 enabled,\n });\n\n // When Web Locks are unavailable, requestLock runs the callback in every tab,\n // so each tab already receives the event through its own socket. Re-broadcasting\n // in that case would duplicate the event across tabs (count multiplied by tab\n // count). Only the exclusive lock owner should fan out to the other tabs.\n const shouldBroadcast = isWebLocksSupported();\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n if (shouldBroadcast) {\n postMessage(data);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\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 }, [enabled]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA0B;AAC1B,yBAAiD;AACjD,0BAAwB;AACxB,mCAAsC;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAAA,EACd,UAAU;AACZ,MAIM;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,IACA;AAAA,EACF,CAAC;AAMD,QAAM,sBAAkB,wCAAoB;AAC5C,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,QAAI,iBAAiB;AACnB,kBAAY,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,8BAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,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,OAAO,CAAC;AACd;","names":[]}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/hooks/useChannelEndpoints.ts
21
+ var useChannelEndpoints_exports = {};
22
+ __export(useChannelEndpoints_exports, {
23
+ useChannelEndpoints: () => useChannelEndpoints
24
+ });
25
+ module.exports = __toCommonJS(useChannelEndpoints_exports);
26
+ var import_react = require("react");
27
+ var import_NovuProvider = require("./NovuProvider.cjs");
28
+ var useChannelEndpoints = (props = {}) => {
29
+ const novu = (0, import_NovuProvider.useNovu)();
30
+ const propsRef = (0, import_react.useRef)(props);
31
+ propsRef.current = props;
32
+ const [endpoints, setEndpoints] = (0, import_react.useState)([]);
33
+ const [error, setError] = (0, import_react.useState)();
34
+ const [isLoading, setIsLoading] = (0, import_react.useState)(true);
35
+ const [isFetching, setIsFetching] = (0, import_react.useState)(false);
36
+ const fetchEndpoints = (0, import_react.useCallback)(
37
+ async (options) => {
38
+ const { onSuccess, onError, ...listArgs } = propsRef.current;
39
+ if (options == null ? void 0 : options.refetch) {
40
+ setError(void 0);
41
+ setIsLoading(true);
42
+ }
43
+ setIsFetching(true);
44
+ try {
45
+ const response = await novu.channelEndpoints.list(listArgs);
46
+ if (response.error) {
47
+ setError(response.error);
48
+ onError == null ? void 0 : onError(response.error);
49
+ } else if (response.data !== void 0) {
50
+ setEndpoints(response.data);
51
+ onSuccess == null ? void 0 : onSuccess(response.data);
52
+ }
53
+ } catch (err) {
54
+ setError(err);
55
+ onError == null ? void 0 : onError(err);
56
+ } finally {
57
+ setIsLoading(false);
58
+ setIsFetching(false);
59
+ }
60
+ },
61
+ [novu]
62
+ );
63
+ (0, import_react.useEffect)(() => {
64
+ const cleanups = [
65
+ "channel-endpoint.create.resolved",
66
+ "channel-endpoint.delete.resolved",
67
+ "channel-endpoint.link.resolved"
68
+ ].map(
69
+ (event) => novu.on(event, () => {
70
+ void fetchEndpoints({ refetch: true });
71
+ })
72
+ );
73
+ void fetchEndpoints({ refetch: true });
74
+ return () => {
75
+ for (const cleanup of cleanups) {
76
+ cleanup();
77
+ }
78
+ };
79
+ }, [novu, fetchEndpoints]);
80
+ const refetch = (0, import_react.useCallback)(() => fetchEndpoints({ refetch: true }), [fetchEndpoints]);
81
+ return {
82
+ endpoints,
83
+ error,
84
+ isLoading,
85
+ isFetching,
86
+ refetch
87
+ };
88
+ };
89
+ // Annotate the CommonJS export names for ESM import in node:
90
+ 0 && (module.exports = {
91
+ useChannelEndpoints
92
+ });
93
+ //# sourceMappingURL=useChannelEndpoints.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useChannelEndpoints.ts"],"sourcesContent":["import type { ChannelEndpointResponse, ListChannelEndpointsArgs, NovuError } from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useNovu } from './NovuProvider';\n\nexport type UseChannelEndpointsProps = ListChannelEndpointsArgs & {\n onSuccess?: (data: ChannelEndpointResponse[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseChannelEndpointsResult = {\n endpoints: ChannelEndpointResponse[];\n error?: NovuError;\n isLoading: boolean;\n isFetching: boolean;\n refetch: () => Promise<void>;\n};\n\n/**\n * List channel endpoints for the current subscriber. Use this to discover a linked\n * user endpoint (e.g. a `slack_user` endpoint) for a given connection identifier.\n *\n * @example\n * const { endpoints } = useChannelEndpoints({ integrationIdentifier: 'my-chat', connectionIdentifier });\n * const isLinked = endpoints.some((endpoint) => endpoint.type === 'slack_user');\n */\nexport const useChannelEndpoints = (props: UseChannelEndpointsProps = {}): UseChannelEndpointsResult => {\n const novu = useNovu();\n const propsRef = useRef<UseChannelEndpointsProps>(props);\n propsRef.current = props;\n\n const [endpoints, setEndpoints] = useState<ChannelEndpointResponse[]>([]);\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const fetchEndpoints = useCallback(\n async (options?: { refetch: boolean }) => {\n const { onSuccess, onError, ...listArgs } = propsRef.current;\n\n if (options?.refetch) {\n setError(undefined);\n setIsLoading(true);\n }\n\n setIsFetching(true);\n\n try {\n const response = await novu.channelEndpoints.list(listArgs);\n\n if (response.error) {\n setError(response.error as NovuError);\n onError?.(response.error as NovuError);\n } else if (response.data !== undefined) {\n setEndpoints(response.data);\n onSuccess?.(response.data);\n }\n } catch (err) {\n setError(err as NovuError);\n onError?.(err as NovuError);\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n },\n [novu]\n );\n\n useEffect(() => {\n const cleanups = (\n [\n 'channel-endpoint.create.resolved',\n 'channel-endpoint.delete.resolved',\n 'channel-endpoint.link.resolved',\n ] as const\n ).map((event) =>\n novu.on(event, () => {\n void fetchEndpoints({ refetch: true });\n })\n );\n\n void fetchEndpoints({ refetch: true });\n\n return () => {\n for (const cleanup of cleanups) {\n cleanup();\n }\n };\n }, [novu, fetchEndpoints]);\n\n const refetch = useCallback(() => fetchEndpoints({ refetch: true }), [fetchEndpoints]);\n\n return {\n endpoints,\n error,\n isLoading,\n isFetching,\n refetch,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAyD;AACzD,0BAAwB;AAuBjB,IAAM,sBAAsB,CAAC,QAAkC,CAAC,MAAiC;AACtG,QAAM,WAAO,6BAAQ;AACrB,QAAM,eAAW,qBAAiC,KAAK;AACvD,WAAS,UAAU;AAEnB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAoC,CAAC,CAAC;AACxE,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAoB;AAC9C,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,IAAI;AAC/C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAElD,QAAM,qBAAiB;AAAA,IACrB,OAAO,YAAmC;AACxC,YAAM,EAAE,WAAW,SAAS,GAAG,SAAS,IAAI,SAAS;AAErD,UAAI,mCAAS,SAAS;AACpB,iBAAS,MAAS;AAClB,qBAAa,IAAI;AAAA,MACnB;AAEA,oBAAc,IAAI;AAElB,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK,QAAQ;AAE1D,YAAI,SAAS,OAAO;AAClB,mBAAS,SAAS,KAAkB;AACpC,6CAAU,SAAS;AAAA,QACrB,WAAW,SAAS,SAAS,QAAW;AACtC,uBAAa,SAAS,IAAI;AAC1B,iDAAY,SAAS;AAAA,QACvB;AAAA,MACF,SAAS,KAAK;AACZ,iBAAS,GAAgB;AACzB,2CAAU;AAAA,MACZ,UAAE;AACA,qBAAa,KAAK;AAClB,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,8BAAU,MAAM;AACd,UAAM,WACJ;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACA;AAAA,MAAI,CAAC,UACL,KAAK,GAAG,OAAO,MAAM;AACnB,aAAK,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,SAAK,eAAe,EAAE,SAAS,KAAK,CAAC;AAErC,WAAO,MAAM;AACX,iBAAW,WAAW,UAAU;AAC9B,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,cAAc,CAAC;AAEzB,QAAM,cAAU,0BAAY,MAAM,eAAe,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;AAErF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,24 @@
1
+ import { ListChannelEndpointsArgs, ChannelEndpointResponse, NovuError } from '@novu/js';
2
+
3
+ type UseChannelEndpointsProps = ListChannelEndpointsArgs & {
4
+ onSuccess?: (data: ChannelEndpointResponse[]) => void;
5
+ onError?: (error: NovuError) => void;
6
+ };
7
+ type UseChannelEndpointsResult = {
8
+ endpoints: ChannelEndpointResponse[];
9
+ error?: NovuError;
10
+ isLoading: boolean;
11
+ isFetching: boolean;
12
+ refetch: () => Promise<void>;
13
+ };
14
+ /**
15
+ * List channel endpoints for the current subscriber. Use this to discover a linked
16
+ * user endpoint (e.g. a `slack_user` endpoint) for a given connection identifier.
17
+ *
18
+ * @example
19
+ * const { endpoints } = useChannelEndpoints({ integrationIdentifier: 'my-chat', connectionIdentifier });
20
+ * const isLinked = endpoints.some((endpoint) => endpoint.type === 'slack_user');
21
+ */
22
+ declare const useChannelEndpoints: (props?: UseChannelEndpointsProps) => UseChannelEndpointsResult;
23
+
24
+ export { type UseChannelEndpointsProps, type UseChannelEndpointsResult, useChannelEndpoints };
@@ -49,9 +49,7 @@ var useCounts = (props) => {
49
49
  const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));
50
50
  let countFiltersToFetch = [];
51
51
  if (notification) {
52
- countFiltersToFetch = currentFilters.filter(
53
- (filter) => (0, import_js.checkNotificationMatchesFilter)(notification, filter)
54
- );
52
+ countFiltersToFetch = currentFilters.filter((filter) => (0, import_js.checkNotificationMatchesFilter)(notification, filter));
55
53
  } else {
56
54
  countFiltersToFetch = currentFilters;
57
55
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useCounts.ts"],"sourcesContent":["import { NOTIFICATION_COUNT_SYNC_EVENTS, checkNotificationMatchesFilter, isSameFilter, Notification, NotificationFilter, NovuError } from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useDataRef } from './internal/useDataRef';\nimport { useWebSocketEvent } from './internal/useWebsocketEvent';\nimport { useNovu, useRealtime } from './NovuProvider';\n\ntype Count = {\n count: number;\n filter: NotificationFilter;\n};\n\n/**\n * Props for the useCounts hook.\n *\n * @example\n * ```tsx\n * // Count unread notifications\n * const { counts } = useCounts({\n * filters: [{ read: false }]\n * });\n *\n * // Count unseen notifications with specific tags\n * const { counts } = useCounts({\n * filters: [{ seen: false, tags: ['important'] }]\n * });\n *\n * // Count seen but unread notifications\n * const { counts } = useCounts({\n * filters: [{ seen: true, read: false }]\n * });\n *\n * // Opt out of the built-in realtime count updates and drive them yourself\n * const { counts, refetch } = useCounts({\n * filters: [{ read: false }],\n * realtime: false,\n * });\n * ```\n */\nexport type UseCountsProps = {\n filters: NotificationFilter[];\n /**\n * When `false`, disables the WebSocket subscriptions that auto-resync\n * counts on `notifications.notification_received` and\n * `notifications.unread_count_changed`. The filter-driven fetch and\n * `refetch()` keep working. Use alongside\n * `useNotifications({ realtime: false })` when you drive live updates\n * yourself.\n *\n * When set, this prop takes precedence over the `realtime` config on\n * `<NovuProvider />`. When omitted, the provider value (default `true`) is used.\n */\n realtime?: boolean;\n onSuccess?: (data: Count[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseCountsResult = {\n counts?: Count[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const useCounts = (props: UseCountsProps): UseCountsResult => {\n const { filters, realtime: propsRealtime, onSuccess, onError } = props;\n const novu = useNovu();\n const { notifications } = novu;\n const providerRealtime = useRealtime();\n const realtime = propsRealtime ?? providerRealtime;\n const filtersRef = useDataRef<NotificationFilter[]>(filters);\n const onSuccessRef = useDataRef(onSuccess);\n const onErrorRef = useDataRef(onError);\n const syncGenerationRef = useRef(0);\n const [error, setError] = useState<NovuError>();\n const [counts, setCounts] = useState<Count[]>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = useCallback(\n async (notification?: Notification, overrideFilters?: NotificationFilter[]) => {\n const currentFilters = overrideFilters || filtersRef.current;\n const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));\n let countFiltersToFetch: NotificationFilter[] = [];\n\n if (notification) {\n countFiltersToFetch = currentFilters.filter((filter) =>\n checkNotificationMatchesFilter(notification, filter)\n );\n } else {\n countFiltersToFetch = currentFilters;\n }\n\n if (countFiltersToFetch.length === 0) {\n return;\n }\n\n const generation = ++syncGenerationRef.current;\n setIsFetching(true);\n\n const countsRes = await notifications.count({ filters: countFiltersToFetch });\n\n if (generation !== syncGenerationRef.current) {\n return;\n }\n\n setIsFetching(false);\n setIsLoading(false);\n\n if (countsRes.error) {\n setError(countsRes.error);\n onErrorRef.current?.(countsRes.error);\n\n return;\n }\n\n const data = countsRes.data!;\n onSuccessRef.current?.(data.counts);\n\n setCounts((oldCounts) => {\n const newCounts: Count[] = [];\n const countsReceived = data.counts;\n\n for (let i = 0; i < existingCounts.length; i++) {\n const existingFilter = existingCounts[i].filter;\n const countReceived = countsReceived.find((c) => isSameFilter(c.filter, existingFilter));\n const count = countReceived || oldCounts?.[i];\n if (count) {\n newCounts.push(count);\n }\n }\n\n return newCounts;\n });\n },\n [notifications, filtersRef, onErrorRef, onSuccessRef]\n );\n\n useWebSocketEvent({\n event: 'notifications.notification_received',\n enabled: realtime,\n eventHandler: (data) => {\n sync(data.result);\n },\n });\n\n useWebSocketEvent({\n event: 'notifications.unread_count_changed',\n enabled: realtime,\n eventHandler: () => {\n sync();\n },\n });\n\n useEffect(() => {\n const cleanups = NOTIFICATION_COUNT_SYNC_EVENTS.map((event) =>\n novu.on(event, (payload) => {\n if ('error' in payload && payload.error) {\n return;\n }\n\n sync();\n })\n );\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [novu, sync]);\n\n useEffect(() => {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n sync(undefined, filters);\n }, [JSON.stringify(filters), sync]);\n\n const refetch = useCallback(async () => {\n await sync();\n }, [sync]);\n\n return { counts, error, refetch, isLoading, isFetching };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/useCounts.ts"],"sourcesContent":["import {\n checkNotificationMatchesFilter,\n isSameFilter,\n NOTIFICATION_COUNT_SYNC_EVENTS,\n Notification,\n NotificationFilter,\n NovuError,\n} from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useDataRef } from './internal/useDataRef';\nimport { useWebSocketEvent } from './internal/useWebsocketEvent';\nimport { useNovu, useRealtime } from './NovuProvider';\n\ntype Count = {\n count: number;\n filter: NotificationFilter;\n};\n\n/**\n * Props for the useCounts hook.\n *\n * @example\n * ```tsx\n * // Count unread notifications\n * const { counts } = useCounts({\n * filters: [{ read: false }]\n * });\n *\n * // Count unseen notifications with specific tags\n * const { counts } = useCounts({\n * filters: [{ seen: false, tags: ['important'] }]\n * });\n *\n * // Count seen but unread notifications\n * const { counts } = useCounts({\n * filters: [{ seen: true, read: false }]\n * });\n *\n * // Opt out of the built-in realtime count updates and drive them yourself\n * const { counts, refetch } = useCounts({\n * filters: [{ read: false }],\n * realtime: false,\n * });\n * ```\n */\nexport type UseCountsProps = {\n filters: NotificationFilter[];\n /**\n * When `false`, disables the WebSocket subscriptions that auto-resync\n * counts on `notifications.notification_received` and\n * `notifications.unread_count_changed`. The filter-driven fetch and\n * `refetch()` keep working. Use alongside\n * `useNotifications({ realtime: false })` when you drive live updates\n * yourself.\n *\n * When set, this prop takes precedence over the `realtime` config on\n * `<NovuProvider />`. When omitted, the provider value (default `true`) is used.\n */\n realtime?: boolean;\n onSuccess?: (data: Count[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseCountsResult = {\n counts?: Count[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const useCounts = (props: UseCountsProps): UseCountsResult => {\n const { filters, realtime: propsRealtime, onSuccess, onError } = props;\n const novu = useNovu();\n const { notifications } = novu;\n const providerRealtime = useRealtime();\n const realtime = propsRealtime ?? providerRealtime;\n const filtersRef = useDataRef<NotificationFilter[]>(filters);\n const onSuccessRef = useDataRef(onSuccess);\n const onErrorRef = useDataRef(onError);\n const syncGenerationRef = useRef(0);\n const [error, setError] = useState<NovuError>();\n const [counts, setCounts] = useState<Count[]>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = useCallback(\n async (notification?: Notification, overrideFilters?: NotificationFilter[]) => {\n const currentFilters = overrideFilters || filtersRef.current;\n const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));\n let countFiltersToFetch: NotificationFilter[] = [];\n\n if (notification) {\n countFiltersToFetch = currentFilters.filter((filter) => checkNotificationMatchesFilter(notification, filter));\n } else {\n countFiltersToFetch = currentFilters;\n }\n\n if (countFiltersToFetch.length === 0) {\n return;\n }\n\n const generation = ++syncGenerationRef.current;\n setIsFetching(true);\n\n const countsRes = await notifications.count({ filters: countFiltersToFetch });\n\n if (generation !== syncGenerationRef.current) {\n return;\n }\n\n setIsFetching(false);\n setIsLoading(false);\n\n if (countsRes.error) {\n setError(countsRes.error);\n onErrorRef.current?.(countsRes.error);\n\n return;\n }\n\n const data = countsRes.data!;\n onSuccessRef.current?.(data.counts);\n\n setCounts((oldCounts) => {\n const newCounts: Count[] = [];\n const countsReceived = data.counts;\n\n for (let i = 0; i < existingCounts.length; i++) {\n const existingFilter = existingCounts[i].filter;\n const countReceived = countsReceived.find((c) => isSameFilter(c.filter, existingFilter));\n const count = countReceived || oldCounts?.[i];\n if (count) {\n newCounts.push(count);\n }\n }\n\n return newCounts;\n });\n },\n [notifications, filtersRef, onErrorRef, onSuccessRef]\n );\n\n useWebSocketEvent({\n event: 'notifications.notification_received',\n enabled: realtime,\n eventHandler: (data) => {\n sync(data.result);\n },\n });\n\n useWebSocketEvent({\n event: 'notifications.unread_count_changed',\n enabled: realtime,\n eventHandler: () => {\n sync();\n },\n });\n\n useEffect(() => {\n const cleanups = NOTIFICATION_COUNT_SYNC_EVENTS.map((event) =>\n novu.on(event, (payload) => {\n if ('error' in payload && payload.error) {\n return;\n }\n\n sync();\n })\n );\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [novu, sync]);\n\n useEffect(() => {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n sync(undefined, filters);\n }, [JSON.stringify(filters), sync]);\n\n const refetch = useCallback(async () => {\n await sync();\n }, [sync]);\n\n return { counts, error, refetch, isLoading, isFetching };\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/hooks/useDeleteChannelConnection.ts
21
+ var useDeleteChannelConnection_exports = {};
22
+ __export(useDeleteChannelConnection_exports, {
23
+ useDeleteChannelConnection: () => useDeleteChannelConnection
24
+ });
25
+ module.exports = __toCommonJS(useDeleteChannelConnection_exports);
26
+ var import_react = require("react");
27
+ var import_NovuProvider = require("./NovuProvider.cjs");
28
+ var useDeleteChannelConnection = (props = {}) => {
29
+ const propsRef = (0, import_react.useRef)(props);
30
+ propsRef.current = props;
31
+ const novu = (0, import_NovuProvider.useNovu)();
32
+ const [isDeleting, setIsDeleting] = (0, import_react.useState)(false);
33
+ const [error, setError] = (0, import_react.useState)();
34
+ const remove = (0, import_react.useCallback)(
35
+ async (identifier) => {
36
+ var _a, _b, _c, _d, _e, _f;
37
+ setError(void 0);
38
+ setIsDeleting(true);
39
+ try {
40
+ const response = await novu.channelConnections.delete({ identifier });
41
+ if (response.error) {
42
+ setError(response.error);
43
+ (_b = (_a = propsRef.current).onError) == null ? void 0 : _b.call(_a, response.error);
44
+ } else {
45
+ (_d = (_c = propsRef.current).onSuccess) == null ? void 0 : _d.call(_c);
46
+ }
47
+ return response;
48
+ } catch (err) {
49
+ const novuError = err;
50
+ setError(novuError);
51
+ (_f = (_e = propsRef.current).onError) == null ? void 0 : _f.call(_e, novuError);
52
+ return { error: novuError };
53
+ } finally {
54
+ setIsDeleting(false);
55
+ }
56
+ },
57
+ [novu]
58
+ );
59
+ return {
60
+ remove,
61
+ isDeleting,
62
+ error
63
+ };
64
+ };
65
+ // Annotate the CommonJS export names for ESM import in node:
66
+ 0 && (module.exports = {
67
+ useDeleteChannelConnection
68
+ });
69
+ //# sourceMappingURL=useDeleteChannelConnection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useDeleteChannelConnection.ts"],"sourcesContent":["import type { NovuError } from '@novu/js';\nimport { useCallback, useRef, useState } from 'react';\nimport { useNovu } from './NovuProvider';\n\nexport type UseDeleteChannelConnectionProps = {\n onSuccess?: () => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseDeleteChannelConnectionResult = {\n isDeleting: boolean;\n error?: NovuError;\n remove: (identifier: string) => Promise<{\n data?: undefined;\n error?: NovuError | undefined;\n }>;\n};\n\n/**\n * Delete a channel connection by identifier. Works for both subscriber-owned and\n * shared (workspace-level) connections the current subscriber can access.\n */\nexport const useDeleteChannelConnection = (\n props: UseDeleteChannelConnectionProps = {}\n): UseDeleteChannelConnectionResult => {\n const propsRef = useRef<UseDeleteChannelConnectionProps>(props);\n propsRef.current = props;\n const novu = useNovu();\n const [isDeleting, setIsDeleting] = useState(false);\n const [error, setError] = useState<NovuError>();\n\n const remove = useCallback(\n async (identifier: string) => {\n setError(undefined);\n setIsDeleting(true);\n\n try {\n const response = await novu.channelConnections.delete({ identifier });\n\n if (response.error) {\n setError(response.error as NovuError);\n propsRef.current.onError?.(response.error as NovuError);\n } else {\n propsRef.current.onSuccess?.();\n }\n\n return response as { data?: undefined; error?: NovuError };\n } catch (err) {\n const novuError = err as NovuError;\n setError(novuError);\n propsRef.current.onError?.(novuError);\n\n return { error: novuError };\n } finally {\n setIsDeleting(false);\n }\n },\n [novu]\n );\n\n return {\n remove,\n isDeleting,\n error,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA8C;AAC9C,0BAAwB;AAoBjB,IAAM,6BAA6B,CACxC,QAAyC,CAAC,MACL;AACrC,QAAM,eAAW,qBAAwC,KAAK;AAC9D,WAAS,UAAU;AACnB,QAAM,WAAO,6BAAQ;AACrB,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAoB;AAE9C,QAAM,aAAS;AAAA,IACb,OAAO,eAAuB;AAhClC;AAiCM,eAAS,MAAS;AAClB,oBAAc,IAAI;AAElB,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,mBAAmB,OAAO,EAAE,WAAW,CAAC;AAEpE,YAAI,SAAS,OAAO;AAClB,mBAAS,SAAS,KAAkB;AACpC,+BAAS,SAAQ,YAAjB,4BAA2B,SAAS;AAAA,QACtC,OAAO;AACL,+BAAS,SAAQ,cAAjB;AAAA,QACF;AAEA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,YAAY;AAClB,iBAAS,SAAS;AAClB,6BAAS,SAAQ,YAAjB,4BAA2B;AAE3B,eAAO,EAAE,OAAO,UAAU;AAAA,MAC5B,UAAE;AACA,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,21 @@
1
+ import { NovuError } from '@novu/js';
2
+
3
+ type UseDeleteChannelConnectionProps = {
4
+ onSuccess?: () => void;
5
+ onError?: (error: NovuError) => void;
6
+ };
7
+ type UseDeleteChannelConnectionResult = {
8
+ isDeleting: boolean;
9
+ error?: NovuError;
10
+ remove: (identifier: string) => Promise<{
11
+ data?: undefined;
12
+ error?: NovuError | undefined;
13
+ }>;
14
+ };
15
+ /**
16
+ * Delete a channel connection by identifier. Works for both subscriber-owned and
17
+ * shared (workspace-level) connections the current subscriber can access.
18
+ */
19
+ declare const useDeleteChannelConnection: (props?: UseDeleteChannelConnectionProps) => UseDeleteChannelConnectionResult;
20
+
21
+ export { type UseDeleteChannelConnectionProps, type UseDeleteChannelConnectionResult, useDeleteChannelConnection };
@@ -20,11 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/utils/requestLock.ts
21
21
  var requestLock_exports = {};
22
22
  __export(requestLock_exports, {
23
+ isWebLocksSupported: () => isWebLocksSupported,
23
24
  requestLock: () => requestLock
24
25
  });
25
26
  module.exports = __toCommonJS(requestLock_exports);
27
+ function isWebLocksSupported() {
28
+ return typeof navigator !== "undefined" && "locks" in navigator && !!navigator.locks;
29
+ }
26
30
  function requestLock(id, cb) {
27
- if (!("locks" in navigator)) {
31
+ if (!isWebLocksSupported()) {
28
32
  cb(id);
29
33
  return () => {
30
34
  };
@@ -47,6 +51,7 @@ function requestLock(id, cb) {
47
51
  }
48
52
  // Annotate the CommonJS export names for ESM import in node:
49
53
  0 && (module.exports = {
54
+ isWebLocksSupported,
50
55
  requestLock
51
56
  });
52
57
  //# sourceMappingURL=requestLock.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/requestLock.ts"],"sourcesContent":["export function requestLock(id: string, cb: (id: string) => void) {\n // Check if the Lock API is available\n if (!('locks' in navigator)) {\n // If Lock API is not available, immediately invoke the callback and return a no-op function\n cb(id);\n\n return () => {};\n }\n\n let isFulfilled = false;\n let promiseResolve: () => void;\n\n const promise = new Promise<void>((resolve) => {\n promiseResolve = resolve;\n });\n\n navigator.locks.request(id, () => {\n if (!isFulfilled) {\n cb(id);\n }\n\n return promise;\n });\n\n return () => {\n isFulfilled = true;\n promiseResolve();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,YAAY,IAAY,IAA0B;AAEhE,MAAI,EAAE,WAAW,YAAY;AAE3B,OAAG,EAAE;AAEL,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,MAAI,cAAc;AAClB,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,qBAAiB;AAAA,EACnB,CAAC;AAED,YAAU,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAI,CAAC,aAAa;AAChB,SAAG,EAAE;AAAA,IACP;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,kBAAc;AACd,mBAAe;AAAA,EACjB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/requestLock.ts"],"sourcesContent":["export function isWebLocksSupported(): boolean {\n return typeof navigator !== 'undefined' && 'locks' in navigator && !!navigator.locks;\n}\n\nexport function requestLock(id: string, cb: (id: string) => void) {\n // Check if the Lock API is available\n if (!isWebLocksSupported()) {\n // If Lock API is not available, immediately invoke the callback and return a no-op function\n cb(id);\n\n return () => {};\n }\n\n let isFulfilled = false;\n let promiseResolve: () => void;\n\n const promise = new Promise<void>((resolve) => {\n promiseResolve = resolve;\n });\n\n navigator.locks.request(id, () => {\n if (!isFulfilled) {\n cb(id);\n }\n\n return promise;\n });\n\n return () => {\n isFulfilled = true;\n promiseResolve();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,sBAA+B;AAC7C,SAAO,OAAO,cAAc,eAAe,WAAW,aAAa,CAAC,CAAC,UAAU;AACjF;AAEO,SAAS,YAAY,IAAY,IAA0B;AAEhE,MAAI,CAAC,oBAAoB,GAAG;AAE1B,OAAG,EAAE;AAEL,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,MAAI,cAAc;AAClB,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,qBAAiB;AAAA,EACnB,CAAC;AAED,YAAU,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAI,CAAC,aAAa;AAChB,SAAG,EAAE;AAAA,IACP;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,kBAAc;AACd,mBAAe;AAAA,EACjB;AACF;","names":[]}
@@ -1,3 +1,4 @@
1
+ declare function isWebLocksSupported(): boolean;
1
2
  declare function requestLock(id: string, cb: (id: string) => void): () => void;
2
3
 
3
- export { requestLock };
4
+ export { isWebLocksSupported, requestLock };
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { SlackConnectButtonProps } from '@novu/js/ui';
3
3
 
4
- type DefaultSlackConnectButtonProps = Pick<SlackConnectButtonProps, 'integrationIdentifier' | 'connectionIdentifier' | 'subscriberId' | 'context' | 'scope' | 'connectionMode' | 'autoLinkUser' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
4
+ type DefaultSlackConnectButtonProps = Pick<SlackConnectButtonProps, 'integrationIdentifier' | 'connectionIdentifier' | 'subscriberId' | 'context' | 'contextHash' | 'scope' | 'connectionMode' | 'autoLinkUser' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
5
5
  declare const DefaultSlackConnectButton: (props: DefaultSlackConnectButtonProps) => react_jsx_runtime.JSX.Element;
6
6
 
7
7
  export { DefaultSlackConnectButton, type DefaultSlackConnectButtonProps };
@@ -9,6 +9,7 @@ var DefaultSlackConnectButton = (props) => {
9
9
  connectionIdentifier,
10
10
  subscriberId,
11
11
  context,
12
+ contextHash,
12
13
  scope,
13
14
  connectionMode,
14
15
  autoLinkUser,
@@ -29,6 +30,7 @@ var DefaultSlackConnectButton = (props) => {
29
30
  connectionIdentifier,
30
31
  subscriberId,
31
32
  context,
33
+ contextHash,
32
34
  scope,
33
35
  connectionMode,
34
36
  autoLinkUser,
@@ -48,6 +50,7 @@ var DefaultSlackConnectButton = (props) => {
48
50
  connectionIdentifier,
49
51
  subscriberId,
50
52
  context,
53
+ contextHash,
51
54
  scope,
52
55
  connectionMode,
53
56
  autoLinkUser,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/slack-connect-button/DefaultSlackConnectButton.tsx"],"sourcesContent":["import { SlackConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultSlackConnectButtonProps = Pick<\n SlackConnectButtonProps,\n | 'integrationIdentifier'\n | 'connectionIdentifier'\n | 'subscriberId'\n | 'context'\n | 'scope'\n | 'connectionMode'\n | 'autoLinkUser'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultSlackConnectButton = (props: DefaultSlackConnectButtonProps) => {\n const {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'SlackConnectButton',\n props: {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AA6Ef;AA1DF,IAAM,4BAA4B,CAAC,UAA0C;AAClF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,IAAI,UAAU;AAE7B,QAAM,QAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,WAAQ,OAAc;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/slack-connect-button/DefaultSlackConnectButton.tsx"],"sourcesContent":["import { SlackConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultSlackConnectButtonProps = Pick<\n SlackConnectButtonProps,\n | 'integrationIdentifier'\n | 'connectionIdentifier'\n | 'subscriberId'\n | 'context'\n | 'contextHash'\n | 'scope'\n | 'connectionMode'\n | 'autoLinkUser'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultSlackConnectButton = (props: DefaultSlackConnectButtonProps) => {\n const {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'SlackConnectButton',\n props: {\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n connectionIdentifier,\n subscriberId,\n context,\n contextHash,\n scope,\n connectionMode,\n autoLinkUser,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AAiFf;AA7DF,IAAM,4BAA4B,CAAC,UAA0C;AAClF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,IAAI,UAAU;AAE7B,QAAM,QAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,WAAQ,OAAc;AAChC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { TelegramConnectButtonProps } from '@novu/js/ui';
3
3
 
4
- type DefaultTelegramConnectButtonProps = Pick<TelegramConnectButtonProps, 'integrationIdentifier' | 'subscriberId' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
4
+ type DefaultTelegramConnectButtonProps = Pick<TelegramConnectButtonProps, 'integrationIdentifier' | 'subscriberId' | 'context' | 'onConnectSuccess' | 'onConnectError' | 'onDisconnectSuccess' | 'onDisconnectError' | 'connectLabel' | 'connectedLabel'>;
5
5
  declare const DefaultTelegramConnectButton: (props: DefaultTelegramConnectButtonProps) => react_jsx_runtime.JSX.Element;
6
6
 
7
7
  export { DefaultTelegramConnectButton, type DefaultTelegramConnectButtonProps };
@@ -7,6 +7,7 @@ var DefaultTelegramConnectButton = (props) => {
7
7
  const {
8
8
  integrationIdentifier,
9
9
  subscriberId,
10
+ context,
10
11
  onConnectSuccess,
11
12
  onConnectError,
12
13
  onDisconnectSuccess,
@@ -22,6 +23,7 @@ var DefaultTelegramConnectButton = (props) => {
22
23
  props: {
23
24
  integrationIdentifier,
24
25
  subscriberId,
26
+ context,
25
27
  onConnectSuccess,
26
28
  onConnectError,
27
29
  onDisconnectSuccess,
@@ -36,6 +38,7 @@ var DefaultTelegramConnectButton = (props) => {
36
38
  novuUI,
37
39
  integrationIdentifier,
38
40
  subscriberId,
41
+ context,
39
42
  onConnectSuccess,
40
43
  onConnectError,
41
44
  onDisconnectSuccess,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/telegram-connect-button/DefaultTelegramConnectButton.tsx"],"sourcesContent":["import { TelegramConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultTelegramConnectButtonProps = Pick<\n TelegramConnectButtonProps,\n | 'integrationIdentifier'\n | 'subscriberId'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultTelegramConnectButton = (props: DefaultTelegramConnectButtonProps) => {\n const {\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'TelegramConnectButton',\n props: {\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n subscriberId,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AAyDf;AA3CF,IAAM,+BAA+B,CAAC,UAA6C;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,IAAI,UAAU;AAE7B,QAAM,QAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,WAAQ,OAAc;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/telegram-connect-button/DefaultTelegramConnectButton.tsx"],"sourcesContent":["import { TelegramConnectButtonProps } from '@novu/js/ui';\nimport { useCallback } from 'react';\nimport { useNovuUI } from '../../context/NovuUIContext';\nimport { Mounter } from '../Mounter';\n\nexport type DefaultTelegramConnectButtonProps = Pick<\n TelegramConnectButtonProps,\n | 'integrationIdentifier'\n | 'subscriberId'\n | 'context'\n | 'onConnectSuccess'\n | 'onConnectError'\n | 'onDisconnectSuccess'\n | 'onDisconnectError'\n | 'connectLabel'\n | 'connectedLabel'\n>;\n\nexport const DefaultTelegramConnectButton = (props: DefaultTelegramConnectButtonProps) => {\n const {\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n } = props;\n const { novuUI } = useNovuUI();\n\n const mount = useCallback(\n (element: HTMLElement) => {\n return novuUI.mountComponent({\n name: 'TelegramConnectButton',\n props: {\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n },\n element,\n });\n },\n [\n novuUI,\n integrationIdentifier,\n subscriberId,\n context,\n onConnectSuccess,\n onConnectError,\n onDisconnectSuccess,\n onDisconnectError,\n connectLabel,\n connectedLabel,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n"],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AA6Df;AA9CF,IAAM,+BAA+B,CAAC,UAA6C;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,OAAO,IAAI,UAAU;AAE7B,QAAM,QAAQ;AAAA,IACZ,CAAC,YAAyB;AACxB,aAAO,OAAO,eAAe;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,oBAAC,WAAQ,OAAc;AAChC;","names":[]}
@@ -4,9 +4,11 @@ export { NovuProvider, useNovu } from './NovuProvider.js';
4
4
  export { UseChannelConnectionProps, UseChannelConnectionResult, useChannelConnection } from './useChannelConnection.js';
5
5
  export { UseChannelConnectionsProps, UseChannelConnectionsResult, useChannelConnections } from './useChannelConnections.js';
6
6
  export { UseChannelEndpointProps, UseChannelEndpointResult, useChannelEndpoint } from './useChannelEndpoint.js';
7
+ export { UseChannelEndpointsProps, UseChannelEndpointsResult, useChannelEndpoints } from './useChannelEndpoints.js';
7
8
  export { UseCountsProps, UseCountsResult, useCounts } from './useCounts.js';
8
9
  export { UseCreateChannelEndpointProps, UseCreateChannelEndpointResult, useCreateChannelEndpoint } from './useCreateChannelEndpoint.js';
9
10
  export { UseCreateSubscriptionProps, UseCreateSubscriptionResult, useCreateSubscription } from './useCreateSubscription.js';
11
+ export { UseDeleteChannelConnectionProps, UseDeleteChannelConnectionResult, useDeleteChannelConnection } from './useDeleteChannelConnection.js';
10
12
  export { UseDeleteChannelEndpointProps, UseDeleteChannelEndpointResult, useDeleteChannelEndpoint } from './useDeleteChannelEndpoint.js';
11
13
  export { UseNotificationsProps, UseNotificationsResult, useNotifications } from './useNotifications.js';
12
14
  export { UsePreferencesProps, UsePreferencesResult, usePreferences } from './usePreferences.js';
@@ -4,9 +4,11 @@ import { NovuProvider, useNovu } from "./NovuProvider.js";
4
4
  export * from "./useChannelConnection.js";
5
5
  export * from "./useChannelConnections.js";
6
6
  export * from "./useChannelEndpoint.js";
7
+ export * from "./useChannelEndpoints.js";
7
8
  export * from "./useCounts.js";
8
9
  export * from "./useCreateChannelEndpoint.js";
9
10
  export * from "./useCreateSubscription.js";
11
+ export * from "./useDeleteChannelConnection.js";
10
12
  export * from "./useDeleteChannelEndpoint.js";
11
13
  export * from "./useNotifications.js";
12
14
  export * from "./usePreferences.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export type * from '@novu/js';\nexport { PreferenceLevel, SeverityLevelEnum, WorkflowCriticalityEnum } from '@novu/js';\nexport { NovuProvider, useNovu } from './NovuProvider';\nexport * from './useChannelConnection';\nexport * from './useChannelConnections';\nexport * from './useChannelEndpoint';\nexport * from './useCounts';\nexport * from './useCreateChannelEndpoint';\nexport * from './useCreateSubscription';\nexport * from './useDeleteChannelEndpoint';\nexport * from './useNotifications';\nexport * from './usePreferences';\nexport * from './useRemoveSubscription';\nexport * from './useSchedule';\nexport * from './useSubscription';\nexport * from './useSubscriptions';\nexport * from './useTelegramSubscriberLink';\nexport * from './useUpdateSubscription';\n"],"mappings":";AACA,SAAS,iBAAiB,mBAAmB,+BAA+B;AAC5E,SAAS,cAAc,eAAe;AACtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export type * from '@novu/js';\nexport { PreferenceLevel, SeverityLevelEnum, WorkflowCriticalityEnum } from '@novu/js';\nexport { NovuProvider, useNovu } from './NovuProvider';\nexport * from './useChannelConnection';\nexport * from './useChannelConnections';\nexport * from './useChannelEndpoint';\nexport * from './useChannelEndpoints';\nexport * from './useCounts';\nexport * from './useCreateChannelEndpoint';\nexport * from './useCreateSubscription';\nexport * from './useDeleteChannelConnection';\nexport * from './useDeleteChannelEndpoint';\nexport * from './useNotifications';\nexport * from './usePreferences';\nexport * from './useRemoveSubscription';\nexport * from './useSchedule';\nexport * from './useSubscription';\nexport * from './useSubscriptions';\nexport * from './useTelegramSubscriberLink';\nexport * from './useUpdateSubscription';\n"],"mappings":";AACA,SAAS,iBAAiB,mBAAmB,+BAA+B;AAC5E,SAAS,cAAc,eAAe;AACtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -1,6 +1,6 @@
1
1
  // src/hooks/internal/useWebsocketEvent.ts
2
2
  import { useEffect } from "react";
3
- import { requestLock } from "../../utils/requestLock.js";
3
+ import { isWebLocksSupported, requestLock } from "../../utils/requestLock.js";
4
4
  import { useNovu } from "../NovuProvider.js";
5
5
  import { useBrowserTabsChannel } from "./useBrowserTabsChannel.js";
6
6
  var useWebSocketEvent = ({
@@ -15,9 +15,12 @@ var useWebSocketEvent = ({
15
15
  onMessage,
16
16
  enabled
17
17
  });
18
+ const shouldBroadcast = isWebLocksSupported();
18
19
  const updateReadCount = (data) => {
19
20
  onMessage(data);
20
- postMessage(data);
21
+ if (shouldBroadcast) {
22
+ postMessage(data);
23
+ }
21
24
  };
22
25
  useEffect(() => {
23
26
  if (!enabled) return;
@@ -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 enabled = true,\n}: {\n event: E;\n eventHandler: (args: Events[E]) => void;\n enabled?: boolean;\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 enabled,\n });\n\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n postMessage(data);\n };\n\n useEffect(() => {\n if (!enabled) return;\n\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 }, [enabled]);\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;AAAA,EACd,UAAU;AACZ,MAIM;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,IACA;AAAA,EACF,CAAC;AAED,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,gBAAY,IAAI;AAAA,EAClB;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,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,OAAO,CAAC;AACd;","names":[]}
1
+ {"version":3,"sources":["../../../../src/hooks/internal/useWebsocketEvent.ts"],"sourcesContent":["import { EventHandler, Events, SocketEventNames } from '@novu/js';\nimport { useEffect } from 'react';\nimport { isWebLocksSupported, 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 enabled = true,\n}: {\n event: E;\n eventHandler: (args: Events[E]) => void;\n enabled?: boolean;\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 enabled,\n });\n\n // When Web Locks are unavailable, requestLock runs the callback in every tab,\n // so each tab already receives the event through its own socket. Re-broadcasting\n // in that case would duplicate the event across tabs (count multiplied by tab\n // count). Only the exclusive lock owner should fan out to the other tabs.\n const shouldBroadcast = isWebLocksSupported();\n const updateReadCount: EventHandler<Events[E]> = (data) => {\n onMessage(data);\n if (shouldBroadcast) {\n postMessage(data);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\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 }, [enabled]);\n};\n"],"mappings":";AACA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB,mBAAmB;AACjD,SAAS,eAAe;AACxB,SAAS,6BAA6B;AAE/B,IAAM,oBAAoB,CAA6B;AAAA,EAC5D,OAAO;AAAA,EACP,cAAc;AAAA,EACd,UAAU;AACZ,MAIM;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,IACA;AAAA,EACF,CAAC;AAMD,QAAM,kBAAkB,oBAAoB;AAC5C,QAAM,kBAA2C,CAAC,SAAS;AACzD,cAAU,IAAI;AACd,QAAI,iBAAiB;AACnB,kBAAY,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,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,OAAO,CAAC;AACd;","names":[]}
@@ -0,0 +1,24 @@
1
+ import { ListChannelEndpointsArgs, ChannelEndpointResponse, NovuError } from '@novu/js';
2
+
3
+ type UseChannelEndpointsProps = ListChannelEndpointsArgs & {
4
+ onSuccess?: (data: ChannelEndpointResponse[]) => void;
5
+ onError?: (error: NovuError) => void;
6
+ };
7
+ type UseChannelEndpointsResult = {
8
+ endpoints: ChannelEndpointResponse[];
9
+ error?: NovuError;
10
+ isLoading: boolean;
11
+ isFetching: boolean;
12
+ refetch: () => Promise<void>;
13
+ };
14
+ /**
15
+ * List channel endpoints for the current subscriber. Use this to discover a linked
16
+ * user endpoint (e.g. a `slack_user` endpoint) for a given connection identifier.
17
+ *
18
+ * @example
19
+ * const { endpoints } = useChannelEndpoints({ integrationIdentifier: 'my-chat', connectionIdentifier });
20
+ * const isLinked = endpoints.some((endpoint) => endpoint.type === 'slack_user');
21
+ */
22
+ declare const useChannelEndpoints: (props?: UseChannelEndpointsProps) => UseChannelEndpointsResult;
23
+
24
+ export { type UseChannelEndpointsProps, type UseChannelEndpointsResult, useChannelEndpoints };
@@ -0,0 +1,68 @@
1
+ // src/hooks/useChannelEndpoints.ts
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { useNovu } from "./NovuProvider.js";
4
+ var useChannelEndpoints = (props = {}) => {
5
+ const novu = useNovu();
6
+ const propsRef = useRef(props);
7
+ propsRef.current = props;
8
+ const [endpoints, setEndpoints] = useState([]);
9
+ const [error, setError] = useState();
10
+ const [isLoading, setIsLoading] = useState(true);
11
+ const [isFetching, setIsFetching] = useState(false);
12
+ const fetchEndpoints = useCallback(
13
+ async (options) => {
14
+ const { onSuccess, onError, ...listArgs } = propsRef.current;
15
+ if (options?.refetch) {
16
+ setError(void 0);
17
+ setIsLoading(true);
18
+ }
19
+ setIsFetching(true);
20
+ try {
21
+ const response = await novu.channelEndpoints.list(listArgs);
22
+ if (response.error) {
23
+ setError(response.error);
24
+ onError?.(response.error);
25
+ } else if (response.data !== void 0) {
26
+ setEndpoints(response.data);
27
+ onSuccess?.(response.data);
28
+ }
29
+ } catch (err) {
30
+ setError(err);
31
+ onError?.(err);
32
+ } finally {
33
+ setIsLoading(false);
34
+ setIsFetching(false);
35
+ }
36
+ },
37
+ [novu]
38
+ );
39
+ useEffect(() => {
40
+ const cleanups = [
41
+ "channel-endpoint.create.resolved",
42
+ "channel-endpoint.delete.resolved",
43
+ "channel-endpoint.link.resolved"
44
+ ].map(
45
+ (event) => novu.on(event, () => {
46
+ void fetchEndpoints({ refetch: true });
47
+ })
48
+ );
49
+ void fetchEndpoints({ refetch: true });
50
+ return () => {
51
+ for (const cleanup of cleanups) {
52
+ cleanup();
53
+ }
54
+ };
55
+ }, [novu, fetchEndpoints]);
56
+ const refetch = useCallback(() => fetchEndpoints({ refetch: true }), [fetchEndpoints]);
57
+ return {
58
+ endpoints,
59
+ error,
60
+ isLoading,
61
+ isFetching,
62
+ refetch
63
+ };
64
+ };
65
+ export {
66
+ useChannelEndpoints
67
+ };
68
+ //# sourceMappingURL=useChannelEndpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useChannelEndpoints.ts"],"sourcesContent":["import type { ChannelEndpointResponse, ListChannelEndpointsArgs, NovuError } from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useNovu } from './NovuProvider';\n\nexport type UseChannelEndpointsProps = ListChannelEndpointsArgs & {\n onSuccess?: (data: ChannelEndpointResponse[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseChannelEndpointsResult = {\n endpoints: ChannelEndpointResponse[];\n error?: NovuError;\n isLoading: boolean;\n isFetching: boolean;\n refetch: () => Promise<void>;\n};\n\n/**\n * List channel endpoints for the current subscriber. Use this to discover a linked\n * user endpoint (e.g. a `slack_user` endpoint) for a given connection identifier.\n *\n * @example\n * const { endpoints } = useChannelEndpoints({ integrationIdentifier: 'my-chat', connectionIdentifier });\n * const isLinked = endpoints.some((endpoint) => endpoint.type === 'slack_user');\n */\nexport const useChannelEndpoints = (props: UseChannelEndpointsProps = {}): UseChannelEndpointsResult => {\n const novu = useNovu();\n const propsRef = useRef<UseChannelEndpointsProps>(props);\n propsRef.current = props;\n\n const [endpoints, setEndpoints] = useState<ChannelEndpointResponse[]>([]);\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const fetchEndpoints = useCallback(\n async (options?: { refetch: boolean }) => {\n const { onSuccess, onError, ...listArgs } = propsRef.current;\n\n if (options?.refetch) {\n setError(undefined);\n setIsLoading(true);\n }\n\n setIsFetching(true);\n\n try {\n const response = await novu.channelEndpoints.list(listArgs);\n\n if (response.error) {\n setError(response.error as NovuError);\n onError?.(response.error as NovuError);\n } else if (response.data !== undefined) {\n setEndpoints(response.data);\n onSuccess?.(response.data);\n }\n } catch (err) {\n setError(err as NovuError);\n onError?.(err as NovuError);\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n },\n [novu]\n );\n\n useEffect(() => {\n const cleanups = (\n [\n 'channel-endpoint.create.resolved',\n 'channel-endpoint.delete.resolved',\n 'channel-endpoint.link.resolved',\n ] as const\n ).map((event) =>\n novu.on(event, () => {\n void fetchEndpoints({ refetch: true });\n })\n );\n\n void fetchEndpoints({ refetch: true });\n\n return () => {\n for (const cleanup of cleanups) {\n cleanup();\n }\n };\n }, [novu, fetchEndpoints]);\n\n const refetch = useCallback(() => fetchEndpoints({ refetch: true }), [fetchEndpoints]);\n\n return {\n endpoints,\n error,\n isLoading,\n isFetching,\n refetch,\n };\n};\n"],"mappings":";AACA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,eAAe;AAuBjB,IAAM,sBAAsB,CAAC,QAAkC,CAAC,MAAiC;AACtG,QAAM,OAAO,QAAQ;AACrB,QAAM,WAAW,OAAiC,KAAK;AACvD,WAAS,UAAU;AAEnB,QAAM,CAAC,WAAW,YAAY,IAAI,SAAoC,CAAC,CAAC;AACxE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoB;AAC9C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAC/C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,QAAM,iBAAiB;AAAA,IACrB,OAAO,YAAmC;AACxC,YAAM,EAAE,WAAW,SAAS,GAAG,SAAS,IAAI,SAAS;AAErD,UAAI,SAAS,SAAS;AACpB,iBAAS,MAAS;AAClB,qBAAa,IAAI;AAAA,MACnB;AAEA,oBAAc,IAAI;AAElB,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK,QAAQ;AAE1D,YAAI,SAAS,OAAO;AAClB,mBAAS,SAAS,KAAkB;AACpC,oBAAU,SAAS,KAAkB;AAAA,QACvC,WAAW,SAAS,SAAS,QAAW;AACtC,uBAAa,SAAS,IAAI;AAC1B,sBAAY,SAAS,IAAI;AAAA,QAC3B;AAAA,MACF,SAAS,KAAK;AACZ,iBAAS,GAAgB;AACzB,kBAAU,GAAgB;AAAA,MAC5B,UAAE;AACA,qBAAa,KAAK;AAClB,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,YAAU,MAAM;AACd,UAAM,WACJ;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACA;AAAA,MAAI,CAAC,UACL,KAAK,GAAG,OAAO,MAAM;AACnB,aAAK,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,SAAK,eAAe,EAAE,SAAS,KAAK,CAAC;AAErC,WAAO,MAAM;AACX,iBAAW,WAAW,UAAU;AAC9B,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,cAAc,CAAC;AAEzB,QAAM,UAAU,YAAY,MAAM,eAAe,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;AAErF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -1,5 +1,9 @@
1
1
  // src/hooks/useCounts.ts
2
- import { NOTIFICATION_COUNT_SYNC_EVENTS, checkNotificationMatchesFilter, isSameFilter } from "@novu/js";
2
+ import {
3
+ checkNotificationMatchesFilter,
4
+ isSameFilter,
5
+ NOTIFICATION_COUNT_SYNC_EVENTS
6
+ } from "@novu/js";
3
7
  import { useCallback, useEffect, useRef, useState } from "react";
4
8
  import { useDataRef } from "./internal/useDataRef.js";
5
9
  import { useWebSocketEvent } from "./internal/useWebsocketEvent.js";
@@ -24,9 +28,7 @@ var useCounts = (props) => {
24
28
  const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));
25
29
  let countFiltersToFetch = [];
26
30
  if (notification) {
27
- countFiltersToFetch = currentFilters.filter(
28
- (filter) => checkNotificationMatchesFilter(notification, filter)
29
- );
31
+ countFiltersToFetch = currentFilters.filter((filter) => checkNotificationMatchesFilter(notification, filter));
30
32
  } else {
31
33
  countFiltersToFetch = currentFilters;
32
34
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useCounts.ts"],"sourcesContent":["import { NOTIFICATION_COUNT_SYNC_EVENTS, checkNotificationMatchesFilter, isSameFilter, Notification, NotificationFilter, NovuError } from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useDataRef } from './internal/useDataRef';\nimport { useWebSocketEvent } from './internal/useWebsocketEvent';\nimport { useNovu, useRealtime } from './NovuProvider';\n\ntype Count = {\n count: number;\n filter: NotificationFilter;\n};\n\n/**\n * Props for the useCounts hook.\n *\n * @example\n * ```tsx\n * // Count unread notifications\n * const { counts } = useCounts({\n * filters: [{ read: false }]\n * });\n *\n * // Count unseen notifications with specific tags\n * const { counts } = useCounts({\n * filters: [{ seen: false, tags: ['important'] }]\n * });\n *\n * // Count seen but unread notifications\n * const { counts } = useCounts({\n * filters: [{ seen: true, read: false }]\n * });\n *\n * // Opt out of the built-in realtime count updates and drive them yourself\n * const { counts, refetch } = useCounts({\n * filters: [{ read: false }],\n * realtime: false,\n * });\n * ```\n */\nexport type UseCountsProps = {\n filters: NotificationFilter[];\n /**\n * When `false`, disables the WebSocket subscriptions that auto-resync\n * counts on `notifications.notification_received` and\n * `notifications.unread_count_changed`. The filter-driven fetch and\n * `refetch()` keep working. Use alongside\n * `useNotifications({ realtime: false })` when you drive live updates\n * yourself.\n *\n * When set, this prop takes precedence over the `realtime` config on\n * `<NovuProvider />`. When omitted, the provider value (default `true`) is used.\n */\n realtime?: boolean;\n onSuccess?: (data: Count[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseCountsResult = {\n counts?: Count[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const useCounts = (props: UseCountsProps): UseCountsResult => {\n const { filters, realtime: propsRealtime, onSuccess, onError } = props;\n const novu = useNovu();\n const { notifications } = novu;\n const providerRealtime = useRealtime();\n const realtime = propsRealtime ?? providerRealtime;\n const filtersRef = useDataRef<NotificationFilter[]>(filters);\n const onSuccessRef = useDataRef(onSuccess);\n const onErrorRef = useDataRef(onError);\n const syncGenerationRef = useRef(0);\n const [error, setError] = useState<NovuError>();\n const [counts, setCounts] = useState<Count[]>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = useCallback(\n async (notification?: Notification, overrideFilters?: NotificationFilter[]) => {\n const currentFilters = overrideFilters || filtersRef.current;\n const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));\n let countFiltersToFetch: NotificationFilter[] = [];\n\n if (notification) {\n countFiltersToFetch = currentFilters.filter((filter) =>\n checkNotificationMatchesFilter(notification, filter)\n );\n } else {\n countFiltersToFetch = currentFilters;\n }\n\n if (countFiltersToFetch.length === 0) {\n return;\n }\n\n const generation = ++syncGenerationRef.current;\n setIsFetching(true);\n\n const countsRes = await notifications.count({ filters: countFiltersToFetch });\n\n if (generation !== syncGenerationRef.current) {\n return;\n }\n\n setIsFetching(false);\n setIsLoading(false);\n\n if (countsRes.error) {\n setError(countsRes.error);\n onErrorRef.current?.(countsRes.error);\n\n return;\n }\n\n const data = countsRes.data!;\n onSuccessRef.current?.(data.counts);\n\n setCounts((oldCounts) => {\n const newCounts: Count[] = [];\n const countsReceived = data.counts;\n\n for (let i = 0; i < existingCounts.length; i++) {\n const existingFilter = existingCounts[i].filter;\n const countReceived = countsReceived.find((c) => isSameFilter(c.filter, existingFilter));\n const count = countReceived || oldCounts?.[i];\n if (count) {\n newCounts.push(count);\n }\n }\n\n return newCounts;\n });\n },\n [notifications, filtersRef, onErrorRef, onSuccessRef]\n );\n\n useWebSocketEvent({\n event: 'notifications.notification_received',\n enabled: realtime,\n eventHandler: (data) => {\n sync(data.result);\n },\n });\n\n useWebSocketEvent({\n event: 'notifications.unread_count_changed',\n enabled: realtime,\n eventHandler: () => {\n sync();\n },\n });\n\n useEffect(() => {\n const cleanups = NOTIFICATION_COUNT_SYNC_EVENTS.map((event) =>\n novu.on(event, (payload) => {\n if ('error' in payload && payload.error) {\n return;\n }\n\n sync();\n })\n );\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [novu, sync]);\n\n useEffect(() => {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n sync(undefined, filters);\n }, [JSON.stringify(filters), sync]);\n\n const refetch = useCallback(async () => {\n await sync();\n }, [sync]);\n\n return { counts, error, refetch, isLoading, isFetching };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/hooks/useCounts.ts"],"sourcesContent":["import {\n checkNotificationMatchesFilter,\n isSameFilter,\n NOTIFICATION_COUNT_SYNC_EVENTS,\n Notification,\n NotificationFilter,\n NovuError,\n} from '@novu/js';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useDataRef } from './internal/useDataRef';\nimport { useWebSocketEvent } from './internal/useWebsocketEvent';\nimport { useNovu, useRealtime } from './NovuProvider';\n\ntype Count = {\n count: number;\n filter: NotificationFilter;\n};\n\n/**\n * Props for the useCounts hook.\n *\n * @example\n * ```tsx\n * // Count unread notifications\n * const { counts } = useCounts({\n * filters: [{ read: false }]\n * });\n *\n * // Count unseen notifications with specific tags\n * const { counts } = useCounts({\n * filters: [{ seen: false, tags: ['important'] }]\n * });\n *\n * // Count seen but unread notifications\n * const { counts } = useCounts({\n * filters: [{ seen: true, read: false }]\n * });\n *\n * // Opt out of the built-in realtime count updates and drive them yourself\n * const { counts, refetch } = useCounts({\n * filters: [{ read: false }],\n * realtime: false,\n * });\n * ```\n */\nexport type UseCountsProps = {\n filters: NotificationFilter[];\n /**\n * When `false`, disables the WebSocket subscriptions that auto-resync\n * counts on `notifications.notification_received` and\n * `notifications.unread_count_changed`. The filter-driven fetch and\n * `refetch()` keep working. Use alongside\n * `useNotifications({ realtime: false })` when you drive live updates\n * yourself.\n *\n * When set, this prop takes precedence over the `realtime` config on\n * `<NovuProvider />`. When omitted, the provider value (default `true`) is used.\n */\n realtime?: boolean;\n onSuccess?: (data: Count[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseCountsResult = {\n counts?: Count[];\n error?: NovuError;\n isLoading: boolean; // initial loading\n isFetching: boolean; // the request is in flight\n refetch: () => Promise<void>;\n};\n\nexport const useCounts = (props: UseCountsProps): UseCountsResult => {\n const { filters, realtime: propsRealtime, onSuccess, onError } = props;\n const novu = useNovu();\n const { notifications } = novu;\n const providerRealtime = useRealtime();\n const realtime = propsRealtime ?? providerRealtime;\n const filtersRef = useDataRef<NotificationFilter[]>(filters);\n const onSuccessRef = useDataRef(onSuccess);\n const onErrorRef = useDataRef(onError);\n const syncGenerationRef = useRef(0);\n const [error, setError] = useState<NovuError>();\n const [counts, setCounts] = useState<Count[]>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n\n const sync = useCallback(\n async (notification?: Notification, overrideFilters?: NotificationFilter[]) => {\n const currentFilters = overrideFilters || filtersRef.current;\n const existingCounts = currentFilters.map((filter) => ({ count: 0, filter }));\n let countFiltersToFetch: NotificationFilter[] = [];\n\n if (notification) {\n countFiltersToFetch = currentFilters.filter((filter) => checkNotificationMatchesFilter(notification, filter));\n } else {\n countFiltersToFetch = currentFilters;\n }\n\n if (countFiltersToFetch.length === 0) {\n return;\n }\n\n const generation = ++syncGenerationRef.current;\n setIsFetching(true);\n\n const countsRes = await notifications.count({ filters: countFiltersToFetch });\n\n if (generation !== syncGenerationRef.current) {\n return;\n }\n\n setIsFetching(false);\n setIsLoading(false);\n\n if (countsRes.error) {\n setError(countsRes.error);\n onErrorRef.current?.(countsRes.error);\n\n return;\n }\n\n const data = countsRes.data!;\n onSuccessRef.current?.(data.counts);\n\n setCounts((oldCounts) => {\n const newCounts: Count[] = [];\n const countsReceived = data.counts;\n\n for (let i = 0; i < existingCounts.length; i++) {\n const existingFilter = existingCounts[i].filter;\n const countReceived = countsReceived.find((c) => isSameFilter(c.filter, existingFilter));\n const count = countReceived || oldCounts?.[i];\n if (count) {\n newCounts.push(count);\n }\n }\n\n return newCounts;\n });\n },\n [notifications, filtersRef, onErrorRef, onSuccessRef]\n );\n\n useWebSocketEvent({\n event: 'notifications.notification_received',\n enabled: realtime,\n eventHandler: (data) => {\n sync(data.result);\n },\n });\n\n useWebSocketEvent({\n event: 'notifications.unread_count_changed',\n enabled: realtime,\n eventHandler: () => {\n sync();\n },\n });\n\n useEffect(() => {\n const cleanups = NOTIFICATION_COUNT_SYNC_EVENTS.map((event) =>\n novu.on(event, (payload) => {\n if ('error' in payload && payload.error) {\n return;\n }\n\n sync();\n })\n );\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [novu, sync]);\n\n useEffect(() => {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n sync(undefined, filters);\n }, [JSON.stringify(filters), sync]);\n\n const refetch = useCallback(async () => {\n await sync();\n }, [sync]);\n\n return { counts, error, refetch, isLoading, isFetching };\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,21 @@
1
+ import { NovuError } from '@novu/js';
2
+
3
+ type UseDeleteChannelConnectionProps = {
4
+ onSuccess?: () => void;
5
+ onError?: (error: NovuError) => void;
6
+ };
7
+ type UseDeleteChannelConnectionResult = {
8
+ isDeleting: boolean;
9
+ error?: NovuError;
10
+ remove: (identifier: string) => Promise<{
11
+ data?: undefined;
12
+ error?: NovuError | undefined;
13
+ }>;
14
+ };
15
+ /**
16
+ * Delete a channel connection by identifier. Works for both subscriber-owned and
17
+ * shared (workspace-level) connections the current subscriber can access.
18
+ */
19
+ declare const useDeleteChannelConnection: (props?: UseDeleteChannelConnectionProps) => UseDeleteChannelConnectionResult;
20
+
21
+ export { type UseDeleteChannelConnectionProps, type UseDeleteChannelConnectionResult, useDeleteChannelConnection };
@@ -0,0 +1,43 @@
1
+ // src/hooks/useDeleteChannelConnection.ts
2
+ import { useCallback, useRef, useState } from "react";
3
+ import { useNovu } from "./NovuProvider.js";
4
+ var useDeleteChannelConnection = (props = {}) => {
5
+ const propsRef = useRef(props);
6
+ propsRef.current = props;
7
+ const novu = useNovu();
8
+ const [isDeleting, setIsDeleting] = useState(false);
9
+ const [error, setError] = useState();
10
+ const remove = useCallback(
11
+ async (identifier) => {
12
+ setError(void 0);
13
+ setIsDeleting(true);
14
+ try {
15
+ const response = await novu.channelConnections.delete({ identifier });
16
+ if (response.error) {
17
+ setError(response.error);
18
+ propsRef.current.onError?.(response.error);
19
+ } else {
20
+ propsRef.current.onSuccess?.();
21
+ }
22
+ return response;
23
+ } catch (err) {
24
+ const novuError = err;
25
+ setError(novuError);
26
+ propsRef.current.onError?.(novuError);
27
+ return { error: novuError };
28
+ } finally {
29
+ setIsDeleting(false);
30
+ }
31
+ },
32
+ [novu]
33
+ );
34
+ return {
35
+ remove,
36
+ isDeleting,
37
+ error
38
+ };
39
+ };
40
+ export {
41
+ useDeleteChannelConnection
42
+ };
43
+ //# sourceMappingURL=useDeleteChannelConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/useDeleteChannelConnection.ts"],"sourcesContent":["import type { NovuError } from '@novu/js';\nimport { useCallback, useRef, useState } from 'react';\nimport { useNovu } from './NovuProvider';\n\nexport type UseDeleteChannelConnectionProps = {\n onSuccess?: () => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseDeleteChannelConnectionResult = {\n isDeleting: boolean;\n error?: NovuError;\n remove: (identifier: string) => Promise<{\n data?: undefined;\n error?: NovuError | undefined;\n }>;\n};\n\n/**\n * Delete a channel connection by identifier. Works for both subscriber-owned and\n * shared (workspace-level) connections the current subscriber can access.\n */\nexport const useDeleteChannelConnection = (\n props: UseDeleteChannelConnectionProps = {}\n): UseDeleteChannelConnectionResult => {\n const propsRef = useRef<UseDeleteChannelConnectionProps>(props);\n propsRef.current = props;\n const novu = useNovu();\n const [isDeleting, setIsDeleting] = useState(false);\n const [error, setError] = useState<NovuError>();\n\n const remove = useCallback(\n async (identifier: string) => {\n setError(undefined);\n setIsDeleting(true);\n\n try {\n const response = await novu.channelConnections.delete({ identifier });\n\n if (response.error) {\n setError(response.error as NovuError);\n propsRef.current.onError?.(response.error as NovuError);\n } else {\n propsRef.current.onSuccess?.();\n }\n\n return response as { data?: undefined; error?: NovuError };\n } catch (err) {\n const novuError = err as NovuError;\n setError(novuError);\n propsRef.current.onError?.(novuError);\n\n return { error: novuError };\n } finally {\n setIsDeleting(false);\n }\n },\n [novu]\n );\n\n return {\n remove,\n isDeleting,\n error,\n };\n};\n"],"mappings":";AACA,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,eAAe;AAoBjB,IAAM,6BAA6B,CACxC,QAAyC,CAAC,MACL;AACrC,QAAM,WAAW,OAAwC,KAAK;AAC9D,WAAS,UAAU;AACnB,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoB;AAE9C,QAAM,SAAS;AAAA,IACb,OAAO,eAAuB;AAC5B,eAAS,MAAS;AAClB,oBAAc,IAAI;AAElB,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,mBAAmB,OAAO,EAAE,WAAW,CAAC;AAEpE,YAAI,SAAS,OAAO;AAClB,mBAAS,SAAS,KAAkB;AACpC,mBAAS,QAAQ,UAAU,SAAS,KAAkB;AAAA,QACxD,OAAO;AACL,mBAAS,QAAQ,YAAY;AAAA,QAC/B;AAEA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,cAAM,YAAY;AAClB,iBAAS,SAAS;AAClB,iBAAS,QAAQ,UAAU,SAAS;AAEpC,eAAO,EAAE,OAAO,UAAU;AAAA,MAC5B,UAAE;AACA,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -1,3 +1,4 @@
1
+ declare function isWebLocksSupported(): boolean;
1
2
  declare function requestLock(id: string, cb: (id: string) => void): () => void;
2
3
 
3
- export { requestLock };
4
+ export { isWebLocksSupported, requestLock };
@@ -1,6 +1,9 @@
1
1
  // src/utils/requestLock.ts
2
+ function isWebLocksSupported() {
3
+ return typeof navigator !== "undefined" && "locks" in navigator && !!navigator.locks;
4
+ }
2
5
  function requestLock(id, cb) {
3
- if (!("locks" in navigator)) {
6
+ if (!isWebLocksSupported()) {
4
7
  cb(id);
5
8
  return () => {
6
9
  };
@@ -22,6 +25,7 @@ function requestLock(id, cb) {
22
25
  };
23
26
  }
24
27
  export {
28
+ isWebLocksSupported,
25
29
  requestLock
26
30
  };
27
31
  //# sourceMappingURL=requestLock.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/requestLock.ts"],"sourcesContent":["export function requestLock(id: string, cb: (id: string) => void) {\n // Check if the Lock API is available\n if (!('locks' in navigator)) {\n // If Lock API is not available, immediately invoke the callback and return a no-op function\n cb(id);\n\n return () => {};\n }\n\n let isFulfilled = false;\n let promiseResolve: () => void;\n\n const promise = new Promise<void>((resolve) => {\n promiseResolve = resolve;\n });\n\n navigator.locks.request(id, () => {\n if (!isFulfilled) {\n cb(id);\n }\n\n return promise;\n });\n\n return () => {\n isFulfilled = true;\n promiseResolve();\n };\n}\n"],"mappings":";AAAO,SAAS,YAAY,IAAY,IAA0B;AAEhE,MAAI,EAAE,WAAW,YAAY;AAE3B,OAAG,EAAE;AAEL,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,MAAI,cAAc;AAClB,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,qBAAiB;AAAA,EACnB,CAAC;AAED,YAAU,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAI,CAAC,aAAa;AAChB,SAAG,EAAE;AAAA,IACP;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,kBAAc;AACd,mBAAe;AAAA,EACjB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/requestLock.ts"],"sourcesContent":["export function isWebLocksSupported(): boolean {\n return typeof navigator !== 'undefined' && 'locks' in navigator && !!navigator.locks;\n}\n\nexport function requestLock(id: string, cb: (id: string) => void) {\n // Check if the Lock API is available\n if (!isWebLocksSupported()) {\n // If Lock API is not available, immediately invoke the callback and return a no-op function\n cb(id);\n\n return () => {};\n }\n\n let isFulfilled = false;\n let promiseResolve: () => void;\n\n const promise = new Promise<void>((resolve) => {\n promiseResolve = resolve;\n });\n\n navigator.locks.request(id, () => {\n if (!isFulfilled) {\n cb(id);\n }\n\n return promise;\n });\n\n return () => {\n isFulfilled = true;\n promiseResolve();\n };\n}\n"],"mappings":";AAAO,SAAS,sBAA+B;AAC7C,SAAO,OAAO,cAAc,eAAe,WAAW,aAAa,CAAC,CAAC,UAAU;AACjF;AAEO,SAAS,YAAY,IAAY,IAA0B;AAEhE,MAAI,CAAC,oBAAoB,GAAG;AAE1B,OAAG,EAAE;AAEL,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,MAAI,cAAc;AAClB,MAAI;AAEJ,QAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,qBAAiB;AAAA,EACnB,CAAC;AAED,YAAU,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAI,CAAC,aAAa;AAChB,SAAG,EAAE;AAAA,IACP;AAEA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,kBAAc;AACd,mBAAe;AAAA,EACjB;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novu/react",
3
- "version": "3.18.0",
3
+ "version": "3.18.2",
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.18.0"
124
+ "@novu/js": "3.18.2"
125
125
  },
126
126
  "nx": {
127
127
  "tags": [