@trops/dash-core 0.1.181 → 0.1.183

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/dist/index.js CHANGED
@@ -27582,7 +27582,7 @@ var STATUS = {
27582
27582
  * @returns {Object} WebSocket provider interface
27583
27583
  */
27584
27584
  var useWebSocketProvider = function useWebSocketProvider(providerType) {
27585
- var _app$providers;
27585
+ var _dashApi$api, _app$providers;
27586
27586
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
27587
27587
  var _options$autoConnect = options.autoConnect,
27588
27588
  autoConnect = _options$autoConnect === void 0 ? true : _options$autoConnect,
@@ -27629,6 +27629,10 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27629
27629
  var maxMessagesRef = React.useRef(maxMessages);
27630
27630
  maxMessagesRef.current = maxMessages;
27631
27631
  var dashApi = app === null || app === void 0 ? void 0 : app.dashApi;
27632
+ // Access the raw preload bridge (mainApi) for the webSocket sub-API.
27633
+ // dashApi is an ElectronDashboardApi wrapper; the webSocket methods
27634
+ // live on the underlying mainApi object (dashApi.api).
27635
+ var wsApi = dashApi === null || dashApi === void 0 || (_dashApi$api = dashApi.api) === null || _dashApi$api === void 0 ? void 0 : _dashApi$api.webSocket;
27632
27636
 
27633
27637
  // Get the widget data
27634
27638
  var widgetData = widgetContext === null || widgetContext === void 0 ? void 0 : widgetContext.widgetData;
@@ -27680,7 +27684,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27680
27684
  }
27681
27685
  return _context2.abrupt("return");
27682
27686
  case 1:
27683
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !provider)) {
27687
+ if (!(!wsApi || !provider)) {
27684
27688
  _context2.next = 2;
27685
27689
  break;
27686
27690
  }
@@ -27709,7 +27713,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27709
27713
  }
27710
27714
  _context2.prev = 5;
27711
27715
  _context2.next = 6;
27712
- return dashApi.webSocket.getStatus(selectedProviderName);
27716
+ return wsApi.getStatus(selectedProviderName);
27713
27717
  case 6:
27714
27718
  statusResult = _context2.sent;
27715
27719
  if (!((statusResult === null || statusResult === void 0 ? void 0 : statusResult.status) === "connected")) {
@@ -27786,7 +27790,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27786
27790
  case 0:
27787
27791
  _context.prev = 0;
27788
27792
  _context.next = 1;
27789
- return dashApi.webSocket.connect(selectedProviderName, {
27793
+ return wsApi.connect(selectedProviderName, {
27790
27794
  url: provider.wsConfig.url,
27791
27795
  headers: provider.wsConfig.headers || null,
27792
27796
  subprotocols: provider.wsConfig.subprotocols || null,
@@ -27866,7 +27870,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27866
27870
  return _context2.stop();
27867
27871
  }
27868
27872
  }, _callee2, null, [[5, 8], [10, 14], [18, 22]]);
27869
- })), [dashApi, provider, providerType, selectedProviderName, applyConnected]);
27873
+ })), [wsApi, provider, providerType, selectedProviderName, applyConnected]);
27870
27874
 
