Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mobile-starter.amisi.ai/llms.txt

Use this file to discover all available pages before exploring further.

@amisi/core

@amisi/core is the “boring but critical” layer. It contains cross-cutting utilities that every other package should depend on instead of re-implementing:
  • Storage wrappers
  • Logging
  • Errors + error boundary
  • Platform helpers
  • Small utilities

Storage

Secure storage

Use secure storage for sensitive values like tokens.
import { secureStorage } from '@amisi/core';

await secureStorage.setItem('accessToken', 'token');
const token = await secureStorage.getItem('accessToken');
await secureStorage.deleteItem('accessToken');

KV storage (MMKV)

Use KV storage for fast, synchronous persistence.
import { kvStorage } from '@amisi/core';

kvStorage.setItem('theme', 'dark');
const theme = kvStorage.getItem('theme');

kvStorage.setBoolean('hasSeenIntro', true);
const hasSeenIntro = kvStorage.getBoolean('hasSeenIntro');

Logging

Use the shared logger instead of console.*.
import { logger } from '@amisi/core';

logger.info('app_started');
logger.warn('network_slow', { latencyMs: 1200 });
logger.error('api_failed', new Error('Bad response'), { endpoint: '/me' });

Errors

AppError

Standardize errors using AppError.
import { AppError, createNetworkError, wrapError } from '@amisi/core';

throw createNetworkError('Request failed');

try {
  await doSomething();
} catch (e) {
  const err: AppError = wrapError(e);
  logger.error('operation_failed', err);
}

ErrorBoundary

Wrap your app once at the root.
import { ErrorBoundary } from '@amisi/core';

export function AppRoot() {
  return (
    <ErrorBoundary>
      <YourApp />
    </ErrorBoundary>
  );
}

Platform

Device helpers

import { device } from '@amisi/core';

if (device.isIOS()) {
  // iOS-only
}

const info = await device.getDeviceInfo();

App state

import { appState } from '@amisi/core';

const unsubscribe = appState.onBackground(() => {
  // pause polling
});

Utils

debounce

import { debounce } from '@amisi/core';

const debounced = debounce((value: string) => {
  // search
}, 300);

invariant

import { invariant } from '@amisi/core';

invariant(userId, 'userId is required');