@proveanything/smartlinks 1.11.2 → 1.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.11.2 | Generated: 2026-04-30T13:11:24.914Z
3
+ Version: 1.11.4 | Generated: 2026-04-30T13:59:47.020Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -58,7 +58,7 @@ Your container **never** detects the host directly. It receives a `host` prop fr
58
58
 
59
59
  Every container mounted by the SmartLinks Mobile launcher receives a single `host` prop — `AdminMobileHostContext`. Do not reach for `window.SmartlinksScanner` or `window.Capacitor` directly; both are wrapped here.
60
60
 
61
- > **SDK export** — `AdminMobileHostContext`, `AdminMobileCapability`, `AdminMobileHostId`, `AdminMobileEvent`, `ScannerEventSubscriber`, `MobileAdminComponentManifest`, and `MobileAdminBundleManifest` are all exported from `@proveanything/smartlinks`. Import via `import type { AdminMobileHostContext } from '@proveanything/smartlinks'` — no local mirror needed.
61
+ > **SDK export** — `AdminMobileHostContext`, `AdminMobileCapability`, `ActionableCapability`, `AdminMobileHostId`, `AdminMobileEvent`, `AdminMobileEventCallback`, `AdminMobileEventSubscriber`, `AdminMobileComponentManifest`, and `AdminMobileBundleManifest` are all exported from `@proveanything/smartlinks`. Import via `import type { AdminMobileHostContext } from '@proveanything/smartlinks'` — no local mirror needed. `ScannerEventSubscriber`, `MobileAdminComponentManifest`, and `MobileAdminBundleManifest` still export as deprecated aliases.
62
62
 
