@nexa/platform
Un objeto platform disponible siempre, con un solo código para Web/Tauri/Capacitor.
platform.notify()
await platform.notify({ title, body })Notificación real del sistema operativo. Web: Notification API (pide permiso). Capacitor: @capacitor/local-notifications.
platform.capturePhoto()
const { dataUrl } = await platform.capturePhoto();Web: getUserMedia + canvas. Capacitor: @capacitor/camera. Devuelve { dataUrl }.
platform.storage() / sessionStorage()
const storage = platform.storage();
storage.set("theme", "dark");
storage.get("theme");
const session = platform.sessionStorage(); // mismo contrato, no sobrevive cerrar el navegadorMismo contrato get/set/remove sobre localStorage o sessionStorage — este último vive solo mientras dure la pestaña.
platform.cache()
const cache = await platform.cache("mi-cache");
await cache.put(url, response);
await cache.match(url);Cache API directa, independiente de [pwa.cache] (que vive en el service worker) — para cachear algo puntual desde código normal.
platform.db()
const users = platform.db("users");
await users.set(id, valor);
await users.get(id);
await users.list();Wrapper mínimo sobre IndexedDB, no un ORM. Cada nombre de colección es su propia base — sin declarar nada de antemano.
platform.network
const status = await platform.network.getStatus(); // { online, type }
const stop = platform.network.onChange((status) => { ... });Capacitor nativo usa @capacitor/network real; Web/Tauri usan navigator.onLine + eventos online/offline. type (wifi/cellular) es exclusivo de Capacitor.
platform.lifecycle
const state = await platform.lifecycle.getState(); // { active }
const stop = platform.lifecycle.onChange((state) => { ... });Capacitor nativo usa @capacitor/app (getState/appStateChange); Web/Tauri usan document.hidden + visibilitychange — la misma señal que usa la propia rama web de @capacitor/app.
platform.geolocation
const position = await platform.geolocation.getCurrentPosition();
const stop = platform.geolocation.watchPosition((position) => { ... });Capacitor nativo usa @capacitor/geolocation; Web/Tauri usan navigator.geolocation — la misma API que usa la propia rama web de @capacitor/geolocation por dentro.
platform.deepLinks
const launch = await platform.deepLinks.getLaunchUrl(); // { url: "" } en Web
const stop = platform.deepLinks.onOpen((event) => { ... });Capacitor nativo usa @capacitor/app (getLaunchUrl/appUrlOpen). Web/Tauri: getLaunchUrl() siempre devuelve url vacía y onOpen() nunca dispara — así se comporta la propia rama web de @capacitor/app.
platform.push
const registration = await platform.push.register({ vapidPublicKey });
// { platform: "capacitor", token } | { platform: "web", subscription }
platform.push.onReceived((n) => { ... }); // solo CapacitorDeliberadamente más chico que el plugin completo de Capacitor: solo registro + recibir. register() devuelve una unión discriminada porque Capacitor y Web no comparten forma de registro.
platform.biometrics
const status = await platform.biometrics.isAvailable(); // { isAvailable, biometryType }
await platform.biometrics.authenticate({ reason: "Desbloquear" });Capacitor nativo usa @aparajita/capacitor-biometric-auth. Web/Tauri usan WebAuthn real — no se replicó la rama web de ese plugin porque es una simulación deliberada, no biometría real.
platform.haptics
await platform.haptics.impact({ style: "MEDIUM" });
await platform.haptics.notification({ type: "ERROR" });
await platform.haptics.vibrate({ duration: 250 });Capacitor nativo usa @capacitor/haptics real. Web/Tauri usan navigator.vibrate — la misma API que usa la propia rama web de @capacitor/haptics.