feat: stabilize Xingtu market data sync

This commit is contained in:
2026-04-21 14:16:29 +08:00
parent 85e835a96a
commit 55324a5bb7
19 changed files with 2150 additions and 1366 deletions
+69 -2
View File
@@ -3,10 +3,15 @@ import {
type CreateMarketControllerOptions
} from "./market/index";
interface ChromeRuntimeLike {
getURL?: (path: string) => string;
id?: string;
}
interface BootContentScriptOptions {
createMarketController?: (
options: CreateMarketControllerOptions
) => { ready: Promise<void> };
) => { dispose?: () => void; ready: Promise<void> };
document?: Document;
window?: Window;
}
@@ -23,6 +28,8 @@ export async function bootContentScript(
return null;
}
installMarketPageBridge(currentDocument);
return controllerFactory({
document: currentDocument,
window: currentWindow
@@ -30,5 +37,65 @@ export async function bootContentScript(
}
function isMarketPage(url: string): boolean {
return url.startsWith("https://xingtu.cn/ad/creator/market");
const parsedUrl = new URL(url);
const isXingtuHost =
parsedUrl.hostname === "xingtu.cn" || parsedUrl.hostname.endsWith(".xingtu.cn");
return isXingtuHost && parsedUrl.pathname.startsWith("/ad/creator/market");
}
function bootstrapContentScript() {
const runtime = (
globalThis as typeof globalThis & {
chrome?: { runtime?: ChromeRuntimeLike };
}
).chrome?.runtime;
if (!runtime || typeof window === "undefined" || typeof document === "undefined") {
return;
}
const marker = "__starChartSearchEnhancerContentController";
const scopedWindow = window as Window & {
[marker]?: boolean | { dispose?: () => void; ready: Promise<void> } | null;
};
if (scopedWindow[marker]) {
return;
}
scopedWindow[marker] = true;
void bootContentScript().then((controller) => {
scopedWindow[marker] = controller;
});
}
bootstrapContentScript();
function installMarketPageBridge(document: Document) {
if (
document.documentElement.querySelector(
'[data-sces-market-bridge="script"]'
)
) {
return;
}
const script = document.createElement("script");
script.dataset.scesMarketBridge = "script";
const runtime = (
globalThis as typeof globalThis & {
chrome?: { runtime?: ChromeRuntimeLike };
}
).chrome?.runtime;
const bridgeUrl = runtime?.getURL?.("content/market-page-bridge.js");
if (bridgeUrl) {
script.src = bridgeUrl;
} else {
script.textContent = "";
}
(document.head ?? document.documentElement).appendChild(script);
}