@webiny/app-websockets 0.0.0-unstable.a4637c5ce6 β†’ 0.0.0-unstable.b6d7105cee

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 (66) hide show
  1. package/README.md +8 -9
  2. package/WebsocketsContextProvider.d.ts +1 -1
  3. package/WebsocketsContextProvider.js +139 -156
  4. package/WebsocketsContextProvider.js.map +1 -1
  5. package/domain/WebsocketsAction.d.ts +1 -1
  6. package/domain/WebsocketsAction.js +17 -24
  7. package/domain/WebsocketsAction.js.map +1 -1
  8. package/domain/WebsocketsActions.d.ts +1 -3
  9. package/domain/WebsocketsActions.js +52 -78
  10. package/domain/WebsocketsActions.js.map +1 -1
  11. package/domain/WebsocketsConnection.d.ts +1 -4
  12. package/domain/WebsocketsConnection.js +73 -107
  13. package/domain/WebsocketsConnection.js.map +1 -1
  14. package/domain/WebsocketsManager.d.ts +1 -1
  15. package/domain/WebsocketsManager.js +33 -34
  16. package/domain/WebsocketsManager.js.map +1 -1
  17. package/domain/WebsocketsSubscriptionManager.d.ts +2 -2
  18. package/domain/WebsocketsSubscriptionManager.js +58 -65
  19. package/domain/WebsocketsSubscriptionManager.js.map +1 -1
  20. package/domain/abstractions/IWebsocketsAction.d.ts +1 -1
  21. package/domain/abstractions/IWebsocketsAction.js +0 -3
  22. package/domain/abstractions/IWebsocketsActions.d.ts +2 -2
  23. package/domain/abstractions/IWebsocketsActions.js +0 -3
  24. package/domain/abstractions/IWebsocketsConnection.d.ts +2 -2
  25. package/domain/abstractions/IWebsocketsConnection.js +7 -6
  26. package/domain/abstractions/IWebsocketsConnection.js.map +1 -1
  27. package/domain/abstractions/IWebsocketsManager.d.ts +2 -6
  28. package/domain/abstractions/IWebsocketsManager.js +0 -3
  29. package/domain/abstractions/IWebsocketsSubscriptionManager.d.ts +2 -2
  30. package/domain/abstractions/IWebsocketsSubscriptionManager.js +0 -3
  31. package/domain/abstractions/types.d.ts +1 -1
  32. package/domain/abstractions/types.js +19 -18
  33. package/domain/abstractions/types.js.map +1 -1
  34. package/domain/index.d.ts +5 -5
  35. package/domain/index.js +5 -7
  36. package/domain/types.d.ts +6 -6
  37. package/domain/types.js +2 -8
  38. package/events/WebsocketEvent.d.ts +10 -0
  39. package/events/WebsocketEvent.js +13 -0
  40. package/events/WebsocketEvent.js.map +1 -0
  41. package/events/abstractions.d.ts +13 -0
  42. package/events/abstractions.js +5 -0
  43. package/events/abstractions.js.map +1 -0
  44. package/exports/admin/websockets.d.ts +1 -0
  45. package/exports/admin/websockets.js +1 -0
  46. package/hooks/index.d.ts +1 -1
  47. package/hooks/index.js +1 -3
  48. package/hooks/useWebsockets.d.ts +1 -1
  49. package/hooks/useWebsockets.js +6 -7
  50. package/hooks/useWebsockets.js.map +1 -1
  51. package/index.d.ts +6 -3
  52. package/index.js +14 -15
  53. package/index.js.map +1 -1
  54. package/package.json +20 -19
  55. package/types.d.ts +2 -2
  56. package/types.js +1 -4
  57. package/utils/getUrl.js +4 -3
  58. package/utils/getUrl.js.map +1 -1
  59. package/domain/abstractions/IWebsocketsAction.js.map +0 -1
  60. package/domain/abstractions/IWebsocketsActions.js.map +0 -1
  61. package/domain/abstractions/IWebsocketsManager.js.map +0 -1
  62. package/domain/abstractions/IWebsocketsSubscriptionManager.js.map +0 -1
  63. package/domain/index.js.map +0 -1
  64. package/domain/types.js.map +0 -1
  65. package/hooks/index.js.map +0 -1
  66. package/types.js.map +0 -1
package/README.md CHANGED
@@ -1,12 +1,11 @@
1
1
  # @webiny/app-websockets
