@qontinui/ui-bridge 0.10.0 → 0.11.0
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 +73 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +73 -40
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +4 -3
- package/dist/react/index.d.ts +4 -3
- package/dist/react/index.js +73 -40
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +73 -40
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -25799,7 +25799,7 @@ function exposeProviderOnWindow(internals) {
|
|
|
25799
25799
|
if (typeof window === "undefined") return;
|
|
25800
25800
|
const w = window;
|
|
25801
25801
|
const root = w.__UI_BRIDGE__ ?? (w.__UI_BRIDGE__ = {});
|
|
25802
|
-
root.version = "0.
|
|
25802
|
+
root.version = "0.11.0";
|
|
25803
25803
|
root.specs = { getGlobalSpecStore };
|
|
25804
25804
|
root.registry = internals.registry;
|
|
25805
25805
|
root.browserCapture = internals.browserCapture;
|
|
@@ -37540,11 +37540,16 @@ function transportHeaders(authHeader) {
|
|
|
37540
37540
|
}
|
|
37541
37541
|
return headers;
|
|
37542
37542
|
}
|
|
37543
|
-
function
|
|
37544
|
-
const
|
|
37545
|
-
|
|
37546
|
-
|
|
37547
|
-
|
|
37543
|
+
function parseSSEDataBlock(block) {
|
|
37544
|
+
const dataLines = [];
|
|
37545
|
+
for (const line of block.split("\n")) {
|
|
37546
|
+
if (line.startsWith(":")) continue;
|
|
37547
|
+
if (!line.startsWith("data:")) continue;
|
|
37548
|
+
let value = line.slice(5);
|
|
37549
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
37550
|
+
dataLines.push(value);
|
|
37551
|
+
}
|
|
37552
|
+
return dataLines.length > 0 ? dataLines.join("\n") : null;
|
|
37548
37553
|
}
|
|
37549
37554
|
function useCommandRelay(options) {
|
|
37550
37555
|
const enabled = options?.enabled ?? true;
|
|
@@ -37584,7 +37589,6 @@ function useCommandRelay(options) {
|
|
|
37584
37589
|
}),
|
|
37585
37590
|
[uiBridge, context]
|
|
37586
37591
|
);
|
|
37587
|
-
const eventSourceRef = useRef(null);
|
|
37588
37592
|
const reconnectTimeoutRef = useRef(null);
|
|
37589
37593
|
const processCommandRef = useRef(() => {
|
|
37590
37594
|
});
|
|
@@ -37660,10 +37664,6 @@ function useCommandRelay(options) {
|
|
|
37660
37664
|
processCommandRef.current = processCommand;
|
|
37661
37665
|
useEffect(() => {
|
|
37662
37666
|
if (!enabled) {
|
|
37663
|
-
if (eventSourceRef.current) {
|
|
37664
|
-
eventSourceRef.current.close();
|
|
37665
|
-
eventSourceRef.current = null;
|
|
37666
|
-
}
|
|
37667
37667
|
if (reconnectTimeoutRef.current) {
|
|
37668
37668
|
clearTimeout(reconnectTimeoutRef.current);
|
|
37669
37669
|
reconnectTimeoutRef.current = null;
|
|
@@ -37671,34 +37671,73 @@ function useCommandRelay(options) {
|
|
|
37671
37671
|
return;
|
|
37672
37672
|
}
|
|
37673
37673
|
let isMounted = true;
|
|
37674
|
+
let abortController = null;
|
|
37675
|
+
const closeStream = () => {
|
|
37676
|
+
if (abortController) {
|
|
37677
|
+
abortController.abort();
|
|
37678
|
+
abortController = null;
|
|
37679
|
+
}
|
|
37680
|
+
};
|
|
37681
|
+
const scheduleReconnect = () => {
|
|
37682
|
+
if (!isMounted) return;
|
|
37683
|
+
if (reconnectTimeoutRef.current) return;
|
|
37684
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
37685
|
+
reconnectTimeoutRef.current = null;
|
|
37686
|
+
if (isMounted) connect();
|
|
37687
|
+
}, SSE_RECONNECT_DELAY_MS);
|
|
37688
|
+
};
|
|
37674
37689
|
const connect = () => {
|
|
37675
37690
|
if (!isMounted) return;
|
|
37676
|
-
|
|
37677
|
-
const
|
|
37678
|
-
|
|
37679
|
-
|
|
37680
|
-
|
|
37681
|
-
|
|
37682
|
-
|
|
37683
|
-
|
|
37684
|
-
|
|
37685
|
-
|
|
37691
|
+
closeStream();
|
|
37692
|
+
const controller = new AbortController();
|
|
37693
|
+
abortController = controller;
|
|
37694
|
+
const url = `${basePath}/commands/stream${tabId ? `?tabId=${encodeURIComponent(tabId)}` : ""}`;
|
|
37695
|
+
const headers = { Accept: "text/event-stream" };
|
|
37696
|
+
const token = resolveAuthToken(authHeaderRef.current);
|
|
37697
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
37698
|
+
fetch(url, { method: "GET", headers, signal: controller.signal, cache: "no-store" }).then(async (resp) => {
|
|
37699
|
+
if (!resp.ok || !resp.body) {
|
|
37700
|
+
if (abortController === controller) abortController = null;
|
|
37701
|
+
scheduleReconnect();
|
|
37702
|
+
return;
|
|
37686
37703
|
}
|
|
37687
|
-
|
|
37688
|
-
|
|
37689
|
-
|
|
37690
|
-
|
|
37691
|
-
|
|
37692
|
-
|
|
37693
|
-
|
|
37694
|
-
|
|
37695
|
-
|
|
37704
|
+
const reader = resp.body.getReader();
|
|
37705
|
+
const decoder = new TextDecoder();
|
|
37706
|
+
let buffer = "";
|
|
37707
|
+
try {
|
|
37708
|
+
for (; ; ) {
|
|
37709
|
+
const { value, done } = await reader.read();
|
|
37710
|
+
if (done) break;
|
|
37711
|
+
buffer += decoder.decode(value, { stream: true });
|
|
37712
|
+
let sep;
|
|
37713
|
+
while ((sep = buffer.indexOf("\n\n")) !== -1) {
|
|
37714
|
+
const block = buffer.slice(0, sep);
|
|
37715
|
+
buffer = buffer.slice(sep + 2);
|
|
37716
|
+
const data = parseSSEDataBlock(block);
|
|
37717
|
+
if (data == null) continue;
|
|
37718
|
+
try {
|
|
37719
|
+
const parsed = JSON.parse(data);
|
|
37720
|
+
if (parsed.type === "connected") continue;
|
|
37721
|
+
if (parsed.commandId && parsed.action) {
|
|
37722
|
+
processCommandRef.current(parsed);
|
|
37723
|
+
}
|
|
37724
|
+
} catch (e) {
|
|
37725
|
+
console.error("[UIBridge] Failed to parse SSE message:", e);
|
|
37726
|
+
}
|
|
37727
|
+
}
|
|
37728
|
+
}
|
|
37729
|
+
} catch {
|
|
37696
37730
|
}
|
|
37697
|
-
|
|
37731
|
+
if (abortController === controller) abortController = null;
|
|
37732
|
+
if (isMounted && !controller.signal.aborted) scheduleReconnect();
|
|
37733
|
+
}).catch(() => {
|
|
37734
|
+
if (abortController === controller) abortController = null;
|
|
37735
|
+
if (isMounted && !controller.signal.aborted) scheduleReconnect();
|
|
37736
|
+
});
|
|
37698
37737
|
};
|
|
37699
37738
|
const handleVisibility = () => {
|
|
37700
37739
|
if (document.visibilityState === "visible") {
|
|
37701
|
-
if (!
|
|
37740
|
+
if (!abortController) {
|
|
37702
37741
|
if (reconnectTimeoutRef.current) {
|
|
37703
37742
|
clearTimeout(reconnectTimeoutRef.current);
|
|
37704
37743
|
reconnectTimeoutRef.current = null;
|
|
@@ -37711,10 +37750,7 @@ function useCommandRelay(options) {
|
|
|
37711
37750
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
37712
37751
|
forceReconnectRef.current = () => {
|
|
37713
37752
|
if (!isMounted) return;
|
|
37714
|
-
|
|
37715
|
-
eventSourceRef.current.close();
|
|
37716
|
-
eventSourceRef.current = null;
|
|
37717
|
-
}
|
|
37753
|
+
closeStream();
|
|
37718
37754
|
if (reconnectTimeoutRef.current) {
|
|
37719
37755
|
clearTimeout(reconnectTimeoutRef.current);
|
|
37720
37756
|
reconnectTimeoutRef.current = null;
|
|
@@ -37725,10 +37761,7 @@ function useCommandRelay(options) {
|
|
|
37725
37761
|
isMounted = false;
|
|
37726
37762
|
forceReconnectRef.current = () => {
|
|
37727
37763
|
};
|
|
37728
|
-
|
|
37729
|
-
eventSourceRef.current.close();
|
|
37730
|
-
eventSourceRef.current = null;
|
|
37731
|
-
}
|
|
37764
|
+
closeStream();
|
|
37732
37765
|
if (reconnectTimeoutRef.current) {
|
|
37733
37766
|
clearTimeout(reconnectTimeoutRef.current);
|
|
37734
37767
|
reconnectTimeoutRef.current = null;
|