@adcops/autocore-react 3.0.39 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/additional-docs/AutoCoreTagContext.md +441 -0
  2. package/dist/assets/BlocklyLogo.d.ts +1 -0
  3. package/dist/assets/BlocklyLogo.d.ts.map +1 -0
  4. package/dist/assets/Distance.d.ts +1 -0
  5. package/dist/assets/Distance.d.ts.map +1 -0
  6. package/dist/assets/JogLong.d.ts +1 -0
  7. package/dist/assets/JogLong.d.ts.map +1 -0
  8. package/dist/assets/JogMedium.d.ts +1 -0
  9. package/dist/assets/JogMedium.d.ts.map +1 -0
  10. package/dist/assets/JogShort.d.ts +1 -0
  11. package/dist/assets/JogShort.d.ts.map +1 -0
  12. package/dist/assets/PythonLogo.d.ts +1 -0
  13. package/dist/assets/PythonLogo.d.ts.map +1 -0
  14. package/dist/assets/Rotation3D.d.ts +1 -0
  15. package/dist/assets/Rotation3D.d.ts.map +1 -0
  16. package/dist/assets/RotationCcw.d.ts +1 -0
  17. package/dist/assets/RotationCcw.d.ts.map +1 -0
  18. package/dist/assets/RotationCcwA.d.ts +1 -0
  19. package/dist/assets/RotationCcwA.d.ts.map +1 -0
  20. package/dist/assets/RotationCcwB.d.ts +1 -0
  21. package/dist/assets/RotationCcwB.d.ts.map +1 -0
  22. package/dist/assets/RotationCcwC.d.ts +1 -0
  23. package/dist/assets/RotationCcwC.d.ts.map +1 -0
  24. package/dist/assets/RotationCw.d.ts +1 -0
  25. package/dist/assets/RotationCw.d.ts.map +1 -0
  26. package/dist/assets/RotationCwA.d.ts +1 -0
  27. package/dist/assets/RotationCwA.d.ts.map +1 -0
  28. package/dist/assets/RotationCwB.d.ts +1 -0
  29. package/dist/assets/RotationCwB.d.ts.map +1 -0
  30. package/dist/assets/RotationCwC.d.ts +1 -0
  31. package/dist/assets/RotationCwC.d.ts.map +1 -0
  32. package/dist/assets/Run.d.ts +1 -0
  33. package/dist/assets/Run.d.ts.map +1 -0
  34. package/dist/assets/Speed.d.ts +1 -0
  35. package/dist/assets/Speed.d.ts.map +1 -0
  36. package/dist/assets/SpeedFast.d.ts +1 -0
  37. package/dist/assets/SpeedFast.d.ts.map +1 -0
  38. package/dist/assets/SpeedMedium.d.ts +1 -0
  39. package/dist/assets/SpeedMedium.d.ts.map +1 -0
  40. package/dist/assets/SpeedNone.d.ts +1 -0
  41. package/dist/assets/SpeedNone.d.ts.map +1 -0
  42. package/dist/assets/SpeedSlow.d.ts +1 -0
  43. package/dist/assets/SpeedSlow.d.ts.map +1 -0
  44. package/dist/assets/Walk.d.ts +1 -0
  45. package/dist/assets/Walk.d.ts.map +1 -0
  46. package/dist/assets/index.d.ts +1 -0
  47. package/dist/assets/index.d.ts.map +1 -0
  48. package/dist/components/AutoCoreDevPanel.d.ts +144 -0
  49. package/dist/components/AutoCoreDevPanel.d.ts.map +1 -0
  50. package/dist/components/AutoCoreDevPanel.js +1 -0
  51. package/dist/components/BlocklyEditor.d.ts +1 -0
  52. package/dist/components/BlocklyEditor.d.ts.map +1 -0
  53. package/dist/components/BlocklyEditor.js +1 -1
  54. package/dist/components/CodeEditor.d.ts +2 -1
  55. package/dist/components/CodeEditor.d.ts.map +1 -0
  56. package/dist/components/CodeEditor.js +1 -1
  57. package/dist/components/FileList.d.ts +1 -0
  58. package/dist/components/FileList.d.ts.map +1 -0
  59. package/dist/components/FileList.js +1 -1
  60. package/dist/components/FileSelect.d.ts +1 -0
  61. package/dist/components/FileSelect.d.ts.map +1 -0
  62. package/dist/components/FileSelect.js +1 -1
  63. package/dist/components/FitText.d.ts +1 -0
  64. package/dist/components/FitText.d.ts.map +1 -0
  65. package/dist/components/FitText.js +1 -1
  66. package/dist/components/Indicator.d.ts +2 -1
  67. package/dist/components/Indicator.d.ts.map +1 -0
  68. package/dist/components/Indicator.js +1 -1
  69. package/dist/components/IndicatorButton.d.ts +23 -137
  70. package/dist/components/IndicatorButton.d.ts.map +1 -0
  71. package/dist/components/IndicatorButton.js +1 -1
  72. package/dist/components/IndicatorRect.d.ts +2 -1
  73. package/dist/components/IndicatorRect.d.ts.map +1 -0
  74. package/dist/components/JogPanel.d.ts +1 -0
  75. package/dist/components/JogPanel.d.ts.map +1 -0
  76. package/dist/components/Lamp.d.ts +2 -1
  77. package/dist/components/Lamp.d.ts.map +1 -0
  78. package/dist/components/Lamp.js +1 -1
  79. package/dist/components/Osk.d.ts +1 -0
  80. package/dist/components/Osk.d.ts.map +1 -0
  81. package/dist/components/Osk.js +1 -1
  82. package/dist/components/OskDialog.d.ts +1 -0
  83. package/dist/components/OskDialog.d.ts.map +1 -0
  84. package/dist/components/ProgressBarWithValue.d.ts +1 -0
  85. package/dist/components/ProgressBarWithValue.d.ts.map +1 -0
  86. package/dist/components/ProgressBarWithValue.js +1 -1
  87. package/dist/components/TextInput.d.ts +62 -103
  88. package/dist/components/TextInput.d.ts.map +1 -0
  89. package/dist/components/TextInput.js +1 -1
  90. package/dist/components/ToggleGroup.d.ts +2 -1
  91. package/dist/components/ToggleGroup.d.ts.map +1 -0
  92. package/dist/components/ToggleGroup.js +1 -1
  93. package/dist/components/ValueDisplay.d.ts +3 -2
  94. package/dist/components/ValueDisplay.d.ts.map +1 -0
  95. package/dist/components/ValueDisplay.js +1 -1
  96. package/dist/components/ValueIndicator.d.ts +2 -1
  97. package/dist/components/ValueIndicator.d.ts.map +1 -0
  98. package/dist/components/ValueIndicator.js +1 -1
  99. package/dist/components/ValueInput.d.ts +2 -1
  100. package/dist/components/ValueInput.d.ts.map +1 -0
  101. package/dist/components/ValueInput.js +1 -1
  102. package/dist/core/ActionMode.d.ts +1 -0
  103. package/dist/core/ActionMode.d.ts.map +1 -0
  104. package/dist/core/AutoCoreTagContext.d.ts +224 -0
  105. package/dist/core/AutoCoreTagContext.d.ts.map +1 -0
  106. package/dist/core/AutoCoreTagContext.js +1 -0
  107. package/dist/core/AutoCoreTagTypes.d.ts +162 -0
  108. package/dist/core/AutoCoreTagTypes.d.ts.map +1 -0
  109. package/dist/core/AutoCoreTagTypes.js +1 -0
  110. package/dist/core/EventEmitterContext.d.ts +295 -2
  111. package/dist/core/EventEmitterContext.d.ts.map +1 -0
  112. package/dist/core/EventEmitterContext.js +1 -1
  113. package/dist/core/IndicatorButtonState.d.ts +1 -0
  114. package/dist/core/IndicatorButtonState.d.ts.map +1 -0
  115. package/dist/core/IndicatorColor.d.ts +1 -0
  116. package/dist/core/IndicatorColor.d.ts.map +1 -0
  117. package/dist/core/MaskPatterns.d.ts +1 -0
  118. package/dist/core/MaskPatterns.d.ts.map +1 -0
  119. package/dist/core/NumerableTypes.d.ts +1 -0
  120. package/dist/core/NumerableTypes.d.ts.map +1 -0
  121. package/dist/core/NumerableTypes.js +1 -1
  122. package/dist/core/PositionContext.d.ts +1 -1
  123. package/dist/core/PositionContext.d.ts.map +1 -0
  124. package/dist/core/UniqueId.d.ts +1 -0
  125. package/dist/core/UniqueId.d.ts.map +1 -0
  126. package/dist/core/ValueSimulator.d.ts +2 -1
  127. package/dist/core/ValueSimulator.d.ts.map +1 -0
  128. package/dist/core/ValueSimulator.js +1 -1
  129. package/dist/core/hoc.d.ts +1 -0
  130. package/dist/core/hoc.d.ts.map +1 -0
  131. package/dist/core/hoc.js +1 -1
  132. package/dist/hooks/adsHooks.d.ts +1 -0
  133. package/dist/hooks/adsHooks.d.ts.map +1 -0
  134. package/dist/hooks/adsHooks.js +1 -1
  135. package/dist/hooks/commandHooks.d.ts +1 -0
  136. package/dist/hooks/commandHooks.d.ts.map +1 -0
  137. package/dist/hooks/commandHooks.js +1 -1
  138. package/dist/hooks/index.d.ts +1 -0
  139. package/dist/hooks/index.d.ts.map +1 -0
  140. package/dist/hooks/useAutoCoreTag.d.ts +26 -0
  141. package/dist/hooks/useAutoCoreTag.d.ts.map +1 -0
  142. package/dist/hooks/useAutoCoreTag.js +1 -0
  143. package/dist/hooks/useScaledValue.d.ts +1 -0
  144. package/dist/hooks/useScaledValue.d.ts.map +1 -0
  145. package/dist/hooks/useScaledValue.js +1 -1
  146. package/dist/hub/CommandMessage.d.ts +1 -0
  147. package/dist/hub/CommandMessage.d.ts.map +1 -0
  148. package/dist/hub/HubBase.d.ts +3 -2
  149. package/dist/hub/HubBase.d.ts.map +1 -0
  150. package/dist/hub/HubSimulate.d.ts +2 -1
  151. package/dist/hub/HubSimulate.d.ts.map +1 -0
  152. package/dist/hub/HubSimulate.js +1 -1
  153. package/dist/hub/HubTauri.d.ts +2 -1
  154. package/dist/hub/HubTauri.d.ts.map +1 -0
  155. package/dist/hub/HubTauri.js +1 -1
  156. package/dist/hub/HubWebSocket.d.ts +2 -1
  157. package/dist/hub/HubWebSocket.d.ts.map +1 -0
  158. package/dist/hub/HubWebSocket.js +1 -1
  159. package/dist/hub/index.d.ts +2 -1
  160. package/dist/hub/index.d.ts.map +1 -0
  161. package/dist/hub/index.js +1 -1
  162. package/docs/.nojekyll +1 -0
  163. package/docs/assets/hierarchy.js +1 -0
  164. package/docs/assets/highlight.css +134 -0
  165. package/docs/assets/icons.js +18 -0
  166. package/docs/assets/icons.svg +1 -0
  167. package/docs/assets/main.js +60 -0
  168. package/docs/assets/navigation.js +1 -0
  169. package/docs/assets/search.js +1 -0
  170. package/docs/assets/style.css +1633 -0
  171. package/docs/classes/components_CodeEditor.CodeEditor.html +108 -101
  172. package/docs/classes/components_Indicator.Indicator.html +122 -0
  173. package/docs/classes/components_IndicatorRect.IndicatorRect.html +121 -0
  174. package/docs/classes/components_JogPanel.JogPanel.html +104 -106
  175. package/docs/classes/components_Lamp.Lamp.html +96 -79
  176. package/docs/classes/components_OskDialog.OskDialog.html +125 -0
  177. package/docs/classes/components_TextInput.TextInput.html +99 -89
  178. package/docs/classes/components_ValueDisplay.ValueDisplay.html +148 -0
  179. package/docs/classes/components_ValueIndicator.ValueIndicator.html +98 -91
  180. package/docs/classes/core_ValueSimulator.ValueSimulator.html +51 -0
  181. package/docs/classes/hub_HubBase.HubBase.html +106 -0
  182. package/docs/classes/hub_HubSimulate.HubSimulate.html +75 -0
  183. package/docs/classes/hub_HubTauri.HubTauri.html +93 -0
  184. package/docs/classes/hub_HubWebSocket.HubWebSocket.html +75 -69
  185. package/docs/documents/core_AutoCoreTagContext.AutoCoreTagContext.html +148 -0
  186. package/docs/enums/components_JogPanel.JogDistanceAction.html +5 -5
  187. package/docs/enums/components_JogPanel.JogPanelAction.html +18 -18
  188. package/docs/enums/components_JogPanel.JogSpeedAction.html +5 -5
  189. package/docs/enums/core_ActionMode.ActionMode.html +6 -6
  190. package/docs/enums/core_IndicatorColor.IndicatorColor.html +22 -22
  191. package/docs/functions/assets.BlocklyLogo.html +1 -0
  192. package/docs/functions/assets.Distance.html +1 -0
  193. package/docs/functions/assets.JogLong.html +1 -0
  194. package/docs/functions/assets.JogMedium.html +1 -0
  195. package/docs/functions/assets.JogShort.html +1 -0
  196. package/docs/functions/assets.PythonLogo.html +1 -0
  197. package/docs/functions/assets.Rotation3D.html +1 -0
  198. package/docs/functions/assets.RotationCcw.html +1 -0
  199. package/docs/functions/assets.RotationCcwA.html +1 -0
  200. package/docs/functions/assets.RotationCcwB.html +1 -0
  201. package/docs/functions/assets.RotationCcwC.html +1 -0
  202. package/docs/functions/assets.RotationCw.html +1 -0
  203. package/docs/functions/assets.RotationCwA.html +1 -0
  204. package/docs/functions/assets.RotationCwB.html +1 -0
  205. package/docs/functions/assets.RotationCwC.html +1 -0
  206. package/docs/functions/assets.Run.html +1 -0
  207. package/docs/functions/assets.Speed.html +1 -0
  208. package/docs/functions/assets.SpeedFast.html +1 -0
  209. package/docs/functions/assets.SpeedMedium.html +1 -0
  210. package/docs/functions/assets.SpeedNone.html +1 -0
  211. package/docs/functions/assets.SpeedSlow.html +1 -0
  212. package/docs/functions/assets.Walk.html +1 -0
  213. package/docs/functions/components_BlocklyEditor.createCustomToolbox.html +5 -5
  214. package/docs/functions/core_UniqueId.UniqueId.html +9 -0
  215. package/docs/functions/core_hoc.hocAddSubscription.html +6 -0
  216. package/docs/functions/hooks_adsHooks.useAdsRegisterSymbols.html +16 -0
  217. package/docs/functions/hooks_adsHooks.useAdsTapValue.html +8 -0
  218. package/docs/functions/hooks_adsHooks.useAdsWriteScaledValue.html +18 -0
  219. package/docs/functions/hooks_adsHooks.useAdsWriteValue.html +9 -0
  220. package/docs/functions/hooks_commandHooks.useRegisterSymbols.html +16 -0
  221. package/docs/functions/hooks_commandHooks.useTapValue.html +10 -0
  222. package/docs/functions/hooks_commandHooks.useWriteScaledValue.html +18 -0
  223. package/docs/functions/hooks_commandHooks.useWriteValue.html +11 -0
  224. package/docs/functions/hooks_useAutoCoreTag.ts.makeAutoCoreTagHooks.html +12 -0
  225. package/docs/functions/hooks_useScaledValue.useScaledValue.html +18 -0
  226. package/docs/functions/hub.createHub.html +3 -0
  227. package/docs/hierarchy.html +1 -0
  228. package/docs/index.html +148 -0
  229. package/docs/interfaces/components_IndicatorButton.IndicatorButtonProps.html +654 -0
  230. package/docs/interfaces/components_IndicatorRect.IndicatorRectProps.html +37 -0
  231. package/docs/interfaces/components_JogPanel.JogPanelButtonDefinition.html +5 -5
  232. package/docs/interfaces/components_ToggleGroup.ToggleGroupProps.html +545 -519
  233. package/docs/interfaces/core_AutoCoreTagTypes.BaseContextValue.html +12 -0
  234. package/docs/interfaces/core_AutoCoreTagTypes.ScaleConfig.html +13 -0
  235. package/docs/interfaces/core_EventEmitterContext.Action.html +8 -0
  236. package/docs/interfaces/core_EventEmitterContext.EventEmitterContextType.html +33 -0
  237. package/docs/interfaces/core_EventEmitterContext.State.html +8 -0
  238. package/docs/interfaces/core_EventEmitterContext.Subscription.html +6 -0
  239. package/docs/interfaces/core_IndicatorButtonState.IndicatorButtonState.html +10 -10
  240. package/docs/interfaces/core_PositionContext.IPositionContext.html +17 -0
  241. package/docs/interfaces/hub_CommandMessage.CommandMessage.html +6 -6
  242. package/docs/interfaces/hub_CommandMessage.CommandMessageResult.html +4 -4
  243. package/docs/modules/assets.html +1 -23
  244. package/docs/modules/assets_BlocklyLogo.html +1 -2
  245. package/docs/modules/assets_Distance.html +1 -2
  246. package/docs/modules/assets_JogLong.html +1 -2
  247. package/docs/modules/assets_JogMedium.html +1 -2
  248. package/docs/modules/assets_JogShort.html +1 -2
  249. package/docs/modules/assets_PythonLogo.html +1 -2
  250. package/docs/modules/assets_Rotation3D.html +1 -2
  251. package/docs/modules/assets_RotationCcw.html +1 -2
  252. package/docs/modules/assets_RotationCcwA.html +1 -2
  253. package/docs/modules/assets_RotationCcwB.html +1 -2
  254. package/docs/modules/assets_RotationCcwC.html +1 -2
  255. package/docs/modules/assets_RotationCw.html +1 -2
  256. package/docs/modules/assets_RotationCwA.html +1 -2
  257. package/docs/modules/assets_RotationCwB.html +1 -2
  258. package/docs/modules/assets_RotationCwC.html +1 -2
  259. package/docs/modules/assets_Run.html +1 -2
  260. package/docs/modules/assets_Speed.html +1 -2
  261. package/docs/modules/assets_SpeedFast.html +1 -2
  262. package/docs/modules/assets_SpeedMedium.html +1 -2
  263. package/docs/modules/assets_SpeedNone.html +1 -2
  264. package/docs/modules/assets_SpeedSlow.html +1 -2
  265. package/docs/modules/assets_Walk.html +1 -2
  266. package/docs/modules/components_AutoCoreDevPanel.html +20 -0
  267. package/docs/modules/components_BlocklyEditor.html +1 -5
  268. package/docs/modules/components_CodeEditor.html +1 -3
  269. package/docs/modules/components_FileList.html +1 -3
  270. package/docs/modules/components_FileSelect.html +1 -0
  271. package/docs/modules/components_FitText.html +1 -3
  272. package/docs/modules/components_Indicator.html +1 -0
  273. package/docs/modules/components_IndicatorButton.html +1 -0
  274. package/docs/modules/components_IndicatorRect.html +1 -0
  275. package/docs/modules/components_JogPanel.html +1 -9
  276. package/docs/modules/components_Lamp.html +1 -4
  277. package/docs/modules/components_Osk.html +1 -0
  278. package/docs/modules/components_OskDialog.html +1 -0
  279. package/docs/modules/components_ProgressBarWithValue.html +1 -0
  280. package/docs/modules/components_TextInput.html +1 -2
  281. package/docs/modules/components_ToggleGroup.html +1 -6
  282. package/docs/modules/components_ValueDisplay.html +1 -0
  283. package/docs/modules/components_ValueIndicator.html +1 -4
  284. package/docs/modules/components_ValueInput.html +1 -2
  285. package/docs/modules/core_ActionMode.html +1 -2
  286. package/docs/modules/core_AutoCoreTagContext.html +11 -0
  287. package/docs/modules/core_AutoCoreTagTypes.html +1 -0
  288. package/docs/modules/core_EventEmitterContext.html +53 -0
  289. package/docs/modules/core_IndicatorButtonState.html +1 -2
  290. package/docs/modules/core_IndicatorColor.html +1 -2
  291. package/docs/modules/core_MaskPatterns.html +1 -0
  292. package/docs/modules/core_NumerableTypes.html +1 -0
  293. package/docs/modules/core_PositionContext.html +1 -0
  294. package/docs/modules/core_UniqueId.html +1 -0
  295. package/docs/modules/core_ValueSimulator.html +1 -0
  296. package/docs/modules/core_hoc.html +1 -0
  297. package/docs/modules/hooks.html +1 -0
  298. package/docs/modules/hooks_adsHooks.html +1 -0
  299. package/docs/modules/hooks_commandHooks.html +1 -0
  300. package/docs/modules/hooks_useAutoCoreTag.ts.html +52 -0
  301. package/docs/modules/hooks_useScaledValue.html +1 -0
  302. package/docs/modules/hub.html +1 -0
  303. package/docs/modules/hub_CommandMessage.html +1 -3
  304. package/docs/modules/hub_HubBase.html +1 -0
  305. package/docs/modules/hub_HubSimulate.html +1 -0
  306. package/docs/modules/hub_HubTauri.html +1 -0
  307. package/docs/modules/hub_HubWebSocket.html +1 -2
  308. package/docs/modules.html +23 -0
  309. package/docs/types/components_IndicatorButton.IndicatorButtonOptionsType.html +1 -1
  310. package/docs/types/core_AutoCoreTagTypes.ExtractByTag.html +2 -0
  311. package/docs/types/core_AutoCoreTagTypes.PrimitiveKind.html +1 -0
  312. package/docs/types/core_AutoCoreTagTypes.TagConfig.html +16 -0
  313. package/docs/types/core_AutoCoreTagTypes.TagValueMap.html +1 -0
  314. package/docs/types/core_AutoCoreTagTypes.TagValueOf.html +1 -0
  315. package/docs/types/core_EventEmitterContext.EmitterDispatchFunction.html +3 -0
  316. package/docs/types/core_EventEmitterContext.EmitterSubscribeFunction.html +3 -0
  317. package/docs/types/core_EventEmitterContext.EmitterUnsubscribeFunction.html +3 -0
  318. package/docs/types/core_NumerableTypes.NumerableFormatOptions.html +4 -0
  319. package/docs/types/core_hoc.HocAddSubscriptionProps.html +6 -0
  320. package/docs/variables/components_AutoCoreDevPanel.AutoCoreDevPanel.html +43 -0
  321. package/docs/variables/components_BlocklyEditor.BlocklyEditor.html +13 -0
  322. package/docs/variables/components_BlocklyEditor.StandardToolbox.html +1 -1
  323. package/docs/variables/components_FileList.FileList.html +23 -0
  324. package/docs/variables/components_FileSelect.FileSelect.html +1 -0
  325. package/docs/variables/components_FitText.FitText.html +4 -0
  326. package/docs/variables/components_IndicatorButton.IndicatorButton.html +1 -0
  327. package/docs/variables/components_JogPanel.DefaultLinearJogButtons.html +2 -2
  328. package/docs/variables/components_JogPanel.DefaultRotationJogButtons.html +2 -2
  329. package/docs/variables/components_Osk.Osk.html +1 -0
  330. package/docs/variables/components_ProgressBarWithValue.ProgressBarWithValue.html +1 -0
  331. package/docs/variables/components_ToggleGroup.ToggleGroup.html +1 -0
  332. package/docs/variables/components_ValueInput.ValueInput.html +4 -0
  333. package/docs/variables/core_AutoCoreTagContext.AutoCoreTagContext.html +1 -0
  334. package/docs/variables/core_AutoCoreTagContext.AutoCoreTagProvider.html +7 -0
  335. package/docs/variables/core_EventEmitterContext.EventEmitterContext.html +64 -0
  336. package/docs/variables/core_EventEmitterContext.EventEmitterProvider.html +10 -0
  337. package/docs/variables/core_MaskPatterns.PrimeReactMaskPatterns.html +14 -0
  338. package/docs/variables/core_MaskPatterns.RegExMaskPatterns.html +15 -0
  339. package/docs/variables/core_PositionContext.DimensionsContext.html +6 -0
  340. package/docs/variables/hooks_useScaledValue.kMillimeters2Inches.html +2 -0
  341. package/docs/variables/hooks_useScaledValue.kNewtons2Pounds.html +2 -0
  342. package/package.json +32 -27
  343. package/readme.md +193 -22
  344. package/src/components/AutoCoreDevPanel.tsx +411 -0
  345. package/src/components/CodeEditor.tsx +2 -2
  346. package/src/components/FileList.tsx +2 -2
  347. package/src/components/Indicator.tsx +2 -2
  348. package/src/components/IndicatorButton.tsx +187 -333
  349. package/src/components/IndicatorRect.tsx +2 -2
  350. package/src/components/Lamp.tsx +3 -3
  351. package/src/components/TextInput.tsx +159 -240
  352. package/src/components/ToggleGroup.tsx +3 -3
  353. package/src/components/ValueDisplay.tsx +4 -4
  354. package/src/components/ValueIndicator.tsx +2 -2
  355. package/src/components/ValueInput.tsx +2 -2
  356. package/src/core/AutoCoreTagContext.tsx +698 -0
  357. package/src/core/AutoCoreTagTypes.ts +202 -0
  358. package/src/core/EventEmitterContext.tsx +582 -225
  359. package/src/core/ValueSimulator.ts +2 -2
  360. package/src/hooks/useAutoCoreTag.ts +103 -0
  361. package/src/hub/HubBase.ts +3 -3
  362. package/src/hub/HubSimulate.ts +2 -2
  363. package/src/hub/HubTauri.ts +3 -3
  364. package/src/hub/HubWebSocket.ts +29 -32
  365. package/src/hub/index.ts +2 -2
  366. package/tsconfig.json +43 -28
  367. package/docs/classes/components_BlocklyEditor.BlocklyEditor.html +0 -124
  368. package/docs/classes/components_ValueInput.ValueInput.html +0 -113
  369. package/docs/functions/assets_BlocklyLogo.default.html +0 -1
  370. package/docs/functions/assets_Distance.default.html +0 -1
  371. package/docs/functions/assets_JogLong.default.html +0 -1
  372. package/docs/functions/assets_JogMedium.default.html +0 -1
  373. package/docs/functions/assets_JogShort.default.html +0 -1
  374. package/docs/functions/assets_PythonLogo.default.html +0 -1
  375. package/docs/functions/assets_Rotation3D.default.html +0 -1
  376. package/docs/functions/assets_RotationCcw.default.html +0 -1
  377. package/docs/functions/assets_RotationCcwA.default.html +0 -1
  378. package/docs/functions/assets_RotationCcwB.default.html +0 -1
  379. package/docs/functions/assets_RotationCcwC.default.html +0 -1
  380. package/docs/functions/assets_RotationCw.default.html +0 -1
  381. package/docs/functions/assets_RotationCwA.default.html +0 -1
  382. package/docs/functions/assets_RotationCwB.default.html +0 -1
  383. package/docs/functions/assets_RotationCwC.default.html +0 -1
  384. package/docs/functions/assets_Run.default.html +0 -1
  385. package/docs/functions/assets_Speed.default.html +0 -1
  386. package/docs/functions/assets_SpeedFast.default.html +0 -1
  387. package/docs/functions/assets_SpeedMedium.default.html +0 -1
  388. package/docs/functions/assets_SpeedNone.default.html +0 -1
  389. package/docs/functions/assets_SpeedSlow.default.html +0 -1
  390. package/docs/functions/assets_Walk.default.html +0 -1
  391. package/docs/functions/components_FileList.FileList.html +0 -21
  392. package/docs/functions/components_FitText.FitText.html +0 -8
  393. package/docs/functions/components_ToggleGroup.ToggleGroup.html +0 -5
