npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tempest-react-sdk

v0.53.0

Published

SDK público da Tempest com componentes, hooks e integrações para projetos React.

Readme

tempest-react-sdk

npm version CI License: MIT React 18 / 19 TypeScript Bundle size

📖 Documentação completa (PT-BR) → · 📖 Full documentation (EN-US) →

O site MkDocs é bilíngue (PT-BR padrão · EN-US) com seletor de idioma 🇧🇷/🇺🇸 no cabeçalho. — The MkDocs site is bilingual (PT-BR default · EN-US) with a 🇧🇷/🇺🇸 language switcher in the header. The site is the navigable, per-module source of truth; this README stays the npm/GitHub landing page.

💡 pip install -r docs/requirements.txt && mkdocs serve é só para preview local — em produção use as URLs do GitHub Pages acima. / For local preview only — in production use the GitHub Pages URLs above.

Shared React/TypeScript building blocks used across Tempest frontends: UI components, hooks, HTTP client, auth store, query keys, forms (zod), real-time transports (SSE / WebSocket / Web Push / Service Worker), self-hosted geolocation (tile-free maps, trajectory tracking, distance/estimate math), a clickable Brazil map + states/cities dataset + BR payment/fiscal rails — Pix BR Code, boleto, NFe access key, national holidays (/br), theme, i18n, telemetry, feature flags, offline storage, error boundary, and a curated set of utilities (cn, formatCurrency, formatCPF, etc.).

The goal is to start every new React frontend with the same opinionated foundation already in place — no copy-pasting Button/Input styles, no rewriting the same auth Zustand store, no re-inventing the SSE reconnect loop. The patterns here are a distillation of what was consolidated in alofans-frontend and transport-admin-system — apps that consume the SDK gain consistency without paying for boilerplate.


Table of contents


Recommended stack

