tempest-react-sdk 0.34.0 → 0.36.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.
- package/README.md +72 -68
- package/dist/audio/audio-output.cjs +2 -0
- package/dist/audio/audio-output.cjs.map +1 -0
- package/dist/audio/audio-output.js +17 -0
- package/dist/audio/audio-output.js.map +1 -0
- package/dist/audio/audio-player.cjs +1 -1
- package/dist/audio/audio-player.cjs.map +1 -1
- package/dist/audio/audio-player.js +21 -20
- package/dist/audio/audio-player.js.map +1 -1
- package/dist/audio/audio-recorder.cjs +2 -0
- package/dist/audio/audio-recorder.cjs.map +1 -0
- package/dist/audio/audio-recorder.js +30 -0
- package/dist/audio/audio-recorder.js.map +1 -0
- package/dist/audio/duration.cjs +2 -0
- package/dist/audio/duration.cjs.map +1 -0
- package/dist/audio/duration.js +10 -0
- package/dist/audio/duration.js.map +1 -0
- package/dist/audio/level-meter.cjs +2 -0
- package/dist/audio/level-meter.cjs.map +1 -0
- package/dist/audio/level-meter.js +34 -0
- package/dist/audio/level-meter.js.map +1 -0
- package/dist/audio/media-access.cjs +2 -0
- package/dist/audio/media-access.cjs.map +1 -0
- package/dist/audio/media-access.js +51 -0
- package/dist/audio/media-access.js.map +1 -0
- package/dist/audio/use-audio-recorder.cjs +2 -0
- package/dist/audio/use-audio-recorder.cjs.map +1 -0
- package/dist/audio/use-audio-recorder.js +94 -0
- package/dist/audio/use-audio-recorder.js.map +1 -0
- package/dist/audio/use-audio.cjs.map +1 -1
- package/dist/audio/use-audio.js.map +1 -1
- package/dist/audio/use-microphone.cjs +2 -0
- package/dist/audio/use-microphone.cjs.map +1 -0
- package/dist/audio/use-microphone.js +54 -0
- package/dist/audio/use-microphone.js.map +1 -0
- package/dist/audio/wav.cjs +2 -0
- package/dist/audio/wav.cjs.map +1 -0
- package/dist/audio/wav.js +49 -0
- package/dist/audio/wav.js.map +1 -0
- package/dist/auth/passkey.cjs +2 -0
- package/dist/auth/passkey.cjs.map +1 -0
- package/dist/auth/passkey.js +171 -0
- package/dist/auth/passkey.js.map +1 -0
- package/dist/auth/use-passkey.cjs +2 -0
- package/dist/auth/use-passkey.cjs.map +1 -0
- package/dist/auth/use-passkey.js +120 -0
- package/dist/auth/use-passkey.js.map +1 -0
- package/dist/br/PixQRCode.cjs +2 -0
- package/dist/br/PixQRCode.cjs.map +1 -0
- package/dist/br/PixQRCode.js +70 -0
- package/dist/br/PixQRCode.js.map +1 -0
- package/dist/br/PixQRCode.module.cjs +2 -0
- package/dist/br/PixQRCode.module.cjs.map +1 -0
- package/dist/br/PixQRCode.module.js +15 -0
- package/dist/br/PixQRCode.module.js.map +1 -0
- package/dist/br/boleto.cjs +2 -0
- package/dist/br/boleto.cjs.map +1 -0
- package/dist/br/boleto.js +225 -0
- package/dist/br/boleto.js.map +1 -0
- package/dist/br/holidays.cjs +2 -0
- package/dist/br/holidays.cjs.map +1 -0
- package/dist/br/holidays.js +148 -0
- package/dist/br/holidays.js.map +1 -0
- package/dist/br/nfe.cjs +2 -0
- package/dist/br/nfe.cjs.map +1 -0
- package/dist/br/nfe.js +104 -0
- package/dist/br/nfe.js.map +1 -0
- package/dist/br/pix.cjs +2 -0
- package/dist/br/pix.cjs.map +1 -0
- package/dist/br/pix.js +148 -0
- package/dist/br/pix.js.map +1 -0
- package/dist/br.cjs +1 -1
- package/dist/br.cjs.map +1 -1
- package/dist/br.d.ts +878 -0
- package/dist/br.js +7 -2
- package/dist/br.js.map +1 -1
- package/dist/capture/barcode.cjs +2 -0
- package/dist/capture/barcode.cjs.map +1 -0
- package/dist/capture/barcode.js +59 -0
- package/dist/capture/barcode.js.map +1 -0
- package/dist/capture/media-recorder.cjs +2 -0
- package/dist/capture/media-recorder.cjs.map +1 -0
- package/dist/capture/media-recorder.js +64 -0
- package/dist/capture/media-recorder.js.map +1 -0
- package/dist/capture/use-barcode-scanner.cjs +2 -0
- package/dist/capture/use-barcode-scanner.cjs.map +1 -0
- package/dist/capture/use-barcode-scanner.js +86 -0
- package/dist/capture/use-barcode-scanner.js.map +1 -0
- package/dist/capture/use-screen-capture.cjs +2 -0
- package/dist/capture/use-screen-capture.cjs.map +1 -0
- package/dist/capture/use-screen-capture.js +79 -0
- package/dist/capture/use-screen-capture.js.map +1 -0
- package/dist/capture/use-speech-recognition.cjs +2 -0
- package/dist/capture/use-speech-recognition.cjs.map +1 -0
- package/dist/capture/use-speech-recognition.js +118 -0
- package/dist/capture/use-speech-recognition.js.map +1 -0
- package/dist/capture/use-torch.cjs +2 -0
- package/dist/capture/use-torch.cjs.map +1 -0
- package/dist/capture/use-torch.js +33 -0
- package/dist/capture/use-torch.js.map +1 -0
- package/dist/capture/use-video-recorder.cjs +2 -0
- package/dist/capture/use-video-recorder.cjs.map +1 -0
- package/dist/capture/use-video-recorder.js +90 -0
- package/dist/capture/use-video-recorder.js.map +1 -0
- package/dist/capture/video-recorder.cjs +2 -0
- package/dist/capture/video-recorder.cjs.map +1 -0
- package/dist/capture/video-recorder.js +31 -0
- package/dist/capture/video-recorder.js.map +1 -0
- package/dist/components/AIChat/AIChat.cjs +1 -1
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js +93 -97
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
- package/dist/components/AIChat/AIChatComposer.js +2 -1
- package/dist/components/AIChat/AIChatComposer.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs +2 -2
- package/dist/components/AIChat/AIChatTurn.js +6 -6
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/Alert/Alert.module.cjs.map +1 -1
- package/dist/components/Alert/Alert.module.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs +2 -0
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.js +123 -0
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.cjs +2 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.js +12 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.cjs +2 -0
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.js +179 -0
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.cjs +2 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.js +19 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -0
- package/dist/components/Badge/Badge.module.cjs.map +1 -1
- package/dist/components/Badge/Badge.module.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs +2 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.js +123 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs +2 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.js +22 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -0
- package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
- package/dist/components/Button/Button.module.cjs.map +1 -1
- package/dist/components/Button/Button.module.js.map +1 -1
- package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.module.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +203 -66
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DataTable.module.cjs +1 -1
- package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.module.js +9 -3
- package/dist/components/DataTable/DataTable.module.js.map +1 -1
- package/dist/components/DataTable/EditableCell.cjs +2 -0
- package/dist/components/DataTable/EditableCell.cjs.map +1 -0
- package/dist/components/DataTable/EditableCell.js +77 -0
- package/dist/components/DataTable/EditableCell.js.map +1 -0
- package/dist/components/DataTable/edit-labels.cjs +2 -0
- package/dist/components/DataTable/edit-labels.cjs.map +1 -0
- package/dist/components/DataTable/edit-labels.js +11 -0
- package/dist/components/DataTable/edit-labels.js.map +1 -0
- package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js +33 -32
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js +1 -2
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/hooks/use-announce.cjs +2 -0
- package/dist/hooks/use-announce.cjs.map +1 -0
- package/dist/hooks/use-announce.js +50 -0
- package/dist/hooks/use-announce.js.map +1 -0
- package/dist/hooks/use-media-devices.cjs +2 -0
- package/dist/hooks/use-media-devices.cjs.map +1 -0
- package/dist/hooks/use-media-devices.js +46 -0
- package/dist/hooks/use-media-devices.js.map +1 -0
- package/dist/hooks/use-media-permission.cjs +2 -0
- package/dist/hooks/use-media-permission.cjs.map +1 -0
- package/dist/hooks/use-media-permission.js +33 -0
- package/dist/hooks/use-media-permission.js.map +1 -0
- package/dist/http/resumable-upload.cjs +2 -0
- package/dist/http/resumable-upload.cjs.map +1 -0
- package/dist/http/resumable-upload.js +249 -0
- package/dist/http/resumable-upload.js.map +1 -0
- package/dist/perf/cache-size.cjs +2 -0
- package/dist/perf/cache-size.cjs.map +1 -0
- package/dist/perf/cache-size.js +16 -0
- package/dist/perf/cache-size.js.map +1 -0
- package/dist/perf/device.cjs +2 -0
- package/dist/perf/device.cjs.map +1 -0
- package/dist/perf/device.js +22 -0
- package/dist/perf/device.js.map +1 -0
- package/dist/perf/format.cjs +2 -0
- package/dist/perf/format.cjs.map +1 -0
- package/dist/perf/format.js +8 -0
- package/dist/perf/format.js.map +1 -0
- package/dist/perf/profiler.cjs +2 -0
- package/dist/perf/profiler.cjs.map +1 -0
- package/dist/perf/profiler.js +46 -0
- package/dist/perf/profiler.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +2705 -38
- package/dist/tempest-react-sdk.js +268 -240
- package/dist/vision/core/timing.cjs +2 -0
- package/dist/vision/core/timing.cjs.map +1 -0
- package/dist/vision/core/timing.js +24 -0
- package/dist/vision/core/timing.js.map +1 -0
- package/dist/vision/index.cjs +1 -1
- package/dist/vision/index.cjs.map +1 -1
- package/dist/vision/index.js +16 -15
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/postprocess/detection.cjs +1 -1
- package/dist/vision/postprocess/detection.cjs.map +1 -1
- package/dist/vision/postprocess/detection.js +2 -2
- package/dist/vision/postprocess/detection.js.map +1 -1
- package/dist/vision/postprocess/segmentation.cjs +1 -1
- package/dist/vision/postprocess/segmentation.cjs.map +1 -1
- package/dist/vision/postprocess/segmentation.js +1 -1
- package/dist/vision/postprocess/segmentation.js.map +1 -1
- package/dist/vision/results.cjs +1 -1
- package/dist/vision/results.cjs.map +1 -1
- package/dist/vision/results.js +18 -13
- package/dist/vision/results.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js +46 -39
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision/tasks/detector.cjs +1 -1
- package/dist/vision/tasks/detector.cjs.map +1 -1
- package/dist/vision/tasks/detector.js +40 -33
- package/dist/vision/tasks/detector.js.map +1 -1
- package/dist/vision/tasks/segmenter.cjs +1 -1
- package/dist/vision/tasks/segmenter.cjs.map +1 -1
- package/dist/vision/tasks/segmenter.js +35 -28
- package/dist/vision/tasks/segmenter.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +40 -57
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vision.cjs +1 -1
- package/dist/vision.d.ts +93 -13
- package/dist/vision.js +21 -20
- package/package.json +1 -1
|
@@ -56,6 +56,7 @@ import { ReactEventHandler } from 'react';
|
|
|
56
56
|
import { ReactNode } from 'react';
|
|
57
57
|
import { ReactPortal } from 'react';
|
|
58
58
|
import { redirect } from 'react-router';
|
|
59
|
+
import { Ref } from 'react';
|
|
59
60
|
import { RefAttributes } from 'react';
|
|
60
61
|
import { RefObject } from 'react';
|
|
61
62
|
import { Route } from 'react-router';
|
|
@@ -187,7 +188,7 @@ export declare interface AccordionProps {
|
|
|
187
188
|
* suggestions={["Resuma o último relatório", "Quais pedidos atrasaram?"]}
|
|
188
189
|
* />
|
|
189
190
|
*/
|
|
190
|
-
export declare function AIChat({ messages, onSend, onStop, onRegenerate, onEditSubmit, onFeedback, onRetry, pending, suggestions, renderAvatar, renderContent, votes, header, emptyState, showSystem, defaultReasoningOpen, showLineNumbers, locale, placeholder, composerActions, composerFooter, composerDisabled, maxRows, onSendError, className, ...rest }: AIChatProps): JSX.Element;
|
|
191
|
+
export declare function AIChat({ messages, onSend, onStop, onRegenerate, onEditSubmit, onFeedback, onRetry, pending, suggestions, renderAvatar, renderContent, votes, header, emptyState, showSystem, defaultReasoningOpen, showLineNumbers, locale, placeholder, composerActions, composerRef, composerFooter, composerDisabled, maxRows, onSendError, className, ...rest }: AIChatProps): JSX.Element;
|
|
191
192
|
|
|
192
193
|
/** A file carried by a turn — an upload on the way in, a document on the way out. */
|
|
193
194
|
export declare interface AIChatAttachment {
|
|
@@ -224,14 +225,23 @@ export declare interface AIChatAttachment {
|
|
|
224
225
|
*/
|
|
225
226
|
export declare const AIChatComposer: ForwardRefExoticComponent<AIChatComposerProps & RefAttributes<AIChatComposerHandle>>;
|
|
226
227
|
|
|
227
|
-
/** Imperative handle, so a thread can focus or refill the field. */
|
|
228
|
+
/** Imperative handle, so a thread can focus, read or refill the field. */
|
|
228
229
|
export declare interface AIChatComposerHandle {
|
|
229
230
|
focus: () => void;
|
|
230
231
|
/** Replace the draft — used to put a prompt back in the field. */
|
|
231
232
|
setValue: (text: string) => void;
|
|
233
|
+
/**
|
|
234
|
+
* The current draft.
|
|
235
|
+
*
|
|
236
|
+
* The counterpart `setValue` needs to be usable for anything **additive**. The
|
|
237
|
+
* field is uncontrolled, so without this the only way to append to a draft — a
|
|
238
|
+
* dictated phrase, a picked slash-command, a pasted citation — is to shadow the
|
|
239
|
+
* whole value in app state through `onChange` and hope the two never drift.
|
|
240
|
+
*/
|
|
241
|
+
getValue: () => string;
|
|
232
242
|
}
|
|
233
243
|
|
|
234
|
-
export declare interface AIChatComposerProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
244
|
+
export declare interface AIChatComposerProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, OverriddenDomProps_8> {
|
|
235
245
|
/** Called with the trimmed prompt. The field clears only when this does not throw. */
|
|
236
246
|
onSend: (text: string) => void | Promise<void>;
|
|
237
247
|
/**
|
|
@@ -302,7 +312,7 @@ export declare interface AIChatMessage {
|
|
|
302
312
|
data?: Record<string, unknown>;
|
|
303
313
|
}
|
|
304
314
|
|
|
305
|
-
export declare interface AIChatProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
315
|
+
export declare interface AIChatProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_7> {
|
|
306
316
|
/** The transcript, **oldest first**. Never reordered by the component. */
|
|
307
317
|
messages: readonly AIChatMessage[];
|
|
308
318
|
/** Renders the composer when given. Receives the trimmed prompt. */
|
|
@@ -349,6 +359,16 @@ export declare interface AIChatProps extends Omit<HTMLAttributes<HTMLDivElement>
|
|
|
349
359
|
placeholder?: string;
|
|
350
360
|
/** Extra controls inside the composer, before the send button. */
|
|
351
361
|
composerActions?: ReactNode;
|
|
362
|
+
/**
|
|
363
|
+
* Reach the composer imperatively — `focus()`, `getValue()`, `setValue()`.
|
|
364
|
+
*
|
|
365
|
+
* What makes dictation (or a slash-command menu, or "edit and resend") possible
|
|
366
|
+
* without this component knowing anything about them: pair it with
|
|
367
|
+
* `composerActions` and the button you put in the composer can write into the
|
|
368
|
+
* field. Speech recognition is **not** wired in here on purpose — it would make
|
|
369
|
+
* every consumer of `AIChat` pay for an API that streams audio to a third party.
|
|
370
|
+
*/
|
|
371
|
+
composerRef?: Ref<AIChatComposerHandle>;
|
|
352
372
|
/** Under the composer field — token count, model name, a disclaimer. */
|
|
353
373
|
composerFooter?: ReactNode;
|
|
354
374
|
/** Disable the composer — no credits, conversation archived, offline. */
|
|
@@ -483,6 +503,41 @@ export declare interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
|
483
503
|
|
|
484
504
|
export declare type AlertVariant = "neutral" | "info" | "success" | "warning" | "danger";
|
|
485
505
|
|
|
506
|
+
/** Every symbology in the spec, used to validate what a detector reports back. */
|
|
507
|
+
export declare const ALL_BARCODE_FORMATS: readonly BarcodeFormat[];
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Announce a message to screen readers, from anywhere — a hook, an event handler,
|
|
511
|
+
* a plain function outside React.
|
|
512
|
+
*
|
|
513
|
+
* ## Why the same string announces twice
|
|
514
|
+
*
|
|
515
|
+
* Screen readers announce a live region when its **content changes**. Writing the
|
|
516
|
+
* same text again is not a change, so "Item removido" twice in a row is read once —
|
|
517
|
+
* the classic reason these announcers are quietly broken. Instead of mutating text,
|
|
518
|
+
* every call replaces the region's child with a **new element**. The DOM mutation is
|
|
519
|
+
* real even when the string is identical, so the second announcement happens, and
|
|
520
|
+
* the reader hears the exact message with no padding characters bolted on.
|
|
521
|
+
*
|
|
522
|
+
* @param message - Text to read out. Empty strings are ignored.
|
|
523
|
+
* @param politeness - `"polite"` (default) or `"assertive"`.
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* announce(`${count} pedidos encontrados`);
|
|
527
|
+
* announce("Falha ao salvar", "assertive");
|
|
528
|
+
*/
|
|
529
|
+
export declare function announce(message: string, politeness?: AnnouncePoliteness): void;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* How urgently a screen reader should interrupt.
|
|
533
|
+
*
|
|
534
|
+
* `"polite"` waits for a pause in what is being read. `"assertive"` cuts in
|
|
535
|
+
* immediately, which is right for an error the user must act on and wrong for
|
|
536
|
+
* everything else — an assertive announcement can truncate the sentence the user
|
|
537
|
+
* was in the middle of.
|
|
538
|
+
*/
|
|
539
|
+
export declare type AnnouncePoliteness = "polite" | "assertive";
|
|
540
|
+
|
|
486
541
|
declare type AnyEventTarget = EventTarget | {
|
|
487
542
|
current: EventTarget | null;
|
|
488
543
|
} | null | undefined;
|
|
@@ -823,7 +878,50 @@ export declare function assertNever(value: never, message?: string): never;
|
|
|
823
878
|
|
|
824
879
|
export declare type AsyncStatus = "idle" | "pending" | "success" | "error";
|
|
825
880
|
|
|
826
|
-
|
|
881
|
+
/**
|
|
882
|
+
* Container/codec candidates, best first.
|
|
883
|
+
*
|
|
884
|
+
* No browser supports all of these, and none supports MP3 or WAV from
|
|
885
|
+
* `MediaRecorder` — see the note on {@link pickAudioMimeType}. Opus in WebM is the
|
|
886
|
+
* first choice because it is the smallest at speech bitrates and is what Chromium
|
|
887
|
+
* and Firefox produce natively; `audio/mp4` is here for Safari, which produces AAC
|
|
888
|
+
* and nothing else.
|
|
889
|
+
*
|
|
890
|
+
* Ported from the intersection of what `MediaRecorder.isTypeSupported` accepts in
|
|
891
|
+
* Chrome 120+, Firefox 115+ and Safari 17. Re-check against
|
|
892
|
+
* <https://developer.mozilla.org/docs/Web/API/MediaRecorder/isTypeSupported> before
|
|
893
|
+
* adding to the list.
|
|
894
|
+
*/
|
|
895
|
+
export declare const AUDIO_MIME_CANDIDATES: readonly string[];
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Playback transport for one clip: play/pause, a seek bar, elapsed and total time.
|
|
899
|
+
*
|
|
900
|
+
* Built around a real `<audio>` element rather than the SDK's `createAudioPlayer`,
|
|
901
|
+
* which is a fire-and-forget handle for notification chimes and has no transport to
|
|
902
|
+
* expose. Accepts a `Blob` directly, because the thing an app most often plays is the
|
|
903
|
+
* recording it just made.
|
|
904
|
+
*
|
|
905
|
+
* The seek bar is a bare `<input type="range">` rather than the SDK's `Slider`: that
|
|
906
|
+
* component is a form field, with a label row and a value badge, and a transport wants
|
|
907
|
+
* neither. The native input keeps the keyboard and screen-reader behaviour that
|
|
908
|
+
* matters here for free.
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* const rec = useAudioRecorder(mic.stream);
|
|
912
|
+
* {rec.recording && (
|
|
913
|
+
* <AudioPlayer src={rec.recording.blob} durationMs={rec.recording.durationMs} />
|
|
914
|
+
* )}
|
|
915
|
+
*/
|
|
916
|
+
export declare function AudioPlayer({ src, durationMs, sinkId, autoPlay, loop, locale, actions, onEnded, onError, disabled, className, ...rest }: AudioPlayerProps): JSX.Element;
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* Imperative handle over one "current" clip.
|
|
920
|
+
*
|
|
921
|
+
* Named `*Handle` like the SDK's other imperative handles (`ChatComposerHandle`,
|
|
922
|
+
* `SignaturePadHandle`) — it is a control surface, not the `<AudioPlayer>` component.
|
|
923
|
+
*/
|
|
924
|
+
export declare interface AudioPlayerHandle {
|
|
827
925
|
/** Play `src`. Returns the underlying element, or `null` when the browser blocked autoplay. */
|
|
828
926
|
play: (src: string, options?: PlayAudioOptions) => Promise<HTMLAudioElement | null>;
|
|
829
927
|
/** Stop the currently-playing clip and rewind it. */
|
|
@@ -832,6 +930,157 @@ export declare interface AudioPlayer {
|
|
|
832
930
|
current: () => HTMLAudioElement | null;
|
|
833
931
|
}
|
|
834
932
|
|
|
933
|
+
export declare interface AudioPlayerProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_4> {
|
|
934
|
+
/**
|
|
935
|
+
* What to play — a URL, or a `Blob`/`File` straight from a recorder.
|
|
936
|
+
*
|
|
937
|
+
* A `Blob` is wrapped in an object URL that is revoked when it changes or the
|
|
938
|
+
* component unmounts, so a page that records twenty notes does not leak twenty
|
|
939
|
+
* URLs for the lifetime of the tab.
|
|
940
|
+
*/
|
|
941
|
+
src: string | Blob | null;
|
|
942
|
+
/**
|
|
943
|
+
* Known length in milliseconds.
|
|
944
|
+
*
|
|
945
|
+
* Pass it whenever you have it — a recording from `useAudioRecorder` always does.
|
|
946
|
+
* See the note on the seek bar for why the element's own `duration` is not
|
|
947
|
+
* trustworthy for a fresh recording.
|
|
948
|
+
*/
|
|
949
|
+
durationMs?: number;
|
|
950
|
+
/** Output device, from `useMediaDevices().audioOutputs`. Chromium only. */
|
|
951
|
+
sinkId?: string;
|
|
952
|
+
/** Start playing as soon as `src` is ready. Default `false`. */
|
|
953
|
+
autoPlay?: boolean;
|
|
954
|
+
/** Loop. Default `false`. */
|
|
955
|
+
loop?: boolean;
|
|
956
|
+
/** Locale for the labels. Default `"pt-BR"`. */
|
|
957
|
+
locale?: "pt-BR" | "en";
|
|
958
|
+
/** Rendered to the right of the times — a download button, a delete button. */
|
|
959
|
+
actions?: React.ReactNode;
|
|
960
|
+
/** Fired when playback reaches the end. */
|
|
961
|
+
onEnded?: () => void;
|
|
962
|
+
/** Fired when the element reports a decode/network error. */
|
|
963
|
+
onError?: (error: unknown) => void;
|
|
964
|
+
/** No `src` yet, or playback not allowed. */
|
|
965
|
+
disabled?: boolean;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Record a voice note: one button to start, a live level meter, a clock, and a
|
|
970
|
+
* playback review before the audio leaves the component.
|
|
971
|
+
*
|
|
972
|
+
* The permission flow is the part worth reading. The microphone is **not** opened on
|
|
973
|
+
* mount — the prompt fires on the first press of Record, because a prompt the user did
|
|
974
|
+
* not provoke is the most reliable way to earn a permanent block, after which
|
|
975
|
+
* `getUserMedia` rejects without ever asking again. When the permission is already
|
|
976
|
+
* `"denied"`, the component says so and how to fix it instead of offering a button
|
|
977
|
+
* that cannot work.
|
|
978
|
+
*
|
|
979
|
+
* The level meter is not decoration either: a muted OS input or a headset with its mic
|
|
980
|
+
* arm folded up produces a perfectly successful recording of silence, and without a
|
|
981
|
+
* visible level the user only finds out after they finish talking.
|
|
982
|
+
*
|
|
983
|
+
* @example
|
|
984
|
+
* <AudioRecorder
|
|
985
|
+
* maxDurationMs={120_000}
|
|
986
|
+
* format="wav"
|
|
987
|
+
* wavOptions={{ mono: true, sampleRate: 16000 }}
|
|
988
|
+
* onRecorded={({ blob }) => upload(blob)}
|
|
989
|
+
* />
|
|
990
|
+
*/
|
|
991
|
+
export declare function AudioRecorder({ onRecorded, maxDurationMs, deviceId, format, wavOptions, audioBitsPerSecond, review, locale, footer, onError, disabled, className, ...rest }: AudioRecorderProps): JSX.Element;
|
|
992
|
+
|
|
993
|
+
/** Imperative recorder. */
|
|
994
|
+
export declare interface AudioRecorderHandle {
|
|
995
|
+
/** Begin recording. No-op when already recording or paused. */
|
|
996
|
+
start: () => void;
|
|
997
|
+
/** Pause. The clock stops; `durationMs` freezes. */
|
|
998
|
+
pause: () => void;
|
|
999
|
+
/** Resume after `pause()`. */
|
|
1000
|
+
resume: () => void;
|
|
1001
|
+
/** Stop and resolve with the assembled recording. */
|
|
1002
|
+
stop: () => Promise<AudioRecording>;
|
|
1003
|
+
/** Stop and throw the audio away. */
|
|
1004
|
+
cancel: () => void;
|
|
1005
|
+
status: () => AudioRecorderStatus;
|
|
1006
|
+
/** Recorded length so far, excluding paused time. */
|
|
1007
|
+
durationMs: () => number;
|
|
1008
|
+
/** The negotiated container. */
|
|
1009
|
+
mimeType: string;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/** Options for {@link createAudioRecorder}. */
|
|
1013
|
+
export declare interface AudioRecorderOptions {
|
|
1014
|
+
/**
|
|
1015
|
+
* Force a container. Throws when the browser cannot produce it.
|
|
1016
|
+
*
|
|
1017
|
+
* Leave it out. The default negotiates from {@link AUDIO_MIME_CANDIDATES}, which
|
|
1018
|
+
* is the only way one call site works on both Chromium and Safari.
|
|
1019
|
+
*/
|
|
1020
|
+
mimeType?: string;
|
|
1021
|
+
/** Target bitrate. 32000–64000 is plenty for speech in Opus. */
|
|
1022
|
+
audioBitsPerSecond?: number;
|
|
1023
|
+
/**
|
|
1024
|
+
* Emit a chunk every N ms through `onChunk`, for streaming upload.
|
|
1025
|
+
*
|
|
1026
|
+
* Without it the whole recording is buffered in memory until `stop()` — fine for
|
|
1027
|
+
* a voice note, not fine for an hour-long meeting.
|
|
1028
|
+
*/
|
|
1029
|
+
timesliceMs?: number;
|
|
1030
|
+
/** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */
|
|
1031
|
+
onChunk?: (chunk: Blob) => void;
|
|
1032
|
+
/** Recorder-level failure (device unplugged mid-recording, encoder error). */
|
|
1033
|
+
onError?: (error: unknown) => void;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
export declare interface AudioRecorderProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_5> {
|
|
1037
|
+
/**
|
|
1038
|
+
* Called once a recording is finished and (when asked) converted.
|
|
1039
|
+
*
|
|
1040
|
+
* Fires on stop and on hitting `maxDurationMs`, never on cancel.
|
|
1041
|
+
*/
|
|
1042
|
+
onRecorded?: (recording: AudioRecording) => void;
|
|
1043
|
+
/** Stop automatically after this long. Strongly recommended on anything public. */
|
|
1044
|
+
maxDurationMs?: number;
|
|
1045
|
+
/** Specific microphone, from `useMediaDevices().audioInputs`. */
|
|
1046
|
+
deviceId?: string;
|
|
1047
|
+
/**
|
|
1048
|
+
* Output container.
|
|
1049
|
+
*
|
|
1050
|
+
* `"native"` (default) keeps what the browser produced — Opus on Chromium and
|
|
1051
|
+
* Firefox, AAC on Safari — which is the smallest and needs no work. `"wav"`
|
|
1052
|
+
* converts on stop, for a backend that only accepts WAV; see `wavOptions`, and
|
|
1053
|
+
* expect roughly ten times the bytes.
|
|
1054
|
+
*/
|
|
1055
|
+
format?: "native" | "wav";
|
|
1056
|
+
/** Passed to `blobToWav` when `format="wav"`. `{ mono: true, sampleRate: 16000 }` suits speech. */
|
|
1057
|
+
wavOptions?: WavOptions;
|
|
1058
|
+
/** Target bitrate. 32000–64000 is plenty for speech in Opus. */
|
|
1059
|
+
audioBitsPerSecond?: number;
|
|
1060
|
+
/** Offer playback of the recording before handing it over. Default `true`. */
|
|
1061
|
+
review?: boolean;
|
|
1062
|
+
/** Locale for the labels. Default `"pt-BR"`. */
|
|
1063
|
+
locale?: "pt-BR" | "en";
|
|
1064
|
+
/** Rendered under the controls — a hint, a character count, a legal notice. */
|
|
1065
|
+
footer?: ReactNode;
|
|
1066
|
+
/** Recorder-level failure, or a failed WAV conversion. */
|
|
1067
|
+
onError?: (error: unknown) => void;
|
|
1068
|
+
disabled?: boolean;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/** Lifecycle of a recording. Shared with the video recorder — the states are the same. */
|
|
1072
|
+
export declare type AudioRecorderStatus = MediaRecorderStatus;
|
|
1073
|
+
|
|
1074
|
+
/** A finished recording. */
|
|
1075
|
+
export declare interface AudioRecording {
|
|
1076
|
+
/** The audio. Wrap with `useObjectUrl` to play it, or POST it as-is. */
|
|
1077
|
+
blob: Blob;
|
|
1078
|
+
/** What the browser actually produced — not necessarily what you asked for. */
|
|
1079
|
+
mimeType: string;
|
|
1080
|
+
/** Recorded length, excluding time spent paused. */
|
|
1081
|
+
durationMs: number;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
835
1084
|
/**
|
|
836
1085
|
* Router-agnostic auth gate. The caller decides what to render in either
|
|
837
1086
|
* branch — typically `<Outlet />` for protected layouts and `<Navigate />` for
|
|
@@ -996,6 +1245,129 @@ export declare interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>
|
|
|
996
1245
|
|
|
997
1246
|
export declare type BannerVariant = "info" | "success" | "warning" | "danger";
|
|
998
1247
|
|
|
1248
|
+
/**
|
|
1249
|
+
* The slice of `BarcodeDetector` this SDK uses.
|
|
1250
|
+
*
|
|
1251
|
+
* Exported so a consumer can **inject a polyfill** where the native API is missing —
|
|
1252
|
+
* see {@link isBarcodeDetectionSupported} for why that matters — and so tests can hand
|
|
1253
|
+
* in a decoder without a camera. Anything with a `detect()` that resolves to objects
|
|
1254
|
+
* carrying a `rawValue` will do.
|
|
1255
|
+
*/
|
|
1256
|
+
export declare interface BarcodeDetectorLike {
|
|
1257
|
+
/**
|
|
1258
|
+
* Decode every symbol visible in the source.
|
|
1259
|
+
*
|
|
1260
|
+
* @param source - A `<video>`, a `<canvas>`, an `ImageBitmap`, a `Blob`…
|
|
1261
|
+
* @returns Every symbol found, or an empty array — finding nothing is not an error.
|
|
1262
|
+
*/
|
|
1263
|
+
detect: (source: ImageBitmapSource) => Promise<readonly DetectedBarcodeLike[]>;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* Symbologies the `BarcodeDetector` API names.
|
|
1268
|
+
*
|
|
1269
|
+
* Three of them carry the weight in Brazil: `ean_13` is the retail barcode on every
|
|
1270
|
+
* packaged product, `qr_code` is what a Pix "copia e cola" payload travels in, and
|
|
1271
|
+
* `code_128` is the label on a shipment. The rest are here because the spec has them
|
|
1272
|
+
* and asking for one costs nothing.
|
|
1273
|
+
*/
|
|
1274
|
+
export declare type BarcodeFormat = "aztec" | "codabar" | "code_128" | "code_39" | "code_93" | "data_matrix" | "ean_13" | "ean_8" | "itf" | "pdf417" | "qr_code" | "upc_a" | "upc_e" | "unknown";
|
|
1275
|
+
|
|
1276
|
+
/** A corner of a detected symbol, in the source's pixel coordinates. */
|
|
1277
|
+
export declare interface BarcodePoint {
|
|
1278
|
+
x: number;
|
|
1279
|
+
y: number;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* Point the camera at a barcode and get its value.
|
|
1284
|
+
*
|
|
1285
|
+
* The counterpart to {@link QRCode}, which only encodes. Under it are
|
|
1286
|
+
* `useBarcodeScanner` (the detect loop and repeat suppression), `useCameraStream` (the
|
|
1287
|
+
* stream and its classified errors) and `useTorch`.
|
|
1288
|
+
*
|
|
1289
|
+
* **Mounting this opens the camera**, so mount it when the user asks to scan rather
|
|
1290
|
+
* than on a page that happens to contain a scanner: a permission prompt nobody
|
|
1291
|
+
* provoked is the surest way to earn a permanent block, and after that `getUserMedia`
|
|
1292
|
+
* rejects without ever prompting again. The usual shape is a button that reveals it.
|
|
1293
|
+
*
|
|
1294
|
+
* The `unsupported` slot is not a nicety. `BarcodeDetector` is Chromium-only — absent
|
|
1295
|
+
* on Firefox, on every browser on iOS, and on Chromium for Windows and Linux — so on a
|
|
1296
|
+
* large share of real devices the fallback *is* the feature. Give it a text field, or
|
|
1297
|
+
* inject a polyfill through `detector`.
|
|
1298
|
+
*
|
|
1299
|
+
* The preview itself is `aria-hidden`: a live camera frame has nothing to announce and
|
|
1300
|
+
* no audio to caption, so what a screen reader gets is the `role="status"` line, which
|
|
1301
|
+
* says whether scanning is running and reads out each accepted code.
|
|
1302
|
+
*
|
|
1303
|
+
* @example
|
|
1304
|
+
* <BarcodeScanner
|
|
1305
|
+
* formats={["ean_13"]}
|
|
1306
|
+
* onScan={({ rawValue }) => addToCart(rawValue)}
|
|
1307
|
+
* footer={<small>Aponte para o código de barras da embalagem.</small>}
|
|
1308
|
+
* unsupported={<ManualCodeInput onSubmit={addToCart} />}
|
|
1309
|
+
* />
|
|
1310
|
+
*/
|
|
1311
|
+
export declare function BarcodeScanner({ onScan, formats, paused, detector, intervalMs, repeatDelayMs, torch, aspectRatio, locale, footer, unsupported, onError, className, ...rest }: BarcodeScannerProps): JSX.Element;
|
|
1312
|
+
|
|
1313
|
+
export declare interface BarcodeScannerProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_6> {
|
|
1314
|
+
/** Called for every accepted read — repeats of the same value are suppressed. */
|
|
1315
|
+
onScan: (result: BarcodeScanResult) => void;
|
|
1316
|
+
/** Symbologies to look for. Defaults to QR + EAN-13 + Code 128. */
|
|
1317
|
+
formats?: readonly BarcodeFormat[];
|
|
1318
|
+
/** Stop looking without releasing the camera — set it while a confirmation is open. */
|
|
1319
|
+
paused?: boolean;
|
|
1320
|
+
/** A decoder to use instead of the native one, for Safari and Firefox. */
|
|
1321
|
+
detector?: BarcodeDetectorLike;
|
|
1322
|
+
/** How often a frame is examined, in ms. Default 200. */
|
|
1323
|
+
intervalMs?: number;
|
|
1324
|
+
/** Ignore the same value again for this long, in ms. Default 2500. */
|
|
1325
|
+
repeatDelayMs?: number;
|
|
1326
|
+
/** Offer the torch toggle when the camera has a lamp. Default `true`. */
|
|
1327
|
+
torch?: boolean;
|
|
1328
|
+
/** Viewport aspect ratio, `width / height`. Default `4 / 3`. */
|
|
1329
|
+
aspectRatio?: number;
|
|
1330
|
+
/** Locale for the labels. Default `"pt-BR"`. */
|
|
1331
|
+
locale?: "pt-BR" | "en";
|
|
1332
|
+
/** Under the viewport — an instruction, the code just read, a manual-entry link. */
|
|
1333
|
+
footer?: ReactNode;
|
|
1334
|
+
/**
|
|
1335
|
+
* Rendered instead of the camera when there is no decoder.
|
|
1336
|
+
*
|
|
1337
|
+
* Worth filling in: on iOS and Firefox this is the **only** thing the user sees, so
|
|
1338
|
+
* the fallback is usually a plain text field for typing the code.
|
|
1339
|
+
*/
|
|
1340
|
+
unsupported?: ReactNode;
|
|
1341
|
+
/** A frame the engine refused to decode. Routine and usually transient. */
|
|
1342
|
+
onError?: (error: unknown) => void;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
/** One decoded symbol, normalised. */
|
|
1346
|
+
export declare interface BarcodeScanResult {
|
|
1347
|
+
/** The decoded payload — a GTIN, a URL, a Pix BR Code. */
|
|
1348
|
+
rawValue: string;
|
|
1349
|
+
/** Which symbology it was read as. `"unknown"` when the engine does not say. */
|
|
1350
|
+
format: BarcodeFormat;
|
|
1351
|
+
/** Box in source pixels, or `null` when the engine reports none. */
|
|
1352
|
+
boundingBox: DOMRectReadOnly | null;
|
|
1353
|
+
/** Corners in source pixels, clockwise from top-left. Empty when unreported. */
|
|
1354
|
+
cornerPoints: readonly BarcodePoint[];
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* Decode a base64url string into bytes.
|
|
1359
|
+
*
|
|
1360
|
+
* WebAuthn transports every binary field as base64url (`-`/`_`, no padding)
|
|
1361
|
+
* because that is what survives JSON, while the DOM API insists on
|
|
1362
|
+
* `ArrayBuffer`. Getting this pair wrong — usually by feeding plain base64 to
|
|
1363
|
+
* `atob` and losing the last byte — is the classic broken-WebAuthn bug, which is
|
|
1364
|
+
* why the SDK owns it instead of leaving it to each app.
|
|
1365
|
+
*
|
|
1366
|
+
* @param value - Base64url text, with or without `=` padding.
|
|
1367
|
+
* @returns The decoded bytes.
|
|
1368
|
+
*/
|
|
1369
|
+
export declare function base64UrlToBytes(value: string): Uint8Array;
|
|
1370
|
+
|
|
999
1371
|
/**
|
|
1000
1372
|
* Initial bearing (forward azimuth) from `origin` to `destination`, in degrees
|
|
1001
1373
|
* clockwise from true north, normalized to `[0, 360)`. Useful for orienting a
|
|
@@ -1025,6 +1397,30 @@ export declare interface BeforeInstallPromptEvent extends Event {
|
|
|
1025
1397
|
prompt: () => Promise<void>;
|
|
1026
1398
|
}
|
|
1027
1399
|
|
|
1400
|
+
/**
|
|
1401
|
+
* Convert a recording to 16-bit WAV, with no dependency.
|
|
1402
|
+
*
|
|
1403
|
+
* `MediaRecorder` cannot produce WAV — it emits Opus on Chromium and Firefox and AAC
|
|
1404
|
+
* on Safari — so a backend that insists on WAV has to be served either by a
|
|
1405
|
+
* server-side transcode or by this. It decodes through `AudioContext.decodeAudioData`,
|
|
1406
|
+
* which is the browser's own decoder for whatever container the recorder chose, then
|
|
1407
|
+
* re-encodes the PCM.
|
|
1408
|
+
*
|
|
1409
|
+
* !!! The cost is real: WAV is uncompressed, so the same voice note that is 40 KB in
|
|
1410
|
+
* Opus is roughly 500 KB here at 48 kHz stereo. `{ mono: true, sampleRate: 16000 }`
|
|
1411
|
+
* takes that to about 80 KB and is what a speech-to-text endpoint wants anyway.
|
|
1412
|
+
*
|
|
1413
|
+
* Resampling uses `OfflineAudioContext`, i.e. the browser's own resampler, rather
|
|
1414
|
+
* than a hand-rolled one — this is exactly the "we want the underlying call, not a
|
|
1415
|
+
* wrapper" case.
|
|
1416
|
+
*
|
|
1417
|
+
* @param blob - A recording from {@link createAudioRecorder}, or any decodable audio.
|
|
1418
|
+
* @param options - See {@link WavOptions}.
|
|
1419
|
+
* @returns A `Blob` of type `audio/wav`.
|
|
1420
|
+
* @throws When the environment has no Web Audio, or the blob cannot be decoded.
|
|
1421
|
+
*/
|
|
1422
|
+
export declare function blobToWav(blob: Blob, options?: WavOptions): Promise<Blob>;
|
|
1423
|
+
|
|
1028
1424
|
/**
|
|
1029
1425
|
* Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with
|
|
1030
1426
|
* `<Show below="md">` to render only on mobile.
|
|
@@ -1207,6 +1603,14 @@ export declare type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
|
1207
1603
|
|
|
1208
1604
|
export declare type ButtonVariant = "primary" | "secondary" | "danger" | "success" | "ghost" | "soft" | "outline" | "link";
|
|
1209
1605
|
|
|
1606
|
+
/**
|
|
1607
|
+
* Encode bytes as an unpadded base64url string.
|
|
1608
|
+
*
|
|
1609
|
+
* @param value - Bytes to encode, as a view or a raw buffer.
|
|
1610
|
+
* @returns Base64url text, safe to put in JSON and in a URL.
|
|
1611
|
+
*/
|
|
1612
|
+
export declare function bytesToBase64Url(value: ArrayBuffer | Uint8Array): string;
|
|
1613
|
+
|
|
1210
1614
|
/** Recommended `gcTime` presets (milliseconds). */
|
|
1211
1615
|
export declare const CACHE_TIME: {
|
|
1212
1616
|
readonly SHORT: number;
|
|
@@ -1214,6 +1618,30 @@ export declare const CACHE_TIME: {
|
|
|
1214
1618
|
readonly LONG: number;
|
|
1215
1619
|
};
|
|
1216
1620
|
|
|
1621
|
+
/**
|
|
1622
|
+
* How large the assets a page precached actually are.
|
|
1623
|
+
*
|
|
1624
|
+
* Reads the `Content-Length` of a stored response instead of its body:
|
|
1625
|
+
* materializing a cached ONNX model or WASM binary to learn its length would
|
|
1626
|
+
* pull tens of megabytes into memory on every measurement.
|
|
1627
|
+
*/
|
|
1628
|
+
/**
|
|
1629
|
+
* Byte size of a response sitting in a Cache Storage bucket.
|
|
1630
|
+
*
|
|
1631
|
+
* @param cacheName The cache bucket to look in.
|
|
1632
|
+
* @param url The request URL the response was stored under.
|
|
1633
|
+
* @returns The size in bytes, or `null` when Cache Storage is unavailable,
|
|
1634
|
+
* the entry is absent, or the stored response carries no usable
|
|
1635
|
+
* `Content-Length` (a chunked transfer, typically).
|
|
1636
|
+
*
|
|
1637
|
+
* @example
|
|
1638
|
+
* ```typescript
|
|
1639
|
+
* const bytes = await cachedResponseBytes("app-models", "/models/detect.onnx");
|
|
1640
|
+
* console.log(bytes === null ? "—" : formatBytes(bytes)); // "12.0 MB"
|
|
1641
|
+
* ```
|
|
1642
|
+
*/
|
|
1643
|
+
export declare function cachedResponseBytes(cacheName: string, url: string): Promise<number | null>;
|
|
1644
|
+
|
|
1217
1645
|
/** A cache-name matcher: a prefix string, a `RegExp`, or a predicate. */
|
|
1218
1646
|
export declare type CacheFilter = string | RegExp | ((name: string) => boolean);
|
|
1219
1647
|
|
|
@@ -1276,6 +1704,18 @@ export declare interface CalendarProps extends Omit<HTMLAttributes<HTMLDivElemen
|
|
|
1276
1704
|
*/
|
|
1277
1705
|
export declare function camelCase(value: string): string;
|
|
1278
1706
|
|
|
1707
|
+
/** A classified camera error with a human-readable, English message. */
|
|
1708
|
+
declare interface CameraStreamError {
|
|
1709
|
+
kind: CameraStreamErrorKind;
|
|
1710
|
+
message: string;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/** Classified reason a camera stream could not be acquired. */
|
|
1714
|
+
declare type CameraStreamErrorKind = "unsupported" | "permission-denied" | "no-camera" | "in-use" | "insecure" | "unknown";
|
|
1715
|
+
|
|
1716
|
+
/** Lifecycle status of the camera stream. */
|
|
1717
|
+
declare type CameraStreamStatus = "idle" | "loading" | "ready" | "error";
|
|
1718
|
+
|
|
1279
1719
|
/**
|
|
1280
1720
|
* Conditionally render based on an access check. Renders `children` when the
|
|
1281
1721
|
* action is allowed, otherwise `fallback` (or nothing). While an async check is
|
|
@@ -1663,8 +2103,52 @@ export declare function clamp(value: number, min: number, max: number): number;
|
|
|
1663
2103
|
/** Clamp a latitude into the valid `[-90, 90]` range. */
|
|
1664
2104
|
export declare function clampLatitude(latitude: number): number;
|
|
1665
2105
|
|
|
2106
|
+
/**
|
|
2107
|
+
* Map an unknown `getUserMedia` failure into a {@link MediaAccessError}.
|
|
2108
|
+
*
|
|
2109
|
+
* The order matters. A missing `navigator.mediaDevices` is almost never "this
|
|
2110
|
+
* browser cannot do audio" — it is a page served over plain HTTP, where the whole
|
|
2111
|
+
* API is simply absent. Reporting `unsupported` there sends the developer looking
|
|
2112
|
+
* for a polyfill for a problem an `https://` URL fixes, so the secure-context check
|
|
2113
|
+
* runs first and wins.
|
|
2114
|
+
*
|
|
2115
|
+
* The `DOMException.name` values are then collapsed into kinds an app can actually
|
|
2116
|
+
* branch on, because the raw names do not group the way a UI needs them:
|
|
2117
|
+
* `NotFoundError` and `OverconstrainedError` both mean "you will not get a device
|
|
2118
|
+
* with these constraints", and `NotReadableError` and `AbortError` both mean "the
|
|
2119
|
+
* hardware is busy" — most often another tab of the same app.
|
|
2120
|
+
*
|
|
2121
|
+
* @param err - Whatever `getUserMedia` (or a device query) rejected with.
|
|
2122
|
+
* @param device - Which device was being opened, for the message.
|
|
2123
|
+
* @returns A stable kind plus a message safe to show a user.
|
|
2124
|
+
*/
|
|
2125
|
+
export declare function classifyMediaError(err: unknown, device?: MediaDeviceKindLabel): MediaAccessError;
|
|
2126
|
+
|
|
2127
|
+
/**
|
|
2128
|
+
* Map a thrown WebAuthn failure onto a {@link PasskeyError}.
|
|
2129
|
+
*
|
|
2130
|
+
* The secure-context check runs first for the same reason it does in the media
|
|
2131
|
+
* classifier: over plain HTTP the whole API is absent or refuses, and reporting
|
|
2132
|
+
* "not supported" sends a developer hunting for a polyfill for something an
|
|
2133
|
+
* `https://` URL fixes.
|
|
2134
|
+
*
|
|
2135
|
+
* @param error - Whatever `navigator.credentials` rejected with.
|
|
2136
|
+
* @param ceremony - Which ceremony was running, for the message.
|
|
2137
|
+
* @returns The classified error, ready to throw or to show.
|
|
2138
|
+
*/
|
|
2139
|
+
export declare function classifyPasskeyError(error: unknown, ceremony: PasskeyCeremony): PasskeyError;
|
|
2140
|
+
|
|
1666
2141
|
declare type ClassValue = string | number | bigint | boolean | null | undefined | ClassValue[];
|
|
1667
2142
|
|
|
2143
|
+
/**
|
|
2144
|
+
* Remove the shared regions and cancel pending cleanups.
|
|
2145
|
+
*
|
|
2146
|
+
* For test teardown and for a micro-frontend being unmounted from a page it does
|
|
2147
|
+
* not own. Regular apps never need it — two empty hidden `div`s cost nothing, and
|
|
2148
|
+
* tearing them down while another component still announces would lose messages.
|
|
2149
|
+
*/
|
|
2150
|
+
export declare function clearAnnouncer(): void;
|
|
2151
|
+
|
|
1668
2152
|
/**
|
|
1669
2153
|
* Delete Cache Storage buckets whose name passes `filter` (all of them when no
|
|
1670
2154
|
* filter is given).
|
|
@@ -2070,7 +2554,29 @@ export declare function createApiClient(config: ApiClientConfig): ApiClient;
|
|
|
2070
2554
|
* Multiple players coexist independently; use this when several layers of UI
|
|
2071
2555
|
* need their own playback state.
|
|
2072
2556
|
*/
|
|
2073
|
-
export declare function createAudioPlayer():
|
|
2557
|
+
export declare function createAudioPlayer(): AudioPlayerHandle;
|
|
2558
|
+
|
|
2559
|
+
/**
|
|
2560
|
+
* Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.
|
|
2561
|
+
*
|
|
2562
|
+
* The engine is shared with the video recorder (`createMediaRecorder`), because the
|
|
2563
|
+
* subtle parts are not audio-specific: `MediaRecorder` reports **no duration** (WebM
|
|
2564
|
+
* it writes carries none in its header, which is why `<audio>` shows `Infinity` for a
|
|
2565
|
+
* fresh recording) so the clock is kept by hand and subtracts paused time; and
|
|
2566
|
+
* `stop()` returns *before* the last `dataavailable` event, so the blob can only be
|
|
2567
|
+
* assembled in `onstop`. What stays here is the part that genuinely differs — the
|
|
2568
|
+
* container list.
|
|
2569
|
+
*
|
|
2570
|
+
* The stream is **not** owned here: `stop()` leaves the microphone open so a retake
|
|
2571
|
+
* does not need a second permission round-trip. Release it with the owning
|
|
2572
|
+
* `useMicrophone().stop()`.
|
|
2573
|
+
*
|
|
2574
|
+
* @param stream - A live audio stream, usually from {@link useMicrophone}.
|
|
2575
|
+
* @param options - See {@link AudioRecorderOptions}.
|
|
2576
|
+
* @returns The imperative recorder.
|
|
2577
|
+
* @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.
|
|
2578
|
+
*/
|
|
2579
|
+
export declare function createAudioRecorder(stream: MediaStream, options?: AudioRecorderOptions): AudioRecorderHandle;
|
|
2074
2580
|
|
|
2075
2581
|
/**
|
|
2076
2582
|
* Build a typed Zustand auth store with `persist` middleware. Each app passes
|
|
@@ -2105,6 +2611,14 @@ export declare interface CreateAuthStoreOptions<TUser> {
|
|
|
2105
2611
|
initialToken?: string | null;
|
|
2106
2612
|
}
|
|
2107
2613
|
|
|
2614
|
+
/**
|
|
2615
|
+
* Build a native detector for the given formats.
|
|
2616
|
+
*
|
|
2617
|
+
* @param formats - Symbologies to look for. Must be ones the engine supports.
|
|
2618
|
+
* @returns The detector, or `null` when the API is missing or refused the formats.
|
|
2619
|
+
*/
|
|
2620
|
+
export declare function createBarcodeDetector(formats?: readonly BarcodeFormat[]): BarcodeDetectorLike | null;
|
|
2621
|
+
|
|
2108
2622
|
/**
|
|
2109
2623
|
* Build a ten-step tint scale from a single color.
|
|
2110
2624
|
*
|
|
@@ -2237,6 +2751,46 @@ export declare interface CreateI18nOptions {
|
|
|
2237
2751
|
messages: Catalog;
|
|
2238
2752
|
}
|
|
2239
2753
|
|
|
2754
|
+
/**
|
|
2755
|
+
* Timing and cost accounting for a pipeline that runs on the user's device.
|
|
2756
|
+
*/
|
|
2757
|
+
/**
|
|
2758
|
+
* Create a profiler for one run of a pipeline.
|
|
2759
|
+
*
|
|
2760
|
+
* Wrap each step in {@link InferenceProfiler.stage}, fold in durations you
|
|
2761
|
+
* already have (an SDK `speed` breakdown, say) with
|
|
2762
|
+
* {@link InferenceProfiler.mark}, then call `report()` once the run finishes.
|
|
2763
|
+
*
|
|
2764
|
+
* Stages are timed independently rather than as a tiling of the run, so
|
|
2765
|
+
* concurrent work is charged its real wall-clock span to each stage and the
|
|
2766
|
+
* timings can sum to more than `totalMs`. Surface that to users when you
|
|
2767
|
+
* render the breakdown — a bar chart implying a partition of the total would
|
|
2768
|
+
* be wrong for a pipeline that overlaps stages.
|
|
2769
|
+
*
|
|
2770
|
+
* @returns A profiler bound to the moment it was created.
|
|
2771
|
+
*
|
|
2772
|
+
* @example
|
|
2773
|
+
* ```typescript
|
|
2774
|
+
* import { createInferenceProfiler } from "tempest-react-sdk";
|
|
2775
|
+
* import { Detector } from "tempest-react-sdk/vision";
|
|
2776
|
+
*
|
|
2777
|
+
* const profiler = createInferenceProfiler();
|
|
2778
|
+
* const detector = await profiler.stage("load-model", () =>
|
|
2779
|
+
* Detector.create("/models/detect.onnx"),
|
|
2780
|
+
* );
|
|
2781
|
+
* const results = await profiler.stage("detect", () => detector.predict(blob));
|
|
2782
|
+
* profiler.mark("forward-pass", results[0].speed.inference);
|
|
2783
|
+
*
|
|
2784
|
+
* const report = await profiler.report({
|
|
2785
|
+
* models: [
|
|
2786
|
+
* { name: "detector", cacheName: "app-models", url: "/models/detect.onnx" },
|
|
2787
|
+
* ],
|
|
2788
|
+
* });
|
|
2789
|
+
* console.log(report.timings, report.totalMs, report.device, report.models);
|
|
2790
|
+
* ```
|
|
2791
|
+
*/
|
|
2792
|
+
export declare function createInferenceProfiler(): InferenceProfiler;
|
|
2793
|
+
|
|
2240
2794
|
/**
|
|
2241
2795
|
* Trivial in-memory adapter. Suitable for tests, local development, or as a
|
|
2242
2796
|
* fallback wrapping the real provider while it loads.
|
|
@@ -2272,6 +2826,48 @@ export declare interface CreateLaunchDarklyFeatureFlagsAdapterOptions {
|
|
|
2272
2826
|
client: LDClientLike;
|
|
2273
2827
|
}
|
|
2274
2828
|
|
|
2829
|
+
/**
|
|
2830
|
+
* Sample the loudness of a live stream, 0–1.
|
|
2831
|
+
*
|
|
2832
|
+
* This exists because a recorder with no visible level is indistinguishable from a
|
|
2833
|
+
* broken one. A muted OS input, a headset whose mic arm is switched off, the wrong
|
|
2834
|
+
* device selected — all three produce a perfectly successful recording of silence,
|
|
2835
|
+
* and the user only finds out after they finish talking.
|
|
2836
|
+
*
|
|
2837
|
+
* The value is RMS, not peak: peak reacts to a single sample and flickers, RMS tracks
|
|
2838
|
+
* perceived loudness. It is deliberately **not** React state — updating state per
|
|
2839
|
+
* frame would re-render the tree 60 times a second. Poll `level()` from a
|
|
2840
|
+
* `requestAnimationFrame` loop and write to the DOM, or read it inside an existing
|
|
2841
|
+
* animation.
|
|
2842
|
+
*
|
|
2843
|
+
* The `AudioContext` is created here and closed by `stop()`. Browsers cap the number
|
|
2844
|
+
* of live contexts (Chrome allows around six), so a meter left running on unmount
|
|
2845
|
+
* eventually breaks every later one on the page.
|
|
2846
|
+
*
|
|
2847
|
+
* @param stream - A live audio stream.
|
|
2848
|
+
* @param options - See {@link LevelMeterOptions}.
|
|
2849
|
+
* @returns A `level()` reader and a `stop()`.
|
|
2850
|
+
*
|
|
2851
|
+
* @example
|
|
2852
|
+
* const meter = createLevelMeter(stream);
|
|
2853
|
+
* const tick = () => { bar.style.transform = `scaleX(${meter.level()})`; raf = requestAnimationFrame(tick); };
|
|
2854
|
+
*/
|
|
2855
|
+
export declare function createLevelMeter(stream: MediaStream, { fftSize, decay }?: LevelMeterOptions): LevelMeter;
|
|
2856
|
+
|
|
2857
|
+
/**
|
|
2858
|
+
* `localStorage`-backed resume storage — the default.
|
|
2859
|
+
*
|
|
2860
|
+
* `localStorage` and not IndexedDB on purpose. The record is four fields and a
|
|
2861
|
+
* URL; the requirement is only that it survives a reload, and pulling Dexie in for
|
|
2862
|
+
* that would put an IndexedDB dependency in the bundle of every app that uploads a
|
|
2863
|
+
* file. Apps that already have `createOfflineStore` open can pass their own
|
|
2864
|
+
* {@link ResumableUploadStorage} instead.
|
|
2865
|
+
*
|
|
2866
|
+
* @param prefix - Key prefix. Default `"tempest-upload:"`.
|
|
2867
|
+
* @returns A storage that no-ops when `localStorage` is unavailable.
|
|
2868
|
+
*/
|
|
2869
|
+
export declare function createLocalUploadStorage(prefix?: string): ResumableUploadStorage;
|
|
2870
|
+
|
|
2275
2871
|
/**
|
|
2276
2872
|
* Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,
|
|
2277
2873
|
* remote ingestion) by implementing the `LoggerSink` interface.
|
|
@@ -2287,6 +2883,34 @@ export declare interface CreateLoggerOptions {
|
|
|
2287
2883
|
namespace?: string;
|
|
2288
2884
|
}
|
|
2289
2885
|
|
|
2886
|
+
/**
|
|
2887
|
+
* Wrap a `MediaStream` in a recorder with a real state machine and an honest clock.
|
|
2888
|
+
*
|
|
2889
|
+
* This is the engine behind both `createAudioRecorder` and `createVideoRecorder`; the
|
|
2890
|
+
* only thing it does not decide is which containers to try, because that is the one
|
|
2891
|
+
* part that genuinely differs between the two.
|
|
2892
|
+
*
|
|
2893
|
+
* Two things `MediaRecorder` does not give you:
|
|
2894
|
+
*
|
|
2895
|
+
* - **A duration.** It reports none, and the `Blob` has no reliable one either —
|
|
2896
|
+
* WebM written by `MediaRecorder` carries no duration in its header, which is why
|
|
2897
|
+
* `<audio>`/`<video>` shows `Infinity` for a fresh recording. So the clock is kept
|
|
2898
|
+
* here, and it subtracts paused time: a recorder that counts wall-clock through a
|
|
2899
|
+
* pause reports a 30-second note as two minutes.
|
|
2900
|
+
* - **A promise from `stop()`.** The last chunk arrives *after* `stop()` returns, in
|
|
2901
|
+
* a `dataavailable` event that fires before `onstop`. Assembling the blob in
|
|
2902
|
+
* `onstop` is the only point where every chunk is in hand.
|
|
2903
|
+
*
|
|
2904
|
+
* The stream is **not** owned here: `stop()` leaves the device open so a retake does
|
|
2905
|
+
* not need a second permission round-trip. Release it with the owning hook's `stop()`.
|
|
2906
|
+
*
|
|
2907
|
+
* @param stream - A live stream, from `getUserMedia` or `getDisplayMedia`.
|
|
2908
|
+
* @param options - See {@link MediaRecordingOptions}.
|
|
2909
|
+
* @returns The imperative recorder.
|
|
2910
|
+
* @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.
|
|
2911
|
+
*/
|
|
2912
|
+
export declare function createMediaRecorder(stream: MediaStream, options: MediaRecordingOptions): MediaRecorderHandle;
|
|
2913
|
+
|
|
2290
2914
|
/**
|
|
2291
2915
|
* Build a typed IndexedDB-backed store using Dexie. Optionally scope every
|
|
2292
2916
|
* operation by an `ownerField` (useful for multi-user SSE history, drafts,
|
|
@@ -2378,6 +3002,55 @@ export declare function createOSRMBackend(options: OSRMBackendOptions): RoutingB
|
|
|
2378
3002
|
*/
|
|
2379
3003
|
export declare function createPartialResponse(request: Request, response: Response): Promise<Response>;
|
|
2380
3004
|
|
|
3005
|
+
/**
|
|
3006
|
+
* Build a WebAuthn client: the base64url ↔ `ArrayBuffer` plumbing, the two
|
|
3007
|
+
* ceremonies, and one classified error type.
|
|
3008
|
+
*
|
|
3009
|
+
* ## What your backend must do
|
|
3010
|
+
*
|
|
3011
|
+
* This is the **client half only**, and a WebAuthn client that documents only its
|
|
3012
|
+
* own half is unusable. Four routes are yours to implement:
|
|
3013
|
+
*
|
|
3014
|
+
* 1. `POST /webauthn/register/begin` → a {@link PasskeyCreationOptionsJSON}. Mint a
|
|
3015
|
+
* random `challenge` (≥16 bytes), store it against the session, and list the
|
|
3016
|
+
* user's existing credentials in `excludeCredentials`.
|
|
3017
|
+
* 2. `POST /webauthn/register/finish` ← a {@link PasskeyRegistrationJSON}. Verify
|
|
3018
|
+
* the challenge, `origin` and `type` inside `clientDataJSON`, parse the
|
|
3019
|
+
* attestation object, then store the credential id, public key and signature
|
|
3020
|
+
* counter.
|
|
3021
|
+
* 3. `POST /webauthn/signin/begin` → a {@link PasskeyRequestOptionsJSON}. New
|
|
3022
|
+
* challenge. Omit `allowCredentials` for a usernameless or autofill flow.
|
|
3023
|
+
* 4. `POST /webauthn/signin/finish` ← a {@link PasskeyAuthenticationJSON}. Look the
|
|
3024
|
+
* credential up by `id`, verify the signature over
|
|
3025
|
+
* `authenticatorData || sha256(clientDataJSON)`, and reject a signature counter
|
|
3026
|
+
* that did not grow (a clone). Only then issue your session token.
|
|
3027
|
+
*
|
|
3028
|
+
* @param options - Defaults applied when the server options omit them.
|
|
3029
|
+
* @returns A client usable from anywhere — React, a plain form, a worker.
|
|
3030
|
+
*
|
|
3031
|
+
* @example
|
|
3032
|
+
* const passkeys = createPasskeyClient({ rpId: "acme.com" });
|
|
3033
|
+
*
|
|
3034
|
+
* const options = await api.post("/webauthn/register/begin");
|
|
3035
|
+
* const credential = await passkeys.register(options);
|
|
3036
|
+
* await api.post("/webauthn/register/finish", { body: credential });
|
|
3037
|
+
*/
|
|
3038
|
+
export declare function createPasskeyClient(options?: CreatePasskeyClientOptions): PasskeyClient;
|
|
3039
|
+
|
|
3040
|
+
/** Options for {@link createPasskeyClient}. */
|
|
3041
|
+
export declare interface CreatePasskeyClientOptions {
|
|
3042
|
+
/**
|
|
3043
|
+
* Default relying-party id, applied when the server options omit one. Must be
|
|
3044
|
+
* the page's domain or a registrable parent of it (`app.acme.com` may use
|
|
3045
|
+
* `acme.com`, never the other way round).
|
|
3046
|
+
*/
|
|
3047
|
+
rpId?: string;
|
|
3048
|
+
/** Default ceremony timeout in ms. Default `60_000`. */
|
|
3049
|
+
timeoutMs?: number;
|
|
3050
|
+
/** `navigator.credentials` replacement, for tests. */
|
|
3051
|
+
credentials?: CredentialsContainerLike;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
2381
3054
|
/**
|
|
2382
3055
|
* Record a live GPS trajectory from `navigator.geolocation.watchPosition`.
|
|
2383
3056
|
* Framework-free — the {@link usePositionTracker} hook wraps this for React.
|
|
@@ -2488,6 +3161,61 @@ export declare function createQueryKeys<TKey extends string, TEntries extends Re
|
|
|
2488
3161
|
*/
|
|
2489
3162
|
export declare function createRefreshQueue(refresh: () => Promise<void>): () => Promise<void>;
|
|
2490
3163
|
|
|
3164
|
+
/**
|
|
3165
|
+
* Chunked, resumable upload speaking the **tus 1.0.0** protocol (core plus the
|
|
3166
|
+
* *creation* and *termination* extensions).
|
|
3167
|
+
*
|
|
3168
|
+
* ## Why tus and not a bespoke scheme
|
|
3169
|
+
*
|
|
3170
|
+
* A resumable client whose wire format is undocumented cannot be integrated, and
|
|
3171
|
+
* inventing one means the backend is ours forever. tus is a published spec with
|
|
3172
|
+
* off-the-shelf servers (`tusd`, `tuspy`, `tus-node-server`), so a caller can point
|
|
3173
|
+
* this at something they did not write.
|
|
3174
|
+
*
|
|
3175
|
+
* ## What the backend must implement
|
|
3176
|
+
*
|
|
3177
|
+
* Every request carries `Tus-Resumable: 1.0.0`.
|
|
3178
|
+
*
|
|
3179
|
+
* | Step | Request | Expected response |
|
|
3180
|
+
* | --- | --- | --- |
|
|
3181
|
+
* | Create | `POST {endpoint}` + `Upload-Length`, `Upload-Metadata`, `Idempotency-Key` | `201` + `Location` (the upload URL, absolute or endpoint-relative) |
|
|
3182
|
+
* | Probe | `HEAD {uploadUrl}` | `200`/`204` + `Upload-Offset` |
|
|
3183
|
+
* | Write | `PATCH {uploadUrl}` + `Upload-Offset`, `Content-Type: application/offset+octet-stream`, chunk body | `204` + the new `Upload-Offset`; `409` when the offset does not match |
|
|
3184
|
+
* | Discard | `DELETE {uploadUrl}` | `204` |
|
|
3185
|
+
*
|
|
3186
|
+
* ## The failure that actually happens
|
|
3187
|
+
*
|
|
3188
|
+
* A chunk that the server stored but whose response never arrived. The client
|
|
3189
|
+
* cannot tell that from a chunk that was lost, and re-sending it blindly would
|
|
3190
|
+
* duplicate bytes. Two things prevent that:
|
|
3191
|
+
*
|
|
3192
|
+
* - **Writes are addressed, not appended.** Every `PATCH` states the offset it
|
|
3193
|
+
* writes at, so a retry after a lost response is asked to write bytes the server
|
|
3194
|
+
* already has and answers `409`. On any retry the client re-reads the truth with
|
|
3195
|
+
* `HEAD` first and continues from there.
|
|
3196
|
+
* - **Creation carries an `Idempotency-Key`** (from `generateIdempotencyKey`),
|
|
3197
|
+
* persisted before the first attempt and reused on retry. tus has no idempotent
|
|
3198
|
+
* creation of its own, so without this a lost `201` leaves an orphan upload on
|
|
3199
|
+
* the server. A backend that honours the header returns the same `Location`; one
|
|
3200
|
+
* that ignores it still works, it just keeps the orphan.
|
|
3201
|
+
*
|
|
3202
|
+
* @param options - Endpoint, file, and the knobs above.
|
|
3203
|
+
* @returns A handle with `start`/`pause`/`resume`/`abort` and live `state`/`offset`.
|
|
3204
|
+
*
|
|
3205
|
+
* @example
|
|
3206
|
+
* const upload = createResumableUpload({
|
|
3207
|
+
* endpoint: "/api/uploads",
|
|
3208
|
+
* file: recording,
|
|
3209
|
+
* metadata: { filename: "nota.webm", ticket: ticketId },
|
|
3210
|
+
* getToken: () => auth.getToken(),
|
|
3211
|
+
* onProgress: ({ fraction }) => setPercent(Math.round(fraction * 100)),
|
|
3212
|
+
* });
|
|
3213
|
+
*
|
|
3214
|
+
* const done = await upload.start();
|
|
3215
|
+
* if (done) await api.post("/api/tickets/1/audio", { body: { url: done.url } });
|
|
3216
|
+
*/
|
|
3217
|
+
export declare function createResumableUpload(options: ResumableUploadOptions): ResumableUpload;
|
|
3218
|
+
|
|
2491
3219
|
/**
|
|
2492
3220
|
* Build a simple RBAC {@link AccessControl} from a static permission set.
|
|
2493
3221
|
*
|
|
@@ -2735,6 +3463,30 @@ export declare interface CreateThemeOptions {
|
|
|
2735
3463
|
darkSelector?: string;
|
|
2736
3464
|
}
|
|
2737
3465
|
|
|
3466
|
+
/**
|
|
3467
|
+
* Record a video stream — a camera, a screen share, or a `canvas.captureStream()`.
|
|
3468
|
+
*
|
|
3469
|
+
* The state machine, the clock that subtracts paused time and the `stop()` that
|
|
3470
|
+
* resolves in `onstop` with every chunk in hand are shared with the audio recorder
|
|
3471
|
+
* (see `createMediaRecorder`); what this adds is the container list and
|
|
3472
|
+
* `videoBitsPerSecond`.
|
|
3473
|
+
*
|
|
3474
|
+
* The stream is **not** owned here. For a screen share in particular, stopping the
|
|
3475
|
+
* recorder must not stop the sharing: a support flow usually records, stops, lets the
|
|
3476
|
+
* user look at the result and then records again.
|
|
3477
|
+
*
|
|
3478
|
+
* @param stream - A live stream carrying at least one video track.
|
|
3479
|
+
* @param options - See {@link VideoRecorderOptions}.
|
|
3480
|
+
* @returns The imperative recorder.
|
|
3481
|
+
* @throws When `MediaRecorder` is unavailable, or an explicit `mimeType` is unsupported.
|
|
3482
|
+
*
|
|
3483
|
+
* @example
|
|
3484
|
+
* const recorder = createVideoRecorder(stream, { videoBitsPerSecond: 2_500_000 });
|
|
3485
|
+
* recorder.start();
|
|
3486
|
+
* const { blob, durationMs } = await recorder.stop();
|
|
3487
|
+
*/
|
|
3488
|
+
export declare function createVideoRecorder(stream: MediaStream, options?: VideoRecorderOptions): VideoRecorderHandle;
|
|
3489
|
+
|
|
2738
3490
|
/**
|
|
2739
3491
|
* Open a WebSocket with automatic exponential-backoff reconnect, optional
|
|
2740
3492
|
* heartbeat pings, and typed JSON parsing.
|
|
@@ -2796,6 +3548,28 @@ export declare interface CreateWebSocketOptions<T> {
|
|
|
2796
3548
|
onStatusChange?: (status: WebSocketStatus) => void;
|
|
2797
3549
|
}
|
|
2798
3550
|
|
|
3551
|
+
/**
|
|
3552
|
+
* Minimal subset of `navigator.credentials` the passkey client touches.
|
|
3553
|
+
*
|
|
3554
|
+
* Declared here — the `<X>Like` pattern the SDK's adapters use — for two reasons:
|
|
3555
|
+
* jsdom has no `navigator.credentials` at all, so tests must inject a double; and
|
|
3556
|
+
* `mediation: "conditional"` is newer than some TypeScript DOM libs, which would
|
|
3557
|
+
* otherwise reject the call that makes autofill work.
|
|
3558
|
+
*/
|
|
3559
|
+
export declare interface CredentialsContainerLike {
|
|
3560
|
+
/** Runs the registration ceremony. */
|
|
3561
|
+
create(options: {
|
|
3562
|
+
publicKey: PublicKeyCredentialCreationOptions;
|
|
3563
|
+
signal?: AbortSignal;
|
|
3564
|
+
}): Promise<Credential | null>;
|
|
3565
|
+
/** Runs the authentication ceremony. */
|
|
3566
|
+
get(options: {
|
|
3567
|
+
publicKey: PublicKeyCredentialRequestOptions;
|
|
3568
|
+
signal?: AbortSignal;
|
|
3569
|
+
mediation?: string;
|
|
3570
|
+
}): Promise<Credential | null>;
|
|
3571
|
+
}
|
|
3572
|
+
|
|
2799
3573
|
/** Cursor-paginated response envelope (`CursorPaginationSchema[T]`). */
|
|
2800
3574
|
export declare interface CursorPage<T> {
|
|
2801
3575
|
/** The rows for this batch. */
|
|
@@ -2927,25 +3701,53 @@ export declare interface DataProviderOptions {
|
|
|
2927
3701
|
|
|
2928
3702
|
/**
|
|
2929
3703
|
* Stateful, headless data table built on top of {@link Table}. Adds
|
|
2930
|
-
* client-side searching, click-to-sort columns, and
|
|
2931
|
-
* delegating all table markup to the underlying Table component.
|
|
3704
|
+
* client-side searching, click-to-sort columns, pagination and opt-in inline
|
|
3705
|
+
* editing while delegating all table markup to the underlying Table component.
|
|
2932
3706
|
*
|
|
2933
3707
|
* - Clicking a sortable header cycles asc → desc → unsorted.
|
|
2934
3708
|
* - Search matches a case-insensitive substring across `searchKeys`
|
|
2935
3709
|
* (or every string/number column when not provided).
|
|
2936
3710
|
* - Pagination is hidden when the result fits on a single page.
|
|
3711
|
+
* - A column with `editable` renders a button that opens an inline editor;
|
|
3712
|
+
* `Enter` commits, `Escape` discards, `Tab` walks to the next editable cell.
|
|
3713
|
+
*
|
|
3714
|
+
* Editing is strictly opt-in: with no `editable` column (or no `onCellChange`) the
|
|
3715
|
+
* rendered markup is byte-for-byte what it was before the feature existed, which
|
|
3716
|
+
* matters because the component is published.
|
|
3717
|
+
*
|
|
3718
|
+
* ## Optimistic, with a visible rollback
|
|
2937
3719
|
*
|
|
2938
|
-
*
|
|
2939
|
-
*
|
|
2940
|
-
*
|
|
2941
|
-
*
|
|
3720
|
+
* An accepted edit is shown immediately and `onCellChange` runs in the background.
|
|
3721
|
+
* If it rejects, the cell returns to the old value **and** shows the reason as a
|
|
3722
|
+
* `role="alert"` tied to the cell. A silent revert is worse than no optimistic
|
|
3723
|
+
* update at all: the user watched their edit appear and has no reason to doubt it.
|
|
3724
|
+
*
|
|
3725
|
+
* The header memo depends on `columns`, `sort` and the editing state only:
|
|
3726
|
+
* `toggleSort` and the commit callbacks are recreated each render but always close
|
|
3727
|
+
* over the same setters, so including them would rebuild every header on every
|
|
3728
|
+
* render without changing behaviour. That is why `exhaustive-deps` is silenced on
|
|
3729
|
+
* that dependency array.
|
|
2942
3730
|
*/
|
|
2943
|
-
export declare function DataTable<T>({ data, columns, pageSize, searchable, searchKeys, initialSort, rowKey, emptyMessage, className, ...rest }: DataTableProps<T>): JSX.Element;
|
|
3731
|
+
export declare function DataTable<T>({ data, columns, pageSize, searchable, searchKeys, initialSort, rowKey, emptyMessage, onCellChange, editLabels, className, ...rest }: DataTableProps<T>): JSX.Element;
|
|
3732
|
+
|
|
3733
|
+
/** One accepted cell edit, handed to `onCellChange`. */
|
|
3734
|
+
export declare interface DataTableCellChange<T> {
|
|
3735
|
+
/** The row as it was before the edit. */
|
|
3736
|
+
row: T;
|
|
3737
|
+
/** Which column changed. */
|
|
3738
|
+
key: keyof T;
|
|
3739
|
+
/** The parsed new value. */
|
|
3740
|
+
value: unknown;
|
|
3741
|
+
/** The value that was displayed before the edit. */
|
|
3742
|
+
previous: unknown;
|
|
3743
|
+
/** Index of the row in the full `data` array. */
|
|
3744
|
+
rowIndex: number;
|
|
3745
|
+
}
|
|
2944
3746
|
|
|
2945
3747
|
/**
|
|
2946
3748
|
* Column definition for {@link DataTable}. Extends the headless {@link Table}
|
|
2947
|
-
* column shape with a typed `key`, opt-in sorting,
|
|
2948
|
-
* are forwarded to the underlying Table cell.
|
|
3749
|
+
* column shape with a typed `key`, opt-in sorting, opt-in inline editing, and the
|
|
3750
|
+
* visual options that are forwarded to the underlying Table cell.
|
|
2949
3751
|
*/
|
|
2950
3752
|
export declare interface DataTableColumn<T> {
|
|
2951
3753
|
/** Property of the row this column reads from. Doubles as the cell key. */
|
|
@@ -2962,8 +3764,49 @@ export declare interface DataTableColumn<T> {
|
|
|
2962
3764
|
priority?: TablePriority;
|
|
2963
3765
|
/** Fixed column width forwarded to the Table cell. */
|
|
2964
3766
|
width?: string | number;
|
|
3767
|
+
/**
|
|
3768
|
+
* Let cells in this column be edited in place. Requires `onCellChange` on the
|
|
3769
|
+
* table; without it the column stays read-only.
|
|
3770
|
+
*/
|
|
3771
|
+
editable?: boolean;
|
|
3772
|
+
/** Editor input type. Default `"text"`. */
|
|
3773
|
+
editorType?: DataTableEditorType;
|
|
3774
|
+
/** Text the editor opens with. Defaults to `String(value ?? "")`. */
|
|
3775
|
+
formatEdit?: (row: T) => string;
|
|
3776
|
+
/**
|
|
3777
|
+
* Turn the typed string into the stored value. Defaults to the trimmed string,
|
|
3778
|
+
* or `Number(raw)` when `editorType` is `"number"`.
|
|
3779
|
+
*/
|
|
3780
|
+
parse?: (raw: string, row: T) => unknown;
|
|
3781
|
+
/** Return a message to reject the edit, or `null` to accept it. */
|
|
3782
|
+
validate?: (value: unknown, row: T) => string | null;
|
|
3783
|
+
}
|
|
3784
|
+
|
|
3785
|
+
/** Copy for the inline-editing affordances. Every entry has a PT-BR default. */
|
|
3786
|
+
export declare interface DataTableEditLabels {
|
|
3787
|
+
/**
|
|
3788
|
+
* Visually hidden prefix that turns a cell's own content into the button's name.
|
|
3789
|
+
*
|
|
3790
|
+
* A prefix and not a whole label: the accessible name has to *contain* the visible
|
|
3791
|
+
* text (WCAG 2.5.3, Label in Name), and a label built from the raw value would say
|
|
3792
|
+
* "850000" over a cell that reads `R$ 8.500,00` — which breaks voice control and
|
|
3793
|
+
* makes the screen reader disagree with the screen.
|
|
3794
|
+
*
|
|
3795
|
+
* A single space is appended when it is rendered, so the name reads
|
|
3796
|
+
* `"Editar Salário: R$ 8.500,00"`. Do not add one yourself.
|
|
3797
|
+
*/
|
|
3798
|
+
editCell: (column: string) => string;
|
|
3799
|
+
/** Accessible name of the editor input. */
|
|
3800
|
+
editor: (column: string, rowNumber: number) => string;
|
|
3801
|
+
/** Announced (politely) once a cell saved. */
|
|
3802
|
+
saved: (column: string) => string;
|
|
3803
|
+
/** Shown in the cell when the save was rejected and no reason was thrown. */
|
|
3804
|
+
saveFailed: (column: string) => string;
|
|
2965
3805
|
}
|
|
2966
3806
|
|
|
3807
|
+
/** Input types an editable column can use. */
|
|
3808
|
+
export declare type DataTableEditorType = "text" | "number" | "date" | "email" | "tel" | "url";
|
|
3809
|
+
|
|
2967
3810
|
export declare interface DataTableProps<T> extends HTMLAttributes<HTMLDivElement> {
|
|
2968
3811
|
/** Full, unfiltered dataset. Sorting/filtering/pagination happen client-side. */
|
|
2969
3812
|
data: T[];
|
|
@@ -2984,6 +3827,14 @@ export declare interface DataTableProps<T> extends HTMLAttributes<HTMLDivElement
|
|
|
2984
3827
|
rowKey?: (row: T, index: number) => string | number;
|
|
2985
3828
|
/** Content shown when no rows match. */
|
|
2986
3829
|
emptyMessage?: ReactNode;
|
|
3830
|
+
/**
|
|
3831
|
+
* Persist an accepted cell edit. Return a promise: while it is pending the cell
|
|
3832
|
+
* already shows the new value, and a rejection rolls that back and surfaces the
|
|
3833
|
+
* error in the cell. Without this prop no column is editable.
|
|
3834
|
+
*/
|
|
3835
|
+
onCellChange?: (change: DataTableCellChange<T>) => void | Promise<void>;
|
|
3836
|
+
/** Override the PT-BR copy of the editing affordances. */
|
|
3837
|
+
editLabels?: Partial<DataTableEditLabels>;
|
|
2987
3838
|
}
|
|
2988
3839
|
|
|
2989
3840
|
export declare interface DataTableSort<T> {
|
|
@@ -3118,12 +3969,24 @@ export declare function decodeJWT(token: string): DecodedJWT;
|
|
|
3118
3969
|
*/
|
|
3119
3970
|
export declare function deepMerge<T>(target: T, source: Partial<T>): T;
|
|
3120
3971
|
|
|
3972
|
+
/**
|
|
3973
|
+
* What a scanner looks for when you do not say.
|
|
3974
|
+
*
|
|
3975
|
+
* Deliberately three formats, not all fourteen. Every extra symbology is more work
|
|
3976
|
+
* per frame, and on a mid-range phone the difference between three and fourteen is the
|
|
3977
|
+
* difference between a scanner that locks on instantly and one that feels broken.
|
|
3978
|
+
*/
|
|
3979
|
+
export declare const DEFAULT_BARCODE_FORMATS: readonly BarcodeFormat[];
|
|
3980
|
+
|
|
3121
3981
|
/**
|
|
3122
3982
|
* Default average car speed in km/h used to derive duration from distance.
|
|
3123
3983
|
* Mirrors `DEFAULT_CAR_SPEED_KMH` from `tempest-fastapi-sdk`.
|
|
3124
3984
|
*/
|
|
3125
3985
|
export declare const DEFAULT_CAR_SPEED_KMH = 50;
|
|
3126
3986
|
|
|
3987
|
+
/** Default chunk size: 5 MiB, the size most tus servers are tuned for. */
|
|
3988
|
+
export declare const DEFAULT_CHUNK_SIZE: number;
|
|
3989
|
+
|
|
3127
3990
|
/**
|
|
3128
3991
|
* Multiplier applied to the great-circle distance to approximate real road
|
|
3129
3992
|
* distance. Mirrors `DEFAULT_CIRCUITY_FACTOR` from `tempest-fastapi-sdk`.
|
|
@@ -3137,6 +4000,21 @@ export declare const DEFAULT_CIRCUITY_FACTOR = 1.3;
|
|
|
3137
4000
|
*/
|
|
3138
4001
|
export declare const DEFAULT_MODE_DURATION_FACTORS: Record<TravelMode, number>;
|
|
3139
4002
|
|
|
4003
|
+
/**
|
|
4004
|
+
* COSE algorithms offered when the server sends no `pubKeyCredParams`, in
|
|
4005
|
+
* preference order.
|
|
4006
|
+
*
|
|
4007
|
+
* `-8` is Ed25519, which modern authenticators prefer and which produces the
|
|
4008
|
+
* smallest signatures. `-7` is ES256, the one algorithm every WebAuthn
|
|
4009
|
+
* authenticator supports. `-257` is RS256, needed for TPM-backed Windows Hello.
|
|
4010
|
+
* Offering all three is what avoids a `NotSupportedError` on some device you do
|
|
4011
|
+
* not own; a server that cannot verify one of them should send its own list.
|
|
4012
|
+
*/
|
|
4013
|
+
export declare const DEFAULT_PUB_KEY_CRED_PARAMS: {
|
|
4014
|
+
type: "public-key";
|
|
4015
|
+
alg: number;
|
|
4016
|
+
}[];
|
|
4017
|
+
|
|
3140
4018
|
/**
|
|
3141
4019
|
* Identity helper that types a declarative route tree. Use it so editors give
|
|
3142
4020
|
* autocomplete and type-checking on every node; the array is returned as-is.
|
|
@@ -3182,12 +4060,53 @@ export declare interface DescriptionListProps extends HTMLAttributes<HTMLDListEl
|
|
|
3182
4060
|
items: DescriptionListItem[];
|
|
3183
4061
|
}
|
|
3184
4062
|
|
|
4063
|
+
/**
|
|
4064
|
+
* The shape a detector resolves with, before normalisation.
|
|
4065
|
+
*
|
|
4066
|
+
* Every field is optional because a polyfill is allowed to report the value and no
|
|
4067
|
+
* geometry at all, and the native engines differ on `cornerPoints`.
|
|
4068
|
+
*/
|
|
4069
|
+
export declare interface DetectedBarcodeLike {
|
|
4070
|
+
rawValue?: string;
|
|
4071
|
+
format?: string;
|
|
4072
|
+
boundingBox?: DOMRectReadOnly;
|
|
4073
|
+
cornerPoints?: readonly BarcodePoint[];
|
|
4074
|
+
}
|
|
4075
|
+
|
|
4076
|
+
/**
|
|
4077
|
+
* Shapes describing what an on-device inference run cost.
|
|
4078
|
+
*
|
|
4079
|
+
* The browser exposes no energy counter and no FLOP counter, so "cost" here
|
|
4080
|
+
* is assembled from what a page can actually observe: how long each stage
|
|
4081
|
+
* took, how much parallelism and memory the device reports, and how large the
|
|
4082
|
+
* cached model weights are. Anything the platform does not expose stays
|
|
4083
|
+
* `null` — a UI can then render "—" instead of a fabricated number.
|
|
4084
|
+
*/
|
|
4085
|
+
/**
|
|
4086
|
+
* Device capabilities as reported by the browser.
|
|
4087
|
+
*
|
|
4088
|
+
* Every field is best-effort. `deviceMemoryGb` and `jsHeapUsedMb` come from
|
|
4089
|
+
* Chromium-only APIs (`navigator.deviceMemory`, `performance.memory`) and are
|
|
4090
|
+
* `null` everywhere else, including Firefox and Safari.
|
|
4091
|
+
*/
|
|
4092
|
+
export declare interface DeviceProfile {
|
|
4093
|
+
/** Logical cores available to workers, or `null` when unreported. */
|
|
4094
|
+
hardwareConcurrency: number | null;
|
|
4095
|
+
/** Approximate device RAM in GiB (coarse, Chromium-only), or `null`. */
|
|
4096
|
+
deviceMemoryGb: number | null;
|
|
4097
|
+
/** Used JS heap in MiB (Chromium-only), or `null`. */
|
|
4098
|
+
jsHeapUsedMb: number | null;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
3185
4101
|
export declare interface DisclosureHandlers {
|
|
3186
4102
|
open: () => void;
|
|
3187
4103
|
close: () => void;
|
|
3188
4104
|
toggle: () => void;
|
|
3189
4105
|
}
|
|
3190
4106
|
|
|
4107
|
+
/** Which surface to put first in the picker. */
|
|
4108
|
+
export declare type DisplaySurfaceHint = "monitor" | "window" | "browser";
|
|
4109
|
+
|
|
3191
4110
|
/** How many steps the diverging token scale has, midpoint included. */
|
|
3192
4111
|
export declare const DIVERGING_STEP_COUNT = 9;
|
|
3193
4112
|
|
|
@@ -3404,6 +4323,23 @@ export declare interface EmptyStateProps {
|
|
|
3404
4323
|
*/
|
|
3405
4324
|
export declare function encodeQR(text: string, options?: QREncodeOptions): QRMatrix;
|
|
3406
4325
|
|
|
4326
|
+
/**
|
|
4327
|
+
* Wrap PCM in a 16-bit RIFF/WAVE container.
|
|
4328
|
+
*
|
|
4329
|
+
* The header is the 44-byte canonical form: `RIFF` size, `WAVE`, a 16-byte `fmt `
|
|
4330
|
+
* chunk declaring format 1 (uncompressed PCM), then `data`. Samples are interleaved
|
|
4331
|
+
* and clamped before scaling, because a value even slightly past ±1 wraps around when
|
|
4332
|
+
* truncated to 16 bits and turns a loud passage into a burst of noise.
|
|
4333
|
+
*
|
|
4334
|
+
* Implemented here rather than pulled from a package: it is a fixed header and a
|
|
4335
|
+
* scaling loop, roughly forty lines, and a dependency for it would put its own
|
|
4336
|
+
* version bounds on every consumer of this SDK to save writing them.
|
|
4337
|
+
*
|
|
4338
|
+
* @param audio - Channels and sample rate.
|
|
4339
|
+
* @returns A `Blob` of type `audio/wav`.
|
|
4340
|
+
*/
|
|
4341
|
+
export declare function encodeWav({ channels, sampleRate }: PcmAudio): Blob;
|
|
4342
|
+
|
|
3407
4343
|
/**
|
|
3408
4344
|
* Class-based React error boundary with a render-prop or static fallback.
|
|
3409
4345
|
* Auto-resets when any value in `resetKeys` changes.
|
|
@@ -3643,7 +4579,7 @@ export declare interface Filter {
|
|
|
3643
4579
|
*/
|
|
3644
4580
|
export declare function FilterBar({ fields, value, onChange, locale, actions, className, ...rest }: FilterBarProps): JSX.Element;
|
|
3645
4581
|
|
|
3646
|
-
export declare interface FilterBarProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
4582
|
+
export declare interface FilterBarProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_12> {
|
|
3647
4583
|
/** Fields the user may filter by. */
|
|
3648
4584
|
fields: readonly FilterField[];
|
|
3649
4585
|
/** Applied filters. Controlled. */
|
|
@@ -3901,6 +4837,31 @@ export declare function formatDate(value: string | Date): string;
|
|
|
3901
4837
|
*/
|
|
3902
4838
|
export declare function formatDateTime(value: string | Date): string;
|
|
3903
4839
|
|
|
4840
|
+
/**
|
|
4841
|
+
* Rendering helpers for the numbers a profiler produces.
|
|
4842
|
+
*/
|
|
4843
|
+
/**
|
|
4844
|
+
* Format a millisecond duration for display.
|
|
4845
|
+
*
|
|
4846
|
+
* Sub-second values keep millisecond resolution — the interesting range for a
|
|
4847
|
+
* single forward pass — and anything longer switches to seconds so a cold
|
|
4848
|
+
* start that pays a model download does not read as a five-digit number.
|
|
4849
|
+
* Durations under `1 ms` render as `"<1 ms"` rather than `"0 ms"`, which
|
|
4850
|
+
* would read as "not measured".
|
|
4851
|
+
*
|
|
4852
|
+
* @param value Duration in milliseconds.
|
|
4853
|
+
* @returns The formatted string, or `"—"` for a non-finite or negative input.
|
|
4854
|
+
*
|
|
4855
|
+
* @example
|
|
4856
|
+
* ```typescript
|
|
4857
|
+
* formatDurationMs(0.04); // "<1 ms"
|
|
4858
|
+
* formatDurationMs(142.6); // "143 ms"
|
|
4859
|
+
* formatDurationMs(4321); // "4.32 s"
|
|
4860
|
+
* formatDurationMs(NaN); // "—"
|
|
4861
|
+
* ```
|
|
4862
|
+
*/
|
|
4863
|
+
export declare function formatDurationMs(value: number): string;
|
|
4864
|
+
|
|
3904
4865
|
/**
|
|
3905
4866
|
* Format a fraction (0-1) as a percentage with one decimal.
|
|
3906
4867
|
*
|
|
@@ -4110,6 +5071,18 @@ export declare interface GetListParams {
|
|
|
4110
5071
|
filters?: DataFilters;
|
|
4111
5072
|
}
|
|
4112
5073
|
|
|
5074
|
+
/**
|
|
5075
|
+
* Which symbologies this engine will actually decode.
|
|
5076
|
+
*
|
|
5077
|
+
* Worth asking rather than assuming: the format list belongs to the platform decoder,
|
|
5078
|
+
* not to the browser, so two Chromium builds on two operating systems answer
|
|
5079
|
+
* differently — and asking for a format the engine does not have makes the constructor
|
|
5080
|
+
* throw `NotSupportedError`, which reads like a bug in your code.
|
|
5081
|
+
*
|
|
5082
|
+
* @returns The supported formats, or an empty array when there is no detector.
|
|
5083
|
+
*/
|
|
5084
|
+
export declare function getSupportedBarcodeFormats(): Promise<readonly BarcodeFormat[]>;
|
|
5085
|
+
|
|
4113
5086
|
/**
|
|
4114
5087
|
* Look up a preset by name.
|
|
4115
5088
|
*
|
|
@@ -4467,15 +5440,79 @@ export declare interface ImageCropperProps extends Omit<HTMLAttributes<HTMLDivEl
|
|
|
4467
5440
|
ref?: React.Ref<ImageCropperHandle>;
|
|
4468
5441
|
}
|
|
4469
5442
|
|
|
4470
|
-
export declare interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src"> {
|
|
4471
|
-
/** Primary image source URL. */
|
|
4472
|
-
src: string;
|
|
4473
|
-
/** Fallback source swapped in once if the primary `src` fails to load. */
|
|
4474
|
-
fallback?: string;
|
|
4475
|
-
/** Alternative text describing the image (required for accessibility). */
|
|
4476
|
-
alt: string;
|
|
4477
|
-
/** When true (default) uses native lazy loading; otherwise loads eagerly. */
|
|
4478
|
-
lazy?: boolean;
|
|
5443
|
+
export declare interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src"> {
|
|
5444
|
+
/** Primary image source URL. */
|
|
5445
|
+
src: string;
|
|
5446
|
+
/** Fallback source swapped in once if the primary `src` fails to load. */
|
|
5447
|
+
fallback?: string;
|
|
5448
|
+
/** Alternative text describing the image (required for accessibility). */
|
|
5449
|
+
alt: string;
|
|
5450
|
+
/** When true (default) uses native lazy loading; otherwise loads eagerly. */
|
|
5451
|
+
lazy?: boolean;
|
|
5452
|
+
}
|
|
5453
|
+
|
|
5454
|
+
/**
|
|
5455
|
+
* Records how long each stage of a pipeline took.
|
|
5456
|
+
*
|
|
5457
|
+
* Stages are measured **independently**, not as a tiling of the whole run:
|
|
5458
|
+
* two stages started concurrently are each charged their full wall-clock
|
|
5459
|
+
* span, so the sum can exceed {@link InferenceReport.totalMs}. That is the
|
|
5460
|
+
* honest reading for a pipeline that decodes an image while the model
|
|
5461
|
+
* sessions are still loading.
|
|
5462
|
+
*/
|
|
5463
|
+
export declare interface InferenceProfiler {
|
|
5464
|
+
/**
|
|
5465
|
+
* Run an async stage and record its duration.
|
|
5466
|
+
*
|
|
5467
|
+
* @param name Stage label used as the key in the report.
|
|
5468
|
+
* @param run The work to time.
|
|
5469
|
+
* @returns Whatever `run` resolved to.
|
|
5470
|
+
*/
|
|
5471
|
+
stage<T>(name: string, run: () => Promise<T>): Promise<T>;
|
|
5472
|
+
/**
|
|
5473
|
+
* Run a synchronous stage and record its duration.
|
|
5474
|
+
*
|
|
5475
|
+
* @param name Stage label used as the key in the report.
|
|
5476
|
+
* @param run The work to time.
|
|
5477
|
+
* @returns Whatever `run` returned.
|
|
5478
|
+
*/
|
|
5479
|
+
stageSync<T>(name: string, run: () => T): T;
|
|
5480
|
+
/**
|
|
5481
|
+
* Record a duration measured elsewhere — a `speed` breakdown returned by
|
|
5482
|
+
* `tempest-react-sdk/vision`, for instance.
|
|
5483
|
+
*
|
|
5484
|
+
* Repeated names accumulate, so folding two passes of the same kind into
|
|
5485
|
+
* one row is a matter of calling `mark` twice.
|
|
5486
|
+
*
|
|
5487
|
+
* @param name Stage label used as the key in the report.
|
|
5488
|
+
* @param durationMs How long it took, in milliseconds.
|
|
5489
|
+
*/
|
|
5490
|
+
mark(name: string, durationMs: number): void;
|
|
5491
|
+
/**
|
|
5492
|
+
* Assemble the report for everything recorded so far.
|
|
5493
|
+
*
|
|
5494
|
+
* @param options Which models to size up in Cache Storage.
|
|
5495
|
+
* @returns The finished report.
|
|
5496
|
+
*/
|
|
5497
|
+
report(options?: InferenceReportOptions): Promise<InferenceReport>;
|
|
5498
|
+
}
|
|
5499
|
+
|
|
5500
|
+
/** What one profiled run cost. */
|
|
5501
|
+
export declare interface InferenceReport {
|
|
5502
|
+
/** Duration in milliseconds per stage name, in the order first recorded. */
|
|
5503
|
+
timings: Readonly<Record<string, number>>;
|
|
5504
|
+
/** Milliseconds from profiler creation to the `report()` call. */
|
|
5505
|
+
totalMs: number;
|
|
5506
|
+
device: DeviceProfile;
|
|
5507
|
+
models: readonly ProfiledModelSize[];
|
|
5508
|
+
/** Epoch millis at which the report was assembled. */
|
|
5509
|
+
measuredAt: number;
|
|
5510
|
+
}
|
|
5511
|
+
|
|
5512
|
+
/** Options for {@link InferenceProfiler.report}. */
|
|
5513
|
+
export declare interface InferenceReportOptions {
|
|
5514
|
+
/** Models to measure in Cache Storage. Omit to report none. */
|
|
5515
|
+
models?: readonly ProfiledModel[];
|
|
4479
5516
|
}
|
|
4480
5517
|
|
|
4481
5518
|
export declare interface InMemoryFlagsOptions {
|
|
@@ -4741,6 +5778,46 @@ export declare function isAndroidWithoutPromptApi(): boolean;
|
|
|
4741
5778
|
*/
|
|
4742
5779
|
export declare function isApiError(error: unknown): error is ApiError;
|
|
4743
5780
|
|
|
5781
|
+
/**
|
|
5782
|
+
* Whether this browser can route audio to a chosen output device.
|
|
5783
|
+
*
|
|
5784
|
+
* Chromium-only at the time of writing: Firefox has `setSinkId` behind a preference
|
|
5785
|
+
* that is off by default, and Safari does not implement it at all. Check this before
|
|
5786
|
+
* rendering an output picker, or the control is a lie on two of three engines.
|
|
5787
|
+
*/
|
|
5788
|
+
export declare function isAudioOutputSelectionSupported(): boolean;
|
|
5789
|
+
|
|
5790
|
+
/** Whether `MediaRecorder` exists and can produce at least one audio container. */
|
|
5791
|
+
export declare function isAudioRecordingSupported(): boolean;
|
|
5792
|
+
|
|
5793
|
+
/**
|
|
5794
|
+
* Whether this browser can decode barcodes on its own.
|
|
5795
|
+
*
|
|
5796
|
+
* **Expect `false` on a lot of real devices, and design for it.** `BarcodeDetector` is
|
|
5797
|
+
* a Chromium-only API backed by a platform decoder, so it is there on Android and
|
|
5798
|
+
* ChromeOS, usually there on macOS, and **absent** on Chromium for Windows and Linux,
|
|
5799
|
+
* in Firefox, and in every browser on iOS (all of which are WebKit underneath,
|
|
5800
|
+
* including Chrome for iOS).
|
|
5801
|
+
*
|
|
5802
|
+
* This SDK ships **no** decoder of its own and no bundled fallback: a QR reader is
|
|
5803
|
+
* Reed–Solomon error correction plus perspective correction plus a finder-pattern
|
|
5804
|
+
* search, and the honest options are a WASM build every consumer of this SDK would pay
|
|
5805
|
+
* for, or nothing. So the escape hatch is injection instead — pass any
|
|
5806
|
+
* {@link BarcodeDetectorLike} (the `barcode-detector` polyfill, your own `zxing-wasm`
|
|
5807
|
+
* wrapper) as `detector` to `useBarcodeScanner`, and the SDK drives it exactly like
|
|
5808
|
+
* the native one.
|
|
5809
|
+
*
|
|
5810
|
+
* @returns `true` when `new BarcodeDetector()` will work.
|
|
5811
|
+
*/
|
|
5812
|
+
export declare function isBarcodeDetectionSupported(): boolean;
|
|
5813
|
+
|
|
5814
|
+
/**
|
|
5815
|
+
* Whether autofill-driven passkeys (`mediation: "conditional"`) are available.
|
|
5816
|
+
*
|
|
5817
|
+
* @returns `false` when the API is missing or throws.
|
|
5818
|
+
*/
|
|
5819
|
+
export declare function isConditionalMediationAvailable(): Promise<boolean>;
|
|
5820
|
+
|
|
4744
5821
|
/**
|
|
4745
5822
|
* Type guard for {@link Coordinate}: an object with finite, in-range
|
|
4746
5823
|
* `latitude` and `longitude`.
|
|
@@ -4805,6 +5882,14 @@ export declare function isIOS(): boolean;
|
|
|
4805
5882
|
*/
|
|
4806
5883
|
export declare function isJWTExpired(token: string, leewaySeconds?: number): boolean;
|
|
4807
5884
|
|
|
5885
|
+
/**
|
|
5886
|
+
* Whether `getUserMedia` is reachable at all.
|
|
5887
|
+
*
|
|
5888
|
+
* Separate from the classifier because a page often wants to hide a "record" button
|
|
5889
|
+
* entirely rather than render it and fail on click.
|
|
5890
|
+
*/
|
|
5891
|
+
export declare function isMediaCaptureSupported(): boolean;
|
|
5892
|
+
|
|
4808
5893
|
/**
|
|
4809
5894
|
* Type guard asserting a value is a number, excluding `NaN`.
|
|
4810
5895
|
*
|
|
@@ -4823,6 +5908,15 @@ export declare function isNumber(value: unknown): value is number;
|
|
|
4823
5908
|
*/
|
|
4824
5909
|
export declare function isOffsetPage<T = unknown>(value: unknown): value is OffsetPage<T>;
|
|
4825
5910
|
|
|
5911
|
+
/**
|
|
5912
|
+
* Whether this browser exposes WebAuthn at all.
|
|
5913
|
+
*
|
|
5914
|
+
* Note that "supported" is not "usable": WebAuthn also requires a secure context,
|
|
5915
|
+
* and a device may have no authenticator. Use
|
|
5916
|
+
* {@link isPlatformAuthenticatorAvailable} before offering a passkey button.
|
|
5917
|
+
*/
|
|
5918
|
+
export declare function isPasskeySupported(): boolean;
|
|
5919
|
+
|
|
4826
5920
|
/**
|
|
4827
5921
|
* Type guard asserting a value is a plain object literal.
|
|
4828
5922
|
*
|
|
@@ -4837,15 +5931,36 @@ export declare function isOffsetPage<T = unknown>(value: unknown): value is Offs
|
|
|
4837
5931
|
*/
|
|
4838
5932
|
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
4839
5933
|
|
|
5934
|
+
/**
|
|
5935
|
+
* Whether the device has a **built-in** authenticator — Face ID, Touch ID,
|
|
5936
|
+
* Windows Hello, an Android screen lock.
|
|
5937
|
+
*
|
|
5938
|
+
* This is the check that decides whether "Entrar com passkey" may be shown at
|
|
5939
|
+
* all. `isPasskeySupported()` is true on a desktop with no biometrics and no
|
|
5940
|
+
* security key, and offering a passkey there sends the user into a sheet that can
|
|
5941
|
+
* only be cancelled. A `false` here does not forbid passkeys — a phone can still
|
|
5942
|
+
* be used over hybrid/QR — it means the flow needs a second step, so present it
|
|
5943
|
+
* as "usar meu celular", not as one tap.
|
|
5944
|
+
*
|
|
5945
|
+
* @returns `false` when the API is missing, so a caller never has to null-check.
|
|
5946
|
+
*/
|
|
5947
|
+
export declare function isPlatformAuthenticatorAvailable(): Promise<boolean>;
|
|
5948
|
+
|
|
4840
5949
|
/**
|
|
4841
5950
|
* Convenience check for environments where the Push API is unavailable
|
|
4842
5951
|
* (Safari iOS without PWA install, older browsers, SSR, etc.).
|
|
4843
5952
|
*/
|
|
4844
5953
|
export declare function isPushSupported(): boolean;
|
|
4845
5954
|
|
|
5955
|
+
/** Whether `getDisplayMedia` is reachable at all. */
|
|
5956
|
+
export declare function isScreenCaptureSupported(): boolean;
|
|
5957
|
+
|
|
4846
5958
|
/** True when the Web Share API is available in this environment. */
|
|
4847
5959
|
export declare function isShareSupported(): boolean;
|
|
4848
5960
|
|
|
5961
|
+
/** Whether this browser exposes the Web Speech recognition API at all. */
|
|
5962
|
+
export declare function isSpeechRecognitionSupported(): boolean;
|
|
5963
|
+
|
|
4849
5964
|
/**
|
|
4850
5965
|
* Reports whether the app is running as an installed PWA (Android Chrome, iOS,
|
|
4851
5966
|
* or desktop). Use it to suppress install CTAs once the user is already in the
|
|
@@ -4870,6 +5985,9 @@ export declare function isValidLatitude(value: number): boolean;
|
|
|
4870
5985
|
/** True when `value` is a finite longitude in `[-180, 180]`. */
|
|
4871
5986
|
export declare function isValidLongitude(value: number): boolean;
|
|
4872
5987
|
|
|
5988
|
+
/** Whether `MediaRecorder` exists and can produce at least one video container. */
|
|
5989
|
+
export declare function isVideoRecordingSupported(): boolean;
|
|
5990
|
+
|
|
4873
5991
|
/**
|
|
4874
5992
|
* Kanban board: columns of cards, reorderable within a column and movable across
|
|
4875
5993
|
* columns, by pointer **or** keyboard.
|
|
@@ -5104,6 +6222,31 @@ export declare interface LDClientLike {
|
|
|
5104
6222
|
off?: (event: string, handler: () => void) => void;
|
|
5105
6223
|
}
|
|
5106
6224
|
|
|
6225
|
+
/** A running level meter. */
|
|
6226
|
+
export declare interface LevelMeter {
|
|
6227
|
+
/** Latest level, 0–1. Read it on your own frame loop. */
|
|
6228
|
+
level: () => number;
|
|
6229
|
+
/** Stop sampling and release the Web Audio graph. */
|
|
6230
|
+
stop: () => void;
|
|
6231
|
+
}
|
|
6232
|
+
|
|
6233
|
+
/** Options for {@link createLevelMeter}. */
|
|
6234
|
+
export declare interface LevelMeterOptions {
|
|
6235
|
+
/**
|
|
6236
|
+
* FFT window. 1024 is a good default: ~21 ms at 48 kHz, long enough to be stable
|
|
6237
|
+
* and short enough to react to a syllable.
|
|
6238
|
+
*/
|
|
6239
|
+
fftSize?: number;
|
|
6240
|
+
/**
|
|
6241
|
+
* Extra smoothing on the way down, 0–1. Default `0.7`.
|
|
6242
|
+
*
|
|
6243
|
+
* A raw RMS reading is jittery enough to make a meter look broken. Attack is left
|
|
6244
|
+
* instant — a meter that lags the voice going *up* reads as "not recording" —
|
|
6245
|
+
* while the decay is eased, which is how every hardware meter behaves.
|
|
6246
|
+
*/
|
|
6247
|
+
decay?: number;
|
|
6248
|
+
}
|
|
6249
|
+
|
|
5107
6250
|
/**
|
|
5108
6251
|
* Full-screen image viewer with keyboard navigation.
|
|
5109
6252
|
*
|
|
@@ -5363,7 +6506,7 @@ export declare type MarkdownInline = {
|
|
|
5363
6506
|
type: "break";
|
|
5364
6507
|
};
|
|
5365
6508
|
|
|
5366
|
-
export declare interface MarkdownProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
6509
|
+
export declare interface MarkdownProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_11> {
|
|
5367
6510
|
/** The Markdown source. */
|
|
5368
6511
|
source: string;
|
|
5369
6512
|
/**
|
|
@@ -5401,7 +6544,7 @@ export declare interface MarkdownProps extends Omit<HTMLAttributes<HTMLDivElemen
|
|
|
5401
6544
|
*/
|
|
5402
6545
|
export declare function Masonry<T>({ items, children, itemKey, columns, gap, className, style, ...rest }: MasonryProps<T>): JSX.Element;
|
|
5403
6546
|
|
|
5404
|
-
export declare interface MasonryProps<T> extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
6547
|
+
export declare interface MasonryProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_10> {
|
|
5405
6548
|
/** What to lay out. */
|
|
5406
6549
|
items: readonly T[];
|
|
5407
6550
|
/** Render one card. */
|
|
@@ -5430,6 +6573,115 @@ export declare interface MasonryProps<T> extends Omit<HTMLAttributes<HTMLDivElem
|
|
|
5430
6573
|
*/
|
|
5431
6574
|
export declare function matrixToPath(matrix: QRMatrix, margin?: number): string;
|
|
5432
6575
|
|
|
6576
|
+
/** A classified capture error with a human-readable, English message. */
|
|
6577
|
+
export declare interface MediaAccessError {
|
|
6578
|
+
kind: MediaAccessErrorKind;
|
|
6579
|
+
message: string;
|
|
6580
|
+
}
|
|
6581
|
+
|
|
6582
|
+
/** Classified reason a capture device could not be acquired. */
|
|
6583
|
+
export declare type MediaAccessErrorKind = "unsupported" | "insecure" | "permission-denied" | "not-found" | "in-use" | "unknown";
|
|
6584
|
+
|
|
6585
|
+
/**
|
|
6586
|
+
* What a media error is about.
|
|
6587
|
+
*
|
|
6588
|
+
* `"screen"` is not a device in the `getUserMedia` sense — it is what
|
|
6589
|
+
* `getDisplayMedia` captures — but it fails through the same `DOMException` names, so
|
|
6590
|
+
* it is classified by the same function rather than by a second copy of the table.
|
|
6591
|
+
*/
|
|
6592
|
+
export declare type MediaDeviceKindLabel = "microphone" | "camera" | "screen";
|
|
6593
|
+
|
|
6594
|
+
/** One device the browser is willing to tell us about. */
|
|
6595
|
+
export declare interface MediaDeviceOption {
|
|
6596
|
+
deviceId: string;
|
|
6597
|
+
/**
|
|
6598
|
+
* Human label, or `""` until permission has been granted.
|
|
6599
|
+
*
|
|
6600
|
+
* See {@link UseMediaDevicesResult.labelsAvailable} — an empty label is not a
|
|
6601
|
+
* bug, it is the browser refusing to fingerprint the machine.
|
|
6602
|
+
*/
|
|
6603
|
+
label: string;
|
|
6604
|
+
kind: MediaDeviceKind;
|
|
6605
|
+
groupId: string;
|
|
6606
|
+
}
|
|
6607
|
+
|
|
6608
|
+
/** Which capture permission to observe. */
|
|
6609
|
+
export declare type MediaPermissionName = "microphone" | "camera";
|
|
6610
|
+
|
|
6611
|
+
/**
|
|
6612
|
+
* Permission state, including the two cases the browser prompt cannot tell you
|
|
6613
|
+
* apart on its own.
|
|
6614
|
+
*
|
|
6615
|
+
* - `"unknown"` — the Permissions API is unavailable (Safari does not report
|
|
6616
|
+
* `microphone`), so the only way to learn the answer is to ask for the device.
|
|
6617
|
+
* - `"prompt"` — never asked. Asking now shows the browser prompt.
|
|
6618
|
+
* - `"granted"` / `"denied"` — settled. `"denied"` is **sticky**: calling
|
|
6619
|
+
* `getUserMedia` again does not re-prompt, it rejects immediately.
|
|
6620
|
+
*/
|
|
6621
|
+
export declare type MediaPermissionState = "unknown" | "prompt" | "granted" | "denied";
|
|
6622
|
+
|
|
6623
|
+
/** Imperative recorder over one `MediaStream`. */
|
|
6624
|
+
export declare interface MediaRecorderHandle {
|
|
6625
|
+
/** Begin recording. No-op when already recording or paused. */
|
|
6626
|
+
start: () => void;
|
|
6627
|
+
/** Pause. The clock stops; `durationMs` freezes. */
|
|
6628
|
+
pause: () => void;
|
|
6629
|
+
/** Resume after `pause()`. */
|
|
6630
|
+
resume: () => void;
|
|
6631
|
+
/** Stop and resolve with the assembled recording. */
|
|
6632
|
+
stop: () => Promise<MediaRecording>;
|
|
6633
|
+
/** Stop and throw the bytes away. */
|
|
6634
|
+
cancel: () => void;
|
|
6635
|
+
status: () => MediaRecorderStatus;
|
|
6636
|
+
/** Recorded length so far, excluding paused time. */
|
|
6637
|
+
durationMs: () => number;
|
|
6638
|
+
/** The negotiated container. */
|
|
6639
|
+
mimeType: string;
|
|
6640
|
+
}
|
|
6641
|
+
|
|
6642
|
+
/** Lifecycle of a recording. */
|
|
6643
|
+
export declare type MediaRecorderStatus = "idle" | "recording" | "paused" | "stopped";
|
|
6644
|
+
|
|
6645
|
+
/** A finished recording, whatever it was made of. */
|
|
6646
|
+
export declare interface MediaRecording {
|
|
6647
|
+
/** The bytes. Wrap with `useObjectUrl` to play it, or POST it as-is. */
|
|
6648
|
+
blob: Blob;
|
|
6649
|
+
/** What the browser actually produced — not necessarily what you asked for. */
|
|
6650
|
+
mimeType: string;
|
|
6651
|
+
/** Recorded length, excluding time spent paused. */
|
|
6652
|
+
durationMs: number;
|
|
6653
|
+
}
|
|
6654
|
+
|
|
6655
|
+
/** What a track carries — used only to word the errors this engine throws. */
|
|
6656
|
+
export declare type MediaRecordingKind = "audio" | "video";
|
|
6657
|
+
|
|
6658
|
+
/** Options for {@link createMediaRecorder}. */
|
|
6659
|
+
export declare interface MediaRecordingOptions {
|
|
6660
|
+
/**
|
|
6661
|
+
* Container candidates, best first. Required: this engine has no opinion about
|
|
6662
|
+
* codecs — the audio and video wrappers own that list.
|
|
6663
|
+
*/
|
|
6664
|
+
candidates: readonly string[];
|
|
6665
|
+
/** Wording for the thrown messages ("cannot record any supported *video* container"). */
|
|
6666
|
+
kind: MediaRecordingKind;
|
|
6667
|
+
/** Force a container, bypassing the negotiation. Throws when unsupported. */
|
|
6668
|
+
mimeType?: string;
|
|
6669
|
+
/** Target audio bitrate. */
|
|
6670
|
+
audioBitsPerSecond?: number;
|
|
6671
|
+
/** Target video bitrate. Ignored by the browser on an audio-only stream. */
|
|
6672
|
+
videoBitsPerSecond?: number;
|
|
6673
|
+
/**
|
|
6674
|
+
* Emit a chunk every N ms through `onChunk`, for streaming upload.
|
|
6675
|
+
*
|
|
6676
|
+
* Without it the whole recording is buffered in memory until `stop()`.
|
|
6677
|
+
*/
|
|
6678
|
+
timesliceMs?: number;
|
|
6679
|
+
/** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */
|
|
6680
|
+
onChunk?: (chunk: Blob) => void;
|
|
6681
|
+
/** Recorder-level failure (device unplugged mid-recording, encoder error). */
|
|
6682
|
+
onError?: (error: unknown) => void;
|
|
6683
|
+
}
|
|
6684
|
+
|
|
5433
6685
|
/**
|
|
5434
6686
|
* Memoize only the most recent call of `fn`, keyed by shallow-equal arguments.
|
|
5435
6687
|
*
|
|
@@ -5513,6 +6765,23 @@ export declare interface MercatorPoint {
|
|
|
5513
6765
|
|
|
5514
6766
|
export declare type Messages = Record<string, string>;
|
|
5515
6767
|
|
|
6768
|
+
/** Lifecycle of a microphone stream. */
|
|
6769
|
+
export declare type MicrophoneStatus = "idle" | "requesting" | "ready" | "error";
|
|
6770
|
+
|
|
6771
|
+
/**
|
|
6772
|
+
* The error for "the API is not here at all", which is a different question from
|
|
6773
|
+
* "the API rejected".
|
|
6774
|
+
*
|
|
6775
|
+
* `classifyMediaError` takes a thrown value; a missing `navigator.mediaDevices` never
|
|
6776
|
+
* threw one, and handing it `null` would come back `unknown` — the least actionable
|
|
6777
|
+
* kind there is. The two real causes are an insecure page (the fix is a URL) and an
|
|
6778
|
+
* engine that genuinely cannot capture (the fix is another browser), and telling them
|
|
6779
|
+
* apart is the whole point.
|
|
6780
|
+
*
|
|
6781
|
+
* @param device - Which device was being opened, for the message.
|
|
6782
|
+
*/
|
|
6783
|
+
export declare function missingCaptureApiError(device?: MediaDeviceKindLabel): MediaAccessError;
|
|
6784
|
+
|
|
5516
6785
|
/**
|
|
5517
6786
|
* Portal-rendered modal dialog with backdrop, Esc handler, and slots for
|
|
5518
6787
|
* header/body/footer. Locks body scroll while open.
|
|
@@ -5782,6 +7051,19 @@ export declare interface NavigationRailProps extends Omit<HTMLAttributes<HTMLEle
|
|
|
5782
7051
|
|
|
5783
7052
|
export { NavLink }
|
|
5784
7053
|
|
|
7054
|
+
/**
|
|
7055
|
+
* Turn one raw detection into a {@link BarcodeScanResult}.
|
|
7056
|
+
*
|
|
7057
|
+
* An unrecognised `format` string becomes `"unknown"` rather than being passed through
|
|
7058
|
+
* as a lie about the union, and missing geometry becomes `null`/`[]` rather than
|
|
7059
|
+
* `undefined`, so a consumer never has to branch on three kinds of absence.
|
|
7060
|
+
*
|
|
7061
|
+
* @param raw - What the detector resolved with.
|
|
7062
|
+
* @param known - The formats considered valid. Defaults to the whole spec list.
|
|
7063
|
+
* @returns The normalised result.
|
|
7064
|
+
*/
|
|
7065
|
+
export declare function normalizeBarcode(raw: DetectedBarcodeLike, known?: readonly BarcodeFormat[]): BarcodeScanResult;
|
|
7066
|
+
|
|
5785
7067
|
/**
|
|
5786
7068
|
* Normalize a longitude into the `[-180, 180]` range, wrapping values that
|
|
5787
7069
|
* cross the antimeridian (e.g. `190` → `-170`).
|
|
@@ -6353,6 +7635,15 @@ export { Outlet }
|
|
|
6353
7635
|
*/
|
|
6354
7636
|
declare type OverriddenDomProps = "children" | "title" | "onSelect";
|
|
6355
7637
|
|
|
7638
|
+
/** DOM attributes this component redefines. */
|
|
7639
|
+
declare type OverriddenDomProps_10 = "children";
|
|
7640
|
+
|
|
7641
|
+
/** DOM attributes this component redefines. */
|
|
7642
|
+
declare type OverriddenDomProps_11 = "children";
|
|
7643
|
+
|
|
7644
|
+
/** DOM attributes this component redefines. */
|
|
7645
|
+
declare type OverriddenDomProps_12 = "children" | "onChange";
|
|
7646
|
+
|
|
6356
7647
|
/** DOM attributes this component redefines. */
|
|
6357
7648
|
declare type OverriddenDomProps_2 = "children" | "onSubmit";
|
|
6358
7649
|
|
|
@@ -6360,22 +7651,22 @@ declare type OverriddenDomProps_2 = "children" | "onSubmit";
|
|
|
6360
7651
|
declare type OverriddenDomProps_3 = "onSubmit" | "value" | "defaultValue" | "rows";
|
|
6361
7652
|
|
|
6362
7653
|
/** DOM attributes this component redefines. */
|
|
6363
|
-
declare type OverriddenDomProps_4 = "children"
|
|
6364
|
-
|
|
6365
|
-
/** DOM attributes the composer redefines. */
|
|
6366
|
-
declare type OverriddenDomProps_5 = "onSubmit" | "value" | "defaultValue" | "rows";
|
|
7654
|
+
declare type OverriddenDomProps_4 = "children";
|
|
6367
7655
|
|
|
6368
7656
|
/** DOM attributes this component redefines. */
|
|
6369
|
-
declare type
|
|
7657
|
+
declare type OverriddenDomProps_5 = "children" | "onError";
|
|
6370
7658
|
|
|
6371
7659
|
/** DOM attributes this component redefines. */
|
|
6372
|
-
declare type
|
|
7660
|
+
declare type OverriddenDomProps_6 = "children" | "onError";
|
|
6373
7661
|
|
|
6374
7662
|
/** DOM attributes this component redefines. */
|
|
6375
|
-
declare type
|
|
7663
|
+
declare type OverriddenDomProps_7 = "children" | "onSubmit";
|
|
7664
|
+
|
|
7665
|
+
/** DOM attributes the composer redefines. */
|
|
7666
|
+
declare type OverriddenDomProps_8 = "onSubmit" | "value" | "defaultValue" | "rows";
|
|
6376
7667
|
|
|
6377
7668
|
/** DOM attributes this component redefines. */
|
|
6378
|
-
declare type OverriddenDomProps_9 = "children" | "onChange";
|
|
7669
|
+
declare type OverriddenDomProps_9 = "children" | "onChange" | "defaultValue";
|
|
6379
7670
|
|
|
6380
7671
|
/**
|
|
6381
7672
|
* Page wrapper with header + (optional) toolbar + content + footer. Pairs
|
|
@@ -6451,6 +7742,221 @@ export declare function parseMarkdown(source: string): MarkdownBlock[];
|
|
|
6451
7742
|
*/
|
|
6452
7743
|
export declare function parseResponse<TSchema extends z.ZodTypeAny>(schema: TSchema, raw: unknown, context: string): z.infer<TSchema>;
|
|
6453
7744
|
|
|
7745
|
+
/** Per-call knobs for {@link PasskeyClient.authenticate}. */
|
|
7746
|
+
export declare interface PasskeyAuthenticateInit extends PasskeyRegisterInit {
|
|
7747
|
+
/**
|
|
7748
|
+
* `"conditional"` is the autofill flow: no modal, the browser offers passkeys
|
|
7749
|
+
* inside a field marked `autocomplete="webauthn"`. Requires a `signal`, and
|
|
7750
|
+
* only one conditional request may be live per page.
|
|
7751
|
+
*/
|
|
7752
|
+
mediation?: PasskeyMediation;
|
|
7753
|
+
}
|
|
7754
|
+
|
|
7755
|
+
/** What the client sends to the backend to finish authentication. */
|
|
7756
|
+
export declare interface PasskeyAuthenticationJSON {
|
|
7757
|
+
/** Base64url credential id — the server looks up the stored public key by it. */
|
|
7758
|
+
id: string;
|
|
7759
|
+
/** Same bytes as `id`. */
|
|
7760
|
+
rawId: string;
|
|
7761
|
+
type: "public-key";
|
|
7762
|
+
/** `"platform"` or `"cross-platform"`. */
|
|
7763
|
+
authenticatorAttachment: string | null;
|
|
7764
|
+
response: {
|
|
7765
|
+
/** Base64url client data. */
|
|
7766
|
+
clientDataJSON: string;
|
|
7767
|
+
/** Base64url authenticator data, carrying the signature counter. */
|
|
7768
|
+
authenticatorData: string;
|
|
7769
|
+
/** Base64url signature over `authenticatorData || sha256(clientDataJSON)`. */
|
|
7770
|
+
signature: string;
|
|
7771
|
+
/** Base64url user handle — present on discoverable credentials, else null. */
|
|
7772
|
+
userHandle: string | null;
|
|
7773
|
+
};
|
|
7774
|
+
/** Extension outputs. */
|
|
7775
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
7776
|
+
}
|
|
7777
|
+
|
|
7778
|
+
/** Capability probes shared by both passkey hooks. */
|
|
7779
|
+
export declare interface PasskeyCapabilities {
|
|
7780
|
+
/** WebAuthn exists in this browser. Known synchronously. */
|
|
7781
|
+
supported: boolean;
|
|
7782
|
+
/**
|
|
7783
|
+
* This device has a built-in authenticator. `null` until the async probe
|
|
7784
|
+
* settles — render nothing passkey-related while it is `null`.
|
|
7785
|
+
*/
|
|
7786
|
+
platformAvailable: boolean | null;
|
|
7787
|
+
/** Autofill-driven sign-in is available. `null` until the probe settles. */
|
|
7788
|
+
conditionalAvailable: boolean | null;
|
|
7789
|
+
}
|
|
7790
|
+
|
|
7791
|
+
/** Which ceremony was running, so the message can name it. */
|
|
7792
|
+
export declare type PasskeyCeremony = "register" | "authenticate";
|
|
7793
|
+
|
|
7794
|
+
/** Framework-free WebAuthn client. Build one with {@link createPasskeyClient}. */
|
|
7795
|
+
export declare interface PasskeyClient {
|
|
7796
|
+
/** Run the registration ceremony and return the JSON your backend verifies. */
|
|
7797
|
+
register(options: PasskeyCreationOptionsJSON, init?: PasskeyRegisterInit): Promise<PasskeyRegistrationJSON>;
|
|
7798
|
+
/** Run the authentication ceremony and return the JSON your backend verifies. */
|
|
7799
|
+
authenticate(options: PasskeyRequestOptionsJSON, init?: PasskeyAuthenticateInit): Promise<PasskeyAuthenticationJSON>;
|
|
7800
|
+
/**
|
|
7801
|
+
* Whether this client can run a ceremony at all — the WebAuthn API exists, or a
|
|
7802
|
+
* `credentials` container was injected.
|
|
7803
|
+
*/
|
|
7804
|
+
isSupported(): boolean;
|
|
7805
|
+
/** Whether this device has a built-in authenticator (Face ID, Hello, …). */
|
|
7806
|
+
isPlatformAuthenticatorAvailable(): Promise<boolean>;
|
|
7807
|
+
/** Whether autofill-driven (`"conditional"`) requests are available. */
|
|
7808
|
+
isConditionalMediationAvailable(): Promise<boolean>;
|
|
7809
|
+
}
|
|
7810
|
+
|
|
7811
|
+
/**
|
|
7812
|
+
* Server-issued registration options, in the base64url JSON shape every WebAuthn
|
|
7813
|
+
* backend speaks (`PublicKeyCredentialCreationOptionsJSON` in the spec).
|
|
7814
|
+
*
|
|
7815
|
+
* `challenge`, `user.id` and every `excludeCredentials[].id` are **base64url**
|
|
7816
|
+
* strings here and `ArrayBuffer`s in the DOM API. Converting them is the plumbing
|
|
7817
|
+
* this client owns.
|
|
7818
|
+
*/
|
|
7819
|
+
export declare interface PasskeyCreationOptionsJSON {
|
|
7820
|
+
/** Base64url server challenge. Single-use; the server must remember it. */
|
|
7821
|
+
challenge: string;
|
|
7822
|
+
/** Relying party. `id` defaults to the client's `rpId`, then to the origin. */
|
|
7823
|
+
rp: {
|
|
7824
|
+
name: string;
|
|
7825
|
+
id?: string;
|
|
7826
|
+
};
|
|
7827
|
+
/** The account. `id` is base64url of an opaque, stable user handle. */
|
|
7828
|
+
user: {
|
|
7829
|
+
id: string;
|
|
7830
|
+
name: string;
|
|
7831
|
+
displayName: string;
|
|
7832
|
+
};
|
|
7833
|
+
/** Allowed COSE algorithms. Defaults to {@link DEFAULT_PUB_KEY_CRED_PARAMS}. */
|
|
7834
|
+
pubKeyCredParams?: {
|
|
7835
|
+
type: "public-key";
|
|
7836
|
+
alg: number;
|
|
7837
|
+
}[];
|
|
7838
|
+
/** Ceremony timeout in ms. Defaults to the client's `timeoutMs`. */
|
|
7839
|
+
timeout?: number;
|
|
7840
|
+
/** Credentials this user already has, so the authenticator refuses a duplicate. */
|
|
7841
|
+
excludeCredentials?: {
|
|
7842
|
+
id: string;
|
|
7843
|
+
type: "public-key";
|
|
7844
|
+
transports?: string[];
|
|
7845
|
+
}[];
|
|
7846
|
+
/** Resident-key / user-verification / attachment requirements. */
|
|
7847
|
+
authenticatorSelection?: AuthenticatorSelectionCriteria;
|
|
7848
|
+
/** Attestation conveyance. Leave unset (`"none"`) unless you verify it. */
|
|
7849
|
+
attestation?: AttestationConveyancePreference;
|
|
7850
|
+
/** Client extension inputs (`credProps`, `largeBlob`, …). */
|
|
7851
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
7852
|
+
}
|
|
7853
|
+
|
|
7854
|
+
/**
|
|
7855
|
+
* A passkey failure carrying a stable {@link PasskeyErrorKind} plus an English
|
|
7856
|
+
* message safe to show a user.
|
|
7857
|
+
*
|
|
7858
|
+
* A class rather than the plain `{ kind, message }` object the media classifier
|
|
7859
|
+
* returns, because these surface by rejecting a promise: an `Error` subclass keeps
|
|
7860
|
+
* stack traces, `instanceof` checks and logging intact, and `kind` is what code
|
|
7861
|
+
* branches on.
|
|
7862
|
+
*/
|
|
7863
|
+
export declare class PasskeyError extends Error {
|
|
7864
|
+
/** Stable, branchable classification. */
|
|
7865
|
+
readonly kind: PasskeyErrorKind;
|
|
7866
|
+
/**
|
|
7867
|
+
* Build a classified passkey error.
|
|
7868
|
+
*
|
|
7869
|
+
* @param kind - The classification a UI branches on.
|
|
7870
|
+
* @param message - English, user-safe explanation.
|
|
7871
|
+
* @param cause - The original thrown value, when there was one.
|
|
7872
|
+
*/
|
|
7873
|
+
constructor(kind: PasskeyErrorKind, message: string, cause?: unknown);
|
|
7874
|
+
}
|
|
7875
|
+
|
|
7876
|
+
/**
|
|
7877
|
+
* Classified reason a passkey ceremony did not produce a credential.
|
|
7878
|
+
*
|
|
7879
|
+
* The kinds group the raw `DOMException.name` values the way a UI has to branch
|
|
7880
|
+
* on them, which is *not* how the spec groups them:
|
|
7881
|
+
*
|
|
7882
|
+
* - `"cancelled"` covers `NotAllowedError`, which the browser raises both when
|
|
7883
|
+
* the user dismissed the sheet and when the ceremony timed out. They are
|
|
7884
|
+
* indistinguishable **by design** — telling a site "the user has no credential
|
|
7885
|
+
* for you" would leak account existence — so a UI must treat them as one thing.
|
|
7886
|
+
* - `"already-registered"` (`InvalidStateError`) is not really a failure: this
|
|
7887
|
+
* device already holds a credential for this user. The correct reaction is
|
|
7888
|
+
* "you are already set up on this device", never a red error.
|
|
7889
|
+
* - `"rp-mismatch"` (`SecurityError`) is the single most common integration bug:
|
|
7890
|
+
* `rp.id` must equal the page's domain or a registrable parent of it.
|
|
7891
|
+
*/
|
|
7892
|
+
export declare type PasskeyErrorKind = "unsupported" | "insecure" | "cancelled" | "already-registered" | "not-supported" | "rp-mismatch" | "invalid-options" | "aborted" | "unknown";
|
|
7893
|
+
|
|
7894
|
+
/** How the browser should surface the authentication ceremony. */
|
|
7895
|
+
export declare type PasskeyMediation = "optional" | "conditional" | "required" | "silent";
|
|
7896
|
+
|
|
7897
|
+
/** Per-call knobs for {@link PasskeyClient.register}. */
|
|
7898
|
+
export declare interface PasskeyRegisterInit {
|
|
7899
|
+
/** Cancel the ceremony (closes the browser sheet). */
|
|
7900
|
+
signal?: AbortSignal;
|
|
7901
|
+
}
|
|
7902
|
+
|
|
7903
|
+
/** What the client sends to the backend to finish registration. */
|
|
7904
|
+
export declare interface PasskeyRegistrationJSON {
|
|
7905
|
+
/** Base64url credential id. */
|
|
7906
|
+
id: string;
|
|
7907
|
+
/** Same bytes as `id`; both are sent because servers differ on which they read. */
|
|
7908
|
+
rawId: string;
|
|
7909
|
+
type: "public-key";
|
|
7910
|
+
/** `"platform"` (this device) or `"cross-platform"` (a phone or key). */
|
|
7911
|
+
authenticatorAttachment: string | null;
|
|
7912
|
+
response: {
|
|
7913
|
+
/** Base64url client data — the server re-checks challenge, origin and type. */
|
|
7914
|
+
clientDataJSON: string;
|
|
7915
|
+
/** Base64url attestation object, holding the new public key. */
|
|
7916
|
+
attestationObject: string;
|
|
7917
|
+
/** Transports the authenticator advertises, when the browser exposes them. */
|
|
7918
|
+
transports?: string[];
|
|
7919
|
+
/** COSE algorithm of the new key, when the browser exposes it. */
|
|
7920
|
+
publicKeyAlgorithm?: number;
|
|
7921
|
+
/** Base64url SPKI public key, when the browser exposes it. */
|
|
7922
|
+
publicKey?: string;
|
|
7923
|
+
/** Base64url authenticator data, when the browser exposes it. */
|
|
7924
|
+
authenticatorData?: string;
|
|
7925
|
+
};
|
|
7926
|
+
/** Extension outputs — `credProps.rk` tells you whether it is discoverable. */
|
|
7927
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
7928
|
+
}
|
|
7929
|
+
|
|
7930
|
+
/** Server-issued authentication options, base64url JSON. */
|
|
7931
|
+
export declare interface PasskeyRequestOptionsJSON {
|
|
7932
|
+
/** Base64url server challenge. */
|
|
7933
|
+
challenge: string;
|
|
7934
|
+
/** Relying party id. Defaults to the client's `rpId`, then to the origin. */
|
|
7935
|
+
rpId?: string;
|
|
7936
|
+
/** Ceremony timeout in ms. Defaults to the client's `timeoutMs`. */
|
|
7937
|
+
timeout?: number;
|
|
7938
|
+
/** Restrict to these credentials. **Omit it** for usernameless / autofill flows. */
|
|
7939
|
+
allowCredentials?: {
|
|
7940
|
+
id: string;
|
|
7941
|
+
type: "public-key";
|
|
7942
|
+
transports?: string[];
|
|
7943
|
+
}[];
|
|
7944
|
+
/** Whether the authenticator must verify the user (biometric / PIN). */
|
|
7945
|
+
userVerification?: UserVerificationRequirement;
|
|
7946
|
+
/** Client extension inputs. */
|
|
7947
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
7948
|
+
}
|
|
7949
|
+
|
|
7950
|
+
/**
|
|
7951
|
+
* Where a passkey ceremony is.
|
|
7952
|
+
*
|
|
7953
|
+
* `"prompting"` and `"verifying"` are split because they need different copy:
|
|
7954
|
+
* while prompting, the browser sheet is up and the user must touch a sensor;
|
|
7955
|
+
* while verifying, your backend is checking the signature and the user should
|
|
7956
|
+
* just wait.
|
|
7957
|
+
*/
|
|
7958
|
+
export declare type PasskeyStatus = "idle" | "prompting" | "verifying" | "success" | "error";
|
|
7959
|
+
|
|
6454
7960
|
/**
|
|
6455
7961
|
* Password field with toggle-visibility button and optional strength meter.
|
|
6456
7962
|
*
|
|
@@ -6494,6 +8000,13 @@ export { Path }
|
|
|
6494
8000
|
*/
|
|
6495
8001
|
export declare function pathLengthKm(points: readonly Coordinate[]): number;
|
|
6496
8002
|
|
|
8003
|
+
/** Raw PCM ready to be wrapped in a RIFF container. */
|
|
8004
|
+
export declare interface PcmAudio {
|
|
8005
|
+
/** One `Float32Array` per channel, samples in −1…1. */
|
|
8006
|
+
channels: readonly Float32Array[];
|
|
8007
|
+
sampleRate: number;
|
|
8008
|
+
}
|
|
8009
|
+
|
|
6497
8010
|
/**
|
|
6498
8011
|
* Extract a permission list from a JWT.
|
|
6499
8012
|
*
|
|
@@ -6550,6 +8063,38 @@ export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "val
|
|
|
6550
8063
|
*/
|
|
6551
8064
|
export declare function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
|
|
6552
8065
|
|
|
8066
|
+
/**
|
|
8067
|
+
* First container in `preferred` the browser can actually produce, or `null`.
|
|
8068
|
+
*
|
|
8069
|
+
* **There is no MP3 or WAV here, and that is not an omission.** `MediaRecorder`
|
|
8070
|
+
* emits Opus (in WebM or Ogg) on Chromium and Firefox and AAC (in MP4) on Safari —
|
|
8071
|
+
* no engine implements an MP3 or WAV encoder for it. If a backend needs WAV,
|
|
8072
|
+
* {@link blobToWav} converts one client-side with no dependency; if it needs MP3,
|
|
8073
|
+
* transcode on the server. Shipping an MP3 encoder would mean a WASM build of the
|
|
8074
|
+
* order of 150 KB in every consumer's bundle to serve one format, which is the
|
|
8075
|
+
* trade this SDK does not make.
|
|
8076
|
+
*
|
|
8077
|
+
* @param preferred - Candidates, best first. Defaults to {@link AUDIO_MIME_CANDIDATES}.
|
|
8078
|
+
* @returns A supported MIME type, or `null` when none is.
|
|
8079
|
+
*/
|
|
8080
|
+
export declare function pickAudioMimeType(preferred?: readonly string[]): string | null;
|
|
8081
|
+
|
|
8082
|
+
/**
|
|
8083
|
+
* First container in `preferred` the browser can actually produce, or `null`.
|
|
8084
|
+
*
|
|
8085
|
+
* @param preferred - Candidates, best first.
|
|
8086
|
+
* @returns A supported MIME type, or `null` when none is.
|
|
8087
|
+
*/
|
|
8088
|
+
export declare function pickRecordingMimeType(preferred: readonly string[]): string | null;
|
|
8089
|
+
|
|
8090
|
+
/**
|
|
8091
|
+
* First video container in `preferred` the browser can actually produce, or `null`.
|
|
8092
|
+
*
|
|
8093
|
+
* @param preferred - Candidates, best first. Defaults to {@link VIDEO_MIME_CANDIDATES}.
|
|
8094
|
+
* @returns A supported MIME type, or `null` when none is.
|
|
8095
|
+
*/
|
|
8096
|
+
export declare function pickVideoMimeType(preferred?: readonly string[]): string | null;
|
|
8097
|
+
|
|
6553
8098
|
/**
|
|
6554
8099
|
* One-time-password style input — N independent cells, paste support, auto-
|
|
6555
8100
|
* advance on input, backspace flows back, arrow keys navigate.
|
|
@@ -6617,7 +8162,7 @@ export declare interface PlacedEvent {
|
|
|
6617
8162
|
}
|
|
6618
8163
|
|
|
6619
8164
|
/**
|
|
6620
|
-
* Convenience wrapper around a shared {@link
|
|
8165
|
+
* Convenience wrapper around a shared {@link AudioPlayerHandle}. Use this for
|
|
6621
8166
|
* one-off notification sounds. For more complex flows (e.g. several
|
|
6622
8167
|
* simultaneous channels), build a dedicated player with {@link createAudioPlayer}.
|
|
6623
8168
|
*/
|
|
@@ -6632,6 +8177,14 @@ export declare interface PlayAudioOptions {
|
|
|
6632
8177
|
autoplay?: boolean;
|
|
6633
8178
|
/** Stop the previous clip managed by this player. Default: false. */
|
|
6634
8179
|
stopPrevious?: boolean;
|
|
8180
|
+
/**
|
|
8181
|
+
* Output device to play on, from `useMediaDevices().audioOutputs`.
|
|
8182
|
+
*
|
|
8183
|
+
* Ignored where the browser has no output routing (everything but Chromium) —
|
|
8184
|
+
* the clip still plays, on the system default. Useful for a chime that must land
|
|
8185
|
+
* on a headset while the call audio stays on the speakers.
|
|
8186
|
+
*/
|
|
8187
|
+
sinkId?: string;
|
|
6635
8188
|
/** Fired when playback ends naturally. */
|
|
6636
8189
|
onEnded?: () => void;
|
|
6637
8190
|
/** Fired on playback error. */
|
|
@@ -6733,6 +8286,23 @@ export declare interface PostHogLike {
|
|
|
6733
8286
|
reset?: () => void;
|
|
6734
8287
|
}
|
|
6735
8288
|
|
|
8289
|
+
/** A model whose cached size should appear in the report. */
|
|
8290
|
+
export declare interface ProfiledModel {
|
|
8291
|
+
/** Label for the report row, e.g. `"detector"`. */
|
|
8292
|
+
name: string;
|
|
8293
|
+
/** Cache Storage bucket holding the response, e.g. `"app-models"`. */
|
|
8294
|
+
cacheName: string;
|
|
8295
|
+
/** Request URL the model was cached under. */
|
|
8296
|
+
url: string;
|
|
8297
|
+
}
|
|
8298
|
+
|
|
8299
|
+
/** A model's size as found in the cache. */
|
|
8300
|
+
export declare interface ProfiledModelSize {
|
|
8301
|
+
name: string;
|
|
8302
|
+
/** Size in bytes, or `null` when uncached or the size is unreported. */
|
|
8303
|
+
bytes: number | null;
|
|
8304
|
+
}
|
|
8305
|
+
|
|
6736
8306
|
/**
|
|
6737
8307
|
* Linear progress bar with determinate / indeterminate modes.
|
|
6738
8308
|
*
|
|
@@ -7050,6 +8620,22 @@ export declare interface RatingStarsProps {
|
|
|
7050
8620
|
*/
|
|
7051
8621
|
export declare function readableForeground(background: string, light?: string, dark?: string): string;
|
|
7052
8622
|
|
|
8623
|
+
/**
|
|
8624
|
+
* Sample the device capabilities the browser reports.
|
|
8625
|
+
*
|
|
8626
|
+
* Safe to call during SSR: without a `navigator` every field is `null`.
|
|
8627
|
+
*
|
|
8628
|
+
* @returns The profile, with `null` for anything this platform withholds.
|
|
8629
|
+
*
|
|
8630
|
+
* @example
|
|
8631
|
+
* ```typescript
|
|
8632
|
+
* const device = readDeviceProfile();
|
|
8633
|
+
* console.log(device.hardwareConcurrency); // 8
|
|
8634
|
+
* console.log(device.deviceMemoryGb); // 8 on Chromium, null on Safari
|
|
8635
|
+
* ```
|
|
8636
|
+
*/
|
|
8637
|
+
export declare function readDeviceProfile(): DeviceProfile;
|
|
8638
|
+
|
|
7053
8639
|
/**
|
|
7054
8640
|
* Read a token's computed value from an element (default: `<html>`).
|
|
7055
8641
|
*
|
|
@@ -7320,6 +8906,131 @@ export declare type ResponsiveValue<T> = T | {
|
|
|
7320
8906
|
desktop?: T;
|
|
7321
8907
|
};
|
|
7322
8908
|
|
|
8909
|
+
/** A resumable upload in progress. Build one with {@link createResumableUpload}. */
|
|
8910
|
+
export declare interface ResumableUpload {
|
|
8911
|
+
/**
|
|
8912
|
+
* Create (or re-attach to) the upload and push chunks until it is complete.
|
|
8913
|
+
*
|
|
8914
|
+
* Resolves `null` when the run stopped because of `pause()` or `abort()` —
|
|
8915
|
+
* neither is a failure. Rejects with a `TempestApiError` when the server
|
|
8916
|
+
* refused and the retries ran out.
|
|
8917
|
+
*/
|
|
8918
|
+
start(): Promise<ResumableUploadResult | null>;
|
|
8919
|
+
/** Stop after the in-flight chunk is dropped, keeping the resume point. */
|
|
8920
|
+
pause(): void;
|
|
8921
|
+
/** Continue from the server's offset. Same resolution contract as `start`. */
|
|
8922
|
+
resume(): Promise<ResumableUploadResult | null>;
|
|
8923
|
+
/**
|
|
8924
|
+
* Stop for good.
|
|
8925
|
+
*
|
|
8926
|
+
* @param options - `discard: true` also sends `DELETE` (tus termination) and
|
|
8927
|
+
* forgets the persisted record, so the next `start()` uploads from zero.
|
|
8928
|
+
*/
|
|
8929
|
+
abort(options?: {
|
|
8930
|
+
discard?: boolean;
|
|
8931
|
+
}): Promise<void>;
|
|
8932
|
+
/** Current state. */
|
|
8933
|
+
readonly state: ResumableUploadState;
|
|
8934
|
+
/** Bytes the server has confirmed. */
|
|
8935
|
+
readonly offset: number;
|
|
8936
|
+
/** The upload URL, once creation succeeded. */
|
|
8937
|
+
readonly url: string | null;
|
|
8938
|
+
/** The resume key in use. */
|
|
8939
|
+
readonly key: string;
|
|
8940
|
+
}
|
|
8941
|
+
|
|
8942
|
+
/** Options for {@link createResumableUpload}. */
|
|
8943
|
+
export declare interface ResumableUploadOptions {
|
|
8944
|
+
/** tus creation endpoint, e.g. `"/api/uploads"`. */
|
|
8945
|
+
endpoint: string;
|
|
8946
|
+
/** The bytes to upload. A `File` also supplies the default resume key. */
|
|
8947
|
+
file: Blob | File;
|
|
8948
|
+
/** Bytes per `PATCH`. Default {@link DEFAULT_CHUNK_SIZE}. */
|
|
8949
|
+
chunkSize?: number;
|
|
8950
|
+
/** Sent as `Upload-Metadata` (base64-encoded values), e.g. `{ filename }`. */
|
|
8951
|
+
metadata?: Record<string, string>;
|
|
8952
|
+
/** Extra headers on every request. */
|
|
8953
|
+
headers?: Record<string, string>;
|
|
8954
|
+
/** Returns the current bearer token, read before each request. */
|
|
8955
|
+
getToken?: () => string | null | undefined;
|
|
8956
|
+
/** Send cookies. Default `false`. */
|
|
8957
|
+
withCredentials?: boolean;
|
|
8958
|
+
/**
|
|
8959
|
+
* Resume key. Defaults to a fingerprint of endpoint + file name/size/mtime, so
|
|
8960
|
+
* picking the same file after a reload resumes instead of restarting.
|
|
8961
|
+
*/
|
|
8962
|
+
key?: string;
|
|
8963
|
+
/**
|
|
8964
|
+
* Where to persist resume state. Defaults to `localStorage`. Pass `null` to
|
|
8965
|
+
* disable persistence — resume then only survives a network blip, not a reload.
|
|
8966
|
+
*/
|
|
8967
|
+
storage?: ResumableUploadStorage | null;
|
|
8968
|
+
/** Backoff for a failed chunk. Forwarded to `retry`. Default 5 attempts. */
|
|
8969
|
+
retry?: RetryOptions;
|
|
8970
|
+
/** Called on every upload-progress tick and after every confirmed chunk. */
|
|
8971
|
+
onProgress?: (progress: ResumableUploadProgress) => void;
|
|
8972
|
+
/** Called whenever {@link ResumableUpload.state} changes. */
|
|
8973
|
+
onStateChange?: (state: ResumableUploadState) => void;
|
|
8974
|
+
}
|
|
8975
|
+
|
|
8976
|
+
/** Byte-level progress for a resumable upload. */
|
|
8977
|
+
export declare interface ResumableUploadProgress {
|
|
8978
|
+
/** Bytes the server holds, including anything a resume skipped. */
|
|
8979
|
+
loaded: number;
|
|
8980
|
+
/** Total size of the file. */
|
|
8981
|
+
total: number;
|
|
8982
|
+
/** `loaded / total`, between 0 and 1. */
|
|
8983
|
+
fraction: number;
|
|
8984
|
+
/** Bytes already on the server when this run started. `0` on a fresh upload. */
|
|
8985
|
+
resumedFrom: number;
|
|
8986
|
+
}
|
|
8987
|
+
|
|
8988
|
+
/** What has to survive a page reload for a resume to be possible. */
|
|
8989
|
+
export declare interface ResumableUploadRecord {
|
|
8990
|
+
/** Upload URL the creation POST returned, absolute. */
|
|
8991
|
+
url: string;
|
|
8992
|
+
/** Last offset the server confirmed. */
|
|
8993
|
+
offset: number;
|
|
8994
|
+
/** File size, so a different file under the same key is not resumed into. */
|
|
8995
|
+
size: number;
|
|
8996
|
+
/** Idempotency key of the creation request, reused if creation is retried. */
|
|
8997
|
+
idempotencyKey: string;
|
|
8998
|
+
/** Epoch ms of the last write, so an app can sweep stale records. */
|
|
8999
|
+
updatedAt: number;
|
|
9000
|
+
}
|
|
9001
|
+
|
|
9002
|
+
/** What a finished upload resolves with. */
|
|
9003
|
+
export declare interface ResumableUploadResult {
|
|
9004
|
+
/** The tus upload URL — hand this to your API to link the stored file. */
|
|
9005
|
+
url: string;
|
|
9006
|
+
/** Total bytes uploaded. */
|
|
9007
|
+
size: number;
|
|
9008
|
+
}
|
|
9009
|
+
|
|
9010
|
+
/**
|
|
9011
|
+
* Where a resumable upload is.
|
|
9012
|
+
*
|
|
9013
|
+
* `"paused"` and `"aborted"` are both "not running", but only `"paused"` keeps the
|
|
9014
|
+
* persisted offset — `abort({ discard: true })` throws it away.
|
|
9015
|
+
*/
|
|
9016
|
+
export declare type ResumableUploadState = "idle" | "creating" | "uploading" | "paused" | "done" | "error" | "aborted";
|
|
9017
|
+
|
|
9018
|
+
/**
|
|
9019
|
+
* Persistence for resume state. Sync or async — both are awaited.
|
|
9020
|
+
*
|
|
9021
|
+
* Implement it over anything: the default is `localStorage`, and
|
|
9022
|
+
* `createOfflineStore` from `@/offline` slots in when you already have a Dexie
|
|
9023
|
+
* database open.
|
|
9024
|
+
*/
|
|
9025
|
+
export declare interface ResumableUploadStorage {
|
|
9026
|
+
/** Read the record for `key`, or `null`. */
|
|
9027
|
+
get(key: string): Promise<ResumableUploadRecord | null> | ResumableUploadRecord | null;
|
|
9028
|
+
/** Write the record for `key`. */
|
|
9029
|
+
set(key: string, record: ResumableUploadRecord): Promise<void> | void;
|
|
9030
|
+
/** Forget the record for `key`. */
|
|
9031
|
+
delete(key: string): Promise<void> | void;
|
|
9032
|
+
}
|
|
9033
|
+
|
|
7323
9034
|
/**
|
|
7324
9035
|
* Run `factory()` with exponential backoff. Each attempt awaits an
|
|
7325
9036
|
* increasing delay capped at `maxDelay`. Throws the last error if every
|
|
@@ -7594,6 +9305,9 @@ export declare interface SchedulerProps extends Omit<HTMLAttributes<HTMLDivEleme
|
|
|
7594
9305
|
now?: Date;
|
|
7595
9306
|
}
|
|
7596
9307
|
|
|
9308
|
+
/** Lifecycle of a screen share. */
|
|
9309
|
+
export declare type ScreenCaptureStatus = "idle" | "requesting" | "sharing" | "error";
|
|
9310
|
+
|
|
7597
9311
|
/**
|
|
7598
9312
|
* A styled scroll container that overflows on the chosen axis and renders a
|
|
7599
9313
|
* thin custom scrollbar (WebKit) while staying fully functional in browsers
|
|
@@ -7765,6 +9479,29 @@ export declare interface SequentialScaleOptions {
|
|
|
7765
9479
|
ordinal?: boolean;
|
|
7766
9480
|
}
|
|
7767
9481
|
|
|
9482
|
+
/**
|
|
9483
|
+
* Send an element's audio to a specific output device.
|
|
9484
|
+
*
|
|
9485
|
+
* The `sinkId` comes from `useMediaDevices().audioOutputs` — and, like every device
|
|
9486
|
+
* label, that list is anonymous until a capture permission has been granted, so an
|
|
9487
|
+
* output picker realistically only works after the microphone has been allowed once.
|
|
9488
|
+
*
|
|
9489
|
+
* Returns `false` instead of throwing when the browser has no `setSinkId`, because
|
|
9490
|
+
* "this engine cannot route audio" is the common case and not an error the caller can
|
|
9491
|
+
* act on: the sound still plays, on the system default device. A rejected
|
|
9492
|
+
* `setSinkId` — a device that was unplugged between enumeration and playback is the
|
|
9493
|
+
* usual cause — also resolves `false`, and playback continues on the default.
|
|
9494
|
+
*
|
|
9495
|
+
* @param element - The `<audio>` or `<video>` element to route.
|
|
9496
|
+
* @param sinkId - Device id, or `""` for the system default.
|
|
9497
|
+
* @returns `true` when the route was applied.
|
|
9498
|
+
*
|
|
9499
|
+
* @example
|
|
9500
|
+
* const ok = await setAudioOutput(audioRef.current, selectedSpeakerId);
|
|
9501
|
+
* if (!ok) toast("Este navegador não permite escolher a saída de som.");
|
|
9502
|
+
*/
|
|
9503
|
+
export declare function setAudioOutput(element: HTMLMediaElement | null, sinkId: string): Promise<boolean>;
|
|
9504
|
+
|
|
7768
9505
|
/**
|
|
7769
9506
|
* Wrap the Web Share API with a uniform result object. Falls through to
|
|
7770
9507
|
* `unsupported: true` when the browser lacks `navigator.share`, leaving the
|
|
@@ -8124,6 +9861,69 @@ export declare interface SparklineProps extends Omit<HTMLAttributes<HTMLSpanElem
|
|
|
8124
9861
|
|
|
8125
9862
|
export declare type SparklineVariant = "line" | "area" | "bar";
|
|
8126
9863
|
|
|
9864
|
+
/** One reading of what was heard. */
|
|
9865
|
+
export declare interface SpeechAlternativeLike {
|
|
9866
|
+
transcript: string;
|
|
9867
|
+
confidence?: number;
|
|
9868
|
+
}
|
|
9869
|
+
|
|
9870
|
+
/** A classified speech error with a human-readable, English message. */
|
|
9871
|
+
export declare interface SpeechError {
|
|
9872
|
+
kind: SpeechErrorKind;
|
|
9873
|
+
message: string;
|
|
9874
|
+
}
|
|
9875
|
+
|
|
9876
|
+
/** Classified reason recognition stopped or never started. */
|
|
9877
|
+
export declare type SpeechErrorKind = "unsupported" | "not-allowed" | "no-speech" | "audio-capture" | "network" | "aborted" | "language-not-supported" | "unknown";
|
|
9878
|
+
|
|
9879
|
+
/** The `error` event, reduced to what this hook reads. */
|
|
9880
|
+
export declare interface SpeechRecognitionErrorEventLike {
|
|
9881
|
+
error: string;
|
|
9882
|
+
message?: string;
|
|
9883
|
+
}
|
|
9884
|
+
|
|
9885
|
+
/** The `result` event, reduced to what this hook reads. */
|
|
9886
|
+
export declare interface SpeechRecognitionEventLike {
|
|
9887
|
+
/** Index of the first result that changed — everything before it is settled. */
|
|
9888
|
+
resultIndex: number;
|
|
9889
|
+
results: SpeechResultListLike;
|
|
9890
|
+
}
|
|
9891
|
+
|
|
9892
|
+
/**
|
|
9893
|
+
* The slice of the Web Speech `SpeechRecognition` object this SDK uses.
|
|
9894
|
+
*
|
|
9895
|
+
* Declared here rather than imported: TypeScript's DOM lib ships the *event* types but
|
|
9896
|
+
* not the constructor, because the API is still prefixed in Chromium and absent in
|
|
9897
|
+
* Firefox. Exported so a test — or a consumer wrapping a different engine — can hand in
|
|
9898
|
+
* something else.
|
|
9899
|
+
*/
|
|
9900
|
+
export declare interface SpeechRecognitionLike {
|
|
9901
|
+
lang: string;
|
|
9902
|
+
continuous: boolean;
|
|
9903
|
+
interimResults: boolean;
|
|
9904
|
+
maxAlternatives: number;
|
|
9905
|
+
start: () => void;
|
|
9906
|
+
stop: () => void;
|
|
9907
|
+
abort: () => void;
|
|
9908
|
+
onresult: ((event: SpeechRecognitionEventLike) => void) | null;
|
|
9909
|
+
onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;
|
|
9910
|
+
onend: (() => void) | null;
|
|
9911
|
+
onstart: (() => void) | null;
|
|
9912
|
+
}
|
|
9913
|
+
|
|
9914
|
+
/** One recognised phrase, settled (`isFinal`) or still being revised. */
|
|
9915
|
+
export declare interface SpeechResultLike {
|
|
9916
|
+
isFinal: boolean;
|
|
9917
|
+
length: number;
|
|
9918
|
+
[index: number]: SpeechAlternativeLike | undefined;
|
|
9919
|
+
}
|
|
9920
|
+
|
|
9921
|
+
/** The growing list of phrases in a session. */
|
|
9922
|
+
export declare interface SpeechResultListLike {
|
|
9923
|
+
length: number;
|
|
9924
|
+
[index: number]: SpeechResultLike | undefined;
|
|
9925
|
+
}
|
|
9926
|
+
|
|
8127
9927
|
/**
|
|
8128
9928
|
* Loading spinner with preset sizes (xs..xl). Provide `label` for screen
|
|
8129
9929
|
* readers, `caption` for a visible message, and `overlay` to center it inside a
|
|
@@ -9235,7 +11035,7 @@ export declare interface TransferItem {
|
|
|
9235
11035
|
data?: Record<string, unknown>;
|
|
9236
11036
|
}
|
|
9237
11037
|
|
|
9238
|
-
export declare interface TransferProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
11038
|
+
export declare interface TransferProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps_9> {
|
|
9239
11039
|
/** The whole catalogue. Both panes are derived from it. */
|
|
9240
11040
|
items: readonly TransferItem[];
|
|
9241
11041
|
/** Ids on the target side. Controlled. */
|
|
@@ -9393,6 +11193,9 @@ export declare interface TruncateTextProps extends HTMLAttributes<HTMLDivElement
|
|
|
9393
11193
|
*/
|
|
9394
11194
|
export declare function turnTime(timestamp: number, locale?: "pt-BR" | "en"): string;
|
|
9395
11195
|
|
|
11196
|
+
/** The tus protocol version this client speaks. */
|
|
11197
|
+
export declare const TUS_VERSION = "1.0.0";
|
|
11198
|
+
|
|
9396
11199
|
/** Sentence for the typing indicator, or `null` when nobody is typing. */
|
|
9397
11200
|
export declare function typingLabel(names: readonly string[], locale?: "pt-BR" | "en"): string | null;
|
|
9398
11201
|
|
|
@@ -9470,6 +11273,20 @@ export declare interface UpdateVariables {
|
|
|
9470
11273
|
data: unknown;
|
|
9471
11274
|
}
|
|
9472
11275
|
|
|
11276
|
+
/**
|
|
11277
|
+
* A stable-enough identity for a file, used as the default resume key.
|
|
11278
|
+
*
|
|
11279
|
+
* Name + size + last-modified is what the tus reference clients fingerprint on:
|
|
11280
|
+
* it is cheap (hashing the bytes of a 400 MB recording is not) and it changes
|
|
11281
|
+
* whenever the file does, which is the property that matters — resuming into the
|
|
11282
|
+
* wrong file would corrupt it silently.
|
|
11283
|
+
*
|
|
11284
|
+
* @param endpoint - Creation endpoint, so the same file to two servers is two uploads.
|
|
11285
|
+
* @param file - The blob or file being uploaded.
|
|
11286
|
+
* @returns A key safe to use in `localStorage`.
|
|
11287
|
+
*/
|
|
11288
|
+
export declare function uploadFingerprint(endpoint: string, file: Blob | File): string;
|
|
11289
|
+
|
|
9473
11290
|
export declare interface UploadProgressEvent {
|
|
9474
11291
|
/** Bytes already uploaded. */
|
|
9475
11292
|
loaded: number;
|
|
@@ -9561,6 +11378,38 @@ export declare function urlBase64ToUint8Array(base64String: string): Uint8Array<
|
|
|
9561
11378
|
*/
|
|
9562
11379
|
export declare function useAccessControl(): AccessControl | null;
|
|
9563
11380
|
|
|
11381
|
+
/**
|
|
11382
|
+
* Announce transient messages to screen readers through one shared live region
|
|
11383
|
+
* pair.
|
|
11384
|
+
*
|
|
11385
|
+
* Reach for this when something happened that a sighted user can see and a screen
|
|
11386
|
+
* reader user cannot: a filter narrowed a list, a row saved, a copy succeeded, an
|
|
11387
|
+
* upload failed. It is **not** for content that is already on screen inside a
|
|
11388
|
+
* region with a role — a status pill, a toast that renders as `role="status"`,
|
|
11389
|
+
* a form error tied to its input — announcing those again reads them twice.
|
|
11390
|
+
*
|
|
11391
|
+
* !!! warning "Never wrap streaming text in a live region"
|
|
11392
|
+
* A live region over text that grows token by token makes the reader start the
|
|
11393
|
+
* whole answer again on every token. Announce the **edges** instead — "gerando
|
|
11394
|
+
* resposta" and "resposta concluída" — and leave the transcript in a plain
|
|
11395
|
+
* `role="log"` the user reads at their own pace. `AIChat` does exactly that.
|
|
11396
|
+
*
|
|
11397
|
+
* Mounting the hook creates the regions even before the first message. That is not
|
|
11398
|
+
* tidiness: a live region inserted into the DOM in the same frame as its first
|
|
11399
|
+
* content routinely loses that announcement, because the assistive technology has
|
|
11400
|
+
* to have registered the region before it can notice a change inside it.
|
|
11401
|
+
*
|
|
11402
|
+
* @returns A stable `announce(message, politeness?)` function.
|
|
11403
|
+
*
|
|
11404
|
+
* @example
|
|
11405
|
+
* const announce = useAnnounce();
|
|
11406
|
+
*
|
|
11407
|
+
* function onFilter(rows: Row[]) {
|
|
11408
|
+
* announce(`${rows.length} resultados`);
|
|
11409
|
+
* }
|
|
11410
|
+
*/
|
|
11411
|
+
export declare function useAnnounce(): (message: string, politeness?: AnnouncePoliteness) => void;
|
|
11412
|
+
|
|
9564
11413
|
/**
|
|
9565
11414
|
* Run an async function and track its `idle/pending/success/error` state.
|
|
9566
11415
|
*
|
|
@@ -9596,11 +11445,73 @@ export declare interface UseAsyncResult<T> {
|
|
|
9596
11445
|
* fine and the value is non-null from the first render.
|
|
9597
11446
|
*
|
|
9598
11447
|
* Hook-managed audio player. Each component instance gets its own
|
|
9599
|
-
* {@link
|
|
11448
|
+
* {@link AudioPlayerHandle}, so unmounting cleanly stops playback. Useful for
|
|
9600
11449
|
* notification chimes, UI feedback sounds, and per-component soundtracks.
|
|
9601
11450
|
*/
|
|
9602
11451
|
export declare function useAudio(): UseAudioResult;
|
|
9603
11452
|
|
|
11453
|
+
/**
|
|
11454
|
+
* Record the given stream, with a clock, a level meter and a state machine.
|
|
11455
|
+
*
|
|
11456
|
+
* Pass the stream from {@link useMicrophone}; the hook stays `ready: false` until
|
|
11457
|
+
* there is one, so a page can render the whole recorder UI before permission is
|
|
11458
|
+
* granted and simply have it disabled.
|
|
11459
|
+
*
|
|
11460
|
+
* The clock and the level are published on an interval (`tickMs`, default 100 ms)
|
|
11461
|
+
* rather than per animation frame. A hook that set state 60 times a second would
|
|
11462
|
+
* re-render everything the recorder is inside; 10 Hz is smooth enough for a timer and
|
|
11463
|
+
* a meter, and the underlying `createLevelMeter` is still available for anyone who
|
|
11464
|
+
* wants a frame-accurate bar written straight to the DOM.
|
|
11465
|
+
*
|
|
11466
|
+
* @param stream - The stream to record, or `null` while permission is pending.
|
|
11467
|
+
* @param options - See {@link UseAudioRecorderOptions}.
|
|
11468
|
+
*
|
|
11469
|
+
* @example
|
|
11470
|
+
* const mic = useMicrophone();
|
|
11471
|
+
* const rec = useAudioRecorder(mic.stream, { maxDurationMs: 120_000 });
|
|
11472
|
+
* <button disabled={!rec.ready} onClick={rec.start}>Gravar</button>
|
|
11473
|
+
*/
|
|
11474
|
+
export declare function useAudioRecorder(stream: MediaStream | null, options?: UseAudioRecorderOptions): UseAudioRecorderResult;
|
|
11475
|
+
|
|
11476
|
+
/** Options for {@link useAudioRecorder}. */
|
|
11477
|
+
export declare interface UseAudioRecorderOptions extends AudioRecorderOptions {
|
|
11478
|
+
/**
|
|
11479
|
+
* Stop automatically after this many milliseconds.
|
|
11480
|
+
*
|
|
11481
|
+
* Worth setting on anything user-facing: a recording left running by accident is
|
|
11482
|
+
* a memory buffer that grows until the tab dies.
|
|
11483
|
+
*/
|
|
11484
|
+
maxDurationMs?: number;
|
|
11485
|
+
/** Called once the recording is assembled, whether by `stop()` or `maxDurationMs`. */
|
|
11486
|
+
onRecorded?: (recording: AudioRecording) => void;
|
|
11487
|
+
/** How often the clock and the level are published, in ms. Default 100. */
|
|
11488
|
+
tickMs?: number;
|
|
11489
|
+
/** Skip the level meter — it costs an `AudioContext`. Default `false`. */
|
|
11490
|
+
disableLevelMeter?: boolean;
|
|
11491
|
+
}
|
|
11492
|
+
|
|
11493
|
+
/** Value returned by {@link useAudioRecorder}. */
|
|
11494
|
+
export declare interface UseAudioRecorderResult {
|
|
11495
|
+
status: AudioRecorderStatus;
|
|
11496
|
+
/** Recorded length so far, excluding paused time. */
|
|
11497
|
+
durationMs: number;
|
|
11498
|
+
/** Loudness 0–1, or `0` when the meter is off or nothing is recording. */
|
|
11499
|
+
level: number;
|
|
11500
|
+
/** The finished recording, or `null` before the first `stop()`. */
|
|
11501
|
+
recording: AudioRecording | null;
|
|
11502
|
+
/** Recorder-level error (encoder failure, device pulled mid-recording). */
|
|
11503
|
+
error: unknown;
|
|
11504
|
+
/** `false` when there is no stream yet, or the browser cannot record. */
|
|
11505
|
+
ready: boolean;
|
|
11506
|
+
start: () => void;
|
|
11507
|
+
pause: () => void;
|
|
11508
|
+
resume: () => void;
|
|
11509
|
+
/** Stop and resolve with the recording. Also published on `recording`. */
|
|
11510
|
+
stop: () => Promise<AudioRecording | null>;
|
|
11511
|
+
/** Stop and throw the audio away. */
|
|
11512
|
+
cancel: () => void;
|
|
11513
|
+
}
|
|
11514
|
+
|
|
9604
11515
|
export declare interface UseAudioResult {
|
|
9605
11516
|
/** Play `src` on the hook's private player. */
|
|
9606
11517
|
play: (src: string, options?: PlayAudioOptions) => Promise<void>;
|
|
@@ -9613,6 +11524,105 @@ export declare interface UseAudioResult {
|
|
|
9613
11524
|
unlocked: boolean;
|
|
9614
11525
|
}
|
|
9615
11526
|
|
|
11527
|
+
/**
|
|
11528
|
+
* Read barcodes and QR codes from the camera.
|
|
11529
|
+
*
|
|
11530
|
+
* The camera and its classified errors come from `useCameraStream`, so this hook is
|
|
11531
|
+
* only the decoding half: it drives a `BarcodeDetector` over the preview on an
|
|
11532
|
+
* interval, suppresses the same value repeating, and exposes the torch.
|
|
11533
|
+
*
|
|
11534
|
+
* **Mounting this opens the camera.** It inherits that from `useCameraStream`, which
|
|
11535
|
+
* acquires on mount — so mount it *after* the user asks to scan (a button that reveals
|
|
11536
|
+
* the scanner), never on a page that merely contains one. A permission prompt nobody
|
|
11537
|
+
* provoked is the most reliable way to earn a permanent block, after which
|
|
11538
|
+
* `getUserMedia` rejects without ever prompting again.
|
|
11539
|
+
*
|
|
11540
|
+
* `supported` deserves a branch in the UI, not an assertion: `BarcodeDetector` is
|
|
11541
|
+
* Chromium-only and missing on Windows/Linux desktop, Firefox and everything on iOS.
|
|
11542
|
+
* Inject a `detector` to cover those, or tell the user to type the code.
|
|
11543
|
+
*
|
|
11544
|
+
* @param options - See {@link UseBarcodeScannerOptions}.
|
|
11545
|
+
* @returns The camera plumbing plus the scan state.
|
|
11546
|
+
*
|
|
11547
|
+
* @example
|
|
11548
|
+
* const scanner = useBarcodeScanner({
|
|
11549
|
+
* formats: ["ean_13"],
|
|
11550
|
+
* onScan: ({ rawValue }) => addToCart(rawValue),
|
|
11551
|
+
* });
|
|
11552
|
+
* return <video ref={scanner.videoRef} muted playsInline />;
|
|
11553
|
+
*/
|
|
11554
|
+
export declare function useBarcodeScanner(options?: UseBarcodeScannerOptions): UseBarcodeScannerResult;
|
|
11555
|
+
|
|
11556
|
+
/** Options for {@link useBarcodeScanner}. */
|
|
11557
|
+
export declare interface UseBarcodeScannerOptions {
|
|
11558
|
+
/** Symbologies to look for. Defaults to {@link DEFAULT_BARCODE_FORMATS}. */
|
|
11559
|
+
formats?: readonly BarcodeFormat[];
|
|
11560
|
+
/** Called for every accepted read — that is, after repeat suppression. */
|
|
11561
|
+
onScan?: (result: BarcodeScanResult) => void;
|
|
11562
|
+
/**
|
|
11563
|
+
* How often a frame is examined, in ms. Default 200.
|
|
11564
|
+
*
|
|
11565
|
+
* Not `requestAnimationFrame`: decoding is 10–40 ms of main-thread work on a
|
|
11566
|
+
* phone, so running it per frame competes with the preview it is reading from and
|
|
11567
|
+
* makes the video stutter. Five looks per second is faster than a human can aim.
|
|
11568
|
+
*/
|
|
11569
|
+
intervalMs?: number;
|
|
11570
|
+
/**
|
|
11571
|
+
* Ignore the **same** value again for this long, in ms. Default 2500.
|
|
11572
|
+
*
|
|
11573
|
+
* A symbol stays in frame for as long as the user holds the camera there, so a
|
|
11574
|
+
* scanner without this fires the same code five times a second — which, wired to
|
|
11575
|
+
* "add item to cart", is a bug the user pays for. A *different* value is never
|
|
11576
|
+
* suppressed.
|
|
11577
|
+
*/
|
|
11578
|
+
repeatDelayMs?: number;
|
|
11579
|
+
/** Stop looking without releasing the camera — a confirmation sheet is open. */
|
|
11580
|
+
paused?: boolean;
|
|
11581
|
+
/**
|
|
11582
|
+
* A decoder to use instead of the native one.
|
|
11583
|
+
*
|
|
11584
|
+
* The way to support Safari and Firefox: hand in a polyfill and everything else
|
|
11585
|
+
* here works unchanged. See {@link isBarcodeDetectionSupported} for why the SDK
|
|
11586
|
+
* does not bundle one.
|
|
11587
|
+
*/
|
|
11588
|
+
detector?: BarcodeDetectorLike;
|
|
11589
|
+
/** Camera constraints, forwarded to `useCameraStream`. Defaults to the rear camera. */
|
|
11590
|
+
constraints?: MediaStreamConstraints;
|
|
11591
|
+
/**
|
|
11592
|
+
* A frame the engine refused to decode.
|
|
11593
|
+
*
|
|
11594
|
+
* Not "nothing found" — that resolves to an empty list and is the normal case.
|
|
11595
|
+
* This is the engine itself failing, which the loop survives because it is
|
|
11596
|
+
* usually transient (a frame arriving between two resolutions).
|
|
11597
|
+
*/
|
|
11598
|
+
onError?: (error: unknown) => void;
|
|
11599
|
+
}
|
|
11600
|
+
|
|
11601
|
+
/** Value returned by {@link useBarcodeScanner}. */
|
|
11602
|
+
export declare interface UseBarcodeScannerResult {
|
|
11603
|
+
/** Attach to a `<video ref={…} muted playsInline />`. */
|
|
11604
|
+
videoRef: RefObject<HTMLVideoElement | null>;
|
|
11605
|
+
/** Camera lifecycle. `"ready"` means the preview is running. */
|
|
11606
|
+
status: CameraStreamStatus;
|
|
11607
|
+
/** Classified camera error, or `null`. */
|
|
11608
|
+
error: CameraStreamError | null;
|
|
11609
|
+
/** `false` when there is no decoder — no native API and none injected. */
|
|
11610
|
+
supported: boolean;
|
|
11611
|
+
/**
|
|
11612
|
+
* Formats actually in use: the requested ones intersected with what the engine
|
|
11613
|
+
* reports. Empty while the probe is in flight, or when nothing matched.
|
|
11614
|
+
*/
|
|
11615
|
+
formats: readonly BarcodeFormat[];
|
|
11616
|
+
/** Whether the detect loop is running right now. */
|
|
11617
|
+
scanning: boolean;
|
|
11618
|
+
/** The most recent accepted read, or `null`. */
|
|
11619
|
+
result: BarcodeScanResult | null;
|
|
11620
|
+
/** The LED torch of this camera, when it has one. */
|
|
11621
|
+
torch: UseTorchResult;
|
|
11622
|
+
/** Re-open the camera after an error (the user changed the permission). */
|
|
11623
|
+
retry: () => void;
|
|
11624
|
+
}
|
|
11625
|
+
|
|
9616
11626
|
/**
|
|
9617
11627
|
* React hook for the PWA install prompt. Captures the `beforeinstallprompt`
|
|
9618
11628
|
* event so you can defer the install UI to a moment that fits your UX.
|
|
@@ -10236,6 +12246,93 @@ export declare interface UseMapResult<K, V> {
|
|
|
10236
12246
|
|
|
10237
12247
|
export { useMatch }
|
|
10238
12248
|
|
|
12249
|
+
/**
|
|
12250
|
+
* List capture and playback devices, and keep the list fresh.
|
|
12251
|
+
*
|
|
12252
|
+
* Two things about `enumerateDevices` that decide how a picker must be built:
|
|
12253
|
+
*
|
|
12254
|
+
* 1. **Labels are gated behind permission.** Before the user grants a capture
|
|
12255
|
+
* permission, every `label` is `""` — the list length and ids are real, the names
|
|
12256
|
+
* are not. A device picker rendered at that point is a column of blanks, so
|
|
12257
|
+
* `labelsAvailable` is exposed to gate it. Ask for the microphone first, then
|
|
12258
|
+
* show the picker.
|
|
12259
|
+
* 2. **The list changes while the page is open.** Plugging in a headset mid-recording
|
|
12260
|
+
* is the normal case, not an edge case, so the hook subscribes to `devicechange`
|
|
12261
|
+
* instead of enumerating once on mount.
|
|
12262
|
+
*
|
|
12263
|
+
* `audioOutputs` is empty on browsers with no output routing at all (Safari and
|
|
12264
|
+
* Firefox do not implement `setSinkId`); an empty array there means "you cannot
|
|
12265
|
+
* offer this choice", not "no speakers".
|
|
12266
|
+
*
|
|
12267
|
+
* @returns The device lists, whether labels are filled in, and a `refresh()`.
|
|
12268
|
+
*
|
|
12269
|
+
* @example
|
|
12270
|
+
* const { audioInputs, labelsAvailable } = useMediaDevices();
|
|
12271
|
+
* // ...after the mic permission is granted:
|
|
12272
|
+
* {labelsAvailable && <Select options={audioInputs.map((d) => ({ value: d.deviceId, label: d.label }))} />}
|
|
12273
|
+
*/
|
|
12274
|
+
export declare function useMediaDevices(): UseMediaDevicesResult;
|
|
12275
|
+
|
|
12276
|
+
/** Value returned by {@link useMediaDevices}. */
|
|
12277
|
+
export declare interface UseMediaDevicesResult {
|
|
12278
|
+
/** Every device, in the order the browser listed them. */
|
|
12279
|
+
devices: MediaDeviceOption[];
|
|
12280
|
+
/** Microphones and other audio sources. */
|
|
12281
|
+
audioInputs: MediaDeviceOption[];
|
|
12282
|
+
/** Speakers and headsets. Empty on browsers with no output routing (Safari, Firefox). */
|
|
12283
|
+
audioOutputs: MediaDeviceOption[];
|
|
12284
|
+
/** Cameras. */
|
|
12285
|
+
videoInputs: MediaDeviceOption[];
|
|
12286
|
+
/**
|
|
12287
|
+
* Whether labels are filled in.
|
|
12288
|
+
*
|
|
12289
|
+
* `false` means the list is real but anonymous — render a picker only after a
|
|
12290
|
+
* capture permission has been granted, or the user sees "" repeated N times.
|
|
12291
|
+
*/
|
|
12292
|
+
labelsAvailable: boolean;
|
|
12293
|
+
/** `enumerateDevices` is unavailable in this browser. */
|
|
12294
|
+
supported: boolean;
|
|
12295
|
+
/** Re-enumerate. The hook already does this on `devicechange`. */
|
|
12296
|
+
refresh: () => void;
|
|
12297
|
+
}
|
|
12298
|
+
|
|
12299
|
+
/**
|
|
12300
|
+
* Read a capture permission **without triggering the prompt**.
|
|
12301
|
+
*
|
|
12302
|
+
* This is the piece that makes a good permission flow possible. `getUserMedia` is
|
|
12303
|
+
* the only way to *get* a device, but calling it is also the only way to *ask*, and
|
|
12304
|
+
* a prompt fired on page load — before the user has pressed anything — is the
|
|
12305
|
+
* single most reliable way to earn a permanent "Block". Reading the state first
|
|
12306
|
+
* lets a page explain why it needs the microphone, and only then ask.
|
|
12307
|
+
*
|
|
12308
|
+
* It also separates "never asked" from "denied", which matters because they need
|
|
12309
|
+
* opposite UI: `"prompt"` gets a button, `"denied"` gets instructions for the
|
|
12310
|
+
* browser's site settings, since no amount of clicking will re-prompt.
|
|
12311
|
+
*
|
|
12312
|
+
* Safari does not expose `microphone` to the Permissions API and throws on the
|
|
12313
|
+
* query, which surfaces as `state: "unknown"` and `supported: false` — treat that
|
|
12314
|
+
* as "you will have to ask to find out", not as an error.
|
|
12315
|
+
*
|
|
12316
|
+
* @param name - Which permission to observe.
|
|
12317
|
+
* @returns The live state, whether it could be read, and a manual `refresh()`.
|
|
12318
|
+
*
|
|
12319
|
+
* @example
|
|
12320
|
+
* const { state } = useMediaPermission("microphone");
|
|
12321
|
+
* if (state === "denied") return <p>Libere o microfone nas configurações do site.</p>;
|
|
12322
|
+
* return <button onClick={start}>Gravar</button>;
|
|
12323
|
+
*/
|
|
12324
|
+
export declare function useMediaPermission(name: MediaPermissionName): UseMediaPermissionResult;
|
|
12325
|
+
|
|
12326
|
+
/** Value returned by {@link useMediaPermission}. */
|
|
12327
|
+
export declare interface UseMediaPermissionResult {
|
|
12328
|
+
/** Current state. Updates live when the user changes it in browser settings. */
|
|
12329
|
+
state: MediaPermissionState;
|
|
12330
|
+
/** Whether the Permissions API could answer at all. */
|
|
12331
|
+
supported: boolean;
|
|
12332
|
+
/** Re-read the permission. Rarely needed — the hook subscribes to changes. */
|
|
12333
|
+
refresh: () => void;
|
|
12334
|
+
}
|
|
12335
|
+
|
|
10239
12336
|
/**
|
|
10240
12337
|
* Subscribe to a CSS media query and re-render on match changes.
|
|
10241
12338
|
*
|
|
@@ -10244,6 +12341,65 @@ export { useMatch }
|
|
|
10244
12341
|
*/
|
|
10245
12342
|
export declare function useMediaQuery(query: string): boolean;
|
|
10246
12343
|
|
|
12344
|
+
/**
|
|
12345
|
+
* Acquire a microphone `MediaStream`, classified errors included, and release it
|
|
12346
|
+
* properly.
|
|
12347
|
+
*
|
|
12348
|
+
* Releasing matters more than it looks. Every track has to be stopped by hand:
|
|
12349
|
+
* dropping the last reference to a `MediaStream` does **not** turn off the
|
|
12350
|
+
* microphone, so the browser keeps showing its recording indicator and the OS keeps
|
|
12351
|
+
* the device busy — which then makes the *next* `getUserMedia` fail with
|
|
12352
|
+
* `NotReadableError` in another tab. The hook stops tracks on `stop()`, on unmount,
|
|
12353
|
+
* and before re-opening.
|
|
12354
|
+
*
|
|
12355
|
+
* @param options - See {@link UseMicrophoneOptions}.
|
|
12356
|
+
* @returns The stream, its status, a classified error, and `start`/`stop`.
|
|
12357
|
+
*
|
|
12358
|
+
* @example
|
|
12359
|
+
* const mic = useMicrophone();
|
|
12360
|
+
* const recorder = useAudioRecorder(mic.stream);
|
|
12361
|
+
* <button onClick={mic.start}>Liberar microfone</button>
|
|
12362
|
+
*/
|
|
12363
|
+
export declare function useMicrophone(options?: UseMicrophoneOptions): UseMicrophoneResult;
|
|
12364
|
+
|
|
12365
|
+
/** Options for {@link useMicrophone}. */
|
|
12366
|
+
export declare interface UseMicrophoneOptions {
|
|
12367
|
+
/**
|
|
12368
|
+
* Open the stream on mount instead of waiting for `start()`. Default `false`.
|
|
12369
|
+
*
|
|
12370
|
+
* Left off on purpose. Opening on mount means prompting on mount, and a
|
|
12371
|
+
* permission prompt the user did not provoke is the most reliable way to earn a
|
|
12372
|
+
* permanent "Block" — after which `getUserMedia` rejects without ever prompting
|
|
12373
|
+
* again. Wire `start()` to the button that needs the microphone.
|
|
12374
|
+
*/
|
|
12375
|
+
autoStart?: boolean;
|
|
12376
|
+
/** Specific microphone, from `useMediaDevices().audioInputs`. */
|
|
12377
|
+
deviceId?: string;
|
|
12378
|
+
/**
|
|
12379
|
+
* Browser voice processing. All three default to `true`, which is what speech
|
|
12380
|
+
* wants; turn them off for music, where a gate chewing on a decaying note is
|
|
12381
|
+
* worse than the room noise it removes.
|
|
12382
|
+
*/
|
|
12383
|
+
echoCancellation?: boolean;
|
|
12384
|
+
noiseSuppression?: boolean;
|
|
12385
|
+
autoGainControl?: boolean;
|
|
12386
|
+
/** Escape hatch: full constraints, replacing everything above. */
|
|
12387
|
+
constraints?: MediaStreamConstraints;
|
|
12388
|
+
}
|
|
12389
|
+
|
|
12390
|
+
/** Value returned by {@link useMicrophone}. */
|
|
12391
|
+
export declare interface UseMicrophoneResult {
|
|
12392
|
+
status: MicrophoneStatus;
|
|
12393
|
+
/** The live stream, or `null`. Feed it to {@link useAudioRecorder} or an analyser. */
|
|
12394
|
+
stream: MediaStream | null;
|
|
12395
|
+
/** Classified error, or `null` outside the `error` status. */
|
|
12396
|
+
error: MediaAccessError | null;
|
|
12397
|
+
/** Open the stream. Safe to call when already open — it is a no-op. */
|
|
12398
|
+
start: () => void;
|
|
12399
|
+
/** Release the microphone. The browser's recording indicator only clears here. */
|
|
12400
|
+
stop: () => void;
|
|
12401
|
+
}
|
|
12402
|
+
|
|
10247
12403
|
/**
|
|
10248
12404
|
* Access the imperative modals API. Must be used within a {@link ModalsProvider}.
|
|
10249
12405
|
*
|
|
@@ -10643,6 +12799,142 @@ export declare interface UsePaginationResult {
|
|
|
10643
12799
|
|
|
10644
12800
|
export { useParams }
|
|
10645
12801
|
|
|
12802
|
+
/**
|
|
12803
|
+
* Probe what this device can do, once per mount.
|
|
12804
|
+
*
|
|
12805
|
+
* @param client - Client whose probes to call.
|
|
12806
|
+
* @returns The three capability answers, two of them async.
|
|
12807
|
+
*/
|
|
12808
|
+
export declare function usePasskeyCapabilities(client?: PasskeyClient): PasskeyCapabilities;
|
|
12809
|
+
|
|
12810
|
+
/**
|
|
12811
|
+
* Register a passkey: fetch options, run `navigator.credentials.create`, hand the
|
|
12812
|
+
* credential to your backend.
|
|
12813
|
+
*
|
|
12814
|
+
* `register()` **resolves** rather than rejects on failure, because every failure
|
|
12815
|
+
* here is already state the UI has to render (`error.kind`, `status`). Forcing a
|
|
12816
|
+
* `try/catch` around a button handler that also has to set state would only
|
|
12817
|
+
* duplicate what the hook holds.
|
|
12818
|
+
*
|
|
12819
|
+
* @param options - Transport callbacks plus optional client and listeners.
|
|
12820
|
+
* @returns Ceremony state, the `register` action, and the capability probes.
|
|
12821
|
+
*
|
|
12822
|
+
* @example
|
|
12823
|
+
* const passkey = usePasskeyRegistration({
|
|
12824
|
+
* getOptions: () => api.post("/webauthn/register/begin"),
|
|
12825
|
+
* verify: (credential) => api.post("/webauthn/register/finish", { body: credential }),
|
|
12826
|
+
* });
|
|
12827
|
+
*
|
|
12828
|
+
* if (passkey.platformAvailable === false) return null;
|
|
12829
|
+
* return (
|
|
12830
|
+
* <button onClick={() => void passkey.register()} disabled={passkey.status === "prompting"}>
|
|
12831
|
+
* Criar passkey
|
|
12832
|
+
* </button>
|
|
12833
|
+
* );
|
|
12834
|
+
*/
|
|
12835
|
+
export declare function usePasskeyRegistration<TResult = unknown>(options: UsePasskeyRegistrationOptions<TResult>): UsePasskeyRegistrationResult<TResult>;
|
|
12836
|
+
|
|
12837
|
+
/** Options for {@link usePasskeyRegistration}. */
|
|
12838
|
+
export declare interface UsePasskeyRegistrationOptions<TResult> {
|
|
12839
|
+
/** Fetch server options — your `POST /webauthn/register/begin`. */
|
|
12840
|
+
getOptions: () => Promise<PasskeyCreationOptionsJSON>;
|
|
12841
|
+
/** Send the credential to be verified — your `POST /webauthn/register/finish`. */
|
|
12842
|
+
verify: (credential: PasskeyRegistrationJSON) => Promise<TResult>;
|
|
12843
|
+
/** Client to use. Defaults to a shared `createPasskeyClient()`. */
|
|
12844
|
+
client?: PasskeyClient;
|
|
12845
|
+
/** Called with whatever `verify` resolved to. */
|
|
12846
|
+
onSuccess?: (result: TResult) => void;
|
|
12847
|
+
/** Called with the classified failure. */
|
|
12848
|
+
onError?: (error: PasskeyError) => void;
|
|
12849
|
+
}
|
|
12850
|
+
|
|
12851
|
+
/** Value returned by {@link usePasskeyRegistration}. */
|
|
12852
|
+
export declare interface UsePasskeyRegistrationResult<TResult> extends PasskeyCapabilities {
|
|
12853
|
+
/** Run the ceremony. Resolves `null` on failure — read `error` for the reason. */
|
|
12854
|
+
register: () => Promise<TResult | null>;
|
|
12855
|
+
/** Current phase. */
|
|
12856
|
+
status: PasskeyStatus;
|
|
12857
|
+
/** Last failure, cleared when a new attempt starts. */
|
|
12858
|
+
error: PasskeyError | null;
|
|
12859
|
+
/** Whatever `verify` resolved to, on success. */
|
|
12860
|
+
data: TResult | null;
|
|
12861
|
+
/** Close the browser sheet from your own UI. */
|
|
12862
|
+
cancel: () => void;
|
|
12863
|
+
/** Back to `"idle"`, clearing `error` and `data`. */
|
|
12864
|
+
reset: () => void;
|
|
12865
|
+
}
|
|
12866
|
+
|
|
12867
|
+
/**
|
|
12868
|
+
* Sign in with a passkey, with or without the autofill flow.
|
|
12869
|
+
*
|
|
12870
|
+
* Two ways in, and a good login page wires both. `signIn()` is the explicit
|
|
12871
|
+
* button. `conditional: true` arms the pleasant one: the browser lists the user's
|
|
12872
|
+
* passkeys inside the username field itself, so signing in is one tap and no
|
|
12873
|
+
* password was ever typed. The field must carry
|
|
12874
|
+
* `autocomplete="username webauthn"` or the list never appears — the hook cannot
|
|
12875
|
+
* do that part for you.
|
|
12876
|
+
*
|
|
12877
|
+
* A conditional request that is aborted (unmount, or the user typing a password
|
|
12878
|
+
* instead) is **not** surfaced as an error: nothing failed, the user chose
|
|
12879
|
+
* another door.
|
|
12880
|
+
*
|
|
12881
|
+
* @param options - Transport callbacks, `conditional`, optional client and listeners.
|
|
12882
|
+
* @returns Ceremony state, the `signIn` action, and the capability probes.
|
|
12883
|
+
*
|
|
12884
|
+
* @example
|
|
12885
|
+
* const passkey = usePasskeySignIn({
|
|
12886
|
+
* conditional: true,
|
|
12887
|
+
* getOptions: () => api.post("/webauthn/signin/begin"),
|
|
12888
|
+
* verify: (assertion) => api.post("/webauthn/signin/finish", { body: assertion }),
|
|
12889
|
+
* onSuccess: (session) => auth.setToken(session.access_token),
|
|
12890
|
+
* });
|
|
12891
|
+
*
|
|
12892
|
+
* <input name="email" autoComplete="username webauthn" />
|
|
12893
|
+
* <button onClick={() => void passkey.signIn()}>Entrar com passkey</button>
|
|
12894
|
+
*/
|
|
12895
|
+
export declare function usePasskeySignIn<TResult = unknown>(options: UsePasskeySignInOptions<TResult>): UsePasskeySignInResult<TResult>;
|
|
12896
|
+
|
|
12897
|
+
/** Options for {@link usePasskeySignIn}. */
|
|
12898
|
+
export declare interface UsePasskeySignInOptions<TResult> {
|
|
12899
|
+
/** Fetch server options — your `POST /webauthn/signin/begin`. */
|
|
12900
|
+
getOptions: () => Promise<PasskeyRequestOptionsJSON>;
|
|
12901
|
+
/** Send the assertion to be verified — your `POST /webauthn/signin/finish`. */
|
|
12902
|
+
verify: (assertion: PasskeyAuthenticationJSON) => Promise<TResult>;
|
|
12903
|
+
/** Client to use. Defaults to a shared `createPasskeyClient()`. */
|
|
12904
|
+
client?: PasskeyClient;
|
|
12905
|
+
/**
|
|
12906
|
+
* Arm the autofill flow on mount (`mediation: "conditional"`).
|
|
12907
|
+
*
|
|
12908
|
+
* The request stays pending, invisibly, until the user picks a passkey from
|
|
12909
|
+
* the browser's autofill list — so the field it should appear on needs
|
|
12910
|
+
* `autocomplete="username webauthn"`. Only one conditional request may be live
|
|
12911
|
+
* per page, and it is aborted on unmount.
|
|
12912
|
+
*/
|
|
12913
|
+
conditional?: boolean;
|
|
12914
|
+
/** Called with whatever `verify` resolved to. */
|
|
12915
|
+
onSuccess?: (result: TResult) => void;
|
|
12916
|
+
/** Called with the classified failure. */
|
|
12917
|
+
onError?: (error: PasskeyError) => void;
|
|
12918
|
+
}
|
|
12919
|
+
|
|
12920
|
+
/** Value returned by {@link usePasskeySignIn}. */
|
|
12921
|
+
export declare interface UsePasskeySignInResult<TResult> extends PasskeyCapabilities {
|
|
12922
|
+
/** Run the modal ceremony. Resolves `null` on failure. */
|
|
12923
|
+
signIn: () => Promise<TResult | null>;
|
|
12924
|
+
/** Current phase. */
|
|
12925
|
+
status: PasskeyStatus;
|
|
12926
|
+
/** Last failure, cleared when a new attempt starts. */
|
|
12927
|
+
error: PasskeyError | null;
|
|
12928
|
+
/** Whatever `verify` resolved to, on success. */
|
|
12929
|
+
data: TResult | null;
|
|
12930
|
+
/** True while an armed conditional (autofill) request is waiting. */
|
|
12931
|
+
conditionalPending: boolean;
|
|
12932
|
+
/** Close the browser sheet from your own UI. */
|
|
12933
|
+
cancel: () => void;
|
|
12934
|
+
/** Back to `"idle"`, clearing `error` and `data`. */
|
|
12935
|
+
reset: () => void;
|
|
12936
|
+
}
|
|
12937
|
+
|
|
10646
12938
|
/**
|
|
10647
12939
|
* Poll an async factory on a fixed interval. Skips overlapping requests if a
|
|
10648
12940
|
* prior call has not finished. Pause via `disabled` or `stopWhen`.
|
|
@@ -10795,6 +13087,102 @@ export declare function useResizeObserver(ref: RefObject<Element | null>): Eleme
|
|
|
10795
13087
|
|
|
10796
13088
|
export { useRouteError }
|
|
10797
13089
|
|
|
13090
|
+
/**
|
|
13091
|
+
* Capture a screen, a window or a tab with `getDisplayMedia`.
|
|
13092
|
+
*
|
|
13093
|
+
* Three states decide whether this feels right, and two of them are easy to miss:
|
|
13094
|
+
*
|
|
13095
|
+
* - **The user dismissed the picker.** A rejection, but not a failure. It leaves
|
|
13096
|
+
* `error` at `null` and the status back at `"idle"`, and calls `onCancelled`.
|
|
13097
|
+
* - **The user stopped the share from the browser's own bar.** Nothing in your UI was
|
|
13098
|
+
* clicked and no promise rejects — the *only* signal is the video track's `ended`
|
|
13099
|
+
* event, so the hook listens for it and clears the stream. Without that listener, an
|
|
13100
|
+
* app shows "gravando" over a stream that is already dead.
|
|
13101
|
+
* - **The share is live.** `surface` says what was picked and `hasAudio` says whether
|
|
13102
|
+
* audio actually came along, which is not what you asked for but what you got.
|
|
13103
|
+
*
|
|
13104
|
+
* The stream is owned here: `stop()` and unmount both release every track. A recorder
|
|
13105
|
+
* built on it (`useVideoRecorder`) deliberately does not, so stopping a recording
|
|
13106
|
+
* leaves the share running for the next take.
|
|
13107
|
+
*
|
|
13108
|
+
* @param options - See {@link UseScreenCaptureOptions}.
|
|
13109
|
+
* @returns The stream, its status, a classified error and `start`/`stop`.
|
|
13110
|
+
*
|
|
13111
|
+
* @example
|
|
13112
|
+
* const screen = useScreenCapture({ preferCurrentTab: true, onEnded: () => save() });
|
|
13113
|
+
* const rec = useVideoRecorder(screen.stream);
|
|
13114
|
+
* <button onClick={screen.start}>Compartilhar tela</button>
|
|
13115
|
+
*/
|
|
13116
|
+
export declare function useScreenCapture(options?: UseScreenCaptureOptions): UseScreenCaptureResult;
|
|
13117
|
+
|
|
13118
|
+
/** Options for {@link useScreenCapture}. */
|
|
13119
|
+
export declare interface UseScreenCaptureOptions {
|
|
13120
|
+
/**
|
|
13121
|
+
* Capture the tab's audio too. Default `false`.
|
|
13122
|
+
*
|
|
13123
|
+
* Chromium only offers this for a **tab** — sharing a window or a whole screen
|
|
13124
|
+
* yields no audio track no matter what you ask for, and Safari has no display
|
|
13125
|
+
* audio at all. Ask for it and check what you got.
|
|
13126
|
+
*/
|
|
13127
|
+
audio?: boolean;
|
|
13128
|
+
/**
|
|
13129
|
+
* Which surface the picker should offer first — `"browser"` is a tab.
|
|
13130
|
+
*
|
|
13131
|
+
* A hint, never a guarantee: the user can always pick something else, and Firefox
|
|
13132
|
+
* ignores it. Read `surface` afterwards to learn what actually happened.
|
|
13133
|
+
*/
|
|
13134
|
+
displaySurface?: DisplaySurfaceHint;
|
|
13135
|
+
/**
|
|
13136
|
+
* Put *this* tab at the top of the picker. Default `false`.
|
|
13137
|
+
*
|
|
13138
|
+
* The right setting for "record what you are seeing right now" in a support flow.
|
|
13139
|
+
* Chromium only.
|
|
13140
|
+
*/
|
|
13141
|
+
preferCurrentTab?: boolean;
|
|
13142
|
+
/** Offer this tab in the list at all. `"exclude"` prevents the hall-of-mirrors capture. */
|
|
13143
|
+
selfBrowserSurface?: "include" | "exclude";
|
|
13144
|
+
/** Let the user switch to a different surface mid-share, without a new prompt. */
|
|
13145
|
+
surfaceSwitching?: "include" | "exclude";
|
|
13146
|
+
/** Include the system audio when a whole screen is shared. Chromium, Windows only. */
|
|
13147
|
+
systemAudio?: "include" | "exclude";
|
|
13148
|
+
/** Escape hatch: full options, replacing everything above. */
|
|
13149
|
+
options?: DisplayMediaStreamOptions;
|
|
13150
|
+
/**
|
|
13151
|
+
* The user stopped the share from the browser's own bar.
|
|
13152
|
+
*
|
|
13153
|
+
* The single most important callback here — see the note on
|
|
13154
|
+
* {@link useScreenCapture}.
|
|
13155
|
+
*/
|
|
13156
|
+
onEnded?: () => void;
|
|
13157
|
+
/**
|
|
13158
|
+
* The user dismissed the picker. **Not an error.**
|
|
13159
|
+
*
|
|
13160
|
+
* Receives the rejection so an app that needs to tell a dismissal from an OS-level
|
|
13161
|
+
* block (macOS screen-recording permission) can look at the message. Most should
|
|
13162
|
+
* simply return the UI to its previous state.
|
|
13163
|
+
*/
|
|
13164
|
+
onCancelled?: (reason: unknown) => void;
|
|
13165
|
+
}
|
|
13166
|
+
|
|
13167
|
+
/** Value returned by {@link useScreenCapture}. */
|
|
13168
|
+
export declare interface UseScreenCaptureResult {
|
|
13169
|
+
status: ScreenCaptureStatus;
|
|
13170
|
+
/** The live stream, or `null`. Feed it to {@link useVideoRecorder} or a `<video>`. */
|
|
13171
|
+
stream: MediaStream | null;
|
|
13172
|
+
/** Classified error, or `null`. A cancelled picker leaves this `null`. */
|
|
13173
|
+
error: MediaAccessError | null;
|
|
13174
|
+
/** What the user actually picked, when the browser reports it. */
|
|
13175
|
+
surface: string | null;
|
|
13176
|
+
/** Whether the stream carries an audio track — ask, do not assume. */
|
|
13177
|
+
hasAudio: boolean;
|
|
13178
|
+
/** `false` when `getDisplayMedia` is missing (every browser on iOS, insecure pages). */
|
|
13179
|
+
supported: boolean;
|
|
13180
|
+
/** Open the picker. Must be called from a user gesture. */
|
|
13181
|
+
start: () => void;
|
|
13182
|
+
/** Stop sharing from the app side. Fires nothing — you asked for it. */
|
|
13183
|
+
stop: () => void;
|
|
13184
|
+
}
|
|
13185
|
+
|
|
10798
13186
|
/**
|
|
10799
13187
|
* Lock `<body>` scroll while `active` is true. Restores the previous overflow
|
|
10800
13188
|
* value on unmount. Safe to nest: stacks the restoration via a counter.
|
|
@@ -11013,6 +13401,96 @@ export declare interface UseSortableResult {
|
|
|
11013
13401
|
setContainer: (node: HTMLElement | null) => void;
|
|
11014
13402
|
}
|
|
11015
13403
|
|
|
13404
|
+
/**
|
|
13405
|
+
* Dictate into your app with the Web Speech API — no dependency, no API key.
|
|
13406
|
+
*
|
|
13407
|
+
* ## Recognition is not local
|
|
13408
|
+
*
|
|
13409
|
+
* **Chromium streams the captured audio to a Google server to transcribe it.** Nothing
|
|
13410
|
+
* about the API says so, there is no setting that changes it, and it happens on every
|
|
13411
|
+
* `start()`. Anything the user says while a session is open leaves the device. Do not
|
|
13412
|
+
* put this on a field that takes clinical notes, credentials, or a client's financial
|
|
13413
|
+
* detail without telling them first — and if the data cannot leave your infrastructure,
|
|
13414
|
+
* this API is the wrong tool and a self-hosted model is the right one.
|
|
13415
|
+
*
|
|
13416
|
+
* ## What the states mean
|
|
13417
|
+
*
|
|
13418
|
+
* `transcript` accumulates the phrases the engine has **settled** on; `interim` is the
|
|
13419
|
+
* guess it is still revising and is replaced wholesale on every event, so rendering
|
|
13420
|
+
* `transcript + interim` gives the live caption effect and rendering `transcript` alone
|
|
13421
|
+
* gives the committed text. `no-speech` and `aborted` come through `onError` but are
|
|
13422
|
+
* routine — a user who pressed the button and said nothing is not a failure to report.
|
|
13423
|
+
*
|
|
13424
|
+
* There is deliberately **no auto-restart** when the engine ends a session on silence.
|
|
13425
|
+
* A restart loop is how an app ends up holding the microphone indefinitely — and, in
|
|
13426
|
+
* Chromium, streaming audio to a third party indefinitely. Show that listening stopped
|
|
13427
|
+
* and let the user press again.
|
|
13428
|
+
*
|
|
13429
|
+
* @param options - See {@link UseSpeechRecognitionOptions}.
|
|
13430
|
+
* @returns Session state, the transcript and the controls.
|
|
13431
|
+
*
|
|
13432
|
+
* @example
|
|
13433
|
+
* const speech = useSpeechRecognition({ onFinal: (text) => setPrompt(text) });
|
|
13434
|
+
* <button onClick={speech.listening ? speech.stop : speech.start}>
|
|
13435
|
+
* {speech.listening ? "Parar" : "Ditar"}
|
|
13436
|
+
* </button>
|
|
13437
|
+
* <p>{speech.transcript}{speech.interim}</p>
|
|
13438
|
+
*/
|
|
13439
|
+
export declare function useSpeechRecognition(options?: UseSpeechRecognitionOptions): UseSpeechRecognitionResult;
|
|
13440
|
+
|
|
13441
|
+
/** Options for {@link useSpeechRecognition}. */
|
|
13442
|
+
export declare interface UseSpeechRecognitionOptions {
|
|
13443
|
+
/** BCP-47 tag. Default `"pt-BR"`. */
|
|
13444
|
+
lang?: string;
|
|
13445
|
+
/**
|
|
13446
|
+
* Keep listening after the first phrase settles. Default `false`.
|
|
13447
|
+
*
|
|
13448
|
+
* Even with this on, the engine ends the session by itself after a stretch of
|
|
13449
|
+
* silence — that is a server-side timeout, not a bug — so watch `listening` rather
|
|
13450
|
+
* than assuming the microphone stays open.
|
|
13451
|
+
*/
|
|
13452
|
+
continuous?: boolean;
|
|
13453
|
+
/** Publish the running guess as it changes. Default `true`. */
|
|
13454
|
+
interimResults?: boolean;
|
|
13455
|
+
/** How many readings per phrase to ask for. Default 1. */
|
|
13456
|
+
maxAlternatives?: number;
|
|
13457
|
+
/** Every update, settled or not. */
|
|
13458
|
+
onResult?: (result: {
|
|
13459
|
+
transcript: string;
|
|
13460
|
+
isFinal: boolean;
|
|
13461
|
+
}) => void;
|
|
13462
|
+
/** Only the settled text of a phrase. The one to wire dictation to. */
|
|
13463
|
+
onFinal?: (transcript: string) => void;
|
|
13464
|
+
/** Classified failure. `no-speech` and `aborted` arrive here too — they are routine. */
|
|
13465
|
+
onError?: (error: SpeechError) => void;
|
|
13466
|
+
/** The session ended, for any reason. */
|
|
13467
|
+
onEnd?: () => void;
|
|
13468
|
+
/** Build the recogniser yourself — another engine, or a stub in a test. */
|
|
13469
|
+
factory?: () => SpeechRecognitionLike;
|
|
13470
|
+
}
|
|
13471
|
+
|
|
13472
|
+
/** Value returned by {@link useSpeechRecognition}. */
|
|
13473
|
+
export declare interface UseSpeechRecognitionResult {
|
|
13474
|
+
/** `false` in Firefox and in every browser that is not Chromium-based. */
|
|
13475
|
+
supported: boolean;
|
|
13476
|
+
/** Whether a session is open right now. */
|
|
13477
|
+
listening: boolean;
|
|
13478
|
+
/** Everything settled so far in this session. Cleared by `reset()`. */
|
|
13479
|
+
transcript: string;
|
|
13480
|
+
/** The running guess. Replaced on every event, empty once the phrase settles. */
|
|
13481
|
+
interim: string;
|
|
13482
|
+
/** Classified error, or `null`. */
|
|
13483
|
+
error: SpeechError | null;
|
|
13484
|
+
/** Open a session. No-op while already listening. */
|
|
13485
|
+
start: () => void;
|
|
13486
|
+
/** Close the session, keeping what was recognised. */
|
|
13487
|
+
stop: () => void;
|
|
13488
|
+
/** Close the session and throw the pending phrase away. */
|
|
13489
|
+
abort: () => void;
|
|
13490
|
+
/** Clear `transcript`, `interim` and `error`. Does not stop a session. */
|
|
13491
|
+
reset: () => void;
|
|
13492
|
+
}
|
|
13493
|
+
|
|
11016
13494
|
/**
|
|
11017
13495
|
* Returns a stable function reference that always invokes the latest
|
|
11018
13496
|
* `callback` argument. Use to break dependency cycles in effects without
|
|
@@ -11116,6 +13594,49 @@ export declare function useToast(): ToastApi;
|
|
|
11116
13594
|
*/
|
|
11117
13595
|
export declare function useToggle(initial?: boolean): [boolean, ToggleHelpers];
|
|
11118
13596
|
|
|
13597
|
+
/**
|
|
13598
|
+
* Drive the camera's LED torch on the video track of a stream.
|
|
13599
|
+
*
|
|
13600
|
+
* The lamp is not a device you can open — it is a **constraint on a live video
|
|
13601
|
+
* track**, so there is nothing to control until a camera stream exists, and it
|
|
13602
|
+
* disappears when that stream is released. That is also why `supported` can only be
|
|
13603
|
+
* answered after the track is live: the same code is `true` on an Android rear camera
|
|
13604
|
+
* and `false` on the front one of the same phone.
|
|
13605
|
+
*
|
|
13606
|
+
* Capability detection prefers `getCapabilities()` and falls back to
|
|
13607
|
+
* `getSettings()`, because Firefox implements neither the torch nor
|
|
13608
|
+
* `getCapabilities()` and Safari reports the setting without the capability. When
|
|
13609
|
+
* neither mentions `torch`, the hook reports `supported: false` instead of offering a
|
|
13610
|
+
* button that silently does nothing.
|
|
13611
|
+
*
|
|
13612
|
+
* @param stream - A live camera stream, or `null` before permission lands.
|
|
13613
|
+
* @returns Whether a lamp exists, its state, and setters.
|
|
13614
|
+
*
|
|
13615
|
+
* @example
|
|
13616
|
+
* const camera = useBarcodeScanner();
|
|
13617
|
+
* {camera.torch.supported && (
|
|
13618
|
+
* <button onClick={() => void camera.torch.toggle()}>Lanterna</button>
|
|
13619
|
+
* )}
|
|
13620
|
+
*/
|
|
13621
|
+
export declare function useTorch(stream: MediaStream | null): UseTorchResult;
|
|
13622
|
+
|
|
13623
|
+
/** Value returned by {@link useTorch}. */
|
|
13624
|
+
export declare interface UseTorchResult {
|
|
13625
|
+
/** Whether this track has a controllable lamp. `false` on every desktop webcam. */
|
|
13626
|
+
supported: boolean;
|
|
13627
|
+
/** Whether the lamp is on, as far as this hook knows. */
|
|
13628
|
+
on: boolean;
|
|
13629
|
+
/**
|
|
13630
|
+
* Turn the lamp on or off.
|
|
13631
|
+
*
|
|
13632
|
+
* @param next - `true` to light it up.
|
|
13633
|
+
* @returns `false` when the track refused — treat that as "no torch".
|
|
13634
|
+
*/
|
|
13635
|
+
set: (next: boolean) => Promise<boolean>;
|
|
13636
|
+
/** Flip it. Same return contract as {@link UseTorchResult.set}. */
|
|
13637
|
+
toggle: () => Promise<boolean>;
|
|
13638
|
+
}
|
|
13639
|
+
|
|
11119
13640
|
/**
|
|
11120
13641
|
* Shortcut for components that only need the `t` function — avoids destructuring.
|
|
11121
13642
|
*/
|
|
@@ -11149,6 +13670,70 @@ export declare interface UseViaCEPResult {
|
|
|
11149
13670
|
reset: () => void;
|
|
11150
13671
|
}
|
|
11151
13672
|
|
|
13673
|
+
/**
|
|
13674
|
+
* Record a video stream — from {@link useScreenCapture}, from a camera, or from a
|
|
13675
|
+
* canvas.
|
|
13676
|
+
*
|
|
13677
|
+
* Pass the stream in; the hook stays `ready: false` until there is one, so a page can
|
|
13678
|
+
* render the whole recorder UI before the user has picked a screen and simply have it
|
|
13679
|
+
* disabled.
|
|
13680
|
+
*
|
|
13681
|
+
* There is no level meter here, which is the one real difference from
|
|
13682
|
+
* `useAudioRecorder`: metering a screen share means opening an `AudioContext` on a
|
|
13683
|
+
* stream that usually has no audio track at all, and browsers cap the number of live
|
|
13684
|
+
* contexts. If you are recording a camera **and** want a level, run
|
|
13685
|
+
* `createLevelMeter` on the same stream yourself.
|
|
13686
|
+
*
|
|
13687
|
+
* The clock is published every `tickMs` (default 250 ms) rather than per frame: a
|
|
13688
|
+
* video recording UI shows `0:07`, and a hook that re-rendered its parent 60 times a
|
|
13689
|
+
* second to move a one-second counter would be the most expensive thing on the page.
|
|
13690
|
+
*
|
|
13691
|
+
* @param stream - The stream to record, or `null` while the picker is open.
|
|
13692
|
+
* @param options - See {@link UseVideoRecorderOptions}.
|
|
13693
|
+
*
|
|
13694
|
+
* @example
|
|
13695
|
+
* const screen = useScreenCapture();
|
|
13696
|
+
* const rec = useVideoRecorder(screen.stream, { maxDurationMs: 120_000 });
|
|
13697
|
+
* <button disabled={!rec.ready} onClick={rec.start}>Gravar tela</button>
|
|
13698
|
+
*/
|
|
13699
|
+
export declare function useVideoRecorder(stream: MediaStream | null, options?: UseVideoRecorderOptions): UseVideoRecorderResult;
|
|
13700
|
+
|
|
13701
|
+
/** Options for {@link useVideoRecorder}. */
|
|
13702
|
+
export declare interface UseVideoRecorderOptions extends VideoRecorderOptions {
|
|
13703
|
+
/**
|
|
13704
|
+
* Stop automatically after this many milliseconds.
|
|
13705
|
+
*
|
|
13706
|
+
* Worth setting on anything user-facing, and more so than for audio: a minute of
|
|
13707
|
+
* 1080p at 2.5 Mbps is roughly 19 MB, so a recording left running by accident
|
|
13708
|
+
* fills memory an order of magnitude faster than a voice note does.
|
|
13709
|
+
*/
|
|
13710
|
+
maxDurationMs?: number;
|
|
13711
|
+
/** Called once the recording is assembled, whether by `stop()` or `maxDurationMs`. */
|
|
13712
|
+
onRecorded?: (recording: VideoRecording) => void;
|
|
13713
|
+
/** How often the clock is published, in ms. Default 250. */
|
|
13714
|
+
tickMs?: number;
|
|
13715
|
+
}
|
|
13716
|
+
|
|
13717
|
+
/** Value returned by {@link useVideoRecorder}. */
|
|
13718
|
+
export declare interface UseVideoRecorderResult {
|
|
13719
|
+
status: MediaRecorderStatus;
|
|
13720
|
+
/** Recorded length so far, excluding paused time. */
|
|
13721
|
+
durationMs: number;
|
|
13722
|
+
/** The finished recording, or `null` before the first `stop()`. */
|
|
13723
|
+
recording: VideoRecording | null;
|
|
13724
|
+
/** Recorder-level error (encoder failure, share revoked mid-recording). */
|
|
13725
|
+
error: unknown;
|
|
13726
|
+
/** `false` when there is no stream yet, or the browser cannot record video. */
|
|
13727
|
+
ready: boolean;
|
|
13728
|
+
start: () => void;
|
|
13729
|
+
pause: () => void;
|
|
13730
|
+
resume: () => void;
|
|
13731
|
+
/** Stop and resolve with the recording. Also published on `recording`. */
|
|
13732
|
+
stop: () => Promise<VideoRecording | null>;
|
|
13733
|
+
/** Stop and throw the video away. */
|
|
13734
|
+
cancel: () => void;
|
|
13735
|
+
}
|
|
13736
|
+
|
|
11152
13737
|
export { useWatch }
|
|
11153
13738
|
|
|
11154
13739
|
/**
|
|
@@ -11266,6 +13851,70 @@ export declare interface ViaCEPResult {
|
|
|
11266
13851
|
siafi?: string;
|
|
11267
13852
|
}
|
|
11268
13853
|
|
|
13854
|
+
/**
|
|
13855
|
+
* Container/codec candidates for video, best first.
|
|
13856
|
+
*
|
|
13857
|
+
* VP9 in WebM leads because it is the best quality per byte that Chromium and Firefox
|
|
13858
|
+
* both encode natively; VP8 is the fallback for older Chromium and for hardware that
|
|
13859
|
+
* refuses VP9. `video/mp4` is last and exists for Safari, which produces H.264 in MP4
|
|
13860
|
+
* and nothing else — and only since Safari 14.1.
|
|
13861
|
+
*
|
|
13862
|
+
* Every candidate carries **Opus or AAC audio in the same container**, because a
|
|
13863
|
+
* screen recording with the tab's audio dropped is a support ticket, not a
|
|
13864
|
+
* simplification. On a stream with no audio track the browser simply omits it.
|
|
13865
|
+
*
|
|
13866
|
+
* Ported from the intersection of what `MediaRecorder.isTypeSupported` accepts in
|
|
13867
|
+
* Chrome 120+, Firefox 115+ and Safari 17. Re-check against
|
|
13868
|
+
* <https://developer.mozilla.org/docs/Web/API/MediaRecorder/isTypeSupported> before
|
|
13869
|
+
* adding to the list.
|
|
13870
|
+
*/
|
|
13871
|
+
export declare const VIDEO_MIME_CANDIDATES: readonly string[];
|
|
13872
|
+
|
|
13873
|
+
/** Imperative video recorder. Same shape as the audio one. */
|
|
13874
|
+
export declare type VideoRecorderHandle = MediaRecorderHandle;
|
|
13875
|
+
|
|
13876
|
+
/** Options for {@link createVideoRecorder}. */
|
|
13877
|
+
export declare interface VideoRecorderOptions {
|
|
13878
|
+
/**
|
|
13879
|
+
* Force a container. Throws when the browser cannot produce it.
|
|
13880
|
+
*
|
|
13881
|
+
* Leave it out. The default negotiates from {@link VIDEO_MIME_CANDIDATES}, which
|
|
13882
|
+
* is the only way one call site works on both Chromium and Safari.
|
|
13883
|
+
*/
|
|
13884
|
+
mimeType?: string;
|
|
13885
|
+
/**
|
|
13886
|
+
* Target video bitrate.
|
|
13887
|
+
*
|
|
13888
|
+
* The browser's default is conservative and a screen recording of text at
|
|
13889
|
+
* 1080p looks smeared under it. 2_500_000 is a good floor for a UI capture,
|
|
13890
|
+
* 8_000_000 for full-motion camera video.
|
|
13891
|
+
*/
|
|
13892
|
+
videoBitsPerSecond?: number;
|
|
13893
|
+
/** Target audio bitrate, when the stream carries audio. 64000–128000 is plenty. */
|
|
13894
|
+
audioBitsPerSecond?: number;
|
|
13895
|
+
/**
|
|
13896
|
+
* Emit a chunk every N ms through `onChunk`, for streaming upload.
|
|
13897
|
+
*
|
|
13898
|
+
* Worth setting for video far sooner than for audio: a minute of 1080p at
|
|
13899
|
+
* 2.5 Mbps is roughly 19 MB sitting in memory.
|
|
13900
|
+
*/
|
|
13901
|
+
timesliceMs?: number;
|
|
13902
|
+
/** Receives each chunk when `timesliceMs` is set. Chunks are **not** independently playable. */
|
|
13903
|
+
onChunk?: (chunk: Blob) => void;
|
|
13904
|
+
/** Recorder-level failure (screen share revoked mid-recording, encoder error). */
|
|
13905
|
+
onError?: (error: unknown) => void;
|
|
13906
|
+
}
|
|
13907
|
+
|
|
13908
|
+
/**
|
|
13909
|
+
* A finished video recording.
|
|
13910
|
+
*
|
|
13911
|
+
* Structurally the same three fields as an audio one — there is nothing
|
|
13912
|
+
* video-specific to add, and inventing a `width`/`height` here would be a lie: the
|
|
13913
|
+
* browser negotiates the frame size with the device and can change it mid-recording.
|
|
13914
|
+
* Read it from the track's `getSettings()` if you need it.
|
|
13915
|
+
*/
|
|
13916
|
+
export declare type VideoRecording = MediaRecording;
|
|
13917
|
+
|
|
11269
13918
|
/**
|
|
11270
13919
|
* Fixed-height virtual list. Renders only the visible window plus a small
|
|
11271
13920
|
* overscan buffer. Suitable for lists of thousands of identical rows.
|
|
@@ -11709,6 +14358,24 @@ export declare interface WatermarkStore {
|
|
|
11709
14358
|
clear: () => void;
|
|
11710
14359
|
}
|
|
11711
14360
|
|
|
14361
|
+
/** Options for {@link blobToWav}. */
|
|
14362
|
+
export declare interface WavOptions {
|
|
14363
|
+
/**
|
|
14364
|
+
* Mix down to one channel. Default `false`.
|
|
14365
|
+
*
|
|
14366
|
+
* Worth turning on for speech headed to a server: a microphone recorded in stereo
|
|
14367
|
+
* carries two nearly identical channels and doubles the upload for nothing.
|
|
14368
|
+
*/
|
|
14369
|
+
mono?: boolean;
|
|
14370
|
+
/**
|
|
14371
|
+
* Resample to this rate. Default: keep the source rate.
|
|
14372
|
+
*
|
|
14373
|
+
* 16000 is the rate most speech-to-text APIs want, and dropping 48 kHz to 16 kHz
|
|
14374
|
+
* removes two thirds of the bytes with no audible loss on voice.
|
|
14375
|
+
*/
|
|
14376
|
+
sampleRate?: number;
|
|
14377
|
+
}
|
|
14378
|
+
|
|
11712
14379
|
/**
|
|
11713
14380
|
* Browser-side Web Push helper. Wraps `Notification.requestPermission`,
|
|
11714
14381
|
* `pushManager.subscribe`, and the corresponding teardown. Transport is up to
|