@@ -2,16 +2,316 @@
2
2
  * Copyright (C) 2024 Automated Design Corp. All Rights Reserved.
3
3
  * Created Date: 2024-01-17 11:45:10
4
4
  * -----
5
- * Last Modified: 2024-04-25 15:24:53
5
+ * Last Modified: 2025-09-06 14:08:30
6
6
  * Modified By: ADC
7
7
  * -----
8
+ *
9
+ */
10
+
11
+ /**
12
+ * @fileoverview EventEmitterContext - Global Event Bus for AutoCore React Applications
13
+ *
14
+ * The EventEmitterContext provides a comprehensive event-driven communication system for React applications,
15
+ * enabling seamless interaction between components and backend services. It serves as the foundational layer
16
+ * for AutoCore's real-time data flow and component communication architecture.
17
+ *
18
+ * ## Core Features
19
+ *
20
+ * - **Global Event Bus**: Publish and subscribe to events across all components
21
+ * - **Backend Integration**: Direct communication with AutoCore server via Hub abstraction
22
+ * - **Type-Safe Subscriptions**: Strongly-typed event handling with automatic cleanup
23
+ * - **Connection Management**: Automatic reconnection and state synchronization
24
+ * - **Development Tools**: Built-in debugging and subscription introspection
25
+ *
26
+ * ## Architecture
27
+ *
28
+ * The system consists of three main components:
29
+ * 1. **EventEmitterProvider**: React context provider that manages global state
30
+ * 2. **Hub**: Abstraction layer for backend communication (WebSocket, HTTP, etc.)
31
+ * 3. **Subscription Manager**: Handles event routing and lifecycle management
32
+ *
33
+ * ## Basic Usage
34
+ *
35
+ * ### 1. Application Setup
36
+ *
37
+ * Wrap your entire application with the EventEmitterProvider:
38
+ *
39
+ * ```tsx
40
+ * // App.tsx
41
+ * import React from 'react';
42
+ * import { EventEmitterProvider } from '@adcops/autocore-react/core/EventEmitterContext';
43
+ * import { PrimeReactProvider } from 'primereact/api';
44
+ * import { MainView } from './MainView';
45
+ *
46
+ * export default function App() {
47
+ * return (
48
+ * <EventEmitterProvider>
49
+ * <PrimeReactProvider>
50
+ * <MainView />
51
+ * </PrimeReactProvider>
52
+ * </EventEmitterProvider>
53
+ * );
54
+ * }
55
+ * ```
56
+ *
57
+ * ### 2. Component Communication
58
+ *
59
+ * Use the context for inter-component communication:
60
+ *
61
+ * ```tsx
62
+ * // PublisherComponent.tsx
63
+ * import React, { useContext } from 'react';
64
+ * import { EventEmitterContext } from '@adcops/autocore-react/core/EventEmitterContext';
65
+ * import { Button } from 'primereact/button';
66
+ *
67
+ * export const PublisherComponent: React.FC = () => {
68
+ * const { dispatch } = useContext(EventEmitterContext);
69
+ *
70
+ * const handleButtonClick = () => {
71
+ * dispatch({
72
+ * topic: 'user-action/button-clicked',
73
+ * payload: { timestamp: Date.now(), buttonId: 'main-action' }
74
+ * });
75
+ * };
76
+ *
77
+ * return <Button label="Trigger Event" onClick={handleButtonClick} />;
78
+ * };
79
+ *
80
+ * // SubscriberComponent.tsx
81
+ * import React, { useContext, useEffect, useState } from 'react';
82
+ * import { EventEmitterContext } from '@adcops/autocore-react/core/EventEmitterContext';
83
+ *
84
+ * export const SubscriberComponent: React.FC = () => {
85
+ * const { subscribe, unsubscribe } = useContext(EventEmitterContext);
86
+ * const [lastAction, setLastAction] = useState<any>(null);
87
+ *
88
+ * useEffect(() => {
89
+ * const subscriptionId = subscribe('user-action/button-clicked', (payload) => {
90
+ * setLastAction(payload);
91
+ * console.log('Button clicked at:', payload.timestamp);
92
+ * });
93
+ *
94
+ * return () => unsubscribe(subscriptionId);
95
+ * }, [subscribe, unsubscribe]);
96
+ *
97
+ * return (
98
+ * <div>
99
+ * {lastAction && (
100
+ * <p>Last action: {new Date(lastAction.timestamp).toLocaleTimeString()}</p>
101
+ * )}
102
+ * </div>
103
+ * );
104
+ * };
105
+ * ```
106
+ *
107
+ * ### 3. Backend Integration
108
+ *
109
+ * Communicate with AutoCore server through the integrated Hub:
110
+ *
111
+ * ```tsx
112
+ * // ControlPanel.tsx
113
+ * import React, { useContext, useEffect, useState } from 'react';
114
+ * import { EventEmitterContext } from '@adcops/autocore-react/core/EventEmitterContext';
115
+ * import { Button } from 'primereact/button';
116
+ * import { InputNumber } from 'primereact/inputnumber';
117
+ *
118
+ * export const ControlPanel: React.FC = () => {
119
+ * const { invoke, subscribe, unsubscribe, isConnected } = useContext(EventEmitterContext);
120
+ * const [motorSpeed, setMotorSpeed] = useState<number>(0);
121
+ * const [targetSpeed, setTargetSpeed] = useState<number>(100);
122
+ * const [connected, setConnected] = useState<boolean>(false);
123
+ *
124
+ * // Monitor connection status
125
+ * useEffect(() => {
126
+ * setConnected(isConnected());
127
+ *
128
+ * const connectionSub = subscribe('HUB/connected', () => setConnected(true));
129
+ * const disconnectionSub = subscribe('HUB/disconnected', () => setConnected(false));
130
+ *
131
+ * return () => {
132
+ * unsubscribe(connectionSub);
133
+ * unsubscribe(disconnectionSub);
134
+ * };
135
+ * }, [subscribe, unsubscribe, isConnected]);
8
136
  *
137
+ * // Subscribe to real-time motor speed updates
138
+ * useEffect(() => {
139
+ * const speedSub = subscribe('ADS/MAIN.motor.speed', (data) => {
140
+ * setMotorSpeed(data.value);
141
+ * });
142
+ *
143
+ * return () => unsubscribe(speedSub);
144
+ * }, [subscribe, unsubscribe]);
145
+ *
146
+ * // Send commands to backend
147
+ * const handleSpeedChange = async () => {
148
+ * try {
149
+ * const result = await invoke('ADS', 'write_value', {
150
+ * symbol_name: 'MAIN.motor.setpoint',
151
+ * value: targetSpeed
152
+ * });
153
+ *
154
+ * if (!result.success) {
155
+ * console.error('Failed to set motor speed:', result.error_message);
156
+ * }
157
+ * } catch (error) {
158
+ * console.error('Communication error:', error);
159
+ * }
160
+ * };
161
+ *
162
+ * const handleEmergencyStop = async () => {
163
+ * try {
164
+ * await invoke('ADS', 'emergency_stop', {});
165
+ * } catch (error) {
166
+ * console.error('Emergency stop failed:', error);
167
+ * }
168
+ * };
169
+ *
170
+ * return (
171
+ * <div className="control-panel">
172
+ * <div className="status">
173
+ * Connection: {connected ? '🟢 Connected' : '🔴 Disconnected'}
174
+ * </div>
175
+ *
176
+ * <div className="motor-control">
177
+ * <p>Current Speed: {motorSpeed} RPM</p>
178
+ *
179
+ * <InputNumber
180
+ * value={targetSpeed}
181
+ * onValueChange={(e) => setTargetSpeed(e.value || 0)}
182
+ * min={0}
183
+ * max={1000}
184
+ * suffix=" RPM"
185
+ * />
186
+ *
187
+ * <Button
188
+ * label="Set Speed"
189
+ * onClick={handleSpeedChange}
190
+ * disabled={!connected}
191
+ * />
192
+ *
193
+ * <Button
194
+ * label="Emergency Stop"
195
+ * onClick={handleEmergencyStop}
196
+ * severity="danger"
197
+ * disabled={!connected}
198
+ * />
199
+ * </div>
200
+ * </div>
201
+ * );
202
+ * };
203
+ * ```
204
+ *
205
+ * ### 4. Advanced Pattern: State Management Hook
206
+ *
207
+ * Create reusable hooks for common patterns:
208
+ *
209
+ * ```tsx
210
+ * // hooks/useRealtimeValue.ts
211
+ * import { useContext, useEffect, useState } from 'react';
212
+ * import { EventEmitterContext } from '@adcops/autocore-react/core/EventEmitterContext';
213
+ *
214
+ * export function useRealtimeValue<T>(topic: string, initialValue?: T) {
215
+ * const { subscribe, unsubscribe } = useContext(EventEmitterContext);
216
+ * const [value, setValue] = useState<T | undefined>(initialValue);
217
+ * const [lastUpdate, setLastUpdate] = useState<Date | null>(null);
218
+ *
219
+ * useEffect(() => {
220
+ * const subscriptionId = subscribe(topic, (data) => {
221
+ * setValue(data.value);
222
+ * setLastUpdate(new Date());
223
+ * });
224
+ *
225
+ * return () => unsubscribe(subscriptionId);
226
+ * }, [topic, subscribe, unsubscribe]);
227
+ *
228
+ * return { value, lastUpdate };
229
+ * }
230
+ *
231
+ * // Usage in component
232
+ * export const SensorDisplay: React.FC = () => {
233
+ * const { value: temperature } = useRealtimeValue<number>('ADS/sensors.temperature');
234
+ * const { value: pressure } = useRealtimeValue<number>('ADS/sensors.pressure');
235
+ *
236
+ * return (
237
+ * <div>
238
+ * <p>Temperature: {temperature?.toFixed(1)}°C</p>
239
+ * <p>Pressure: {pressure?.toFixed(2)} bar</p>
240
+ * </div>
241
+ * );
242
+ * };
243
+ * ```
244
+ *
245
+ * ## Integration with AutoCore Systems
246
+ *
247
+ * The EventEmitterContext is designed to work seamlessly with other AutoCore React components:
248
+ *
249
+ * ```tsx
250
+ * // Complete AutoCore application setup
251
+ * import React from 'react';
252
+ * import { EventEmitterProvider } from '@adcops/autocore-react/core/EventEmitterContext';
253
+ * import { AutoCoreTagProvider } from '@adcops/autocore-react/core/AutoCoreTagContext';
254
+ * import { PrimeReactProvider } from 'primereact/api';
255
+ * import { tagSpec } from './config/tags';
256
+ * import { MainInterface } from './components/MainInterface';
257
+ *
258
+ * export default function App() {
259
+ * return (
260
+ * <EventEmitterProvider>
261
+ * <AutoCoreTagProvider tags={tagSpec} eagerRead>
262
+ * <PrimeReactProvider>
263
+ * <MainInterface />
264
+ * </PrimeReactProvider>
265
+ * </AutoCoreTagProvider>
266
+ * </EventEmitterProvider>
267
+ * );
268
+ * }
269
+ * ```
270
+ *
271
+ * ## Best Practices
272
+ *
273
+ * 1. **Always Cleanup Subscriptions**: Use the cleanup function returned by useEffect
274
+ * 2. **Use Meaningful Topic Names**: Follow a hierarchical naming convention (e.g., 'domain/category/specific')
275
+ * 3. **Handle Connection States**: Always check connection status before invoking backend functions
276
+ * 4. **Error Handling**: Wrap invoke calls in try-catch blocks
277
+ * 5. **Type Safety**: Use TypeScript interfaces for payload structures
278
+ * 6. **Performance**: Avoid subscribing to high-frequency events in render-heavy components
279
+ *
280
+ * ## Debugging
281
+ *
282
+ * Use the built-in debugging features:
283
+ *
284
+ * ```tsx
285
+ * const { getSubscriptions, state } = useContext(EventEmitterContext);
286
+ *
287
+ * // View all subscriptions
288
+ * console.log('All subscriptions:', getSubscriptions());
289
+ *
290
+ * // View subscriptions for specific topic
291
+ * console.log('Motor subscriptions:', getSubscriptions('ADS/MAIN.motor.speed'));
292
+ *
293
+ * // View current state
294
+ * console.log('EventEmitter state:', state);
295
+ * ```
296
+ *
297
+ * @module core/EventEmitterContext
298
+ * @version 3.0.41
299
+ * @author Automated Design Corp.
300
+ * @since 1.0.0
9
301
  */