Vite + React + TypeScript is the supported consumer stack. The SDK is built and tested against Vite 8 in library mode and assumes a Vite-style host app:

  • ESM-first module resolution (the package's exports field declares import / require conditions).
  • import.meta.env for env vars (the recipes use import.meta.env.VITE_API_URL, import.meta.env.VITE_VAPID_PUBLIC_KEY, etc.).
  • Native CSS Modules (the package's hashed tempest_* class names are emitted as CSS Modules under the hood and consumed via the global tempest-react-sdk/styles.css import).
  • Fast HMR — provider files (ThemeProvider, I18nProvider, etc.) opt into React Refresh.
  • First-class compatibility with the Vite plugin ecosystem (vite-plugin-pwa for service workers, vite-plugin-dts, vite-plugin-svgr, etc.).

Fastest path — scaffold a fully wired app with the create-tempest-app CLI that ships inside the SDK (Vite @ alias, declarative routing, Zustand store, TanStack Query, providers — all pre-fiados):

# brand-new project (no install needed) — create the folder, scaffold into it with "."
mkdir my-app
cd my-app
npx -p tempest-react-sdk create-tempest-app .
npm install
cp .env.example .env
npm run dev

# want it installable + web-push + offline ready? add --pwa
npx -p tempest-react-sdk create-tempest-app . --pwa

. means "the current directory" — it preserves files you already have (git init, README.md, LICENSE) and takes the project name from the folder, so it is the recommended mode. Passing a name (create-tempest-app my-app) creates the folder instead, and aborts when it is not empty. Note there is no create-tempest-app package on npm — npm create tempest-app 404s, because the CLI is this package's bin; that is what -p tempest-react-sdk is for.

The --pwa flag overlays a manifest, install prompt (useBeforeInstallPrompt), push wiring (usePushSubscription), offline caching (app-shell precache + runtime caching), generated icons (tempestPwaIcons, via sharp) and a dev-mode service worker (tempestPwaDevSw) on top of the base app — full vite-plugin-pwa parity for the common case, built from tempest-react-sdk/sw + tempest-react-sdk/vite, with no vite-plugin-pwa. See Scaffold › PWA mode.

Already have a project? Install the SDK, then scaffold src/ + configs into it:

npm install tempest-react-sdk
npx create-tempest-app .     # merges into the current dir, skips existing files

See Scaffold a new app for the generated layout.

Or start from a bare Vite template and add the SDK manually:

npm create vite@latest my-app -- --template react-ts
cd my-app
npm install tempest-react-sdk

The demo gallery in examples/gallery is itself a Vite app — use it as the reference project layout.

Scope: client-side only. This SDK targets client-rendered, offline-capable PWAs — service worker, IndexedDB outbox, install prompt, background sync. It does not support server-side rendering or React Server Components: no module ships a "use client" directive, and components assume they mount in a browser. Next.js App Router is not a target.

Other client bundlers (Webpack, Rspack, Parcel) may work — the package ships standard ESM + CJS + rolled-up .d.ts — but they are not exercised in CI, and the Vite-specific pieces used in the recipes (import.meta.env, the /vite plugins) need their own equivalents. When in doubt, start with Vite.

Vite reference: https://vite.dev/guide/. React + TypeScript template: https://vite.dev/guide/#scaffolding-your-first-vite-project.


Install

npm install tempest-react-sdk

Via package.json:

{
  "dependencies": {
    "tempest-react-sdk": "^0.27.0"
  }
}

Requires React >=18 and Node >=22.12 to build.

Peer & bundled dependencies

react, react-dom and react-router are peer dependencies — those must come from the host app, because a second copy is not just wasted bytes, it is a second instance of a React context and it breaks at runtime.

Everything else (zod, zustand, dexie, react-hook-form, @tanstack/react-query, lucide-react) is a direct dependency of the SDK, installed automatically by npm install tempest-react-sdk. You never need to install them manually.

| Package | Status | Used by | | ------------------------------------- | ------------------- | ----------------------------------------------------------------------- | | react, react-dom (^18 \|\| ^19) | Peer (required) | Everything | | react-router (^7 \|\| ^8) | Peer (required) | AppRouter, defineRoutes, RouteGuard, routing re-exports | | @tanstack/react-query (^5) | Direct dep (auto) | QueryProvider, createQueryKeys, AppProviders | | zod (^3.23 \|\| ^4) | Direct dep (auto) | parseResponse, validateForm, zodResolver, useZodForm | | zustand (^4 \|\| ^5) | Direct dep (auto) | createAuthStore, createStore, createSelectors | | dexie (^4.4) | Direct dep (auto) | createOfflineStore | | react-hook-form (^7.76) | Direct dep (auto) | zodResolver, useZodForm, masked inputs | | lucide-react (^1.31) | Direct dep (auto) | Component icons (leftIcon/rightIcon on Input, Button, etc.) | | vite, @vitejs/plugin-react | Optional peer | createViteConfig (tempest-react-sdk/vite) — already in any Vite app |

The minimum install is just:

npm install tempest-react-sdk react react-dom react-router

Why react-router is a peer and not a bundled dep. It holds React context. A copy nested under tempest-react-sdk/node_modules is a different <Router> context than the one your app renders, so any SDK hook reaching for it throws useNavigate() may be used only in the context of a <Router> — a runtime crash, not a size regression. That is the same reason react itself is a peer, and it is why react-router is the one exception to the "everything is a direct dep" rule. The ^7 || ^8 range means an app on either major installs one copy and the SDK adapts to it: the re-exported surface is identical across both, and both ship the DOM bindings inside react-router (there is no separate react-router-dom).

Bundle impact: every bundled dep is externalised in the SDK's Rollup config, and dist/ ships with the module graph preserved (one file per source module), so your bundler drops what you don't import instead of inheriting one opaque blob — importing cn alone costs 153 B brotli, a full app shell around 6.8 KB. Your app's bundler (Vite / webpack / Rspack) resolves the deps from node_modules and tree-shakes them the same way — if you never call createOfflineStore, Dexie never enters your final bundle.

Version conflicts: if your app already pins (say) [email protected], npm dedupes when the range is compatible. If ranges diverge you get two copies — pin a single version in your own package.json to force one, or open an issue if the SDK's range is too tight.

Adapters for external SDKs (@sentry/browser, posthog-js, @growthbook/growthbook, launchdarkly-js-client-sdk) are not bundled — install those only when you opt into the adapter. The caller passes the SDK instance to the factory.

CSS import

Import the base stylesheet once at the entry of your app (e.g. main.tsx / src/index.tsx):

import "tempest-react-sdk/styles.css";

This injects the design tokens (--tempest-primary, --tempest-radius-md, ...), a minimal CSS reset, and the per-component CSS Modules. Tokens live on :root and on [data-tempest-theme="dark"], so the app can override them globally or per subtree (see Theming).

The styles ship hashed under the tempest_ namespace — they do not collide with Tailwind, Stitches, Linaria, or app-level CSS Modules.

Rebranding. The --tempest-* tokens are the only theming API, and createTheme writes them for you — primary alone yields the ten-step scale for both color schemes (dark inverts the ramp), plus the status families, the radius scale and the focus ring:

import { applyTheme, createTheme, themePresets } from "tempest-react-sdk";

applyTheme(createTheme({ primary: "#7c3aed", radius: "lg" }));
applyTheme(createTheme(themePresets.violet)); // or start from a preset

The ramp is derived in OKLCH (HSL lightness is not perceptual, which is what makes generated palettes look broken for some hues) and anchored at step 500, so the color you pass is the color your buttons get. --tempest-primary-foreground and the text-on-soft step are picked by measured contrast, not convention — hardcoding white breaks a yellow brand. See Theme › createTheme.

Optional layout layer. CSS Modules cover the inside of each component; the layer around them (page shell, two-column form, action row, card, a region that scrolls sideways instead of the page) is a second, opt-in stylesheet:

import "tempest-react-sdk/utilities.css";

~50 token-driven classes, all prefixed tempest-, 1.13 KB brotli — a page shell like <div className="tempest-container tempest-page"> with .tempest-grid-auto, .tempest-form-grid, .tempest-card, .tempest-truncate. It is not imported by styles.css, so an app with its own layout system pays nothing. It is deliberately not a utility framework: no p-4 mt-2 bg-blue-500 per value. See Styles › opt-in utility layer.


What's inside

Every module is re-exported from the package root — import { Button, useDebounce, createApiClient } from "tempest-react-sdk" always works.

| Module | Exports | | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | components | Avatar, Badge, Breadcrumbs, Button, Card, Checkbox, ChipInput, ConfirmDialog, Container, DatePicker, Drawer, EmptyState, ErrorState, FileUpload, Form (FormSection, FormRow, FormActions), Grid, Input, InstallBanner, InstallButton, Modal, Pagination, Progress, Radio, RadioGroup, SearchBar, Select, Skeleton, Spinner, Stack, Stepper, Switch, Table, Tabs, Textarea, Toast (ToastProvider, useToast), Tooltip, VirtualList | | hooks | useDebounce, usePagination, useClientFilter, useMediaQuery, useOnline, useDocumentVisibility, useIntersectionObserver, useResizeObserver, useClipboard, useKeyboardShortcut, useBeforeInstallPrompt, useIdle, useGeolocation, useScrollLock, useFocusTrap, useStableCallback, useAnnounce (+ pure announce/clearAnnouncer — one shared live-region pair), useDeepMemo, useObjectUrl, useLongPressHandlers (spreadable long-press handlers + wasLongPress() guard), useInstallPrompt (install-method resolver with decline cooldown), useServiceWorkerUpdate (consent-based SW update flow), useStorageEstimate + estimateStorage/requestPersistentStorage (Storage API quota & persistence), PWA env helpers isIOS/isAndroid/isAndroidWithoutPromptApi/isStandalone/buildOpenInChromeIntent, type BeforeInstallPromptEvent | | http | createApiClient, buildApiUrl, parseResponse, uploadWithProgress, createResumableUpload (tus 1.0.0: chunked + resumable, pause/resume/abort), createLocalUploadStorage, uploadFingerprint, retry, generateIdempotencyKey, usePoll, types: ApiClient, ApiClientConfig, ApiError, BuildApiUrlOptions, RequestOptions, RetryOptions, UploadProgressEvent, UploadWithProgressOptions, UsePollOptions, UsePollResult | | auth (peer: zustand) | createAuthStore, AuthGuard, decodeJWT, isJWTExpired, lazyWithRetry, createRefreshQueue, passkeys/WebAuthn: createPasskeyClient, usePasskeyRegistration, usePasskeySignIn, usePasskeyCapabilities, isPasskeySupported, isPlatformAuthenticatorAvailable, isConditionalMediationAvailable, classifyPasskeyError, PasskeyError, base64UrlToBytes, bytesToBase64Url, types: AuthState, CreateAuthStoreOptions, AuthGuardProps, DecodedJWT, LazyWithRetryOptions | | oauth (caller injects @react-oauth/google) | GoogleSignIn (normalises Google's credential/error payload), useOAuthCallback (runs the callback exchange once, StrictMode-proof), types: GoogleSignInProps, OAuthCredential, OAuthError, UseOAuthCallbackOptions, UseOAuthCallbackResult | | query (peer: @tanstack/react-query) | QueryProvider, createQueryKeys, STALE_TIME, CACHE_TIME, REFETCH_TIME, usePaginatedQuery, useCursorQuery, useOfflineMutation (optimistic offline mutation + cache rollback), upsertById/removeById (optimistic list-cache helpers), persistQueryClientOffline (IndexedDB cache persistence for offline reads) | | router (dep: react-router) | defineRoutes, AppRouter, RouteGuard, + re-exports (Link, NavLink, Outlet, Navigate, useNavigate, useParams, useSearchParams, useLocation, useMatch, useRouteError, redirect, BrowserRouter/HashRouter/MemoryRouter/Routes/Route), types: TempestRouteObject, RouterKind, AppRouterProps, RouteGuardProps | | store (dep: zustand) | createStore, createSelectors, types: CreateStoreOptions, CreateStorePersistOptions, WithSelectors | | app | AppProviders (composes ErrorBoundaryQueryProviderThemeProviderI18nProvider), type: AppProvidersProps | | vite (subpath tempest-react-sdk/vite) | createViteConfig, tempestPwaManifest (emits precache-manifest.json for offline precache), tempestPwaIcons (generates the PNG icon set from one SVG via sharp), tempestPwaDevSw (serves the SW under npm run dev), tempestPwaIcons({ appleSplash }) (Apple splash screens), types: CreateViteConfigOptions, ProxyEntry, TempestViteConfig, TempestPwaManifestOptions, TempestPwaIconsOptions, TempestPwaDevSwOptions, AppleSplashSpec, TempestVitePlugin | | forms (peer: zod, react-hook-form) | validateForm, zodResolver, useZodForm, validateCPF, validateCNPJ, formatCEP, formatCNPJ, unmask, CPFInput, CNPJInput, PhoneInput, CEPInput, MoneyInput, useViaCEP | | sse | createEventStream, useEventStream | | ws | createWebSocket (handshake timeout, silence watchdog, jittered backoff, navigator.onLine suspend, close-code classification, opened promise), useWebSocket, isRejectionCloseCode, HEARTBEAT_CLOSE_CODE | | webrtc | tuneOpus (Opus fmtp per audio m-line: per-key merge, stereo + sprop-stereo, inserts a missing fmtp), setTunedLocalDescription (falls back to the untouched SDP when the browser refuses the edit), setSenderBitrate | | geo (opt. peer leaflet) | haversineKm, pathLengthKm, bearingDeg, estimateTravel, createOSRMBackend, boundingBox, projectMercator, fitProjection, createPositionTracker, usePositionTracker, TrajectoryMap — tile-free SVG map + trajectory tracking (no external/paid API; Leaflet is an opt-in, lazy-loaded tile layer for self-hosted tiles), types: Coordinate, TrackPoint, TravelEstimate, TravelMode, GeoBounds, RoutingBackend | | br (subpath tempest-react-sdk/br) | BrazilMap, BrazilStateMap, BrazilStateCitySelect, listStates, getState, citiesByUf, statesByRegion, ufChoices, cityChoices, isValidUf, normalizeUf, isValidCity, loadBrUfGeoJson, loadStateMunicipalities, types UF, BrRegion, BrazilState — clickable 27-UF SVG map + per-state municipality submaps (bundled simplified IBGE GeoJSON, lazy per UF) + states/cities dataset, no external API; mirrors the FastAPI SDK utils/locations | | push | WebPushClient, WebPushUnsupportedError, WebPushPermissionDeniedError, usePushSubscription, urlBase64ToUint8Array, isPushSupported | | sw (also subpath tempest-react-sdk/sw) | registerServiceWorker (opt-in autoUpdate poll + reload, no vite-plugin-pwa), skipWaiting, unregisterAllServiceWorkers, installPushHandler, installNotificationClickHandler, installSkipWaitingListener, installPrecache (app-shell offline + Navigation Preload), installRuntimeCache (per-route caching, incl. rangeRequests), createPartialResponse (206 range slicing), installBackgroundSync (offline mutation queue + periodicsync), registerPeriodicSync (main-thread periodic sync), inspectCaches/clearCaches (cache observability) — the React-free tempest-react-sdk/sw subpath is ideal for bundling into your own sw.ts | | charts (subpath tempest-react-sdk/charts, opt. peer recharts) | AreaChart, BarChart, LineChart, PieChart, RadarChart, DEFAULT_CHART_COLORS — themed recharts wrappers (recharts externalized; install it only if you use charts) | | icons (subpath tempest-react-sdk/icons) | Icon, IconProvider, createIconRegistry, useIcon, preloadIcons, iconStatus, peekIcon, loadIcon, resolveIconAlias, isIconName, iconNames, iconAliases, type IconName — render any of lucide's 2024 icons by kebab-case slug. A literal slug becomes a static import via the tempestIcons() Vite plugin (zero extra requests); a runtime slug loads one chunk per initial letter (25 max) instead of the ~2000 chunk boundaries lucide-react's own DynamicIcon forces. Unknown slug renders fallback and never throws; lucide's 257 deprecated aliases keep resolving | | audio | createAudioPlayer, playAudio, stopAudio, useAudio, createAudioBus / useAudioBus (gain above 100%, post-mix limiter, setSinkId routing), DEFAULT_MAX_GAIN | | capture | BarcodeScanner, useBarcodeScanner, useTorch, isBarcodeDetectionSupported, getSupportedBarcodeFormats, createBarcodeDetector, normalizeBarcode, useVideoRecorder, createVideoRecorder, pickVideoMimeType, isVideoRecordingSupported, useScreenCapture, isScreenCaptureSupported, useSpeechRecognition, isSpeechRecognitionSupported, createMediaRecorder — barcode/QR reading over the native BarcodeDetector (Chromium-only, so inject a polyfill through detector or render the unsupported fallback), video + screen recording on the same engine as the audio recorder, and Web Speech dictation (Chromium streams the audio to a Google server) | | offline (peer: dexie) | createOfflineStore, createOfflineSync (outbox + delta-pull + watermark engine, now with subscribe/getState/dispose + cross-tab crossTab), useOfflineSync/useSyncStatus (reactive hooks), lastWriteWins/higherVersionWins (conflict resolvers), types: OfflineStore, OfflineStoreConfig, ListOptions, OfflineSync, OfflineSyncConfig, OutboxEntry, PullPage, SyncPhase, SyncState, SyncRunSummary, SyncTrigger, SyncStatus, SyncTone, WatermarkStore | | error-boundary | ErrorBoundary, useErrorHandler, types: ErrorBoundaryProps, ErrorBoundaryRenderProps | | theme | ThemeProvider, useTheme, getInitialTheme, themeInitScript, types: ThemeMode, ResolvedTheme | | i18n | createI18n, I18nProvider, useI18n, useTranslate, types: Catalog, Messages, I18n, InterpolationValues | | logger | createLogger, consoleSink, types: Logger, LogEntry, LogLevel, LoggerSink | | telemetry | TelemetryProvider, useTelemetry, consoleTelemetryAdapter, createSentryTelemetryAdapter, createPostHogTelemetryAdapter, types: TelemetryAdapter, TelemetryEvent, TelemetryUser, CreateSentryTelemetryAdapterOptions, SentryLike, CreatePostHogTelemetryAdapterOptions, PostHogLike | | perf | createInferenceProfiler, readDeviceProfile, cachedResponseBytes, formatDurationMs, types: InferenceProfiler, InferenceReport, InferenceReportOptions, DeviceProfile, ProfiledModel, ProfiledModelSize — custo de inferência on-device: cronômetro por etapa, perfil do dispositivo (cores/RAM/heap) e tamanho dos modelos em Cache Storage | | feature-flags | FeatureFlagsProvider, useFeatureFlag, useFlagValue, createInMemoryFlags, createGrowthBookFeatureFlagsAdapter, createLaunchDarklyFeatureFlagsAdapter, types: FeatureFlagsAdapter, FlagValue, GrowthBookLike, LDClientLike | | share | share, isShareSupported, shareOrDownloadBlob (Web Share file → download fallback), types: SharePayload, ShareResult, ShareOrDownloadOptions | | utils | cn, format BR (formatCurrency, formatDate, formatDateForInput, formatDateTime, formatPhone, formatCPF, formatPercent), storage, strings (slugify, truncate, capitalize, camelCase, kebabCase, pluralize), numbers (clamp, formatBytes, formatCompactNumber, percentOf), arrays (groupBy, uniqueBy, chunk, range), objects (pick, omit, deepMerge, isEmpty), guards (isDefined, isString, isNumber, isPlainObject, assertNever), functions (debounce, throttle, once, memoizeOne), promises (sleep, withTimeout), randomId, relativeTime, writeXlsx (generic single-sheet OOXML .xlsx writer → Uint8Array), CSV (toCsv, downloadCsv — RFC 4180 escaping + BOM) | | generic components | display (CopyButton, RelativeTime, Money, TruncateText, VisuallyHidden), headless (Portal, ClickOutside, ConditionalWrapper, For, ErrorText), media/content (Image, DataList, DescriptionList) | | Module | Exports | | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | components | Avatar, Badge, Breadcrumbs, Button, Card, Checkbox, ChipInput, ConfirmDialog, Container, DatePicker, Drawer, EmptyState, ErrorState, FileUpload, Form (FormSection, FormRow, FormActions), Grid, Input, InstallBanner, InstallButton, Modal, Pagination, Progress, Radio, RadioGroup, SearchBar, Select, Skeleton, Spinner, Stack, Stepper, Switch, Table, Tabs, Textarea, Toast (ToastProvider, useToast), Tooltip, VirtualList | | hooks | useDebounce, usePagination, useClientFilter, useMediaQuery, useOnline, useDocumentVisibility, useIntersectionObserver, useResizeObserver, useClipboard, useKeyboardShortcut, useBeforeInstallPrompt, useIdle, useGeolocation, useScrollLock, useFocusTrap, useStableCallback, useDeepMemo, useObjectUrl, useLongPressHandlers (spreadable long-press handlers + wasLongPress() guard), useInstallPrompt (install-method resolver with decline cooldown), useServiceWorkerUpdate (consent-based SW update flow), useStorageEstimate + estimateStorage/requestPersistentStorage (Storage API quota & persistence), PWA env helpers isIOS/isAndroid/isAndroidWithoutPromptApi/isStandalone/buildOpenInChromeIntent, type BeforeInstallPromptEvent | | http | createApiClient, buildApiUrl, parseResponse, uploadWithProgress, retry, generateIdempotencyKey, usePoll, types: ApiClient, ApiClientConfig, ApiError, BuildApiUrlOptions, RequestOptions, RetryOptions, UploadProgressEvent, UploadWithProgressOptions, UsePollOptions, UsePollResult | | auth (peer: zustand) | createAuthStore, AuthGuard, decodeJWT, isJWTExpired, lazyWithRetry, createRefreshQueue, types: AuthState, CreateAuthStoreOptions, AuthGuardProps, DecodedJWT, LazyWithRetryOptions | | oauth (caller injects @react-oauth/google) | GoogleSignIn (normalises Google's credential/error payload), useOAuthCallback (runs the callback exchange once, StrictMode-proof), types: GoogleSignInProps, OAuthCredential, OAuthError, UseOAuthCallbackOptions, UseOAuthCallbackResult | | query (peer: @tanstack/react-query) | QueryProvider, createQueryKeys, STALE_TIME, CACHE_TIME, REFETCH_TIME, usePaginatedQuery, useCursorQuery, useOfflineMutation (optimistic offline mutation + cache rollback), upsertById/removeById (optimistic list-cache helpers), persistQueryClientOffline (IndexedDB cache persistence for offline reads) | | router (dep: react-router) | defineRoutes, AppRouter, RouteGuard, + re-exports (Link, NavLink, Outlet, Navigate, useNavigate, useParams, useSearchParams, useLocation, useMatch, useRouteError, redirect, BrowserRouter/HashRouter/MemoryRouter/Routes/Route), types: TempestRouteObject, RouterKind, AppRouterProps, RouteGuardProps | | store (dep: zustand) | createStore, createSelectors, types: CreateStoreOptions, CreateStorePersistOptions, WithSelectors | | app | AppProviders (composes ErrorBoundaryQueryProviderThemeProviderI18nProvider), type: AppProvidersProps | | vite (subpath tempest-react-sdk/vite) | createViteConfig, tempestPwaManifest (emits precache-manifest.json for offline precache), tempestPwaIcons (generates the PNG icon set from one SVG via sharp), tempestPwaDevSw (serves the SW under npm run dev), tempestPwaIcons({ appleSplash }) (Apple splash screens), types: CreateViteConfigOptions, ProxyEntry, TempestViteConfig, TempestPwaManifestOptions, TempestPwaIconsOptions, TempestPwaDevSwOptions, AppleSplashSpec, TempestVitePlugin | | forms (peer: zod, react-hook-form) | validateForm, zodResolver, useZodForm, validateCPF, validateCNPJ, formatCEP, formatCNPJ, unmask, CPFInput, CNPJInput, PhoneInput, CEPInput, MoneyInput, useViaCEP | | sse | createEventStream, useEventStream | | ws | createWebSocket (handshake timeout, silence watchdog, jittered backoff, navigator.onLine suspend, close-code classification, opened promise), useWebSocket, isRejectionCloseCode, HEARTBEAT_CLOSE_CODE | | webrtc | tuneOpus (Opus fmtp per audio m-line: per-key merge, stereo + sprop-stereo, inserts a missing fmtp), setTunedLocalDescription (falls back to the untouched SDP when the browser refuses the edit), setSenderBitrate