tempest-react-sdk 0.54.0 → 0.56.0

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.
Files changed (45) hide show
  1. package/README.md +74 -73
  2. package/dist/components/AudioPlayer/AudioPlayer.cjs +1 -1
  3. package/dist/components/AudioPlayer/AudioPlayer.js +6 -6
  4. package/dist/components/VideoPlayer/VideoPlayer.cjs +2 -0
  5. package/dist/components/VideoPlayer/VideoPlayer.cjs.map +1 -0
  6. package/dist/components/VideoPlayer/VideoPlayer.js +229 -0
  7. package/dist/components/VideoPlayer/VideoPlayer.js.map +1 -0
  8. package/dist/components/VideoPlayer/VideoPlayer.module.cjs +2 -0
  9. package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -0
  10. package/dist/components/VideoPlayer/VideoPlayer.module.js +19 -0
  11. package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -0
  12. package/dist/components/VideoPlayer/playback-rates.cjs +2 -0
  13. package/dist/components/VideoPlayer/playback-rates.cjs.map +1 -0
  14. package/dist/components/VideoPlayer/playback-rates.js +11 -0
  15. package/dist/components/VideoPlayer/playback-rates.js.map +1 -0
  16. package/dist/imaging/exceptions.cjs +1 -1
  17. package/dist/imaging/exceptions.cjs.map +1 -1
  18. package/dist/imaging/exceptions.js +5 -1
  19. package/dist/imaging/exceptions.js.map +1 -1
  20. package/dist/imaging/frame.cjs +2 -0
  21. package/dist/imaging/frame.cjs.map +1 -0
  22. package/dist/imaging/frame.js +82 -0
  23. package/dist/imaging/frame.js.map +1 -0
  24. package/dist/imaging.cjs +1 -1
  25. package/dist/imaging.d.ts +611 -494
  26. package/dist/imaging.js +10 -9
  27. package/dist/styles/VideoPlayer.css +23 -0
  28. package/dist/styles/media.css +22 -0
  29. package/dist/styles.css +1 -1
  30. package/dist/tempest-react-sdk.cjs +1 -1
  31. package/dist/tempest-react-sdk.d.ts +389 -23
  32. package/dist/tempest-react-sdk.js +213 -209
  33. package/dist/webrtc/mesh-quality.cjs +2 -0
  34. package/dist/webrtc/mesh-quality.cjs.map +1 -0
  35. package/dist/webrtc/mesh-quality.js +51 -0
  36. package/dist/webrtc/mesh-quality.js.map +1 -0
  37. package/dist/webrtc/peer-link.cjs +2 -0
  38. package/dist/webrtc/peer-link.cjs.map +1 -0
  39. package/dist/webrtc/peer-link.js +45 -0
  40. package/dist/webrtc/peer-link.js.map +1 -0
  41. package/dist/webrtc/peer-mesh.cjs +2 -0
  42. package/dist/webrtc/peer-mesh.cjs.map +1 -0
  43. package/dist/webrtc/peer-mesh.js +155 -0
  44. package/dist/webrtc/peer-mesh.js.map +1 -0
  45. package/package.json +1 -1
package/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
 
