mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 16:08:05 +00:00
* test(run): smoke-test running and testing each language's fixture smoke/run.test.ts drives the frontend's run store against a real openidea-server for TypeScript, Python, Rust, Go, Java and Kotlin: the detected configurations, a run to its output, the tests with the fixture's failing test switched on (counts, failure name, location and message in the test tree), and Rerun Failed Tests running only that test. `pnpm smoke` runs it; the Language smoke workflow runs it per language after the code intelligence smoke. * ci(language-smoke): let main's runs finish Merges to main came faster than a run, so each one cancelled the run before it: main never finished the smoke nor saved the build cache PRs restore. Only a PR's runs are superseded now.
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
/**
|
|
* The frontend's view of the desktop app, with a real backend: the window's Tauri runtime
|
|
* (callbacks, `Channel`s, the event plugin) in-process, and every app command sent to an
|
|
* `openidea-server` through the route remote development uses (`src/platform/tauriCore.ts`).
|
|
*/
|
|
import { setInvokeRoute } from "@/platform/tauriCore";
|
|
import { encodeArgs } from "@/platform/remote";
|
|
import { Server } from "./server";
|
|
|
|
type Callback = (message: unknown) => void;
|
|
|
|
// One runtime per page, as in the app: the frontend registers its event listeners once
|
|
// (`src/platform/ipc.ts`), so they outlive the servers connected one after another.
|
|
const callbacks = new Map<number, Callback>();
|
|
const listeners: { event: string; handler: number }[] = [];
|
|
const channels = new Map<number, { onmessage: (data: unknown) => void }>();
|
|
let nextCallback = 1;
|
|
let installed = false;
|
|
|
|
function install() {
|
|
if (installed) return;
|
|
installed = true;
|
|
const internals = {
|
|
metadata: { currentWindow: { label: "main" }, currentWebview: { label: "main", windowLabel: "main" } },
|
|
transformCallback(cb: Callback) {
|
|
const id = nextCallback++;
|
|
callbacks.set(id, cb);
|
|
return id;
|
|
},
|
|
unregisterCallback(id: number) {
|
|
callbacks.delete(id);
|
|
},
|
|
convertFileSrc: (path: string) => path,
|
|
// Only the window's own plugins reach this: app commands take the route below.
|
|
async invoke(cmd: string, args: Record<string, unknown> = {}) {
|
|
if (cmd === "plugin:event|listen") {
|
|
listeners.push({ event: args.event as string, handler: args.handler as number });
|
|
return listeners.length;
|
|
}
|
|
if (cmd === "plugin:window|get_all_windows") return [];
|
|
if (cmd.startsWith("plugin:")) return null;
|
|
throw { kind: "unavailable", message: `${cmd} has no route`, detail: null };
|
|
},
|
|
};
|
|
Object.assign(window, {
|
|
__TAURI_INTERNALS__: internals,
|
|
__TAURI_EVENT_PLUGIN_INTERNALS__: { unregisterListener: () => {} },
|
|
});
|
|
}
|
|
|
|
/** Connects this page's frontend to `server`; returns a function that disconnects it. */
|
|
export function connectDesktop(server: Server): () => void {
|
|
install();
|
|
channels.clear();
|
|
server.onChannel = (id, data) => channels.get(id)?.onmessage(data);
|
|
server.onEvent = (target, event) => {
|
|
if (target !== null && target !== "main") return;
|
|
for (const l of listeners) {
|
|
if (l.event === "ide://event") callbacks.get(l.handler)?.({ event: l.event, id: 0, payload: event });
|
|
}
|
|
};
|
|
setInvokeRoute((cmd, args) => {
|
|
if (cmd.startsWith("plugin:")) return null;
|
|
const { json, channels: used } = encodeArgs(args);
|
|
for (const [id, channel] of used) channels.set(id, channel as unknown as { onmessage: (data: unknown) => void });
|
|
return server.invoke(cmd, JSON.parse(json));
|
|
});
|
|
return () => {
|
|
setInvokeRoute(null);
|
|
server.onChannel = () => {};
|
|
server.onEvent = () => {};
|
|
};
|
|
}
|