63
63
  ```typescript
64
64
  interface AdminMobileHostContext {
@@ -82,8 +82,8 @@ interface AdminMobileHostContext {
82
82
  keyboard: boolean
83
83
  }
84
84
 
85
- // Unified hardware event stream
86
- events: { subscribe: ScannerEventSubscriber }
85
+ // Unified hardware event stream — callback type: AdminMobileEventCallback
86
+ events: { subscribe: (cb: AdminMobileEventCallback) => () => void }
87
87
 
88
88
  // Promise-based hardware actions — reject with a structured error when unavailable
89
89
  actions: {
@@ -97,12 +97,12 @@ interface AdminMobileHostContext {
97
97
  }
98
98
  }
99
99
 
100
- // Host-provided UI helpers
100
+ // Host-provided UI helpers — all optional, see §3 note
101
101
  ui: {
102
- toast: (opts: { title: string; description?: string; variant?: 'default' | 'destructive' }) => void
103
- haptic: (style?: 'light' | 'success' | 'error') => void
104
- setHeaderTitle: (title: string | null) => void
105
- navigateBack: () => void
102
+ toast?: (opts: { title: string; description?: string; variant?: 'default' | 'destructive' }) => void
103
+ haptic?: (style?: 'light' | 'success' | 'error') => void
104
+ setHeaderTitle?: (title: string | null) => void
105
+ navigateBack?: () => void
106
106
  }
107
107
 
108
108
  // Network & device info
@@ -143,9 +143,10 @@ if (host.hardware.nfc) {
143
143
 
144
144
  ### `host.ui` — native helpers vs. your own components
145
145
 
146
- `host.ui.setHeaderTitle()` and `host.ui.navigateBack()` are **host-only**there is no in-container equivalent. Call them via `host.ui` or omit them.
146
+ All four `host.ui` methods are **optional by design**. A container may run in the Sidekick mobile shell, a standalone PWA or browser tab, Storybook, or a screenshot harness none of those environments is guaranteed to have a native toast system, a managed header, or a back stack. Forcing every host implementer to provide them would exclude the web and desktop use-cases the rest of the contract explicitly supports. Always guard with `?.`:
147
147
 
148
- `host.ui.toast()` and `host.ui.haptic()` are **optional conveniences**. Use them when you want native system feedback. When rendering in Storybook, unit tests, or a plain browser tab, your own `<Toaster />` is a perfectly valid substitute — you do not need to stub the entire `host.ui` surface just to get toast notifications.
148
+ - `host.ui.toast?.({...})` / `host.ui.haptic?.('success')` optional native feedback. Fall back to your own `<Toaster />` when absent.
149
+ - `host.ui.setHeaderTitle?.('Scanning…')` / `host.ui.navigateBack?.()` — host-shell integrations with no in-container equivalent. Silently no-op when the host doesn't implement them.
149
150
 
150
151
  **Stub pattern for testing and Storybook:**
151
152
 
@@ -222,12 +223,23 @@ The custom Kotlin shell and both Capacitor shells ship the same baseline plugin
222
223
  | `@capacitor/device` | `host.device.info()` |
223
224
  | `@capacitor/share` | `host.actions.share()` |
224
225
  | `@capacitor/clipboard` | `host.actions.clipboard.*` |
225
- | `@capacitor/preferences` | `host.storage.*` *(planned)* |
226
+ | `@capacitor/preferences` | `host.storage.*` *(planned — see note below)* |
226
227
  | `@capacitor/app` | host-managed (back button, deep links) |
227
228
  | `@capacitor/status-bar` | host-managed |
228
229
  | `@capacitor/keyboard` | host-managed |
229
230
  | `@capacitor/toast` | wired into `host.ui.toast()` |
230
231
 
232
+ > **`host.storage` — planned shape.** Once released, the surface will wrap `@capacitor/preferences` directly:
233
+ > ```ts
234
+ > host.storage: {
235
+ > get(key: string): Promise<string | null>
236
+ > set(key: string, value: string): Promise<void>
237
+ > remove(key: string): Promise<void>
238
+ > keys(): Promise<string[]>
239
+ > }
240
+ > ```
241
+ > Until then: `localStorage` works on web hosts; use `@capacitor/preferences` directly (bundle it in) on native.
242
+
231
243
  ### Tier 2 — capability-gated (declare in manifest)
232
244
 
233
245
  | Plugin | Capability flag |
@@ -385,7 +397,9 @@ try {
385
397
  | `lifecycle: 'pause'` | App backgrounded | Pause readers to save battery |
386
398
  | `lifecycle: 'resume'` | App foregrounded | Resubscribe; refresh stale data |
387
399
 
388
- Use `host.events.subscribe` for all lifecycle events — it fires identically on every host.
400
+ Use `host.events.subscribe` for all lifecycle events — all five host types (`custom-android`, `capacitor-ios`, `capacitor-android`, `pwa`, `browser`) are guaranteed to emit every `'pause'`/`'resume'`/`'offline'`/`'online'` phase. No `window.addEventListener('online')` fallback is needed.
401
+
402
+ > **Planned** — `phase: 'mount' | 'unmount'` events are on the roadmap. These will fire when the container becomes visible / is removed from the host view stack, enabling deferred reader start-up without a `useEffect` dependency.
389
403
 
390
404
  ---
391
405
 
@@ -521,8 +535,8 @@ export const MOBILE_ADMIN_MANIFEST = {
521
535
 
522
536
  - **Always check `host.hardware.X` before calling `host.actions.X`** — never assume a capability is available.
523
537
  - **Always wrap action calls in try/catch** — handle `HostPermissionDeniedError`, `HostTimeoutError`, and `HostCapabilityUnavailableError`.
524
- - **Use `host.ui.setHeaderTitle` and `host.ui.navigateBack`** for header integrationthese are host-only and have no in-container equivalent.
525
- - **`host.ui.toast` and `host.ui.haptic` are optional** use them for native feedback, or fall back to your own `<Toaster />` when testing in isolation.
538
+ - **All four `host.ui` methods are optional** (`toast`, `haptic`, `setHeaderTitle`, `navigateBack`)guard every call with `?.`. See the `host.ui` section above.
539
+ - **`host.ui.setHeaderTitle` and `host.ui.navigateBack`** integrate with the host shell and have no in-container equivalent; call with `?.`.
526
540
  - **Use `host.events.subscribe` for lifecycle events** — `'offline'`/`'online'`/`'pause'`/`'resume'` fire consistently on every host.
527
541
  - **Never call `initializeApi`, never use top-level SDK imports for API calls** — `host.SL` is already configured. `SL.method()` instead of `host.SL.method()` silently uses the wrong baseURL.
528
542
  - **Bundle Capacitor plugins in** (do not externalise) — so the component degrades gracefully on PWA/browser without crashing.
package/dist/index.d.ts CHANGED
@@ -23,5 +23,7 @@ export type { Collection, CollectionResponse, CollectionCreateRequest, Collectio
23
23
  export type { Proof, ProofResponse, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, } from "./types/proof";
24
24
  export type { QrShortCodeLookupResponse, } from "./types/qr";
25
25
  export type { ReverseTagLookupParams, ReverseTagLookupResponse, } from "./types/tags";
26
- export type { AdminMobileCapability, AdminMobileHostId, AdminMobileEvent, ScannerEventSubscriber, AdminMobileHostContext, MobileAdminComponentManifest, MobileAdminBundleManifest, } from './mobile-admin/types';
26
+ export type { AdminMobileCapability, ActionableCapability, AdminMobileHostId, AdminMobileEvent, AdminMobileEventCallback, AdminMobileEventSubscriber, ScannerEventSubscriber, // @deprecated use AdminMobileEventCallback
27
+ AdminMobileHostContext, AdminMobileComponentManifest, AdminMobileBundleManifest, MobileAdminComponentManifest, // @deprecated — use AdminMobileComponentManifest
28
+ MobileAdminBundleManifest, } from './mobile-admin/types';
27
29
  export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors';
@@ -5,6 +5,7 @@
5
5
  * All three classes call `Object.setPrototypeOf(this, new.target.prototype)` so
6
6
  * `instanceof` works correctly when transpiled to ES5.
7
7
  */
8
+ import type { ActionableCapability, AdminMobileHostId } from './types';
8
9
  /**
9
10
  * Thrown when a container requests a hardware action that the current host
10
11
  * does not support (e.g. calling `requestNfcTap` on a `'pwa'` host).
@@ -20,10 +21,10 @@
20
21
  */
21
22
  export declare class HostCapabilityUnavailableError extends Error {
22
23
  /** The capability that was requested but is unavailable. */
23
- capability: 'nfc' | 'rfid' | 'qr' | 'camera';
24
- /** `AdminMobileHostId` string of the host that rejected the request. */
25
- host: string;
26
- constructor(capability: HostCapabilityUnavailableError['capability'], host: string);
24
+ capability: ActionableCapability;
25
+ /** The host on which the capability is unavailable. */
26
+ host: AdminMobileHostId;
27
+ constructor(capability: ActionableCapability, host: AdminMobileHostId);
27
28
  }
28
29
  /**
29
30
  * Thrown when the user denies a runtime permission request (e.g. camera or
@@ -40,8 +41,8 @@ export declare class HostCapabilityUnavailableError extends Error {
40
41
  */
41
42
  export declare class HostPermissionDeniedError extends Error {
42
43
  /** The capability for which permission was denied. */
43
- capability: 'nfc' | 'rfid' | 'qr' | 'camera';
44
- constructor(capability: HostPermissionDeniedError['capability']);
44
+ capability: ActionableCapability;
45
+ constructor(capability: ActionableCapability);
45
46
  }
46
47
  /**
47
48
  * Thrown when a time-bounded host action (NFC tap, QR scan) exceeds its
@@ -58,7 +59,7 @@ export declare class HostPermissionDeniedError extends Error {
58
59
  */
59
60
  export declare class HostTimeoutError extends Error {
60
61
  /** The capability that timed out. */
61
- capability: 'nfc' | 'qr';
62
+ capability: Extract<ActionableCapability, 'nfc' | 'qr' | 'geolocation'>;
62
63
  /** The timeout threshold in milliseconds. */
63
64
  timeoutMs: number;
64
65
  constructor(capability: HostTimeoutError['capability'], timeoutMs: number);
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * Hardware/software capability tokens a mobile admin host may advertise.
3
3
  * Passed to `AdminMobileHostContext.capabilities` and to
4
- * `MobileAdminComponentManifest.capabilities`.
4
+ * `AdminMobileComponentManifest.capabilities`.
5
5
  */
6
6
  export type AdminMobileCapability = 'nfc' | 'nfc-advanced' | 'rfid' | 'qr' | 'camera' | 'keyboard' | 'geolocation' | 'push';
7
+ /**
8
+ * Subset of `AdminMobileCapability` that can be the subject of a structured
9
+ * error. `'keyboard'` is excluded — it is a passive event source with no
10
+ * request method that can fail.
11
+ */
12
+ export type ActionableCapability = Exclude<AdminMobileCapability, 'keyboard'>;
7
13
  /**
8
14
  * Canonical identifiers for mobile admin host environments.
9
15
  * Use for display / diagnostics only — feature-detect at runtime via
@@ -31,8 +37,19 @@ export type AdminMobileEvent = {
31
37
  type: 'lifecycle';
32
38
  phase: 'pause' | 'resume' | 'offline' | 'online';
33
39
  };
34
- /** Callback signature for `AdminMobileHostContext.events.subscribe`. */
35
- export type ScannerEventSubscriber = (event: AdminMobileEvent) => void;
40
+ /** Callback invoked for every hardware event emitted by the host. */
41
+ export type AdminMobileEventCallback = (event: AdminMobileEvent) => void;
42
+ /**
43
+ * The full type of `AdminMobileHostContext.events.subscribe` —
44
+ * takes a callback and returns a cleanup function.
45
+ */
46
+ export type AdminMobileEventSubscriber = (cb: AdminMobileEventCallback) => () => void;
47
+ /**
48
+ * @deprecated Renamed to `AdminMobileEventCallback` in 1.12.
49
+ * Will be removed in a future minor release.
50
+ * @see AdminMobileEventCallback
51
+ */
52
+ export type ScannerEventSubscriber = AdminMobileEventCallback;
36
53
  /**
37
54
  * The `host` prop passed to every mobile admin container component.
38
55
  *
@@ -82,7 +99,7 @@ export interface AdminMobileHostContext {
82
99
  * @param cb - Called for every incoming `AdminMobileEvent`.
83
100
  * @returns Cleanup function — call inside `useEffect` return.
84
101
  */
85
- subscribe: (cb: ScannerEventSubscriber) => () => void;
102
+ subscribe: (cb: AdminMobileEventCallback) => () => void;
86
103
  };
87
104
  /** Imperative hardware actions. */
88
105
  actions: {
@@ -137,8 +154,16 @@ export interface AdminMobileHostContext {
137
154
  }) => void;
138
155
  /** Trigger a haptic pulse. Optional — see interface note. */
139
156
  haptic?: (style?: 'light' | 'success' | 'error') => void;
140
- setHeaderTitle: (title: string | null) => void;
141
- navigateBack: () => void;
157
+ /**
158
+ * Optional host shell may not provide a managed header
159
+ * (browser tabs, Storybook, desktop views). Guard with `?.`.
160
+ */
161
+ setHeaderTitle?: (title: string | null) => void;
162
+ /**
163
+ * Optional — host shell may not have a native back stack
164
+ * (browser tabs, Storybook, desktop views). Guard with `?.`.
165
+ */
166
+ navigateBack?: () => void;
142
167
  };
143
168
  /** Network connectivity helpers. */
144
169
  network: {
@@ -162,7 +187,7 @@ export interface AdminMobileHostContext {
162
187
  _version: number;
163
188
  }
164
189
  /** Manifest metadata for a single mobile admin container component. */
165
- export interface MobileAdminComponentManifest {
190
+ export interface AdminMobileComponentManifest {
166
191
  /** Component export name (matches the export in the bundle). */
167
192
  name: string;
168
193
  /** Human-readable description shown in the host launcher UI. */
@@ -184,7 +209,7 @@ export interface MobileAdminComponentManifest {
184
209
  * Shape of the `mobileAdmin` key inside `app.manifest.json`.
185
210
  * Describes the bundle files and the components it exports.
186
211
  */
187
- export interface MobileAdminBundleManifest {
212
+ export interface AdminMobileBundleManifest {
188
213
  files: {
189
214
  js: {
190
215
  /** UMD bundle path (relative to dist root). Used by the custom-android host. */
@@ -195,5 +220,15 @@ export interface MobileAdminBundleManifest {
195
220
  /** CSS bundle path, or `null` if the component ships no styles. */
196
221
  css: string | null;
197
222
  };
198
- components: MobileAdminComponentManifest[];
223
+ components: AdminMobileComponentManifest[];
199
224
  }
225
+ /**
226
+ * @deprecated Renamed to `AdminMobileComponentManifest` in 1.12.
227
+ * @see AdminMobileComponentManifest
228
+ */
229
+ export type MobileAdminComponentManifest = AdminMobileComponentManifest;
230
+ /**
231
+ * @deprecated Renamed to `AdminMobileBundleManifest` in 1.12.
232
+ * @see AdminMobileBundleManifest
233
+ */
234
+ export type MobileAdminBundleManifest = AdminMobileBundleManifest;
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.11.2 | Generated: 2026-04-30T13:11:24.914Z
3
+ Version: 1.11.4 | Generated: 2026-04-30T13:59:47.020Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -58,7 +58,7 @@ Your container **never** detects the host directly. It receives a `host` prop fr
58
58
 
59
59
  Every container mounted by the SmartLinks Mobile launcher receives a single `host` prop — `AdminMobileHostContext`. Do not reach for `window.SmartlinksScanner` or `window.Capacitor` directly; both are wrapped here.
60
60
 
61
- > **SDK export** — `AdminMobileHostContext`, `AdminMobileCapability`, `AdminMobileHostId`, `AdminMobileEvent`, `ScannerEventSubscriber`, `MobileAdminComponentManifest`, and `MobileAdminBundleManifest` are all exported from `@proveanything/smartlinks`. Import via `import type { AdminMobileHostContext } from '@proveanything/smartlinks'` — no local mirror needed.
61
+ > **SDK export** — `AdminMobileHostContext`, `AdminMobileCapability`, `ActionableCapability`, `AdminMobileHostId`, `AdminMobileEvent`, `AdminMobileEventCallback`, `AdminMobileEventSubscriber`, `AdminMobileComponentManifest`, and `AdminMobileBundleManifest` are all exported from `@proveanything/smartlinks`. Import via `import type { AdminMobileHostContext } from '@proveanything/smartlinks'` — no local mirror needed. `ScannerEventSubscriber`, `MobileAdminComponentManifest`, and `MobileAdminBundleManifest` still export as deprecated aliases.
62
62
 
63
63
  ```typescript