14
14
  - **PT-BR:** [Scaffold](https://mauriciobenjamin700.github.io/tempest-react-sdk/scaffold/) · [Estrutura de app](https://mauriciobenjamin700.github.io/tempest-react-sdk/architecture/) · [Componentes](https://mauriciobenjamin700.github.io/tempest-react-sdk/components/) · [Hooks](https://mauriciobenjamin700.github.io/tempest-react-sdk/hooks/) · [Utilitários](https://mauriciobenjamin700.github.io/tempest-react-sdk/utilities/)
15
15
  - **EN-US:** [Scaffold](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/scaffold/) · [App foundation](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/architecture/) · [Components](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/components/) · [Hooks](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/hooks/) · [Utilities](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/utilities/)
16
+ - **🆕 Novo na plataforma web?** A trilha opcional **Fundamentos da Web** cobre HTML, CSS, JavaScript, TypeScript e React antes do tutorial — [PT-BR](https://mauriciobenjamin700.github.io/tempest-react-sdk/basics/) · [EN-US](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/basics/). Já sabe React? Vá direto ao tutorial — [PT-BR](https://mauriciobenjamin700.github.io/tempest-react-sdk/tutorial/) · [EN-US](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/tutorial/).
16
17
  - **🤖 For LLMs:** [llms.txt](https://mauriciobenjamin700.github.io/tempest-react-sdk/llms.txt) (curated index) · [llms-full.txt](https://mauriciobenjamin700.github.io/tempest-react-sdk/llms-full.txt) (full docs in one block) — [llmstxt.org](https://llmstxt.org) convention.
17
18
 
18
19
  > 💡 `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.
@@ -237,79 +238,79 @@ import "tempest-react-sdk/utilities.css";
237
238
 
238
239
  Every module is re-exported from the package root — `import { Button, useDebounce, createApiClient } from "tempest-react-sdk"` always works.
239
240
 
240
- | Module | Exports |
241
- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
242
- | `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` |
243
- | `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` |
244
- | `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` |
245
- | `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` |
246
- | `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` |
247
- | `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) |
248
- | `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` |
249
- | `store` _(dep: `zustand`)_ | `createStore`, `createSelectors`, types: `CreateStoreOptions`, `CreateStorePersistOptions`, `WithSelectors` |
250
- | `app` | `AppProviders` (composes `ErrorBoundary` → `QueryProvider` → `ThemeProvider` → `I18nProvider`), type: `AppProvidersProps` |
251
- | `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` |
252
- | `forms` _(peer: `zod`, `react-hook-form`)_ | `validateForm`, `zodResolver`, `useZodForm`, `validateCPF`, `validateCNPJ`, `formatCEP`, `formatCNPJ`, `unmask`, `CPFInput`, `CNPJInput`, `PhoneInput`, `CEPInput`, `MoneyInput`, `useViaCEP` |
253
- | `sse` | `createEventStream`, `useEventStream` (`onParseError` para frame que não é JSON) |
254
- | `ws` | `createWebSocket` (handshake timeout, silence watchdog, jittered backoff, `navigator.onLine` suspend, close-code classification, `opened` promise), `useWebSocket`, `onParseError` (frame que não é JSON: descarta em vez de entregar `string` como `T`), `isRejectionCloseCode`, `HEARTBEAT_CLOSE_CODE` |
255
- | `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`, `createLinkStatsSampler` / `useLinkStats` / `readRoundTripMs` (throughput as a delta, round trip from the **selected** candidate pair) |
256
- | `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` |
257
- | `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` |
258
- | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
259
- | `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` |
260
- | `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) |
261
- | `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 |
262
- | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio`, `createAudioBus` / `useAudioBus` (gain above 100%, post-mix limiter, `setSinkId` routing), `DEFAULT_MAX_GAIN` |
263
- | `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**) |
264
- | `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` |
265
- | `error-boundary` | `ErrorBoundary`, `useErrorHandler`, types: `ErrorBoundaryProps`, `ErrorBoundaryRenderProps` |
266
- | `theme` | `ThemeProvider`, `useTheme`, `getInitialTheme`, `themeInitScript`, types: `ThemeMode`, `ResolvedTheme` |
267
- | `i18n` | `createI18n`, `I18nProvider`, `useI18n`, `useTranslate`, types: `Catalog`, `Messages`, `I18n`, `InterpolationValues` |
268
- | `logger` | `createLogger`, `consoleSink`, types: `Logger`, `LogEntry`, `LogLevel`, `LoggerSink` |
269
- | `telemetry` | `TelemetryProvider`, `useTelemetry`, `consoleTelemetryAdapter`, `createSentryTelemetryAdapter`, `createPostHogTelemetryAdapter`, types: `TelemetryAdapter`, `TelemetryEvent`, `TelemetryUser`, `CreateSentryTelemetryAdapterOptions`, `SentryLike`, `CreatePostHogTelemetryAdapterOptions`, `PostHogLike` |
270
- | `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 |
271
- | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
272
- | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
273
- | `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) |
274
- | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
275
- | Module | Exports |
276
- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
277
- | `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` |
278
- | `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` |
279
- | `http` | `createApiClient`, `buildApiUrl`, `parseResponse`, `uploadWithProgress`, `retry`, `generateIdempotencyKey`, `usePoll`, types: `ApiClient`, `ApiClientConfig`, `ApiError`, `BuildApiUrlOptions`, `RequestOptions`, `RetryOptions`, `UploadProgressEvent`, `UploadWithProgressOptions`, `UsePollOptions`, `UsePollResult` |
280
- | `auth` _(peer: `zustand`)_ | `createAuthStore`, `AuthGuard`, `decodeJWT`, `isJWTExpired`, `lazyWithRetry`, `createRefreshQueue`, types: `AuthState`, `CreateAuthStoreOptions`, `AuthGuardProps`, `DecodedJWT`, `LazyWithRetryOptions` |
281
- | `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` |
282
- | `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) |
283
- | `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` |
284
- | `store` _(dep: `zustand`)_ | `createStore`, `createSelectors`, types: `CreateStoreOptions`, `CreateStorePersistOptions`, `WithSelectors` |
285
- | `app` | `AppProviders` (composes `ErrorBoundary` → `QueryProvider` → `ThemeProvider` → `I18nProvider`), type: `AppProvidersProps` |
286
- | `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` |
287
- | `forms` _(peer: `zod`, `react-hook-form`)_ | `validateForm`, `zodResolver`, `useZodForm`, `validateCPF`, `validateCNPJ`, `formatCEP`, `formatCNPJ`, `unmask`, `CPFInput`, `CNPJInput`, `PhoneInput`, `CEPInput`, `MoneyInput`, `useViaCEP` |
288
- | `sse` | `createEventStream`, `useEventStream` (`onParseError` para frame que não é JSON) |
289
- | `ws` | `createWebSocket` (handshake timeout, silence watchdog, jittered backoff, `navigator.onLine` suspend, close-code classification, `opened` promise), `useWebSocket`, `onParseError` (frame que não é JSON: descarta em vez de entregar `string` como `T`), `isRejectionCloseCode`, `HEARTBEAT_CLOSE_CODE` |
290
- | `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`, `createLinkStatsSampler` / `useLinkStats` / `readRoundTripMs` (throughput as a delta, round trip from the **selected** candidate pair) |
291
- | `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` |
292
- | `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` |
293
- | `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 |
294
- | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
295
- | `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` |
296
- | `editor` _(subpath `tempest-react-sdk/editor`, opt. peers `@tiptap/react`+`@tiptap/starter-kit`)_ | `RichTextEditor` — themed tiptap v3 rich-text editor with toolbar (tiptap externalized; install it only if you use the editor) |
297
- | `vision` _(subpath `tempest-react-sdk/vision`, opt. peer `onnxruntime-web`)_ | `Classifier`, `Detector`, `Segmenter`, `DetectClassify` (fused detect→classify pipeline) + `warmup()`, `raiseOnEmpty`/`NoDetectionsError`, `LetterboxPipeline`, `readFusionSpec` and results/labels/preprocess — on-device ONNX vision inference, vendored from `@mauriciobenjamin700/ort-vision-sdk-web` (onnxruntime-web externalized; install it only if you use vision). Plus browser capture primitives: `useCameraStream` (rear-camera `getUserMedia` + classified errors + `retry()`), `computeImageLuminance`/`isLuminanceAcceptable`/`LowLuminanceError`/`LUMINANCE_SAMPLE_MAX_EDGE` (BT.709 brightness), `useLiveLuminance` (live rAF sampling) |
298
- | `tabular` _(subpath `tempest-react-sdk/tabular`, opt. peer `onnxruntime-web`)_ | `TabularPredictor`, `useTabularPredictor` — scikit-learn models exported by `tempest-fastapi-sdk`'s `export_sklearn_to_onnx`, running in the browser with no inference server. Offline by design: `fetchModelBytes`/`isModelCached`/`cacheModelBytes`/`clearModelCache` (Cache Storage, cache-first) plus `configureOrtAssets`/`ortAssetUrls`/`ORT_WASM_ASSETS` for the runtime's WebAssembly binaries, which ONNX Runtime Web fetches at session creation. Import the default `onnxruntime-web` entry — the WebGPU build has no `ai.onnx.ml` kernels |
299
- | `imaging` _(subpath `tempest-react-sdk/imaging`, no deps)_ | `resizeImage`, `cropImage`, `rotateImage`, `flipImage`, `compressToTarget` (binary-searches quality into a byte budget), `createThumbnails` (several sizes from one decode), `decodeImage`/`readImageInfo`, `encodeImage`, `supportsImageType`/`bestSupportedType`, plus `useImagePreview`/`useImageProcessing`. Canvas only — decodes with EXIF orientation applied (phone photos arrive upright), reports the format actually produced (asking for AVIF where there is no encoder silently returns PNG), and re-encoding drops EXIF, which is the privacy step as much as the bandwidth one |
300
- | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio`, `createAudioBus` / `useAudioBus` (gain above 100%, post-mix limiter, `setSinkId` routing), `DEFAULT_MAX_GAIN` |
301
- | `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**) |
302
- | `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` |
303
- | `error-boundary` | `ErrorBoundary`, `useErrorHandler`, types: `ErrorBoundaryProps`, `ErrorBoundaryRenderProps` |
304
- | `theme` | `ThemeProvider`, `useTheme`, `getInitialTheme`, `themeInitScript`, types: `ThemeMode`, `ResolvedTheme` |
305
- | `i18n` | `createI18n`, `I18nProvider`, `useI18n`, `useTranslate`, types: `Catalog`, `Messages`, `I18n`, `InterpolationValues` |
306
- | `logger` | `createLogger`, `consoleSink`, types: `Logger`, `LogEntry`, `LogLevel`, `LoggerSink` |
307
- | `telemetry` | `TelemetryProvider`, `useTelemetry`, `consoleTelemetryAdapter`, `createSentryTelemetryAdapter`, `createPostHogTelemetryAdapter`, types: `TelemetryAdapter`, `TelemetryEvent`, `TelemetryUser`, `CreateSentryTelemetryAdapterOptions`, `SentryLike`, `CreatePostHogTelemetryAdapterOptions`, `PostHogLike` |
308
- | `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 |
309
- | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
310
- | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
311
- | `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) |
312
- | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
241
+ | Module | Exports |
242
+ | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
243
+ | `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` |
244
+ | `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` |
245
+ | `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` |
246
+ | `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` |
247
+ | `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` |
248
+ | `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) |
249
+ | `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` |
250
+ | `store` _(dep: `zustand`)_ | `createStore`, `createSelectors`, types: `CreateStoreOptions`, `CreateStorePersistOptions`, `WithSelectors` |
251
+ | `app` | `AppProviders` (composes `ErrorBoundary` → `QueryProvider` → `ThemeProvider` → `I18nProvider`), type: `AppProvidersProps` |
252
+ | `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` |
253
+ | `forms` _(peer: `zod`, `react-hook-form`)_ | `validateForm`, `zodResolver`, `useZodForm`, `validateCPF`, `validateCNPJ`, `formatCEP`, `formatCNPJ`, `unmask`, `CPFInput`, `CNPJInput`, `PhoneInput`, `CEPInput`, `MoneyInput`, `useViaCEP` |
254
+ | `sse` | `createEventStream`, `useEventStream` (`onParseError` para frame que não é JSON) |
255
+ | `ws` | `createWebSocket` (handshake timeout, silence watchdog, jittered backoff, `navigator.onLine` suspend, close-code classification, `opened` promise), `useWebSocket`, `onParseError` (frame que não é JSON: descarta em vez de entregar `string` como `T`), `isRejectionCloseCode`, `HEARTBEAT_CLOSE_CODE` |
256
+ | `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`, `createLinkStatsSampler` / `useLinkStats` / `readRoundTripMs` (throughput as a delta, round trip from the **selected** candidate pair) |
257
+ | `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` |
258
+ | `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` |
259
+ | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
260
+ | `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` |
261
+ | `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) |
262
+ | `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 |
263
+ | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio`, `createAudioBus` / `useAudioBus` (gain above 100%, post-mix limiter, `setSinkId` routing), `DEFAULT_MAX_GAIN` |
264
+ | `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**) |
265
+ | `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` |
266
+ | `error-boundary` | `ErrorBoundary`, `useErrorHandler`, types: `ErrorBoundaryProps`, `ErrorBoundaryRenderProps` |
267
+ | `theme` | `ThemeProvider`, `useTheme`, `getInitialTheme`, `themeInitScript`, types: `ThemeMode`, `ResolvedTheme` |
268
+ | `i18n` | `createI18n`, `I18nProvider`, `useI18n`, `useTranslate`, types: `Catalog`, `Messages`, `I18n`, `InterpolationValues` |
269
+ | `logger` | `createLogger`, `consoleSink`, types: `Logger`, `LogEntry`, `LogLevel`, `LoggerSink` |
270
+ | `telemetry` | `TelemetryProvider`, `useTelemetry`, `consoleTelemetryAdapter`, `createSentryTelemetryAdapter`, `createPostHogTelemetryAdapter`, types: `TelemetryAdapter`, `TelemetryEvent`, `TelemetryUser`, `CreateSentryTelemetryAdapterOptions`, `SentryLike`, `CreatePostHogTelemetryAdapterOptions`, `PostHogLike` |
271
+ | `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 |
272
+ | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
273
+ | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
274
+ | `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) |
275
+ | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
276
+ | Module | Exports |
277
+ | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
278
+ | `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` |
279
+ | `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` |
280
+ | `http` | `createApiClient`, `buildApiUrl`, `parseResponse`, `uploadWithProgress`, `retry`, `generateIdempotencyKey`, `usePoll`, types: `ApiClient`, `ApiClientConfig`, `ApiError`, `BuildApiUrlOptions`, `RequestOptions`, `RetryOptions`, `UploadProgressEvent`, `UploadWithProgressOptions`, `UsePollOptions`, `UsePollResult` |
281
+ | `auth` _(peer: `zustand`)_ | `createAuthStore`, `AuthGuard`, `decodeJWT`, `isJWTExpired`, `lazyWithRetry`, `createRefreshQueue`, types: `AuthState`, `CreateAuthStoreOptions`, `AuthGuardProps`, `DecodedJWT`, `LazyWithRetryOptions` |
282
+ | `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` |
283
+ | `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) |
284
+ | `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` |
285
+ | `store` _(dep: `zustand`)_ | `createStore`, `createSelectors`, types: `CreateStoreOptions`, `CreateStorePersistOptions`, `WithSelectors` |
286
+ | `app` | `AppProviders` (composes `ErrorBoundary` → `QueryProvider` → `ThemeProvider` → `I18nProvider`), type: `AppProvidersProps` |
287
+ | `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` |
288
+ | `forms` _(peer: `zod`, `react-hook-form`)_ | `validateForm`, `zodResolver`, `useZodForm`, `validateCPF`, `validateCNPJ`, `formatCEP`, `formatCNPJ`, `unmask`, `CPFInput`, `CNPJInput`, `PhoneInput`, `CEPInput`, `MoneyInput`, `useViaCEP` |
289
+ | `sse` | `createEventStream`, `useEventStream` (`onParseError` para frame que não é JSON) |
290
+ | `ws` | `createWebSocket` (handshake timeout, silence watchdog, jittered backoff, `navigator.onLine` suspend, close-code classification, `opened` promise), `useWebSocket`, `onParseError` (frame que não é JSON: descarta em vez de entregar `string` como `T`), `isRejectionCloseCode`, `HEARTBEAT_CLOSE_CODE` |
291
+ | `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`, `createLinkStatsSampler` / `useLinkStats` / `readRoundTripMs` (throughput as a delta, round trip from the **selected** candidate pair) |
292
+ | `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` |
293
+ | `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` |
294
+ | `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 |
295
+ | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
296
+ | `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` |
297
+ | `editor` _(subpath `tempest-react-sdk/editor`, opt. peers `@tiptap/react`+`@tiptap/starter-kit`)_ | `RichTextEditor` — themed tiptap v3 rich-text editor with toolbar (tiptap externalized; install it only if you use the editor) |
298
+ | `vision` _(subpath `tempest-react-sdk/vision`, opt. peer `onnxruntime-web`)_ | `Classifier`, `Detector`, `Segmenter`, `DetectClassify` (fused detect→classify pipeline) + `warmup()`, `raiseOnEmpty`/`NoDetectionsError`, `LetterboxPipeline`, `readFusionSpec` and results/labels/preprocess — on-device ONNX vision inference, vendored from `@mauriciobenjamin700/ort-vision-sdk-web` (onnxruntime-web externalized; install it only if you use vision). Plus browser capture primitives: `useCameraStream` (rear-camera `getUserMedia` + classified errors + `retry()`), `computeImageLuminance`/`isLuminanceAcceptable`/`LowLuminanceError`/`LUMINANCE_SAMPLE_MAX_EDGE` (BT.709 brightness), `useLiveLuminance` (live rAF sampling) |
299
+ | `tabular` _(subpath `tempest-react-sdk/tabular`, opt. peer `onnxruntime-web`)_ | `TabularPredictor`, `useTabularPredictor` — scikit-learn models exported by `tempest-fastapi-sdk`'s `export_sklearn_to_onnx`, running in the browser with no inference server. Offline by design: `fetchModelBytes`/`isModelCached`/`cacheModelBytes`/`clearModelCache` (Cache Storage, cache-first) plus `configureOrtAssets`/`ortAssetUrls`/`ORT_WASM_ASSETS` for the runtime's WebAssembly binaries, which ONNX Runtime Web fetches at session creation. Import the default `onnxruntime-web` entry — the WebGPU build has no `ai.onnx.ml` kernels |
300
+ | `imaging` _(subpath `tempest-react-sdk/imaging`, no deps)_ | `resizeImage`, `cropImage`, `rotateImage`, `flipImage`, `compressToTarget` (binary-searches quality into a byte budget), `createThumbnails` (several sizes from one decode), `captureFrame` (one frame out of a `<video>`, at the instant you ask for), `decodeImage`/`readImageInfo`, `encodeImage`, `supportsImageType`/`bestSupportedType`, plus `useImagePreview`/`useImageProcessing`. Canvas only — decodes with EXIF orientation applied (phone photos arrive upright), reports the format actually produced (asking for AVIF where there is no encoder silently returns PNG), and re-encoding drops EXIF, which is the privacy step as much as the bandwidth one. `captureFrame` is the one with teeth: `seeked` does not mean the new frame is readable, so the naive seek-then-draw returns the neighbouring frame with no error — and a `MediaRecorder` blob reports no duration until it is probed for one, which it does for you |
301
+ | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio`, `createAudioBus` / `useAudioBus` (gain above 100%, post-mix limiter, `setSinkId` routing), `DEFAULT_MAX_GAIN` |
302
+ | `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**) |
303
+ | `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` |
304
+ | `error-boundary` | `ErrorBoundary`, `useErrorHandler`, types: `ErrorBoundaryProps`, `ErrorBoundaryRenderProps` |
305
+ | `theme` | `ThemeProvider`, `useTheme`, `getInitialTheme`, `themeInitScript`, types: `ThemeMode`, `ResolvedTheme` |
306
+ | `i18n` | `createI18n`, `I18nProvider`, `useI18n`, `useTranslate`, types: `Catalog`, `Messages`, `I18n`, `InterpolationValues` |
307
+ | `logger` | `createLogger`, `consoleSink`, types: `Logger`, `LogEntry`, `LogLevel`, `LoggerSink` |
308
+ | `telemetry` | `TelemetryProvider`, `useTelemetry`, `consoleTelemetryAdapter`, `createSentryTelemetryAdapter`, `createPostHogTelemetryAdapter`, types: `TelemetryAdapter`, `TelemetryEvent`, `TelemetryUser`, `CreateSentryTelemetryAdapterOptions`, `SentryLike`, `CreatePostHogTelemetryAdapterOptions`, `PostHogLike` |
309
+ | `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 |
310
+ | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
311
+ | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
312
+ | `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) |
313
+ | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
313
314
 
314
315
  Full per-module docs are published as a bilingual MkDocs site on GitHub Pages — **[Português (BR)](https://mauriciobenjamin700.github.io/tempest-react-sdk/)** / **[English (US)](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/)** (one page per module + draw.io diagrams in [`docs/diagrams/`](./docs/diagrams)). The source markdown lives in [`docs/`](./docs) (PT-BR base files + `.en.md` translations).
315
316
 
@@ -1,2 +1,2 @@
1
- const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-object-url.cjs"),n=require("../../audio/audio-output.cjs"),r=require("../../audio/duration.cjs"),i=require("./AudioPlayer.module.cjs");let a=require("react"),o=require("react/jsx-runtime"),s=require("lucide-react");var c={"pt-BR":{play:`Tocar`,pause:`Pausar`,seek:`Posição`},en:{play:`Play`,pause:`Pause`,seek:`Seek`}};function l({src:l,durationMs:u,sinkId:d,autoPlay:f=!1,loop:p=!1,locale:m=`pt-BR`,actions:h,onEnded:g,onError:_,disabled:v=!1,className:y,...b}){let x=c[m],S=(0,a.useRef)(null),[C,w]=(0,a.useState)(!1),[T,E]=(0,a.useState)(0),[D,O]=(0,a.useState)(1/0),k=(0,a.useRef)(!1),A=t.useObjectUrl(typeof l==`string`?null:l),j=typeof l==`string`?l:A,M=Number.isFinite(u)?u:D,N=Number.isFinite(M)&&M>0;(0,a.useEffect)(()=>{E(0),w(!1),O(1/0),k.current=!1},[j]),(0,a.useEffect)(()=>{d!==void 0&&n.setAudioOutput(S.current,d)},[d,j]);let P=()=>{let e=S.current;if(!e)return;if(Number.isFinite(e.duration)){O(e.duration*1e3);return}if(k.current||Number.isFinite(u))return;k.current=!0;let t=()=>{e.removeEventListener(`timeupdate`,t),Number.isFinite(e.duration)&&O(e.duration*1e3),e.currentTime=0};e.addEventListener(`timeupdate`,t),e.currentTime=1e101},F=()=>{let e=S.current;if(!(!e||!j)){if(e.paused){e.play().then(()=>w(!0)).catch(e=>_?.(e));return}e.pause(),w(!1)}},I=e=>{let t=S.current;!t||!N||(t.currentTime=e/1e3,E(e))};return(0,o.jsxs)(`div`,{className:e.cn(i.default.player,y),...b,children:[(0,o.jsx)(`audio`,{ref:S,src:j??void 0,loop:p,autoPlay:f,preload:`metadata`,onLoadedMetadata:P,onDurationChange:P,onTimeUpdate:()=>{let e=S.current;e&&E(e.currentTime*1e3)},onPlay:()=>w(!0),onPause:()=>w(!1),onEnded:()=>{w(!1),E(0),g?.()},onError:e=>_?.(e)}),(0,o.jsx)(`button`,{type:`button`,className:i.default.transport,onClick:F,disabled:v||!j,"aria-label":C?x.pause:x.play,title:C?x.pause:x.play,children:C?(0,o.jsx)(s.Pause,{size:16,"aria-hidden":!0}):(0,o.jsx)(s.Play,{size:16,"aria-hidden":!0})}),(0,o.jsx)(`input`,{type:`range`,className:i.default.seek,min:0,max:N?Math.round(M):0,step:100,value:Math.min(Math.round(T),N?Math.round(M):0),onChange:e=>I(Number(e.target.value)),disabled:v||!N,"aria-label":x.seek,"aria-valuetext":`${r.formatDuration(T)} / ${r.formatDuration(M)}`}),(0,o.jsxs)(`span`,{className:i.default.time,children:[(0,o.jsx)(`span`,{children:r.formatDuration(T)}),(0,o.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,o.jsx)(`span`,{children:r.formatDuration(M)})]}),h&&(0,o.jsx)(`span`,{className:i.default.actions,children:h})]})}exports.AudioPlayer=l;
1
+ const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-object-url.cjs"),n=require("../../audio/duration.cjs"),r=require("../../audio/audio-output.cjs"),i=require("./AudioPlayer.module.cjs");let a=require("react"),o=require("react/jsx-runtime"),s=require("lucide-react");var c={"pt-BR":{play:`Tocar`,pause:`Pausar`,seek:`Posição`},en:{play:`Play`,pause:`Pause`,seek:`Seek`}};function l({src:l,durationMs:u,sinkId:d,autoPlay:f=!1,loop:p=!1,locale:m=`pt-BR`,actions:h,onEnded:g,onError:_,disabled:v=!1,className:y,...b}){let x=c[m],S=(0,a.useRef)(null),[C,w]=(0,a.useState)(!1),[T,E]=(0,a.useState)(0),[D,O]=(0,a.useState)(1/0),k=(0,a.useRef)(!1),A=t.useObjectUrl(typeof l==`string`?null:l),j=typeof l==`string`?l:A,M=Number.isFinite(u)?u:D,N=Number.isFinite(M)&&M>0;(0,a.useEffect)(()=>{E(0),w(!1),O(1/0),k.current=!1},[j]),(0,a.useEffect)(()=>{d!==void 0&&r.setAudioOutput(S.current,d)},[d,j]);let P=()=>{let e=S.current;if(!e)return;if(Number.isFinite(e.duration)){O(e.duration*1e3);return}if(k.current||Number.isFinite(u))return;k.current=!0;let t=()=>{e.removeEventListener(`timeupdate`,t),Number.isFinite(e.duration)&&O(e.duration*1e3),e.currentTime=0};e.addEventListener(`timeupdate`,t),e.currentTime=1e101},F=()=>{let e=S.current;if(!(!e||!j)){if(e.paused){e.play().then(()=>w(!0)).catch(e=>_?.(e));return}e.pause(),w(!1)}},I=e=>{let t=S.current;!t||!N||(t.currentTime=e/1e3,E(e))};return(0,o.jsxs)(`div`,{className:e.cn(i.default.player,y),...b,children:[(0,o.jsx)(`audio`,{ref:S,src:j??void 0,loop:p,autoPlay:f,preload:`metadata`,onLoadedMetadata:P,onDurationChange:P,onTimeUpdate:()=>{let e=S.current;e&&E(e.currentTime*1e3)},onPlay:()=>w(!0),onPause:()=>w(!1),onEnded:()=>{w(!1),E(0),g?.()},onError:e=>_?.(e)}),(0,o.jsx)(`button`,{type:`button`,className:i.default.transport,onClick:F,disabled:v||!j,"aria-label":C?x.pause:x.play,title:C?x.pause:x.play,children:C?(0,o.jsx)(s.Pause,{size:16,"aria-hidden":!0}):(0,o.jsx)(s.Play,{size:16,"aria-hidden":!0})}),(0,o.jsx)(`input`,{type:`range`,className:i.default.seek,min:0,max:N?Math.round(M):0,step:100,value:Math.min(Math.round(T),N?Math.round(M):0),onChange:e=>I(Number(e.target.value)),disabled:v||!N,"aria-label":x.seek,"aria-valuetext":`${n.formatDuration(T)} / ${n.formatDuration(M)}`}),(0,o.jsxs)(`span`,{className:i.default.time,children:[(0,o.jsx)(`span`,{children:n.formatDuration(T)}),(0,o.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,o.jsx)(`span`,{children:n.formatDuration(M)})]}),h&&(0,o.jsx)(`span`,{className:i.default.actions,children:h})]})}exports.AudioPlayer=l;
2
2
  //# sourceMappingURL=AudioPlayer.cjs.map
@@ -1,7 +1,7 @@
1
1
  import { cn as e } from "../../utils/cn.js";
2
2
  import { useObjectUrl as t } from "../../hooks/use-object-url.js";
3
- import { setAudioOutput as n } from "../../audio/audio-output.js";
4
- import { formatDuration as r } from "../../audio/duration.js";
3
+ import { formatDuration as n } from "../../audio/duration.js";
4
+ import { setAudioOutput as r } from "../../audio/audio-output.js";
5
5
  import i from "./AudioPlayer.module.js";
6
6
  import { useEffect as a, useRef as o, useState as s } from "react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
@@ -24,7 +24,7 @@ function p({ src: p, durationMs: m, sinkId: h, autoPlay: g = !1, loop: _ = !1, l
24
24
  a(() => {
25
25
  A(0), O(!1), M(Infinity), N.current = !1;
26
26
  }, [F]), a(() => {
27
- h !== void 0 && n(E.current, h);
27
+ h !== void 0 && r(E.current, h);
28
28
  }, [h, F]);
29
29
  let R = () => {
30
30
  let e = E.current;
@@ -97,17 +97,17 @@ function p({ src: p, durationMs: m, sinkId: h, autoPlay: g = !1, loop: _ = !1, l
97
97
  onChange: (e) => B(Number(e.target.value)),
98
98
  disabled: S || !L,
99
99
  "aria-label": T.seek,
100
- "aria-valuetext": `${r(k)} / ${r(I)}`
100
+ "aria-valuetext": `${n(k)} / ${n(I)}`
101
101
  }),
102
102
  /* @__PURE__ */ l("span", {
103
103
  className: i.time,
104
104
  children: [
105
- /* @__PURE__ */ c("span", { children: r(k) }),
105
+ /* @__PURE__ */ c("span", { children: n(k) }),
106
106
  /* @__PURE__ */ c("span", {
107
107
  "aria-hidden": "true",
108
108
  children: "/"
109
109
  }),
110
- /* @__PURE__ */ c("span", { children: r(I) })
110
+ /* @__PURE__ */ c("span", { children: n(I) })
111
111
  ]
112
112
  }),
113
113
  y && /* @__PURE__ */ c("span", {
@@ -0,0 +1,2 @@
1
+ const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-fullscreen.cjs"),n=require("../../hooks/use-object-url.cjs"),r=require("./playback-rates.cjs"),i=require("../../audio/duration.cjs"),a=require("./VideoPlayer.module.cjs");let o=require("react"),s=require("react/jsx-runtime"),c=require("lucide-react");var l={"pt-BR":{play:`Tocar`,pause:`Pausar`,seek:`Posição`,mute:`Silenciar`,unmute:`Ativar som`,volume:`Volume`,rate:`Velocidade`,enterFullscreen:`Tela cheia`,exitFullscreen:`Sair da tela cheia`},en:{play:`Play`,pause:`Pause`,seek:`Seek`,mute:`Mute`,unmute:`Unmute`,volume:`Volume`,rate:`Speed`,enterFullscreen:`Full screen`,exitFullscreen:`Exit full screen`}};function u(e,t){return`${e.toLocaleString(t===`en`?`en-US`:`pt-BR`)}×`}function d({src:d,durationMs:f,poster:p,tracks:m,aspectRatio:h=16/9,rate:g,rates:_=r.DEFAULT_PLAYBACK_RATES,onRateChange:v,shiftPitch:y=!1,fullscreen:b=!0,autoPlay:x=!1,loop:S=!1,muted:C=!1,locale:w=`pt-BR`,actions:T,onEnded:E,onError:D,disabled:O=!1,className:k,...A}){let j=l[w],M=(0,o.useRef)(null),N=(0,o.useRef)(null),P=(0,o.useRef)(!1),[F,I]=(0,o.useState)(!1),[L,R]=(0,o.useState)(0),[z,B]=(0,o.useState)(1/0),[V,H]=(0,o.useState)(g??1),[U,W]=(0,o.useState)(1),[G,K]=(0,o.useState)(C),q=t.useFullscreen(M),J=n.useObjectUrl(typeof d==`string`?null:d),Y=typeof d==`string`?d:J,X=g??V,Z=Number.isFinite(f)?f:z,Q=Number.isFinite(Z)&&Z>0;(0,o.useEffect)(()=>{R(0),I(!1),B(1/0),P.current=!1},[Y]),(0,o.useEffect)(()=>{let e=N.current;e&&(e.defaultPlaybackRate=X,e.playbackRate=X,e.preservesPitch=!y)},[X,y,Y]),(0,o.useEffect)(()=>{let e=N.current;e&&(e.volume=U,e.muted=G)},[U,G,Y]);let $=()=>{let e=N.current;if(!e)return;if(Number.isFinite(e.duration)){B(e.duration*1e3);return}if(P.current||Number.isFinite(f))return;P.current=!0;let t=()=>{e.removeEventListener(`timeupdate`,t),Number.isFinite(e.duration)&&B(e.duration*1e3),e.currentTime=0};e.addEventListener(`timeupdate`,t),e.currentTime=1e101},ee=()=>{let e=N.current;if(!(!e||!Y)){if(e.paused){Promise.resolve(e.play()).then(()=>I(!0)).catch(e=>D?.(e));return}e.pause(),I(!1)}},te=e=>{let t=N.current;!t||!Q||(t.currentTime=e/1e3,R(e))},ne=e=>{g===void 0&&H(e),v?.(e)};return(0,s.jsxs)(`div`,{ref:M,className:e.cn(a.default.player,q.isFullscreen&&a.default.immersive,k),...A,children:[(0,s.jsx)(`div`,{className:a.default.frame,style:{aspectRatio:h},children:(0,s.jsx)(`video`,{ref:N,className:a.default.video,src:Y??void 0,poster:p,loop:S,autoPlay:x,playsInline:!0,preload:`metadata`,onLoadedMetadata:$,onDurationChange:$,onTimeUpdate:()=>{let e=N.current;e&&R(e.currentTime*1e3)},onPlay:()=>I(!0),onPause:()=>I(!1),onVolumeChange:()=>{let e=N.current;e&&(W(e.volume),K(e.muted))},onEnded:()=>{I(!1),E?.()},onError:e=>D?.(e),children:m?.map(e=>(0,s.jsx)(`track`,{kind:e.kind??`captions`,src:e.src,srcLang:e.srcLang,label:e.label,default:e.default},`${e.kind??`captions`}-${e.srcLang}-${e.src}`))})}),(0,s.jsxs)(`div`,{className:a.default.chrome,children:[(0,s.jsx)(`button`,{type:`button`,className:a.default.transport,onClick:ee,disabled:O||!Y,"aria-label":F?j.pause:j.play,title:F?j.pause:j.play,children:F?(0,s.jsx)(c.Pause,{size:16,"aria-hidden":!0}):(0,s.jsx)(c.Play,{size:16,"aria-hidden":!0})}),(0,s.jsx)(`input`,{type:`range`,className:a.default.seek,min:0,max:Q?Math.round(Z):0,step:100,value:Math.min(Math.round(L),Q?Math.round(Z):0),onChange:e=>te(Number(e.target.value)),disabled:O||!Q,"aria-label":j.seek,"aria-valuetext":`${i.formatDuration(L)} / ${i.formatDuration(Z)}`}),(0,s.jsxs)(`span`,{className:a.default.time,children:[(0,s.jsx)(`span`,{children:i.formatDuration(L)}),(0,s.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,s.jsx)(`span`,{children:i.formatDuration(Z)})]}),(0,s.jsx)(`button`,{type:`button`,className:a.default.icon,onClick:()=>K(e=>!e),disabled:O,"aria-label":G?j.unmute:j.mute,title:G?j.unmute:j.mute,children:G?(0,s.jsx)(c.VolumeX,{size:16,"aria-hidden":!0}):(0,s.jsx)(c.Volume2,{size:16,"aria-hidden":!0})}),(0,s.jsx)(`input`,{type:`range`,className:a.default.volume,min:0,max:1,step:.05,value:G?0:U,onChange:e=>{let t=Number(e.target.value);W(t),K(t===0)},disabled:O,"aria-label":j.volume}),_.length>0&&(0,s.jsx)(`select`,{className:a.default.rate,value:X,onChange:e=>ne(Number(e.target.value)),disabled:O,"aria-label":j.rate,title:j.rate,children:_.map(e=>(0,s.jsx)(`option`,{value:e,children:u(e,w)},e))}),b&&q.supported&&(0,s.jsx)(`button`,{type:`button`,className:a.default.icon,onClick:()=>{q.toggle().catch(e=>D?.(e))},disabled:O,"aria-label":q.isFullscreen?j.exitFullscreen:j.enterFullscreen,title:q.isFullscreen?j.exitFullscreen:j.enterFullscreen,children:q.isFullscreen?(0,s.jsx)(c.Minimize,{size:16,"aria-hidden":!0}):(0,s.jsx)(c.Maximize,{size:16,"aria-hidden":!0})}),T&&(0,s.jsx)(`span`,{className:a.default.actions,children:T})]})]})}exports.VideoPlayer=d;
2
+ //# sourceMappingURL=VideoPlayer.cjs.map