2
- [![](https://img.shields.io/npm/dw/@webiny/app-websockets.svg)](https://www.npmjs.com/package/@webiny/app-websockets)
3
- [![](https://img.shields.io/npm/v/@webiny/app-websockets.svg)](https://www.npmjs.com/package/@webiny/app-websockets)
4
- [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
5
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
6
2
 
7
- Exposes a simple `SocketsProvider` React provider component and enables you to quickly send socket messages via the `useSockets` React hook.
3
+ > [!NOTE]
4
+ > This package is part of the [Webiny](https://www.webiny.com) monorepo.
5
+ > It’s **included in every Webiny project by default** and is not meant to be used as a standalone package.
8
6
 
9
- ## Install
10
- ```
11
- yarn add @webiny/app-websockets
12
- ```
7
+ πŸ“˜ **Documentation:** [https://www.webiny.com/docs](https://www.webiny.com/docs)
8
+
9
+ ---
10
+
11
+ _This README file is automatically generated during the publish process._
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { IWebsocketsContext } from "./types";
2
+ import type { IWebsocketsContext } from "./types.js";
3
3
  export interface IWebsocketsContextProviderProps {
4
4
  loader?: React.ReactElement;
5
5
  children: React.ReactNode;
@@ -1,163 +1,146 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
- import { useTenancy } from "@webiny/app-tenancy";
3
- import { useI18N } from "@webiny/app-i18n";
4
- import { useSecurity } from "@webiny/app-security";
5
- import { WebsocketsCloseCode } from "./types";
6
- import { createWebsocketsAction, createWebsocketsActions, createWebsocketsConnection, createWebsocketsManager, createWebsocketsSubscriptionManager } from "./domain";
7
- import { getUrl } from "./utils/getUrl";
8
- export const WebsocketsContext = /*#__PURE__*/React.createContext(undefined);
9
- export const WebsocketsContextProvider = props => {
10
- const {
11
- tenant
12
- } = useTenancy();
13
- const {
14
- getCurrentLocale
15
- } = useI18N();
16
- const {
17
- getIdToken
18
- } = useSecurity();
19
- const locale = getCurrentLocale("default");
20
- const socketsRef = useRef();
21
- const [current, setCurrent] = useState({});
22
- const getToken = useCallback(async () => {
23
- return await getIdToken();
24
- }, [getIdToken]);
25
- const subscriptionManager = useMemo(() => {
26
- const manager = createWebsocketsSubscriptionManager();
27
- let currentIteration = 0;
28
- manager.onClose(event => {
29
- if (currentIteration > 5 || event.code !== WebsocketsCloseCode.GOING_AWAY) {
30
- return;
31
- }
32
- currentIteration++;
33
- setTimeout(() => {
34
- if (!socketsRef.current) {
35
- return;
36
- } else if (socketsRef.current.isClosed()) {
37
- console.log("Running auto-reconnect.");
38
- socketsRef.current.connect();
39
- }
40
- }, 1000);
41
- });
42
- return manager;
43
- }, []);
44
-
45
- /**
46
- * We need this useEffect to close the websocket connection and remove window focus event in case component is unmounted.
47
- * This will, probably, happen only during the development phase.
48
- *
49
- * If we did not disconnect on component unmount, we would have a memory leak - multiple connections would be opened.
50
- */
51
- useEffect(() => {
52
- /**
53
- * We want to add a window event listener which will check if the connection is closed, and if its - it will connect again.
54
- */
55
- const abortController = new AbortController();
56
- window.addEventListener("focus", () => {
57
- if (!socketsRef.current) {
58
- return;
59
- } else if (socketsRef.current.isClosed()) {
60
- console.log("Running auto-reconnect on focus.");
61
- socketsRef.current.connect();
62
- }
63
- }, {
64
- signal: abortController.signal
65
- });
66
- window.addEventListener("close", () => {
67
- subscriptionManager.triggerOnClose(new CloseEvent("windowClose", {
68
- code: WebsocketsCloseCode.GOING_AWAY,
69
- reason: "Closing Window or Tab."
70
- }));
71
- }, {
72
- signal: abortController.signal
73
- });
74
- return () => {
75
- abortController.abort();
76
- };
77
- }, []);
78
- useEffect(() => {
79
- (async () => {
80
- const token = await getToken();
81
- if (!token || !tenant || !locale) {
82
- return;
83
- } else if (current.tenant === tenant && current.locale === locale) {
84
- return;
85
- } else if (socketsRef.current) {
86
- await socketsRef.current.close(WebsocketsCloseCode.NORMAL, "Changing tenant/locale.");
87
- }
88
- const url = getUrl();
89
- if (!url) {
90
- console.error("Not possible to connect to the websocket without a valid URL.", {
91
- tenant,
92
- locale,
93
- token
1
+ import react, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { useFeature, useTenantContext } from "@webiny/app-admin";
3
+ import { AuthenticationContextFeature } from "@webiny/app-admin/features/security/AuthenticationContext/feature.js";
4
+ import { EventPublisherFeature } from "@webiny/app/features/eventPublisher/feature.js";
5
+ import { WebsocketEvent } from "./events/WebsocketEvent.js";
6
+ import { WebsocketsCloseCode } from "./types.js";
7
+ import { createWebsocketsAction, createWebsocketsActions, createWebsocketsConnection, createWebsocketsManager, createWebsocketsSubscriptionManager } from "./domain/index.js";
8
+ import { getUrl } from "./utils/getUrl.js";
9
+ const WebsocketsContext = /*#__PURE__*/ react.createContext(void 0);
10
+ const WebsocketsContextProvider = (props)=>{
11
+ const { tenant } = useTenantContext();
12
+ const { authenticationContext } = useFeature(AuthenticationContextFeature);
13
+ const { eventPublisher } = useFeature(EventPublisherFeature);
14
+ const socketsRef = useRef(null);
15
+ const [current, setCurrent] = useState({});
16
+ const getToken = useCallback(async ()=>await authenticationContext.getIdToken(), [
17
+ authenticationContext
18
+ ]);
19
+ const subscriptionManager = useMemo(()=>{
20
+ const manager = createWebsocketsSubscriptionManager();
21
+ let currentIteration = 0;
22
+ manager.onClose((event)=>{
23
+ if (currentIteration > 5 || event.code !== WebsocketsCloseCode.GOING_AWAY) return;
24
+ currentIteration++;
25
+ setTimeout(()=>{
26
+ if (!socketsRef.current) return;
27
+ if (socketsRef.current.isClosed()) {
28
+ console.log("Running auto-reconnect.");
29
+ socketsRef.current.connect();
30
+ }
31
+ }, 1000);
94
32
  });
95
- return;
96
- }
97
- socketsRef.current = createWebsocketsManager(createWebsocketsConnection({
98
- subscriptionManager,
99
- url,
33
+ return manager;
34
+ }, []);
35
+ useEffect(()=>{
36
+ const abortController = new AbortController();
37
+ window.addEventListener("focus", ()=>{
38
+ if (!socketsRef.current) return;
39
+ if (socketsRef.current.isClosed()) {
40
+ console.log("Running auto-reconnect on focus.");
41
+ socketsRef.current.connect();
42
+ }
43
+ }, {
44
+ signal: abortController.signal
45
+ });
46
+ window.addEventListener("close", ()=>{
47
+ subscriptionManager.triggerOnClose(new CloseEvent("windowClose", {
48
+ code: WebsocketsCloseCode.GOING_AWAY,
49
+ reason: "Closing Window or Tab."
50
+ }));
51
+ }, {
52
+ signal: abortController.signal
53
+ });
54
+ return ()=>{
55
+ abortController.abort();
56
+ };
57
+ }, []);
58
+ useEffect(()=>{
59
+ (async ()=>{
60
+ const token = await getToken();
61
+ if (!token || !tenant) return;
62
+ if (current.tenant === tenant) return;
63
+ if (socketsRef.current) await socketsRef.current.close(WebsocketsCloseCode.NORMAL, "Changing tenant.");
64
+ const url = getUrl();
65
+ if (!url) return void console.error("Not possible to connect to the websocket without a valid URL.", {
66
+ tenant,
67
+ token
68
+ });
69
+ socketsRef.current = createWebsocketsManager(createWebsocketsConnection({
70
+ subscriptionManager,
71
+ url,
72
+ tenant,
73
+ getToken,
74
+ protocol: [
75
+ "webiny-ws-v1"
76
+ ]
77
+ }));
78
+ await socketsRef.current.connect();
79
+ setCurrent({
80
+ tenant
81
+ });
82
+ })();
83
+ }, [
100
84
  tenant,
101
- locale,
102
- getToken,
103
- protocol: ["webiny-ws-v1"]
104
- }));
105
- await socketsRef.current.connect();
106
- setCurrent({
85
+ subscriptionManager,
86
+ getToken
87
+ ]);
88
+ useEffect(()=>{
89
+ if (!socketsRef.current) return;
90
+ const subscription = socketsRef.current.onMessage(async (event)=>{
91
+ await eventPublisher.publish(new WebsocketEvent(event.data));
92
+ });
93
+ return ()=>{
94
+ subscription.off();
95
+ };
96
+ }, [
97
+ current.tenant,
98
+ eventPublisher
99
+ ]);
100
+ const websocketActions = useMemo(()=>createWebsocketsActions({
101
+ manager: socketsRef.current,
102
+ tenant,
103
+ getToken
104
+ }), [
105
+ socketsRef.current,
107
106
  tenant,
108
- locale
109
- });
110
- })();
111
- }, [tenant, locale, subscriptionManager, getToken]);
112
- const websocketActions = useMemo(() => {
113
- return createWebsocketsActions({
114
- manager: socketsRef.current,
115
- tenant,
116
- locale,
117
- getToken
118
- });
119
- }, [socketsRef.current, tenant, locale, getToken]);
120
- const send = useCallback(async (action, data, timeout) => {
121
- return websocketActions.run({
122
- action,
123
- data,
124
- timeout
125
- });
126
- }, [websocketActions]);
127
- const createAction = useCallback(name => {
128
- return createWebsocketsAction(websocketActions, name);
129
- }, [websocketActions]);
130
- const onMessage = useCallback((action, cb) => {
131
- return socketsRef.current.onMessage(async event => {
132
- if (event.data.action !== action) {
133
- return;
134
- }
135
- cb(event.data);
136
- });
137
- }, [socketsRef.current]);
138
- const onError = useCallback(cb => {
139
- return socketsRef.current.onError(data => {
140
- return cb(data);
141
- });
142
- }, [socketsRef.current]);
143
- const onClose = useCallback(cb => {
144
- return socketsRef.current.onClose(data => {
145
- return cb(data);
107
+ getToken
108
+ ]);
109
+ const send = useCallback(async (action, data, timeout)=>websocketActions.run({
110
+ action,
111
+ data,
112
+ timeout
113
+ }), [
114
+ websocketActions
115
+ ]);
116
+ const createAction = useCallback((name)=>createWebsocketsAction(websocketActions, name), [
117
+ websocketActions
118
+ ]);
119
+ const onMessage = useCallback((action, cb)=>socketsRef.current.onMessage(async (event)=>{
120
+ if (event.data.action !== action) return;
121
+ cb(event.data);
122
+ }), [
123
+ socketsRef.current
124
+ ]);
125
+ const onError = useCallback((cb)=>socketsRef.current.onError((data)=>cb(data)), [
126
+ socketsRef.current
127
+ ]);
128
+ const onClose = useCallback((cb)=>socketsRef.current.onClose((data)=>cb(data)), [
129
+ socketsRef.current
130
+ ]);
131
+ if (!socketsRef.current) return props.loader || null;
132
+ const value = {
133
+ send,
134
+ createAction,
135
+ onMessage,
136
+ onError,
137
+ onClose
138
+ };
139
+ return /*#__PURE__*/ react.createElement(WebsocketsContext.Provider, {
140
+ value: value,
141
+ ...props
146
142
  });
147
- }, [socketsRef.current]);
148
- if (!socketsRef.current) {
149
- return props.loader || null;
150
- }
151
- const value = {
152
- send,
153
- createAction,
154
- onMessage,
155
- onError,
156
- onClose
157
- };
158
- return /*#__PURE__*/React.createElement(WebsocketsContext.Provider, Object.assign({
159
- value: value
160
- }, props));
161
143
  };
144
+ export { WebsocketsContext, WebsocketsContextProvider };
162
145
 
163
146
  //# sourceMappingURL=WebsocketsContextProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","useTenancy","useI18N","useSecurity","WebsocketsCloseCode","createWebsocketsAction","createWebsocketsActions","createWebsocketsConnection","createWebsocketsManager","createWebsocketsSubscriptionManager","getUrl","WebsocketsContext","createContext","undefined","WebsocketsContextProvider","props","tenant","getCurrentLocale","getIdToken","locale","socketsRef","current","setCurrent","getToken","subscriptionManager","manager","currentIteration","onClose","event","code","GOING_AWAY","setTimeout","isClosed","console","log","connect","abortController","AbortController","window","addEventListener","signal","triggerOnClose","CloseEvent","reason","abort","token","close","NORMAL","url","error","protocol","websocketActions","send","action","data","timeout","run","createAction","name","onMessage","cb","onError","loader","value","createElement","Provider","Object","assign"],"sources":["WebsocketsContextProvider.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useTenancy } from \"@webiny/app-tenancy\";\nimport { useI18N } from \"@webiny/app-i18n\";\nimport { useSecurity } from \"@webiny/app-security\";\nimport type {\n IncomingGenericData,\n IWebsocketsContext,\n IWebsocketsContextSendCallable,\n IWebsocketsManagerCloseEvent,\n IWebsocketsManagerErrorEvent\n} from \"~/types\";\nimport { WebsocketsCloseCode } from \"~/types\";\nimport {\n createWebsocketsAction,\n createWebsocketsActions,\n createWebsocketsConnection,\n createWebsocketsManager,\n createWebsocketsSubscriptionManager\n} from \"./domain\";\nimport type { IGenericData, IWebsocketsManager } from \"./domain/types\";\nimport { getUrl } from \"./utils/getUrl\";\n\nexport interface IWebsocketsContextProviderProps {\n loader?: React.ReactElement;\n children: React.ReactNode;\n}\n\nexport const WebsocketsContext = React.createContext<IWebsocketsContext>(\n undefined as unknown as IWebsocketsContext\n);\n\ninterface ICurrentData {\n tenant?: string;\n locale?: string;\n}\n\nexport const WebsocketsContextProvider = (props: IWebsocketsContextProviderProps) => {\n const { tenant } = useTenancy();\n const { getCurrentLocale } = useI18N();\n const { getIdToken } = useSecurity();\n const locale = getCurrentLocale(\"default\");\n\n const socketsRef = useRef<IWebsocketsManager>();\n\n const [current, setCurrent] = useState<ICurrentData>({});\n\n const getToken = useCallback(async () => {\n return await getIdToken();\n }, [getIdToken]);\n\n const subscriptionManager = useMemo(() => {\n const manager = createWebsocketsSubscriptionManager();\n\n let currentIteration = 0;\n manager.onClose(event => {\n if (currentIteration > 5 || event.code !== WebsocketsCloseCode.GOING_AWAY) {\n return;\n }\n currentIteration++;\n setTimeout(() => {\n if (!socketsRef.current) {\n return;\n } else if (socketsRef.current.isClosed()) {\n console.log(\"Running auto-reconnect.\");\n\n socketsRef.current.connect();\n }\n }, 1000);\n });\n\n return manager;\n }, []);\n\n /**\n * We need this useEffect to close the websocket connection and remove window focus event in case component is unmounted.\n * This will, probably, happen only during the development phase.\n *\n * If we did not disconnect on component unmount, we would have a memory leak - multiple connections would be opened.\n */\n useEffect(() => {\n /**\n * We want to add a window event listener which will check if the connection is closed, and if its - it will connect again.\n */\n const abortController = new AbortController();\n\n window.addEventListener(\n \"focus\",\n () => {\n if (!socketsRef.current) {\n return;\n } else if (socketsRef.current.isClosed()) {\n console.log(\"Running auto-reconnect on focus.\");\n socketsRef.current.connect();\n }\n },\n { signal: abortController.signal }\n );\n window.addEventListener(\n \"close\",\n () => {\n subscriptionManager.triggerOnClose(\n new CloseEvent(\"windowClose\", {\n code: WebsocketsCloseCode.GOING_AWAY,\n reason: \"Closing Window or Tab.\"\n })\n );\n },\n { signal: abortController.signal }\n );\n\n return () => {\n abortController.abort();\n };\n }, []);\n\n useEffect(() => {\n (async () => {\n const token = await getToken();\n if (!token || !tenant || !locale) {\n return;\n } else if (current.tenant === tenant && current.locale === locale) {\n return;\n } else if (socketsRef.current) {\n await socketsRef.current.close(\n WebsocketsCloseCode.NORMAL,\n \"Changing tenant/locale.\"\n );\n }\n const url = getUrl();\n\n if (!url) {\n console.error(\"Not possible to connect to the websocket without a valid URL.\", {\n tenant,\n locale,\n token\n });\n return;\n }\n\n socketsRef.current = createWebsocketsManager(\n createWebsocketsConnection({\n subscriptionManager,\n url,\n tenant,\n locale,\n getToken,\n protocol: [\"webiny-ws-v1\"]\n })\n );\n await socketsRef.current.connect();\n\n setCurrent({\n tenant,\n locale\n });\n })();\n }, [tenant, locale, subscriptionManager, getToken]);\n\n const websocketActions = useMemo(() => {\n return createWebsocketsActions({\n manager: socketsRef.current!,\n tenant,\n locale,\n getToken\n });\n }, [socketsRef.current, tenant, locale, getToken]);\n\n const send = useCallback<IWebsocketsContextSendCallable>(\n async (action, data, timeout) => {\n return websocketActions.run({\n action,\n data,\n timeout\n });\n },\n [websocketActions]\n );\n\n const createAction = useCallback(\n <T extends IGenericData = IGenericData, R extends IGenericData = IGenericData>(\n name: string\n ) => {\n return createWebsocketsAction<T, R>(websocketActions, name);\n },\n [websocketActions]\n );\n\n const onMessage = useCallback(\n <T extends IncomingGenericData = IncomingGenericData>(\n action: string,\n cb: (data: T) => void\n ) => {\n return socketsRef.current!.onMessage<T>(async event => {\n if (event.data.action !== action) {\n return;\n }\n cb(event.data);\n });\n },\n [socketsRef.current]\n );\n\n const onError = useCallback(\n (cb: (data: IWebsocketsManagerErrorEvent) => void) => {\n return socketsRef.current!.onError(data => {\n return cb(data);\n });\n },\n [socketsRef.current]\n );\n\n const onClose = useCallback(\n (cb: (data: IWebsocketsManagerCloseEvent) => void) => {\n return socketsRef.current!.onClose(data => {\n return cb(data);\n });\n },\n [socketsRef.current]\n );\n\n if (!socketsRef.current) {\n return props.loader || null;\n }\n\n const value: IWebsocketsContext = {\n send,\n createAction,\n onMessage,\n onError,\n onClose\n };\n return <WebsocketsContext.Provider value={value} {...props} />;\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAChF,SAASC,UAAU,QAAQ,qBAAqB;AAChD,SAASC,OAAO,QAAQ,kBAAkB;AAC1C,SAASC,WAAW,QAAQ,sBAAsB;AAQlD,SAASC,mBAAmB;AAC5B,SACIC,sBAAsB,EACtBC,uBAAuB,EACvBC,0BAA0B,EAC1BC,uBAAuB,EACvBC,mCAAmC;AAGvC,SAASC,MAAM;AAOf,OAAO,MAAMC,iBAAiB,gBAAGhB,KAAK,CAACiB,aAAa,CAChDC,SACJ,CAAC;AAOD,OAAO,MAAMC,yBAAyB,GAAIC,KAAsC,IAAK;EACjF,MAAM;IAAEC;EAAO,CAAC,GAAGf,UAAU,CAAC,CAAC;EAC/B,MAAM;IAAEgB;EAAiB,CAAC,GAAGf,OAAO,CAAC,CAAC;EACtC,MAAM;IAAEgB;EAAW,CAAC,GAAGf,WAAW,CAAC,CAAC;EACpC,MAAMgB,MAAM,GAAGF,gBAAgB,CAAC,SAAS,CAAC;EAE1C,MAAMG,UAAU,GAAGrB,MAAM,CAAqB,CAAC;EAE/C,MAAM,CAACsB,OAAO,EAAEC,UAAU,CAAC,GAAGtB,QAAQ,CAAe,CAAC,CAAC,CAAC;EAExD,MAAMuB,QAAQ,GAAG3B,WAAW,CAAC,YAAY;IACrC,OAAO,MAAMsB,UAAU,CAAC,CAAC;EAC7B,CAAC,EAAE,CAACA,UAAU,CAAC,CAAC;EAEhB,MAAMM,mBAAmB,GAAG1B,OAAO,CAAC,MAAM;IACtC,MAAM2B,OAAO,GAAGhB,mCAAmC,CAAC,CAAC;IAErD,IAAIiB,gBAAgB,GAAG,CAAC;IACxBD,OAAO,CAACE,OAAO,CAACC,KAAK,IAAI;MACrB,IAAIF,gBAAgB,GAAG,CAAC,IAAIE,KAAK,CAACC,IAAI,KAAKzB,mBAAmB,CAAC0B,UAAU,EAAE;QACvE;MACJ;MACAJ,gBAAgB,EAAE;MAClBK,UAAU,CAAC,MAAM;QACb,IAAI,CAACX,UAAU,CAACC,OAAO,EAAE;UACrB;QACJ,CAAC,MAAM,IAAID,UAAU,CAACC,OAAO,CAACW,QAAQ,CAAC,CAAC,EAAE;UACtCC,OAAO,CAACC,GAAG,CAAC,yBAAyB,CAAC;UAEtCd,UAAU,CAACC,OAAO,CAACc,OAAO,CAAC,CAAC;QAChC;MACJ,CAAC,EAAE,IAAI,CAAC;IACZ,CAAC,CAAC;IAEF,OAAOV,OAAO;EAClB,CAAC,EAAE,EAAE,CAAC;;EAEN;AACJ;AACA;AACA;AACA;AACA;EACI5B,SAAS,CAAC,MAAM;IACZ;AACR;AACA;IACQ,MAAMuC,eAAe,GAAG,IAAIC,eAAe,CAAC,CAAC;IAE7CC,MAAM,CAACC,gBAAgB,CACnB,OAAO,EACP,MAAM;MACF,IAAI,CAACnB,UAAU,CAACC,OAAO,EAAE;QACrB;MACJ,CAAC,MAAM,IAAID,UAAU,CAACC,OAAO,CAACW,QAAQ,CAAC,CAAC,EAAE;QACtCC,OAAO,CAACC,GAAG,CAAC,kCAAkC,CAAC;QAC/Cd,UAAU,CAACC,OAAO,CAACc,OAAO,CAAC,CAAC;MAChC;IACJ,CAAC,EACD;MAAEK,MAAM,EAAEJ,eAAe,CAACI;IAAO,CACrC,CAAC;IACDF,MAAM,CAACC,gBAAgB,CACnB,OAAO,EACP,MAAM;MACFf,mBAAmB,CAACiB,cAAc,CAC9B,IAAIC,UAAU,CAAC,aAAa,EAAE;QAC1Bb,IAAI,EAAEzB,mBAAmB,CAAC0B,UAAU;QACpCa,MAAM,EAAE;MACZ,CAAC,CACL,CAAC;IACL,CAAC,EACD;MAAEH,MAAM,EAAEJ,eAAe,CAACI;IAAO,CACrC,CAAC;IAED,OAAO,MAAM;MACTJ,eAAe,CAACQ,KAAK,CAAC,CAAC;IAC3B,CAAC;EACL,CAAC,EAAE,EAAE,CAAC;EAEN/C,SAAS,CAAC,MAAM;IACZ,CAAC,YAAY;MACT,MAAMgD,KAAK,GAAG,MAAMtB,QAAQ,CAAC,CAAC;MAC9B,IAAI,CAACsB,KAAK,IAAI,CAAC7B,MAAM,IAAI,CAACG,MAAM,EAAE;QAC9B;MACJ,CAAC,MAAM,IAAIE,OAAO,CAACL,MAAM,KAAKA,MAAM,IAAIK,OAAO,CAACF,MAAM,KAAKA,MAAM,EAAE;QAC/D;MACJ,CAAC,MAAM,IAAIC,UAAU,CAACC,OAAO,EAAE;QAC3B,MAAMD,UAAU,CAACC,OAAO,CAACyB,KAAK,CAC1B1C,mBAAmB,CAAC2C,MAAM,EAC1B,yBACJ,CAAC;MACL;MACA,MAAMC,GAAG,GAAGtC,MAAM,CAAC,CAAC;MAEpB,IAAI,CAACsC,GAAG,EAAE;QACNf,OAAO,CAACgB,KAAK,CAAC,+DAA+D,EAAE;UAC3EjC,MAAM;UACNG,MAAM;UACN0B;QACJ,CAAC,CAAC;QACF;MACJ;MAEAzB,UAAU,CAACC,OAAO,GAAGb,uBAAuB,CACxCD,0BAA0B,CAAC;QACvBiB,mBAAmB;QACnBwB,GAAG;QACHhC,MAAM;QACNG,MAAM;QACNI,QAAQ;QACR2B,QAAQ,EAAE,CAAC,cAAc;MAC7B,CAAC,CACL,CAAC;MACD,MAAM9B,UAAU,CAACC,OAAO,CAACc,OAAO,CAAC,CAAC;MAElCb,UAAU,CAAC;QACPN,MAAM;QACNG;MACJ,CAAC,CAAC;IACN,CAAC,EAAE,CAAC;EACR,CAAC,EAAE,CAACH,MAAM,EAAEG,MAAM,EAAEK,mBAAmB,EAAED,QAAQ,CAAC,CAAC;EAEnD,MAAM4B,gBAAgB,GAAGrD,OAAO,CAAC,MAAM;IACnC,OAAOQ,uBAAuB,CAAC;MAC3BmB,OAAO,EAAEL,UAAU,CAACC,OAAQ;MAC5BL,MAAM;MACNG,MAAM;MACNI;IACJ,CAAC,CAAC;EACN,CAAC,EAAE,CAACH,UAAU,CAACC,OAAO,EAAEL,MAAM,EAAEG,MAAM,EAAEI,QAAQ,CAAC,CAAC;EAElD,MAAM6B,IAAI,GAAGxD,WAAW,CACpB,OAAOyD,MAAM,EAAEC,IAAI,EAAEC,OAAO,KAAK;IAC7B,OAAOJ,gBAAgB,CAACK,GAAG,CAAC;MACxBH,MAAM;MACNC,IAAI;MACJC;IACJ,CAAC,CAAC;EACN,CAAC,EACD,CAACJ,gBAAgB,CACrB,CAAC;EAED,MAAMM,YAAY,GAAG7D,WAAW,CAExB8D,IAAY,IACX;IACD,OAAOrD,sBAAsB,CAAO8C,gBAAgB,EAAEO,IAAI,CAAC;EAC/D,CAAC,EACD,CAACP,gBAAgB,CACrB,CAAC;EAED,MAAMQ,SAAS,GAAG/D,WAAW,CACzB,CACIyD,MAAc,EACdO,EAAqB,KACpB;IACD,OAAOxC,UAAU,CAACC,OAAO,CAAEsC,SAAS,CAAI,MAAM/B,KAAK,IAAI;MACnD,IAAIA,KAAK,CAAC0B,IAAI,CAACD,MAAM,KAAKA,MAAM,EAAE;QAC9B;MACJ;MACAO,EAAE,CAAChC,KAAK,CAAC0B,IAAI,CAAC;IAClB,CAAC,CAAC;EACN,CAAC,EACD,CAAClC,UAAU,CAACC,OAAO,CACvB,CAAC;EAED,MAAMwC,OAAO,GAAGjE,WAAW,CACtBgE,EAAgD,IAAK;IAClD,OAAOxC,UAAU,CAACC,OAAO,CAAEwC,OAAO,CAACP,IAAI,IAAI;MACvC,OAAOM,EAAE,CAACN,IAAI,CAAC;IACnB,CAAC,CAAC;EACN,CAAC,EACD,CAAClC,UAAU,CAACC,OAAO,CACvB,CAAC;EAED,MAAMM,OAAO,GAAG/B,WAAW,CACtBgE,EAAgD,IAAK;IAClD,OAAOxC,UAAU,CAACC,OAAO,CAAEM,OAAO,CAAC2B,IAAI,IAAI;MACvC,OAAOM,EAAE,CAACN,IAAI,CAAC;IACnB,CAAC,CAAC;EACN,CAAC,EACD,CAAClC,UAAU,CAACC,OAAO,CACvB,CAAC;EAED,IAAI,CAACD,UAAU,CAACC,OAAO,EAAE;IACrB,OAAON,KAAK,CAAC+C,MAAM,IAAI,IAAI;EAC/B;EAEA,MAAMC,KAAyB,GAAG;IAC9BX,IAAI;IACJK,YAAY;IACZE,SAAS;IACTE,OAAO;IACPlC;EACJ,CAAC;EACD,oBAAOhC,KAAA,CAAAqE,aAAA,CAACrD,iBAAiB,CAACsD,QAAQ,EAAAC,MAAA,CAAAC,MAAA;IAACJ,KAAK,EAAEA;EAAM,GAAKhD,KAAK,CAAG,CAAC;AAClE,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"WebsocketsContextProvider.js","sources":["../src/WebsocketsContextProvider.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useFeature, useTenantContext } from \"@webiny/app-admin\";\nimport { AuthenticationContextFeature } from \"@webiny/app-admin/features/security/AuthenticationContext/feature.js\";\nimport { EventPublisherFeature } from \"@webiny/app/features/eventPublisher/feature.js\";\nimport { WebsocketEvent } from \"./events/WebsocketEvent.js\";\nimport type {\n IncomingGenericData,\n IWebsocketsContext,\n IWebsocketsContextSendCallable,\n IWebsocketsManagerCloseEvent,\n IWebsocketsManagerErrorEvent\n} from \"~/types.js\";\nimport { WebsocketsCloseCode } from \"~/types.js\";\nimport {\n createWebsocketsAction,\n createWebsocketsActions,\n createWebsocketsConnection,\n createWebsocketsManager,\n createWebsocketsSubscriptionManager\n} from \"./domain/index.js\";\nimport type { IGenericData, IWebsocketsManager } from \"./domain/types.js\";\nimport { getUrl } from \"./utils/getUrl.js\";\n\nexport interface IWebsocketsContextProviderProps {\n loader?: React.ReactElement;\n children: React.ReactNode;\n}\n\nexport const WebsocketsContext = React.createContext<IWebsocketsContext>(\n undefined as unknown as IWebsocketsContext\n);\n\ninterface ICurrentData {\n tenant?: string;\n}\n\nexport const WebsocketsContextProvider = (props: IWebsocketsContextProviderProps) => {\n const { tenant } = useTenantContext();\n const { authenticationContext } = useFeature(AuthenticationContextFeature);\n const { eventPublisher } = useFeature(EventPublisherFeature);\n\n const socketsRef = useRef<IWebsocketsManager | null>(null);\n\n const [current, setCurrent] = useState<ICurrentData>({});\n\n const getToken = useCallback(async () => {\n return await authenticationContext.getIdToken();\n }, [authenticationContext]);\n\n const subscriptionManager = useMemo(() => {\n const manager = createWebsocketsSubscriptionManager();\n\n let currentIteration = 0;\n manager.onClose(event => {\n if (currentIteration > 5 || event.code !== WebsocketsCloseCode.GOING_AWAY) {\n return;\n }\n currentIteration++;\n setTimeout(() => {\n if (!socketsRef.current) {\n return;\n } else if (socketsRef.current.isClosed()) {\n console.log(\"Running auto-reconnect.\");\n\n socketsRef.current.connect();\n }\n }, 1000);\n });\n\n return manager;\n }, []);\n\n /**\n * We need this useEffect to close the websocket connection and remove window focus event in case component is unmounted.\n * This will, probably, happen only during the development phase.\n *\n * If we did not disconnect on component unmount, we would have a memory leak - multiple connections would be opened.\n */\n useEffect(() => {\n /**\n * We want to add a window event listener which will check if the connection is closed, and if its - it will connect again.\n */\n const abortController = new AbortController();\n\n window.addEventListener(\n \"focus\",\n () => {\n if (!socketsRef.current) {\n return;\n } else if (socketsRef.current.isClosed()) {\n console.log(\"Running auto-reconnect on focus.\");\n socketsRef.current.connect();\n }\n },\n { signal: abortController.signal }\n );\n window.addEventListener(\n \"close\",\n () => {\n subscriptionManager.triggerOnClose(\n new CloseEvent(\"windowClose\", {\n code: WebsocketsCloseCode.GOING_AWAY,\n reason: \"Closing Window or Tab.\"\n })\n );\n },\n { signal: abortController.signal }\n );\n\n return () => {\n abortController.abort();\n };\n }, []);\n\n useEffect(() => {\n (async () => {\n const token = await getToken();\n if (!token || !tenant) {\n return;\n } else if (current.tenant === tenant) {\n return;\n } else if (socketsRef.current) {\n await socketsRef.current.close(WebsocketsCloseCode.NORMAL, \"Changing tenant.\");\n }\n const url = getUrl();\n\n if (!url) {\n console.error(\"Not possible to connect to the websocket without a valid URL.\", {\n tenant,\n token\n });\n return;\n }\n\n socketsRef.current = createWebsocketsManager(\n createWebsocketsConnection({\n subscriptionManager,\n url,\n tenant,\n getToken,\n protocol: [\"webiny-ws-v1\"]\n })\n );\n await socketsRef.current.connect();\n\n setCurrent({ tenant });\n })();\n }, [tenant, subscriptionManager, getToken]);\n\n /**\n * Bridge: subscribe once to ALL incoming websocket messages and re-publish each one through\n * the EventPublisher as a `WebsocketEvent`. Feature code registers `WebsocketEventHandler`\n * handlers instead of subscribing to the websocket service directly.\n */\n useEffect(() => {\n if (!socketsRef.current) {\n return;\n }\n const subscription = socketsRef.current.onMessage<IncomingGenericData>(async event => {\n await eventPublisher.publish(new WebsocketEvent(event.data));\n });\n return () => {\n subscription.off();\n };\n }, [current.tenant, eventPublisher]);\n\n const websocketActions = useMemo(() => {\n return createWebsocketsActions({\n manager: socketsRef.current!,\n tenant,\n getToken\n });\n }, [socketsRef.current, tenant, getToken]);\n\n const send = useCallback<IWebsocketsContextSendCallable>(\n async (action, data, timeout) => {\n return websocketActions.run({\n action,\n data,\n timeout\n });\n },\n [websocketActions]\n );\n\n const createAction = useCallback(\n <T extends IGenericData = IGenericData, R extends IGenericData = IGenericData>(\n name: string\n ) => {\n return createWebsocketsAction<T, R>(websocketActions, name);\n },\n [websocketActions]\n );\n\n const onMessage = useCallback(\n <T extends IncomingGenericData = IncomingGenericData>(\n action: string,\n cb: (data: T) => void\n ) => {\n return socketsRef.current!.onMessage<T>(async event => {\n if (event.data.action !== action) {\n return;\n }\n cb(event.data);\n });\n },\n [socketsRef.current]\n );\n\n const onError = useCallback(\n (cb: (data: IWebsocketsManagerErrorEvent) => void) => {\n return socketsRef.current!.onError(data => {\n return cb(data);\n });\n },\n [socketsRef.current]\n );\n\n const onClose = useCallback(\n (cb: (data: IWebsocketsManagerCloseEvent) => void) => {\n return socketsRef.current!.onClose(data => {\n return cb(data);\n });\n },\n [socketsRef.current]\n );\n\n if (!socketsRef.current) {\n return props.loader || null;\n }\n\n const value: IWebsocketsContext = {\n send,\n createAction,\n onMessage,\n onError,\n onClose\n };\n return <WebsocketsContext.Provider value={value} {...props} />;\n};\n"],"names":["WebsocketsContext","React","undefined","WebsocketsContextProvider","props","tenant","useTenantContext","authenticationContext","useFeature","AuthenticationContextFeature","eventPublisher","EventPublisherFeature","socketsRef","useRef","current","setCurrent","useState","getToken","useCallback","subscriptionManager","useMemo","manager","createWebsocketsSubscriptionManager","currentIteration","event","WebsocketsCloseCode","setTimeout","console","useEffect","abortController","AbortController","window","CloseEvent","token","url","getUrl","createWebsocketsManager","createWebsocketsConnection","subscription","WebsocketEvent","websocketActions","createWebsocketsActions","send","action","data","timeout","createAction","name","createWebsocketsAction","onMessage","cb","onError","onClose","value"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { IGenericData, IWebsocketsAction, IWebsocketsActions, IWebsocketsActionsTriggerParams } from "./types";
1
+ import type { IGenericData, IWebsocketsAction, IWebsocketsActions, IWebsocketsActionsTriggerParams } from "./types.js";
2
2
  export declare class WebsocketsAction<T extends IGenericData = IGenericData, R extends IGenericData = IGenericData> implements IWebsocketsAction<T, R> {
3
3
  private readonly actions;
4
4
  private readonly name;
@@ -1,28 +1,21 @@
1
- export class WebsocketsAction {
2
- constructor(actions, name) {
3
- this.name = name;
4
- this.actions = actions;
5
- }
6
- async trigger(params) {
7
- const {
8
- data,
9
- onResponse,
10
- timeout = 10000
11
- } = params || {};
12
- const promise = this.actions.run({
13
- action: this.name,
14
- data,
15
- timeout: onResponse && timeout > 0 ? timeout : undefined
16
- });
17
- if (!onResponse) {
18
- return null;
1
+ class WebsocketsAction {
2
+ constructor(actions, name){
3
+ this.name = name;
4
+ this.actions = actions;
5
+ }
6
+ async trigger(params) {
7
+ const { data, onResponse, timeout = 10000 } = params || {};
8
+ const promise = this.actions.run({
9
+ action: this.name,
10
+ data,
11
+ timeout: onResponse && timeout > 0 ? timeout : void 0
12
+ });
13
+ if (!onResponse) return null;
14
+ const result = await promise;
15
+ return onResponse(result);
19
16
  }
20
- const result = await promise;
21
- return onResponse(result);
22
- }
23
17
  }
24
- export const createWebsocketsAction = (actions, name) => {
25
- return new WebsocketsAction(actions, name);
26
- };
18
+ const createWebsocketsAction = (actions, name)=>new WebsocketsAction(actions, name);
19
+ export { WebsocketsAction, createWebsocketsAction };
27
20
 
28
21
  //# sourceMappingURL=WebsocketsAction.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["WebsocketsAction","constructor","actions","name","trigger","params","data","onResponse","timeout","promise","run","action","undefined","result","createWebsocketsAction"],"sources":["WebsocketsAction.ts"],"sourcesContent":["import type {\n IGenericData,\n IWebsocketsAction,\n IWebsocketsActions,\n IWebsocketsActionsTriggerParams\n} from \"./types\";\n\nexport class WebsocketsAction<\n T extends IGenericData = IGenericData,\n R extends IGenericData = IGenericData\n> implements IWebsocketsAction<T, R>\n{\n private readonly actions: IWebsocketsActions;\n private readonly name: string;\n\n public constructor(actions: IWebsocketsActions, name: string) {\n this.name = name;\n this.actions = actions;\n }\n\n public async trigger(params?: IWebsocketsActionsTriggerParams<T, R>): Promise<R | null> {\n const { data, onResponse, timeout = 10000 } = params || {};\n const promise = this.actions.run<T, R>({\n action: this.name,\n data,\n timeout: onResponse && timeout > 0 ? timeout : undefined\n });\n if (!onResponse) {\n return null;\n }\n const result = await promise;\n\n return onResponse(result);\n }\n}\n\nexport const createWebsocketsAction = <\n T extends IGenericData = IGenericData,\n R extends IGenericData = IGenericData\n>(\n actions: IWebsocketsActions,\n name: string\n): IWebsocketsAction<T, R> => {\n return new WebsocketsAction<T, R>(actions, name);\n};\n"],"mappings":"AAOA,OAAO,MAAMA,gBAAgB,CAI7B;EAIWC,WAAWA,CAACC,OAA2B,EAAEC,IAAY,EAAE;IAC1D,IAAI,CAACA,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACD,OAAO,GAAGA,OAAO;EAC1B;EAEA,MAAaE,OAAOA,CAACC,MAA8C,EAAqB;IACpF,MAAM;MAAEC,IAAI;MAAEC,UAAU;MAAEC,OAAO,GAAG;IAAM,CAAC,GAAGH,MAAM,IAAI,CAAC,CAAC;IAC1D,MAAMI,OAAO,GAAG,IAAI,CAACP,OAAO,CAACQ,GAAG,CAAO;MACnCC,MAAM,EAAE,IAAI,CAACR,IAAI;MACjBG,IAAI;MACJE,OAAO,EAAED,UAAU,IAAIC,OAAO,GAAG,CAAC,GAAGA,OAAO,GAAGI;IACnD,CAAC,CAAC;IACF,IAAI,CAACL,UAAU,EAAE;MACb,OAAO,IAAI;IACf;IACA,MAAMM,MAAM,GAAG,MAAMJ,OAAO;IAE5B,OAAOF,UAAU,CAACM,MAAM,CAAC;EAC7B;AACJ;AAEA,OAAO,MAAMC,sBAAsB,GAAGA,CAIlCZ,OAA2B,EAC3BC,IAAY,KACc;EAC1B,OAAO,IAAIH,gBAAgB,CAAOE,OAAO,EAAEC,IAAI,CAAC;AACpD,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"domain/WebsocketsAction.js","sources":["../../src/domain/WebsocketsAction.ts"],"sourcesContent":["import type {\n IGenericData,\n IWebsocketsAction,\n IWebsocketsActions,\n IWebsocketsActionsTriggerParams\n} from \"./types.js\";\n\nexport class WebsocketsAction<\n T extends IGenericData = IGenericData,\n R extends IGenericData = IGenericData\n> implements IWebsocketsAction<T, R> {\n private readonly actions: IWebsocketsActions;\n private readonly name: string;\n\n public constructor(actions: IWebsocketsActions, name: string) {\n this.name = name;\n this.actions = actions;\n }\n\n public async trigger(params?: IWebsocketsActionsTriggerParams<T, R>): Promise<R | null> {\n const { data, onResponse, timeout = 10000 } = params || {};\n const promise = this.actions.run<T, R>({\n action: this.name,\n data,\n timeout: onResponse && timeout > 0 ? timeout : undefined\n });\n if (!onResponse) {\n return null;\n }\n const result = await promise;\n\n return onResponse(result);\n }\n}\n\nexport const createWebsocketsAction = <\n T extends IGenericData = IGenericData,\n R extends IGenericData = IGenericData\n>(\n actions: IWebsocketsActions,\n name: string\n): IWebsocketsAction<T, R> => {\n return new WebsocketsAction<T, R>(actions, name);\n};\n"],"names":["WebsocketsAction","actions","name","params","data","onResponse","timeout","promise","undefined","result","createWebsocketsAction"],"mappings":"AAOO,MAAMA;IAOT,YAAmBC,OAA2B,EAAEC,IAAY,CAAE;QAC1D,IAAI,CAAC,IAAI,GAAGA;QACZ,IAAI,CAAC,OAAO,GAAGD;IACnB;IAEA,MAAa,QAAQE,MAA8C,EAAqB;QACpF,MAAM,EAAEC,IAAI,EAAEC,UAAU,EAAEC,UAAU,KAAK,EAAE,GAAGH,UAAU,CAAC;QACzD,MAAMI,UAAU,IAAI,CAAC,OAAO,CAAC,GAAG,CAAO;YACnC,QAAQ,IAAI,CAAC,IAAI;YACjBH;YACA,SAASC,cAAcC,UAAU,IAAIA,UAAUE;QACnD;QACA,IAAI,CAACH,YACD,OAAO;QAEX,MAAMI,SAAS,MAAMF;QAErB,OAAOF,WAAWI;IACtB;AACJ;AAEO,MAAMC,yBAAyB,CAIlCT,SACAC,OAEO,IAAIF,iBAAuBC,SAASC"}
@@ -1,15 +1,13 @@
1
- import type { IGenericData, IWebsocketsActions, IWebsocketsActionsRunParams, IWebsocketsManager } from "./types";
1
+ import type { IGenericData, IWebsocketsActions, IWebsocketsActionsRunParams, IWebsocketsManager } from "./types.js";
2
2
  export interface IWebsocketActionsParams {
3
3
  manager: IWebsocketsManager;
4
4
  tenant: string | null;
5
- locale: string | null;
6
5
  getToken: () => Promise<string | undefined>;
7
6
  }
8
7
  export declare class WebsocketsActions implements IWebsocketsActions {
9
8
  readonly manager: IWebsocketsManager;
10
9
  private readonly getToken;
11
10
  private readonly tenant;
12
- private readonly locale;
13
11
  constructor(params: IWebsocketActionsParams);
14
12
  run<T extends IGenericData = IGenericData, R extends IGenericData = IGenericData>(params: IWebsocketsActionsRunParams<T>): Promise<R | null>;
15
13
  }
@@ -1,84 +1,58 @@
1
- export class WebsocketsActions {
2
- constructor(params) {
3
- this.manager = params.manager;
4
- this.tenant = params.tenant;
5
- this.locale = params.locale;
6
- this.getToken = params.getToken;
7
- }
8
- async run(params) {
9
- const {
10
- action,
11
- timeout,
12
- data
13
- } = params;
14
- const token = await this.getToken();
15
- if (!token) {
16
- console.error("Token is not set - cannot send a websocket message.");
17
- return null;
18
- } else if (!this.tenant) {
19
- console.error("Tenant is not set - cannot send a websocket message.");
20
- return null;
21
- } else if (!this.locale) {
22
- console.error("Locale is not set - cannot send a websocket message.");
23
- return null;
1
+ class WebsocketsActions {
2
+ constructor(params){
3
+ this.manager = params.manager;
4
+ this.tenant = params.tenant;
5
+ this.getToken = params.getToken;
24
6
  }
25
- /**
26
- * If no timeout was sent, we will just send the message and return null.
27
- * No waiting for the response.
28
- */
29
- if (!timeout || timeout < 0) {
30
- this.manager.send({
31
- /**
32
- * It is ok to cast as we are checking the values a few lines above.
33
- */
34
- token,
35
- tenant: this.tenant,
36
- locale: this.locale,
37
- action,
38
- data: data || {}
39
- });
40
- return null;
41
- }
42
- /**
43
- * In case of a timeout, we will send the message and wait for the response.
44
- */
45
- return await new Promise((resolve, reject) => {
46
- let promiseTimeout = null;
47
- const subscription = this.manager.onMessage(async event => {
48
- if (event.data.messageId !== subscription.id) {
49
- return;
7
+ async run(params) {
8
+ const { action, timeout, data } = params;
9
+ const token = await this.getToken();
10
+ if (token) {
11
+ if (!this.tenant) {
12
+ console.error("Tenant is not set - cannot send a websocket message.");
13
+ return null;
14
+ }
15
+ } else {
16
+ console.error("Token is not set - cannot send a websocket message.");
17
+ return null;
50
18
  }
51
- resolve(event.data);
52
- subscription.off();
53
- if (!promiseTimeout) {
54
- return;
19
+ if (!timeout || timeout < 0) {
20
+ this.manager.send({
21
+ token,
22
+ tenant: this.tenant,
23
+ action,
24
+ data: data || {}
25
+ });
26
+ return null;
55
27
  }
56
- clearTimeout(promiseTimeout);
57
- });
58
- promiseTimeout = setTimeout(() => {
59
- const message = `Websocket action "${action}" timeout.`;
60
- subscription.off();
61
- reject(new Error(message));
62
- }, timeout);
63
- this.manager.send({
64
- /**
65
- * It is ok to cast as we are checking the values a few lines above.
66
- */
67
- token,
68
- tenant: this.tenant,
69
- locale: this.locale,
70
- messageId: subscription.id,
71
- action,
72
- data: data || {}
73
- });
74
- }).catch(ex => {
75
- console.error("Error while sending websocket message.", ex);
76
- return null;
77
- });
78
- }
28
+ return await new Promise((resolve, reject)=>{
29
+ let promiseTimeout = null;
30
+ const subscription = this.manager.onMessage(async (event)=>{
31
+ if (event.data.messageId !== subscription.id) return;
32
+ resolve(event.data);
33
+ subscription.off();
34
+ if (!promiseTimeout) return;
35
+ clearTimeout(promiseTimeout);
36
+ });
37
+ promiseTimeout = setTimeout(()=>{
38
+ const message = `Websocket action "${action}" timeout.`;
39
+ subscription.off();
40
+ reject(new Error(message));
41
+ }, timeout);
42
+ this.manager.send({
43
+ token,
44
+ tenant: this.tenant,
45
+ messageId: subscription.id,
46
+ action,
47
+ data: data || {}
48
+ });
49
+ }).catch((ex)=>{
50
+ console.error("Error while sending websocket message.", ex);
51
+ return null;
52
+ });
53
+ }
79
54
  }
80
- export const createWebsocketsActions = params => {
81
- return new WebsocketsActions(params);
82
- };
55
+ const createWebsocketsActions = (params)=>new WebsocketsActions(params);
56
+ export { WebsocketsActions, createWebsocketsActions };
83
57
 
84
58
  //# sourceMappingURL=WebsocketsActions.js.map