@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/react/index.mjs
CHANGED
|
@@ -24946,7 +24946,7 @@ function exposeProviderOnWindow(internals) {
|
|
|
24946
24946
|
if (typeof window === "undefined") return;
|
|
24947
24947
|
const w = window;
|
|
24948
24948
|
const root = w.__UI_BRIDGE__ ?? (w.__UI_BRIDGE__ = {});
|
|
24949
|
-
root.version = "0.
|
|
24949
|
+
root.version = "0.11.0";
|
|
24950
24950
|
root.specs = { getGlobalSpecStore };
|
|
24951
24951
|
root.registry = internals.registry;
|
|
24952
24952
|
root.browserCapture = internals.browserCapture;
|
|
@@ -32930,11 +32930,16 @@ function transportHeaders(authHeader) {
|
|
|
32930
32930
|
}
|
|
32931
32931
|
return headers;
|
|
32932
32932
|
}
|
|
32933
|
-
function
|
|
32934
|
-
const
|
|
32935
|
-
|
|
32936
|
-
|
|
32937
|
-
|
|
32933
|
+
function parseSSEDataBlock(block) {
|
|
32934
|
+
const dataLines = [];
|
|
32935
|
+
for (const line of block.split("\n")) {
|
|
32936
|
+
if (line.startsWith(":")) continue;
|
|
32937
|
+
if (!line.startsWith("data:")) continue;
|
|
32938
|
+
let value = line.slice(5);
|
|
32939
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
32940
|
+
dataLines.push(value);
|
|
32941
|
+
}
|
|
32942
|
+
return dataLines.length > 0 ? dataLines.join("\n") : null;
|
|
32938
32943
|
}
|
|
32939
32944
|
function useCommandRelay(options) {
|
|
32940
32945
|
const enabled = options?.enabled ?? true;
|
|
@@ -32974,7 +32979,6 @@ function useCommandRelay(options) {
|
|
|
32974
32979
|
}),
|
|
32975
32980
|
[uiBridge, context]
|
|
32976
32981
|
);
|
|
32977
|
-
const eventSourceRef = useRef(null);
|
|
32978
32982
|
const reconnectTimeoutRef = useRef(null);
|
|
32979
32983
|
const processCommandRef = useRef(() => {
|
|
32980
32984
|
});
|
|
@@ -33050,10 +33054,6 @@ function useCommandRelay(options) {
|
|
|
33050
33054
|
processCommandRef.current = processCommand;
|
|
33051
33055
|
useEffect(() => {
|
|
33052
33056
|
if (!enabled) {
|
|
33053
|
-
if (eventSourceRef.current) {
|
|
33054
|
-
eventSourceRef.current.close();
|
|
33055
|
-
eventSourceRef.current = null;
|
|
33056
|
-
}
|
|
33057
33057
|
if (reconnectTimeoutRef.current) {
|
|
33058
33058
|
clearTimeout(reconnectTimeoutRef.current);
|
|
33059
33059
|
reconnectTimeoutRef.current = null;
|
|
@@ -33061,34 +33061,73 @@ function useCommandRelay(options) {
|
|
|
33061
33061
|
return;
|
|
33062
33062
|
}
|
|
33063
33063
|
let isMounted = true;
|
|
33064
|
+
let abortController = null;
|
|
33065
|
+
const closeStream = () => {
|
|
33066
|
+
if (abortController) {
|
|
33067
|
+
abortController.abort();
|
|
33068
|
+
abortController = null;
|
|
33069
|
+
}
|
|
33070
|
+
};
|
|
33071
|
+
const scheduleReconnect = () => {
|
|
33072
|
+
if (!isMounted) return;
|
|
33073
|
+
if (reconnectTimeoutRef.current) return;
|
|
33074
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
33075
|
+
reconnectTimeoutRef.current = null;
|
|
33076
|
+
if (isMounted) connect();
|
|
33077
|
+
}, SSE_RECONNECT_DELAY_MS);
|
|
33078
|
+
};
|
|
33064
33079
|
const connect = () => {
|
|
33065
33080
|
if (!isMounted) return;
|
|
33066
|
-
|
|
33067
|
-
const
|
|
33068
|
-
|
|
33069
|
-
|
|
33070
|
-
|
|
33071
|
-
|
|
33072
|
-
|
|
33073
|
-
|
|
33074
|
-
|
|
33075
|
-
|
|
33081
|
+
closeStream();
|
|
33082
|
+
const controller = new AbortController();
|
|
33083
|
+
abortController = controller;
|
|
33084
|
+
const url = `${basePath}/commands/stream${tabId ? `?tabId=${encodeURIComponent(tabId)}` : ""}`;
|
|
33085
|
+
const headers = { Accept: "text/event-stream" };
|
|
33086
|
+
const token = resolveAuthToken(authHeaderRef.current);
|
|
33087
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
33088
|
+
fetch(url, { method: "GET", headers, signal: controller.signal, cache: "no-store" }).then(async (resp) => {
|
|
33089
|
+
if (!resp.ok || !resp.body) {
|
|
33090
|
+
if (abortController === controller) abortController = null;
|
|
33091
|
+
scheduleReconnect();
|
|
33092
|
+
return;
|
|
33076
33093
|
}
|
|
33077
|
-
|
|
33078
|
-
|
|
33079
|
-
|
|
33080
|
-
|
|
33081
|
-
|
|
33082
|
-
|
|
33083
|
-
|
|
33084
|
-
|
|
33085
|
-
|
|
33094
|
+
const reader = resp.body.getReader();
|
|
33095
|
+
const decoder = new TextDecoder();
|
|
33096
|
+
let buffer = "";
|
|
33097
|
+
try {
|
|
33098
|
+
for (; ; ) {
|
|
33099
|
+
const { value, done } = await reader.read();
|
|
33100
|
+
if (done) break;
|
|
33101
|
+
buffer += decoder.decode(value, { stream: true });
|
|
33102
|
+
let sep;
|
|
33103
|
+
while ((sep = buffer.indexOf("\n\n")) !== -1) {
|
|
33104
|
+
const block = buffer.slice(0, sep);
|
|
33105
|
+
buffer = buffer.slice(sep + 2);
|
|
33106
|
+
const data = parseSSEDataBlock(block);
|
|
33107
|
+
if (data == null) continue;
|
|
33108
|
+
try {
|
|
33109
|
+
const parsed = JSON.parse(data);
|
|
33110
|
+
if (parsed.type === "connected") continue;
|
|
33111
|
+
if (parsed.commandId && parsed.action) {
|
|
33112
|
+
processCommandRef.current(parsed);
|
|
33113
|
+
}
|
|
33114
|
+
} catch (e) {
|
|
33115
|
+
console.error("[UIBridge] Failed to parse SSE message:", e);
|
|
33116
|
+
}
|
|
33117
|
+
}
|
|
33118
|
+
}
|
|
33119
|
+
} catch {
|
|
33086
33120
|
}
|
|
33087
|
-
|
|
33121
|
+
if (abortController === controller) abortController = null;
|
|
33122
|
+
if (isMounted && !controller.signal.aborted) scheduleReconnect();
|
|
33123
|
+
}).catch(() => {
|
|
33124
|
+
if (abortController === controller) abortController = null;
|
|
33125
|
+
if (isMounted && !controller.signal.aborted) scheduleReconnect();
|
|
33126
|
+
});
|
|
33088
33127
|
};
|
|
33089
33128
|
const handleVisibility = () => {
|
|
33090
33129
|
if (document.visibilityState === "visible") {
|
|
33091
|
-
if (!
|
|
33130
|
+
if (!abortController) {
|
|
33092
33131
|
if (reconnectTimeoutRef.current) {
|
|
33093
33132
|
clearTimeout(reconnectTimeoutRef.current);
|
|
33094
33133
|
reconnectTimeoutRef.current = null;
|
|
@@ -33101,10 +33140,7 @@ function useCommandRelay(options) {
|
|
|
33101
33140
|
document.addEventListener("visibilitychange", handleVisibility);
|
|
33102
33141
|
forceReconnectRef.current = () => {
|
|
33103
33142
|
if (!isMounted) return;
|
|
33104
|
-
|
|
33105
|
-
eventSourceRef.current.close();
|
|
33106
|
-
eventSourceRef.current = null;
|
|
33107
|
-
}
|
|
33143
|
+
closeStream();
|
|
33108
33144
|
if (reconnectTimeoutRef.current) {
|
|
33109
33145
|
clearTimeout(reconnectTimeoutRef.current);
|
|
33110
33146
|
reconnectTimeoutRef.current = null;
|
|
@@ -33115,10 +33151,7 @@ function useCommandRelay(options) {
|
|
|
33115
33151
|
isMounted = false;
|
|
33116
33152
|
forceReconnectRef.current = () => {
|
|
33117
33153
|
};
|
|
33118
|
-
|
|
33119
|
-
eventSourceRef.current.close();
|
|
33120
|
-
eventSourceRef.current = null;
|
|
33121
|
-
}
|
|
33154
|
+
closeStream();
|
|
33122
33155
|
if (reconnectTimeoutRef.current) {
|
|
33123
33156
|
clearTimeout(reconnectTimeoutRef.current);
|
|
33124
33157
|
reconnectTimeoutRef.current = null;
|