64
64
  interface AdminMobileHostContext {
@@ -82,8 +82,8 @@ interface AdminMobileHostContext {
82
82
  keyboard: boolean
83
83
  }
84
84
 
85
- // Unified hardware event stream
86
- events: { subscribe: ScannerEventSubscriber }
85
+ // Unified hardware event stream — callback type: AdminMobileEventCallback
86
+ events: { subscribe: (cb: AdminMobileEventCallback) => () => void }
87
87
 
88
88
  // Promise-based hardware actions — reject with a structured error when unavailable
89
89
  actions: {
@@ -97,12 +97,12 @@ interface AdminMobileHostContext {
97
97
  }
98
98
  }
99
99
 
100
- // Host-provided UI helpers
100
+ // Host-provided UI helpers — all optional, see §3 note
101
101
  ui: {
102
- toast: (opts: { title: string; description?: string; variant?: 'default' | 'destructive' }) => void
103
- haptic: (style?: 'light' | 'success' | 'error') => void
104
- setHeaderTitle: (title: string | null) => void
105
- navigateBack: () => void
102
+ toast?: (opts: { title: string; description?: string; variant?: 'default' | 'destructive' }) => void
103
+ haptic?: (style?: 'light' | 'success' | 'error') => void
104
+ setHeaderTitle?: (title: string | null) => void
105
+ navigateBack?: () => void
106
106
  }
107
107
 
108
108
  // Network & device info
@@ -143,9 +143,10 @@ if (host.hardware.nfc) {
143
143
 
144
144
  ### `host.ui` — native helpers vs. your own components
145
145
 
146
- `host.ui.setHeaderTitle()` and `host.ui.navigateBack()` are **host-only**there is no in-container equivalent. Call them via `host.ui` or omit them.
146
+ All four `host.ui` methods are **optional by design**. A container may run in the Sidekick mobile shell, a standalone PWA or browser tab, Storybook, or a screenshot harness none of those environments is guaranteed to have a native toast system, a managed header, or a back stack. Forcing every host implementer to provide them would exclude the web and desktop use-cases the rest of the contract explicitly supports. Always guard with `?.`:
147
147
 
148
- `host.ui.toast()` and `host.ui.haptic()` are **optional conveniences**. Use them when you want native system feedback. When rendering in Storybook, unit tests, or a plain browser tab, your own `<Toaster />` is a perfectly valid substitute — you do not need to stub the entire `host.ui` surface just to get toast notifications.
148
+ - `host.ui.toast?.({...})` / `host.ui.haptic?.('success')` optional native feedback. Fall back to your own `<Toaster />` when absent.
149
+ - `host.ui.setHeaderTitle?.('Scanning…')` / `host.ui.navigateBack?.()` — host-shell integrations with no in-container equivalent. Silently no-op when the host doesn't implement them.
149
150
 
150
151
  **Stub pattern for testing and Storybook:**
151
152
 
@@ -222,12 +223,23 @@ The custom Kotlin shell and both Capacitor shells ship the same baseline plugin
222
223
  | `@capacitor/device` | `host.device.info()` |
223
224
  | `@capacitor/share` | `host.actions.share()` |
224
225
  | `@capacitor/clipboard` | `host.actions.clipboard.*` |
225
- | `@capacitor/preferences` | `host.storage.*` *(planned)* |
226
+ | `@capacitor/preferences` | `host.storage.*` *(planned — see note below)* |
226
227
  | `@capacitor/app` | host-managed (back button, deep links) |
227
228
  | `@capacitor/status-bar` | host-managed |
228
229
  | `@capacitor/keyboard` | host-managed |
229
230
  | `@capacitor/toast` | wired into `host.ui.toast()` |
230
231
 
232
+ > **`host.storage` — planned shape.** Once released, the surface will wrap `@capacitor/preferences` directly:
233
+ > ```ts
234
+ > host.storage: {
235
+ > get(key: string): Promise<string | null>
236
+ > set(key: string, value: string): Promise<void>
237
+ > remove(key: string): Promise<void>
238
+ > keys(): Promise<string[]>
239
+ > }
240
+ > ```
241
+ > Until then: `localStorage` works on web hosts; use `@capacitor/preferences` directly (bundle it in) on native.
242
+
231
243
  ### Tier 2 — capability-gated (declare in manifest)
232
244
 
233
245
  | Plugin | Capability flag |
@@ -385,7 +397,9 @@ try {
385
397
  | `lifecycle: 'pause'` | App backgrounded | Pause readers to save battery |
386
398
  | `lifecycle: 'resume'` | App foregrounded | Resubscribe; refresh stale data |
387
399
 
388
- Use `host.events.subscribe` for all lifecycle events — it fires identically on every host.
400
+ Use `host.events.subscribe` for all lifecycle events — all five host types (`custom-android`, `capacitor-ios`, `capacitor-android`, `pwa`, `browser`) are guaranteed to emit every `'pause'`/`'resume'`/`'offline'`/`'online'` phase. No `window.addEventListener('online')` fallback is needed.
401
+
402
+ > **Planned** — `phase: 'mount' | 'unmount'` events are on the roadmap. These will fire when the container becomes visible / is removed from the host view stack, enabling deferred reader start-up without a `useEffect` dependency.
389
403
 
390
404
  ---
391
405
 
@@ -521,8 +535,8 @@ export const MOBILE_ADMIN_MANIFEST = {
521
535
 
522
536
  - **Always check `host.hardware.X` before calling `host.actions.X`** — never assume a capability is available.
523
537
  - **Always wrap action calls in try/catch** — handle `HostPermissionDeniedError`, `HostTimeoutError`, and `HostCapabilityUnavailableError`.
524
- - **Use `host.ui.setHeaderTitle` and `host.ui.navigateBack`** for header integrationthese are host-only and have no in-container equivalent.
525
- - **`host.ui.toast` and `host.ui.haptic` are optional** use them for native feedback, or fall back to your own `<Toaster />` when testing in isolation.
538
+ - **All four `host.ui` methods are optional** (`toast`, `haptic`, `setHeaderTitle`, `navigateBack`)guard every call with `?.`. See the `host.ui` section above.
539
+ - **`host.ui.setHeaderTitle` and `host.ui.navigateBack`** integrate with the host shell and have no in-container equivalent; call with `?.`.
526
540
  - **Use `host.events.subscribe` for lifecycle events** — `'offline'`/`'online'`/`'pause'`/`'resume'` fire consistently on every host.
527
541
  - **Never call `initializeApi`, never use top-level SDK imports for API calls** — `host.SL` is already configured. `SL.method()` instead of `host.SL.method()` silently uses the wrong baseURL.
528
542
  - **Bundle Capacitor plugins in** (do not externalise) — so the component degrades gracefully on PWA/browser without crashing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",