@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.esm.js CHANGED
@@ -27564,7 +27564,7 @@ var STATUS = {
27564
27564
  * @returns {Object} WebSocket provider interface
27565
27565
  */
27566
27566
  var useWebSocketProvider = function useWebSocketProvider(providerType) {
27567
- var _app$providers;
27567
+ var _dashApi$api, _app$providers;
27568
27568
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
27569
27569
  var _options$autoConnect = options.autoConnect,
27570
27570
  autoConnect = _options$autoConnect === void 0 ? true : _options$autoConnect,
@@ -27611,6 +27611,10 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27611
27611
  var maxMessagesRef = useRef(maxMessages);
27612
27612
  maxMessagesRef.current = maxMessages;
27613
27613
  var dashApi = app === null || app === void 0 ? void 0 : app.dashApi;
27614
+ // Access the raw preload bridge (mainApi) for the webSocket sub-API.
27615
+ // dashApi is an ElectronDashboardApi wrapper; the webSocket methods
27616
+ // live on the underlying mainApi object (dashApi.api).
27617
+ var wsApi = dashApi === null || dashApi === void 0 || (_dashApi$api = dashApi.api) === null || _dashApi$api === void 0 ? void 0 : _dashApi$api.webSocket;
27614
27618
 
27615
27619
  // Get the widget data
27616
27620
  var widgetData = widgetContext === null || widgetContext === void 0 ? void 0 : widgetContext.widgetData;
@@ -27662,7 +27666,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27662
27666
  }
27663
27667
  return _context2.abrupt("return");
27664
27668
  case 1:
27665
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !provider)) {
27669
+ if (!(!wsApi || !provider)) {
27666
27670
  _context2.next = 2;
27667
27671
  break;
27668
27672
  }
@@ -27691,7 +27695,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27691
27695
  }
27692
27696
  _context2.prev = 5;
27693
27697
  _context2.next = 6;
27694
- return dashApi.webSocket.getStatus(selectedProviderName);
27698
+ return wsApi.getStatus(selectedProviderName);
27695
27699
  case 6:
27696
27700
  statusResult = _context2.sent;
27697
27701
  if (!((statusResult === null || statusResult === void 0 ? void 0 : statusResult.status) === "connected")) {
@@ -27768,7 +27772,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27768
27772
  case 0:
27769
27773
  _context.prev = 0;
27770
27774
  _context.next = 1;
27771
- return dashApi.webSocket.connect(selectedProviderName, {
27775
+ return wsApi.connect(selectedProviderName, {
27772
27776
  url: provider.wsConfig.url,
27773
27777
  headers: provider.wsConfig.headers || null,
27774
27778
  subprotocols: provider.wsConfig.subprotocols || null,
@@ -27848,7 +27852,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27848
27852
  return _context2.stop();
27849
27853
  }
27850
27854
  }, _callee2, null, [[5, 8], [10, 14], [18, 22]]);
27851
- })), [dashApi, provider, providerType, selectedProviderName, applyConnected]);
27855
+ })), [wsApi, provider, providerType, selectedProviderName, applyConnected]);
27852
27856
 
