Nexanexa
Paso 16

Empaquetado nativo y @nexa/platform

El mismo código fuente compila a un binario de escritorio real (Tauri), un APK real (Capacitor Android) o un proyecto Xcode real (Capacitor iOS) — sin reescribir nada. Web, escritorio, Android e iOS desde un solo proyecto, y @nexa/platform es lo que hace que el mismo handler funcione en los tres sin ramas propias.

Escritorio con Tauri

nexa add tauri
cd src-tauri && cargo build
# binario de escritorio real, ejecutable

Genera src-tauri/ real — cargo build produce un binario de escritorio real y ejecutable en Windows, macOS y Linux.

Android con Capacitor

nexa add capacitor
npx @capacitor/cli add android
cd android && ./gradlew assembleDebug
# APK real en app/build/outputs/apk/debug/

Requiere el SDK de Android instalado — el resultado es un APK real, compilado con Gradle. Verificado de punta a punta con un SDK real.

iOS con Capacitor

nexa add capacitor
npx @capacitor/cli add ios
npx cap open ios
# abre el proyecto real en Xcode (requiere macOS)

Mismo capacitor.config.json que Android — add ios genera un proyecto Xcode real (ios/). Necesita macOS con Xcode para compilar: no probado en este entorno Linux, pero el mecanismo es idéntico al de Android.

@nexa/platform: un mismo handler, tres plataformas

function shareThis() {
    platform.share({ title: "Nexa", url: location.href });
}

const users = platform.db("users");
await users.set("1", { name: "Ada" });

platform.share()/platform.notify()/platform.capturePhoto() llaman al plugin real de Capacitor en Android/iOS (@capacitor/share, etc.) y a la Web API estándar en web y en el webview de Tauri — sin que el proyecto escriba ninguna rama propia. platform.storage()/platform.sessionStorage() envuelven localStorage/sessionStorage con el mismo contrato en los tres entornos; platform.cache() da acceso directo a la Cache API (sin declarar [pwa]); platform.db("nombre") es un wrapper mínimo sobre IndexedDB, sin declarar nada de antemano. Cada función lanza un Error con mensaje claro si la capacidad no está disponible — nunca falla en silencio.

Tema oscuro, red y ciclo de vida

platform.theme.set("dark");

platform.network.onChange((status) => {
    console.log(status.online, status.type);
});

platform.lifecycle.onChange((state) => {
    console.log(state.active ? "activa" : "en segundo plano");
});

platform.theme.set("dark"|"light"|"system") persiste la preferencia y le gana al prefers-color-scheme del sistema (sin llamarlo nunca, el sitio ya lo respeta). platform.network.getStatus()/onChange() dan el estado de conectividad real (online/offline, y el tipo de conexión en Capacitor); platform.lifecycle.getState()/onChange() avisan cuando la app pasa a segundo plano o vuelve — en Capacitor vía @capacitor/app, en web vía document.hidden/visibilitychange. Se amplía de a un módulo por vez, según necesidad real: geolocalización, deep links, push real, biometría y haptics todavía no están.