tempest-react-sdk 0.51.0 → 0.53.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 +35 -5
- package/dist/audio/audio-bus.cjs +2 -0
- package/dist/audio/audio-bus.cjs.map +1 -0
- package/dist/audio/audio-bus.js +116 -0
- package/dist/audio/audio-bus.js.map +1 -0
- package/dist/audio/use-audio-bus.cjs +2 -0
- package/dist/audio/use-audio-bus.cjs.map +1 -0
- package/dist/audio/use-audio-bus.js +11 -0
- package/dist/audio/use-audio-bus.js.map +1 -0
- package/dist/auth/refresh-queue.cjs +1 -1
- package/dist/auth/refresh-queue.cjs.map +1 -1
- package/dist/auth/refresh-queue.js +6 -6
- package/dist/auth/refresh-queue.js.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.cjs +1 -1
- package/dist/components/RangeSlider/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.js +23 -23
- package/dist/components/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.cjs +1 -1
- package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.js +1 -1
- package/dist/components/Scheduler/Scheduler.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
- package/dist/components/Slider/Slider.cjs +1 -1
- package/dist/components/Slider/Slider.cjs.map +1 -1
- package/dist/components/Slider/Slider.js +9 -9
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/forms/FormField.cjs +1 -1
- package/dist/forms/FormField.cjs.map +1 -1
- package/dist/forms/FormField.js +23 -21
- package/dist/forms/FormField.js.map +1 -1
- package/dist/http/describe-api-error.cjs +1 -1
- package/dist/http/describe-api-error.cjs.map +1 -1
- package/dist/http/describe-api-error.js +4 -2
- package/dist/http/describe-api-error.js.map +1 -1
- package/dist/http/use-describe-api-error.cjs +1 -1
- package/dist/http/use-describe-api-error.cjs.map +1 -1
- package/dist/http/use-describe-api-error.js +3 -2
- package/dist/http/use-describe-api-error.js.map +1 -1
- package/dist/offline/create-offline-database.cjs +2 -0
- package/dist/offline/create-offline-database.cjs.map +1 -0
- package/dist/offline/create-offline-database.js +29 -0
- package/dist/offline/create-offline-database.js.map +1 -0
- package/dist/offline/create-offline-store.cjs +1 -1
- package/dist/offline/create-offline-store.cjs.map +1 -1
- package/dist/offline/create-offline-store.js +29 -25
- package/dist/offline/create-offline-store.js.map +1 -1
- package/dist/query/QueryProvider.cjs +1 -1
- package/dist/query/QueryProvider.cjs.map +1 -1
- package/dist/query/QueryProvider.js +13 -11
- package/dist/query/QueryProvider.js.map +1 -1
- package/dist/query/foreign-client-warning.cjs +2 -0
- package/dist/query/foreign-client-warning.cjs.map +1 -0
- package/dist/query/foreign-client-warning.js +12 -0
- package/dist/query/foreign-client-warning.js.map +1 -0
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +695 -41
- package/dist/tempest-react-sdk.js +52 -46
- package/dist/utils/duplicate-instance.cjs +2 -0
- package/dist/utils/duplicate-instance.cjs.map +1 -0
- package/dist/utils/duplicate-instance.js +6 -0
- package/dist/utils/duplicate-instance.js.map +1 -0
- package/dist/utils/format.cjs +1 -1
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.js +8 -3
- package/dist/utils/format.js.map +1 -1
- package/dist/webrtc/opus-sdp.cjs +3 -0
- package/dist/webrtc/opus-sdp.cjs.map +1 -0
- package/dist/webrtc/opus-sdp.js +94 -0
- package/dist/webrtc/opus-sdp.js.map +1 -0
- package/dist/webrtc/sender-bitrate.cjs +2 -0
- package/dist/webrtc/sender-bitrate.cjs.map +1 -0
- package/dist/webrtc/sender-bitrate.js +15 -0
- package/dist/webrtc/sender-bitrate.js.map +1 -0
- package/dist/ws/create-web-socket.cjs +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js +123 -47
- package/dist/ws/create-web-socket.js.map +1 -1
- package/dist/ws/resilience.cjs +2 -0
- package/dist/ws/resilience.cjs.map +1 -0
- package/dist/ws/resilience.js +21 -0
- package/dist/ws/resilience.js.map +1 -0
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +37 -23
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +1 -1
|
@@ -1059,6 +1059,88 @@ export declare type AsyncStatus = "idle" | "pending" | "success" | "error";
|
|
|
1059
1059
|
*/
|
|
1060
1060
|
export declare const AUDIO_MIME_CANDIDATES: readonly string[];
|
|
1061
1061
|
|
|
1062
|
+
/** A running mix. */
|
|
1063
|
+
export declare interface AudioBus {
|
|
1064
|
+
/**
|
|
1065
|
+
* Play a stream through the shared mix.
|
|
1066
|
+
*
|
|
1067
|
+
* @param stream - The stream to play. Only its first audio track is used.
|
|
1068
|
+
* @param options - `gain` is the initial multiplier, default `1`.
|
|
1069
|
+
* @returns A handle to adjust or detach this source.
|
|
1070
|
+
*/
|
|
1071
|
+
attach: (stream: MediaStream, options?: {
|
|
1072
|
+
gain?: number;
|
|
1073
|
+
}) => AudioBusHandle;
|
|
1074
|
+
/** Scale every source, on top of its own gain. */
|
|
1075
|
+
setMasterGain: (gain: number) => void;
|
|
1076
|
+
/** Current master gain, after clamping. */
|
|
1077
|
+
readonly masterGain: number;
|
|
1078
|
+
/**
|
|
1079
|
+
* Route the whole mix to one output device.
|
|
1080
|
+
*
|
|
1081
|
+
* @param deviceId - Device id from `useMediaDevices().audioOutputs`, or `""`
|
|
1082
|
+
* for the system default.
|
|
1083
|
+
* @returns `false` when the engine cannot route audio, or the device is gone.
|
|
1084
|
+
*/
|
|
1085
|
+
setOutputDevice: (deviceId: string) => Promise<boolean>;
|
|
1086
|
+
/** Device id the mix is routed to. `""` is the system default. */
|
|
1087
|
+
readonly outputDevice: string;
|
|
1088
|
+
/**
|
|
1089
|
+
* Resume a context the browser started suspended.
|
|
1090
|
+
*
|
|
1091
|
+
* Autoplay policy suspends a context created outside a user gesture, and a
|
|
1092
|
+
* suspended context is silent with no error anywhere. Call this from the
|
|
1093
|
+
* click that starts playback.
|
|
1094
|
+
*/
|
|
1095
|
+
resume: () => Promise<void>;
|
|
1096
|
+
/**
|
|
1097
|
+
* Detach everything and close the context this bus created.
|
|
1098
|
+
*
|
|
1099
|
+
* Idempotent, and the bus stays callable afterwards: `attach` hands back an
|
|
1100
|
+
* inert handle instead of throwing. That is not politeness — creating a node
|
|
1101
|
+
* on a closed `AudioContext` throws `InvalidStateError`, and the stream that
|
|
1102
|
+
* arrives late is the normal case (a WebRTC `ontrack` firing after the
|
|
1103
|
+
* component that owned the bus went away).
|
|
1104
|
+
*/
|
|
1105
|
+
close: () => void;
|
|
1106
|
+
/** Whether this browser gave us a Web Audio graph at all. */
|
|
1107
|
+
readonly supported: boolean;
|
|
1108
|
+
/** Whether this browser can route the mix to a chosen output device. */
|
|
1109
|
+
readonly canSelectOutput: boolean;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/** One source attached to the bus. */
|
|
1113
|
+
export declare interface AudioBusHandle {
|
|
1114
|
+
/**
|
|
1115
|
+
* Set this source's gain, where `1` is the level it arrived at.
|
|
1116
|
+
*
|
|
1117
|
+
* Values above `1` are the point of the whole graph: `element.volume` is
|
|
1118
|
+
* clamped at `1`, so a quiet talker could only ever be attenuated — the one
|
|
1119
|
+
* correction nobody needs.
|
|
1120
|
+
*/
|
|
1121
|
+
setGain: (gain: number) => void;
|
|
1122
|
+
/** Current gain, after clamping. */
|
|
1123
|
+
readonly gain: number;
|
|
1124
|
+
/** Detach this source and release its nodes. The bus stays up. */
|
|
1125
|
+
stop: () => void;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/** Options for {@link createAudioBus}. */
|
|
1129
|
+
export declare interface AudioBusOptions {
|
|
1130
|
+
/** Ceiling for every gain on this bus. Default {@link DEFAULT_MAX_GAIN}. */
|
|
1131
|
+
maxGain?: number;
|
|
1132
|
+
/** Override the master limiter, or pass `false` to run without one. */
|
|
1133
|
+
limiter?: Partial<LimiterSettings> | false;
|
|
1134
|
+
/**
|
|
1135
|
+
* Reuse an existing `AudioContext` instead of creating one.
|
|
1136
|
+
*
|
|
1137
|
+
* Browsers cap the number of live contexts (Chrome allows around six), so a
|
|
1138
|
+
* page that already has one — a level meter, a player — should hand it over
|
|
1139
|
+
* rather than open a second.
|
|
1140
|
+
*/
|
|
1141
|
+
context?: AudioContext;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1062
1144
|
/**
|
|
1063
1145
|
* Playback transport for one clip: play/pause, a seek bar, elapsed and total time.
|
|
1064
1146
|
*
|
|
@@ -2910,6 +2992,34 @@ export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value
|
|
|
2910
2992
|
*/
|
|
2911
2993
|
export declare function createApiClient(config: ApiClientConfig): ApiClient;
|
|
2912
2994
|
|
|
2995
|
+
/**
|
|
2996
|
+
* Mix several streams into one output, with gain above 100% and a master limiter.
|
|
2997
|
+
*
|
|
2998
|
+
* Three things make this a graph instead of a few `<audio>` elements:
|
|
2999
|
+
*
|
|
3000
|
+
* 1. **`element.volume` is clamped at `1`.** A participant who speaks too quietly
|
|
3001
|
+
* can only be turned *down* — the one correction nobody needs. A `GainNode`
|
|
3002
|
+
* has no ceiling, so this bus takes one (`maxGain`, default 3).
|
|
3003
|
+
* 2. **Clipping is a property of the sum.** Three sources at 200% each are clean
|
|
3004
|
+
* alone and distort the instant they play together. A per-source limiter
|
|
3005
|
+
* cannot see that; the one after the mix can, which is where this puts it.
|
|
3006
|
+
* 3. **`setSinkId` lives on the element, not on the context.** Sending the mix to
|
|
3007
|
+
* a headset while the rest of the system keeps the speakers is only reachable
|
|
3008
|
+
* by leaving through a `MediaStreamAudioDestinationNode` into a real
|
|
3009
|
+
* `<audio>`. `AudioContext.setSinkId` has far thinner support.
|
|
3010
|
+
*
|
|
3011
|
+
* @param options - See {@link AudioBusOptions}.
|
|
3012
|
+
* @returns The bus. On an engine with no Web Audio it is inert but callable, and
|
|
3013
|
+
* `supported` is `false` — a page without sound beats a page that throws.
|
|
3014
|
+
*
|
|
3015
|
+
* @example
|
|
3016
|
+
* const bus = createAudioBus({ maxGain: 3 });
|
|
3017
|
+
* const handle = bus.attach(remoteStream, { gain: 1 });
|
|
3018
|
+
* handle.setGain(2.4); // above 1 — the point of the whole thing
|
|
3019
|
+
* await bus.setOutputDevice(headsetId);
|
|
3020
|
+
*/
|
|
3021
|
+
export declare function createAudioBus({ maxGain, limiter: limiterOptions, context: injectedContext, }?: AudioBusOptions): AudioBus;
|
|
3022
|
+
|
|
2913
3023
|
/**
|
|
2914
3024
|
* Create an isolated audio player that tracks a single "current" clip.
|
|
2915
3025
|
* Multiple players coexist independently; use this when several layers of UI
|
|
@@ -3320,6 +3430,60 @@ export declare interface CreateLoggerOptions {
|
|
|
3320
3430
|
*/
|
|
3321
3431
|
export declare function createMediaRecorder(stream: MediaStream, options: MediaRecordingOptions): MediaRecorderHandle;
|
|
3322
3432
|
|
|
3433
|
+
/**
|
|
3434
|
+
* Build several {@link OfflineStore}s that share one IndexedDB database.
|
|
3435
|
+
*
|
|
3436
|
+
* `createOfflineStore` gives each store a database of its own, which is the
|
|
3437
|
+
* right shape for one isolated cache. It is the wrong shape as soon as the
|
|
3438
|
+
* tables belong together: chats and their messages, an entity and its drafts,
|
|
3439
|
+
* anything you would read or clear as a unit. Splitting those across databases
|
|
3440
|
+
* costs a real transaction — Dexie runs one atomically only *within* a single
|
|
3441
|
+
* database — and it splits the version bump for a related change across two
|
|
3442
|
+
* places.
|
|
3443
|
+
*
|
|
3444
|
+
* This keeps them in one database at one version, so a schema change is one
|
|
3445
|
+
* bump and a multi-table write can be wrapped in `db.transaction(...)`.
|
|
3446
|
+
*
|
|
3447
|
+
* Stores are reached through `store<TItem>(name)` rather than a prebuilt map.
|
|
3448
|
+
* That is forced rather than chosen: Dexie's `Table<T>` expands `UpdateSpec<T>`
|
|
3449
|
+
* over the keys of `T`, so building `{ [K in keyof TSchema]: OfflineStore<…> }`
|
|
3450
|
+
* — or even naming `OfflineStore<TSchema[K], string>` inside the accessor —
|
|
3451
|
+
* makes the checker answer TS2589 ("excessively deep"). Taking the record type
|
|
3452
|
+
* as a parameter keeps it a plain type argument, which resolves fine. The table
|
|
3453
|
+
* name is still checked against the declared schema.
|
|
3454
|
+
*
|
|
3455
|
+
* The store surface is identical to `createOfflineStore`; only ownership of the
|
|
3456
|
+
* database changes. `ownerField` is set per table, since a database commonly
|
|
3457
|
+
* mixes per-user data with shared data.
|
|
3458
|
+
*
|
|
3459
|
+
* @param config - Database name, version, and one entry per table.
|
|
3460
|
+
* @returns A `store(name)` accessor, the shared Dexie instance, and a
|
|
3461
|
+
* `destroy()` that drops the database.
|
|
3462
|
+
*
|
|
3463
|
+
* @example
|
|
3464
|
+
* type Chat = { id: string; service_id: string; updated_at: string };
|
|
3465
|
+
* type Message = { id: string; service_chat_id: string; created_at: string };
|
|
3466
|
+
*
|
|
3467
|
+
* const database = createOfflineDatabase<{ chats: Chat; messages: Message }>({
|
|
3468
|
+
* databaseName: "ChatDatabase",
|
|
3469
|
+
* version: 1,
|
|
3470
|
+
* tables: {
|
|
3471
|
+
* chats: { indexes: "&id, service_id, updated_at" },
|
|
3472
|
+
* messages: { indexes: "&id, service_chat_id, created_at" },
|
|
3473
|
+
* },
|
|
3474
|
+
* });
|
|
3475
|
+
*
|
|
3476
|
+
* const chats = database.store<Chat>("chats");
|
|
3477
|
+
* const messages = database.store<Message>("messages");
|
|
3478
|
+
*
|
|
3479
|
+
* // Both tables in one atomic transaction — impossible across two databases.
|
|
3480
|
+
* await database.db.transaction("rw", chats.raw, messages.raw, async () => {
|
|
3481
|
+
* await chats.put(chat);
|
|
3482
|
+
* await messages.bulkPut(pending);
|
|
3483
|
+
* });
|
|
3484
|
+
*/
|
|
3485
|
+
export declare function createOfflineDatabase<TSchema extends OfflineSchema>(config: OfflineDatabaseConfig<TSchema>): OfflineDatabase<TSchema>;
|
|
3486
|
+
|
|
3323
3487
|
/**
|
|
3324
3488
|
* Build a typed IndexedDB-backed store using Dexie. Optionally scope every
|
|
3325
3489
|
* operation by an `ownerField` (useful for multi-user SSE history, drafts,
|
|
@@ -3561,14 +3725,44 @@ export declare function createQueryKeys<TKey extends string, TEntries extends Re
|
|
|
3561
3725
|
* at once, all of them share the same in-flight `refresh()` promise instead
|
|
3562
3726
|
* of triggering N parallel refreshes.
|
|
3563
3727
|
*
|
|
3728
|
+
* **In-flight sharing alone does not collapse a burst.** A page that fires
|
|
3729
|
+
* several requests at once gets several 401s back, but they do not land inside
|
|
3730
|
+
* one window: the stragglers arrive after the first refresh already resolved,
|
|
3731
|
+
* find no promise to join, and each starts another one — rotating a token that
|
|
3732
|
+
* is already fresh. Measured against a mock backend, five concurrent expired
|
|
3733
|
+
* requests took two refreshes, not one.
|
|
3734
|
+
*
|
|
3735
|
+
* Pass `getToken` to close that gap. The queue remembers the token its last
|
|
3736
|
+
* refresh produced, and a call that finds that same token still in place returns
|
|
3737
|
+
* immediately, because the refresh it was about to perform has already happened.
|
|
3738
|
+
* The same five requests then take exactly one refresh, and so do twenty.
|
|
3739
|
+
*
|
|
3740
|
+
* @param refresh - Performs the refresh and installs the new credentials.
|
|
3741
|
+
* @param options - Optional token reader that enables already-refreshed
|
|
3742
|
+
* detection.
|
|
3743
|
+
* @returns A function that refreshes at most once per rotation.
|
|
3744
|
+
*
|
|
3564
3745
|
* @example
|
|
3565
|
-
* const refresh = createRefreshQueue(() => AuthService.refresh()
|
|
3746
|
+
* const refresh = createRefreshQueue(() => AuthService.refresh(), {
|
|
3747
|
+
* getToken: () => useAuthStore.getState().token,
|
|
3748
|
+
* });
|
|
3566
3749
|
*
|
|
3567
3750
|
* // In every request that hits 401:
|
|
3568
3751
|
* await refresh();
|
|
3569
3752
|
* // ...retry the original request
|
|
3570
3753
|
*/
|
|
3571
|
-
export declare function createRefreshQueue(refresh: () => Promise<void
|
|
3754
|
+
export declare function createRefreshQueue(refresh: () => Promise<void>, options?: CreateRefreshQueueOptions): () => Promise<void>;
|
|
3755
|
+
|
|
3756
|
+
export declare interface CreateRefreshQueueOptions {
|
|
3757
|
+
/**
|
|
3758
|
+
* Reads the credential the refresh installs — typically the access token.
|
|
3759
|
+
*
|
|
3760
|
+
* Supplying it makes the queue skip a refresh whose work another caller has
|
|
3761
|
+
* already done. Without it, only calls that literally overlap in time are
|
|
3762
|
+
* collapsed.
|
|
3763
|
+
*/
|
|
3764
|
+
getToken?: () => string | null | undefined;
|
|
3765
|
+
}
|
|
3572
3766
|
|
|
3573
3767
|
/**
|
|
3574
3768
|
* Chunked, resumable upload speaking the **tus 1.0.0** protocol (core plus the
|
|
@@ -3931,12 +4125,29 @@ export declare interface CreateThemeOptions {
|
|
|
3931
4125
|
export declare function createVideoRecorder(stream: MediaStream, options?: VideoRecorderOptions): VideoRecorderHandle;
|
|
3932
4126
|
|
|
3933
4127
|
/**
|
|
3934
|
-
* Open a WebSocket
|
|
3935
|
-
* heartbeat pings
|
|
4128
|
+
* Open a WebSocket that survives a bad network: exponential backoff with jitter,
|
|
4129
|
+
* a handshake timeout, a silence watchdog, optional heartbeat pings and typed
|
|
4130
|
+
* JSON parsing.
|
|
4131
|
+
*
|
|
4132
|
+
* Three failure modes are covered that an event-driven retry loop misses on its
|
|
4133
|
+
* own, because none of them fire an event: a handshake that hangs instead of
|
|
4134
|
+
* failing, an open socket whose link died mid-flight, and a device with its
|
|
4135
|
+
* radio off burning the retry budget. See `handshakeTimeout`, `silenceTimeout`
|
|
4136
|
+
* and `waitForOnline`.
|
|
3936
4137
|
*
|
|
3937
4138
|
* @param url - Full ws:// or wss:// URL.
|
|
3938
4139
|
* @param options - Connection configuration and callbacks.
|
|
3939
|
-
* @returns Controller exposing `send`, `close`, `reconnect`,
|
|
4140
|
+
* @returns Controller exposing `send`, `close`, `reconnect`, `setSilenceTimeout`,
|
|
4141
|
+
* `opened` and `status`.
|
|
4142
|
+
*
|
|
4143
|
+
* @example
|
|
4144
|
+
* const socket = createWebSocket(url, {
|
|
4145
|
+
* silenceTimeout: 75_000,
|
|
4146
|
+
* onReconnecting: (n, total) => setBanner(`Reconectando ${n}/${total}…`),
|
|
4147
|
+
* onReconnected: () => refetchEverything(),
|
|
4148
|
+
* onLost: (reason) => setBanner(reason === "rejected" ? "Acesso negado" : "Sem conexão"),
|
|
4149
|
+
* });
|
|
4150
|
+
* await socket.opened;
|
|
3940
4151
|
*/
|
|
3941
4152
|
export declare function createWebSocket<T = unknown>(url: string, options?: CreateWebSocketOptions<T>): WebSocketController;
|
|
3942
4153
|
|
|
@@ -3949,6 +4160,50 @@ export declare interface CreateWebSocketOptions<T> {
|
|
|
3949
4160
|
initialBackoff?: number;
|
|
3950
4161
|
/** Maximum backoff (ms). Default: 30000. */
|
|
3951
4162
|
maxBackoff?: number;
|
|
4163
|
+
/**
|
|
4164
|
+
* Fraction of each backoff delay added at random, 0–1. Default: 0.3.
|
|
4165
|
+
*
|
|
4166
|
+
* Matters when the *server* is what went down: every client retries on the
|
|
4167
|
+
* same schedule, so the box comes back up into a synchronized stampede. Pass
|
|
4168
|
+
* `0` for a fixed schedule.
|
|
4169
|
+
*/
|
|
4170
|
+
jitter?: number;
|
|
4171
|
+
/**
|
|
4172
|
+
* How long one handshake may stay in `CONNECTING` before the attempt is
|
|
4173
|
+
* abandoned and retried (ms). Default: 8000. Pass 0 to disable.
|
|
4174
|
+
*
|
|
4175
|
+
* A `WebSocket` that cannot reach its server does not necessarily fail: it
|
|
4176
|
+
* sits in `CONNECTING` firing neither `open` nor `close` nor `error`. A retry
|
|
4177
|
+
* chain built only on those events stops on its first hung attempt and never
|
|
4178
|
+
* moves again — and hung, rather than refused, is precisely how a bad mobile
|
|
4179
|
+
* link behaves, which is the case reconnection exists for.
|
|
4180
|
+
*/
|
|
4181
|
+
handshakeTimeout?: number;
|
|
4182
|
+
/**
|
|
4183
|
+
* Silence tolerated on an open socket before the link is treated as dead (ms).
|
|
4184
|
+
* Default: 0 (off).
|
|
4185
|
+
*
|
|
4186
|
+
* The socket only reports a connection that closes cleanly. A link that dies
|
|
4187
|
+
* mid-flight leaves `readyState` at `OPEN` on this side with nothing ever
|
|
4188
|
+
* arriving again, so silence is the only symptom available. The timer is
|
|
4189
|
+
* re-armed by **any** inbound frame, not just by pings — traffic is traffic.
|
|
4190
|
+
*
|
|
4191
|
+
* Set it to a comfortable multiple of the server's ping interval (2.5× is a
|
|
4192
|
+
* good default) so one dropped ping is not mistaken for an outage. When the
|
|
4193
|
+
* server announces its own interval in the handshake, feed that back with
|
|
4194
|
+
* {@link WebSocketController.setSilenceTimeout} instead of hard-coding the
|
|
4195
|
+
* value on both ends.
|
|
4196
|
+
*/
|
|
4197
|
+
silenceTimeout?: number;
|
|
4198
|
+
/**
|
|
4199
|
+
* Suspend the retry schedule while `navigator.onLine` is false, and resume on
|
|
4200
|
+
* the `online` event. Default: true.
|
|
4201
|
+
*
|
|
4202
|
+
* Burning retries against a radio that is switched off is how a phone
|
|
4203
|
+
* exhausts its budget inside a tunnel and gives up exactly when it comes out
|
|
4204
|
+
* the other side.
|
|
4205
|
+
*/
|
|
4206
|
+
waitForOnline?: boolean;
|
|
3952
4207
|
/**
|
|
3953
4208
|
* Ping interval (ms). When set, the client sends `pingPayload` periodically
|
|
3954
4209
|
* to keep the socket alive. Default: 0 (disabled).
|
|
@@ -3989,6 +4244,34 @@ export declare interface CreateWebSocketOptions<T> {
|
|
|
3989
4244
|
onClose?: (event: CloseEvent) => void;
|
|
3990
4245
|
onError?: (event: Event) => void;
|
|
3991
4246
|
onStatusChange?: (status: WebSocketStatus) => void;
|
|
4247
|
+
/**
|
|
4248
|
+
* A retry has been scheduled. `attempt` is 1-based, `total` is `maxRetries`.
|
|
4249
|
+
*
|
|
4250
|
+
* Reconnecting is not an error and reads badly as one: announcing every
|
|
4251
|
+
* attempt puts a fresh "the connection dropped" in front of someone whose
|
|
4252
|
+
* session is in the middle of coming back on its own. Show a quiet
|
|
4253
|
+
* reconnecting state here and treat {@link CreateWebSocketOptions.onLost} as
|
|
4254
|
+
* the failure.
|
|
4255
|
+
*/
|
|
4256
|
+
onReconnecting?: (attempt: number, total: number) => void;
|
|
4257
|
+
/**
|
|
4258
|
+
* The socket is back up after at least one retry.
|
|
4259
|
+
*
|
|
4260
|
+
* Nothing is resumed for you: a server that keys state by connection sees a
|
|
4261
|
+
* brand-new client, so this is where the caller re-subscribes, re-joins or
|
|
4262
|
+
* refetches whatever the gap invalidated.
|
|
4263
|
+
*/
|
|
4264
|
+
onReconnected?: () => void;
|
|
4265
|
+
/**
|
|
4266
|
+
* No further attempt will be made — `"rejected"` when the server refused the
|
|
4267
|
+
* client outright (close code 4400–4499, minus the 4408 heartbeat timeout),
|
|
4268
|
+
* `"exhausted"` when the schedule ran out.
|
|
4269
|
+
*
|
|
4270
|
+
* This is the one that deserves UI, because it is the only state the caller
|
|
4271
|
+
* can act on: offer a "try again" that calls
|
|
4272
|
+
* {@link WebSocketController.reconnect}.
|
|
4273
|
+
*/
|
|
4274
|
+
onLost?: (reason: WebSocketLostReason) => void;
|
|
3992
4275
|
}
|
|
3993
4276
|
|
|
3994
4277
|
/**
|
|
@@ -4616,6 +4899,9 @@ export declare const DEFAULT_CHUNK_SIZE: number;
|
|
|
4616
4899
|
*/
|
|
4617
4900
|
export declare const DEFAULT_CIRCUITY_FACTOR = 1.3;
|
|
4618
4901
|
|
|
4902
|
+
/** Default ceiling for a per-source or master gain, as a multiplier. */
|
|
4903
|
+
export declare const DEFAULT_MAX_GAIN = 3;
|
|
4904
|
+
|
|
4619
4905
|
/**
|
|
4620
4906
|
* Per-mode multipliers applied to the car duration. Mirrors
|
|
4621
4907
|
* `DEFAULT_MODE_DURATION_FACTORS` from `tempest-fastapi-sdk` — motorcycles are
|
|
@@ -4658,6 +4944,9 @@ export declare function defineRoutes(routes: TempestRouteObject[]): TempestRoute
|
|
|
4658
4944
|
*
|
|
4659
4945
|
* The funnel, in order:
|
|
4660
4946
|
*
|
|
4947
|
+
* 0. `codes[error.code]` — the sentence you wrote for that exact backend case.
|
|
4948
|
+
* Checked first because nothing the funnel derives can beat it, and because a
|
|
4949
|
+
* request that never landed carries no `code` for it to shadow.
|
|
4661
4950
|
* 1. A request that never reached the server — `status === 0`, or a non-API
|
|
4662
4951
|
* error thrown while the browser reports itself offline — produces the
|
|
4663
4952
|
* offline sentence. This is the step apps skip, and skipping it renders
|
|
@@ -4670,7 +4959,8 @@ export declare function defineRoutes(routes: TempestRouteObject[]): TempestRoute
|
|
|
4670
4959
|
* names internals. The per-field messages stay on `fields`, where a form can
|
|
4671
4960
|
* attach them to the inputs that failed.
|
|
4672
4961
|
* 3. The backend's own `detail`, which is the most specific thing available and
|
|
4673
|
-
* is already written for a person
|
|
4962
|
+
* is already written for a person — unless `useDetail: false` says that text
|
|
4963
|
+
* is for developers.
|
|
4674
4964
|
* 4. `fallback`, with `(HTTP <status>)` appended when a status is known, so the
|
|
4675
4965
|
* screenshot in the support ticket carries the one fact a developer needs.
|
|
4676
4966
|
*
|
|
@@ -4683,12 +4973,53 @@ export declare function defineRoutes(routes: TempestRouteObject[]): TempestRoute
|
|
|
4683
4973
|
* toast(describeApiError(error, "Não foi possível salvar o pedido"));
|
|
4684
4974
|
* }
|
|
4685
4975
|
*
|
|
4976
|
+
* @example
|
|
4977
|
+
* catch (error) {
|
|
4978
|
+
* toast(
|
|
4979
|
+
* describeApiError(error, "Não foi possível se candidatar", {
|
|
4980
|
+
* codes: {
|
|
4981
|
+
* SERVICE_FULL: "Este serviço atingiu o limite de vagas.",
|
|
4982
|
+
* CANDIDATE_ALREADY_EXISTS: "Você já se candidatou a este serviço.",
|
|
4983
|
+
* },
|
|
4984
|
+
* useDetail: false,
|
|
4985
|
+
* }),
|
|
4986
|
+
* );
|
|
4987
|
+
* }
|
|
4988
|
+
*
|
|
4686
4989
|
* @param error - The caught value, of any shape.
|
|
4687
4990
|
* @param fallback - What to say when the error carries nothing better.
|
|
4688
|
-
* @param
|
|
4991
|
+
* @param options - A `codes` catalog, `useDetail`, and overrides for the fixed
|
|
4992
|
+
* sentences.
|
|
4689
4993
|
* @returns A sentence to show the user.
|
|
4690
4994
|
*/
|
|
4691
|
-
export declare function describeApiError(error: unknown, fallback: string,
|
|
4995
|
+
export declare function describeApiError(error: unknown, fallback: string, options?: DescribeApiErrorOptions): string;
|
|
4996
|
+
|
|
4997
|
+
/**
|
|
4998
|
+
* Everything {@link describeApiError} accepts beyond the error and the fallback.
|
|
4999
|
+
*
|
|
5000
|
+
* Extends the fixed sentences rather than sitting beside them, so a caller that
|
|
5001
|
+
* already passed `{ offline, validation }` keeps compiling untouched.
|
|
5002
|
+
*/
|
|
5003
|
+
export declare interface DescribeApiErrorOptions extends Partial<ApiErrorStrings> {
|
|
5004
|
+
/**
|
|
5005
|
+
* Maps the backend's programmatic `code` to a sentence in your language.
|
|
5006
|
+
*
|
|
5007
|
+
* The client already surfaces `code` on `ApiError`, but without this every
|
|
5008
|
+
* app writes the same `switch` over it. A hit here wins over every other
|
|
5009
|
+
* step: it is the only sentence written for that exact case, by someone who
|
|
5010
|
+
* knew both the backend contract and the screen it lands on.
|
|
5011
|
+
*/
|
|
5012
|
+
codes?: Readonly<Record<string, string>>;
|
|
5013
|
+
/**
|
|
5014
|
+
* Whether the backend's `detail` may be shown when no `code` matched.
|
|
5015
|
+
* Default `true`.
|
|
5016
|
+
*
|
|
5017
|
+
* Set it to `false` when `detail` is written for developers rather than
|
|
5018
|
+
* users, or when it could echo internals — the result is then always either
|
|
5019
|
+
* a sentence you wrote or the fallback.
|
|
5020
|
+
*/
|
|
5021
|
+
useDetail?: boolean;
|
|
5022
|
+
}
|
|
4692
5023
|
|
|
4693
5024
|
/**
|
|
4694
5025
|
* One filter, in words: `"Status é Pago"`.
|
|
@@ -5667,30 +5998,41 @@ export declare function formatPercent(value: number): string;
|
|
|
5667
5998
|
/**
|
|
5668
5999
|
* Apply the Brazilian phone mask `(XX) XXXXX-XXXX` or `(XX) XXXX-XXXX`.
|
|
5669
6000
|
*
|
|
6001
|
+
* By default the grouping is decided by **length**, which is what a field
|
|
6002
|
+
* accepting both landlines and mobiles needs.
|
|
6003
|
+
*
|
|
6004
|
+
* `mobile: true` is for a field that only accepts mobile numbers, and it exists
|
|
6005
|
+
* because the default is wrong as an as-you-type mask there. Reading anything up
|
|
6006
|
+
* to ten digits as a landline puts the hyphen after the fourth subscriber digit,
|
|
6007
|
+
* so a half-typed mobile renders `(11) 9123-4`; it only becomes `(11) 91234-5`
|
|
6008
|
+
* once the eleventh digit lands. The separator visibly jumps backwards while the
|
|
6009
|
+
* user is still typing. With `mobile`, the same input reads `(11) 91234` and the
|
|
6010
|
+
* hyphen never moves. It also inserts the leading `9` every Brazilian mobile
|
|
6011
|
+
* carries, so a ten-digit number gets corrected rather than masked as a landline.
|
|
6012
|
+
*
|
|
5670
6013
|
* @param value - Raw digits or partially masked string.
|
|
6014
|
+
* @param options - Masking options.
|
|
5671
6015
|
* @returns Masked phone string.
|
|
5672
|
-
*/
|
|
5673
|
-
export declare function formatPhone(value: string): string;
|
|
5674
|
-
|
|
5675
|
-
/**
|
|
5676
|
-
* Glue between `react-hook-form` `Controller` and the SDK's controlled
|
|
5677
|
-
* components. Wraps any control that accepts `{ value, onChange, label,
|
|
5678
|
-
* error }` and routes RHF state into it — eliminating the per-field
|
|
5679
|
-
* `<Controller render={...} />` boilerplate.
|
|
5680
6016
|
*
|
|
5681
6017
|
* @example
|
|
5682
|
-
*
|
|
5683
|
-
*
|
|
5684
|
-
*
|
|
5685
|
-
* <FormField name="email" label="Email" required>
|
|
5686
|
-
* <Input type="email" />
|
|
5687
|
-
* </FormField>
|
|
5688
|
-
* <FormField name="cep" label="CEP">
|
|
5689
|
-
* <CEPInput />
|
|
5690
|
-
* </FormField>
|
|
5691
|
-
* </Form>
|
|
5692
|
-
* </FormProvider>;
|
|
6018
|
+
* formatPhone("1191234"); // "(11) 9123-4"
|
|
6019
|
+
* formatPhone("1191234", { mobile: true }); // "(11) 91234"
|
|
6020
|
+
* formatPhone("1112345678", { mobile: true }); // "(11) 91234-5678" — 9 inserted
|
|
5693
6021
|
*/
|
|
6022
|
+
export declare function formatPhone(value: string, options?: FormatPhoneOptions): string;
|
|
6023
|
+
|
|
6024
|
+
export declare interface FormatPhoneOptions {
|
|
6025
|
+
/**
|
|
6026
|
+
* Treat the number as a mobile line: insert the mandatory `9` after the area
|
|
6027
|
+
* code when it is missing, and group the subscriber part `5+4` from the
|
|
6028
|
+
* first digit typed instead of waiting for the eleventh.
|
|
6029
|
+
*
|
|
6030
|
+
* Default `false`, which keeps the length-based behaviour: `4+4` up to ten
|
|
6031
|
+
* digits, `5+4` at eleven.
|
|
6032
|
+
*/
|
|
6033
|
+
mobile?: boolean;
|
|
6034
|
+
}
|
|
6035
|
+
|
|
5694
6036
|
export declare function FormField<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>>({ name, label, helperText, required, control, children }: FormFieldProps<TValues, TName>): JSX.Element;
|
|
5695
6037
|
|
|
5696
6038
|
export declare interface FormFieldChildProps {
|
|
@@ -6006,6 +6348,17 @@ export { HashRouter }
|
|
|
6006
6348
|
*/
|
|
6007
6349
|
export declare function haversineKm(origin: Coordinate, destination: Coordinate): number;
|
|
6008
6350
|
|
|
6351
|
+
/**
|
|
6352
|
+
* Heartbeat timeout, which sits inside the rejection range but is not one.
|
|
6353
|
+
*
|
|
6354
|
+
* `tempest-fastapi-sdk` closes with 4408 when no `pong` arrived within
|
|
6355
|
+
* `WS_HEARTBEAT_TIMEOUT_SECONDS`. That is the *link* failing, not the server
|
|
6356
|
+
* refusing the peer — exactly the case reconnection exists for. Treating the
|
|
6357
|
+
* whole 4400–4499 range as fatal, which is the obvious reading, makes one
|
|
6358
|
+
* missed pong permanent.
|
|
6359
|
+
*/
|
|
6360
|
+
export declare const HEARTBEAT_CLOSE_CODE = 4408;
|
|
6361
|
+
|
|
6009
6362
|
/** Convert a hex color to OKLCH. */
|
|
6010
6363
|
export declare function hexToOklch(hex: string): Oklch;
|
|
6011
6364
|
|
|
@@ -6736,6 +7089,18 @@ export declare function isPlatformAuthenticatorAvailable(): Promise<boolean>;
|
|
|
6736
7089
|
*/
|
|
6737
7090
|
export declare function isPushSupported(): boolean;
|
|
6738
7091
|
|
|
7092
|
+
/**
|
|
7093
|
+
* Whether a close code means the server refused this client for good.
|
|
7094
|
+
*
|
|
7095
|
+
* @param code - The `CloseEvent.code`.
|
|
7096
|
+
* @returns `true` when reconnecting can only reproduce the refusal.
|
|
7097
|
+
*
|
|
7098
|
+
* @example
|
|
7099
|
+
* isRejectionCloseCode(4401); // true — unauthorized
|
|
7100
|
+
* isRejectionCloseCode(4408); // false — heartbeat timeout, retry it
|
|
7101
|
+
*/
|
|
7102
|
+
export declare function isRejectionCloseCode(code: number): boolean;
|
|
7103
|
+
|
|
6739
7104
|
/**
|
|
6740
7105
|
* Whether an HTTP status describes a condition a replay can plausibly fix.
|
|
6741
7106
|
*
|
|
@@ -7149,6 +7514,20 @@ export declare interface LightboxProps {
|
|
|
7149
7514
|
className?: string;
|
|
7150
7515
|
}
|
|
7151
7516
|
|
|
7517
|
+
/** Shape of the master limiter. Matches `DynamicsCompressorNode`'s params. */
|
|
7518
|
+
export declare interface LimiterSettings {
|
|
7519
|
+
/** dBFS above which the compressor starts working. */
|
|
7520
|
+
threshold: number;
|
|
7521
|
+
/** dB range over which the curve bends. `0` is a hard knee. */
|
|
7522
|
+
knee: number;
|
|
7523
|
+
/** Input/output ratio above the threshold. 20 is limiting, not compression. */
|
|
7524
|
+
ratio: number;
|
|
7525
|
+
/** Seconds to clamp a peak. */
|
|
7526
|
+
attack: number;
|
|
7527
|
+
/** Seconds to let go. */
|
|
7528
|
+
release: number;
|
|
7529
|
+
}
|
|
7530
|
+
|
|
7152
7531
|
export { Link }
|
|
7153
7532
|
|
|
7154
7533
|
export declare interface ListOptions<TItem> {
|
|
@@ -8052,6 +8431,36 @@ export declare interface OAuthError {
|
|
|
8052
8431
|
raw?: unknown;
|
|
8053
8432
|
}
|
|
8054
8433
|
|
|
8434
|
+
export declare interface OfflineDatabase<TSchema extends OfflineSchema> {
|
|
8435
|
+
/**
|
|
8436
|
+
* The {@link OfflineStore} for one table.
|
|
8437
|
+
*
|
|
8438
|
+
* The name is checked against the declared schema; the record type is
|
|
8439
|
+
* supplied by the caller — `store<Chat>("chats")`. Deriving it from the
|
|
8440
|
+
* schema instead (`OfflineStore<TSchema[K], string>`) is what the shape
|
|
8441
|
+
* below documents as unavailable: Dexie's `Table<T>` expands `UpdateSpec<T>`
|
|
8442
|
+
* over the keys of `T`, and an unresolved indexed access there makes the
|
|
8443
|
+
* checker answer TS2589 no matter how the value is cast.
|
|
8444
|
+
*
|
|
8445
|
+
* Stores are created once and memoised, so repeated calls with the same
|
|
8446
|
+
* name return the same object.
|
|
8447
|
+
*/
|
|
8448
|
+
store: <TItem>(name: keyof TSchema & string) => OfflineStore<TItem, string>;
|
|
8449
|
+
/** The Dexie instance shared by every store. */
|
|
8450
|
+
db: default_2;
|
|
8451
|
+
/** Delete the whole database from the browser. */
|
|
8452
|
+
destroy: () => Promise<void>;
|
|
8453
|
+
}
|
|
8454
|
+
|
|
8455
|
+
export declare interface OfflineDatabaseConfig<TSchema extends OfflineSchema> {
|
|
8456
|
+
/** IndexedDB database name. */
|
|
8457
|
+
databaseName: string;
|
|
8458
|
+
/** Schema version. Bump when changing any table's indexes. */
|
|
8459
|
+
version: number;
|
|
8460
|
+
/** One entry per object store, all inside this single database. */
|
|
8461
|
+
tables: OfflineTablesConfig<TSchema>;
|
|
8462
|
+
}
|
|
8463
|
+
|
|
8055
8464
|
/**
|
|
8056
8465
|
* Fixed bar that appears while the browser is offline and, by default, flashes
|
|
8057
8466
|
* a brief confirmation when the connection returns. Backed by {@link useOnline}
|
|
@@ -8113,6 +8522,9 @@ export declare interface OfflineQueryPersistenceOptions {
|
|
|
8113
8522
|
throttleMs?: number;
|
|
8114
8523
|
}
|
|
8115
8524
|
|
|
8525
|
+
/** Maps each table name to the record type it stores. */
|
|
8526
|
+
export declare type OfflineSchema = Record<string, unknown>;
|
|
8527
|
+
|
|
8116
8528
|
export declare interface OfflineStore<TItem, TKey extends string | number> {
|
|
8117
8529
|
/** Insert or replace a record. */
|
|
8118
8530
|
put: (item: TItem, owner?: string) => Promise<TKey>;
|
|
@@ -8273,6 +8685,25 @@ export declare interface OfflineSyncConfig<TPayload, TRemote> {
|
|
|
8273
8685
|
broadcastChannelName?: string;
|
|
8274
8686
|
}
|
|
8275
8687
|
|
|
8688
|
+
export declare interface OfflineTableConfig<TItem> {
|
|
8689
|
+
/**
|
|
8690
|
+
* Dexie index definition for this table. Use `&` for a unique primary key,
|
|
8691
|
+
* e.g. `"&id, service_id, created_at"`.
|
|
8692
|
+
*/
|
|
8693
|
+
indexes: string;
|
|
8694
|
+
/** Property used as the primary key (default: `"id"`). */
|
|
8695
|
+
keyPath?: keyof TItem & string;
|
|
8696
|
+
/**
|
|
8697
|
+
* Optional owner scoping for this table. Set per table, since one database
|
|
8698
|
+
* commonly mixes scoped and unscoped data.
|
|
8699
|
+
*/
|
|
8700
|
+
ownerField?: keyof TItem & string;
|
|
8701
|
+
}
|
|
8702
|
+
|
|
8703
|
+
export declare type OfflineTablesConfig<TSchema extends OfflineSchema> = {
|
|
8704
|
+
[K in keyof TSchema]: OfflineTableConfig<TSchema[K]>;
|
|
8705
|
+
};
|
|
8706
|
+
|
|
8276
8707
|
/** A pan offset in frame pixels, measured from the centered position. */
|
|
8277
8708
|
declare interface Offset {
|
|
8278
8709
|
x: number;
|
|
@@ -8392,6 +8823,68 @@ export declare interface OpenModalOptions {
|
|
|
8392
8823
|
/** The operators a field offers. */
|
|
8393
8824
|
export declare function operatorsFor(field: FilterField): FilterOperator[];
|
|
8394
8825
|
|
|
8826
|
+
/**
|
|
8827
|
+
* @tempest-limits file-lines — parsing a session description, merging one
|
|
8828
|
+
* `fmtp` line and inserting a missing one are the same pass over the same
|
|
8829
|
+
* grammar; split apart, each half is a parser of half an SDP.
|
|
8830
|
+
*/
|
|
8831
|
+
/** What an Opus `fmtp` line can be asked to carry. Every field is optional. */
|
|
8832
|
+
export declare interface OpusProfile {
|
|
8833
|
+
/**
|
|
8834
|
+
* Ceiling the encoder is asked to respect, in bits per second.
|
|
8835
|
+
*
|
|
8836
|
+
* This describes what we want **to receive**. To cap what we *send*, use
|
|
8837
|
+
* `setSenderBitrate` — in a mesh that is the one that matters, because the
|
|
8838
|
+
* uplink carries one copy per participant.
|
|
8839
|
+
*/
|
|
8840
|
+
maxAverageBitrate?: number;
|
|
8841
|
+
/** Highest sample rate worth decoding, in Hz. `48000` for full band. */
|
|
8842
|
+
maxPlaybackRate?: number;
|
|
8843
|
+
/**
|
|
8844
|
+
* Two channels instead of one.
|
|
8845
|
+
*
|
|
8846
|
+
* Sets `stereo` **and** `sprop-stereo`, which point in opposite directions:
|
|
8847
|
+
* `stereo=1` asks the *remote* to send two channels, `sprop-stereo=1`
|
|
8848
|
+
* announces that *we* will. Setting only one leaves the link asymmetric,
|
|
8849
|
+
* which is the recurring reason "I asked for stereo and got mono".
|
|
8850
|
+
*/
|
|
8851
|
+
stereo?: boolean;
|
|
8852
|
+
/**
|
|
8853
|
+
* In-band forward error correction (`useinbandfec`).
|
|
8854
|
+
*
|
|
8855
|
+
* Rebuilds a lost packet from the next one, which keeps speech intelligible
|
|
8856
|
+
* on a lossy link — and smears music, since it spends bitrate on redundancy
|
|
8857
|
+
* instead of detail.
|
|
8858
|
+
*/
|
|
8859
|
+
fec?: boolean;
|
|
8860
|
+
/**
|
|
8861
|
+
* Discontinuous transmission (`usedtx`): stop sending during silence.
|
|
8862
|
+
*
|
|
8863
|
+
* Saves uplink in a mesh, at the cost of clipping the first instant after a
|
|
8864
|
+
* pause. Wrong for music and for a shared screen, where the quiet passages
|
|
8865
|
+
* are content.
|
|
8866
|
+
*/
|
|
8867
|
+
dtx?: boolean;
|
|
8868
|
+
/** Constant bitrate (`cbr`). Off by default, as Opus intends. */
|
|
8869
|
+
cbr?: boolean;
|
|
8870
|
+
/**
|
|
8871
|
+
* Any other `fmtp` key, merged verbatim.
|
|
8872
|
+
*
|
|
8873
|
+
* The escape hatch for a parameter this type does not model. Values are
|
|
8874
|
+
* written as given; a key with an empty string is emitted as a bare flag.
|
|
8875
|
+
*/
|
|
8876
|
+
extra?: Record<string, string>;
|
|
8877
|
+
}
|
|
8878
|
+
|
|
8879
|
+
/**
|
|
8880
|
+
* Profiles to apply, keyed by audio m-line index (`0`, `1`, …) or by `mid`.
|
|
8881
|
+
*
|
|
8882
|
+
* Position and `mid` can be mixed in one object. A key that matches nothing is
|
|
8883
|
+
* ignored rather than an error — an SDP is negotiated, and a slot that was not
|
|
8884
|
+
* offered this time is normal.
|
|
8885
|
+
*/
|
|
8886
|
+
export declare type OpusProfileMap = Record<string | number, OpusProfile>;
|
|
8887
|
+
|
|
8395
8888
|
/**
|
|
8396
8889
|
* First sequential step that clears 2:1 against the chart surface.
|
|
8397
8890
|
*
|
|
@@ -9464,7 +9957,7 @@ export declare function range(start: number, end: number, step?: number): number
|
|
|
9464
9957
|
* stays accessible and works with keyboards/screen readers without
|
|
9465
9958
|
* heavyweight positioning libs. The active fill is positioned via percentages.
|
|
9466
9959
|
*/
|
|
9467
|
-
export declare function RangeSlider({ value, onChange, min, max, step, label, helperText, disabled, formatValue, className, }: RangeSliderProps): JSX.Element;
|
|
9960
|
+
export declare function RangeSlider({ value, onChange, min, max, step, label, helperText, disabled, formatValue, "aria-label": ariaLabel, className, }: RangeSliderProps): JSX.Element;
|
|
9468
9961
|
|
|
9469
9962
|
export declare interface RangeSliderProps {
|
|
9470
9963
|
value: RangeValue;
|
|
@@ -9477,6 +9970,14 @@ export declare interface RangeSliderProps {
|
|
|
9477
9970
|
disabled?: boolean;
|
|
9478
9971
|
/** Formatter for the value badge next to the label. Defaults to `min – max`. */
|
|
9479
9972
|
formatValue?: (value: RangeValue) => string;
|
|
9973
|
+
/**
|
|
9974
|
+
* Accessible name for the pair, for when the visible `label` block does not fit.
|
|
9975
|
+
*
|
|
9976
|
+
* Each thumb still gets its own suffixed name — `"Preço (mínimo)"` and
|
|
9977
|
+
* `"Preço (máximo)"` — because a screen reader user moving between the two
|
|
9978
|
+
* needs to know which end they are on. Takes precedence over `label`.
|
|
9979
|
+
*/
|
|
9980
|
+
"aria-label"?: string;
|
|
9480
9981
|
className?: string;
|
|
9481
9982
|
}
|
|
9482
9983
|
|
|
@@ -10367,6 +10868,56 @@ export declare interface SequentialScaleOptions {
|
|
|
10367
10868
|
*/
|
|
10368
10869
|
export declare function setAudioOutput(element: HTMLMediaElement | null, sinkId: string): Promise<boolean>;
|
|
10369
10870
|
|
|
10871
|
+
/**
|
|
10872
|
+
* Cap what one sender transmits, in bits per second.
|
|
10873
|
+
*
|
|
10874
|
+
* This is the other half of the pair that confuses people: an Opus `fmtp` line
|
|
10875
|
+
* describes what we want **to receive**, while this is what limits what we
|
|
10876
|
+
* **send**. Both are needed, and in a mesh topology this one matters more,
|
|
10877
|
+
* because the uplink carries one copy of the stream per participant.
|
|
10878
|
+
*
|
|
10879
|
+
* The read-modify-write is not ceremony. `setParameters` only accepts the very
|
|
10880
|
+
* object `getParameters` handed back — a freshly built one is rejected — and a
|
|
10881
|
+
* sender that has not negotiated yet reports **no** encodings at all, so writing
|
|
10882
|
+
* to `encodings[0]` without checking throws on exactly the call that sets the
|
|
10883
|
+
* cap before the first offer.
|
|
10884
|
+
*
|
|
10885
|
+
* @param sender - The `RTCRtpSender` to cap, from `pc.getSenders()` or
|
|
10886
|
+
* `transceiver.sender`.
|
|
10887
|
+
* @param maxBitrate - Ceiling in bits per second, or `null` to lift the cap.
|
|
10888
|
+
* @returns `false` when the browser refused the change, which happens when the
|
|
10889
|
+
* sender has no track or the transceiver is gone. Playback continues
|
|
10890
|
+
* uncapped — a call that keeps running beats one that throws over a bitrate.
|
|
10891
|
+
*
|
|
10892
|
+
* @example
|
|
10893
|
+
* const sender = pc.getSenders().find((s) => s.track?.kind === "audio");
|
|
10894
|
+
* if (sender) await setSenderBitrate(sender, 48_000);
|
|
10895
|
+
*/
|
|
10896
|
+
export declare function setSenderBitrate(sender: RTCRtpSender, maxBitrate: number | null): Promise<boolean>;
|
|
10897
|
+
|
|
10898
|
+
/**
|
|
10899
|
+
* Set a local description, falling back to the untouched one if it is refused.
|
|
10900
|
+
*
|
|
10901
|
+
* Chrome has been tightening what `setLocalDescription` accepts from edited SDP,
|
|
10902
|
+
* and there is no way to know in advance. Without a fallback the call dies
|
|
10903
|
+
* instead of merely losing the profile — which is the wrong trade by a wide
|
|
10904
|
+
* margin: worse audio beats no audio.
|
|
10905
|
+
*
|
|
10906
|
+
* @param connection - The peer connection.
|
|
10907
|
+
* @param description - The description from `createOffer` / `createAnswer`.
|
|
10908
|
+
* @param profiles - Passed straight to {@link tuneOpus}.
|
|
10909
|
+
* @returns `"tuned"` when the rewritten SDP was accepted, `"original"` when the
|
|
10910
|
+
* fallback was used — worth reporting, because it means the profile silently
|
|
10911
|
+
* did not apply.
|
|
10912
|
+
* @throws Whatever `setLocalDescription` throws for the original description: at
|
|
10913
|
+
* that point the failure is not about the rewrite and the caller has to know.
|
|
10914
|
+
*
|
|
10915
|
+
* @example
|
|
10916
|
+
* const applied = await setTunedLocalDescription(pc, await pc.createOffer(), profiles);
|
|
10917
|
+
* if (applied === "original") logger.warn("opus profile refused by the browser");
|
|
10918
|
+
*/
|
|
10919
|
+
export declare function setTunedLocalDescription(connection: RTCPeerConnection, description: RTCSessionDescriptionInit, profiles: OpusProfile | OpusProfileMap): Promise<TunedDescriptionResult>;
|
|
10920
|
+
|
|
10370
10921
|
/** Imperative handle over a pool of short sound effects. */
|
|
10371
10922
|
export declare interface SfxPool {
|
|
10372
10923
|
/** Play a clip, allocating and caching its element on first use. */
|
|
@@ -10709,7 +11260,7 @@ export declare function sleep(ms: number): Promise<void>;
|
|
|
10709
11260
|
* accessible (keyboard + screen reader) with no positioning libs. The active
|
|
10710
11261
|
* fill is a percentage-width bar. For a two-thumb range, use `RangeSlider`.
|
|
10711
11262
|
*/
|
|
10712
|
-
export declare function Slider({ value, onChange, min, max, step, label, helperText, disabled, formatValue, className, }: SliderProps): JSX.Element;
|
|
11263
|
+
export declare function Slider({ value, onChange, min, max, step, label, helperText, disabled, formatValue, "aria-label": ariaLabel, className, }: SliderProps): JSX.Element;
|
|
10713
11264
|
|
|
10714
11265
|
export declare interface SliderProps {
|
|
10715
11266
|
/** Current value. */
|
|
@@ -10724,6 +11275,17 @@ export declare interface SliderProps {
|
|
|
10724
11275
|
disabled?: boolean;
|
|
10725
11276
|
/** Formatter for the value badge next to the label. Defaults to the raw number. */
|
|
10726
11277
|
formatValue?: (value: number) => string;
|
|
11278
|
+
/**
|
|
11279
|
+
* Accessible name, for when the visible `label` block does not fit.
|
|
11280
|
+
*
|
|
11281
|
+
* A slider in a one-line footer, a table cell or a toolbar has no room for the
|
|
11282
|
+
* label row above the track, and without this every such control announces
|
|
11283
|
+
* itself as "Slider" — several on the same screen become indistinguishable to a
|
|
11284
|
+
* screen reader. Takes precedence over `label`; wrapping the field in an outer
|
|
11285
|
+
* `<label>` does not work, because an explicit `aria-label` on the input wins
|
|
11286
|
+
* the accessible-name precedence order.
|
|
11287
|
+
*/
|
|
11288
|
+
"aria-label"?: string;
|
|
10727
11289
|
className?: string;
|
|
10728
11290
|
}
|
|
10729
11291
|
|
|
@@ -12169,6 +12731,42 @@ export declare interface TruncateTextProps extends HTMLAttributes<HTMLDivElement
|
|
|
12169
12731
|
children: ReactNode;
|
|
12170
12732
|
}
|
|
12171
12733
|
|
|
12734
|
+
/** Which description a peer connection actually accepted. */
|
|
12735
|
+
export declare type TunedDescriptionResult = "tuned" | "original";
|
|
12736
|
+
|
|
12737
|
+
/**
|
|
12738
|
+
* Apply Opus profiles to the audio m-lines of a session description.
|
|
12739
|
+
*
|
|
12740
|
+
* Audio over WebRTC is mono and narrow by default, and the only place that is
|
|
12741
|
+
* corrected is the SDP — which is why shared-screen audio famously sounds like a
|
|
12742
|
+
* telephone: music and video inherit the speech profile (mono, ~32 kbps, FEC on,
|
|
12743
|
+
* DTX gating the quiet passages) and no high-level API lets you change it.
|
|
12744
|
+
*
|
|
12745
|
+
* Deliberately **without** built-in presets: which values to use is the
|
|
12746
|
+
* consumer's call — voice in a mesh does not want what system audio wants — and
|
|
12747
|
+
* a preset table is the kind of thing that has no business inside a dependency.
|
|
12748
|
+
* What lives here is the parsing, merging and insertion, which is where the long
|
|
12749
|
+
* tail is. Getting any of it wrong degrades silently: nobody sees an exception,
|
|
12750
|
+
* the audio is just worse.
|
|
12751
|
+
*
|
|
12752
|
+
* @param sdp - The description from `createOffer` or `createAnswer`.
|
|
12753
|
+
* @param profiles - One {@link OpusProfile} for every audio m-line, or an
|
|
12754
|
+
* {@link OpusProfileMap} keyed by audio m-line index or by `mid`.
|
|
12755
|
+
* @returns The rewritten SDP, with CRLF line endings as RFC 4566 requires.
|
|
12756
|
+
* Untouched when there is no Opus, when no profile matches, or when a profile
|
|
12757
|
+
* asks for nothing.
|
|
12758
|
+
*
|
|
12759
|
+
* @example
|
|
12760
|
+
* const tuned = tuneOpus(offer.sdp, {
|
|
12761
|
+
* 0: { maxAverageBitrate: 48_000, stereo: false, fec: true, dtx: true },
|
|
12762
|
+
* 1: { maxAverageBitrate: 192_000, stereo: true, fec: false, dtx: false },
|
|
12763
|
+
* });
|
|
12764
|
+
*
|
|
12765
|
+
* @example
|
|
12766
|
+
* const tuned = tuneOpus(offer.sdp, { stereo: true, dtx: false });
|
|
12767
|
+
*/
|
|
12768
|
+
export declare function tuneOpus(sdp: string, profiles: OpusProfile | OpusProfileMap): string;
|
|
12769
|
+
|
|
12172
12770
|
/**
|
|
12173
12771
|
* Clock label for a turn — the time, not a relative phrase.
|
|
12174
12772
|
*
|
|
@@ -12429,6 +13027,31 @@ export declare interface UseAsyncResult<T> {
|
|
|
12429
13027
|
*/
|
|
12430
13028
|
export declare function useAudio(): UseAudioResult;
|
|
12431
13029
|
|
|
13030
|
+
/**
|
|
13031
|
+
* Keep one {@link AudioBus} alive for as long as the component is mounted.
|
|
13032
|
+
*
|
|
13033
|
+
* The bus is built on the first render and closed on unmount, which matters more
|
|
13034
|
+
* than it looks: browsers cap the number of live `AudioContext`s (Chrome allows
|
|
13035
|
+
* around six), so a bus leaked on unmount eventually breaks every later one on
|
|
13036
|
+
* the page.
|
|
13037
|
+
*
|
|
13038
|
+
* Options are read once. A bus is a device route and a mixing graph, not a
|
|
13039
|
+
* render output — rebuilding it because a prop changed would drop every attached
|
|
13040
|
+
* source mid-sentence. Change gain and output through the bus itself.
|
|
13041
|
+
*
|
|
13042
|
+
* @param options - See {@link AudioBusOptions}. Read on the first render only.
|
|
13043
|
+
* @returns The bus, stable for the component's lifetime.
|
|
13044
|
+
*
|
|
13045
|
+
* @example
|
|
13046
|
+
* const bus = useAudioBus({ maxGain: 3 });
|
|
13047
|
+
*
|
|
13048
|
+
* useEffect(() => {
|
|
13049
|
+
* const handle = bus.attach(stream, { gain: 1 });
|
|
13050
|
+
* return () => handle.stop();
|
|
13051
|
+
* }, [bus, stream]);
|
|
13052
|
+
*/
|
|
13053
|
+
export declare function useAudioBus(options?: AudioBusOptions): AudioBus;
|
|
13054
|
+
|
|
12432
13055
|
/**
|
|
12433
13056
|
* Record the given stream, with a clock, a level meter and a state machine.
|
|
12434
13057
|
*
|
|
@@ -12844,7 +13467,7 @@ export declare function useDelete<T>(resource: string, options?: UseDeleteOption
|
|
|
12844
13467
|
/** Options for the delete mutation (mutationFn + onSuccess are provided). */
|
|
12845
13468
|
export declare type UseDeleteOptions<T> = Omit<UseMutationOptions<T, Error, string | number>, "mutationFn">;
|
|
12846
13469
|
|
|
12847
|
-
export declare function useDescribeApiError(): (error: unknown, fallback: string) => string;
|
|
13470
|
+
export declare function useDescribeApiError(): (error: unknown, fallback: string, options?: DescribeApiErrorOptions) => string;
|
|
12848
13471
|
|
|
12849
13472
|
/**
|
|
12850
13473
|
* Manage open/closed boolean state with stable `open`/`close`/`toggle` handlers.
|
|
@@ -14894,11 +15517,13 @@ export { useWatch }
|
|
|
14894
15517
|
* for the host component and tears it down on unmount.
|
|
14895
15518
|
*
|
|
14896
15519
|
* Every callback is read through a ref, so `onOpen` / `onMessage` / `onClose` /
|
|
14897
|
-
* `onError`
|
|
14898
|
-
* and never reopens the
|
|
14899
|
-
*
|
|
14900
|
-
* `
|
|
14901
|
-
*
|
|
15520
|
+
* `onError` / `onReconnecting` / `onReconnected` / `onLost` always run the
|
|
15521
|
+
* latest closure — an inline arrow function is fine and never reopens the
|
|
15522
|
+
* socket. Connection-shaping options (`protocols`, `maxRetries`,
|
|
15523
|
+
* `initialBackoff`, `maxBackoff`, `jitter`, `handshakeTimeout`,
|
|
15524
|
+
* `silenceTimeout`, `waitForOnline`, `pingInterval`, `queueWhileClosed`) are
|
|
15525
|
+
* baked into the connection, so changing one reopens it with the new value
|
|
15526
|
+
* rather than being silently ignored.
|
|
14902
15527
|
*
|
|
14903
15528
|
* @param url - Full ws:// or wss:// URL.
|
|
14904
15529
|
* @param options - Connection configuration and callbacks.
|
|
@@ -14927,6 +15552,13 @@ export declare interface UseWebSocketResult<T> {
|
|
|
14927
15552
|
send: (payload: string | Blob | BufferSource) => boolean;
|
|
14928
15553
|
/** Force a reconnect, resetting the retry counter. */
|
|
14929
15554
|
reconnect: () => void;
|
|
15555
|
+
/**
|
|
15556
|
+
* Change the silence watchdog at runtime, in ms. `0` disables it.
|
|
15557
|
+
*
|
|
15558
|
+
* For a server that announces its own heartbeat interval in the first frame,
|
|
15559
|
+
* so the tolerated silence is not hard-coded on both ends.
|
|
15560
|
+
*/
|
|
15561
|
+
setSilenceTimeout: (ms: number) => void;
|
|
14930
15562
|
}
|
|
14931
15563
|
|
|
14932
15564
|
/**
|
|
@@ -15586,10 +16218,38 @@ export declare interface WebSocketController {
|
|
|
15586
16218
|
close: (code?: number, reason?: string) => void;
|
|
15587
16219
|
/** Force an immediate reconnect, resetting the retry counter. */
|
|
15588
16220
|
reconnect: () => void;
|
|
16221
|
+
/**
|
|
16222
|
+
* Change the silence watchdog at runtime, in ms. `0` disables it.
|
|
16223
|
+
*
|
|
16224
|
+
* For the common case where the server announces its heartbeat interval in
|
|
16225
|
+
* the first frame, so the tolerated silence is not hard-coded on both ends:
|
|
16226
|
+
*
|
|
16227
|
+
* ```ts
|
|
16228
|
+
* onMessage: ({ data }) => {
|
|
16229
|
+
* if (data.type === "welcome") socket.setSilenceTimeout(data.heartbeat_seconds * 2500);
|
|
16230
|
+
* }
|
|
16231
|
+
* ```
|
|
16232
|
+
*/
|
|
16233
|
+
setSilenceTimeout: (ms: number) => void;
|
|
16234
|
+
/**
|
|
16235
|
+
* Resolves on the first successful open, rejects when the socket is lost
|
|
16236
|
+
* before ever opening.
|
|
16237
|
+
*
|
|
16238
|
+
* Joining and dropping are different events: a call that never connected has
|
|
16239
|
+
* to be reported, while one that dropped mid-session should reconnect
|
|
16240
|
+
* quietly. Await this for the join, handle
|
|
16241
|
+
* {@link CreateWebSocketOptions.onLost} for the drop. Pair it with
|
|
16242
|
+
* `maxRetries: 0` when the first attempt should fail fast instead of
|
|
16243
|
+
* spending the whole schedule on a server that is not there.
|
|
16244
|
+
*/
|
|
16245
|
+
opened: Promise<void>;
|
|
15589
16246
|
/** Current connection status. */
|
|
15590
16247
|
readonly status: WebSocketStatus;
|
|
15591
16248
|
}
|
|
15592
16249
|
|
|
16250
|
+
/** Why a socket stopped trying to come back. */
|
|
16251
|
+
export declare type WebSocketLostReason = "rejected" | "exhausted";
|
|
16252
|
+
|
|
15593
16253
|
export declare interface WebSocketMessage<T> {
|
|
15594
16254
|
/** Parsed payload — JSON-decoded when possible, raw string otherwise. */
|
|
15595
16255
|
data: T;
|
|
@@ -15597,12 +16257,6 @@ export declare interface WebSocketMessage<T> {
|
|
|
15597
16257
|
raw: MessageEvent;
|
|
15598
16258
|
}
|
|
15599
16259
|
|
|
15600
|
-
/**
|
|
15601
|
-
* @tempest-limits file-lines, function-lines — reconnect with backoff, heartbeat,
|
|
15602
|
-
* the send queue that survives a disconnect and the listener set that must be re-
|
|
15603
|
-
* attached to each new socket — one connection's lifetime, one closure. The queue
|
|
15604
|
-
* and the reconnect timer are the same decision seen twice.
|
|
15605
|
-
*/
|
|
15606
16260
|
export declare type WebSocketStatus = "idle" | "connecting" | "open" | "closing" | "closed" | "error";
|
|
15607
16261
|
|
|
15608
16262
|
export declare type WeekStart = 0 | 1;
|