27853
27857
  /**
27854
27858
  * Disconnect from the WebSocket server.
@@ -27859,7 +27863,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27859
27863
  return _regeneratorRuntime.wrap(function (_context3) {
27860
27864
  while (1) switch (_context3.prev = _context3.next) {
27861
27865
  case 0:
27862
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
27866
+ if (!(!wsApi || !selectedProviderName)) {
27863
27867
  _context3.next = 1;
27864
27868
  break;
27865
27869
  }
@@ -27897,7 +27901,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27897
27901
  pendingConnects["delete"](selectedProviderName);
27898
27902
  _context3.prev = 4;
27899
27903
  _context3.next = 5;
27900
- return dashApi.webSocket.disconnect(selectedProviderName);
27904
+ return wsApi.disconnect(selectedProviderName);
27901
27905
  case 5:
27902
27906
  _context3.next = 7;
27903
27907
  break;
@@ -27909,7 +27913,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27909
27913
  return _context3.stop();
27910
27914
  }
27911
27915
  }, _callee3, null, [[4, 6]]);
27912
- })), [dashApi, selectedProviderName]);
27916
+ })), [wsApi, selectedProviderName]);
27913
27917
 
27914
27918
  /**
27915
27919
  * Send data through the WebSocket connection
@@ -27920,14 +27924,14 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27920
27924
  return _regeneratorRuntime.wrap(function (_context4) {
27921
27925
  while (1) switch (_context4.prev = _context4.next) {
27922
27926
  case 0:
27923
- if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
27927
+ if (!(!wsApi || !selectedProviderName)) {
27924
27928
  _context4.next = 1;
27925
27929
  break;
27926
27930
  }
27927
27931
  throw new Error("WebSocket not connected");
27928
27932
  case 1:
27929
27933
  _context4.next = 2;
27930
- return dashApi.webSocket.send(selectedProviderName, data);
27934
+ return wsApi.send(selectedProviderName, data);
27931
27935
  case 2:
27932
27936
  result = _context4.sent;
27933
27937
  if (!result.error) {
@@ -27946,7 +27950,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27946
27950
  return function (_x) {
27947
27951
  return _ref4.apply(this, arguments);
27948
27952
  };
27949
- }(), [dashApi, selectedProviderName]);
27953
+ }(), [wsApi, selectedProviderName]);
27950
27954
 
27951
27955
  // Keep a ref to connect so the auto-connect effect doesn't depend on it
27952
27956
  var connectRef = useRef(connect);
@@ -27954,7 +27958,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27954
27958
 
27955
27959
  // Listen for incoming messages from main process
27956
27960
  useEffect(function () {
27957
- if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
27961
+ if (!wsApi || !selectedProviderName) return;
27958
27962
  var handleMessage = function handleMessage(_event, payload) {
27959
27963
  if (payload.provider !== selectedProviderName) return;
27960
27964
  if (!mountedRef.current) return;
@@ -27969,15 +27973,15 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
27969
27973
  setMessages(next);
27970
27974
  setLastMessage(msg);
27971
27975
  };
27972
- dashApi.webSocket.onMessage(handleMessage);
27976
+ wsApi.onMessage(handleMessage);
27973
27977
  return function () {
27974
- return dashApi.webSocket.offMessage(handleMessage);
27978
+ return wsApi.offMessage(handleMessage);
27975
27979
  };
27976
- }, [dashApi, selectedProviderName]);
27980
+ }, [wsApi, selectedProviderName]);
27977
27981
 
27978
27982
  // Listen for status changes from main process
27979
27983
  useEffect(function () {
27980
- if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
27984
+ if (!wsApi || !selectedProviderName) return;
27981
27985
  var handleStatusChange = function handleStatusChange(_event, payload) {
27982
27986
  if (payload.provider !== selectedProviderName) return;
27983
27987
  if (!mountedRef.current) return;
@@ -28014,11 +28018,11 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28014
28018
  }
28015
28019
  }
28016
28020
  };
28017
- dashApi.webSocket.onStatusChange(handleStatusChange);
28021
+ wsApi.onStatusChange(handleStatusChange);
28018
28022
  return function () {
28019
- return dashApi.webSocket.offStatusChange(handleStatusChange);
28023
+ return wsApi.offStatusChange(handleStatusChange);
28020
28024
  };
28021
- }, [dashApi, selectedProviderName]);
28025
+ }, [wsApi, selectedProviderName]);
28022
28026
 
28023
28027
  // Auto-connect on mount or when provider selection changes
28024
28028
  useEffect(function () {
@@ -28035,7 +28039,7 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28035
28039
  mountedRef.current = false;
28036
28040
 
28037
28041
  // Decrement consumer count; only disconnect if last consumer
28038
- if (connectedRef.current && dashApi !== null && dashApi !== void 0 && dashApi.webSocket && selectedProviderName) {
28042
+ if (connectedRef.current && wsApi && selectedProviderName) {
28039
28043
  var state = connectionStates.get(selectedProviderName);
28040
28044
  if (state) {
28041
28045
  state.consumerCount = Math.max(0, state.consumerCount - 1);
@@ -28047,10 +28051,10 @@ var useWebSocketProvider = function useWebSocketProvider(providerType) {
28047
28051
  // Last consumer — disconnect
28048
28052
  connectionStates["delete"](selectedProviderName);
28049
28053
  }
28050
- dashApi.webSocket.disconnect(selectedProviderName)["catch"](function () {});
28054
+ wsApi.disconnect(selectedProviderName)["catch"](function () {});
28051
28055
  }
28052
28056
  };
28053
- }, [dashApi, selectedProviderName]);
28057
+ }, [wsApi, selectedProviderName]);
28054
28058
  return {
28055
28059
  isConnected: isConnected,
28056
28060
  isConnecting: isConnecting,
@@ -38594,6 +38598,16 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38594
38598
  _useState10 = _slicedToArray(_useState1, 2),
38595
38599
  errors = _useState10[0],
38596
38600
  setErrors = _useState10[1];
38601
+ var _useState11 = useState(false),
38602
+ _useState12 = _slicedToArray(_useState11, 2),
38603
+ isWsTesting = _useState12[0],
38604
+ setIsWsTesting = _useState12[1];
38605
+ var _useState13 = useState(null),
38606
+ _useState14 = _slicedToArray(_useState13, 2),
38607
+ wsTestResult = _useState14[0],
38608
+ setWsTestResult = _useState14[1];
38609
+ var appContext = useContext(AppContext);
38610
+ var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
38597
38611
  var nextRowIdRef = useRef(0);
38598
38612
  var nextRowId = function nextRowId() {
38599
38613
  return "ws_hdr_".concat(++nextRowIdRef.current);
@@ -38683,6 +38697,92 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38683
38697
  });
38684
38698
  });
38685
38699
  }
38700
+ function handleTestConnection() {
38701
+ return _handleTestConnection.apply(this, arguments);
38702
+ }
38703
+ function _handleTestConnection() {
38704
+ _handleTestConnection = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
38705
+ var headers, _iterator4, _step4, row, subprotoArray, testName, startTime, result, latency, _t;
38706
+ return _regeneratorRuntime.wrap(function (_context) {
38707
+ while (1) switch (_context.prev = _context.next) {
38708
+ case 0:
38709
+ if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !url.trim() || !isValidWsUrl(url))) {
38710
+ _context.next = 1;
38711
+ break;
38712
+ }
38713
+ return _context.abrupt("return");
38714
+ case 1:
38715
+ setIsWsTesting(true);
38716
+ setWsTestResult(null);
38717
+
38718
+ // Build config from current form state (same as handleSave)
38719
+ headers = {};
38720
+ _iterator4 = _createForOfIteratorHelper$4(headerRows);
38721
+ try {
38722
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
38723
+ row = _step4.value;
38724
+ if (row.key.trim()) {
38725
+ headers[row.key.trim()] = row.value;
38726
+ }
38727
+ }
38728
+ } catch (err) {
38729
+ _iterator4.e(err);
38730
+ } finally {
38731
+ _iterator4.f();
38732
+ }
38733
+ subprotoArray = subprotocols.split(",").map(function (s) {
38734
+ return s.trim();
38735
+ }).filter(Boolean);
38736
+ testName = name.trim() || "__ws_test__";
38737
+ startTime = Date.now();
38738
+ _context.prev = 2;
38739
+ _context.next = 3;
38740
+ return dashApi.webSocket.connect(testName, {
38741
+ url: url.trim(),
38742
+ headers: Object.keys(headers).length > 0 ? headers : null,
38743
+ subprotocols: subprotoArray.length > 0 ? subprotoArray : null,
38744
+ credentials: Object.keys(credentials).length > 0 ? credentials : null
38745
+ });
38746
+ case 3:
38747
+ result = _context.sent;
38748
+ latency = Date.now() - startTime;
38749
+ if (!result.error) {
38750
+ _context.next = 4;
38751
+ break;
38752
+ }
38753
+ setWsTestResult({
38754
+ success: false,
38755
+ message: result.message || "Connection failed"
38756
+ });
38757
+ _context.next = 5;
38758
+ break;
38759
+ case 4:
38760
+ setWsTestResult({
38761
+ success: true,
38762
+ message: "Connected in ".concat(latency, "ms")
38763
+ });
38764
+ _context.next = 5;
38765
+ return dashApi.webSocket.disconnect(testName)["catch"](function () {});
38766
+ case 5:
38767
+ _context.next = 7;
38768
+ break;
38769
+ case 6:
38770
+ _context.prev = 6;
38771
+ _t = _context["catch"](2);
38772
+ setWsTestResult({
38773
+ success: false,
38774
+ message: (_t === null || _t === void 0 ? void 0 : _t.message) || "Connection failed"
38775
+ });
38776
+ case 7:
38777
+ setIsWsTesting(false);
38778
+ case 8:
38779
+ case "end":
38780
+ return _context.stop();
38781
+ }
38782
+ }, _callee, null, [[2, 6]]);
38783
+ }));
38784
+ return _handleTestConnection.apply(this, arguments);
38785
+ }
38686
38786
  return /*#__PURE__*/jsxs("div", {
38687
38787
  className: "flex flex-col flex-1 min-h-0",
38688
38788
  children: [/*#__PURE__*/jsxs("div", {
@@ -38701,7 +38801,7 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38701
38801
  return setName(value);
38702
38802
  },
38703
38803
  placeholder: "e.g., crypto-ws, stock-feed",
38704
- error: !!errors.name
38804
+ inputClassName: errors.name ? "border-red-500" : ""
38705
38805
  }), errors.name && /*#__PURE__*/jsx("span", {
38706
38806
  className: "text-xs text-red-400",
38707
38807
  children: errors.name
@@ -38717,7 +38817,7 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38717
38817
  return setUrl(value);
38718
38818
  },
38719
38819
  placeholder: "wss://api.example.com/ws or ws://localhost:8080",
38720
- error: !!errors.url
38820
+ inputClassName: errors.url ? "border-red-500" : ""
38721
38821
  }), errors.url && /*#__PURE__*/jsx("span", {
38722
38822
  className: "text-xs text-red-400",
38723
38823
  children: errors.url
@@ -38825,17 +38925,32 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
38825
38925
  });
38826
38926
  },
