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>
This commit is contained in:
62
extension/src/shared/state.ts
Normal file
62
extension/src/shared/state.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/// 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);
|
||||
}
|
||||
Reference in New Issue
Block a user