@adcops/autocore-react 3.3.9 → 3.3.10
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/LICENSE +58 -58
- package/additional-docs/AutoCoreTagContext.md +441 -441
- package/additional-docs/ButtonApiSpecs.md +48 -48
- package/additional-docs/GlobalEventEmitter.md +243 -243
- package/additional-docs/general_recommendations.md +22 -22
- package/additional-docs/react_performance_notes.md +94 -94
- package/dist/assets/svg/blockly_logo.svg +82 -82
- package/dist/assets/svg/distance.svg +40 -40
- package/dist/assets/svg/python_logo.svg +246 -246
- package/dist/assets/svg/rotation_ccw.svg +50 -50
- package/dist/assets/svg/rotation_ccw_a.svg +57 -57
- package/dist/assets/svg/rotation_ccw_b.svg +57 -57
- package/dist/assets/svg/rotation_ccw_c.svg +57 -57
- package/dist/assets/svg/rotation_cw.svg +49 -49
- package/dist/assets/svg/rotation_cw_a.svg +30 -30
- package/dist/assets/svg/rotation_cw_b.svg +30 -30
- package/dist/assets/svg/rotation_cw_c.svg +30 -30
- package/dist/assets/svg/speed.svg +39 -39
- package/dist/components/BlocklyEditor.css +93 -93
- package/dist/components/JogPanel.css +41 -41
- package/dist/components/ProgressBarWithValue.css +27 -27
- package/dist/components/ValueIndicator.css +31 -31
- package/dist/components/osk.css +123 -123
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
- package/dist/core/AutoCoreTagContext.js +1 -1
- package/dist/hub/HubBase.d.ts +3 -3
- package/dist/hub/HubBase.d.ts.map +1 -1
- package/dist/hub/HubBase.js +1 -1
- package/package.json +104 -104
- package/readme.md +343 -343
- package/src/assets/BlocklyLogo.tsx +27 -27
- package/src/assets/Distance.tsx +18 -18
- package/src/assets/JogLong.tsx +13 -13
- package/src/assets/JogMedium.tsx +13 -13
- package/src/assets/JogShort.tsx +13 -13
- package/src/assets/PythonLogo.tsx +83 -83
- package/src/assets/Rotation3D.tsx +13 -13
- package/src/assets/RotationCcw.tsx +33 -33
- package/src/assets/RotationCcwA.tsx +45 -45
- package/src/assets/RotationCcwB.tsx +45 -45
- package/src/assets/RotationCcwC.tsx +45 -45
- package/src/assets/RotationCw.tsx +31 -31
- package/src/assets/RotationCwA.tsx +42 -42
- package/src/assets/RotationCwB.tsx +42 -42
- package/src/assets/RotationCwC.tsx +42 -42
- package/src/assets/Run.tsx +13 -13
- package/src/assets/Speed.tsx +18 -18
- package/src/assets/SpeedFast.tsx +13 -13
- package/src/assets/SpeedMedium.tsx +13 -13
- package/src/assets/SpeedNone.tsx +13 -13
- package/src/assets/SpeedSlow.tsx +13 -13
- package/src/assets/Walk.tsx +13 -13
- package/src/assets/index.ts +22 -22
- package/src/assets/svg/blockly_logo.svg +82 -82
- package/src/assets/svg/distance.svg +40 -40
- package/src/assets/svg/python_logo.svg +246 -246
- package/src/assets/svg/rotation_ccw.svg +50 -50
- package/src/assets/svg/rotation_ccw_a.svg +57 -57
- package/src/assets/svg/rotation_ccw_b.svg +57 -57
- package/src/assets/svg/rotation_ccw_c.svg +57 -57
- package/src/assets/svg/rotation_cw.svg +49 -49
- package/src/assets/svg/rotation_cw_a.svg +30 -30
- package/src/assets/svg/rotation_cw_b.svg +30 -30
- package/src/assets/svg/rotation_cw_c.svg +30 -30
- package/src/assets/svg/speed.svg +39 -39
- package/src/components/AutoCoreDevPanel.tsx +414 -414
- package/src/components/BlocklyEditor.css +93 -93
- package/src/components/BlocklyEditor.tsx +609 -609
- package/src/components/CodeEditor.tsx +155 -155
- package/src/components/FileList.tsx +390 -390
- package/src/components/FileSelect.tsx +128 -128
- package/src/components/FitText.tsx +35 -35
- package/src/components/Indicator.tsx +188 -188
- package/src/components/IndicatorButton.tsx +214 -214
- package/src/components/IndicatorRect.tsx +172 -172
- package/src/components/JogPanel.css +41 -41
- package/src/components/JogPanel.tsx +461 -461
- package/src/components/Lamp.tsx +243 -243
- package/src/components/Osk.tsx +192 -192
- package/src/components/OskDialog.tsx +164 -164
- package/src/components/ProgressBarWithValue.css +27 -27
- package/src/components/ProgressBarWithValue.tsx +48 -48
- package/src/components/TextInput.tsx +195 -195
- package/src/components/ToggleGroup.tsx +322 -322
- package/src/components/ValueDisplay.tsx +236 -236
- package/src/components/ValueIndicator.css +31 -31
- package/src/components/ValueIndicator.tsx +135 -135
- package/src/components/ValueInput.tsx +368 -368
- package/src/components/osk.css +123 -123
- package/src/core/ActionMode.ts +19 -19
- package/src/core/AutoCoreTagContext.tsx +625 -614
- package/src/core/AutoCoreTagTypes.ts +334 -334
- package/src/core/CoreStreamTypes.ts +512 -512
- package/src/core/EventEmitterContext.tsx +434 -434
- package/src/core/IndicatorButtonState.ts +34 -34
- package/src/core/IndicatorColor.ts +35 -35
- package/src/core/MaskPatterns.ts +87 -87
- package/src/core/NumerableTypes.ts +80 -80
- package/src/core/PositionContext.ts +59 -59
- package/src/core/UniqueId.ts +41 -41
- package/src/core/ValueSimulator.ts +166 -166
- package/src/core/hoc.tsx +65 -65
- package/src/hooks/adsHooks.tsx +287 -287
- package/src/hooks/commandHooks.tsx +300 -300
- package/src/hooks/index.ts +12 -12
- package/src/hooks/useAutoCoreTag.ts +103 -103
- package/src/hooks/useScaledValue.tsx +99 -99
- package/src/hub/CommandMessage.ts +89 -89
- package/src/hub/DebugPanel.ts +307 -307
- package/src/hub/HubBase.ts +249 -236
- package/src/hub/HubSimulate.ts +124 -124
- package/src/hub/HubTauri.ts +140 -140
- package/src/hub/HubWebSocket.ts +250 -250
- package/src/hub/debug.ts +211 -211
- package/src/hub/index.ts +81 -81
- package/src/themes/adc-dark/_extensions.scss +166 -166
- package/src/themes/adc-dark/_variables.scss +913 -913
- package/src/themes/adc-dark/blue/_fonts.scss +23 -23
- package/src/themes/adc-dark/blue/adc_theme.scss +31 -31
- package/src/themes/adc-dark/blue/theme.scss +14 -14
- package/src/themes/theme-base/_colors.scss +17 -17
- package/src/themes/theme-base/_common.scss +74 -74
- package/src/themes/theme-base/_components.scss +111 -111
- package/src/themes/theme-base/_mixins.scss +243 -243
- package/src/themes/theme-base/components/button/_button.scss +644 -644
- package/src/themes/theme-base/components/button/_speeddial.scss +91 -91
- package/src/themes/theme-base/components/button/_splitbutton.scss +358 -358
- package/src/themes/theme-base/components/data/_carousel.scss +39 -39
- package/src/themes/theme-base/components/data/_datascroller.scss +47 -47
- package/src/themes/theme-base/components/data/_datatable.scss +388 -388
- package/src/themes/theme-base/components/data/_dataview.scss +47 -47
- package/src/themes/theme-base/components/data/_filter.scss +137 -137
- package/src/themes/theme-base/components/data/_orderlist.scss +86 -86
- package/src/themes/theme-base/components/data/_organizationchart.scss +50 -50
- package/src/themes/theme-base/components/data/_paginator.scss +91 -91
- package/src/themes/theme-base/components/data/_picklist.scss +73 -73
- package/src/themes/theme-base/components/data/_timeline.scss +38 -38
- package/src/themes/theme-base/components/data/_tree.scss +184 -184
- package/src/themes/theme-base/components/data/_treetable.scss +431 -431
- package/src/themes/theme-base/components/file/_fileupload.scss +41 -41
- package/src/themes/theme-base/components/input/_autocomplete.scss +94 -94
- package/src/themes/theme-base/components/input/_calendar.scss +251 -251
- package/src/themes/theme-base/components/input/_cascadeselect.scss +107 -107
- package/src/themes/theme-base/components/input/_checkbox.scss +181 -181
- package/src/themes/theme-base/components/input/_chips.scss +102 -102
- package/src/themes/theme-base/components/input/_colorpicker.scss +17 -17
- package/src/themes/theme-base/components/input/_dropdown.scss +252 -252
- package/src/themes/theme-base/components/input/_editor.scss +122 -122
- package/src/themes/theme-base/components/input/_iconfield.scss +9 -9
- package/src/themes/theme-base/components/input/_inputgroup.scss +74 -74
- package/src/themes/theme-base/components/input/_inputicon.scss +14 -14
- package/src/themes/theme-base/components/input/_inputnumber.scss +4 -4
- package/src/themes/theme-base/components/input/_inputotp.scss +10 -10
- package/src/themes/theme-base/components/input/_inputswitch.scss +99 -99
- package/src/themes/theme-base/components/input/_inputtext.scss +101 -101
- package/src/themes/theme-base/components/input/_listbox.scss +138 -138
- package/src/themes/theme-base/components/input/_mention.scss +30 -30
- package/src/themes/theme-base/components/input/_multiselect.scss +278 -278
- package/src/themes/theme-base/components/input/_password.scss +32 -32
- package/src/themes/theme-base/components/input/_radiobutton.scss +169 -169
- package/src/themes/theme-base/components/input/_rating.scss +80 -80
- package/src/themes/theme-base/components/input/_selectbutton.scss +49 -49
- package/src/themes/theme-base/components/input/_slider.scss +49 -49
- package/src/themes/theme-base/components/input/_togglebutton.scss +99 -99
- package/src/themes/theme-base/components/input/_treeselect.scss +151 -151
- package/src/themes/theme-base/components/input/_tristatecheckbox.scss +46 -46
- package/src/themes/theme-base/components/menu/_breadcrumb.scss +42 -42
- package/src/themes/theme-base/components/menu/_contextmenu.scss +39 -39
- package/src/themes/theme-base/components/menu/_dock.scss +109 -109
- package/src/themes/theme-base/components/menu/_megamenu.scss +141 -141
- package/src/themes/theme-base/components/menu/_menu.scss +33 -33
- package/src/themes/theme-base/components/menu/_menubar.scss +216 -216
- package/src/themes/theme-base/components/menu/_panelmenu.scss +153 -153
- package/src/themes/theme-base/components/menu/_slidemenu.scss +60 -60
- package/src/themes/theme-base/components/menu/_steps.scss +57 -57
- package/src/themes/theme-base/components/menu/_tabmenu.scss +50 -50
- package/src/themes/theme-base/components/menu/_tieredmenu.scss +43 -43
- package/src/themes/theme-base/components/messages/_inlinemessage.scss +69 -69
- package/src/themes/theme-base/components/messages/_message.scss +107 -107
- package/src/themes/theme-base/components/messages/_toast.scss +100 -100
- package/src/themes/theme-base/components/misc/_avatar.scss +33 -33
- package/src/themes/theme-base/components/misc/_badge.scss +76 -76
- package/src/themes/theme-base/components/misc/_chip.scss +38 -38
- package/src/themes/theme-base/components/misc/_inplace.scss +17 -17
- package/src/themes/theme-base/components/misc/_metergroup.scss +80 -80
- package/src/themes/theme-base/components/misc/_progressbar.scss +17 -17
- package/src/themes/theme-base/components/misc/_scrolltop.scss +24 -24
- package/src/themes/theme-base/components/misc/_skeleton.scss +7 -7
- package/src/themes/theme-base/components/misc/_tag.scss +39 -39
- package/src/themes/theme-base/components/misc/_terminal.scss +12 -12
- package/src/themes/theme-base/components/multimedia/_galleria.scss +153 -153
- package/src/themes/theme-base/components/multimedia/_image.scss +53 -53
- package/src/themes/theme-base/components/overlay/_confirmpopup.scss +72 -72
- package/src/themes/theme-base/components/overlay/_dialog.scss +78 -78
- package/src/themes/theme-base/components/overlay/_overlaypanel.scss +64 -64
- package/src/themes/theme-base/components/overlay/_sidebar.scss +23 -23
- package/src/themes/theme-base/components/overlay/_tooltip.scss +33 -33
- package/src/themes/theme-base/components/panel/_accordion.scss +118 -118
- package/src/themes/theme-base/components/panel/_card.scss +30 -30
- package/src/themes/theme-base/components/panel/_divider.scss +30 -30
- package/src/themes/theme-base/components/panel/_fieldset.scss +47 -47
- package/src/themes/theme-base/components/panel/_panel.scss +47 -47
- package/src/themes/theme-base/components/panel/_scrollpanel.scss +10 -10
- package/src/themes/theme-base/components/panel/_splitter.scss +23 -23
- package/src/themes/theme-base/components/panel/_stepper.scss +136 -136
- package/src/themes/theme-base/components/panel/_tabview.scss +147 -147
- package/src/themes/theme-base/components/panel/_toolbar.scss +11 -11
- package/terser.config.cjs +25 -25
- package/todo.md +18 -18
- package/tools/build-themes.cjs +65 -65
- package/tools/copy-distribution-files.cjs +77 -77
- package/tools/minify.cjs +55 -55
- package/tsconfig.json +48 -48
- package/typedoc.json +12 -12
- package/.claude/settings.local.json +0 -7
package/src/hub/HubSimulate.ts
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2023 Automated Design Corp. All Rights Reserved.
|
|
3
|
-
* Created Date: 2023-12-17 10:38:21
|
|
4
|
-
* -----
|
|
5
|
-
* Last Modified: 2026-01-29 09:34:15
|
|
6
|
-
* Modified By: ADC
|
|
7
|
-
* -----
|
|
8
|
-
*
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { HubBase } from './HubBase';
|
|
12
|
-
import type { CommandMessage } from "./CommandMessage";
|
|
13
|
-
import { MessageType } from "./CommandMessage";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Hub for simulating backend functionality when no actual backend is present.
|
|
17
|
-
*
|
|
18
|
-
* Useful for development, testing, and demos without a running autocore-server.
|
|
19
|
-
* The simulator echoes back requests as successful responses after a configurable delay.
|
|
20
|
-
*
|
|
21
|
-
* ## Usage Examples
|
|
22
|
-
*
|
|
23
|
-
* ```typescript
|
|
24
|
-
* const { hub } = useContext(EventEmitterContext);
|
|
25
|
-
*
|
|
26
|
-
* // Read returns the topic as the "value"
|
|
27
|
-
* const result = await hub.read("ads.plc1.gio.bControlPowerOk");
|
|
28
|
-
* console.log(result.data); // { value: "ads.plc1.gio.bControlPowerOk" }
|
|
29
|
-
*
|
|
30
|
-
* // Write echoes back the written value
|
|
31
|
-
* await hub.write("ads.plc1.gio.nSetpoint", 100);
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export class HubSimulate extends HubBase {
|
|
35
|
-
|
|
36
|
-
private responseDelay: number;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Constructor
|
|
40
|
-
* @param responseDelay Simulated response delay in milliseconds (default: 20ms)
|
|
41
|
-
*/
|
|
42
|
-
constructor(responseDelay: number = 20) {
|
|
43
|
-
super();
|
|
44
|
-
this.responseDelay = responseDelay;
|
|
45
|
-
this.setIsConnected(true); // Simulator is always "connected"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Simulate sending a message to a backend.
|
|
50
|
-
*
|
|
51
|
-
* For Read operations, returns the topic as the value.
|
|
52
|
-
* For Write operations, echoes back the payload.
|
|
53
|
-
* For all operations, returns a successful response after the configured delay.
|
|
54
|
-
*
|
|
55
|
-
* @param topic The FQDN of the resource
|
|
56
|
-
* @param messageType The action to perform
|
|
57
|
-
* @param payload Optional data payload
|
|
58
|
-
* @returns Promise<CommandMessage> A simulated successful response
|
|
59
|
-
*/
|
|
60
|
-
invoke(topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> {
|
|
61
|
-
return new Promise((resolve) => {
|
|
62
|
-
setTimeout(() => {
|
|
63
|
-
let responseData: any;
|
|
64
|
-
|
|
65
|
-
// Simulate appropriate responses based on message type
|
|
66
|
-
switch (messageType) {
|
|
67
|
-
case MessageType.Read:
|
|
68
|
-
// Simulate reading - return the topic as a "value"
|
|
69
|
-
responseData = { value: topic, simulated: true };
|
|
70
|
-
break;
|
|
71
|
-
|
|
72
|
-
case MessageType.Write:
|
|
73
|
-
// Simulate writing - echo back the payload
|
|
74
|
-
responseData = { written: true, ...payload };
|
|
75
|
-
break;
|
|
76
|
-
|
|
77
|
-
case MessageType.Subscribe:
|
|
78
|
-
// Simulate subscribing - acknowledge
|
|
79
|
-
responseData = { subscribed: true, topic: topic };
|
|
80
|
-
break;
|
|
81
|
-
|
|
82
|
-
case MessageType.Unsubscribe:
|
|
83
|
-
// Simulate unsubscribing - acknowledge
|
|
84
|
-
responseData = { unsubscribed: true, topic: topic };
|
|
85
|
-
break;
|
|
86
|
-
|
|
87
|
-
default:
|
|
88
|
-
// Echo back the payload for other message types
|
|
89
|
-
responseData = payload ?? {};
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const response: CommandMessage = {
|
|
94
|
-
transaction_id: 0,
|
|
95
|
-
timecode: Date.now(),
|
|
96
|
-
topic: topic,
|
|
97
|
-
message_type: MessageType.Response,
|
|
98
|
-
data: responseData,
|
|
99
|
-
success: true,
|
|
100
|
-
error_message: ''
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
resolve(response);
|
|
104
|
-
}, this.responseDelay);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Simulate a broadcast from the "backend".
|
|
110
|
-
*
|
|
111
|
-
* This is useful for testing subscription handlers.
|
|
112
|
-
*
|
|
113
|
-
* @param topic The topic to broadcast on
|
|
114
|
-
* @param data The data to broadcast
|
|
115
|
-
* @param delay Optional delay before broadcasting (default: 0ms)
|
|
116
|
-
*/
|
|
117
|
-
simulateBroadcast(topic: string, data: any, delay: number = 0): void {
|
|
118
|
-
setTimeout(() => {
|
|
119
|
-
this.publish(topic, data);
|
|
120
|
-
}, delay);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export default HubSimulate;
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2023 Automated Design Corp. All Rights Reserved.
|
|
3
|
+
* Created Date: 2023-12-17 10:38:21
|
|
4
|
+
* -----
|
|
5
|
+
* Last Modified: 2026-01-29 09:34:15
|
|
6
|
+
* Modified By: ADC
|
|
7
|
+
* -----
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { HubBase } from './HubBase';
|
|
12
|
+
import type { CommandMessage } from "./CommandMessage";
|
|
13
|
+
import { MessageType } from "./CommandMessage";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Hub for simulating backend functionality when no actual backend is present.
|
|
17
|
+
*
|
|
18
|
+
* Useful for development, testing, and demos without a running autocore-server.
|
|
19
|
+
* The simulator echoes back requests as successful responses after a configurable delay.
|
|
20
|
+
*
|
|
21
|
+
* ## Usage Examples
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const { hub } = useContext(EventEmitterContext);
|
|
25
|
+
*
|
|
26
|
+
* // Read returns the topic as the "value"
|
|
27
|
+
* const result = await hub.read("ads.plc1.gio.bControlPowerOk");
|
|
28
|
+
* console.log(result.data); // { value: "ads.plc1.gio.bControlPowerOk" }
|
|
29
|
+
*
|
|
30
|
+
* // Write echoes back the written value
|
|
31
|
+
* await hub.write("ads.plc1.gio.nSetpoint", 100);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class HubSimulate extends HubBase {
|
|
35
|
+
|
|
36
|
+
private responseDelay: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Constructor
|
|
40
|
+
* @param responseDelay Simulated response delay in milliseconds (default: 20ms)
|
|
41
|
+
*/
|
|
42
|
+
constructor(responseDelay: number = 20) {
|
|
43
|
+
super();
|
|
44
|
+
this.responseDelay = responseDelay;
|
|
45
|
+
this.setIsConnected(true); // Simulator is always "connected"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Simulate sending a message to a backend.
|
|
50
|
+
*
|
|
51
|
+
* For Read operations, returns the topic as the value.
|
|
52
|
+
* For Write operations, echoes back the payload.
|
|
53
|
+
* For all operations, returns a successful response after the configured delay.
|
|
54
|
+
*
|
|
55
|
+
* @param topic The FQDN of the resource
|
|
56
|
+
* @param messageType The action to perform
|
|
57
|
+
* @param payload Optional data payload
|
|
58
|
+
* @returns Promise<CommandMessage> A simulated successful response
|
|
59
|
+
*/
|
|
60
|
+
invoke(topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> {
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
let responseData: any;
|
|
64
|
+
|
|
65
|
+
// Simulate appropriate responses based on message type
|
|
66
|
+
switch (messageType) {
|
|
67
|
+
case MessageType.Read:
|
|
68
|
+
// Simulate reading - return the topic as a "value"
|
|
69
|
+
responseData = { value: topic, simulated: true };
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case MessageType.Write:
|
|
73
|
+
// Simulate writing - echo back the payload
|
|
74
|
+
responseData = { written: true, ...payload };
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case MessageType.Subscribe:
|
|
78
|
+
// Simulate subscribing - acknowledge
|
|
79
|
+
responseData = { subscribed: true, topic: topic };
|
|
80
|
+
break;
|
|
81
|
+
|
|
82
|
+
case MessageType.Unsubscribe:
|
|
83
|
+
// Simulate unsubscribing - acknowledge
|
|
84
|
+
responseData = { unsubscribed: true, topic: topic };
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
default:
|
|
88
|
+
// Echo back the payload for other message types
|
|
89
|
+
responseData = payload ?? {};
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const response: CommandMessage = {
|
|
94
|
+
transaction_id: 0,
|
|
95
|
+
timecode: Date.now(),
|
|
96
|
+
topic: topic,
|
|
97
|
+
message_type: MessageType.Response,
|
|
98
|
+
data: responseData,
|
|
99
|
+
success: true,
|
|
100
|
+
error_message: ''
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
resolve(response);
|
|
104
|
+
}, this.responseDelay);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Simulate a broadcast from the "backend".
|
|
110
|
+
*
|
|
111
|
+
* This is useful for testing subscription handlers.
|
|
112
|
+
*
|
|
113
|
+
* @param topic The topic to broadcast on
|
|
114
|
+
* @param data The data to broadcast
|
|
115
|
+
* @param delay Optional delay before broadcasting (default: 0ms)
|
|
116
|
+
*/
|
|
117
|
+
simulateBroadcast(topic: string, data: any, delay: number = 0): void {
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
this.publish(topic, data);
|
|
120
|
+
}, delay);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default HubSimulate;
|
package/src/hub/HubTauri.ts
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2023 Automated Design Corp. All Rights Reserved.
|
|
3
|
-
* Created Date: 2023-12-17 09:50:23
|
|
4
|
-
* Author: Thomas C. Bitsky Jr.
|
|
5
|
-
* -----
|
|
6
|
-
* Last Modified: 2026-01-29 09:34:21
|
|
7
|
-
* Modified By: ADC
|
|
8
|
-
* -----
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { HubBase } from './HubBase';
|
|
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>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Hub for integrating with the Tauri backend.
|
|
22
|
-
*
|
|
23
|
-
* The Tauri backend is expected to broadcast messages on the event
|
|
24
|
-
* name: 'autocore://broadcast_event'
|
|
25
|
-
*
|
|
26
|
-
* This hub will capture those messages and dispatch them globally to any
|
|
27
|
-
* listeners in the web app.
|
|
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");
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* The hub can also publish/subscribe to frontend-only events:
|
|
45
|
-
*
|
|
46
|
-
* ```typescript
|
|
47
|
-
* hub.publish("ui/panel-opened", { panelId: "settings" });
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export class HubTauri extends HubBase {
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Constructor
|
|
54
|
-
*/
|
|
55
|
-
constructor() {
|
|
56
|
-
super();
|
|
57
|
-
|
|
58
|
-
// Mark as connected since Tauri IPC is always available
|
|
59
|
-
this.setIsConnected(true);
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Receive broadcasts from the Tauri backend. Data is received as a payload object,
|
|
63
|
-
* {topic: string, payload: any | null}
|
|
64
|
-
* From here, we extract into a form HubBase can use, then pass on to the
|
|
65
|
-
* dispatcher.
|
|
66
|
-
*
|
|
67
|
-
* Events without a topic are ignored.
|
|
68
|
-
*/
|
|
69
|
-
listen('autocore://broadcast_event', (ev: any) => {
|
|
70
|
-
let objPayload = JSON.parse(ev.payload);
|
|
71
|
-
|
|
72
|
-
if (objPayload.topic !== undefined && objPayload.topic !== null) {
|
|
73
|
-
if (objPayload.payload !== undefined && objPayload.payload !== null) {
|
|
74
|
-
this.publish(objPayload.topic, objPayload.payload);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
this.publish(objPayload.topic, undefined);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
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
|
|
93
|
-
*/
|
|
94
|
-
invoke(topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> {
|
|
95
|
-
console.log(`HubTauri.invoke: topic=${topic}, type=${MessageType[messageType]}`);
|
|
96
|
-
|
|
97
|
-
// Build the command arguments
|
|
98
|
-
const args: InvokeArgs = {
|
|
99
|
-
topic: topic,
|
|
100
|
-
message_type: messageType,
|
|
101
|
-
...(payload ?? {})
|
|
102
|
-
};
|
|
103
|
-
|
|
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
|
-
});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2023 Automated Design Corp. All Rights Reserved.
|
|
3
|
+
* Created Date: 2023-12-17 09:50:23
|
|
4
|
+
* Author: Thomas C. Bitsky Jr.
|
|
5
|
+
* -----
|
|
6
|
+
* Last Modified: 2026-01-29 09:34:21
|
|
7
|
+
* Modified By: ADC
|
|
8
|
+
* -----
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { HubBase } from './HubBase';
|
|
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>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Hub for integrating with the Tauri backend.
|
|
22
|
+
*
|
|
23
|
+
* The Tauri backend is expected to broadcast messages on the event
|
|
24
|
+
* name: 'autocore://broadcast_event'
|
|
25
|
+
*
|
|
26
|
+
* This hub will capture those messages and dispatch them globally to any
|
|
27
|
+
* listeners in the web app.
|
|
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");
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* The hub can also publish/subscribe to frontend-only events:
|
|
45
|
+
*
|
|
46
|
+
* ```typescript
|
|
47
|
+
* hub.publish("ui/panel-opened", { panelId: "settings" });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export class HubTauri extends HubBase {
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Constructor
|
|
54
|
+
*/
|
|
55
|
+
constructor() {
|
|
56
|
+
super();
|
|
57
|
+
|
|
58
|
+
// Mark as connected since Tauri IPC is always available
|
|
59
|
+
this.setIsConnected(true);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Receive broadcasts from the Tauri backend. Data is received as a payload object,
|
|
63
|
+
* {topic: string, payload: any | null}
|
|
64
|
+
* From here, we extract into a form HubBase can use, then pass on to the
|
|
65
|
+
* dispatcher.
|
|
66
|
+
*
|
|
67
|
+
* Events without a topic are ignored.
|
|
68
|
+
*/
|
|
69
|
+
listen('autocore://broadcast_event', (ev: any) => {
|
|
70
|
+
let objPayload = JSON.parse(ev.payload);
|
|
71
|
+
|
|
72
|
+
if (objPayload.topic !== undefined && objPayload.topic !== null) {
|
|
73
|
+
if (objPayload.payload !== undefined && objPayload.payload !== null) {
|
|
74
|
+
this.publish(objPayload.topic, objPayload.payload);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.publish(objPayload.topic, undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
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
|
|
93
|
+
*/
|
|
94
|
+
invoke(topic: string, messageType: MessageType, payload?: object): Promise<CommandMessage> {
|
|
95
|
+
console.log(`HubTauri.invoke: topic=${topic}, type=${MessageType[messageType]}`);
|
|
96
|
+
|
|
97
|
+
// Build the command arguments
|
|
98
|
+
const args: InvokeArgs = {
|
|
99
|
+
topic: topic,
|
|
100
|
+
message_type: messageType,
|
|
101
|
+
...(payload ?? {})
|
|
102
|
+
};
|
|
103
|
+
|
|
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
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|