Files
relicario/extension/src/shared/state.ts
adlee-was-taken ce59223fc0 feat(ext): shared state host — decouple components from popup.ts
Introduce shared/state.ts as a service-locator so popup components
(item-detail, item-form, trash, devices, settings, etc.) work in both
the popup and vault tab bundles. Both entry points register themselves
as the host; components import from shared/state instead of popup.ts.
Vault.ts now delegates to the real popup components, removing ~300 lines
of placeholder renderers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:38:06 -04:00

63 lines
1.7 KiB
TypeScript

/// Service-locator for cross-bundle state access.
///
/// Both popup.ts and vault.ts register themselves as the "host".
/// All popup components import from here instead of from popup.ts,
/// so the same component code works in either bundle.
import type { Request, Response } from './messages';
export interface StateHost {
getState(): any;
setState(partial: any): void;
navigate(view: string, extras?: any): void;
sendMessage(request: Request): Promise<Response>;
escapeHtml(s: string): string;
popOutToTab(): void;
isInTab(): boolean;
openVaultTab(hash?: string): void;
}
let host: StateHost | null = null;
export function registerHost(h: StateHost): void { host = h; }
export function getState(): any {
if (!host) throw new Error('No state host registered');
return host.getState();
}
export function setState(partial: any): void {
if (!host) throw new Error('No state host registered');
host.setState(partial);
}
export function navigate(view: string, extras?: any): void {
if (!host) throw new Error('No state host registered');
host.navigate(view, extras);
}
export function sendMessage(request: Request): Promise<Response> {
if (!host) throw new Error('No state host registered');
return host.sendMessage(request);
}
export function escapeHtml(s: string): string {
if (!host) throw new Error('No state host registered');
return host.escapeHtml(s);
}
export function popOutToTab(): void {
if (!host) throw new Error('No state host registered');
host.popOutToTab();
}
export function isInTab(): boolean {
if (!host) return false;
return host.isInTab();
}
export function openVaultTab(hash?: string): void {
if (!host) throw new Error('No state host registered');
host.openVaultTab(hash);
}