Files
crypto_okx/lib/common/static/instance_live.js
T
dekun a1abe159fa Initial standalone crypto_okx with one-click deploy.
Add deploy/manage.sh bootstrap for git.bz121.com/dekun/crypto_okx and point docs at this repo.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 20:00:59 +08:00

112 lines
3.1 KiB
JavaScript

/**
* embed 壳:SSE 收到后台 tick 后拉 JSON 快照更新 DOM,切换 tab 不再重复请求 HTML.
*/
(function (global) {
let liveEventSource = null;
let liveReconnectTimer = null;
let localLiveVersion = -1;
let sseConnected = false;
let refreshTimer = null;
function isEmbedShell() {
return document.body && document.body.getAttribute("data-embed-shell") === "1";
}
function currentTab() {
if (global.InstanceEmbed && typeof global.InstanceEmbed.getTab === "function") {
return global.InstanceEmbed.getTab();
}
return document.body.getAttribute("data-page") || "trade";
}
function refreshTabData(tab, opts) {
const options = opts || {};
if (typeof global.refreshAccountSnapshot === "function") {
global.refreshAccountSnapshot(options);
}
if (typeof global.refreshPriceSnapshotConditional === "function") {
global.refreshPriceSnapshotConditional();
}
if (tab === "options" && global.OptionsPanelLive && typeof global.OptionsPanelLive.refreshSoft === "function") {
global.OptionsPanelLive.refreshSoft(options);
}
// 数据看板自有 SSE + 快照,不跟 embed live tick 重拉.
}
function scheduleRefresh(opts) {
if (refreshTimer) return;
const options = opts || {};
refreshTimer = setTimeout(function () {
refreshTimer = null;
if (document.hidden) return;
refreshTabData(currentTab(), { silent: true, force: !!options.force });
}, 80);
}
function onLiveEvent(data) {
const reason = data && data.reason;
const ver = Number(data && data.live_version) || 0;
if (!ver) return;
if (reason === "connect") {
localLiveVersion = ver;
scheduleRefresh();
return;
}
if (ver === localLiveVersion) return;
localLiveVersion = ver;
scheduleRefresh({ force: reason === "balance" });
}
function closeLiveStream() {
if (liveEventSource) {
liveEventSource.close();
liveEventSource = null;
}
if (liveReconnectTimer) {
clearTimeout(liveReconnectTimer);
liveReconnectTimer = null;
}
sseConnected = false;
}
function connectLiveStream() {
if (!isEmbedShell()) return;
closeLiveStream();
liveEventSource = new EventSource("/api/instance/live/stream");
liveEventSource.addEventListener("live", function (ev) {
try {
onLiveEvent(JSON.parse(ev.data || "{}"));
} catch (_) {}
});
liveEventSource.onopen = function () {
sseConnected = true;
};
liveEventSource.onerror = function () {
sseConnected = false;
closeLiveStream();
liveReconnectTimer = setTimeout(function () {
connectLiveStream();
}, 8000);
};
}
function startLive() {
if (!isEmbedShell()) return;
connectLiveStream();
}
global.InstanceLive = {
start: startLive,
refreshTabData: refreshTabData,
isConnected: function () {
return sseConnected;
},
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", startLive);
} else {
startLive();
}
})(typeof window !== "undefined" ? window : globalThis);