mirror of
https://github.com/hanzo-templates/desktop-recorder.git
synced 2026-10-30 20:43:38 +00:00
DEFECT: hanzo-templates shipped 71 templates and not one of them built a native application. Every "make me a desktop app" request dead-ended in the browser, and the one repo that looked like it might help (`mobile`) was completely empty — no commits, no files. There was no answer to "how do I ship a .dmg / .msi / .deb from this platform". REASON for the shape: - Tauri v2 by default. A Rust core against the OS webview produces single-digit MB installers; Electron is reserved for the cases where Chromium itself is the requirement (see desktop-recorder's desktopCapturer). - ONE seam, `src/native.ts`. A native window cannot be iframed, so the gallery preview has to be a real build of the same UI, not a screenshot and not a dead link. `bridge()` resolves a command through the Rust core (or the Electron main process) when it is running natively and through the fallbacks in `src/web.ts` when it is a browser tab. No call site branches; the two shells implement the same contract, which is why app.tsx and shell.tsx are identical across both. - Frameless everywhere. `decorations: false` / `frame: false` means the titlebar in shell.tsx IS the chrome, so the traffic lights do real work through the same bridge rather than importing a shell-specific API. - @hanzo/base for the backend and the a.hanzo.ai analytics/chat runtime in index.html, so a fork starts with persistence and telemetry already wired. - Release fans out to per-OS runners. Desktop bundles must be produced on the target OS (codesign, .dmg/.msi/.deb tooling); this one workflow is the documented exception to the shared build fleet. Upstream and license are recorded in every README. MIT/Apache-2.0/BSD only: these are meant to be forked and commercialised. Co-authored-by: Hanzo Dev <[email protected]>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
import Base from "@hanzo/base";
|
|
|
|
/**
|
|
* The template's backend: one Hanzo Base instance. A fork points at its own by
|
|
* setting VITE_BASE_URL — no code edit. Both halves of the app (Tauri window
|
|
* and web preview) talk to the same collections, so a record written on the
|
|
* desktop shows up in the browser.
|
|
*/
|
|
export const base = new Base(
|
|
import.meta.env.VITE_BASE_URL ?? "https://base.hanzo.ai",
|
|
);
|
|
|
|
export type Sync = { ok: boolean; note: string };
|
|
|
|
/** Push rows to a Base collection, reporting the outcome instead of throwing:
|
|
* an unconfigured fork must still render, just with "offline" in the status
|
|
* bar. Local state is always the source of truth for the UI. */
|
|
export async function push(
|
|
collection: string,
|
|
rows: Record<string, unknown>[],
|
|
): Promise<Sync> {
|
|
try {
|
|
const c = base.collection(collection);
|
|
for (const r of rows) await c.create(r);
|
|
return { ok: true, note: `synced ${rows.length} -> ${collection}` };
|
|
} catch (e) {
|
|
return { ok: false, note: `base offline (${(e as Error).message})` };
|
|
}
|
|
}
|
|
|
|
/** Read a Base collection, empty on any failure — same rule as push(). */
|
|
export async function pull<T>(collection: string): Promise<T[]> {
|
|
try {
|
|
return (await base.collection(collection).getFullList()) as T[];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|