10
302
 
303
+ import React, {
304
+ createContext,
305
+ useState,
306
+ useMemo,
307
+ useCallback,
308
+ useRef,
309
+ useEffect,
310
+ } from "react";
11
311
 
12
- import React, { createContext, ReactNode, useState, useMemo, useCallback } from 'react';
312
+ import type {ReactNode} from "react";
13
313
  import { createHub, Hub } from "../hub";
14
- import { CommandMessageResult } from "../hub/CommandMessage";
314
+ import type { CommandMessageResult } from "../hub/CommandMessage";
15
315
 
16
316
  export { Hub };
17
317
 
@@ -19,26 +319,25 @@ export { Hub };
19
319
  * Represents an event subsription.
20
320
  */
21
321
  export interface Subscription {
22
- /** ID of the subscription used for unsubscription. */
23
- id: number;
24
- /** Callback function. */
25
- callback: React.Dispatch<any>;
322
+ /** ID of the subscription used for unsubscription. */
323
+ id: number;
324
+ /** Callback function. */
325
+ callback: React.Dispatch<any>;
26
326
  }
27
327
 
28
-
29
328
  /**
30
329
  * Represents the payload data associated with an event.
31
330
  */
32
331
  export interface State {
33
- /**
34
- * The optional data payload of the event.
35
- */
36
- eventData?: any;
37
- /** Callback subscription. A list of callback subscriptions matched to a topic. */
38
- subscriptions: Record<string, Subscription[]>;
39
-
40
- /** Tracks the next subscription ID that will be assigned. */
41
- nextSubscriptionId: number;
332
+ /**
333
+ * The optional data payload of the event.
334
+ */
335
+ eventData?: any;
336
+ /** Callback subscription. A list of callback subscriptions matched to a topic. */
337
+ subscriptions: Record<string, Subscription[]>;
338
+
339
+ /** Tracks the next subscription ID that will be assigned. */
340
+ nextSubscriptionId: number;
42
341
  }
