Files
WRNexusJS/.publish/mobile
ClintchizandClaude Opus 5 7a2b58652a
Quality / quality (ubuntu-latest) (push) Failing after 11m2s
Quality / quality (windows-latest) (push) Canceled after 0s
chore(release): prepare 0.8.6
Bumps all 47 packages, the root manifest and the VS Code extension to 0.8.6,
and rebuilds the editor compiler, language server and extension bundles that
embed the version.

The release carries the output delivery fix: camelCase outputs now reach
parent bindings, and 18 components emit through output.* instead of
hand-built CustomEvents. See the 0.8.6 migration entry for what changes for
consumers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 01:54:44 +05:30
..
2026-08-09 01:54:44 +05:30
2026-08-02 23:18:51 +05:30

@wrnexus/mobile

SSR-safe access to Capacitor plugins from WRNexusJS browser code.

Overview

@wrnexus/mobile keeps optional native imports out of server rendering while giving browser-owned modules one consistent registry for Capacitor plugins. During SSR, mobile.isNative() is false and mobile.platform() is "web".

Installation

Install a plugin through the WRNexusJS CLI so the web and native projects stay aligned:

wrnexus mobile add @capacitor/camera @capacitor/haptics

Usage

Register and invoke a Capacitor plugin

Import Capacitor packages only from browser-owned code, never from API routes or SSR helpers.

import { Camera, CameraResultType } from "@capacitor/camera";
import { mobile } from "@wrnexus/mobile";

mobile.registerPlugin("Camera", Camera);

export async function takePhoto() {
  if (!mobile.isNative()) return null;
  return mobile.invoke("Camera", "getPhoto", {
    quality: 85,
    resultType: CameraResultType.Uri,
  });
}

Provide a browser fallback

whenNative runs the first callback only in a Capacitor WebView and can return a web/SSR-safe fallback everywhere else.

import { Haptics, ImpactStyle } from "@capacitor/haptics";
import { mobile } from "@wrnexus/mobile";

mobile.registerPlugin("Haptics", Haptics);

export const confirmAction = () =>
  mobile.whenNative(
    () => mobile.invoke("Haptics", "impact", { style: ImpactStyle.Medium }),
    () => navigator.vibrate?.(30),
  );

Read an optional plugin without throwing

import type { NetworkPlugin } from "@capacitor/network";
import { mobile } from "@wrnexus/mobile";

const network = mobile.plugin<NetworkPlugin>("Network");
const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" };

API

  • registerPlugin(name, instance) registers a browser-imported plugin.
  • plugin(name) returns a plugin or undefined; requirePlugin(name) throws when absent.
  • invoke(plugin, method, options?) calls a registered method and returns its result.
  • whenNative(native, fallback?) selects native behavior without breaking SSR.
  • isNative() and platform() report the current Capacitor environment.

Unavailable required plugins throw MobileUnavailableError with an actionable message.

The package also provides portable application-facing primitives:

  • listenDeepLinks normalizes initial and live links with an allowed-scheme list.
  • PushNotifications performs permission gating and validates registrations.
  • SecureStorage namespaces and validates keys over an application-supplied encrypted Keychain/Keystore adapter; it does not mislabel browser localStorage as secure.
  • OfflineQueue persists bounded sync batches through a pluggable durable store.

Requirements / Notes

  • Capacitor plugin imports must remain in browser-owned modules.
  • @wrnexus/mobile re-exports native from @wrnexus/native for applications that prefer the higher-level cross-platform capability API.