27871
27875
  /**
27872
27876
  * Disconnect from the WebSocket server.
@@ -27877,7 +27881,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27877
27881
  return _regeneratorRuntime.wrap(function (_context3) {
27878
27882
  while (1) switch (_context3.prev = _context3.next) {
27879
27883
  case 0:
27880
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
27884
+ if (!(!wsApi || !selectedProviderName)) {
27881
27885
  _context3.next = 1;
27882
27886
  break;
27883
27887
  }
@@ -27915,7 +27919,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27915
27919
  pendingConnects["delete"](selectedProviderName);
27916
27920
  _context3.prev = 4;
27917
27921
  _context3.next = 5;
27918
- return dashApi.webSocket.disconnect(selectedProviderName);
27922
+ return wsApi.disconnect(selectedProviderName);
27919
27923
  case 5:
27920
27924
  _context3.next = 7;
27921
27925
  break;
@@ -27927,7 +27931,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27927
27931
  return _context3.stop();
27928
27932
  }
27929
27933
  }, _callee3, null, [[4, 6]]);
27930
- })), [dashApi, selectedProviderName]);
27934
+ })), [wsApi, selectedProviderName]);
27931
27935
 
27932
27936
  /**
27933
27937
  * Send data through the WebSocket connection
@@ -27938,14 +27942,14 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27938
27942
  return _regeneratorRuntime.wrap(function (_context4) {
27939
27943
  while (1) switch (_context4.prev = _context4.next) {
27940
27944
  case 0:
27941
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
27945
+ if (!(!wsApi || !selectedProviderName)) {
27942
27946
  _context4.next = 1;
27943
27947
  break;
27944
27948
  }
27945
27949
  throw new Error("WebSocket not connected");
27946
27950
  case 1:
27947
27951
  _context4.next = 2;
27948
- return dashApi.webSocket.send(selectedProviderName, data);
27952
+ return wsApi.send(selectedProviderName, data);
27949
27953
  case 2:
27950
27954
  result = _context4.sent;
27951
27955
  if (!result.error) {
@@ -27964,7 +27968,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27964
27968
  return function (_x) {
27965
27969
  return _ref4.apply(this, arguments);
27966
27970
  };
27967
- }(), [dashApi, selectedProviderName]);
27971
+ }(), [wsApi, selectedProviderName]);
27968
27972
 
27969
27973
  // Keep a ref to connect so the auto-connect effect doesn't depend on it
27970
27974
  var connectRef = React.useRef(connect);
@@ -27972,7 +27976,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27972
27976
 
27973
27977
  // Listen for incoming messages from main process
27974
27978
  React.useEffect(function () {
27975
- if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
27979
+ if (!wsApi || !selectedProviderName) return;
27976
27980
  var handleMessage = function handleMessage(_event, payload) {
27977
27981
  if (payload.provider !== selectedProviderName) return;
27978
27982
  if (!mountedRef.current) return;
@@ -27987,15 +27991,15 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27987
27991
  setMessages(next);
27988
27992
  setLastMessage(msg);
27989
27993
  };
27990
- dashApi.webSocket.onMessage(handleMessage);
27994
+ wsApi.onMessage(handleMessage);
27991
27995
  return function () {
27992
- return dashApi.webSocket.offMessage(handleMessage);
27996
+ return wsApi.offMessage(handleMessage);
27993
27997
  };
27994
- }, [dashApi, selectedProviderName]);
27998
+ }, [wsApi, selectedProviderName]);
27995
27999
 
27996
28000
  // Listen for status changes from main process
27997
28001
  React.useEffect(function () {
27998
- if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
28002
+ if (!wsApi || !selectedProviderName) return;
27999
28003
  var handleStatusChange = function handleStatusChange(_event, payload) {
28000
28004
  if (payload.provider !== selectedProviderName) return;
28001
28005
  if (!mountedRef.current) return;
@@ -28032,11 +28036,11 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28032
28036
  }
28033
28037
  }
28034
28038
  };
28035
- dashApi.webSocket.onStatusChange(handleStatusChange);
28039
+ wsApi.onStatusChange(handleStatusChange);
28036
28040
  return function () {
28037
- return dashApi.webSocket.offStatusChange(handleStatusChange);
28041
+ return wsApi.offStatusChange(handleStatusChange);
28038
28042
  };
28039
- }, [dashApi, selectedProviderName]);
28043
+ }, [wsApi, selectedProviderName]);
28040
28044
 
28041
28045
  // Auto-connect on mount or when provider selection changes
28042
28046
  React.useEffect(function () {
@@ -28053,7 +28057,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28053
28057
  mountedRef.current = false;
28054
28058
 
28055
28059
  // Decrement consumer count; only disconnect if last consumer
28056
- if (connectedRef.current && dashApi !== null && dashApi !== void 0 && dashApi.webSocket && selectedProviderName) {
28060
+ if (connectedRef.current && wsApi && selectedProviderName) {
28057
28061
  var state = connectionStates.get(selectedProviderName);
28058
28062
  if (state) {
28059
28063
  state.consumerCount = Math.max(0, state.consumerCount - 1);
@@ -28065,10 +28069,10 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28065
28069
  // Last consumer — disconnect
28066
28070
  connectionStates["delete"](selectedProviderName);
28067
28071
  }
28068
- dashApi.webSocket.disconnect(selectedProviderName)["catch"](function () {});
28072
+ wsApi.disconnect(selectedProviderName)["catch"](function () {});
28069
28073
  }
28070
28074
  };
28071
- }, [dashApi, selectedProviderName]);
28075
+ }, [wsApi, selectedProviderName]);
28072
28076
  return {
28073
28077
  isConnected: isConnected,
28074
28078
  isConnecting: isConnecting,
@@ -38612,6 +38616,16 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38612
38616
  _useState10 = _slicedToArray(_useState1, 2),
38613
38617
  errors = _useState10[0],
38614
38618
  setErrors = _useState10[1];
38619
+ var _useState11 = React.useState(false),
38620
+ _useState12 = _slicedToArray(_useState11, 2),
38621
+ isWsTesting = _useState12[0],
38622
+ setIsWsTesting = _useState12[1];
38623
+ var _useState13 = React.useState(null),
38624
+ _useState14 = _slicedToArray(_useState13, 2),
38625
+ wsTestResult = _useState14[0],
38626
+ setWsTestResult = _useState14[1];
38627
+ var appContext = React.useContext(AppContext);
38628
+ var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
38615
38629
  var nextRowIdRef = React.useRef(0);
38616
38630
  var nextRowId = function nextRowId() {
38617
38631
  return "ws_hdr_".concat(++nextRowIdRef.current);
@@ -38701,6 +38715,92 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38701
38715
  });
38702
38716
  });
38703
38717
  }
38718
+ function handleTestConnection() {
38719
+ return _handleTestConnection.apply(this, arguments);
38720
+ }
38721
+ function _handleTestConnection() {
38722
+ _handleTestConnection = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
38723
+ var headers, _iterator4, _step4, row, subprotoArray, testName, startTime, result, latency, _t;
38724
+ return _regeneratorRuntime.wrap(function (_context) {
38725
+ while (1) switch (_context.prev = _context.next) {
38726
+ case 0:
38727
+ if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !url.trim() || !isValidWsUrl(url))) {
38728
+ _context.next = 1;
38729
+ break;
38730
+ }
38731
+ return _context.abrupt("return");
38732
+ case 1:
38733
+ setIsWsTesting(true);
38734
+ setWsTestResult(null);
38735
+
38736
+ // Build config from current form state (same as handleSave)
38737
+ headers = {};
38738
+ _iterator4 = _createForOfIteratorHelper$4(headerRows);
38739
+ try {
38740
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
38741
+ row = _step4.value;
38742
+ if (row.key.trim()) {
38743
+ headers[row.key.trim()] = row.value;
38744
+ }
38745
+ }
38746
+ } catch (err) {
38747
+ _iterator4.e(err);
38748
+ } finally {
38749
+ _iterator4.f();
38750
+ }
38751
+ subprotoArray = subprotocols.split(",").map(function (s) {
38752
+ return s.trim();
38753
+ }).filter(Boolean);
38754
+ testName = name.trim() || "__ws_test__";
38755
+ startTime = Date.now();
38756
+ _context.prev = 2;
38757
+ _context.next = 3;
38758
+ return dashApi.webSocket.connect(testName, {
38759
+ url: url.trim(),
38760
+ headers: Object.keys(headers).length > 0 ? headers : null,
38761
+ subprotocols: subprotoArray.length > 0 ? subprotoArray : null,
38762
+ credentials: Object.keys(credentials).length > 0 ? credentials : null
38763
+ });
38764
+ case 3:
38765
+ result = _context.sent;
38766
+ latency = Date.now() - startTime;
38767
+ if (!result.error) {
38768
+ _context.next = 4;
38769
+ break;
38770
+ }
38771
+ setWsTestResult({
38772
+ success: false,
38773
+ message: result.message || "Connection failed"
38774
+ });
38775
+ _context.next = 5;
38776
+ break;
38777
+ case 4:
38778
+ setWsTestResult({
38779
+ success: true,
38780
+ message: "Connected in ".concat(latency, "ms")
38781
+ });
38782
+ _context.next = 5;
38783
+ return dashApi.webSocket.disconnect(testName)["catch"](function () {});
38784
+ case 5:
38785
+ _context.next = 7;
38786
+ break;
38787
+ case 6:
38788
+ _context.prev = 6;
38789
+ _t = _context["catch"](2);
38790
+ setWsTestResult({
38791
+ success: false,
38792
+ message: (_t === null || _t === void 0 ? void 0 : _t.message) || "Connection failed"
38793
+ });
38794
+ case 7:
38795
+ setIsWsTesting(false);
38796
+ case 8:
38797
+ case "end":
38798
+ return _context.stop();
38799
+ }
38800
+ }, _callee, null, [[2, 6]]);
38801
+ }));
38802
+ return _handleTestConnection.apply(this, arguments);
38803
+ }
38704
38804
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
38705
38805
  className: "flex flex-col flex-1 min-h-0",
38706
38806
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -38719,7 +38819,7 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38719
38819
  return setName(value);
38720
38820
  },
38721
38821
  placeholder: "e.g., crypto-ws, stock-feed",
38722
- error: !!errors.name
38822
+ inputClassName: errors.name ? "border-red-500" : ""
38723
38823
  }), errors.name && /*#__PURE__*/jsxRuntime.jsx("span", {
38724
38824
  className: "text-xs text-red-400",
38725
38825
  children: errors.name
@@ -38735,7 +38835,7 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38735
38835
  return setUrl(value);
38736
38836
  },
38737
38837
  placeholder: "wss://api.example.com/ws or ws://localhost:8080",
38738
- error: !!errors.url
38838
+ inputClassName: errors.url ? "border-red-500" : ""
38739
38839
  }), errors.url && /*#__PURE__*/jsxRuntime.jsx("span", {
38740
38840
  className: "text-xs text-red-400",
38741
38841
  children: errors.url
@@ -38843,17 +38943,32 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38843
38943
  });