43
342
 
44
343
  /**
@@ -47,37 +346,35 @@ export interface State {
47
346
  * a value of any type.
48
347
  */
49
348
  export interface Action {
50
-
51
- /**
52
- * The topic or identifier of the event.
53
- */
54
- topic: string;
55
-
56
- /**
57
- * The optional data payload associated with the event.
58
- */
59
- payload?: any;
349
+ /**
350
+ * The topic or identifier of the event.
351
+ */
352
+ topic: string;
353
+
354
+ /**
355
+ * The optional data payload associated with the event.
356
+ */
357
+ payload?: any;
60
358
  }
61
359
 
62
- /**
360
+ /**
63
361
  * Type declaration for the EventEmitter dispatch function, which
64
362
  * publishes an Action globally throughout the EventEmitterContext.
65
363
  */
66
364
  export type EmitterDispatchFunction = (action: Action) => void;
67
365
 
68
- /**
366
+ /**
69
367
  * Type declaration for the EventEmitter dispatch function, which
70
368
  * receives an Action on a specific topic broadcast through the EventEmitterContext.
71
369
  */
72
370
  export type EmitterSubscribeFunction = (action: Action) => void;
73
371
 
74
- /**
372
+ /**
75
373
  * Type declaration for the EventEmitter unsubscribe function, which
76
374
  * receives an Action on a specific topic broadcast through the EventEmitterContext.
77
375
  */
