@adcops/autocore-react 3.0.40 → 3.3.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.
- package/additional-docs/AutoCoreTagContext.md +441 -0
- package/additional-docs/react_performance_notes.md +94 -0
- package/dist/assets/BlocklyLogo.d.ts +1 -0
- package/dist/assets/BlocklyLogo.d.ts.map +1 -0
- package/dist/assets/Distance.d.ts +1 -0
- package/dist/assets/Distance.d.ts.map +1 -0
- package/dist/assets/JogLong.d.ts +1 -0
- package/dist/assets/JogLong.d.ts.map +1 -0
- package/dist/assets/JogMedium.d.ts +1 -0
- package/dist/assets/JogMedium.d.ts.map +1 -0
- package/dist/assets/JogShort.d.ts +1 -0
- package/dist/assets/JogShort.d.ts.map +1 -0
- package/dist/assets/PythonLogo.d.ts +1 -0
- package/dist/assets/PythonLogo.d.ts.map +1 -0
- package/dist/assets/Rotation3D.d.ts +1 -0
- package/dist/assets/Rotation3D.d.ts.map +1 -0
- package/dist/assets/RotationCcw.d.ts +1 -0
- package/dist/assets/RotationCcw.d.ts.map +1 -0
- package/dist/assets/RotationCcwA.d.ts +1 -0
- package/dist/assets/RotationCcwA.d.ts.map +1 -0
- package/dist/assets/RotationCcwB.d.ts +1 -0
- package/dist/assets/RotationCcwB.d.ts.map +1 -0
- package/dist/assets/RotationCcwC.d.ts +1 -0
- package/dist/assets/RotationCcwC.d.ts.map +1 -0
- package/dist/assets/RotationCw.d.ts +1 -0
- package/dist/assets/RotationCw.d.ts.map +1 -0
- package/dist/assets/RotationCwA.d.ts +1 -0
- package/dist/assets/RotationCwA.d.ts.map +1 -0
- package/dist/assets/RotationCwB.d.ts +1 -0
- package/dist/assets/RotationCwB.d.ts.map +1 -0
- package/dist/assets/RotationCwC.d.ts +1 -0
- package/dist/assets/RotationCwC.d.ts.map +1 -0
- package/dist/assets/Run.d.ts +1 -0
- package/dist/assets/Run.d.ts.map +1 -0
- package/dist/assets/Speed.d.ts +1 -0
- package/dist/assets/Speed.d.ts.map +1 -0
- package/dist/assets/SpeedFast.d.ts +1 -0
- package/dist/assets/SpeedFast.d.ts.map +1 -0
- package/dist/assets/SpeedMedium.d.ts +1 -0
- package/dist/assets/SpeedMedium.d.ts.map +1 -0
- package/dist/assets/SpeedNone.d.ts +1 -0
- package/dist/assets/SpeedNone.d.ts.map +1 -0
- package/dist/assets/SpeedSlow.d.ts +1 -0
- package/dist/assets/SpeedSlow.d.ts.map +1 -0
- package/dist/assets/Walk.d.ts +1 -0
- package/dist/assets/Walk.d.ts.map +1 -0
- package/dist/assets/index.d.ts +1 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/components/AutoCoreDevPanel.d.ts +144 -0
- package/dist/components/AutoCoreDevPanel.d.ts.map +1 -0
- package/dist/components/AutoCoreDevPanel.js +1 -0
- package/dist/components/BlocklyEditor.d.ts +1 -0
- package/dist/components/BlocklyEditor.d.ts.map +1 -0
- package/dist/components/BlocklyEditor.js +1 -1
- package/dist/components/CodeEditor.d.ts +2 -1
- package/dist/components/CodeEditor.d.ts.map +1 -0
- package/dist/components/CodeEditor.js +1 -1
- package/dist/components/FileList.d.ts +1 -0
- package/dist/components/FileList.d.ts.map +1 -0
- package/dist/components/FileList.js +1 -1
- package/dist/components/FileSelect.d.ts +1 -0
- package/dist/components/FileSelect.d.ts.map +1 -0
- package/dist/components/FileSelect.js +1 -1
- package/dist/components/FitText.d.ts +1 -0
- package/dist/components/FitText.d.ts.map +1 -0
- package/dist/components/FitText.js +1 -1
- package/dist/components/Indicator.d.ts +2 -1
- package/dist/components/Indicator.d.ts.map +1 -0
- package/dist/components/Indicator.js +1 -1
- package/dist/components/IndicatorButton.d.ts +2 -1
- package/dist/components/IndicatorButton.d.ts.map +1 -0
- package/dist/components/IndicatorButton.js +1 -1
- package/dist/components/IndicatorRect.d.ts +2 -1
- package/dist/components/IndicatorRect.d.ts.map +1 -0
- package/dist/components/JogPanel.d.ts +1 -0
- package/dist/components/JogPanel.d.ts.map +1 -0
- package/dist/components/Lamp.d.ts +2 -1
- package/dist/components/Lamp.d.ts.map +1 -0
- package/dist/components/Lamp.js +1 -1
- package/dist/components/Osk.d.ts +1 -0
- package/dist/components/Osk.d.ts.map +1 -0
- package/dist/components/Osk.js +1 -1
- package/dist/components/OskDialog.d.ts +1 -0
- package/dist/components/OskDialog.d.ts.map +1 -0
- package/dist/components/ProgressBarWithValue.d.ts +1 -0
- package/dist/components/ProgressBarWithValue.d.ts.map +1 -0
- package/dist/components/ProgressBarWithValue.js +1 -1
- package/dist/components/TextInput.d.ts +62 -103
- package/dist/components/TextInput.d.ts.map +1 -0
- package/dist/components/TextInput.js +1 -1
- package/dist/components/ToggleGroup.d.ts +2 -1
- package/dist/components/ToggleGroup.d.ts.map +1 -0
- package/dist/components/ToggleGroup.js +1 -1
- package/dist/components/ValueDisplay.d.ts +3 -2
- package/dist/components/ValueDisplay.d.ts.map +1 -0
- package/dist/components/ValueDisplay.js +1 -1
- package/dist/components/ValueIndicator.d.ts +2 -1
- package/dist/components/ValueIndicator.d.ts.map +1 -0
- package/dist/components/ValueIndicator.js +1 -1
- package/dist/components/ValueInput.d.ts +2 -1
- package/dist/components/ValueInput.d.ts.map +1 -0
- package/dist/components/ValueInput.js +1 -1
- package/dist/core/ActionMode.d.ts +1 -0
- package/dist/core/ActionMode.d.ts.map +1 -0
- package/dist/core/AutoCoreTagContext.d.ts +98 -0
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -0
- package/dist/core/AutoCoreTagContext.js +1 -0
- package/dist/core/AutoCoreTagTypes.d.ts +283 -0
- package/dist/core/AutoCoreTagTypes.d.ts.map +1 -0
- package/dist/core/AutoCoreTagTypes.js +1 -0
- package/dist/core/CoreStreamTypes.d.ts +345 -0
- package/dist/core/CoreStreamTypes.d.ts.map +1 -0
- package/dist/core/CoreStreamTypes.js +1 -0
- package/dist/core/EventEmitterContext.d.ts +113 -202
- package/dist/core/EventEmitterContext.d.ts.map +1 -0
- package/dist/core/EventEmitterContext.js +1 -1
- package/dist/core/IndicatorButtonState.d.ts +1 -0
- package/dist/core/IndicatorButtonState.d.ts.map +1 -0
- package/dist/core/IndicatorColor.d.ts +1 -0
- package/dist/core/IndicatorColor.d.ts.map +1 -0
- package/dist/core/MaskPatterns.d.ts +1 -0
- package/dist/core/MaskPatterns.d.ts.map +1 -0
- package/dist/core/NumerableTypes.d.ts +1 -0
- package/dist/core/NumerableTypes.d.ts.map +1 -0
- package/dist/core/NumerableTypes.js +1 -1
- package/dist/core/PositionContext.d.ts +1 -1
- package/dist/core/PositionContext.d.ts.map +1 -0
- package/dist/core/UniqueId.d.ts +1 -0
- package/dist/core/UniqueId.d.ts.map +1 -0
- package/dist/core/ValueSimulator.d.ts +2 -1
- package/dist/core/ValueSimulator.d.ts.map +1 -0
- package/dist/core/ValueSimulator.js +1 -1
- package/dist/core/hoc.d.ts +1 -0
- package/dist/core/hoc.d.ts.map +1 -0
- package/dist/core/hoc.js +1 -1
- package/dist/hooks/adsHooks.d.ts +1 -0
- package/dist/hooks/adsHooks.d.ts.map +1 -0
- package/dist/hooks/adsHooks.js +1 -1
- package/dist/hooks/commandHooks.d.ts +4 -3
- package/dist/hooks/commandHooks.d.ts.map +1 -0
- package/dist/hooks/commandHooks.js +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useAutoCoreTag.d.ts +26 -0
- package/dist/hooks/useAutoCoreTag.d.ts.map +1 -0
- package/dist/hooks/useAutoCoreTag.js +1 -0
- package/dist/hooks/useScaledValue.d.ts +1 -0
- package/dist/hooks/useScaledValue.d.ts.map +1 -0
- package/dist/hooks/useScaledValue.js +1 -1
- package/dist/hub/CommandMessage.d.ts +19 -9
- package/dist/hub/CommandMessage.d.ts.map +1 -0
- package/dist/hub/CommandMessage.js +1 -1
- package/dist/hub/DebugPanel.d.ts +31 -0
- package/dist/hub/DebugPanel.d.ts.map +1 -0
- package/dist/hub/DebugPanel.js +1 -0
- package/dist/hub/HubBase.d.ts +85 -130
- package/dist/hub/HubBase.d.ts.map +1 -0
- package/dist/hub/HubBase.js +1 -1
- package/dist/hub/HubSimulate.d.ts +42 -8
- package/dist/hub/HubSimulate.d.ts.map +1 -0
- package/dist/hub/HubSimulate.js +1 -1
- package/dist/hub/HubTauri.d.ts +25 -60
- package/dist/hub/HubTauri.d.ts.map +1 -0
- package/dist/hub/HubTauri.js +1 -1
- package/dist/hub/HubWebSocket.d.ts +34 -17
- package/dist/hub/HubWebSocket.d.ts.map +1 -0
- package/dist/hub/HubWebSocket.js +1 -1
- package/dist/hub/debug.d.ts +23 -0
- package/dist/hub/debug.d.ts.map +1 -0
- package/dist/hub/debug.js +1 -0
- package/dist/hub/index.d.ts +20 -4
- package/dist/hub/index.d.ts.map +1 -0
- package/dist/hub/index.js +1 -1
- package/package.json +32 -27
- package/readme.md +193 -22
- package/src/components/AutoCoreDevPanel.tsx +414 -0
- package/src/components/CodeEditor.tsx +2 -2
- package/src/components/FileList.tsx +7 -6
- package/src/components/FileSelect.tsx +2 -1
- package/src/components/Indicator.tsx +2 -2
- package/src/components/IndicatorButton.tsx +2 -2
- package/src/components/IndicatorRect.tsx +2 -2
- package/src/components/Lamp.tsx +3 -3
- package/src/components/TextInput.tsx +159 -240
- package/src/components/ToggleGroup.tsx +3 -3
- package/src/components/ValueDisplay.tsx +4 -4
- package/src/components/ValueIndicator.tsx +2 -2
- package/src/components/ValueInput.tsx +2 -2
- package/src/core/ActionMode.ts +1 -1
- package/src/core/AutoCoreTagContext.tsx +615 -0
- package/src/core/AutoCoreTagTypes.ts +334 -0
- package/src/core/CoreStreamTypes.ts +512 -0
- package/src/core/EventEmitterContext.tsx +257 -281
- package/src/core/IndicatorButtonState.ts +1 -1
- package/src/core/ValueSimulator.ts +2 -2
- package/src/core/hoc.tsx +1 -1
- package/src/hooks/adsHooks.tsx +21 -22
- package/src/hooks/commandHooks.tsx +23 -19
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useAutoCoreTag.ts +103 -0
- package/src/hooks/useScaledValue.tsx +1 -1
- package/src/hub/CommandMessage.ts +71 -19
- package/src/hub/DebugPanel.ts +280 -0
- package/src/hub/HubBase.ts +147 -223
- package/src/hub/HubSimulate.ts +93 -24
- package/src/hub/HubTauri.ts +87 -96
- package/src/hub/HubWebSocket.ts +133 -158
- package/src/hub/debug.ts +211 -0
- package/src/hub/index.ts +49 -39
- package/tsconfig.json +43 -28
- package/docs/classes/components_BlocklyEditor.BlocklyEditor.html +0 -124
- package/docs/classes/components_CodeEditor.CodeEditor.html +0 -128
- package/docs/classes/components_JogPanel.JogPanel.html +0 -138
- package/docs/classes/components_Lamp.Lamp.html +0 -105
- package/docs/classes/components_TextInput.TextInput.html +0 -115
- package/docs/classes/components_ValueIndicator.ValueIndicator.html +0 -119
- package/docs/classes/components_ValueInput.ValueInput.html +0 -113
- package/docs/classes/hub_HubWebSocket.HubWebSocket.html +0 -106
- package/docs/enums/components_JogPanel.JogDistanceAction.html +0 -5
- package/docs/enums/components_JogPanel.JogPanelAction.html +0 -18
- package/docs/enums/components_JogPanel.JogSpeedAction.html +0 -5
- package/docs/enums/core_ActionMode.ActionMode.html +0 -6
- package/docs/enums/core_IndicatorColor.IndicatorColor.html +0 -23
- package/docs/functions/assets_BlocklyLogo.default.html +0 -1
- package/docs/functions/assets_Distance.default.html +0 -1
- package/docs/functions/assets_JogLong.default.html +0 -1
- package/docs/functions/assets_JogMedium.default.html +0 -1
- package/docs/functions/assets_JogShort.default.html +0 -1
- package/docs/functions/assets_PythonLogo.default.html +0 -1
- package/docs/functions/assets_Rotation3D.default.html +0 -1
- package/docs/functions/assets_RotationCcw.default.html +0 -1
- package/docs/functions/assets_RotationCcwA.default.html +0 -1
- package/docs/functions/assets_RotationCcwB.default.html +0 -1
- package/docs/functions/assets_RotationCcwC.default.html +0 -1
- package/docs/functions/assets_RotationCw.default.html +0 -1
- package/docs/functions/assets_RotationCwA.default.html +0 -1
- package/docs/functions/assets_RotationCwB.default.html +0 -1
- package/docs/functions/assets_RotationCwC.default.html +0 -1
- package/docs/functions/assets_Run.default.html +0 -1
- package/docs/functions/assets_Speed.default.html +0 -1
- package/docs/functions/assets_SpeedFast.default.html +0 -1
- package/docs/functions/assets_SpeedMedium.default.html +0 -1
- package/docs/functions/assets_SpeedNone.default.html +0 -1
- package/docs/functions/assets_SpeedSlow.default.html +0 -1
- package/docs/functions/assets_Walk.default.html +0 -1
- package/docs/functions/components_BlocklyEditor.createCustomToolbox.html +0 -6
- package/docs/functions/components_FileList.FileList.html +0 -21
- package/docs/functions/components_FitText.FitText.html +0 -8
- package/docs/functions/components_ToggleGroup.ToggleGroup.html +0 -5
- package/docs/interfaces/components_JogPanel.JogPanelButtonDefinition.html +0 -5
- package/docs/interfaces/components_ToggleGroup.ToggleGroupProps.html +0 -618
- package/docs/interfaces/core_IndicatorButtonState.IndicatorButtonState.html +0 -10
- package/docs/interfaces/hub_CommandMessage.CommandMessage.html +0 -6
- package/docs/interfaces/hub_CommandMessage.CommandMessageResult.html +0 -4
- package/docs/modules/assets.html +0 -23
- package/docs/modules/assets_BlocklyLogo.html +0 -2
- package/docs/modules/assets_Distance.html +0 -2
- package/docs/modules/assets_JogLong.html +0 -2
- package/docs/modules/assets_JogMedium.html +0 -2
- package/docs/modules/assets_JogShort.html +0 -2
- package/docs/modules/assets_PythonLogo.html +0 -2
- package/docs/modules/assets_Rotation3D.html +0 -2
- package/docs/modules/assets_RotationCcw.html +0 -2
- package/docs/modules/assets_RotationCcwA.html +0 -2
- package/docs/modules/assets_RotationCcwB.html +0 -2
- package/docs/modules/assets_RotationCcwC.html +0 -2
- package/docs/modules/assets_RotationCw.html +0 -2
- package/docs/modules/assets_RotationCwA.html +0 -2
- package/docs/modules/assets_RotationCwB.html +0 -2
- package/docs/modules/assets_RotationCwC.html +0 -2
- package/docs/modules/assets_Run.html +0 -2
- package/docs/modules/assets_Speed.html +0 -2
- package/docs/modules/assets_SpeedFast.html +0 -2
- package/docs/modules/assets_SpeedMedium.html +0 -2
- package/docs/modules/assets_SpeedNone.html +0 -2
- package/docs/modules/assets_SpeedSlow.html +0 -2
- package/docs/modules/assets_Walk.html +0 -2
- package/docs/modules/components_BlocklyEditor.html +0 -5
- package/docs/modules/components_CodeEditor.html +0 -3
- package/docs/modules/components_FileList.html +0 -3
- package/docs/modules/components_FitText.html +0 -3
- package/docs/modules/components_JogPanel.html +0 -9
- package/docs/modules/components_Lamp.html +0 -4
- package/docs/modules/components_TextInput.html +0 -2
- package/docs/modules/components_ToggleGroup.html +0 -6
- package/docs/modules/components_ValueIndicator.html +0 -4
- package/docs/modules/components_ValueInput.html +0 -2
- package/docs/modules/core_ActionMode.html +0 -2
- package/docs/modules/core_IndicatorButtonState.html +0 -2
- package/docs/modules/core_IndicatorColor.html +0 -2
- package/docs/modules/hub_CommandMessage.html +0 -3
- package/docs/modules/hub_HubWebSocket.html +0 -2
- package/docs/types/components_IndicatorButton.IndicatorButtonOptionsType.html +0 -1
- package/docs/variables/components_BlocklyEditor.StandardToolbox.html +0 -1
- package/docs/variables/components_JogPanel.DefaultLinearJogButtons.html +0 -2
- package/docs/variables/components_JogPanel.DefaultRotationJogButtons.html +0 -2
package/src/hub/HubTauri.ts
CHANGED
|
@@ -3,87 +3,49 @@
|
|
|
3
3
|
* Created Date: 2023-12-17 09:50:23
|
|
4
4
|
* Author: Thomas C. Bitsky Jr.
|
|
5
5
|
* -----
|
|
6
|
-
* Last Modified:
|
|
6
|
+
* Last Modified: 2026-01-29 09:34:21
|
|
7
7
|
* Modified By: ADC
|
|
8
8
|
* -----
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { InvokeArgs } from '@tauri-apps/api/tauri';
|
|
13
12
|
import { HubBase } from './HubBase';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
13
|
+
import { invoke as tauriInvoke } from '@tauri-apps/api/core';
|
|
14
|
+
import { listen } from '@tauri-apps/api/event';
|
|
15
|
+
import type { CommandMessage } from "./CommandMessage";
|
|
16
|
+
import { MessageType } from "./CommandMessage";
|
|
17
|
+
|
|
18
|
+
type InvokeArgs = Record<string, unknown>;
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Hub for integrating with the Tauri backend.
|
|
19
|
-
*
|
|
20
|
-
* The
|
|
22
|
+
*
|
|
23
|
+
* The Tauri backend is expected to broadcast messages on the event
|
|
21
24
|
* name: 'autocore://broadcast_event'
|
|
22
|
-
*
|
|
23
|
-
* This hub will capture those messages and dispatch them globally to any
|
|
25
|
+
*
|
|
26
|
+
* This hub will capture those messages and dispatch them globally to any
|
|
24
27
|
* listeners in the web app.
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* Example: Listen to an event 'xarm-position':
|
|
28
|
-
* ```
|
|
29
|
-
* const {subscribe, unsubscribe} = useContext(EventEmitterContext);
|
|
30
|
-
* useEffect(() => {
|
|
31
|
-
* const unsubscripeMp = subscribe('xarm-position', (value) => {
|
|
32
|
-
* // The rust backend sent a JSON object of 3D position values.
|
|
33
|
-
* setX(value.x);
|
|
34
|
-
* setY(value.y);
|
|
35
|
-
* setZ(value.z);
|
|
36
|
-
* setA(value.roll);
|
|
37
|
-
* setB(value.yaw);
|
|
38
|
-
* setC(value.pitch);
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* return () => {
|
|
42
|
-
* unsubscribe(unsubscripeMp);
|
|
43
|
-
* }
|
|
44
|
-
*
|
|
45
|
-
* }, [] );
|
|
46
28
|
*
|
|
29
|
+
* ## Usage Examples
|
|
30
|
+
*
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const { hub } = useContext(EventEmitterContext);
|
|
33
|
+
*
|
|
34
|
+
* // Read a value
|
|
35
|
+
* const result = await hub.read("ads.plc1.gio.bControlPowerOk");
|
|
36
|
+
*
|
|
37
|
+
* // Write a value
|
|
38
|
+
* await hub.write("ads.plc1.gio.nSetpoint", 100);
|
|
39
|
+
*
|
|
40
|
+
* // Subscribe to changes
|
|
41
|
+
* await hub.subscribe("modbus.holding_registers.5");
|
|
47
42
|
* ```
|
|
48
|
-
*
|
|
49
|
-
* The hub should also be used for invoking events in the Tauri backend.
|
|
50
|
-
* This example will call the function "update_count" in the rust backend, passing
|
|
51
|
-
* the expected argument "count".
|
|
52
|
-
* ```
|
|
53
|
-
* const {invoke} = useContext(EventEmitterContext);
|
|
54
|
-
* const incrementCount = () => {
|
|
55
|
-
* count += 1;
|
|
56
|
-
* invoke('update_count', {"count": count});
|
|
57
|
-
* };
|
|
58
|
-
* ```
|
|
59
|
-
*
|
|
60
|
-
* Of course, like any class derived from HubBase, the hub can be used to publish and subscribe to
|
|
61
|
-
* topics in the front-end, without need of interacting with the Tauri backed.
|
|
62
|
-
*
|
|
63
|
-
* ```
|
|
64
|
-
* const {dispatch, subscribe, unsubscribe} = useContext(EventEmitterContext);
|
|
65
|
-
* const [controlPower, setControlPower] = useState(false);
|
|
66
|
-
* useEffect(() => {
|
|
67
|
-
* const unsubscribeControlPower = subscribe('value-simulator-bBit1', (value) => {
|
|
68
|
-
* setControlPower(value);
|
|
69
|
-
* });
|
|
70
43
|
*
|
|
44
|
+
* The hub can also publish/subscribe to frontend-only events:
|
|
71
45
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* }
|
|
75
|
-
* }, [] );
|
|
76
|
-
*
|
|
77
|
-
* const onPbPressed = () => {
|
|
78
|
-
* let count = 1;
|
|
79
|
-
* dispatch({
|
|
80
|
-
* topic: "my-awesome-topic",
|
|
81
|
-
* payload: count
|
|
82
|
-
* });
|
|
83
|
-
* }
|
|
84
|
-
*
|
|
46
|
+
* ```typescript
|
|
47
|
+
* hub.publish("ui/panel-opened", { panelId: "settings" });
|
|
85
48
|
* ```
|
|
86
|
-
*
|
|
87
49
|
*/
|
|
88
50
|
export class HubTauri extends HubBase {
|
|
89
51
|
|
|
@@ -93,57 +55,86 @@ export class HubTauri extends HubBase {
|
|
|
93
55
|
constructor() {
|
|
94
56
|
super();
|
|
95
57
|
|
|
58
|
+
// Mark as connected since Tauri IPC is always available
|
|
59
|
+
this.setIsConnected(true);
|
|
96
60
|
|
|
97
61
|
/**
|
|
98
62
|
* Receive broadcasts from the Tauri backend. Data is received as a payload object,
|
|
99
63
|
* {topic: string, payload: any | null}
|
|
100
64
|
* From here, we extract into a form HubBase can use, then pass on to the
|
|
101
65
|
* dispatcher.
|
|
102
|
-
*
|
|
66
|
+
*
|
|
103
67
|
* Events without a topic are ignored.
|
|
104
68
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
69
|
+
listen('autocore://broadcast_event', (ev: any) => {
|
|
107
70
|
let objPayload = JSON.parse(ev.payload);
|
|
108
71
|
|
|
109
|
-
if (objPayload.topic !== undefined && objPayload.topic !== null
|
|
110
|
-
|
|
111
|
-
if ( objPayload.payload !== undefined && objPayload.payload !== null ) {
|
|
72
|
+
if (objPayload.topic !== undefined && objPayload.topic !== null) {
|
|
73
|
+
if (objPayload.payload !== undefined && objPayload.payload !== null) {
|
|
112
74
|
this.publish(objPayload.topic, objPayload.payload);
|
|
113
75
|
}
|
|
114
76
|
else {
|
|
115
77
|
this.publish(objPayload.topic, undefined);
|
|
116
78
|
}
|
|
117
|
-
|
|
118
79
|
}
|
|
119
|
-
|
|
120
80
|
});
|
|
121
|
-
|
|
122
81
|
}
|
|
123
82
|
|
|
124
83
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
84
|
+
* Send a message to the Tauri backend.
|
|
85
|
+
*
|
|
86
|
+
* The topic and messageType are passed to a generic Tauri command handler
|
|
87
|
+
* that routes the request appropriately.
|
|
88
|
+
*
|
|
89
|
+
* @param topic The FQDN of the resource (e.g., "ads.plc1.gio.bControlPowerOk")
|
|
90
|
+
* @param messageType The action to perform (Read, Write, Subscribe, etc.)
|
|
91
|
+
* @param payload Optional data payload (e.g., value to write)
|
|
92
|
+
* @returns Promise<CommandMessage> The response from the backend
|
|
130
93
|
*/
|
|
131
|
-
invoke(
|
|
132
|
-
|
|
133
|
-
console.log(JSON.stringify(event));
|
|
94
|
+
invoke(topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> {
|
|
95
|
+
console.log(`HubTauri.invoke: topic=${topic}, type=${MessageType[messageType]}`);
|
|
134
96
|
|
|
135
|
-
|
|
136
|
-
|
|
97
|
+
// Build the command arguments
|
|
98
|
+
const args: InvokeArgs = {
|
|
99
|
+
topic: topic,
|
|
100
|
+
message_type: messageType,
|
|
101
|
+
...(payload ?? {})
|
|
102
|
+
};
|
|
137
103
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
104
|
+
// Call the generic autocore handler in Tauri backend
|
|
105
|
+
return new Promise((resolve, reject) => {
|
|
106
|
+
tauriInvoke('autocore_invoke', args)
|
|
107
|
+
.then((result: any) => {
|
|
108
|
+
// If the result is already a CommandMessage, use it directly
|
|
109
|
+
if (result && typeof result === 'object' && 'topic' in result) {
|
|
110
|
+
resolve(result as CommandMessage);
|
|
111
|
+
} else {
|
|
112
|
+
// Wrap raw result in CommandMessage
|
|
113
|
+
const response: CommandMessage = {
|
|
114
|
+
transaction_id: 0,
|
|
115
|
+
timecode: Date.now(),
|
|
116
|
+
topic: topic,
|
|
117
|
+
message_type: MessageType.Response,
|
|
118
|
+
data: result,
|
|
119
|
+
success: true,
|
|
120
|
+
error_message: ''
|
|
121
|
+
};
|
|
122
|
+
resolve(response);
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
.catch((error: any) => {
|
|
126
|
+
// Wrap error in CommandMessage
|
|
127
|
+
const response: CommandMessage = {
|
|
128
|
+
transaction_id: 0,
|
|
129
|
+
timecode: Date.now(),
|
|
130
|
+
topic: topic,
|
|
131
|
+
message_type: MessageType.Response,
|
|
132
|
+
data: null,
|
|
133
|
+
success: false,
|
|
134
|
+
error_message: error?.toString() || 'Unknown error'
|
|
135
|
+
};
|
|
136
|
+
reject(response);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
147
139
|
}
|
|
148
|
-
|
|
149
|
-
}
|
|
140
|
+
}
|
package/src/hub/HubWebSocket.ts
CHANGED
|
@@ -2,36 +2,40 @@
|
|
|
2
2
|
* Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
|
|
3
3
|
* Created Date: 2024-04-17 09:13:07
|
|
4
4
|
* -----
|
|
5
|
-
* Last Modified:
|
|
5
|
+
* Last Modified: 2026-01-29 09:34:31
|
|
6
|
+
* Modified By: ADC
|
|
6
7
|
* -----
|
|
7
8
|
*
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* @module hub/HubWebSocket
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
* The result field of CommandMessages used for broadcast must have
|
|
14
|
-
* success set to true, and must contain the field "topic." The topic field, along
|
|
15
|
-
* with the domain field of the CommandMessage will be combined for the topic used
|
|
16
|
-
* by the websocket client.
|
|
14
|
+
* Implementation of `HubBase` using standard WebSockets.
|
|
17
15
|
*
|
|
18
|
-
*
|
|
16
|
+
* ## Functionality
|
|
19
17
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* - **Transport**: Connects to `ws://host:port/ws/` (or `wss://`).
|
|
19
|
+
* - **Request/Response**: Correlates requests to responses using `transaction_id`.
|
|
20
|
+
* - **Broadcasts**: Handles unsolicited messages (subscriptions) and routes them via `HubBase.publish`.
|
|
21
|
+
* - **Binary Data**: Handles `FILE_DOWNLOAD` events by decoding Base64 payloads into Blobs.
|
|
22
|
+
*
|
|
23
|
+
* ## Protocol
|
|
24
|
+
*
|
|
25
|
+
* Messages are JSON-serialized `CommandMessage` objects.
|
|
26
|
+
* - **Requests**: Client sends `message_type` (Read/Write/etc) + `transaction_id`.
|
|
27
|
+
* - **Responses**: Server replies with same `transaction_id` + `success`/`data`.
|
|
28
|
+
* - **Broadcasts**: Server sends `message_type: Broadcast` + `topic` (FQDN) + `data`.
|
|
22
29
|
*/
|
|
23
30
|
|
|
24
31
|
import { HubBase } from './HubBase';
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
// Function to parse the JSON string received from the server into a CommandMessage object
|
|
28
|
-
// function parseCommandMessage(jsonString: string): CommandMessage {
|
|
29
|
-
// const parsed: CommandMessage = JSON.parse(jsonString);
|
|
30
|
-
// // Assuming the JSON structure directly matches the TypeScript interfaces
|
|
31
|
-
// return parsed;
|
|
32
|
-
// }
|
|
33
|
-
|
|
32
|
+
import { MessageType, type CommandMessage } from "./CommandMessage";
|
|
33
|
+
import { getDebugPanel } from './DebugPanel';
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Internal tracking record for pending requests.
|
|
37
|
+
* Allows the `invoke` promise to be resolved/rejected when the response arrives.
|
|
38
|
+
*/
|
|
35
39
|
interface RequestRecord {
|
|
36
40
|
resolve: (value?: any) => void;
|
|
37
41
|
reject: (reason?: any) => void;
|
|
@@ -40,237 +44,208 @@ interface RequestRecord {
|
|
|
40
44
|
|
|
41
45
|
/**
|
|
42
46
|
* Converts a Base64 encoded string into a Blob object.
|
|
47
|
+
* Used for file downloads.
|
|
43
48
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* and constructs a Blob from the resulting byte arrays.
|
|
49
|
-
*
|
|
50
|
-
* @param {string} b64Data The base64 encoded string you want to convert to a Blob.
|
|
51
|
-
* @param {string} [contentType='application/octet-stream'] The MIME type of the Blob.
|
|
52
|
-
* This parameter is optional and defaults to 'application/octet-stream'.
|
|
53
|
-
* @param {number} [sliceSize=512] The size of each chunk used to slice the Base64 string.
|
|
54
|
-
* Smaller slice sizes can improve the function's handling of large Base64 strings.
|
|
55
|
-
* This parameter is optional and defaults to 512.
|
|
56
|
-
*
|
|
57
|
-
* @returns {Blob} A Blob object representing the decoded binary data.
|
|
49
|
+
* @param {string} b64Data The base64 encoded string.
|
|
50
|
+
* @param {string} [contentType='application/octet-stream'] The MIME type.
|
|
51
|
+
* @param {number} [sliceSize=512] Chunk size for processing.
|
|
52
|
+
* @returns {Blob} The decoded binary blob.
|
|
58
53
|
*/
|
|
59
54
|
function b64toBlob(
|
|
60
|
-
b64Data: string,
|
|
61
|
-
contentType: string =
|
|
55
|
+
b64Data: string,
|
|
56
|
+
contentType: string = "application/octet-stream",
|
|
62
57
|
sliceSize: number = 512
|
|
63
58
|
): Blob {
|
|
64
|
-
|
|
65
59
|
const byteCharacters = atob(b64Data);
|
|
66
|
-
const
|
|
60
|
+
const buffers: ArrayBuffer[] = [];
|
|
67
61
|
|
|
68
62
|
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
|
69
63
|
const slice = byteCharacters.slice(offset, offset + sliceSize);
|
|
70
64
|
|
|
71
|
-
const byteNumbers
|
|
72
|
-
for (let i = 0; i < slice.length; i++)
|
|
73
|
-
byteNumbers[i] = slice.charCodeAt(i);
|
|
74
|
-
}
|
|
65
|
+
const byteNumbers = new Array<number>(slice.length);
|
|
66
|
+
for (let i = 0; i < slice.length; i++) byteNumbers[i] = slice.charCodeAt(i);
|
|
75
67
|
|
|
76
|
-
const
|
|
77
|
-
|
|
68
|
+
const uint8 = new Uint8Array(byteNumbers);
|
|
69
|
+
buffers.push(uint8.buffer as ArrayBuffer);
|
|
78
70
|
}
|
|
79
71
|
|
|
80
|
-
|
|
81
|
-
return blob;
|
|
72
|
+
return new Blob(buffers, { type: contentType });
|
|
82
73
|
}
|
|
83
74
|
|
|
84
75
|
|
|
76
|
+
|
|
85
77
|
/**
|
|
86
|
-
*
|
|
78
|
+
* Triggers a browser download for a Blob object.
|
|
87
79
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* dynamically created anchor tag (`<a>`), sets the suggested filename, and then simulates a click on
|
|
91
|
-
* this link to start the download. After the download is triggered, the link is removed and the URL
|
|
92
|
-
* is revoked to free up memory.
|
|
93
|
-
*
|
|
94
|
-
* @param {Blob} blob The Blob object containing the data to be downloaded.
|
|
95
|
-
* @param {string} filename The filename to be used for the downloaded file.
|
|
80
|
+
* @param {Blob} blob The binary data.
|
|
81
|
+
* @param {string} filename The suggested filename.
|
|
96
82
|
*/
|
|
97
83
|
function downloadBlob(blob: Blob, filename: string): void {
|
|
98
|
-
// Create a URL for the blob object
|
|
99
84
|
const url = window.URL.createObjectURL(blob);
|
|
100
|
-
|
|
101
|
-
// Create a temporary anchor tag (`<a>`) element
|
|
102
85
|
const a = document.createElement('a');
|
|
103
|
-
a.href = url;
|
|
104
|
-
a.download = filename;
|
|
105
|
-
|
|
106
|
-
// Append the anchor tag to the body of the document
|
|
86
|
+
a.href = url;
|
|
87
|
+
a.download = filename;
|
|
107
88
|
document.body.appendChild(a);
|
|
108
|
-
|
|
109
|
-
// Programmatically trigger a click on the anchor tag
|
|
110
89
|
a.click();
|
|
111
|
-
|
|
112
|
-
// Remove the anchor tag from the document
|
|
113
90
|
document.body.removeChild(a);
|
|
114
|
-
|
|
115
|
-
// Revoke the blob URL to free up resources
|
|
116
91
|
window.URL.revokeObjectURL(url);
|
|
117
92
|
}
|
|
118
93
|
|
|
119
94
|
|
|
120
|
-
|
|
121
|
-
|
|
95
|
+
/**
|
|
96
|
+
* WebSocket implementation of the Hub communication layer.
|
|
97
|
+
*/
|
|
122
98
|
export class HubWebSocket extends HubBase {
|
|
123
99
|
private socket: WebSocket;
|
|
124
100
|
private requestId = 0;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Map of pending Transaction ID -> Promise Resolvers.
|
|
104
|
+
* Used to match asynchronous WebSocket responses to their original requests.
|
|
105
|
+
*/
|
|
125
106
|
private pendingRequests = new Map<number, RequestRecord>();
|
|
126
107
|
|
|
127
108
|
/**
|
|
128
|
-
*
|
|
109
|
+
* Initializes the WebSocket connection immediately.
|
|
129
110
|
*/
|
|
130
111
|
constructor() {
|
|
131
112
|
super();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// Default to using autocore-server.
|
|
136
|
-
let port = undefined; // window.location.port; // Get the port from the address bar, if any
|
|
113
|
+
console.log("[HubWebSocket] Constructor called");
|
|
114
|
+
getDebugPanel().hubCreated();
|
|
137
115
|
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
this.socket = new WebSocket(wsUrl);
|
|
116
|
+
const host = window.location.hostname;
|
|
117
|
+
const port = window.location.port;
|
|
142
118
|
|
|
119
|
+
const proto = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
|
120
|
+
const wsUrl = `${proto}${host}${port ? ':' + port : ''}/ws/`;
|
|
143
121
|
|
|
122
|
+
this.socket = new WebSocket(wsUrl);
|
|
144
123
|
let self = this;
|
|
145
124
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.socket.onopen = function() {
|
|
125
|
+
// --- Connection Handlers ---
|
|
126
|
+
|
|
127
|
+
this.socket.onopen = function () {
|
|
150
128
|
console.log("WebSocket connection established.");
|
|
129
|
+
getDebugPanel().wsOpened(wsUrl);
|
|
130
|
+
// Notify app that we are online
|
|
151
131
|
self.publish("HUB/connected", true);
|
|
152
132
|
self.setIsConnected(true);
|
|
153
133
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// Message recevied via the websocket connection.
|
|
157
|
-
//
|
|
158
|
-
this.socket.onmessage = (event) => {
|
|
159
|
-
const data: CommandMessage = JSON.parse(event.data);
|
|
160
134
|
|
|
161
|
-
|
|
135
|
+
// --- Message Handler ---
|
|
162
136
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
137
|
+
this.socket.onmessage = (event) => {
|
|
138
|
+
const data: CommandMessage = JSON.parse(event.data);
|
|
139
|
+
getDebugPanel().messageReceived(
|
|
140
|
+
MessageType[data.message_type] || String(data.message_type),
|
|
141
|
+
data.topic,
|
|
142
|
+
data.transaction_id
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
console.log(`HUB MSG RX: ${JSON.stringify(data)}`);
|
|
146
|
+
|
|
147
|
+
// Check if this message is a response to a pending request (has ID)
|
|
148
|
+
if (data.transaction_id && this.pendingRequests.has(data.transaction_id)) {
|
|
149
|
+
const { resolve, reject } = this.pendingRequests.get(data.transaction_id)!;
|
|
150
|
+
|
|
151
|
+
// SPECIAL CASE: File Download Response
|
|
152
|
+
if (data.topic === "FILE_DOWNLOAD"
|
|
153
|
+
&& data.data["file_name"] !== undefined && data.data["file_name"] !== null
|
|
154
|
+
&& data.data["file_name"].length > 0
|
|
170
155
|
) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
let tokens = data.args["file_name"].split("/");
|
|
156
|
+
let tokens = data.data["file_name"].split("/");
|
|
157
|
+
const filename = tokens[tokens.length - 1];
|
|
174
158
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const blob = b64toBlob(data.
|
|
159
|
+
if (data.success) {
|
|
160
|
+
// Decode and trigger download
|
|
161
|
+
const blob = b64toBlob(data.data);
|
|
178
162
|
downloadBlob(blob, filename);
|
|
179
|
-
|
|
180
|
-
// Don't send the whole file through; that's crazy.
|
|
181
|
-
data.result.data = filename;
|
|
182
|
-
|
|
183
|
-
// Signal the function that initiated the download that all is well.
|
|
184
|
-
resolve(data.result);
|
|
185
163
|
|
|
164
|
+
// Clean up response data to avoid passing giant string to app
|
|
165
|
+
data.data = filename;
|
|
166
|
+
resolve(data);
|
|
186
167
|
} else {
|
|
187
|
-
|
|
188
|
-
reject(new Error(data.result?.error_message));
|
|
168
|
+
reject(new Error(data.error_message));
|
|
189
169
|
}
|
|
190
|
-
|
|
191
170
|
}
|
|
171
|
+
// STANDARD CASE: Normal Command Response
|
|
192
172
|
else {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// Return the result to the function that initiated the request.
|
|
196
|
-
reject(new Error(data.result?.error_message));
|
|
173
|
+
if (!data.success) {
|
|
174
|
+
reject(new Error(data.error_message));
|
|
197
175
|
} else {
|
|
198
|
-
//
|
|
199
|
-
resolve(data
|
|
200
|
-
}
|
|
176
|
+
// Success: resolve with the full message
|
|
177
|
+
resolve(data);
|
|
178
|
+
}
|
|
201
179
|
}
|
|
202
|
-
|
|
180
|
+
// Cleanup request record
|
|
181
|
+
this.pendingRequests.delete(data.transaction_id);
|
|
203
182
|
} else {
|
|
183
|
+
// No transaction ID means it's an unsolicited broadcast (subscription update)
|
|
184
|
+
console.log(`HUB BROADCAST: ${JSON.stringify(data)}`);
|
|
204
185
|
this.handleUnsolicitedMessage(data);
|
|
205
186
|
}
|
|
206
187
|
};
|
|
207
188
|
|
|
208
|
-
//
|
|
209
|
-
// Error occurred in the Websocket connection.
|
|
210
|
-
//
|
|
211
189
|
this.socket.onerror = (error: Event) => {
|
|
212
190
|
console.error('WebSocket error:', error);
|
|
191
|
+
getDebugPanel().wsError(String(error));
|
|
213
192
|
};
|
|
214
193
|
|
|
215
|
-
|
|
216
|
-
// The Websocket connection has closed.
|
|
217
|
-
//
|
|
218
|
-
this.socket.onclose = () => {
|
|
194
|
+
this.socket.onclose = (event: CloseEvent) => {
|
|
219
195
|
self.setIsConnected(false);
|
|
220
|
-
console.log('WebSocket connection closed.');
|
|
196
|
+
console.log('WebSocket connection closed.');
|
|
197
|
+
getDebugPanel().wsClosed(event.code, event.reason || 'No reason');
|
|
221
198
|
};
|
|
222
199
|
}
|
|
223
200
|
|
|
224
201
|
|
|
225
202
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* @returns Promise<CommandMessageResult>
|
|
203
|
+
* Sends a command to the server via WebSocket.
|
|
204
|
+
*
|
|
205
|
+
* Wraps the operation in a Promise that resolves when the server replies
|
|
206
|
+
* with a matching `transaction_id`.
|
|
231
207
|
*/
|
|
232
|
-
invoke = (
|
|
208
|
+
invoke = (topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> => {
|
|
233
209
|
|
|
234
210
|
return new Promise((resolve, reject) => {
|
|
235
|
-
const id = ++this.requestId; //
|
|
211
|
+
const id = ++this.requestId; // Generate unique ID
|
|
236
212
|
this.pendingRequests.set(id, { resolve, reject });
|
|
237
213
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
214
|
+
const data = payload ? payload : {};
|
|
215
|
+
|
|
216
|
+
const cm: CommandMessage = {
|
|
217
|
+
transaction_id: id,
|
|
218
|
+
topic: topic,
|
|
219
|
+
data: data,
|
|
220
|
+
timecode: Date.now(),
|
|
221
|
+
message_type: messageType,
|
|
222
|
+
success: false,
|
|
223
|
+
error_message: ''
|
|
244
224
|
};
|
|
245
225
|
|
|
226
|
+
getDebugPanel().messageSent(MessageType[messageType], topic, id);
|
|
246
227
|
this.socket.send(JSON.stringify(cm));
|
|
247
228
|
});
|
|
248
229
|
}
|
|
249
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Processes messages that are not responses to a specific request.
|
|
233
|
+
* Usually these are subscription updates (Broadcasts).
|
|
234
|
+
*/
|
|
250
235
|
handleUnsolicitedMessage = (msg: CommandMessage) => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
&& msg.result.data !== undefined && msg.result.data !== null
|
|
257
|
-
) {
|
|
258
|
-
|
|
259
|
-
let topic = `${msg.domain}/${msg.result.data["topic"]}`;
|
|
260
|
-
|
|
261
|
-
//console.log(`HUB PUBLISHING: ${topic} : ${JSON.stringify(msg.result.data)}`);
|
|
262
|
-
this.publish(topic, msg.result.data);
|
|
236
|
+
if (msg.message_type == MessageType.Broadcast && msg.topic.length > 1) {
|
|
237
|
+
console.log(`HUB PUBLISHING: ${msg.topic} : ${JSON.stringify(msg.data)}`);
|
|
238
|
+
|
|
239
|
+
// Pass to HubBase to map the FQDN topic to a local tagName and dispatch
|
|
240
|
+
this.publish(msg.topic, msg.data);
|
|
263
241
|
}
|
|
264
|
-
// else {
|
|
265
|
-
// console.error("INVALID BROADCAST RECEIVED!");
|
|
266
|
-
// }
|
|
267
242
|
}
|
|
268
243
|
|
|
269
|
-
disconnect= (): void => {
|
|
244
|
+
disconnect = (): void => {
|
|
270
245
|
this.socket.close();
|
|
271
246
|
}
|
|
272
247
|
|
|
273
248
|
protected emit = (eventName: string, payload?: object): void => {
|
|
274
249
|
this.socket.send(JSON.stringify({ eventName, payload }));
|
|
275
250
|
}
|
|
276
|
-
}
|
|
251
|
+
}
|