Add v2 rewrite: monorepo with desktop and web apps, shared packages, docs, and wireframes

This commit is contained in:
2026-05-14 13:13:21 -04:00
parent 6d7eed9230
commit 379c07b50c
49 changed files with 11607 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
{
"name": "@mosaiciq/desktop",
"private": true,
"type": "module"
}

View File

@@ -0,0 +1,7 @@
# Desktop Source Layout
- `main.ts`: Electron app lifecycle and browser window setup.
- `preload.ts`: isolated bridge exposed to the renderer.
- `rpc.ts`: local RPC method handling.
The desktop app owns Electron APIs. Renderer-facing types come from `packages/contracts`, and reusable non-Electron data belongs in `packages/shared`.

46
apps/desktop/src/main.ts Normal file
View File

@@ -0,0 +1,46 @@
import { app, BrowserWindow, ipcMain } from "electron";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { handleRpc } from "./rpc.js";
import type { RpcMethod, RpcRequestMap } from "../../../packages/contracts/src/rpc.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const isDev = process.env.VITE_DEV_SERVER_URL || !app.isPackaged;
async function createWindow() {
const win = new BrowserWindow({
width: 1440,
height: 960,
minWidth: 1024,
minHeight: 700,
title: "MosaicIQ",
backgroundColor: "#f8f5ed",
webPreferences: {
preload: path.join(__dirname, "preload.js"),
contextIsolation: true,
nodeIntegration: false,
sandbox: false
}
});
if (isDev) {
await win.loadURL(process.env.VITE_DEV_SERVER_URL ?? "http://127.0.0.1:5173");
win.webContents.openDevTools({ mode: "detach" });
} else {
await win.loadFile(path.join(__dirname, "../../../../apps/web/dist/index.html"));
}
}
ipcMain.handle("rpc:call", (_event, method: RpcMethod, payload: RpcRequestMap[RpcMethod]) => {
return handleRpc(method, payload);
});
app.whenReady().then(createWindow);
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) void createWindow();
});

View File

@@ -0,0 +1,21 @@
import { contextBridge, ipcRenderer } from "electron";
import type { RpcClient, RpcMethod, RpcRequestMap } from "../../../packages/contracts/src/rpc.js";
const api: RpcClient = {
call(method, payload) {
return ipcRenderer.invoke("rpc:call", method, payload);
}
};
contextBridge.exposeInMainWorld("mosaic", api);
declare global {
interface Window {
mosaic: {
call<T extends RpcMethod>(
method: T,
payload: RpcRequestMap[T]
): Promise<import("../../../packages/contracts/src/rpc.js").RpcResult<T>>;
};
}
}

9
apps/desktop/src/rpc.ts Normal file
View File

@@ -0,0 +1,9 @@
import type { RpcMethod, RpcRequestMap, RpcResult } from "../../../packages/contracts/src/rpc.js";
import { handleMockRpc } from "../../../packages/shared/src/mockRpc.js";
export async function handleRpc<T extends RpcMethod>(
method: T,
payload: RpcRequestMap[T]
): Promise<RpcResult<T>> {
return handleMockRpc(method, payload);
}