Core CI / core (ubuntu-latest) (push) Failing after 3m29s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 7m23s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
/** Explicit, read-only bridge for documented browser captures of the real engine.
|
|
* This never activates in a normal browser preview or remote website. */
|
|
const commands = new Set([
|
|
"stats",
|
|
"desktop_status",
|
|
"semantic_status",
|
|
"search",
|
|
"hybrid_search",
|
|
"search_measured",
|
|
"hybrid_search_measured",
|
|
"prepare_media_preview",
|
|
]);
|
|
|
|
export function captureRequested(href: string) {
|
|
const url = new URL(href);
|
|
return (
|
|
url.searchParams.get("capture") === "1" &&
|
|
url.protocol === "http:" &&
|
|
["127.0.0.1", "localhost", "[::1]"].includes(url.hostname)
|
|
);
|
|
}
|
|
|
|
export class CaptureBridge {
|
|
private token: string | null = null;
|
|
private origin: string | null = null;
|
|
get active() {
|
|
return this.token !== null;
|
|
}
|
|
|
|
async initialize(href: string, request: typeof fetch = fetch) {
|
|
this.token = null;
|
|
this.origin = null;
|
|
if (!captureRequested(href)) return false;
|
|
const origin = new URL(href).origin;
|
|
const response = await request(`${origin}/capture-info`, {
|
|
credentials: "omit",
|
|
cache: "no-store",
|
|
redirect: "error",
|
|
});
|
|
if (!response.ok)
|
|
throw new Error("The local capture engine is unavailable.");
|
|
const info = (await response.json()) as {
|
|
mode?: unknown;
|
|
token?: unknown;
|
|
ready?: unknown;
|
|
};
|
|
if (
|
|
info.mode !== "readme-capture" ||
|
|
info.ready !== true ||
|
|
typeof info.token !== "string" ||
|
|
info.token.length < 32 ||
|
|
info.token.length > 512
|
|
)
|
|
throw new Error(
|
|
"The local endpoint did not identify a ready read-only capture engine.",
|
|
);
|
|
this.origin = origin;
|
|
this.token = info.token;
|
|
return true;
|
|
}
|
|
|
|
async invoke<T>(
|
|
command: string,
|
|
args?: Record<string, unknown>,
|
|
request: typeof fetch = fetch,
|
|
): Promise<T> {
|
|
if (!this.active || !this.origin)
|
|
throw new Error("Run the desktop app to use real local search.");
|
|
if (!commands.has(command))
|
|
throw new Error(
|
|
"This action is unavailable in the read-only documentation capture.",
|
|
);
|
|
const response = await request(`${this.origin}/capture-api/${command}`, {
|
|
method: "POST",
|
|
credentials: "omit",
|
|
cache: "no-store",
|
|
redirect: "error",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-Searchi-Capture-Token": this.token!,
|
|
},
|
|
body: JSON.stringify(args ?? {}),
|
|
});
|
|
const value = await response.json();
|
|
if (!response.ok) throw value;
|
|
return value as T;
|
|
}
|
|
|
|
mediaURL(path: string) {
|
|
if (
|
|
!this.active ||
|
|
!this.origin ||
|
|
!/^\/capture-media\/[A-Za-z0-9_-]+(?:\.[A-Za-z0-9]+)?$/.test(path)
|
|
)
|
|
throw new Error(
|
|
"Capture media must be an indexed fixture URL issued by the local engine.",
|
|
);
|
|
return new URL(path, this.origin).href;
|
|
}
|
|
}
|