/** @wrnexus/mobile — SSR-safe access to Capacitor's native bridge. */ export { native } from "@wrnexus/native"; export type MobilePlatform = "ios" | "android" | "web" | string; export interface CapacitorBridge { isNativePlatform?: () => boolean; getPlatform?: () => MobilePlatform; Plugins?: Record; } export class MobileUnavailableError extends Error { constructor(message = "A Capacitor native runtime is not available") { super(message); this.name = "MobileUnavailableError"; } } function bridge(): CapacitorBridge | undefined { if (typeof globalThis === "undefined") return undefined; return (globalThis as typeof globalThis & { Capacitor?: CapacitorBridge }).Capacitor; } const registered = new Map(); /** Register a plugin imported by browser-only application code. */ export function registerPlugin(name: string, instance: T): T { registered.set(name, instance); return instance; } /** True only inside a native Capacitor iOS or Android WebView. SSR-safe. */ export function isNative(): boolean { return bridge()?.isNativePlatform?.() ?? false; } /** Current Capacitor platform, falling back to `web` during SSR and in browsers. */ export function platform(): MobilePlatform { return bridge()?.getPlatform?.() ?? "web"; } /** Return an injected Capacitor plugin, or undefined when it is unavailable. */ export function plugin(name: string): T | undefined { if (!isNative()) return undefined; return (registered.get(name) ?? bridge()?.Plugins?.[name]) as T | undefined; } /** Require an installed native plugin and produce a useful error when absent. */ export function requirePlugin(name: string): T { const value = plugin(name); if (!value) { throw new MobileUnavailableError( `Capacitor plugin "${name}" is unavailable. Run \`wrnexus mobile add \` and rebuild the native app.`, ); } return value; } /** Invoke a plugin method without importing native code into an SSR module. */ export async function invoke( pluginName: string, method: string, options?: unknown, ): Promise { const target = requirePlugin>(pluginName); const fn = target[method]; if (typeof fn !== "function") { throw new MobileUnavailableError(`Capacitor plugin "${pluginName}" has no method "${method}".`); } return (await fn.call(target, options)) as TResult; } /** Run native behavior when available, with an optional SSR/web fallback. */ export async function whenNative( native: () => T | Promise, fallback?: () => T | Promise, ): Promise { if (isNative()) return native(); return fallback?.(); } export const mobile = { isNative, platform, registerPlugin, plugin, requirePlugin, invoke, whenNative, };