78
376
  export type EmitterUnsubscribeFunction = (action: Action) => void;
79
377
 
80
-
81
378
  /**
82
379
  * Defines the context for an event emitter used throughout a front-end application to manage and dispatch events.
83
380
  * This interface includes methods for managing the application's state, handling global actions, communicating with the back end,
@@ -86,66 +383,66 @@ export type EmitterUnsubscribeFunction = (action: Action) => void;
86
383
  * components and the back end, as well as among components themselves.
87
384
  */
88
385
  export interface EventEmitterContextType {
89
- /**
90
- * The current state of the event emitter, containing the latest event data.
91
- */
92
- state: State;
93
-
94
- /**
95
- * A function to dispatch actions globally throughout the front-end,
96
- * triggering state updates and events.
97
- *
98
- * @param action The action to dispatch, containing topic and optional payload.
99
- */
100
- dispatch: (action: Action) => void;
101
-
102
-
103
- /**
104
- * Invoke/send a message to the back end.
105
- * This does NOT get published to the front end.
106
- */
107
- invoke(domain: string, fname: string, payload?: object): Promise<CommandMessageResult>;
108
-
109
- /**
110
- * Subscribe to events identified by the topic.
111
- * @param topic The subscription topic.
112
- * @param callback The callback to signal.
113
- * @returns number Subscription ID used to unsubscribe later.
114
- */
115
- subscribe: (topic: string, callback: React.Dispatch<any>) => number;
116
-
117
- /**
118
- * Unsubscribe to events.
119
- * @param subscriptionId The id of the subscription returned by the subscribe method.
120
- * @returns
121
- */
122
- unsubscribe: (subscriptionId: number) => void;
123
-
124
-
125
- /**
126
- * Global hub for publishing and receiving events throughout the interface, and for exchanging
127
- * data with the backend.
128
- */
129
- hub: Hub | null;
130
-
131
- /**
132
- * Retrieves the current subscriptions. Used for debugging purposes.
133
- * @param topic Optional. The topic to retrieve subscriptions for. If omitted, returns all subscriptions.
134
- * @returns An object containing the current subscriptions, optionally filtered by topic.
135
- */
136
- getSubscriptions: (topic?: string) => Record<string, Subscription[]> | Subscription[];
137
-
138
-
139
- /**
140
- * Returns true if the Hub in use is connected to its source.
141
- * @returns boolean
142
- */
143
- isConnected: () => boolean;
386
+ /**
387
+ * The current state of the event emitter, containing the latest event data.
388
+ */
389
+ state: State;
390
+
391
+ /**
392
+ * A function to dispatch actions globally throughout the front-end,
393
+ * triggering state updates and events.
394
+ *
395
+ * @param action The action to dispatch, containing topic and optional payload.
396
+ */
397
+ dispatch: (action: Action) => void;
398
+
399
+ /**
400
+ * Invoke/send a message to the back end.
401
+ * This does NOT get published to the front end.
402
+ */
403
+ invoke(
404
+ domain: string,
405
+ fname: string,
406
+ payload?: object
407
+ ): Promise<CommandMessageResult>;
408
+
409
+ /**
410
+ * Subscribe to events identified by the topic.
411
+ * @param topic The subscription topic.
412
+ * @param callback The callback to signal.
413
+ * @returns number Subscription ID used to unsubscribe later.
414
+ */
415
+ subscribe: (topic: string, callback: React.Dispatch<any>) => number;
416
+
417
+ /**
418
+ * Unsubscribe to events.
419
+ * @param subscriptionId The id of the subscription returned by the subscribe method.
420
+ * @returns
421
+ */
422
+ unsubscribe: (subscriptionId: number) => void;
423
+
424
+ /**
425
+ * Global hub for publishing and receiving events throughout the interface, and for exchanging
426
+ * data with the backend.
427
+ */
428
+ hub: Hub | null;
429
+
430
+ /**
431
+ * Retrieves the current subscriptions. Used for debugging purposes.
432
+ * @param topic Optional. The topic to retrieve subscriptions for. If omitted, returns all subscriptions.
433
+ * @returns An object containing the current subscriptions, optionally filtered by topic.
434
+ */
435
+ getSubscriptions: (
436
+ topic?: string
437
+ ) => Record<string, Subscription[]> | Subscription[];
438
+
439
+ /**
440
+ * Returns true if the Hub in use is connected to its source.
441
+ * @returns boolean
442
+ */
443
+ isConnected: () => boolean;
144
444
  }
