feat(FN-3398): update desktop README with multi-project setup and troublesh

The merge lands Step 7 of FN-3398, adding documentation and delivery artifacts across the mobile and desktop packages with updated READMEs, mobile-specific docs, and architecture references.

Fusion-Task-Id: FN-3398
This commit is contained in:
Fusion
2026-05-04 21:41:52 -07:00
committed by gsxdsm
parent 9699c3f2b6
commit 3feeb9026a
43 changed files with 2025 additions and 398 deletions

View File

@@ -0,0 +1,90 @@
import type { AddressInfo } from "node:net";
import { once } from "node:events";
import type { Server } from "node:http";
type TaskStoreLike = {
init(): Promise<void>;
watch(): Promise<void>;
close(): void;
};
export interface DesktopLocalRuntime {
store: TaskStoreLike;
server: Server;
port: number;
}
export interface DesktopLocalServerState {
status: "idle" | "starting" | "ready" | "error";
port?: number;
error?: string | null;
}
export class DesktopLocalServerManager {
private runtime: DesktopLocalRuntime | null = null;
private state: DesktopLocalServerState = { status: "idle", error: null };
constructor(private readonly rootDir: string) {}
getState(): DesktopLocalServerState {
return this.state;
}
getPort(): number | undefined {
return this.runtime?.port;
}
async start(): Promise<DesktopLocalRuntime> {
if (this.runtime) {
this.state = { status: "ready", port: this.runtime.port, error: null };
return this.runtime;
}
this.state = { status: "starting", error: null };
try {
const { TaskStore } = await import("@fusion/core");
const { createServer } = await import("@fusion/dashboard");
const store = new TaskStore(this.rootDir) as TaskStoreLike;
await store.init();
await store.watch();
const app = createServer(store);
const server = app.listen(0);
await Promise.race([
once(server, "listening"),
once(server, "error").then(([error]) => {
throw error;
}),
]);
const address = server.address() as AddressInfo | null;
if (!address?.port) {
throw new Error("Failed to resolve local server port");
}
this.runtime = { store, server, port: address.port };
this.state = { status: "ready", port: address.port, error: null };
return this.runtime;
} catch (error) {
this.state = {
status: "error",
error: error instanceof Error ? error.message : String(error),
};
throw error;
}
}
async stop(): Promise<void> {
if (!this.runtime) {
this.state = { status: "idle", error: null };
return;
}
const runtime = this.runtime;
this.runtime = null;
await new Promise<void>((resolve) => runtime.server.close(() => resolve()));
runtime.store.close();
this.state = { status: "idle", error: null };
}
}