38844
38944
  },
38845
38945
  placeholder: "Enter ".concat(field),
38846
- error: !!errors["cred_".concat(field)]
38946
+ inputClassName: errors["cred_".concat(field)] ? "border-red-500" : ""
38847
38947
  }), errors["cred_".concat(field)] && /*#__PURE__*/jsxRuntime.jsx("span", {
38848
38948
  className: "text-xs text-red-400",
38849
38949
  children: errors["cred_".concat(field)]
38850
38950
  })]
38851
38951
  }, field);
38852
38952
  })]
38953
+ }), wsTestResult && /*#__PURE__*/jsxRuntime.jsx("div", {
38954
+ className: "p-3 rounded-lg text-sm ".concat(wsTestResult.success ? "bg-green-900/30 border border-green-700 text-green-300" : "bg-red-900/30 border border-red-700 text-red-300"),
38955
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
38956
+ className: "flex items-center gap-2",
38957
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
38958
+ icon: wsTestResult.success ? "circle-check" : "circle-exclamation"
38959
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
38960
+ children: wsTestResult.message
38961
+ })]
38962
+ })
38853
38963
  })]
38854
38964
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
38855
38965
  className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
38856
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
38966
+ children: [(dashApi === null || dashApi === void 0 ? void 0 : dashApi.webSocket) && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
38967
+ title: isWsTesting ? "Testing..." : "Test Connection",
38968
+ onClick: handleTestConnection,
38969
+ size: "sm",
38970
+ disabled: !url.trim() || !isValidWsUrl(url)
38971
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
38857
38972
  title: "Cancel",
38858
38973
  onClick: onCancel,
38859
38974
  size: "sm"