63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import { Hono } from "hono";
|
|
|
|
/**
|
|
* The contract every rSpace module must implement.
|
|
*
|
|
* A module is a self-contained feature area (books, pubs, cart, canvas, etc.)
|
|
* that exposes Hono routes and metadata. The shell mounts these routes under
|
|
* `/:space/{moduleId}` in unified mode. In standalone mode, the module's own
|
|
* `standalone.ts` mounts them at the root with a minimal shell.
|
|
*/
|
|
export interface RSpaceModule {
|
|
/** Short identifier used in URLs: 'books', 'pubs', 'cart', 'canvas', etc. */
|
|
id: string;
|
|
/** Human-readable name: 'rBooks', 'rPubs', 'rCart', etc. */
|
|
name: string;
|
|
/** Emoji or SVG string for the app switcher */
|
|
icon: string;
|
|
/** One-line description */
|
|
description: string;
|
|
/** Mountable Hono sub-app. Routes are relative to the mount point. */
|
|
routes: Hono;
|
|
/** Optional: standalone domain for this module (e.g. 'rbooks.online') */
|
|
standaloneDomain?: string;
|
|
/** Called when a new space is created (e.g. to initialize module-specific data) */
|
|
onSpaceCreate?: (spaceSlug: string) => Promise<void>;
|
|
/** Called when a space is deleted (e.g. to clean up module-specific data) */
|
|
onSpaceDelete?: (spaceSlug: string) => Promise<void>;
|
|
}
|
|
|
|
/** Registry of all loaded modules */
|
|
const modules = new Map<string, RSpaceModule>();
|
|
|
|
export function registerModule(mod: RSpaceModule): void {
|
|
modules.set(mod.id, mod);
|
|
}
|
|
|
|
export function getModule(id: string): RSpaceModule | undefined {
|
|
return modules.get(id);
|
|
}
|
|
|
|
export function getAllModules(): RSpaceModule[] {
|
|
return Array.from(modules.values());
|
|
}
|
|
|
|
/** Metadata exposed to the client for the app switcher */
|
|
export interface ModuleInfo {
|
|
id: string;
|
|
name: string;
|
|
icon: string;
|
|
description: string;
|
|
standaloneDomain?: string;
|
|
}
|
|
|
|
export function getModuleInfoList(): ModuleInfo[] {
|
|
return getAllModules().map((m) => ({
|
|
id: m.id,
|
|
name: m.name,
|
|
icon: m.icon,
|
|
description: m.description,
|
|
...(m.standaloneDomain ? { standaloneDomain: m.standaloneDomain } : {}),
|
|
}));
|
|
}
|