145
445
 
146
-
147
- let globalSubscriptionId = 1;
148
-
149
446
  /**
150
447
  * A global context for managing event emission and subscription.
151
448
  *
@@ -153,7 +450,7 @@ let globalSubscriptionId = 1;
153
450
  * in a React application. It serves as a global event bus that components can subscribe to or emit events, allowing for
154
451
  * a loosely coupled architecture. Additionally, it provides a mechanism for invoking backend functions and managing
155
452
  * subscriptions, making it easier to integrate React components with backend services.
156
- *
453
+ *
157
454
  * The context includes several key functionalities:
158
455
  * - `state`: Maintains the current state of subscriptions and their identifiers.
159
456
  * - `dispatch`: Allows components to emit events with specific topics and payloads, which can be listened to by other components.
@@ -161,21 +458,21 @@ let globalSubscriptionId = 1;
161
458
  * - `unsubscribe`: Provides a way for components to stop listening to events, helping prevent memory leaks and unnecessary updates.
162
459
  * - `invoke`: Facilitates calling backend functions with specific arguments and handling their responses asynchronously.
163
460
  * - `getSubscriptions`: Offers insight into current active subscriptions, useful for debugging purposes.
164
- *
461
+ *
165
462
  * This context is essential for applications that require a high degree of inter-component communication or need to
166
463
  * interact with a backend efficiently.
167
- *
464
+ *
168
465
  * For more information, see [Additional Documentation](../additional-docs/GlobalEventEmitter.md).
169
- *
466
+ *
170
467
  * ## Usage
171
- *
468
+ *
172
469
  * The entire application should be wrapped in the EventEmitterProvider.
173
- *
470
+ *
174
471
  * App.tsx
175
472
  * ```
176
473
  * import { EventEmitterProvider } from "@adcops/autocore-react/core/EventEmitterContext.js";
177
474
  * function App() {
178
- *
475
+ *
179
476
  * return(
180
477
  * <EventEmitterProvider>
181
478
  * <PrimeReactProvider>
@@ -187,31 +484,31 @@ let globalSubscriptionId = 1;
187
484
  * </PrimeReactProvider>
188
485
  * </EventEmitterProvider>
189
486
  * );
190
- *
487
+ *
191
488
  * }
192
- *
489
+ *
193
490
  * ```
194
- *
491
+ *
195
492
  * ### Catching and receiving events
196
493
  * The EventEmitterContext creates an appropriate instance of the hub, which is derived from HubBase.
197
494
  * That hub can be used to publish and subscribe to
198
495
  * topics globally in the front-end, regardless of being connected to any backend.
199
496
  * Usage within a component is simple.
200
- *
497
+ *
201
498
  * ```
202
499
  * const {dispatch, subscribe, unsubscribe} = useContext(EventEmitterContext);
203
500
  * const [controlPower, setControlPower] = useState(false);
204
501
  * useEffect(() => {
205
502
  * const unsubscribeControlPower = subscribe('value-simulator-bBit1', (value) => {
206
503
  * setControlPower(value);
207
- * });
504
+ * });
208
505
  *
209
506
  *
210
507
  * return () => {
211
508
  * unsubscribe(unsubscribeControlPower);
212
509
  * }
213
510
  * }, [] );
214
- *
511
+ *
215
512
  * const onPbPressed = () => {
216
513
  * let count = 1;
217
514
  * dispatch({
@@ -219,30 +516,30 @@ let globalSubscriptionId = 1;
219
516
  * payload: count
220
517
  * });
221
518
  * }
222
- *
223
- * ```
519
+ *
520
+ * ```
224
521
  * The hub should also be used for invoking events in the backend.
225
522
  * This example will call the function "update_count" in the backend, passing
226
523
  * the expected argument "count". Details of the interaction between the Hub and
227
524
  * the backend will be handled by the appropriate HubBase sub-class, and should
228
525
  * be transparent to the front end.
229
- *
526
+ *
230
527
  * ```
231
528
  * const {invoke} = useContext(EventEmitterContext);
232
529
  * const incrementCount = () => {
233
530
  * count += 1;
234
- * invoke('update_count', {"count": count});
531
+ * invoke('update_count', {"count": count});
235
532
  * };
236
- *
533
+ *
237
534
  * Subscribing to a topic is simple. The type of value received is specific
238
535
  * to the topic.
239
- *
536
+ *
240
537
  * Example: Listen to an event 'xarm-position':
241
538
  * ```
242
539
  * const {subscribe, unsubscribe} = useContext(EventEmitterContext);
243
540
  * useEffect(() => {
244
541
  * const unsubscripeMp = subscribe('xarm-position', (value) => {
245
- * // The publisher sent a JSON object of 3D position values.
542
+ * // The publisher sent a JSON object of 3D position values.
246
543
  * setX(value.x);
247
544
  * setY(value.y);
248
545
  * setZ(value.z);
@@ -250,49 +547,55 @@ let globalSubscriptionId = 1;
250
547
  * setB(value.yaw);
251
548
  * setC(value.pitch);
252
549
  * });
253
- *
550
+ *
254
551
  * return () => {
255
552
  * unsubscribe(unsubscripeMp);
256
553
  * }
257
- *
554
+ *
258
555
  * }, [] );
259
556
  *
260
557
  * ```
261
- *
558
+ *
262
559
  * For applications that need to access the instance of the hub, get the current instance
263
560
  * from the EventEmitterContext:
264
- *
561
+ *
265
562
  * ```
266
563
  * const {hub} = useContext(EventEmitterContext);
267
564
  * * ```
268
- *
269
- *
565
+ *
566
+ *
270
567
  */
