@trops/dash-core 0.1.159 → 0.1.160
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 +530 -8
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +530 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26713,7 +26713,7 @@ var useWidgetProviders = function useWidgetProviders() {
|
|
|
26713
26713
|
var serverStates = new Map();
|
|
26714
26714
|
// Map<serverName, { status, tools, resources, consumerCount }>
|
|
26715
26715
|
|
|
26716
|
-
var pendingConnects = new Map();
|
|
26716
|
+
var pendingConnects$1 = new Map();
|
|
26717
26717
|
// Map<serverName, Promise<result>>
|
|
26718
26718
|
|
|
26719
26719
|
/**
|
|
@@ -26928,13 +26928,13 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
26928
26928
|
setError(null);
|
|
26929
26929
|
|
|
26930
26930
|
// 2. Another hook instance already connecting? Piggyback on its promise
|
|
26931
|
-
if (!pendingConnects.has(selectedProviderName)) {
|
|
26931
|
+
if (!pendingConnects$1.has(selectedProviderName)) {
|
|
26932
26932
|
_context.next = 17;
|
|
26933
26933
|
break;
|
|
26934
26934
|
}
|
|
26935
26935
|
_context.prev = 10;
|
|
26936
26936
|
_context.next = 11;
|
|
26937
|
-
return pendingConnects.get(selectedProviderName);
|
|
26937
|
+
return pendingConnects$1.get(selectedProviderName);
|
|
26938
26938
|
case 11:
|
|
26939
26939
|
result = _context.sent;
|
|
26940
26940
|
if (mountedRef.current) {
|
|
@@ -26976,7 +26976,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
26976
26976
|
// 3. First caller — fire the IPC call and share the promise
|
|
26977
26977
|
connectPromise = new Promise(function (resolve, reject) {
|
|
26978
26978
|
dashApi.mcpStartServer(selectedProviderName, provider.mcpConfig, provider.credentials, function (event, result) {
|
|
26979
|
-
pendingConnects["delete"](selectedProviderName);
|
|
26979
|
+
pendingConnects$1["delete"](selectedProviderName);
|
|
26980
26980
|
if (result.error) {
|
|
26981
26981
|
serverStates.set(selectedProviderName, {
|
|
26982
26982
|
status: "error",
|
|
@@ -26997,7 +26997,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
26997
26997
|
});
|
|
26998
26998
|
resolve(result);
|
|
26999
26999
|
}, function (event, err) {
|
|
27000
|
-
pendingConnects["delete"](selectedProviderName);
|
|
27000
|
+
pendingConnects$1["delete"](selectedProviderName);
|
|
27001
27001
|
serverStates.set(selectedProviderName, {
|
|
27002
27002
|
status: "error",
|
|
27003
27003
|
tools: [],
|
|
@@ -27007,7 +27007,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
27007
27007
|
reject(err);
|
|
27008
27008
|
});
|
|
27009
27009
|
});
|
|
27010
|
-
pendingConnects.set(selectedProviderName, connectPromise);
|
|
27010
|
+
pendingConnects$1.set(selectedProviderName, connectPromise);
|
|
27011
27011
|
_context.prev = 18;
|
|
27012
27012
|
_context.next = 19;
|
|
27013
27013
|
return connectPromise;
|
|
@@ -27093,7 +27093,7 @@ var useMcpProvider = function useMcpProvider(providerType) {
|
|
|
27093
27093
|
setResources([]);
|
|
27094
27094
|
setStatus("disconnected");
|
|
27095
27095
|
connectedRef.current = false;
|
|
27096
|
-
pendingConnects["delete"](selectedProviderName);
|
|
27096
|
+
pendingConnects$1["delete"](selectedProviderName);
|
|
27097
27097
|
return _context2.abrupt("return", new Promise(function (resolve) {
|
|
27098
27098
|
dashApi.mcpStopServer(selectedProviderName, function () {
|
|
27099
27099
|
return resolve();
|
|
@@ -27535,6 +27535,528 @@ var useScheduler = function useScheduler() {
|
|
|
27535
27535
|
};
|
|
27536
27536
|
};
|
|
27537
27537
|
|
|
27538
|
+
/**
|
|
27539
|
+
* Module-level shared state for WebSocket connections.
|
|
27540
|
+
* Prevents multiple hook instances (e.g., 4 widgets using the same WS provider)
|
|
27541
|
+
* from each firing their own IPC connect call.
|
|
27542
|
+
*
|
|
27543
|
+
* connectionStates: tracks connection status + consumer reference count per provider
|
|
27544
|
+
* pendingConnects: deduplicates in-flight IPC calls so only 1 fires per provider
|
|
27545
|
+
*/
|
|
27546
|
+
var connectionStates = new Map();
|
|
27547
|
+
// Map<providerName, { status, consumerCount }>
|
|
27548
|
+
|
|
27549
|
+
var pendingConnects = new Map();
|
|
27550
|
+
// Map<providerName, Promise<result>>
|
|
27551
|
+
|
|
27552
|
+
var STATUS = {
|
|
27553
|
+
DISCONNECTED: "disconnected",
|
|
27554
|
+
CONNECTING: "connecting",
|
|
27555
|
+
CONNECTED: "connected",
|
|
27556
|
+
ERROR: "error"
|
|
27557
|
+
};
|
|
27558
|
+
|
|
27559
|
+
/**
|
|
27560
|
+
* useWebSocketProvider Hook
|
|
27561
|
+
*
|
|
27562
|
+
* Provides access to a WebSocket connection for a widget.
|
|
27563
|
+
* Handles connection lifecycle, shared-connection ref counting,
|
|
27564
|
+
* message buffering, and bidirectional communication.
|
|
27565
|
+
*
|
|
27566
|
+
* Mirrors useMcpProvider.js patterns exactly:
|
|
27567
|
+
* - Module-level Maps (not component state) for connection sharing
|
|
27568
|
+
* - consumerCount determines socket lifecycle
|
|
27569
|
+
* - pendingConnects prevents duplicate connect calls during mount storms
|
|
27570
|
+
*
|
|
27571
|
+
* @param {string} providerType - The WebSocket provider type (e.g., "crypto-ws")
|
|
27572
|
+
* @param {Object} options - Optional configuration
|
|
27573
|
+
* @param {boolean} options.autoConnect - Whether to auto-connect on mount (default: true)
|
|
27574
|
+
* @param {number} options.maxMessages - Max messages in buffer (default: 100)
|
|
27575
|
+
*
|
|
27576
|
+
* @returns {Object} WebSocket provider interface
|
|
27577
|
+
*/
|
|
27578
|
+
var useWebSocketProvider = function useWebSocketProvider(providerType) {
|
|
27579
|
+
var _app$providers;
|
|
27580
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
27581
|
+
var _options$autoConnect = options.autoConnect,
|
|
27582
|
+
autoConnect = _options$autoConnect === void 0 ? true : _options$autoConnect,
|
|
27583
|
+
_options$maxMessages = options.maxMessages,
|
|
27584
|
+
maxMessages = _options$maxMessages === void 0 ? 100 : _options$maxMessages;
|
|
27585
|
+
var app = React.useContext(AppContext);
|
|
27586
|
+
var workspace = React.useContext(WorkspaceContext);
|
|
27587
|
+
var widgetContext = React.useContext(WidgetContext);
|
|
27588
|
+
var _useState = React.useState(false),
|
|
27589
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
27590
|
+
isConnected = _useState2[0],
|
|
27591
|
+
setIsConnected = _useState2[1];
|
|
27592
|
+
var _useState3 = React.useState(false),
|
|
27593
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
27594
|
+
isConnecting = _useState4[0],
|
|
27595
|
+
setIsConnecting = _useState4[1];
|
|
27596
|
+
var _useState5 = React.useState(null),
|
|
27597
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
27598
|
+
error = _useState6[0],
|
|
27599
|
+
setError = _useState6[1];
|
|
27600
|
+
var _useState7 = React.useState(null),
|
|
27601
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
27602
|
+
lastMessage = _useState8[0],
|
|
27603
|
+
setLastMessage = _useState8[1];
|
|
27604
|
+
var _useState9 = React.useState([]),
|
|
27605
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
27606
|
+
messages = _useState0[0],
|
|
27607
|
+
setMessages = _useState0[1];
|
|
27608
|
+
var _useState1 = React.useState(STATUS.DISCONNECTED),
|
|
27609
|
+
_useState10 = _slicedToArray(_useState1, 2),
|
|
27610
|
+
status = _useState10[0],
|
|
27611
|
+
setStatus = _useState10[1];
|
|
27612
|
+
var connectedRef = React.useRef(false);
|
|
27613
|
+
var mountedRef = React.useRef(true);
|
|
27614
|
+
var messagesRef = React.useRef([]);
|
|
27615
|
+
var maxMessagesRef = React.useRef(maxMessages);
|
|
27616
|
+
maxMessagesRef.current = maxMessages;
|
|
27617
|
+
var dashApi = app === null || app === void 0 ? void 0 : app.dashApi;
|
|
27618
|
+
|
|
27619
|
+
// Get the widget data
|
|
27620
|
+
var widgetData = widgetContext === null || widgetContext === void 0 ? void 0 : widgetContext.widgetData;
|
|
27621
|
+
|
|
27622
|
+
// Get the selected WebSocket provider for this widget
|
|
27623
|
+
// Same two-layer lookup as useMcpProvider:
|
|
27624
|
+
// 1. Widget-level: stored directly on the layout item
|
|
27625
|
+
// 2. Workspace-level: stored as workspace.selectedProviders[widgetId][providerType]
|
|
27626
|
+
var widgetId = widgetData === null || widgetData === void 0 ? void 0 : widgetData.uuidString;
|
|
27627
|
+
var selectedProviderName = function (_widgetData$selectedP, _workspace$workspaceD) {
|
|
27628
|
+
if (widgetData !== null && widgetData !== void 0 && (_widgetData$selectedP = widgetData.selectedProviders) !== null && _widgetData$selectedP !== void 0 && _widgetData$selectedP[providerType]) {
|
|
27629
|
+
return widgetData.selectedProviders[providerType];
|
|
27630
|
+
}
|
|
27631
|
+
if (widgetId && workspace !== null && workspace !== void 0 && (_workspace$workspaceD = workspace.workspaceData) !== null && _workspace$workspaceD !== void 0 && (_workspace$workspaceD = _workspace$workspaceD.selectedProviders) !== null && _workspace$workspaceD !== void 0 && (_workspace$workspaceD = _workspace$workspaceD[widgetId]) !== null && _workspace$workspaceD !== void 0 && _workspace$workspaceD[providerType]) {
|
|
27632
|
+
return workspace.workspaceData.selectedProviders[widgetId][providerType];
|
|
27633
|
+
}
|
|
27634
|
+
return null;
|
|
27635
|
+
}();
|
|
27636
|
+
|
|
27637
|
+
// Get the provider data (including credentials)
|
|
27638
|
+
// Read from AppContext.providers (not DashboardContext)
|
|
27639
|
+
var provider = selectedProviderName ? app === null || app === void 0 || (_app$providers = app.providers) === null || _app$providers === void 0 ? void 0 : _app$providers[selectedProviderName] : null;
|
|
27640
|
+
|
|
27641
|
+
/**
|
|
27642
|
+
* Apply connection result to this hook instance's local state.
|
|
27643
|
+
*/
|
|
27644
|
+
var applyConnected = React.useCallback(function () {
|
|
27645
|
+
if (!mountedRef.current) return;
|
|
27646
|
+
setIsConnected(true);
|
|
27647
|
+
setIsConnecting(false);
|
|
27648
|
+
setStatus(STATUS.CONNECTED);
|
|
27649
|
+
connectedRef.current = true;
|
|
27650
|
+
}, []);
|
|
27651
|
+
|
|
27652
|
+
/**
|
|
27653
|
+
* Connect to the WebSocket server.
|
|
27654
|
+
* Uses module-level deduplication so only one IPC call fires per provider,
|
|
27655
|
+
* even when multiple hook instances call connect() simultaneously.
|
|
27656
|
+
*/
|
|
27657
|
+
var connect = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
27658
|
+
var _provider$wsConfig;
|
|
27659
|
+
var cached, statusResult, result, state, connectPromise, _result2, _t3, _t4;
|
|
27660
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
27661
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
27662
|
+
case 0:
|
|
27663
|
+
if (!connectedRef.current) {
|
|
27664
|
+
_context2.next = 1;
|
|
27665
|
+
break;
|
|
27666
|
+
}
|
|
27667
|
+
return _context2.abrupt("return");
|
|
27668
|
+
case 1:
|
|
27669
|
+
if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !provider)) {
|
|
27670
|
+
_context2.next = 2;
|
|
27671
|
+
break;
|
|
27672
|
+
}
|
|
27673
|
+
setError(!provider ? "No ".concat(providerType, " WebSocket provider selected for this widget") : "Dashboard API not available");
|
|
27674
|
+
return _context2.abrupt("return");
|
|
27675
|
+
case 2:
|
|
27676
|
+
if (!(provider.providerClass !== "websocket")) {
|
|
27677
|
+
_context2.next = 3;
|
|
27678
|
+
break;
|
|
27679
|
+
}
|
|
27680
|
+
setError("Provider \"".concat(selectedProviderName, "\" is not a WebSocket provider"));
|
|
27681
|
+
return _context2.abrupt("return");
|
|
27682
|
+
case 3:
|
|
27683
|
+
if ((_provider$wsConfig = provider.wsConfig) !== null && _provider$wsConfig !== void 0 && _provider$wsConfig.url) {
|
|
27684
|
+
_context2.next = 4;
|
|
27685
|
+
break;
|
|
27686
|
+
}
|
|
27687
|
+
setError("Provider \"".concat(selectedProviderName, "\" has no WebSocket URL configured"));
|
|
27688
|
+
return _context2.abrupt("return");
|
|
27689
|
+
case 4:
|
|
27690
|
+
// 1. Already connected at module level? Verify with main process.
|
|
27691
|
+
cached = connectionStates.get(selectedProviderName);
|
|
27692
|
+
if (!(cached && cached.status === STATUS.CONNECTED)) {
|
|
27693
|
+
_context2.next = 9;
|
|
27694
|
+
break;
|
|
27695
|
+
}
|
|
27696
|
+
_context2.prev = 5;
|
|
27697
|
+
_context2.next = 6;
|
|
27698
|
+
return dashApi.webSocket.getStatus(selectedProviderName);
|
|
27699
|
+
case 6:
|
|
27700
|
+
statusResult = _context2.sent;
|
|
27701
|
+
if (!((statusResult === null || statusResult === void 0 ? void 0 : statusResult.status) === "connected")) {
|
|
27702
|
+
_context2.next = 7;
|
|
27703
|
+
break;
|
|
27704
|
+
}
|
|
27705
|
+
cached.consumerCount++;
|
|
27706
|
+
applyConnected();
|
|
27707
|
+
return _context2.abrupt("return");
|
|
27708
|
+
case 7:
|
|
27709
|
+
// Server was stopped externally — clear stale cache and reconnect
|
|
27710
|
+
connectionStates["delete"](selectedProviderName);
|
|
27711
|
+
_context2.next = 9;
|
|
27712
|
+
break;
|
|
27713
|
+
case 8:
|
|
27714
|
+
_context2.prev = 8;
|
|
27715
|
+
_context2["catch"](5);
|
|
27716
|
+
connectionStates["delete"](selectedProviderName);
|
|
27717
|
+
case 9:
|
|
27718
|
+
setIsConnecting(true);
|
|
27719
|
+
setError(null);
|
|
27720
|
+
setStatus(STATUS.CONNECTING);
|
|
27721
|
+
|
|
27722
|
+
// 2. Another hook instance already connecting? Piggyback on its promise
|
|
27723
|
+
if (!pendingConnects.has(selectedProviderName)) {
|
|
27724
|
+
_context2.next = 17;
|
|
27725
|
+
break;
|
|
27726
|
+
}
|
|
27727
|
+
_context2.prev = 10;
|
|
27728
|
+
_context2.next = 11;
|
|
27729
|
+
return pendingConnects.get(selectedProviderName);
|
|
27730
|
+
case 11:
|
|
27731
|
+
result = _context2.sent;
|
|
27732
|
+
if (mountedRef.current) {
|
|
27733
|
+
_context2.next = 12;
|
|
27734
|
+
break;
|
|
27735
|
+
}
|
|
27736
|
+
return _context2.abrupt("return");
|
|
27737
|
+
case 12:
|
|
27738
|
+
if (!result.error) {
|
|
27739
|
+
_context2.next = 13;
|
|
27740
|
+
break;
|
|
27741
|
+
}
|
|
27742
|
+
setError(result.message);
|
|
27743
|
+
setIsConnecting(false);
|
|
27744
|
+
setStatus(STATUS.ERROR);
|
|
27745
|
+
return _context2.abrupt("return");
|
|
27746
|
+
case 13:
|
|
27747
|
+
state = connectionStates.get(selectedProviderName);
|
|
27748
|
+
if (state) state.consumerCount++;
|
|
27749
|
+
applyConnected();
|
|
27750
|
+
_context2.next = 16;
|
|
27751
|
+
break;
|
|
27752
|
+
case 14:
|
|
27753
|
+
_context2.prev = 14;
|
|
27754
|
+
_t3 = _context2["catch"](10);
|
|
27755
|
+
if (mountedRef.current) {
|
|
27756
|
+
_context2.next = 15;
|
|
27757
|
+
break;
|
|
27758
|
+
}
|
|
27759
|
+
return _context2.abrupt("return");
|
|
27760
|
+
case 15:
|
|
27761
|
+
setError((_t3 === null || _t3 === void 0 ? void 0 : _t3.message) || "Failed to connect to WebSocket server");
|
|
27762
|
+
setIsConnecting(false);
|
|
27763
|
+
setStatus(STATUS.ERROR);
|
|
27764
|
+
case 16:
|
|
27765
|
+
return _context2.abrupt("return");
|
|
27766
|
+
case 17:
|
|
27767
|
+
// 3. First caller — fire the IPC call and share the promise
|
|
27768
|
+
connectPromise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
27769
|
+
var _result, _t;
|
|
27770
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
27771
|
+
while (1) switch (_context.prev = _context.next) {
|
|
27772
|
+
case 0:
|
|
27773
|
+
_context.prev = 0;
|
|
27774
|
+
_context.next = 1;
|
|
27775
|
+
return dashApi.webSocket.connect(selectedProviderName, {
|
|
27776
|
+
url: provider.wsConfig.url,
|
|
27777
|
+
headers: provider.wsConfig.headers || null,
|
|
27778
|
+
subprotocols: provider.wsConfig.subprotocols || null,
|
|
27779
|
+
credentials: provider.credentials || null
|
|
27780
|
+
});
|
|
27781
|
+
case 1:
|
|
27782
|
+
_result = _context.sent;
|
|
27783
|
+
pendingConnects["delete"](selectedProviderName);
|
|
27784
|
+
if (!_result.error) {
|
|
27785
|
+
_context.next = 2;
|
|
27786
|
+
break;
|
|
27787
|
+
}
|
|
27788
|
+
connectionStates.set(selectedProviderName, {
|
|
27789
|
+
status: STATUS.ERROR,
|
|
27790
|
+
consumerCount: 0
|
|
27791
|
+
});
|
|
27792
|
+
return _context.abrupt("return", _result);
|
|
27793
|
+
case 2:
|
|
27794
|
+
connectionStates.set(selectedProviderName, {
|
|
27795
|
+
status: STATUS.CONNECTED,
|
|
27796
|
+
consumerCount: 1
|
|
27797
|
+
});
|
|
27798
|
+
return _context.abrupt("return", _result);
|
|
27799
|
+
case 3:
|
|
27800
|
+
_context.prev = 3;
|
|
27801
|
+
_t = _context["catch"](0);
|
|
27802
|
+
pendingConnects["delete"](selectedProviderName);
|
|
27803
|
+
connectionStates.set(selectedProviderName, {
|
|
27804
|
+
status: STATUS.ERROR,
|
|
27805
|
+
consumerCount: 0
|
|
27806
|
+
});
|
|
27807
|
+
throw _t;
|
|
27808
|
+
case 4:
|
|
27809
|
+
case "end":
|
|
27810
|
+
return _context.stop();
|
|
27811
|
+
}
|
|
27812
|
+
}, _callee, null, [[0, 3]]);
|
|
27813
|
+
}))();
|
|
27814
|
+
pendingConnects.set(selectedProviderName, connectPromise);
|
|
27815
|
+
_context2.prev = 18;
|
|
27816
|
+
_context2.next = 19;
|
|
27817
|
+
return connectPromise;
|
|
27818
|
+
case 19:
|
|
27819
|
+
_result2 = _context2.sent;
|
|
27820
|
+
if (mountedRef.current) {
|
|
27821
|
+
_context2.next = 20;
|
|
27822
|
+
break;
|
|
27823
|
+
}
|
|
27824
|
+
return _context2.abrupt("return");
|
|
27825
|
+
case 20:
|
|
27826
|
+
if (!_result2.error) {
|
|
27827
|
+
_context2.next = 21;
|
|
27828
|
+
break;
|
|
27829
|
+
}
|
|
27830
|
+
setError(_result2.message);
|
|
27831
|
+
setIsConnecting(false);
|
|
27832
|
+
setStatus(STATUS.ERROR);
|
|
27833
|
+
return _context2.abrupt("return");
|
|
27834
|
+
case 21:
|
|
27835
|
+
applyConnected();
|
|
27836
|
+
_context2.next = 24;
|
|
27837
|
+
break;
|
|
27838
|
+
case 22:
|
|
27839
|
+
_context2.prev = 22;
|
|
27840
|
+
_t4 = _context2["catch"](18);
|
|
27841
|
+
if (mountedRef.current) {
|
|
27842
|
+
_context2.next = 23;
|
|
27843
|
+
break;
|
|
27844
|
+
}
|
|
27845
|
+
return _context2.abrupt("return");
|
|
27846
|
+
case 23:
|
|
27847
|
+
setError((_t4 === null || _t4 === void 0 ? void 0 : _t4.message) || "Failed to connect to WebSocket server");
|
|
27848
|
+
setIsConnecting(false);
|
|
27849
|
+
setStatus(STATUS.ERROR);
|
|
27850
|
+
case 24:
|
|
27851
|
+
case "end":
|
|
27852
|
+
return _context2.stop();
|
|
27853
|
+
}
|
|
27854
|
+
}, _callee2, null, [[5, 8], [10, 14], [18, 22]]);
|
|
27855
|
+
})), [dashApi, provider, providerType, selectedProviderName, applyConnected]);
|
|
27856
|
+
|
|
27857
|
+
/**
|
|
27858
|
+
* Disconnect from the WebSocket server.
|
|
27859
|
+
* Only sends the IPC disconnect call when this is the last consumer.
|
|
27860
|
+
*/
|
|
27861
|
+
var disconnect = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
27862
|
+
var state;
|
|
27863
|
+
return _regeneratorRuntime.wrap(function (_context3) {
|
|
27864
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
27865
|
+
case 0:
|
|
27866
|
+
if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
|
|
27867
|
+
_context3.next = 1;
|
|
27868
|
+
break;
|
|
27869
|
+
}
|
|
27870
|
+
return _context3.abrupt("return");
|
|
27871
|
+
case 1:
|
|
27872
|
+
state = connectionStates.get(selectedProviderName);
|
|
27873
|
+
if (!state) {
|
|
27874
|
+
_context3.next = 3;
|
|
27875
|
+
break;
|
|
27876
|
+
}
|
|
27877
|
+
state.consumerCount = Math.max(0, state.consumerCount - 1);
|
|
27878
|
+
if (!(state.consumerCount > 0)) {
|
|
27879
|
+
_context3.next = 2;
|
|
27880
|
+
break;
|
|
27881
|
+
}
|
|
27882
|
+
// Other widgets still using this connection — just update local state
|
|
27883
|
+
setIsConnected(false);
|
|
27884
|
+
setLastMessage(null);
|
|
27885
|
+
setMessages([]);
|
|
27886
|
+
messagesRef.current = [];
|
|
27887
|
+
setStatus(STATUS.DISCONNECTED);
|
|
27888
|
+
connectedRef.current = false;
|
|
27889
|
+
return _context3.abrupt("return");
|
|
27890
|
+
case 2:
|
|
27891
|
+
// Last consumer — actually disconnect
|
|
27892
|
+
connectionStates["delete"](selectedProviderName);
|
|
27893
|
+
case 3:
|
|
27894
|
+
// Clear state synchronously before the IPC call
|
|
27895
|
+
setIsConnected(false);
|
|
27896
|
+
setLastMessage(null);
|
|
27897
|
+
setMessages([]);
|
|
27898
|
+
messagesRef.current = [];
|
|
27899
|
+
setStatus(STATUS.DISCONNECTED);
|
|
27900
|
+
connectedRef.current = false;
|
|
27901
|
+
pendingConnects["delete"](selectedProviderName);
|
|
27902
|
+
_context3.prev = 4;
|
|
27903
|
+
_context3.next = 5;
|
|
27904
|
+
return dashApi.webSocket.disconnect(selectedProviderName);
|
|
27905
|
+
case 5:
|
|
27906
|
+
_context3.next = 7;
|
|
27907
|
+
break;
|
|
27908
|
+
case 6:
|
|
27909
|
+
_context3.prev = 6;
|
|
27910
|
+
_context3["catch"](4);
|
|
27911
|
+
case 7:
|
|
27912
|
+
case "end":
|
|
27913
|
+
return _context3.stop();
|
|
27914
|
+
}
|
|
27915
|
+
}, _callee3, null, [[4, 6]]);
|
|
27916
|
+
})), [dashApi, selectedProviderName]);
|
|
27917
|
+
|
|
27918
|
+
/**
|
|
27919
|
+
* Send data through the WebSocket connection
|
|
27920
|
+
*/
|
|
27921
|
+
var send = React.useCallback(/*#__PURE__*/function () {
|
|
27922
|
+
var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(data) {
|
|
27923
|
+
var result;
|
|
27924
|
+
return _regeneratorRuntime.wrap(function (_context4) {
|
|
27925
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
27926
|
+
case 0:
|
|
27927
|
+
if (!(!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName)) {
|
|
27928
|
+
_context4.next = 1;
|
|
27929
|
+
break;
|
|
27930
|
+
}
|
|
27931
|
+
throw new Error("WebSocket not connected");
|
|
27932
|
+
case 1:
|
|
27933
|
+
_context4.next = 2;
|
|
27934
|
+
return dashApi.webSocket.send(selectedProviderName, data);
|
|
27935
|
+
case 2:
|
|
27936
|
+
result = _context4.sent;
|
|
27937
|
+
if (!result.error) {
|
|
27938
|
+
_context4.next = 3;
|
|
27939
|
+
break;
|
|
27940
|
+
}
|
|
27941
|
+
throw new Error(result.message);
|
|
27942
|
+
case 3:
|
|
27943
|
+
return _context4.abrupt("return", result);
|
|
27944
|
+
case 4:
|
|
27945
|
+
case "end":
|
|
27946
|
+
return _context4.stop();
|
|
27947
|
+
}
|
|
27948
|
+
}, _callee4);
|
|
27949
|
+
}));
|
|
27950
|
+
return function (_x) {
|
|
27951
|
+
return _ref4.apply(this, arguments);
|
|
27952
|
+
};
|
|
27953
|
+
}(), [dashApi, selectedProviderName]);
|
|
27954
|
+
|
|
27955
|
+
// Keep a ref to connect so the auto-connect effect doesn't depend on it
|
|
27956
|
+
var connectRef = React.useRef(connect);
|
|
27957
|
+
connectRef.current = connect;
|
|
27958
|
+
|
|
27959
|
+
// Listen for incoming messages from main process
|
|
27960
|
+
React.useEffect(function () {
|
|
27961
|
+
if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
|
|
27962
|
+
var handleMessage = function handleMessage(_event, payload) {
|
|
27963
|
+
if (payload.provider !== selectedProviderName) return;
|
|
27964
|
+
if (!mountedRef.current) return;
|
|
27965
|
+
var msg = payload.data;
|
|
27966
|
+
|
|
27967
|
+
// Update circular buffer
|
|
27968
|
+
var next = [].concat(_toConsumableArray(messagesRef.current), [msg]);
|
|
27969
|
+
if (next.length > maxMessagesRef.current) {
|
|
27970
|
+
next.splice(0, next.length - maxMessagesRef.current);
|
|
27971
|
+
}
|
|
27972
|
+
messagesRef.current = next;
|
|
27973
|
+
setMessages(next);
|
|
27974
|
+
setLastMessage(msg);
|
|
27975
|
+
};
|
|
27976
|
+
dashApi.webSocket.onMessage(handleMessage);
|
|
27977
|
+
return function () {
|
|
27978
|
+
return dashApi.webSocket.offMessage(handleMessage);
|
|
27979
|
+
};
|
|
27980
|
+
}, [dashApi, selectedProviderName]);
|
|
27981
|
+
|
|
27982
|
+
// Listen for status changes from main process
|
|
27983
|
+
React.useEffect(function () {
|
|
27984
|
+
if (!(dashApi !== null && dashApi !== void 0 && dashApi.webSocket) || !selectedProviderName) return;
|
|
27985
|
+
var handleStatusChange = function handleStatusChange(_event, payload) {
|
|
27986
|
+
if (payload.provider !== selectedProviderName) return;
|
|
27987
|
+
if (!mountedRef.current) return;
|
|
27988
|
+
var newStatus = payload.status;
|
|
27989
|
+
setStatus(newStatus);
|
|
27990
|
+
if (newStatus === STATUS.CONNECTED) {
|
|
27991
|
+
setIsConnected(true);
|
|
27992
|
+
setIsConnecting(false);
|
|
27993
|
+
setError(null);
|
|
27994
|
+
connectedRef.current = true;
|
|
27995
|
+
} else if (newStatus === STATUS.DISCONNECTED) {
|
|
27996
|
+
setIsConnected(false);
|
|
27997
|
+
setIsConnecting(false);
|
|
27998
|
+
connectedRef.current = false;
|
|
27999
|
+
} else if (newStatus === STATUS.ERROR) {
|
|
28000
|
+
setIsConnected(false);
|
|
28001
|
+
setIsConnecting(false);
|
|
28002
|
+
setError(payload.error || "WebSocket error");
|
|
28003
|
+
connectedRef.current = false;
|
|
28004
|
+
} else if (newStatus === STATUS.CONNECTING) {
|
|
28005
|
+
setIsConnecting(true);
|
|
28006
|
+
}
|
|
28007
|
+
};
|
|
28008
|
+
dashApi.webSocket.onStatusChange(handleStatusChange);
|
|
28009
|
+
return function () {
|
|
28010
|
+
return dashApi.webSocket.offStatusChange(handleStatusChange);
|
|
28011
|
+
};
|
|
28012
|
+
}, [dashApi, selectedProviderName]);
|
|
28013
|
+
|
|
28014
|
+
// Auto-connect on mount or when provider selection changes
|
|
28015
|
+
React.useEffect(function () {
|
|
28016
|
+
if (autoConnect && selectedProviderName && !connectedRef.current) {
|
|
28017
|
+
connectRef.current();
|
|
28018
|
+
}
|
|
28019
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28020
|
+
}, [autoConnect, selectedProviderName]);
|
|
28021
|
+
|
|
28022
|
+
// Track mounted state and cleanup on unmount
|
|
28023
|
+
React.useEffect(function () {
|
|
28024
|
+
mountedRef.current = true;
|
|
28025
|
+
return function () {
|
|
28026
|
+
mountedRef.current = false;
|
|
28027
|
+
|
|
28028
|
+
// Decrement consumer count; only disconnect if last consumer
|
|
28029
|
+
if (connectedRef.current && dashApi !== null && dashApi !== void 0 && dashApi.webSocket && selectedProviderName) {
|
|
28030
|
+
var state = connectionStates.get(selectedProviderName);
|
|
28031
|
+
if (state) {
|
|
28032
|
+
state.consumerCount = Math.max(0, state.consumerCount - 1);
|
|
28033
|
+
if (state.consumerCount > 0) {
|
|
28034
|
+
// Other widgets still using this connection — don't disconnect
|
|
28035
|
+
return;
|
|
28036
|
+
}
|
|
28037
|
+
|
|
28038
|
+
// Last consumer — disconnect
|
|
28039
|
+
connectionStates["delete"](selectedProviderName);
|
|
28040
|
+
}
|
|
28041
|
+
dashApi.webSocket.disconnect(selectedProviderName)["catch"](function () {});
|
|
28042
|
+
}
|
|
28043
|
+
};
|
|
28044
|
+
}, [dashApi, selectedProviderName]);
|
|
28045
|
+
return {
|
|
28046
|
+
isConnected: isConnected,
|
|
28047
|
+
isConnecting: isConnecting,
|
|
28048
|
+
error: error,
|
|
28049
|
+
lastMessage: lastMessage,
|
|
28050
|
+
messages: messages,
|
|
28051
|
+
send: send,
|
|
28052
|
+
connect: connect,
|
|
28053
|
+
disconnect: disconnect,
|
|
28054
|
+
status: status,
|
|
28055
|
+
provider: provider,
|
|
28056
|
+
serverName: selectedProviderName
|
|
28057
|
+
};
|
|
28058
|
+
};
|
|
28059
|
+
|
|
27538
28060
|
function ownKeys$h(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
27539
28061
|
function _objectSpread$h(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$h(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$h(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
27540
28062
|
var PreviewComponentsPane = function PreviewComponentsPane(_ref) {
|
|
@@ -46555,6 +47077,7 @@ exports.useNotifications = useNotifications;
|
|
|
46555
47077
|
exports.useProvider = useProvider;
|
|
46556
47078
|
exports.useProviderClient = useProviderClient;
|
|
46557
47079
|
exports.useScheduler = useScheduler;
|
|
47080
|
+
exports.useWebSocketProvider = useWebSocketProvider;
|
|
46558
47081
|
exports.useWidgetEvents = useWidgetEvents;
|
|
46559
47082
|
exports.useWidgetProviders = useWidgetProviders;
|
|
46560
47083
|
exports.useWidgetSchedulerStatus = useWidgetSchedulerStatus;
|