38827
38927
  placeholder: "Enter ".concat(field),
38828
- error: !!errors["cred_".concat(field)]
38928
+ inputClassName: errors["cred_".concat(field)] ? "border-red-500" : ""
38829
38929
  }), errors["cred_".concat(field)] && /*#__PURE__*/jsx("span", {
38830
38930
  className: "text-xs text-red-400",
38831
38931
  children: errors["cred_".concat(field)]
38832
38932
  })]
38833
38933
  }, field);
38834
38934
  })]
38935
+ }), wsTestResult && /*#__PURE__*/jsx("div", {
38936
+ 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"),
38937
+ children: /*#__PURE__*/jsxs("div", {
38938
+ className: "flex items-center gap-2",
38939
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
38940
+ icon: wsTestResult.success ? "circle-check" : "circle-exclamation"
38941
+ }), /*#__PURE__*/jsx("span", {
38942
+ children: wsTestResult.message
38943
+ })]
38944
+ })
38835
38945
  })]
38836
38946
  }), /*#__PURE__*/jsxs("div", {
38837
38947
  className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
38838
- children: [/*#__PURE__*/jsx(Button, {
38948
+ children: [(dashApi === null || dashApi === void 0 ? void 0 : dashApi.webSocket) && /*#__PURE__*/jsx(Button, {
38949
+ title: isWsTesting ? "Testing..." : "Test Connection",
38950
+ onClick: handleTestConnection,
38951
+ size: "sm",
38952
+ disabled: !url.trim() || !isValidWsUrl(url)
38953
+ }), /*#__PURE__*/jsx(Button, {
38839
38954
  title: "Cancel",
38840
38955
  onClick: onCancel,
38841
38956
  size: "sm"