271
568
  export const EventEmitterContext = createContext<EventEmitterContextType>({
272
- state: { subscriptions: {}, nextSubscriptionId: 1 },
273
- dispatch: () => { },
274
- subscribe: () => { return 0; }, // Placeholder for subscription logic
275
- invoke: async (domain: string, fname: string, payload?: object) => {
276
- domain;
277
- fname;
278
- payload;
279
- let ret: CommandMessageResult = {
280
- data: {},
281
- success: false,
282
- error_message: ""
283
- };
284
- // Placeholder for invoke logic
285
- // Implement the logic to send a message to the backend and return a promise
286
- return Promise.resolve(ret); // Example placeholder, replace with actual implementation
287
- },
288
- unsubscribe: (subscriptionId: number) => { subscriptionId; }, // Placeholder for unsubscription logic
289
- hub: null,
290
- getSubscriptions: () => { return []; },
291
- isConnected: () => { return false }
292
-
569
+ state: { subscriptions: {}, nextSubscriptionId: 1 },
570
+ dispatch: () => {},
571
+ subscribe: () => {
572
+ return 0;
573
+ }, // Placeholder for subscription logic
574
+ invoke: async (domain: string, fname: string, payload?: object) => {
575
+ domain;
576
+ fname;
577
+ payload;
578
+ let ret: CommandMessageResult = {
579
+ data: {},
580
+ success: false,
581
+ error_message: "",
582
+ };
583
+ // Placeholder for invoke logic
584
+ // Implement the logic to send a message to the backend and return a promise
585
+ return Promise.resolve(ret); // Example placeholder, replace with actual implementation
586
+ },
587
+ unsubscribe: (subscriptionId: number) => {
588
+ subscriptionId;
589
+ }, // Placeholder for unsubscription logic
590
+ hub: null,
591
+ getSubscriptions: () => {
592
+ return [];
593
+ },
594
+ isConnected: () => {
595
+ return false;
596
+ },
293
597
  });
294
598
 
295
-
296
599
  /**
297
600
  * A React component that provides the EventEmitterContext to its children.
298
601
  *
@@ -300,16 +603,16 @@ export const EventEmitterContext = createContext<EventEmitterContextType>({
300
603
  * with the event emitter.
301
604
  *
302
605
  * @param children The child components to be wrapped in the context.
303
- *
606
+ *
304
607
  * ## Usage
305
- *
608
+ *
306
609
  * The entire application should be wrapped in the EventEmitterProvider.
307
- *
610
+ *
308
611
  * App.tsx
309
612
  * ```
310
613
  * import { EventEmitterProvider } from "@adcops/autocore-react/core/EventEmitterContext.js";
311
614
  * function App() {
312
- *
615
+ *
313
616
  * return(
314
617
  * <EventEmitterProvider>
315
618
  * <PrimeReactProvider>
@@ -321,89 +624,143 @@ export const EventEmitterContext = createContext<EventEmitterContextType>({
321
624
  * </PrimeReactProvider>
322
625
  * </EventEmitterProvider>
323
626
  * );
324
- *
627
+ *
325
628
  * }
326
- *
327
- * ```
629
+ *
630
+ * ```
328
631
  */
329
- export const EventEmitterProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
330
- const [state, setState] = useState<State>({ subscriptions: {}, nextSubscriptionId: 1 });
331
-
332
- // Memoize the hub instance so it's only created once
333
- const hub = useMemo(() => createHub(), []);
334
-
335
- const dispatch = useCallback((action: Action) => {
336
- const { topic, payload } = action;
337
-
338
- setState(prevState => {
339
- const callbacks = prevState.subscriptions[topic] || [];
340
- callbacks.forEach(sub => sub.callback(payload));
341
- return { ...prevState, eventData: payload };
342
- });
343
-
344
- }, []);
345
-
346
- const subscribe = useCallback((topic: string, callback: React.Dispatch<any>): number => {
347
-
348
- globalSubscriptionId += 1;
349
- const subscriptionId = globalSubscriptionId; // state.nextSubscriptionId;
350
-
351
- setState(prevState => ({
352
- ...prevState,
353
- subscriptions: {
354
- ...prevState.subscriptions,
355
- [topic]: [...(prevState.subscriptions[topic] || []), { id: subscriptionId, callback }]
356
- },
357
- nextSubscriptionId: globalSubscriptionId + 1 // prevState.nextSubscriptionId + 1
358
- }));
359
-
360
- return subscriptionId;
361
- }, []);
362
-
363
-
364
- const unsubscribe = useCallback((subscriptionId: number) => {
365
- setState(prevState => {
366
- const newSubscriptions = { ...prevState.subscriptions };
367
- Object.keys(newSubscriptions).forEach(topic => {
368
- newSubscriptions[topic] = newSubscriptions[topic].filter(sub => sub.id !== subscriptionId);
369
- if (newSubscriptions[topic].length === 0) {
370
- delete newSubscriptions[topic];
371
- }
372
- });
373
- return { ...prevState, subscriptions: newSubscriptions };
374
- });
375
- }, []);
376
-
377
-
378
- const getSubscriptions = useCallback((topic?: string): Record<string, Subscription[]> | Subscription[] => {
379
- if (topic) {
380
- // Return subscriptions for the provided topic, or an empty array if the topic doesn't exist
381
- return state.subscriptions[topic] || [];
382
- } else {
383
- // Return all subscriptions
384
- return state.subscriptions;
385
- }
386
- }, []);
387
-
388
- // Provide the memoized hub instance in the context value
389
- const contextValue = useMemo(() => ({
390
- state,
391
- dispatch,
392
- subscribe,
393
- unsubscribe,
394
- invoke: hub.invoke,
395
- hub,
396
- getSubscriptions,
397
- isConnected: hub.isConnected
398
- }), [state, hub]);
399
-
400
-
401
- hub.setContext(contextValue);
402
-
403
- return (
404
- <EventEmitterContext.Provider value={contextValue}>
405
- {children}
406
- </EventEmitterContext.Provider>
407
- );
408
-
409
- };
632
+ export const EventEmitterProvider: React.FC<{ children: ReactNode }> = ({
633
+ children,
634
+ }) => {
635
+ const [state, setState] = useState<State>({
636
+ subscriptions: {},
637
+ nextSubscriptionId: 1,
638
+ });
639
+
640
+ // Memoize the hub instance so it's only created once
641
+ const hub = useMemo(() => createHub(), []);
642
+
643
+ // Use ref for subscription ID management (avoids global state issues)
644
+ const nextIdRef = useRef(1);
645
+
646
+ // Subscription storage - this is the single source of truth
647
+ const subsRef = useRef<Record<string, Subscription[]>>({});
648
+
649
+ // Sync state with ref for debugging/inspection purposes only
650
+ useEffect(() => {
651
+ setState(prev => ({
652
+ ...prev,
653
+ subscriptions: { ...subsRef.current },
654
+ nextSubscriptionId: nextIdRef.current
655
+ }));
656
+ }, []);
657
+
658
+ const dispatch = useCallback((action: Action) => {
659
+ const { topic, payload } = action;
660
+
661
+ // Read from ref (single source of truth) and create a defensive copy
662
+ const listeners = subsRef.current[topic]?.slice() ?? [];
663
+
664
+ // Execute callbacks synchronously to avoid timing issues
665
+ for (const sub of listeners) {
666
+ try {
667
+ sub.callback(payload);
668
+ } catch (e) {
669
+ console.error("[EventBus] listener error", e);
670
+ }
671
+ }
672
+
673
+ // Update state for debugging/inspection (optional)
674
+ setState((prev) => ({ ...prev, eventData: payload }));
675
+ }, []);
676
+
677
+ const subscribe = useCallback(
678
+ (topic: string, callback: React.Dispatch<any>): number => {
679
+ const id = nextIdRef.current++;
680
+
681
+ // Create new subscription entry
682
+ const newSub: Subscription = { id, callback };
683
+
684
+ // Atomically update the ref with a complete new structure
685
+ const currentSubs = subsRef.current[topic] ?? [];
686
+ const newSubs = [...currentSubs, newSub];
687
+
688
+ subsRef.current = {
689
+ ...subsRef.current,
690
+ [topic]: newSubs
691
+ };
692
+
693
+ // Update state for debugging/inspection
694
+ setState(prevState => ({
695
+ ...prevState,
696
+ subscriptions: { ...subsRef.current },
697
+ nextSubscriptionId: nextIdRef.current,
698
+ }));
699
+
700
+ return id;
701
+ },
702
+ []
703
+ );
704
+
705
+ const unsubscribe = useCallback((subscriptionId: number) => {
706
+ // Create a completely new structure to avoid mutation issues
707
+ const newSubscriptions: Record<string, Subscription[]> = {};
708
+
709
+ for (const [topic, subs] of Object.entries(subsRef.current)) {
710
+ const filteredSubs = subs.filter(s => s.id !== subscriptionId);
711
+ if (filteredSubs.length > 0) {
712
+ newSubscriptions[topic] = filteredSubs;
713
+ }
714
+ // If no subscriptions left for this topic, don't include it
715
+ }
716
+
717
+ // Atomically replace the entire structure
718
+ subsRef.current = newSubscriptions;
719
+
720
+ // Update state for debugging/inspection
721
+ setState(prev => ({
722
+ ...prev,
723
+ subscriptions: { ...newSubscriptions }
724
+ }));
725
+ }, []);
726
+
727
+ // Clean up on unmount and handle HMR
728
+ useEffect(() => {
729
+ return () => {
730
+ subsRef.current = {};
731
+ nextIdRef.current = 1;
732
+ };
733
+ }, []);
734
+
735
+ // Handle HMR so listeners don't leak across hot updates
736
+ if (import.meta && (import.meta as any).hot) {
737
+ (import.meta as any).hot.dispose(() => {
738
+ subsRef.current = {};
739
+ nextIdRef.current = 1;
740
+ });
741
+ }
742
+
743
+ // Provide the memoized hub instance in the context value
744
+ const contextValue = useMemo(
745
+ () => ({
746
+ state,
747
+ dispatch,
748
+ subscribe,
749
+ unsubscribe,
750
+ invoke: hub.invoke,
751
+ hub,
752
+ getSubscriptions: (topic?: string) =>
753
+ topic ? subsRef.current[topic] ?? [] : subsRef.current,
754
+ isConnected: hub.isConnected,
755
+ }),
756
+ [state, hub, dispatch, subscribe, unsubscribe]
757
+ );
758
+
759
+ hub.setContext(contextValue);
760
+
761
+ return (
762
+ <EventEmitterContext.Provider value={contextValue}>
763
+ {children}
764
+ </EventEmitterContext.Provider>
765
+ );
766
+ };