@reause/shared 0.1.2

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.
@@ -0,0 +1,2713 @@
1
+ import { Context, Dispatch, PropsWithChildren, ReactNode, Ref, RefObject, SetStateAction } from "react";
2
+ //#region createEventHook/index.d.ts
3
+ /**
4
+ * Utility for creating event hooks — React port of VueUse's `createEventHook`.
5
+ *
6
+ * Map from @vueuse/shared `createEventHook`
7
+ * Mapping notes:
8
+ * - VueUse auto-disposes listeners through the Vue effect scope
9
+ * (`tryOnScopeDispose`); React has no scope equivalent, so that call is
10
+ * dropped. Clean up manually with the `{ off }` object returned by `on`
11
+ * (e.g. in an effect cleanup), or bind the hook with `useListener(on, cb)`
12
+ * for automatic cleanup on unmount.
13
+ * - `trigger` matches upstream error semantics: a synchronous throw inside
14
+ * one listener propagates out of `trigger` and aborts the remaining
15
+ * listeners (upstream has no per-listener guard); rejections from async
16
+ * listeners still surface on the promise returned by `trigger`.
17
+ *
18
+ * The source code for this function was inspired by vue-apollo's `useEventHook` util
19
+ * https://github.com/vuejs/vue-apollo/blob/v4/packages/vue-apollo-composable/src/util/useEventHook.ts
20
+ *
21
+ * @see https://vueuse.org/createEventHook
22
+ *
23
+ * @example
24
+ * const resultEvent = createEventHook<Response>()
25
+ * useListener(resultEvent.on, (response) => { console.log(response) })
26
+ * resultEvent.trigger(response)
27
+ */
28
+ type IsAny<T> = 0 extends (1 & T) ? true : false;
29
+ type Callback<T> = IsAny<T> extends true ? (...param: any) => void : ([T] extends [void] ? (...param: unknown[]) => void : [T] extends [any[]] ? (...param: T) => void : (...param: [T, ...unknown[]]) => void);
30
+ export type EventHookOn<T = any> = (fn: Callback<T>) => {
31
+ off: () => void;
32
+ };
33
+ export type EventHookOff<T = any> = (fn: Callback<T>) => void;
34
+ export type EventHookTrigger<T = any> = (...param: Parameters<Callback<T>>) => Promise<unknown[]>;
35
+ export interface EventHook<T = any> {
36
+ on: EventHookOn<T>;
37
+ off: EventHookOff<T>;
38
+ trigger: EventHookTrigger<T>;
39
+ clear: () => void;
40
+ }
41
+ export type EventHookReturn<T> = EventHook<T>;
42
+ /**
43
+ * Utility for creating event hooks
44
+ *
45
+ * @see https://vueuse.org/createEventHook
46
+ *
47
+ * @__NO_SIDE_EFFECTS__
48
+ */
49
+ export declare function createEventHook<T = any>(): EventHookReturn<T>;
50
+ //#endregion
51
+ //#region createGlobalState/index.d.ts
52
+ export type GlobalStateInitAction<State> = State | (() => State);
53
+ export type GlobalStateSetAction<State> = State | ((prev: State) => State);
54
+ export type GlobalStateSetter<State> = (update: GlobalStateSetAction<State>) => void;
55
+ /**
56
+ * Keep state in the global scope, reusable across React components — React
57
+ * port of VueUse's `createGlobalState`, with the parameter following
58
+ * react-use's `createGlobalState`.
59
+ *
60
+ * Map from @vueuse/shared `createGlobalState`
61
+ * Mapping: upstream runs the factory inside a detached `effectScope(true)`
62
+ * once and returns the reactive object, so every caller shares the same refs
63
+ * and `computed`s. React has no `effectScope` and no reactive `ref`, so the
64
+ * port keeps the state in a module-level external store (a per-factory closure
65
+ * holding the value plus a `Set` of listeners) and every consumer reads it
66
+ * through `useSyncExternalStore`. The store is never disposed or reset, so
67
+ * state survives unmount exactly like upstream's detached scope.
68
+ *
69
+ * The parameter follows react-use `createGlobalState`: it is the **initial
70
+ * state** — a plain value, or a zero-arg function computing it. It is resolved
71
+ * exactly once, at `createGlobalState` call time (module scope), mirroring
72
+ * react-use's `store.state = initialState instanceof Function ? initialState()
73
+ * : initialState`; the initializer therefore never runs during a component
74
+ * render, and the returned hook takes no arguments. This differs from upstream
75
+ * VueUse, where the factory receives the arguments of the first hook call.
76
+ *
77
+ * Deviations from upstream:
78
+ * - module-level external store instead of `effectScope(true)` — the scope's
79
+ * only job was keeping the state alive outside any component; a module-level
80
+ * closure does that without a scope, and `useSyncExternalStore` makes every
81
+ * consumer re-render on change.
82
+ * - the returned hook yields the tuple `[state, setState]` instead of the
83
+ * factory's object of refs (`{ count, doubleCount, increment }`): §2B of the
84
+ * naming rules — a state-like writable hook returns `[value, setValue]`.
85
+ * Derive computed values inside the consumer from `state`, and expose
86
+ * actions through the factory's returned state or a plain function.
87
+ * - the parameter is react-use's initial state (value or zero-arg initializer)
88
+ * instead of upstream's variadic factory (see above).
89
+ *
90
+ * The tuple is memoized on the snapshot, so its identity is stable across
91
+ * renders for a given state (effect deps / memoized children keyed on the
92
+ * tuple do not churn); `setState` is a single function shared by every
93
+ * consumer, like react-use's `store.setState`.
94
+ *
95
+ * ```ts
96
+ * const useGlobalState = createGlobalState(() => 0)
97
+ *
98
+ * function Counter() {
99
+ * const [count, setCount] = useGlobalState()
100
+ * return <button onClick={() => setCount(prev => prev + 1)}>{count}</button>
101
+ * }
102
+ * ```
103
+ *
104
+ * @see https://vueuse.org/createGlobalState
105
+ * @see https://github.com/streamich/react-use/blob/master/src/factory/createGlobalState.ts
106
+ * @param initialState The initial state — a plain value or a zero-arg function
107
+ * computing it; resolved exactly once, at `createGlobalState` call time.
108
+ */
109
+ export declare function createGlobalState<State = unknown>(initialState: GlobalStateInitAction<State>): () => [State, GlobalStateSetter<State>];
110
+ export declare function createGlobalState<State = undefined>(): () => [State, GlobalStateSetter<State>];
111
+ //#endregion
112
+ //#region createInjectionState/index.d.ts
113
+ export interface CreateInjectionStateOptions<Return> {
114
+ /**
115
+ * Custom injectionKey for InjectionState — the React equivalent of
116
+ * upstream's string/symbol key. React keys a context by object identity, so
117
+ * pass a `createContext(...)` instance; consumers may then read it directly
118
+ * with `useContext`.
119
+ */
120
+ injectionKey?: Context<Return | undefined>;
121
+ /**
122
+ * Default value used by `useInjectedState` when no provider is rendered
123
+ * above the consumer. Implemented natively through `createContext`; when a
124
+ * custom `injectionKey` is supplied, that context's own default is used
125
+ * instead.
126
+ */
127
+ defaultValue?: Return;
128
+ }
129
+ export type CreateInjectionStateProvider<Props extends object, ProvideReturn = ReactNode> = (props: PropsWithChildren<Props>) => ProvideReturn;
130
+ export type CreateInjectionStateReturn<Props extends object, ProvideReturn, InjectReturn> = Readonly<[
131
+ /**
132
+ * Render this component to create and provide the state to its descendants.
133
+ */
134
+ Provider: CreateInjectionStateProvider<Props, ProvideReturn>,
135
+ /**
136
+ * Call this hook in a consumer component to inject the state.
137
+ */
138
+ useInjectedState: () => InjectReturn]>;
139
+ /**
140
+ * Create a state that can be injected into descendant components — React port
141
+ * of VueUse's `createInjectionState`.
142
+ *
143
+ * Map from @vueuse/shared `createInjectionState`
144
+ * Mapping: React has no provide/inject pair, so the providing side becomes a
145
+ * component and the state travels through a React Context created by the
146
+ * factory (or supplied through `options.injectionKey`). Slot 0 of the returned
147
+ * tuple is `Provider` — render it (it may wrap children) and the composable
148
+ * runs during its render, exactly once per render, with the props passed to
149
+ * it. Slot 1 is `useInjectedState`, which reads the nearest `Provider` above
150
+ * the calling component with `useContext`.
151
+ * Because JSX can only pass a single props object, the factory receives one
152
+ * object — upstream's `(initialValue: number) => ...` becomes
153
+ * `({ initialValue }: { initialValue: number }) => ...`.
154
+ *
155
+ * The second type parameter (`ProvideReturn`) is upstream's
156
+ * `useProvidingState` return slot, which in this port is the provider
157
+ * component's render output (`ReactNode`).
158
+ *
159
+ * Deviations from upstream:
160
+ * - `options.injectionKey` takes a React `Context` instead of a string/symbol
161
+ * key: React keys a context by object identity, so the factory's own
162
+ * `Context` is the default key and a custom context can be shared with a
163
+ * plain `useContext`.
164
+ * - The providing side is a component (`Provider`) rather than a callable
165
+ * `useProvidingState`: React cannot provide during a hook call of the same
166
+ * component that consumes it.
167
+ * - The factory takes a single props object instead of variadic arguments.
168
+ * - `children` is a reserved prop: it is consumed by `Provider` for rendering
169
+ * and is not forwarded to the factory.
170
+ *
171
+ * @see https://vueuse.org/createInjectionState
172
+ *
173
+ * @__NO_SIDE_EFFECTS__
174
+ *
175
+ * @example
176
+ * const [CounterStoreProvider, useCounterStore] = createInjectionState(
177
+ * ({ initialValue }: { initialValue: number }) => {
178
+ * const [count, setCount] = useState(initialValue)
179
+ * return { count, inc: () => setCount(c => c + 1) }
180
+ * },
181
+ * )
182
+ *
183
+ * function Counter() {
184
+ * const { count, inc } = useCounterStore()!
185
+ * return <button onClick={inc}>{count}</button>
186
+ * }
187
+ *
188
+ * <CounterStoreProvider initialValue={0}>
189
+ * <Counter />
190
+ * </CounterStoreProvider>
191
+ */
192
+ export declare function createInjectionState<Props extends object, Return>(composable: (props: Props) => Return, options: {
193
+ defaultValue: Return;
194
+ } & CreateInjectionStateOptions<Return>): CreateInjectionStateReturn<Props, ReactNode, Return>;
195
+ export declare function createInjectionState<Props extends object, Return>(composable: (props: Props) => Return, options?: CreateInjectionStateOptions<Return>): CreateInjectionStateReturn<Props, ReactNode, Return | undefined>;
196
+ //#endregion
197
+ //#region createSharedHook/index.d.ts
198
+ /**
199
+ * Make a composable function usable with multiple React components.
200
+ *
201
+ * Map from @vueuse/shared `createSharedComposable`
202
+ * Mapping: upstream runs the composable once inside a detached
203
+ * `effectScope(true)`, counts the subscribers and stops the scope when the
204
+ * last consumer leaves. React has no `effectScope`, so the same lifetime is
205
+ * expressed by an external store held in the closure of one
206
+ * `createSharedHook` call — the `state` snapshot, a `Set` of `listeners`, the
207
+ * `refCount` and the optional `cleanup` — which every consumer reads through
208
+ * `useSyncExternalStore`.
209
+ *
210
+ * The shared instance is created by the **first consumer to render** (the
211
+ * "creator"): it runs the wrapped hook on every one of its renders — the
212
+ * wrapped hook is therefore free to use React hooks internally — assigning
213
+ * the result to `state`, and `useLayoutEffect` publishes the latest value to
214
+ * every other consumer after commit. Every later consumer never calls the
215
+ * wrapped hook (both call patterns are stable per consumer, so the hook order
216
+ * never changes across renders); it just reads the published snapshot. The
217
+ * creator assigns `state` *before* `useSyncExternalStore` reads its snapshot
218
+ * in the same render, so every consumer — creator included — receives the
219
+ * shared value on its very first render, never `undefined`.
220
+ *
221
+ * The creator deliberately **does not register a store listener**: it already
222
+ * re-renders on its own state changes (the wrapped hook's setters belong to
223
+ * its component) and re-publishes afterwards, so a notification would only
224
+ * re-render it from its own publish. `useSyncExternalStore` requires the
225
+ * snapshot to stay reference-stable between real changes ("the result of
226
+ * getSnapshot should be cached"): every creator render assigns a fresh
227
+ * reference, so a subscribed creator would see "the store changed" forever and
228
+ * loop. The creator still counts toward `refCount`, so teardown timing is
229
+ * exact — it just never receives notifications.
230
+ *
231
+ * Deviations from upstream:
232
+ * - upstream runs the composable exactly once, with the first caller's
233
+ * arguments; here the creator re-runs the wrapped hook on every one of its
234
+ * renders (React hooks cannot be called outside a render), so while the
235
+ * creator stays mounted the shared value keeps tracking its latest render.
236
+ * - **frozen after the creator unmounts**: the wrapped hook's setters belong
237
+ * to the creator's component, so if the creator unmounts while other
238
+ * consumers remain mounted, the shared value stops updating — it freezes at
239
+ * the last published value. The instance itself lives on until the last
240
+ * consumer unmounts (upstream lifetime parity).
241
+ * - `getServerSnapshot` returns the same snapshot as the client: server
242
+ * rendering yields the uninitialized value, the client fills it in after
243
+ * hydration, and `useSyncExternalStore` handles the mismatch.
244
+ * - Teardown has no `tryOnScopeDispose` to hook into, so the optional
245
+ * `cleanup` argument is called — and the state dropped — when the last
246
+ * consumer unmounts; a later mount starts a fresh instance, exactly like
247
+ * upstream's `scope.stop()` followed by `state = undefined`.
248
+ *
249
+ * ```tsx
250
+ * const useSharedMouse = createSharedHook(useMouse)
251
+ *
252
+ * // CompA — const { x, y } = useSharedMouse()
253
+ * // CompB — const { x, y } = useSharedMouse() // same state, no new listeners
254
+ * ```
255
+ *
256
+ * @see https://vueuse.org/createSharedComposable
257
+ * @param hook The composable to share across every consumer of the returned
258
+ * hook. It runs on every render of the first consumer (the creator).
259
+ * @param cleanup Called when the last consumer unmounts, before the shared
260
+ * state is dropped — the place to undo whatever `hook` set up outside React.
261
+ */
262
+ export declare function createSharedHook<Fn extends (...args: any[]) => any>(hook: Fn, cleanup?: () => void): (...args: Parameters<Fn>) => ReturnType<Fn>;
263
+ //#endregion
264
+ //#region isDefined/index.d.ts
265
+ export type IsDefinedReturn = boolean;
266
+ /**
267
+ * Non-nullish checking type guard for ref-like objects.
268
+ *
269
+ * Map from @vueuse/shared `isDefined`
270
+ * Mapping: upstream narrows a Vue `Ref` / `ComputedRef` itself; this port
271
+ * operates on React ref-like objects (`{ current }`) and narrows `.current`
272
+ * to `Exclude<T, null | undefined>` — upstream's `Ref` and `ComputedRef`
273
+ * overloads collapse into the single ref-like overload below. The
274
+ * plain-value overload keeps upstream parity at the type level, so bare
275
+ * values can be guarded with the same call. At runtime a ref-like is
276
+ * detected via `isRefLike` (mirroring upstream's `unref`), so both shapes
277
+ * share one check — with one edge: a plain object that happens to look like
278
+ * a ref (`{ current: undefined }`) is unwrapped and judged by `.current`
279
+ * (upstream `unref` only unwraps Vue refs, so the same object would be
280
+ * `true` there).
281
+ *
282
+ * @__NO_SIDE_EFFECTS__
283
+ * @example
284
+ * const example = useRef(Math.random() ? 'example' : undefined) // RefObject<string | undefined>
285
+ *
286
+ * if (isDefined(example))
287
+ * example.current // string — narrowed by the type guard
288
+ *
289
+ * @see https://vueuse.org/shared/isDefined/
290
+ */
291
+ export declare function isDefined<T>(v: RefObject<T>): v is RefObject<Exclude<T, null | undefined>>;
292
+ export declare function isDefined<T>(v: T): v is Exclude<T, null | undefined>;
293
+ //#endregion
294
+ //#region makeDestructurable/index.d.ts
295
+ /**
296
+ * Make isomorphic destructurable for object and array at the same time —
297
+ * React port of VueUse's `makeDestructurable` (a pure utility function, so it
298
+ * maps 1:1 with no React adaptation). See this blog for the underlying idea:
299
+ * https://antfu.me/posts/destructuring-with-object-or-array/
300
+ *
301
+ * Map from @vueuse/shared `makeDestructurable`
302
+ * Upstream semantics are kept verbatim: given `(obj, arr)` the returned value
303
+ * can be destructured as an object (`const { foo, bar } = obj`) or as an array
304
+ * (`const [foo, bar] = obj`) — the array mode is backed by a non-enumerable
305
+ * `Symbol.iterator` defined on a shallow clone of `obj` (spread
306
+ * `{ ...obj }`); `Object.assign` appears only in the no-Symbol SSR fallback.
307
+ *
308
+ * @example
309
+ * const foo = { name: 'foo' }
310
+ * const bar = 1024
311
+ * const obj = makeDestructurable({ foo, bar } as const, [foo, bar] as const)
312
+ * const { foo: f1, bar: b1 } = obj // object destructuring
313
+ * const [f2, b2] = obj // array destructuring
314
+ */
315
+ export declare function makeDestructurable<T extends Record<string, unknown>, A extends readonly any[]>(obj: T, arr: A): T & A;
316
+ //#endregion
317
+ //#region utils/index.d.ts
318
+ export declare function promiseTimeout(ms: number, throwOnTimeout?: boolean, reason?: string): Promise<void>;
319
+ export interface SingletonPromiseReturn<T> {
320
+ (): Promise<T>;
321
+ /**
322
+ * Reset current staled promise.
323
+ * await it to have proper shutdown.
324
+ */
325
+ reset: () => Promise<void>;
326
+ }
327
+ /**
328
+ * Create singleton promise function
329
+ *
330
+ * @example
331
+ * ```
332
+ * const promise = createSingletonPromise(async () => { ... })
333
+ *
334
+ * await promise()
335
+ * await promise() // all of them will be bind to a single promise instance
336
+ * await promise() // and be resolved together
337
+ * ```
338
+ */
339
+ export declare function createSingletonPromise<T>(fn: () => Promise<T>): SingletonPromiseReturn<T>;
340
+ /**
341
+ * Increase string a value with unit
342
+ *
343
+ * @example '2px' + 1 = '3px'
344
+ * @example '15em' + (-2) = '13em'
345
+ */
346
+ export declare function increaseWithUnit(target: number, delta: number): number;
347
+ export declare function increaseWithUnit(target: string, delta: number): string;
348
+ export declare function increaseWithUnit(target: string | number, delta: number): string | number;
349
+ /**
350
+ * Get a px value for SSR use, do not rely on this method outside of SSR as REM
351
+ * unit is assumed at 16px, which might not be the case on the client
352
+ *
353
+ * @example pxValue('37rem') // 592
354
+ * @example pxValue('500px') // 500
355
+ */
356
+ export declare function pxValue(px: string): number;
357
+ /**
358
+ * Create a new subset object by giving keys
359
+ */
360
+ export declare function objectPick<O extends object, T extends keyof O>(obj: O, keys: T[], omitUndefined?: boolean): Pick<O, T>;
361
+ /**
362
+ * Create a new subset object by omit giving keys
363
+ */
364
+ export declare function objectOmit<O extends object, T extends keyof O>(obj: O, keys: T[], omitUndefined?: boolean): Omit<O, T>;
365
+ export declare function toArray<T>(value: T | readonly T[]): readonly T[];
366
+ export declare function toArray<T>(value: T | T[]): T[];
367
+ export declare const isDef: <T = any>(val?: T) => val is T;
368
+ export declare const assert: (condition: boolean, ...infos: any[]) => void;
369
+ export declare const isObject: (val: any) => val is object;
370
+ export declare const now: () => number;
371
+ export declare const timestamp: () => number;
372
+ export declare const clamp: (n: number, min: number, max: number) => number;
373
+ export declare const rand: (min: number, max: number) => number;
374
+ export declare const hasOwn: <T extends object, K extends keyof T>(val: T, key: K) => key is K;
375
+ export declare const isIOS: boolean;
376
+ export declare const hyphenate: (str: string) => string;
377
+ /** A plain value or a React ref. Zero-argument getter values are not supported. */
378
+ export type RefOrValue<T> = T | Ref<T>;
379
+ /** Values accepted by controllable state hooks. */
380
+ export type StateValue<T> = RefOrValue<T> | (() => T) | readonly [T, (value: T | ((prev: T) => T)) => void] | {
381
+ value: T;
382
+ onChange?: (value: T) => void;
383
+ };
384
+ /**
385
+ * Allow a custom `window` instance, e.g. working with iframes or in testing
386
+ * environments. Single source of truth — VueUse defines this in shared too.
387
+ */
388
+ export interface ConfigurableWindow {
389
+ window?: Window;
390
+ }
391
+ /**
392
+ * Type guard for React ref objects (`RefObject` — `{ current }` holders).
393
+ * Callback refs are functions and cannot be read synchronously, so they are
394
+ * not ref-like.
395
+ */
396
+ export declare function isRefLike<T>(value: RefOrValue<T> | undefined | null): value is RefObject<T | null>;
397
+ /**
398
+ * Resolve a plain value or a React ref to its current value — the React
399
+ * replacement for VueUse's `toValue`. Getters are not supported: pass a
400
+ * React ref (`useRef`) when the latest value must be read lazily.
401
+ */
402
+ export declare function toValue<T>(value: StateValue<T>): T;
403
+ export declare function toValue<T>(value: StateValue<T> | undefined | null): T | undefined | null;
404
+ /**
405
+ * Write a value back through a writable `State<T>` source — a ref-like
406
+ * `.current`, a `[value, setter]` tuple or a `{ value, onChange }` pair.
407
+ * Plain values and getters have no write path and are skipped. This is the
408
+ * write-side counterpart of `toValue`; hooks that push values into a
409
+ * `State<T>` import it from here rather than re-implementing the branches.
410
+ */
411
+ export declare function writeState<T>(source: StateValue<T> | undefined | null, value: T): void;
412
+ //#endregion
413
+ //#region useControllableState/index.d.ts
414
+ export type StateTuple<T> = [T, Dispatch<SetStateAction<T>>];
415
+ /** A value, lazy getter, React ref, state tuple, or value/onChange pair. */
416
+ export type State<T> = StateValue<T>;
417
+ export interface UseControllableStateOptions<T> {
418
+ defaultValue?: T | (() => T);
419
+ shouldUpdate?: (prev: T, next: T) => boolean;
420
+ passive?: boolean;
421
+ }
422
+ /**
423
+ * Combine controlled and uncontrolled state sources.
424
+ *
425
+ * `state` is resolved with `toValue` on every render. A tuple
426
+ * `[value, setter]` or a `{ value, onChange }` pair is always controlled: the
427
+ * current value is the resolved source and `setValue` writes through to the
428
+ * tuple setter / `onChange`. With `passive: true` a plain value, getter, or
429
+ * ref source is uncontrolled — the hook initializes from the source and local
430
+ * updates persist, and external source changes are synced back (honoring
431
+ * `shouldUpdate`). With the default `passive: false` such a source is
432
+ * controlled (the external value wins on every render); `setValue` then has
433
+ * no channel back to the caller, so it warns instead of silently discarding
434
+ * the update — pass a tuple, a `{ value, onChange }` pair, or use
435
+ * `passive: true` to write. `defaultValue` (value or lazy initializer) seeds
436
+ * the internal state of uncontrolled sources; `shouldUpdate(prev, next)`
437
+ * guards every commit, including the passive sync.
438
+ */
439
+ export declare function useControllableState<T>(state: State<T>, options?: UseControllableStateOptions<T>): StateTuple<T>;
440
+ //#endregion
441
+ //#region syncState/index.d.ts
442
+ export type SyncStateDirection = 'both' | 'ltr' | 'rtl';
443
+ export interface SyncStateTransform<L, R> {
444
+ ltr: (left: L) => R;
445
+ rtl: (right: R) => L;
446
+ }
447
+ export interface SyncStateOptions<L, R, D extends SyncStateDirection = 'both'> {
448
+ /**
449
+ * Timing for syncing, same as watch's `flush` option.
450
+ *
451
+ * React note: no React equivalent — effects always run after commit, so
452
+ * `'sync'` / `'pre'` / `'post'` are accepted for upstream signature
453
+ * compatibility and all behave identically.
454
+ *
455
+ * @default 'sync'
456
+ */
457
+ flush?: 'sync' | 'pre' | 'post';
458
+ /**
459
+ * Watch deeply.
460
+ *
461
+ * React note: no React equivalent — a `.current` write never schedules a
462
+ * re-render by itself, so nested mutations cannot be observed (only the
463
+ * value as a whole is compared, via `Object.is`). Accepted for upstream
464
+ * signature compatibility.
465
+ *
466
+ * @default false
467
+ */
468
+ deep?: boolean;
469
+ /**
470
+ * Sync values immediately (on mount).
471
+ *
472
+ * @default true
473
+ */
474
+ immediate?: boolean;
475
+ /**
476
+ * Direction of syncing.
477
+ *
478
+ * @default 'both'
479
+ */
480
+ direction?: D;
481
+ /**
482
+ * Value convertors applied on the way to the other side: `ltr` maps a left
483
+ * value before it is written into the right state, `rtl` maps a right
484
+ * value before it is written into the left state. A missing convertor
485
+ * falls back to identity.
486
+ */
487
+ transform?: Partial<SyncStateTransform<L, R>>;
488
+ }
489
+ /**
490
+ * Two-way state synchronization — keeps two writable `State<T>` sources in
491
+ * sync, with optional direction and value transforms.
492
+ *
493
+ * Map from @vueuse/shared `syncRef`
494
+ * (`source/vueuse/packages/shared/syncRef/`), renamed `syncState` for the
495
+ * React port: the two sides are `State<T>` sources — a `[value, setter]`
496
+ * tuple, a `{ value, onChange }` pair, a ref-like `{ current }`, a getter or
497
+ * a plain value — instead of Vue refs. Each side is read with `toValue` and
498
+ * written back through its writable form (tuple setter / `onChange` /
499
+ * `.current`); plain values and getters have no write path, so that side is
500
+ * treated as read-only (the sync becomes one-way for it).
501
+ *
502
+ * React Hook adaptation: upstream drives both sides through Vue's reactive
503
+ * `watchPausable`, pausing all watchers while writing so a side never echoes
504
+ * its own write back. React has no reactive system, so `syncState` is
505
+ * implemented as a hook (call it unconditionally at the top of a component).
506
+ * A `useEffect` that runs after every commit compares each side's resolved
507
+ * value with the last observed one via `Object.is` and mirrors the changed
508
+ * side into the other — through the optional `transform` convertors when
509
+ * given — recording the value it just wrote as already observed on the
510
+ * receiving side (the React analogue of upstream's pause/resume). Ref-like
511
+ * `.current` writes are synchronous and need no absorption; writes through a
512
+ * setter / `onChange` are asynchronous, so until the target's value reflects
513
+ * the write the stale pre-write value is absorbed and never mistaken for an
514
+ * external change. Read-only sides (plain values / getters) are never marked
515
+ * as written, so a changing source keeps propagating. The initial sync
516
+ * (upstream default `immediate: true`) runs in the mount effect and cascades
517
+ * ltr before rtl,
518
+ * matching upstream's watcher creation order. Because the observation happens
519
+ * post-commit, an external mutation is only adopted on the render that
520
+ * follows it — the mutation itself never schedules a render, so a bare
521
+ * `.current` write outside of React is not observed (see the maintainer
522
+ * notes on reause #40 / #41). The returned `stop` function tears the
523
+ * synchronization down; the effect also stops doing any work once the owning
524
+ * component unmounts.
525
+ *
526
+ * @example
527
+ * const [a, setA] = useState('a')
528
+ * const [b, setB] = useState('b')
529
+ *
530
+ * const stop = syncState([a, setA], [b, setB])
531
+ *
532
+ * console.log(a) // a
533
+ *
534
+ * setB('foo') // then the component re-renders
535
+ * console.log(a) // foo
536
+ *
537
+ * setA('bar') // then the component re-renders
538
+ * console.log(b) // bar
539
+ *
540
+ * stop()
541
+ */
542
+ export declare function syncState<L, R, D extends SyncStateDirection = 'both'>(left: State<L>, right: State<R>, options?: SyncStateOptions<L, R, D>): () => void;
543
+ //#endregion
544
+ //#region syncStates/index.d.ts
545
+ export interface SyncStatesOptions {
546
+ /**
547
+ * Timing for syncing, same as watch's `flush` option.
548
+ *
549
+ * React note: there is no React equivalent — effects always run after
550
+ * commit, so `'sync'` / `'pre'` / `'post'` are accepted for upstream
551
+ * signature compatibility and all behave identically.
552
+ *
553
+ * @default 'sync'
554
+ */
555
+ flush?: 'sync' | 'pre' | 'post';
556
+ /**
557
+ * Watch deeply.
558
+ *
559
+ * React note: no React equivalent — a `.current` write never schedules a
560
+ * re-render by itself, so nested mutations cannot be observed (only the
561
+ * source value as a whole is compared, via `Object.is`). Accepted for
562
+ * upstream signature compatibility.
563
+ *
564
+ * @default false
565
+ */
566
+ deep?: boolean;
567
+ /**
568
+ * Sync values immediately (on mount).
569
+ *
570
+ * @default true
571
+ */
572
+ immediate?: boolean;
573
+ }
574
+ /**
575
+ * Keep target state(s) in sync with a source value — React port of VueUse's
576
+ * `syncRefs`.
577
+ *
578
+ * Map from @vueuse/shared `syncRefs`
579
+ * (`source/vueuse/packages/shared/syncRefs/`), renamed `syncStates` for the
580
+ * React port: the source is a `State<T>` — a plain value, getter, ref-like,
581
+ * `[value, setter]` tuple or `{ value, onChange }` pair (upstream:
582
+ * `WatchSource`) — resolved with `toValue`; the targets are writable
583
+ * `State<T>` sources written back through their writable form (tuple setter /
584
+ * `onChange` / `.current`); upstream's `flush` / `deep` / `immediate` options
585
+ * are kept for signature compatibility.
586
+ *
587
+ * React Hook adaptation: upstream syncs through Vue's reactive `watch`, and
588
+ * React has no reactive system — so `syncStates` is implemented as a hook
589
+ * (call it unconditionally at the top of a component). Internally a
590
+ * `useEffect` that runs after every commit compares the resolved source value
591
+ * with the last observed one via `Object.is`; a change is written through to
592
+ * all targets. Because the observation happens post-commit, the caller must
593
+ * re-render (e.g. `setState`) for a new source value to reach the targets —
594
+ * a bare mutation outside of React is never observed (see the maintainer
595
+ * notes on reause #40 / #41). The returned `stop` function tears the
596
+ * synchronization down; the effect also stops doing any work once the owning
597
+ * component unmounts.
598
+ *
599
+ * @example
600
+ * function Form() {
601
+ * const [source, setSource] = useState('hello')
602
+ * const [target, setTarget] = useState('target')
603
+ *
604
+ * const stop = syncStates(source, [target, setTarget])
605
+ *
606
+ * // during the first render `target` is still 'target' — the sync effect
607
+ * // runs after the commit, so the source reaches the target only once the
608
+ * // component has mounted (target === 'hello' afterwards).
609
+ * // Calling `setSource('foo')` re-renders and the effect then copies 'foo'
610
+ * // into the target state on the following commit.
611
+ *
612
+ * stop()
613
+ * }
614
+ */
615
+ export declare function syncStates<T>(source: State<T>, targets: State<T> | State<T>[], options?: SyncStatesOptions): () => void;
616
+ //#endregion
617
+ //#region until/index.d.ts
618
+ export interface UntilToMatchOptions {
619
+ /**
620
+ * Milliseconds timeout for promise to resolve/reject if the when condition does not meet.
621
+ * 0 for never timed out
622
+ *
623
+ * @default 0
624
+ */
625
+ timeout?: number;
626
+ /**
627
+ * Reject the promise when timeout
628
+ *
629
+ * @default false
630
+ */
631
+ throwOnTimeout?: boolean;
632
+ /**
633
+ * `deep` option for the internal watch — kept for API compatibility. The
634
+ * React poller re-reads the source on every tick, so deep observation is
635
+ * implicit and this option is effectively a no-op.
636
+ *
637
+ * @default false
638
+ */
639
+ deep?: boolean;
640
+ }
641
+ export interface UntilBaseInstance<T, Not extends boolean = false> {
642
+ toMatch: (<U extends T = T>(condition: (v: T) => v is U, options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, U>> : Promise<U>) & ((condition: (v: T) => boolean, options?: UntilToMatchOptions) => Promise<T>);
643
+ changed: (options?: UntilToMatchOptions) => Promise<T>;
644
+ changedTimes: (n?: number, options?: UntilToMatchOptions) => Promise<T>;
645
+ }
646
+ type Falsy = false | void | null | undefined | 0 | 0n | '';
647
+ export interface UntilValueInstance<T, Not extends boolean = false> extends UntilBaseInstance<T, Not> {
648
+ readonly not: UntilValueInstance<T, Not extends true ? false : true>;
649
+ toBe: <P = T>(value: P, options?: UntilToMatchOptions) => Not extends true ? Promise<T> : Promise<P>;
650
+ toBeTruthy: (options?: UntilToMatchOptions) => Not extends true ? Promise<T & Falsy> : Promise<Exclude<T, Falsy>>;
651
+ toBeNull: (options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, null>> : Promise<null>;
652
+ toBeUndefined: (options?: UntilToMatchOptions) => Not extends true ? Promise<Exclude<T, undefined>> : Promise<undefined>;
653
+ toBeNaN: (options?: UntilToMatchOptions) => Promise<T>;
654
+ }
655
+ type ElementOf<T> = T extends readonly unknown[] ? T[number] : never;
656
+ export interface UntilArrayInstance<T> extends UntilBaseInstance<T> {
657
+ readonly not: UntilArrayInstance<T>;
658
+ toContains: (value: ElementOf<T>, options?: UntilToMatchOptions) => Promise<T>;
659
+ }
660
+ /**
661
+ * Promised one-time watch for changes
662
+ *
663
+ * Map from @vueuse/shared `until`
664
+ * React adaptation: upstream resolves when Vue's reactive `watch` callback
665
+ * first observes the condition holding; React has no reactive refs or watch,
666
+ * so this port **polls** the source — a plain value or a zero-argument getter
667
+ * — at a small fixed interval (the same polling `useFetch` uses for its
668
+ * `refetch` watch) and resolves the promise the first time the condition
669
+ * holds. `until` is a **pure function, not a hook** — no React hooks are
670
+ * involved — so it can be used anywhere a plain promise utility can.
671
+ *
672
+ * A plain value is a snapshot: it never changes between polls, so use a getter
673
+ * when the value may change after `until` was called (`until(() => ref.current)`).
674
+ * A `Ref` / `{ current }` object is not accepted directly. The `value` passed to
675
+ * `toBe` / `toContains` is a plain value too.
676
+ *
677
+ * @example
678
+ * let count = 0
679
+ * void until(() => count).toMatch(v => v > 7).then(() => {
680
+ * alert('Counter is now larger than 7!')
681
+ * })
682
+ * count = 8 // the next poll resolves
683
+ *
684
+ * @see https://vueuse.org/shared/until/
685
+ */
686
+ export declare function until<T extends unknown[]>(r: () => T): UntilArrayInstance<T>;
687
+ export declare function until<T>(r: () => T): UntilValueInstance<T>;
688
+ export declare function until<T extends unknown[]>(r: T): UntilArrayInstance<T>;
689
+ export declare function until<T>(r: T): UntilValueInstance<T>;
690
+ //#endregion
691
+ //#region useArrayDifference/index.d.ts
692
+ export interface UseArrayDifferenceOptions {
693
+ /**
694
+ * Returns asymmetric difference
695
+ *
696
+ * @see https://en.wikipedia.org/wiki/Symmetric_difference
697
+ * @default false
698
+ */
699
+ symmetric?: boolean;
700
+ }
701
+ export type UseArrayDifferenceReturn<T = any> = T[];
702
+ export declare function useArrayDifference<T>(list: readonly T[], values: readonly T[], key?: keyof T, options?: UseArrayDifferenceOptions): UseArrayDifferenceReturn<T>;
703
+ export declare function useArrayDifference<T>(list: readonly T[], values: readonly T[], compareFn?: (value: T, othVal: T) => boolean, options?: UseArrayDifferenceOptions): UseArrayDifferenceReturn<T>;
704
+ //#endregion
705
+ //#region useArrayEvery/index.d.ts
706
+ export type UseArrayEveryReturn = boolean;
707
+ /**
708
+ * React port of VueUse's `useArrayEvery`.
709
+ *
710
+ * Map from @vueuse/shared `useArrayEvery`
711
+ * Mapping: upstream wraps `toValue(list).every(...)` in `computed(() => ...)`
712
+ * and returns a `ComputedRef`; React has no reactive value tracking, so this
713
+ * is a plain function recomputed on every render over the plain `list` array
714
+ * the caller passes. Hold the array in `useState` (or any render-scoped value)
715
+ * and pass a new array to observe a change — the result recomputes on the next
716
+ * render. The predicate may return any value (coerced by truthiness, like
717
+ * `Array.prototype.every`).
718
+ *
719
+ * @see https://vueuse.org/shared/useArrayEvery/
720
+ *
721
+ * @example
722
+ * const [list, setList] = useState([0, 2, 4])
723
+ * useArrayEvery(list, val => val % 2 === 0) // true
724
+ * setList([0, 2, 5]) // false on the next render
725
+ *
726
+ * @param list - the array was called upon.
727
+ * @param fn - a function to test each element.
728
+ *
729
+ * @returns **true** if the `fn` function returns a **truthy** value for every element from the array. Otherwise, **false**.
730
+ */
731
+ export declare function useArrayEvery<T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => unknown): UseArrayEveryReturn;
732
+ //#endregion
733
+ //#region useArrayFilter/index.d.ts
734
+ export type UseArrayFilterReturn<T = any> = T[];
735
+ /**
736
+ * Reactive `Array.filter`
737
+ *
738
+ * Map from @vueuse/shared `useArrayFilter`
739
+ * React port of VueUse's `useArrayFilter`.
740
+ *
741
+ * Mapping: Vue's `computed` → recompute per render and return a plain array
742
+ * (no `.value`) over the plain `list` array the caller passes. Pass a
743
+ * `useState` array directly — the filtered result updates on the next render.
744
+ *
745
+ * @see https://vueuse.org/useArrayFilter
746
+ *
747
+ * @example
748
+ * const [list, setList] = useState([0, 1, 2, 3, 4])
749
+ * const evens = useArrayFilter(list, i => i % 2 === 0) // [0, 2, 4]
750
+ * setList([1, 2, 3]) // evens === [2] on the next render
751
+ */
752
+ export declare function useArrayFilter<T, S extends T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => element is S): UseArrayFilterReturn<S>;
753
+ export declare function useArrayFilter<T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => unknown): UseArrayFilterReturn<T>;
754
+ //#endregion
755
+ //#region useArrayFind/index.d.ts
756
+ export type UseArrayFindReturn<T = any> = T | undefined;
757
+ /**
758
+ * React port of VueUse's `useArrayFind`.
759
+ *
760
+ * Map from @vueuse/shared `useArrayFind`
761
+ * Mapping: upstream wraps `toValue(list).find(...)` in `computed(() => ...)`
762
+ * and returns a `ComputedRef`; React has no reactive value tracking, so this
763
+ * is a plain function recomputed on every render over the plain `list` array
764
+ * the caller passes. Hold the array in `useState` and pass a new array to
765
+ * observe a change — the first match is returned on the next render.
766
+ *
767
+ * @see https://vueuse.org/shared/useArrayFind/
768
+ *
769
+ * @example
770
+ * const [list, setList] = useState([1, -1, 2])
771
+ * useArrayFind(list, val => val > 0) // 1
772
+ * setList([3, -1, 2]) // 3 on the next render
773
+ */
774
+ export declare function useArrayFind<T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => boolean): UseArrayFindReturn<T>;
775
+ //#endregion
776
+ //#region useArrayFindIndex/index.d.ts
777
+ export type UseArrayFindIndexReturn = number;
778
+ /**
779
+ * React port of VueUse's `useArrayFindIndex`.
780
+ *
781
+ * Map from @vueuse/shared `useArrayFindIndex`
782
+ * Mapping: upstream wraps `toValue(list).findIndex(...)` in `computed(...)`
783
+ * and accepts a `RefOrValue`; React has no reactive value tracking, so
784
+ * this is a plain function that recomputes the index on every render — pass
785
+ * a state array (upstream: reactive array) and re-render with new state to
786
+ * see the updated result. The return is a plain number, no `.value`.
787
+ *
788
+ * @example
789
+ * const [list, setList] = useState([0, 2, 4, 6, 8])
790
+ * useArrayFindIndex(list, i => i % 2 === 0) // 0
791
+ *
792
+ * setList([1, 3, 5, 7, 9]) // result === -1 on the next render
793
+ *
794
+ * @param list - the array was called upon.
795
+ * @param fn - a function to test each element.
796
+ *
797
+ * @returns the index of the first element in the array that passes the test. Otherwise, "-1".
798
+ */
799
+ export declare function useArrayFindIndex<T>(list: T[], fn: (element: T, index: number, array: T[]) => unknown): UseArrayFindIndexReturn;
800
+ //#endregion
801
+ //#region useArrayFindLast/index.d.ts
802
+ export type UseArrayFindLastReturn<T = any> = T | undefined;
803
+ /**
804
+ * React port of VueUse's `useArrayFindLast`.
805
+ *
806
+ * Map from @vueuse/shared `useArrayFindLast`
807
+ * Mapping: upstream wraps native `Array.prototype.findLast` (with a loop
808
+ * fallback for runtimes without it) in `computed(() => ...)` and returns a
809
+ * `ComputedRef`; React has no reactive value tracking, so this is a plain
810
+ * function recomputed on every render over the plain `list` array the caller
811
+ * passes — the loop helper stands in for the native method since the repo
812
+ * targets lib ES2022. Hold the array in `useState` and pass a new array to
813
+ * observe a change — the last match is returned on the next render.
814
+ *
815
+ * @see https://vueuse.org/shared/useArrayFindLast/
816
+ *
817
+ * @example
818
+ * const [list, setList] = useState([1, -1, 2])
819
+ * useArrayFindLast(list, val => val > 0) // 2
820
+ * setList([1, -1, -2]) // 1 on the next render
821
+ */
822
+ export declare function useArrayFindLast<T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => boolean): UseArrayFindLastReturn<T>;
823
+ //#endregion
824
+ //#region useArrayIncludes/index.d.ts
825
+ export type UseArrayIncludesComparatorFn<T, V> = (element: T, value: V, index: number, array: readonly T[]) => boolean;
826
+ export interface UseArrayIncludesOptions<T, V> {
827
+ fromIndex?: number;
828
+ comparator?: UseArrayIncludesComparatorFn<T, V> | keyof T;
829
+ }
830
+ export type UseArrayIncludesReturn = boolean;
831
+ /**
832
+ * React port of VueUse's `useArrayIncludes`.
833
+ *
834
+ * Map from @vueuse/shared `useArrayIncludes`
835
+ * Mapping: upstream wraps `toValue(list).slice(fromIndex).some(...)` in
836
+ * `computed(() => ...)` and returns a `ComputedRef`; React has no reactive
837
+ * value tracking, so this is a plain function recomputed on every render over
838
+ * the plain `list` array and `value` the caller passes. The default comparator
839
+ * mirrors `Array.prototype.includes` (strict equality). Hold the array in
840
+ * `useState` and pass a new array to observe a change.
841
+ *
842
+ * @see https://vueuse.org/shared/useArrayIncludes/
843
+ *
844
+ * @example
845
+ * const list = [0, 2, 4]
846
+ * useArrayIncludes(list, 2) // true
847
+ * useArrayIncludes(list, 8) // false
848
+ * useArrayIncludes([{ id: 1 }, { id: 2 }], 2, 'id') // true
849
+ * useArrayIncludes(list, 0, { fromIndex: 1, comparator: (a, b) => a === b }) // false
850
+ *
851
+ * @param list - the array was called upon.
852
+ * @param value - the value to search for.
853
+ * @param comparator - a function to compare elements with, a key of the elements to compare by, or an options object with `fromIndex` and `comparator`.
854
+ *
855
+ * @returns **true** if the `value` is found in the array. Otherwise, **false**.
856
+ */
857
+ export declare function useArrayIncludes<T, V = any>(list: readonly T[], value: V, comparator?: UseArrayIncludesComparatorFn<T, V>): UseArrayIncludesReturn;
858
+ export declare function useArrayIncludes<T, V = any>(list: readonly T[], value: V, comparator?: keyof T): UseArrayIncludesReturn;
859
+ export declare function useArrayIncludes<T, V = any>(list: readonly T[], value: V, options?: UseArrayIncludesOptions<T, V>): UseArrayIncludesReturn;
860
+ //#endregion
861
+ //#region useArrayJoin/index.d.ts
862
+ export type UseArrayJoinReturn = string;
863
+ /**
864
+ * React port of VueUse's `useArrayJoin`.
865
+ *
866
+ * Map from @vueuse/shared `useArrayJoin`
867
+ * Mapping: upstream wraps `toValue(list).map(i => toValue(i)).join(toValue(separator))`
868
+ * in `computed(...)` and accepts a `RefOrValue`; React has no reactive
869
+ * value tracking, so this is a plain function that recomputes the join on
870
+ * every render — pass a state array (upstream: reactive array) and re-render
871
+ * with new state to see the updated result. The return is a plain string,
872
+ * no `.value`.
873
+ *
874
+ * `list` holds plain values only: the elements are joined with
875
+ * `Array.prototype.join`, so no per-element unwrap happens (upstream
876
+ * `toValue`s each element). A function element would be stringified to its
877
+ * source instead of invoked.
878
+ *
879
+ * @example
880
+ * const [list, setList] = useState(['foo', 0, { prop: 'val' }])
881
+ * useArrayJoin(list) // 'foo,0,[object Object]'
882
+ * useArrayJoin(list, '--') // 'foo--0--[object Object]'
883
+ *
884
+ * setList([...list, 'bar']) // result === 'foo--0--[object Object]--bar' on the next render
885
+ *
886
+ * @param list - the array was called upon.
887
+ * @param separator - a string to separate each pair of adjacent elements of the array. If omitted, the array elements are separated with a comma (",").
888
+ *
889
+ * @returns a string with all array elements joined. If `list.length` is 0, the empty string is returned.
890
+ */
891
+ export declare function useArrayJoin(list: any[], separator?: string): UseArrayJoinReturn;
892
+ //#endregion
893
+ //#region useArrayMap/index.d.ts
894
+ export type UseArrayMapReturn<T = any> = T[];
895
+ /**
896
+ * Reactive `Array.map`
897
+ *
898
+ * Map from @vueuse/shared `useArrayMap`
899
+ * React port of VueUse's `useArrayMap`.
900
+ *
901
+ * Mapping: Vue's `computed` → recompute per render and return a plain array
902
+ * (no `.value`) over the plain `list` array the caller passes.
903
+ * Pass a `useState` array directly — the result updates on the next render.
904
+ *
905
+ * @example
906
+ * const [list, setList] = useState([0, 1, 2, 3, 4])
907
+ * const result = useArrayMap(list, i => i * 2) // [0, 2, 4, 6, 8]
908
+ * setList(list.slice(0, -1)) // result: [0, 2, 4, 6] on the next render
909
+ */
910
+ export declare function useArrayMap<T, U = T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => U): UseArrayMapReturn<U>;
911
+ //#endregion
912
+ //#region useArrayReduce/index.d.ts
913
+ export type UseArrayReducer<PV, CV, R> = (previousValue: PV, currentValue: CV, currentIndex: number) => R;
914
+ export type UseArrayReduceReturn<T = any> = T;
915
+ /**
916
+ * Reactive `Array.reduce`
917
+ *
918
+ * Map from @vueuse/shared `useArrayReduce`
919
+ * React port of VueUse's `useArrayReduce`.
920
+ *
921
+ * Mapping: upstream wraps `toValue(list).reduce(...)` in `computed(() => ...)`
922
+ * and returns a `ComputedRef`; React has no reactive value tracking, so this
923
+ * is a plain function recomputed on every render over the plain `list` array
924
+ * the caller passes. Hold the array in `useState` and pass a new array to
925
+ * observe a change — the reduced result recomputes on the next render.
926
+ *
927
+ * @see https://vueuse.org/shared/useArrayReduce/
928
+ *
929
+ * @example
930
+ * const [list, setList] = useState([1, 2, 3])
931
+ * useArrayReduce(list, (prev, item) => prev + item) // 6
932
+ * setList([4, 2, 3]) // 9 on the next render
933
+ *
934
+ * @param list - the array was called upon.
935
+ * @param reducer - a "reducer" function.
936
+ *
937
+ * @returns the value that results from running the "reducer" callback function to completion over the entire array.
938
+ */
939
+ export declare function useArrayReduce<T>(list: readonly T[], reducer: UseArrayReducer<T, T, T>): UseArrayReduceReturn<T>;
940
+ /**
941
+ * Reactive `Array.reduce`
942
+ *
943
+ * @param list - the array was called upon.
944
+ * @param reducer - a "reducer" function.
945
+ * @param initialValue - a value (or a React lazy-initializer function, invoked
946
+ * per evaluation like `useState`) to be initialized the first time when the callback is called.
947
+ *
948
+ * @returns the value that results from running the "reducer" callback function to completion over the entire array.
949
+ */
950
+ export declare function useArrayReduce<T, U>(list: readonly T[], reducer: UseArrayReducer<U, T, U>, initialValue: U | (() => U)): UseArrayReduceReturn<U>;
951
+ //#endregion
952
+ //#region useArraySome/index.d.ts
953
+ export type UseArraySomeReturn = boolean;
954
+ /**
955
+ * React port of VueUse's `useArraySome`.
956
+ *
957
+ * Map from @vueuse/shared `useArraySome`
958
+ * Mapping: `computed(() => ...)` → recompute on every render — the result is a
959
+ * plain `boolean` (no `.value`, no caching) computed from the plain `list`
960
+ * array the caller passes. Hold the array in `useState` and pass a new array
961
+ * to observe a change; the result recomputes on the next render.
962
+ *
963
+ * @see https://vueuse.org/shared/useArraySome/
964
+ * @param list - the array was called upon.
965
+ * @param fn - a function to test each element.
966
+ *
967
+ * @returns **true** if the `fn` function returns a **truthy** value for any element from the array. Otherwise, **false**.
968
+ *
969
+ * @example
970
+ * const [list, setList] = useState([0, 2, 4, 6, 8])
971
+ * const result = useArraySome(list, i => i > 10) // false
972
+ * setList([...list, 11]) // result === true on the next render
973
+ */
974
+ export declare function useArraySome<T>(list: readonly T[], fn: (element: T, index: number, array: readonly T[]) => unknown): UseArraySomeReturn;
975
+ //#endregion
976
+ //#region useArrayUnique/index.d.ts
977
+ export type UseArrayUniqueReturn<T = any> = T[];
978
+ /**
979
+ * Reactive `Array.unique`
980
+ *
981
+ * Map from @vueuse/shared `useArrayUnique`
982
+ * React port of VueUse's `useArrayUnique`.
983
+ *
984
+ * Mapping: upstream wraps `toValue(list)` in `computed(() => ...)` and returns
985
+ * a `ComputedRef`; React has no reactive value tracking, so this is a plain
986
+ * function recomputed on every render over the plain `list` array the caller
987
+ * passes — the result is a deduped plain array (no `.value`, no caching).
988
+ * Duplicate detection uses a `Set` of the values (reference identity for
989
+ * objects) unless a custom `compareFn` is given — same as upstream. Hold the
990
+ * array in `useState` and pass a new array to observe a change.
991
+ *
992
+ * @see https://vueuse.org/shared/useArrayUnique/
993
+ *
994
+ * @example
995
+ * const [list, setList] = useState([0, 2, 2, 4, 4, 4])
996
+ * const result = useArrayUnique(list) // [0, 2, 4]
997
+ *
998
+ * setList([0, 2, 4, 6, 6]) // result === [0, 2, 4, 6] on the next render
999
+ */
1000
+ export declare function useArrayUnique<T>(list: readonly T[], compareFn?: (a: T, b: T, array: readonly T[]) => boolean): UseArrayUniqueReturn<T>;
1001
+ //#endregion
1002
+ //#region useCounter/index.d.ts
1003
+ export interface UseCounterOptions {
1004
+ min?: number;
1005
+ max?: number;
1006
+ }
1007
+ export interface UseCounterReturn {
1008
+ /**
1009
+ * The current value of the counter.
1010
+ */
1011
+ count: number;
1012
+ /**
1013
+ * Increment the counter.
1014
+ *
1015
+ * @param {number} [delta=1] The number to increment.
1016
+ */
1017
+ inc: (delta?: number) => void;
1018
+ /**
1019
+ * Decrement the counter.
1020
+ *
1021
+ * @param {number} [delta=1] The number to decrement.
1022
+ */
1023
+ dec: (delta?: number) => void;
1024
+ /**
1025
+ * Get the current value of the counter — the latest rendered value (React
1026
+ * state updates are applied on the next render, so a read right after
1027
+ * `inc` / `dec` / `set` still sees the previous value).
1028
+ */
1029
+ get: () => number;
1030
+ /**
1031
+ * Set the counter to a new value (clamped to `[min, max]`).
1032
+ *
1033
+ * @param value The new value of the counter.
1034
+ */
1035
+ set: (value: number) => void;
1036
+ /**
1037
+ * Reset the counter to the initial value — or to `val` when passed, which
1038
+ * also rebases the value future resets restore — and return the new value.
1039
+ *
1040
+ * @param val The value to reset to (defaults to the initial value).
1041
+ */
1042
+ reset: (val?: number) => number;
1043
+ }
1044
+ /**
1045
+ * React port of VueUse's `useCounter`.
1046
+ *
1047
+ * Map from @vueuse/shared `useCounter`
1048
+ * Mapping: `ref(initialValue)` → `useState`, mutation functions become
1049
+ * stable `useCallback`s; options are kept in refs so callbacks stay stable.
1050
+ *
1051
+ * @example
1052
+ * const { count, inc, dec, set, reset } = useCounter(10, { min: 0, max: 100 })
1053
+ */
1054
+ export declare function useCounter(initialValue?: State<number>, options?: UseCounterOptions): UseCounterReturn;
1055
+ //#endregion
1056
+ //#region useDateFormat/index.d.ts
1057
+ export type DateLike = Date | number | string | undefined;
1058
+ export interface UseDateFormatOptions {
1059
+ /**
1060
+ * The locale(s) to used for dd/ddd/dddd/MMM/MMMM format
1061
+ *
1062
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument).
1063
+ *
1064
+ * A plain locale (or locale array), matching upstream's
1065
+ * `MaybeRefOrGetter<Intl.LocalesArgument>` resolved to its current value.
1066
+ */
1067
+ locales?: Intl.LocalesArgument;
1068
+ /**
1069
+ * A custom function to re-modify the way to display meridiem
1070
+ *
1071
+ */
1072
+ customMeridiem?: (hours: number, minutes: number, isLowercase?: boolean, hasPeriod?: boolean) => string;
1073
+ }
1074
+ /**
1075
+ * Unwrap the house input convention — a plain value, a ref-like `{ current }`
1076
+ * or a getter function (house replacement for Vue's `toValue` /
1077
+ * `RefOrValue<T>`).
1078
+ */
1079
+ export declare function formatDate(date: Date, formatStr: string, options?: UseDateFormatOptions): string;
1080
+ export declare function normalizeDate(date: DateLike): Date;
1081
+ /**
1082
+ * The return type of `useDateFormat`.
1083
+ *
1084
+ * Upstream (`@vueuse/shared`) declares `ComputedRef<string>`; this React port
1085
+ * returns the formatted string directly — a plain `string` recomputed on every
1086
+ * render / call.
1087
+ */
1088
+ export type UseDateFormatReturn = string;
1089
+ /**
1090
+ * Get the formatted date according to the string of tokens passed in.
1091
+ *
1092
+ * Map from @vueuse/shared `useDateFormat`.
1093
+ *
1094
+ * React divergence: upstream wraps the result in a Vue `computed` and returns
1095
+ * `ComputedRef<string>` — this port returns a PLAIN STRING. Call it during
1096
+ * render and pass plain values (e.g. your `useState` date); the string is
1097
+ * recomputed on every render with fresh inputs. Do not read `.value` from it.
1098
+ *
1099
+ * Inputs (`date`, `formatStr`, `options.locales`) are plain read-only values
1100
+ * — pass `ref.current` or the state value; a `MaybeRefOrGetter` source must be
1101
+ * resolved by the caller (upstream types them `MaybeRefOrGetter`).
1102
+ *
1103
+ * Supported tokens (mirroring upstream 1:1, default format `HH:mm:ss`):
1104
+ * `Yo YY YYYY` — year · `M Mo MM MMM MMMM` — month (locale-aware short/long
1105
+ * names via `Intl`) · `D Do DD` — day of month · `H Ho HH` — 24-hour clock ·
1106
+ * `h ho hh` — 12-hour clock · `m mo mm` — minutes · `s so ss` — seconds ·
1107
+ * `SSS` — milliseconds (3 digits) · `d dd ddd dddd` — weekday (locale-aware
1108
+ * via `Intl`) · `A AA a aa` — meridiem, customizable via
1109
+ * `options.customMeridiem` · `z zz zzz zzzz` — timezone offset names
1110
+ * (`shortOffset` / `longOffset` via `toLocaleString`). Text wrapped in
1111
+ * brackets (`[...]`) is output literally as an escape sequence.
1112
+ *
1113
+ * @see https://vueuse.org/useDateFormat
1114
+ * @param date - The date to format, can either be a `Date` object, a timestamp, or a string
1115
+ * @param formatStr - The combination of tokens to format the date
1116
+ * @param options - UseDateFormatOptions
1117
+ *
1118
+ * @__NO_SIDE_EFFECTS__
1119
+ */
1120
+ export declare function useDateFormat(date: DateLike, formatStr?: string, options?: UseDateFormatOptions): UseDateFormatReturn;
1121
+ //#endregion
1122
+ //#region useDebounceFn/index.d.ts
1123
+ export type FunctionArgs<Args extends any[] = any[], Return = unknown> = (...args: Args) => Return;
1124
+ export interface DebounceFilterOptions {
1125
+ /**
1126
+ * The maximum time allowed to be delayed before it's invoked.
1127
+ * In milliseconds.
1128
+ */
1129
+ maxWait?: RefOrValue<number>;
1130
+ /**
1131
+ * Whether to reject the last call if it's been cancelled.
1132
+ *
1133
+ * @default false
1134
+ */
1135
+ rejectOnCancel?: boolean;
1136
+ }
1137
+ export interface UseDebounceFnReturn<T extends FunctionArgs> {
1138
+ (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
1139
+ /**
1140
+ * Cancel the pending invocation — the outstanding promise settles
1141
+ * (resolves, or rejects with `rejectOnCancel`) without calling `fn`.
1142
+ */
1143
+ cancel: () => void;
1144
+ /**
1145
+ * Invoke the pending call immediately and settle its promise with the result.
1146
+ */
1147
+ flush: () => void;
1148
+ /**
1149
+ * `true` while a call is waiting to be invoked.
1150
+ *
1151
+ * Note: unlike upstream's reactive readonly ref, this is a plain
1152
+ * (non-reactive) getter — read it imperatively, it does not trigger
1153
+ * re-renders.
1154
+ */
1155
+ readonly isPending: boolean;
1156
+ }
1157
+ /**
1158
+ * Debounce execution of a function — React port of VueUse's `useDebounceFn`.
1159
+ *
1160
+ * Map from @vueuse/shared `useDebounceFn`
1161
+ * Mapping: upstream builds `createFilterWrapper(debounceFilter(ms, options), fn)`
1162
+ * so every call returns a promise and the wrapper carries `cancel` / `flush` /
1163
+ * `isPending`. This port builds the same wrapper once (`useMemo`) so its
1164
+ * identity is stable across renders; the latest `fn` / `ms` / `options` are
1165
+ * mirrored into refs so every call sees fresh values. `ms` accepts a number or
1166
+ * a ref-like `{ current }` (upstream: `RefOrValue<number>`) and is re-read on
1167
+ * every call. `isPending` becomes a non-reactive getter (React has no reactive
1168
+ * refs); promise settlement mirrors upstream — a regular debounce resolves
1169
+ * with the result, a superseded/canceled call settles with `undefined` (or
1170
+ * rejects with `rejectOnCancel`), and the `maxWait` trailing edge runs the
1171
+ * latest invocation but settles the pending promise without its result.
1172
+ * Pending timers are cleared when the component unmounts (upstream leaves
1173
+ * disposal to the effect scope).
1174
+ *
1175
+ * @example
1176
+ * const debouncedFn = useDebounceFn(() => { ... }, 1000)
1177
+ * debouncedFn()
1178
+ * debouncedFn.cancel()
1179
+ * debouncedFn.flush()
1180
+ */
1181
+ export declare function useDebounceFn<T extends FunctionArgs>(fn: T, ms?: RefOrValue<number>, options?: DebounceFilterOptions): UseDebounceFnReturn<T>;
1182
+ //#endregion
1183
+ //#region useInterval/index.d.ts
1184
+ export interface UseIntervalOptions<Controls extends boolean = false> {
1185
+ /**
1186
+ * Expose more controls
1187
+ *
1188
+ * @default false
1189
+ */
1190
+ controls?: Controls;
1191
+ /**
1192
+ * Start the interval automatically on mount
1193
+ *
1194
+ * @default true
1195
+ */
1196
+ immediate?: boolean;
1197
+ /**
1198
+ * Callback on every interval tick, receives the incremented count
1199
+ */
1200
+ callback?: (count: number) => void;
1201
+ /**
1202
+ * Increment the counter (and fire `callback`) immediately when the interval
1203
+ * starts or `resume` is called
1204
+ *
1205
+ * @default false
1206
+ */
1207
+ immediateCallback?: boolean;
1208
+ }
1209
+ export interface UseIntervalControls {
1210
+ /**
1211
+ * Current count
1212
+ */
1213
+ counter: number;
1214
+ /**
1215
+ * Reset the counter to `0`
1216
+ */
1217
+ reset: () => void;
1218
+ /**
1219
+ * `true` while the interval is running
1220
+ */
1221
+ isActive: boolean;
1222
+ /**
1223
+ * Stop the interval
1224
+ */
1225
+ pause: () => void;
1226
+ /**
1227
+ * (Re)start the interval
1228
+ */
1229
+ resume: () => void;
1230
+ }
1231
+ export type UseIntervalReturn = number | UseIntervalControls;
1232
+ /**
1233
+ * React port of VueUse's `useInterval`.
1234
+ *
1235
+ * Map from @vueuse/shared `useInterval`
1236
+ * Mapping: upstream wraps `useIntervalFn` and returns a readonly
1237
+ * `ShallowRef<number>`; since `useIntervalFn` is mapped in its own module,
1238
+ * this port inlines the interval logic to stay self-contained — the counter
1239
+ * is a plain `number` state (no `.value`), the setup-time `resume()`
1240
+ * (`immediate`) becomes a mount `useEffect` (guarded against the StrictMode
1241
+ * double-invocation so `immediateCallback` fires only once), and
1242
+ * `tryOnScopeDispose(pause)` becomes the effect cleanup. `{ controls: true }`
1243
+ * exposes `counter` / `reset` plus the `Pausable` controls (`isActive` /
1244
+ * `pause` / `resume`). `interval` accepts a number or a React ref (upstream:
1245
+ * `RefOrValue<number>`); like upstream's reactive watch, a changed interval
1246
+ * live-restarts the timer while it is active (a ref's `.current` mutation is
1247
+ * only picked up on the next render — React has no reactive refs).
1248
+ * `immediateCallback` follows `useIntervalFn`'s semantics (upstream
1249
+ * `useInterval` doesn't forward it). `pause` / `resume` / `reset` are stable
1250
+ * `useCallback`s.
1251
+ *
1252
+ * @example
1253
+ * // count will increase every 200ms
1254
+ * const counter = useInterval(200)
1255
+ *
1256
+ * const { counter, isActive, pause, resume, reset } = useInterval(200, { controls: true })
1257
+ */
1258
+ export declare function useInterval(interval?: RefOrValue<number>, options?: UseIntervalOptions<false>): number;
1259
+ export declare function useInterval(interval: RefOrValue<number>, options: UseIntervalOptions<true>): UseIntervalControls;
1260
+ //#endregion
1261
+ //#region useIntervalFn/index.d.ts
1262
+ type Fn = () => void;
1263
+ export interface UseIntervalFnOptions {
1264
+ /**
1265
+ * Start the timer automatically when the component mounts
1266
+ *
1267
+ * @default true
1268
+ */
1269
+ immediate?: boolean;
1270
+ /**
1271
+ * Execute the callback immediately after calling `resume`
1272
+ *
1273
+ * @default false
1274
+ */
1275
+ immediateCallback?: boolean;
1276
+ }
1277
+ export interface UseIntervalFnReturn {
1278
+ /**
1279
+ * Whether the timer is currently active
1280
+ */
1281
+ isActive: boolean;
1282
+ /**
1283
+ * Pause the timer
1284
+ */
1285
+ pause: () => void;
1286
+ /**
1287
+ * Resume the timer (restarts it with the current interval)
1288
+ */
1289
+ resume: () => void;
1290
+ }
1291
+ /**
1292
+ * React port of VueUse's `useIntervalFn` — wrapper for `setInterval` with
1293
+ * controls.
1294
+ *
1295
+ * Map from @vueuse/shared `useIntervalFn`
1296
+ * Mapping: upstream accepts `RefOrValue<number>` for the interval — this
1297
+ * port accepts a plain `number`. `isActive` is a boolean state (upstream: a
1298
+ * readonly shallow ref), also mirrored in a ref so `resume()` can check it
1299
+ * synchronously right after `immediateCallback` fires the callback — the
1300
+ * callback may `pause()` itself ("pause in callback"). The timer is scheduled
1301
+ * in a mount effect (upstream starts synchronously during setup) and cleared
1302
+ * on unmount via effect cleanup; changing the interval while active restarts
1303
+ * the timer (upstream: a `watch` on the interval calls `resume()`). The
1304
+ * callback, interval and options are kept in refs so every tick and restart
1305
+ * uses the newest ones.
1306
+ *
1307
+ * @example
1308
+ * const { isActive, pause, resume } = useIntervalFn(() => { ... }, 1000)
1309
+ */
1310
+ export declare function useIntervalFn(cb: Fn, interval?: number, options?: UseIntervalFnOptions): UseIntervalFnReturn;
1311
+ //#endregion
1312
+ //#region useLastChanged/index.d.ts
1313
+ export interface UseLastChangedOptions<InitialValue extends number | null | undefined = undefined> {
1314
+ /**
1315
+ * Value returned before any change has been recorded.
1316
+ *
1317
+ * (Upstream also extends Vue's `WatchOptions` — `immediate` / `deep` /
1318
+ * `flush` / `once` have no React equivalent here, see the mapping note.)
1319
+ *
1320
+ * @default null
1321
+ */
1322
+ initialValue?: InitialValue;
1323
+ }
1324
+ export type UseLastChangedReturn = number | null;
1325
+ /**
1326
+ * React port of VueUse's `useLastChanged`.
1327
+ *
1328
+ * Map from @vueuse/shared `useLastChanged`
1329
+ * Records the timestamp of the last change
1330
+ *
1331
+ * @see https://vueuse.org/shared/useLastChanged
1332
+ */
1333
+ export declare function useLastChanged<T>(value: T, options?: UseLastChangedOptions<undefined>): UseLastChangedReturn;
1334
+ export declare function useLastChanged<T>(value: T, options: UseLastChangedOptions<number>): number;
1335
+ //#endregion
1336
+ //#region useListener/index.d.ts
1337
+ /**
1338
+ * A listener registration function — the `onXxx` callbacks returned by hooks
1339
+ * such as `useFileDialog`'s `onChange` / `onCancel`. Mirror of upstream
1340
+ * `EventHookOn<T>`.
1341
+ */
1342
+ export type ListenerOn<T extends (...args: any[]) => void> = (fn: T) => {
1343
+ off: () => void;
1344
+ } | void;
1345
+ /**
1346
+ * React port of the `useListener` protocol — bind a callback to an event
1347
+ * registration function returned by a reause hook, with automatic cleanup
1348
+ * on unmount.
1349
+ *
1350
+ * Map from @reause/shared `useListener` (protocol: #129)
1351
+ * Motivation: hooks like `useFileDialog` return `onChange` / `onCancel`
1352
+ * registration functions (upstream `EventHookOn`). In Vue those auto-clean
1353
+ * via the effect scope; in React we need a hook to own that lifecycle.
1354
+ * `useListener` registers `cb` with `on` on mount and, when `on` returns an
1355
+ * `off` function, calls it on unmount, so listeners are cleaned up and
1356
+ * callbacks never fire after the component is gone. (An `on` that returns
1357
+ * nothing provides no cleanup — nothing can be released.) The callback is
1358
+ * kept in a ref, so changing `cb` across renders does not re-register — the
1359
+ * latest callback is used by the already-registered listener. If `on` itself
1360
+ * changes (a new hook instance), the effect re-runs and re-registers.
1361
+ *
1362
+ * @example
1363
+ * const { files, open, onChange } = useFileDialog()
1364
+ * useListener(onChange, (files) => { console.log(files) })
1365
+ */
1366
+ export declare function useListener<T extends (...args: any[]) => void>(on: ListenerOn<T>, cb: T): void;
1367
+ //#endregion
1368
+ //#region useMount/index.d.ts
1369
+ /**
1370
+ * React port of react-use's `useMount`.
1371
+ *
1372
+ * Map from react-use `useMount`.
1373
+ * Runs `fn` exactly once after the component mounts.
1374
+ *
1375
+ * @example
1376
+ * useMount(() => {
1377
+ * trackPageView()
1378
+ * })
1379
+ */
1380
+ export declare function useMount(fn: () => void): void;
1381
+ //#endregion
1382
+ //#region useStateAutoReset/index.d.ts
1383
+ export type UseStateAutoResetReturn<T = any> = [T, Dispatch<SetStateAction<T>>];
1384
+ /**
1385
+ * A state which will be reset to the default value after some time.
1386
+ *
1387
+ * Map from @vueuse/shared `refAutoReset`
1388
+ * (`source/vueuse/packages/shared/refAutoReset/`). Upstream returns a single
1389
+ * writable Vue ref; per this repo's `useState*` family convention the return
1390
+ * is the React `[value, setValue]` tuple — `value` is the state, `setValue`
1391
+ * is a `useState`-style setter (value or updater form, `Dispatch<SetStateAction>`)
1392
+ * that also (re)schedules a timer to restore `defaultValue` after `afterMs`
1393
+ * milliseconds. `defaultValue` accepts the shared `State<T>` form (plain value,
1394
+ * lazy getter, ref-like object, state tuple, or controlled `{ value, onChange }` pair).
1395
+ * `afterMs` accepts the shared `RefOrValue<number>` form and is resolved with `toValue` at fire time
1396
+ * (upstream: `toValue`); the pending timer is cleared on unmount (upstream:
1397
+ * `tryOnScopeDispose`, timers in the effect scope). The deprecated `autoResetRef`
1398
+ * alias is not ported.
1399
+ *
1400
+ * @param defaultValue The value which will be set.
1401
+ * @param afterMs A zero-or-greater delay in milliseconds.
1402
+ * @example
1403
+ * const [message, setMessage] = useStateAutoReset('default message', 1000)
1404
+ *
1405
+ * function handleMessage() {
1406
+ * setMessage('message has set') // resets to 'default message' after 1000ms
1407
+ * }
1408
+ */
1409
+ export declare function useStateAutoReset<T = any>(defaultValue: State<T>, afterMs?: RefOrValue<number>): UseStateAutoResetReturn<T>;
1410
+ //#endregion
1411
+ //#region useStateDebounced/index.d.ts
1412
+ export type UseStateDebouncedReturn<T = any> = [value: T, setValue: Dispatch<SetStateAction<T>>, debounced: T];
1413
+ /**
1414
+ * Debounce updates of a state value — React port of VueUse's `refDebounced`.
1415
+ *
1416
+ * Map from @vueuse/shared `refDebounced`
1417
+ * Mapping: upstream takes a Vue `Ref<T>` and returns a readonly ref that only
1418
+ * flips to the latest source value once it stops changing for `ms` (a watcher
1419
+ * hands every change to `useDebounceFn`). The naming follows this repo's
1420
+ * `ref* → useState*` rule (`refDebounced` → `useStateDebounced`), the Vue
1421
+ * `Ref<T>` input becomes a plain initial value, and the readonly ref becomes
1422
+ * an extra state slot — so the hook returns the tuple
1423
+ * `[value, setValue, debounced]`:
1424
+ *
1425
+ * ```ts
1426
+ * const [input, setInput, debounced] = useStateDebounced('foo', 1000)
1427
+ *
1428
+ * setInput('bar')
1429
+ * console.log(debounced) // 'foo' — flips to 'bar' once the debounce elapses
1430
+ * ```
1431
+ *
1432
+ * `value` is the source state, `setValue` its setter, and `debounced` lags
1433
+ * behind it by `ms`. Writes settle through a `useDebounceFn` updater, so a
1434
+ * burst of writes collapses into a single trailing update carrying the last
1435
+ * written value. `ms` (and `options.maxWait`) accept a plain number or a
1436
+ * ref-like `{ current }` (upstream: `RefOrValue<number>`) and are re-read on
1437
+ * every write; pending timers are cleared when the component unmounts
1438
+ * (upstream disposes with the effect scope). Note: a write only schedules the
1439
+ * debounce when the value actually changes — writing the same value is
1440
+ * skipped by `useControllableState`'s `Object.is` guard, so the pending timer
1441
+ * is not re-delayed (upstream's `watch` re-delays on every source write, even
1442
+ * unchanged ones).
1443
+ *
1444
+ * @example
1445
+ * ```ts
1446
+ * const [value, setValue, debounced] = useStateDebounced('foo', 1000)
1447
+ * ```
1448
+ */
1449
+ export declare function useStateDebounced<T>(value: State<T>, ms?: RefOrValue<number>, options?: DebounceFilterOptions): UseStateDebouncedReturn<T>;
1450
+ //#endregion
1451
+ //#region useStateDefault/index.d.ts
1452
+ export type UseStateDefaultReturn<T = any> = [
1453
+ /**
1454
+ * Current value — the source's current value, or `defaultValue` when the
1455
+ * source is `null`/`undefined`.
1456
+ */
1457
+ value: T,
1458
+ /**
1459
+ * Setter to update the value (value or updater form, like `setState`) —
1460
+ * writes through to a ref-like source's `current`, a state tuple's setter
1461
+ * or a `{ value, onChange }` source's `onChange`.
1462
+ */
1463
+ setValue: Dispatch<SetStateAction<T | undefined | null>>];
1464
+ /**
1465
+ * Apply default value to a ref-like source — React port of VueUse's
1466
+ * `refDefault` renamed to `useStateDefault` (this repo's naming for the
1467
+ * `ref*` family; upstream's single writable computed ref becomes a tuple).
1468
+ *
1469
+ * Map from @vueuse/shared `refDefault`
1470
+ * Mapping: upstream derives a writable `computed` from a source
1471
+ * `Ref<T | undefined | null>` — it reads `source.value ?? defaultValue` and
1472
+ * writes back to `source.value`. This port accepts a `State<T | undefined |
1473
+ * null>` — a plain value, a ref-like object (`{ current }`, e.g. the first
1474
+ * tuple element of `useStorage`), a getter, a `[value, setter]` tuple or a
1475
+ * `{ value, onChange }` pair — and returns the React tuple
1476
+ * `const [value, setValue] = useStateDefault(raw, 'default')`. `value` is
1477
+ * derived on every render from the source through `toValue` (`source.current
1478
+ * ?? defaultValue`), so it always reflects the source's current value —
1479
+ * including writes made from outside the component; `setValue` resolves the
1480
+ * next value (value or updater form), writes it through to the source (its
1481
+ * `current`, its setter or its `onChange`) and bumps a local version counter
1482
+ * so the derived `value` re-renders. SSR-safe: nothing touches the DOM and the
1483
+ * first server render already shows the default.
1484
+ *
1485
+ * @param source The `State<T | undefined | null>` source holding the
1486
+ * value — read through `toValue` on every render and
1487
+ * written back to `current` / the tuple setter /
1488
+ * `onChange` on `setValue`.
1489
+ * @param defaultValue The value displayed while the source is `null` or
1490
+ * `undefined`.
1491
+ * @return A tuple `[value, setValue]` — the current value (source value or
1492
+ * `defaultValue`) and its setter.
1493
+ *
1494
+ * @example
1495
+ * const raw = { current: undefined as string | undefined }
1496
+ * const [value, setValue] = useStateDefault(raw, 'default')
1497
+ *
1498
+ * setValue('hello')
1499
+ * console.log(value) // 'hello' after the next render (React derives at render)
1500
+ *
1501
+ * setValue(undefined)
1502
+ * console.log(value) // 'default' after the next render
1503
+ */
1504
+ export declare function useStateDefault<T = any>(source: State<T | undefined | null>, defaultValue: T): UseStateDefaultReturn<T>;
1505
+ //#endregion
1506
+ //#region useStateManualReset/index.d.ts
1507
+ export type UseStateManualResetReturn<T> = [value: T, setValue: Dispatch<SetStateAction<T>>, reset: () => void];
1508
+ /**
1509
+ * React port of VueUse's `refManualReset`.
1510
+ *
1511
+ * Map from @vueuse/shared `refManualReset`
1512
+ * (`source/vueuse/packages/shared/refManualReset/`). Create a state with
1513
+ * manual reset functionality — any update can be reverted back to the initial
1514
+ * value with the returned `reset` function.
1515
+ *
1516
+ * Upstream returns a writable Vue `Ref<T>` extended with a `reset` method
1517
+ * (built on `customRef`). Per this repo's naming rules the port is renamed to
1518
+ * `useStateManualReset` and the ref becomes a `[value, setValue, reset]`
1519
+ * tuple: the second element is the plain `useState` setter (value or updater
1520
+ * form), and `reset` restores the default value.
1521
+ *
1522
+ * The state input accepts the shared `State<T>` form: a value, getter, ref-like
1523
+ * object, state tuple, or controlled `{ value, onChange }` object. `reset`
1524
+ * re-reads the input on every call, so plain, getter and ref-like sources
1525
+ * reset to the latest source value (matching upstream's
1526
+ * `value = toValue(defaultValue)`); tuple / `{ value, onChange }` (controlled)
1527
+ * sources have no stored default, so they restore the initial argument value.
1528
+ *
1529
+ * @example
1530
+ * const [message, setMessage, resetMessage] = useStateManualReset('default message')
1531
+ * setMessage('message has set')
1532
+ * resetMessage()
1533
+ * console.log(message) // 'default message'
1534
+ */
1535
+ export declare function useStateManualReset<T>(value: State<T>): UseStateManualResetReturn<T>;
1536
+ //#endregion
1537
+ //#region useStateThrottled/index.d.ts
1538
+ export type UseStateThrottledReturn<T = any> = [value: T, setValue: Dispatch<SetStateAction<T>>, throttled: T];
1539
+ /**
1540
+ * Throttle changing of a state value — React port of VueUse's `refThrottled`.
1541
+ *
1542
+ * The `value` argument accepts any `State<T>` supported by
1543
+ * `useControllableState`: a plain value, lazy initializer, controlled tuple,
1544
+ * or `{ value, onChange }` source. The returned tuple contains the current
1545
+ * value, its setter, and a throttled mirror.
1546
+ *
1547
+ * A `delay <= 0` short-circuits like upstream (`if (delay <= 0) return value`):
1548
+ * the throttled element is the input itself — no throttling, no timers.
1549
+ *
1550
+ * @param value State source accepted by `useControllableState`.
1551
+ * @param delay Delay in milliseconds between commits (default: 200).
1552
+ * @param trailing Whether to commit the latest value after the window (default: true).
1553
+ * @param leading Whether to commit on the leading edge (default: true).
1554
+ */
1555
+ export declare function useStateThrottled<T = any>(value: State<T>, delay?: number, trailing?: boolean, leading?: boolean): UseStateThrottledReturn<T>;
1556
+ //#endregion
1557
+ //#region useStateWithControl/index.d.ts
1558
+ export interface UseStateWithControlOptions<T> {
1559
+ /**
1560
+ * Callback function before the state changing.
1561
+ *
1562
+ * Returning `false` to dismiss the change.
1563
+ */
1564
+ onBeforeChange?: (value: T, oldValue: T) => void | boolean;
1565
+ /**
1566
+ * Callback function after the state changed.
1567
+ *
1568
+ * This happens synchronously, with less overhead compared to an effect.
1569
+ */
1570
+ onChanged?: (value: T, oldValue: T) => void;
1571
+ }
1572
+ export interface UseStateWithControlControls<T> {
1573
+ /**
1574
+ * Get the current value. The `tracking` argument is accepted for API parity
1575
+ * with upstream but is a no-op in React — there is no reactivity dependency
1576
+ * collection during render.
1577
+ */
1578
+ get: (tracking?: boolean) => T;
1579
+ /**
1580
+ * Set the value with fine-grained control. `triggering` controls whether the
1581
+ * change re-renders the component (defaults to `true`).
1582
+ */
1583
+ set: (value: T, triggering?: boolean) => void;
1584
+ /**
1585
+ * Get the value without tracking in the reactivity system — alias for
1586
+ * `get(false)`.
1587
+ */
1588
+ untrackedGet: () => T;
1589
+ /**
1590
+ * Set the value without triggering the reactivity system — alias for
1591
+ * `set(value, false)`.
1592
+ */
1593
+ silentSet: (value: T) => void;
1594
+ /**
1595
+ * Alias for `untrackedGet()`.
1596
+ */
1597
+ peek: () => T;
1598
+ /**
1599
+ * Alias for `silentSet(value)`.
1600
+ */
1601
+ lay: (value: T) => void;
1602
+ /**
1603
+ * Reset the value back to the initial value passed to the hook.
1604
+ */
1605
+ reset: () => void;
1606
+ }
1607
+ export type UseStateWithControlReturn<T> = [
1608
+ /**
1609
+ * Current value — identical to the `value` a plain `useState` would hold.
1610
+ */
1611
+ value: T,
1612
+ /**
1613
+ * Setter to update the value (value or updater form, like `setState`).
1614
+ */
1615
+ setValue: Dispatch<SetStateAction<T>>,
1616
+ /**
1617
+ * Fine-grained controls over the value: `get` / `set` / `peek` / `lay`, the
1618
+ * untracked/silent shorthands, and `reset`.
1619
+ */
1620
+ control: UseStateWithControlControls<T>];
1621
+ /**
1622
+ * Fine-grained controls over a state and its re-renders — React port of
1623
+ * VueUse's `refWithControl`.
1624
+ *
1625
+ * Map from @vueuse/shared `refWithControl`
1626
+ * (`source/vueuse/packages/shared/refWithControl/`). Upstream returns a single
1627
+ * writable Vue `Ref` extended with `get` / `set` / `untrackedGet` /
1628
+ * `silentSet` / `peek` / `lay`. This port owns the state like a `useState` and
1629
+ * returns the React tuple `const [num, setNum, control] = useStateWithControl(0)`
1630
+ * — the name follows this repo's `ref*` → `useState*` mapping rule. `setNum`
1631
+ * behaves like a normal `setState` (value or updater form — the updater base
1632
+ * is the current internal value, which may be ahead of the rendered value
1633
+ * after a silent write), while `control`
1634
+ * keeps the fine-grained get/set pair: `set(value, false)` (and `lay` /
1635
+ * `silentSet`) updates the value without re-rendering (upstream: without
1636
+ * triggering reactivity), and `peek` / `untrackedGet` read it back — in React
1637
+ * there is no dependency tracking during render, so those are plain aliases
1638
+ * for the current value. `reset()` (a small addition, upstream has no
1639
+ * equivalent) restores the initial value and participates in the change
1640
+ * callbacks (`onBeforeChange` can dismiss it, `onChanged` fires when
1641
+ * accepted). Option names are kept from upstream:
1642
+ * `onBeforeChange` can dismiss a change by returning `false`, and `onChanged`
1643
+ * fires synchronously after an accepted change.
1644
+ *
1645
+ * @param state State source: a plain value, getter, ref-like value, state
1646
+ * tuple, or `{ value, onChange }` controllable state.
1647
+ * @param options
1648
+ * @return A tuple `[value, setValue, control]` — the current value, a
1649
+ * `setState`-like setter and the fine-grained control object.
1650
+ *
1651
+ * @example
1652
+ * const [num, setNum, control] = useStateWithControl(0)
1653
+ *
1654
+ * setNum(42) // just like a normal useState setter
1655
+ * control.set(30, false) // set the value without re-rendering
1656
+ * control.peek() // get the value without tracking
1657
+ */
1658
+ export declare function useStateWithControl<T>(state: State<T>, options?: UseStateWithControlOptions<T>): UseStateWithControlReturn<T>;
1659
+ //#endregion
1660
+ //#region useThrottleFn/index.d.ts
1661
+ export type PromisifyFn<T extends FunctionArgs> = (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
1662
+ /**
1663
+ * Throttle execution of a function — React port of VueUse's `useThrottleFn`.
1664
+ * Especially useful for rate limiting execution of handlers on events like
1665
+ * resize and scroll.
1666
+ *
1667
+ * Map from @vueuse/shared `useThrottleFn`
1668
+ * Mapping: upstream builds `createFilterWrapper(throttleFilter(ms, trailing,
1669
+ * leading, rejectOnCancel), fn)` and returns a plain `PromisifyFn<T>` — the
1670
+ * throttled wrapper carries no `cancel` / `flush` / `isPending` (unlike the
1671
+ * debounce filter, upstream's `throttleFilter` is not cancelable), so this
1672
+ * port mirrors that: the return value is the wrapped function and nothing
1673
+ * more. The wrapper is built once (`useMemo`) so its identity is stable
1674
+ * across renders — safe to add/remove in effects; the latest `fn` / `ms` /
1675
+ * `trailing` / `leading` / `rejectOnCancel` are mirrored into refs so every
1676
+ * call sees fresh values (upstream captures the flags once, at filter
1677
+ * creation). `ms` accepts a number or a ref-like `{ current: number }`
1678
+ * (upstream: `RefOrValue<number>`) and is re-read on every call. The
1679
+ * throttle filter logic is inlined (upstream: `utils/filters.ts`
1680
+ * `throttleFilter` — leading/trailing timestamps with a trailing invoke on
1681
+ * window end). The wrapper is cleaned up on unmount: any pending trailing
1682
+ * timer is cleared when the component unmounts — a React hygiene measure;
1683
+ * upstream registers no disposal at all (`@__NO_SIDE_EFFECTS__`), so a
1684
+ * pending call would still fire there after teardown.
1685
+ *
1686
+ * @param fn A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,
1687
+ * to `callback` when the throttled-function is executed.
1688
+ * @param ms A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.
1689
+ * (default value: 200)
1690
+ *
1691
+ * @param [trailing] if true, call fn again after the time is up (default value: true)
1692
+ *
1693
+ * @param [leading] if true, call fn on the leading edge of the ms timeout (default value: true)
1694
+ *
1695
+ * @param [rejectOnCancel] if true, reject the last call if it's been cancel (default value: false)
1696
+ *
1697
+ * @return A new, throttled, function.
1698
+ *
1699
+ * @example
1700
+ * const throttledFn = useThrottleFn(() => { ... }, 1000)
1701
+ * throttledFn()
1702
+ */
1703
+ export declare function useThrottleFn<T extends FunctionArgs>(fn: T, ms?: RefOrValue<number>, trailing?: boolean, leading?: boolean, rejectOnCancel?: boolean): PromisifyFn<T>;
1704
+ //#endregion
1705
+ //#region useTimeout/index.d.ts
1706
+ export interface UseTimeoutOptions<Controls extends boolean = false> {
1707
+ /**
1708
+ * Expose more controls
1709
+ *
1710
+ * @default false
1711
+ */
1712
+ controls?: Controls;
1713
+ /**
1714
+ * Callback on timeout
1715
+ */
1716
+ callback?: () => void;
1717
+ /**
1718
+ * Start the timer immediately
1719
+ *
1720
+ * @default true
1721
+ */
1722
+ immediate?: boolean;
1723
+ /**
1724
+ * Execute the callback immediately after calling `start`
1725
+ *
1726
+ * @default false
1727
+ */
1728
+ immediateCallback?: boolean;
1729
+ }
1730
+ export interface UseTimeoutReturn {
1731
+ /**
1732
+ * `true` once the timeout has fired
1733
+ */
1734
+ ready: boolean;
1735
+ /**
1736
+ * `true` while the timer is armed and waiting
1737
+ */
1738
+ isPending: boolean;
1739
+ /**
1740
+ * (Re)arm the timer
1741
+ */
1742
+ start: () => void;
1743
+ /**
1744
+ * Cancel the pending timer
1745
+ */
1746
+ stop: () => void;
1747
+ }
1748
+ /**
1749
+ * React port of VueUse's `useTimeout`.
1750
+ *
1751
+ * Map from @vueuse/shared `useTimeout`
1752
+ * Mapping: upstream `useTimeout` wraps `useTimeoutFn` and derives
1753
+ * `ready` as `!isPending`; since `useTimeoutFn` is mapped in its own module,
1754
+ * this port inlines the timer logic to stay self-contained — `ref` →
1755
+ * `useState` for `isPending`, `ready` derived as `!isPending` like upstream,
1756
+ * the setup-time `start()` (immediate) becomes an empty-dependency `useEffect`
1757
+ * on mount, and `tryOnScopeDispose(stop)` becomes the effect cleanup.
1758
+ * `interval` accepts a number or a React ref (upstream: `RefOrValue<number>`);
1759
+ * `start` / `stop` are stable `useCallback`s.
1760
+ *
1761
+ * @example
1762
+ * const ready = useTimeout(1000) // boolean, becomes true after 1s
1763
+ *
1764
+ * const { ready, start, stop } = useTimeout(1000, { controls: true })
1765
+ */
1766
+ export declare function useTimeout(interval?: RefOrValue<number>, options?: UseTimeoutOptions<false>): boolean;
1767
+ export declare function useTimeout(interval: RefOrValue<number>, options: UseTimeoutOptions<true>): UseTimeoutReturn;
1768
+ //#endregion
1769
+ //#region useTimeoutFn/index.d.ts
1770
+ type AnyFn = (...args: any[]) => any;
1771
+ export interface UseTimeoutFnOptions {
1772
+ /**
1773
+ * Start the timer immediately
1774
+ *
1775
+ * @default true
1776
+ */
1777
+ immediate?: boolean;
1778
+ /**
1779
+ * Execute the callback immediately after calling `start`
1780
+ *
1781
+ * @default false
1782
+ */
1783
+ immediateCallback?: boolean;
1784
+ }
1785
+ export interface UseTimeoutFnReturn<CallbackFn extends AnyFn> {
1786
+ isPending: boolean;
1787
+ stop: () => void;
1788
+ start: (...args: Parameters<CallbackFn> | []) => void;
1789
+ }
1790
+ /**
1791
+ * React port of VueUse's `useTimeoutFn` — wrapper for `setTimeout` with
1792
+ * controls.
1793
+ *
1794
+ * Map from @vueuse/shared `useTimeoutFn`
1795
+ * Mapping: upstream accepts `RefOrValue<number>` for the interval — this
1796
+ * port accepts a plain `number`. `isPending` becomes a boolean state
1797
+ * (upstream: a readonly shallow ref) that starts `false` and is set inside
1798
+ * the mount effect — like upstream's `shallowRef(false)` + `isClient` gate,
1799
+ * the server render does not report pending. `immediateCallback` runs the
1800
+ * callback synchronously on `start` (before the timer is armed). The timer
1801
+ * is scheduled in a mount effect (upstream starts synchronously during
1802
+ * setup) and a pending timer is cleared on unmount via effect cleanup. The
1803
+ * latest callback and interval are kept in refs so restarts always use the
1804
+ * newest ones.
1805
+ *
1806
+ * @example
1807
+ * const { isPending, start, stop } = useTimeoutFn(() => { ... }, 3000)
1808
+ */
1809
+ export declare function useTimeoutFn<CallbackFn extends AnyFn>(cb: CallbackFn, interval: number, options?: UseTimeoutFnOptions): UseTimeoutFnReturn<CallbackFn>;
1810
+ //#endregion
1811
+ //#region useToggle/index.d.ts
1812
+ export interface UseToggleOptions<Truthy, Falsy> {
1813
+ /**
1814
+ * Custom value for `true`
1815
+ *
1816
+ * @default true
1817
+ */
1818
+ truthyValue?: Truthy;
1819
+ /**
1820
+ * Custom value for `false`
1821
+ *
1822
+ * @default false
1823
+ */
1824
+ falsyValue?: Falsy;
1825
+ }
1826
+ export type UseToggleReturn<T extends boolean | number | string = boolean> = [T, (value?: T | ((current: T) => T)) => void];
1827
+ /**
1828
+ * React port of VueUse's `useToggle` — a toggler between a truthy and a falsy
1829
+ * value, both configurable.
1830
+ *
1831
+ * Map from @vueuse/shared `useToggle`
1832
+ * Mapping: `ref(initialValue)` → `useControllableState(initialValue)`,
1833
+ * `toggle()` → stable `useCallback`; accepts the full `State<T>` input.
1834
+ * `truthyValue` / `falsyValue` are plain values (upstream: `MaybeRefOrGetter` —
1835
+ * reactive refs/getters are not supported, see `RefOrValue`). Upstream's
1836
+ * `toggle` returns the new value synchronously; React state updates are async,
1837
+ * so here `toggle` is `() => void` and the new value is read from `value` on
1838
+ * the next render. Like upstream, a bare `toggle()` flips between
1839
+ * `truthyValue` and `falsyValue`, `toggle(value)` (including an explicit
1840
+ * `undefined`) forces the value, and a function argument is applied as a
1841
+ * functional update (React adaptation).
1842
+ *
1843
+ * @example
1844
+ * const [value, toggle] = useToggle()
1845
+ * toggle() // false → true
1846
+ * toggle(false) // force to false
1847
+ *
1848
+ * const [status, toggleStatus] = useToggle('on', { truthyValue: 'on', falsyValue: 'off' })
1849
+ * toggleStatus() // 'on' → 'off'
1850
+ */
1851
+ export declare function useToggle<T extends boolean | number | string = boolean, Truthy = true, Falsy = false>(initialValue?: State<T>, options?: UseToggleOptions<Truthy, Falsy>): UseToggleReturn<T>;
1852
+ //#endregion
1853
+ //#region useToNumber/index.d.ts
1854
+ export interface UseToNumberOptions {
1855
+ /**
1856
+ * Method to use to convert the value to a number.
1857
+ *
1858
+ * Or a custom function for the conversion.
1859
+ *
1860
+ * @default 'parseFloat'
1861
+ */
1862
+ method?: 'parseFloat' | 'parseInt' | ((value: string | number) => number);
1863
+ /**
1864
+ * The base in mathematical numeral systems passed to `parseInt`.
1865
+ * Only works with `method: 'parseInt'`
1866
+ */
1867
+ radix?: number;
1868
+ /**
1869
+ * Replace NaN with zero
1870
+ *
1871
+ * @default false
1872
+ */
1873
+ nanToZero?: boolean;
1874
+ }
1875
+ /**
1876
+ * React port of VueUse's `useToNumber`.
1877
+ *
1878
+ * Map from @vueuse/shared `useToNumber`
1879
+ * Mapping: `ComputedRef<number>` → plain number recomputed from the current
1880
+ * value on every render (accepts `number | string`); no hook state needed.
1881
+ *
1882
+ * @__NO_SIDE_EFFECTS__
1883
+ * @example
1884
+ * useToNumber('123') // 123
1885
+ * useToNumber('0xFA', { method: 'parseInt', radix: 16 }) // 250
1886
+ */
1887
+ export declare function useToNumber(value: number | string, options?: UseToNumberOptions): number;
1888
+ //#endregion
1889
+ //#region useToString/index.d.ts
1890
+ /**
1891
+ * React port of VueUse's `useToString`.
1892
+ *
1893
+ * Map from @vueuse/shared `useToString`
1894
+ * Mapping: VueUse wraps the template-literal coercion in `computed(() => ...)`
1895
+ * and accepts a `MaybeRefOrGetter`; React has no reactive value tracking, so
1896
+ * this is a plain function returning the stringified value directly.
1897
+ *
1898
+ * The `value` param is a PLAIN read-only value — pass `ref.current` or the
1899
+ * state value. Getter inputs are intentionally not supported (getters were
1900
+ * removed repo-wide); unlike upstream, a getter passed here is coerced as-is
1901
+ * (its source text), not invoked.
1902
+ *
1903
+ * @example
1904
+ * useToString(123.345) // '123.345'
1905
+ * useToString('hi') // 'hi'
1906
+ * useToString({ foo: 'hi' }) // '[object Object]'
1907
+ */
1908
+ export declare function useToString(value: unknown): string;
1909
+ //#endregion
1910
+ //#region useUnmount/index.d.ts
1911
+ /**
1912
+ * React port of react-use's `useUnmount`.
1913
+ *
1914
+ * Map from react-use `useUnmount`
1915
+ * Mapping: react-use's `useUnmount` keeps the callback in a `useRef`,
1916
+ * reassigning it on every render so the newest callback is invoked, and runs
1917
+ * it via an empty-dependency `useEffect` cleanup (react-use's `useEffectOnce`
1918
+ * is just `useEffect(effect, [])`). This port follows the same semantics.
1919
+ *
1920
+ * @example
1921
+ * useUnmount(() => cleanup())
1922
+ */
1923
+ export declare function useUnmount(fn: () => any): void;
1924
+ //#endregion
1925
+ //#region useUpdate/index.d.ts
1926
+ /**
1927
+ * React port of react-use's `useUpdate`.
1928
+ *
1929
+ * Map from react-use `useUpdate`
1930
+ * Mapping: `useReducer` with a wrapping counter — the returned function
1931
+ * dispatches an update that forces a re-render and is stable across renders.
1932
+ *
1933
+ * @example
1934
+ * const update = useUpdate()
1935
+ * update() // forces a re-render
1936
+ */
1937
+ export declare function useUpdate(): () => void;
1938
+ //#endregion
1939
+ //#region useWatch/index.d.ts
1940
+ export interface UseWatchCallback<T = any> {
1941
+ (value: T, oldValue: T | undefined): void;
1942
+ }
1943
+ export interface UseWatchOptions {
1944
+ /**
1945
+ * Fire the callback once on mount with the current value.
1946
+ * @default false
1947
+ */
1948
+ immediate?: boolean;
1949
+ }
1950
+ /**
1951
+ * React port of VueUse's `watch`.
1952
+ *
1953
+ * Map from @vueuse/shared `watch`
1954
+ * Mapping: Vue's reactive dependency tracking becomes a `useEffect` whose
1955
+ * dependency list is the source itself — `[source]` for a single value, the
1956
+ * source's elements for an array source — so the callback re-fires whenever
1957
+ * any watched part changes. The previous value is tracked in a ref updated
1958
+ * by the effect (inlined `usePrevious`), and the callback never fires on the
1959
+ * first render unless `immediate: true`.
1960
+ *
1961
+ * This is the parent of all `useWatch*` variants.
1962
+ *
1963
+ * @example
1964
+ * ```ts
1965
+ * useWatch(count, (value, oldValue) => console.log(value, oldValue))
1966
+ * useWatch([count, name], (value, oldValue) => console.log(value, oldValue))
1967
+ * ```
1968
+ */
1969
+ export declare function useWatch<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchOptions): void;
1970
+ export declare function useWatch<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchOptions): void;
1971
+ //#endregion
1972
+ //#region useWatchArray/index.d.ts
1973
+ export interface UseWatchArrayCallback<V = any, OV = any> {
1974
+ (value: V, oldValue: OV, added: V, removed: OV): void;
1975
+ }
1976
+ export interface UseWatchArrayOptions<Immediate extends Readonly<boolean> = false> {
1977
+ /**
1978
+ * Fire the callback once on mount with the current list.
1979
+ * @default false
1980
+ */
1981
+ immediate?: Immediate;
1982
+ }
1983
+ /**
1984
+ * React port of VueUse's `watchArray` — watch for an array with additions and removals.
1985
+ *
1986
+ * Mapping: built on the house `useWatch` — the list is a plain array value tracked across
1987
+ * renders, `useWatch` handles the change detection, and the previous list is diffed against
1988
+ * the next one with item-identity matching (like upstream) so the callback receives
1989
+ * `(newList, oldList, added, removed)`. The list is wrapped as a single-element watch
1990
+ * source (`[list]`) so `useWatch` tracks it by reference identity instead of spreading a
1991
+ * variable-length list into its dependency list (React requires a constant deps size).
1992
+ *
1993
+ * Divergences from the upstream Vue API:
1994
+ * - `source` is a plain array value — Vue's `WatchSource` forms (ref / getter / reactive)
1995
+ * have no React equivalent, compute the array during render and pass it directly.
1996
+ * - The list is tracked by reference identity: replacing it with a new array fires the
1997
+ * callback even when the items are identical (like a Vue ref reassignment), while
1998
+ * re-renders that keep the same array reference do not fire.
1999
+ * - In-place mutations (`push` / `splice`) do not re-render — produce a new array
2000
+ * (`setList([...list, item])`) to trigger the watch.
2001
+ * - The upstream `onCleanup` callback parameter is not ported — `useWatch` has no
2002
+ * watch-cleanup equivalent, use `useEffect` cleanup in the component instead.
2003
+ * - The return value is `void` — upstream returns a stop `WatchHandle`; watching
2004
+ * ends when the component unmounts.
2005
+ *
2006
+ * @example
2007
+ * ```ts
2008
+ * useWatchArray(list, (newList, oldList, added, removed) => {
2009
+ * console.log('added:', added, 'removed:', removed)
2010
+ * })
2011
+ * ```
2012
+ */
2013
+ export declare function useWatchArray<T, Immediate extends Readonly<boolean> = false>(source: T[], cb: UseWatchArrayCallback<T[], Immediate extends true ? T[] | undefined : T[]>, options?: UseWatchArrayOptions<Immediate>): void;
2014
+ //#endregion
2015
+ //#region useWatchAtMost/index.d.ts
2016
+ export interface UseWatchAtMostOptions {
2017
+ /**
2018
+ * The maximum number of times the callback may fire.
2019
+ */
2020
+ count: number;
2021
+ /**
2022
+ * Fire the callback once on mount with the current value.
2023
+ * @default false
2024
+ */
2025
+ immediate?: boolean;
2026
+ }
2027
+ export interface UseWatchAtMostReturn {
2028
+ /**
2029
+ * The number of times the callback has fired so far.
2030
+ */
2031
+ count: number;
2032
+ /**
2033
+ * Stop watching before the limit is reached.
2034
+ */
2035
+ stop: () => void;
2036
+ /**
2037
+ * Pause the watch — source changes do not fire the callback nor count
2038
+ * towards the limit until `resume` is called.
2039
+ */
2040
+ pause: () => void;
2041
+ /**
2042
+ * Resume a paused watch.
2043
+ */
2044
+ resume: () => void;
2045
+ }
2046
+ export declare function useWatchAtMost<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options: UseWatchAtMostOptions): UseWatchAtMostReturn;
2047
+ export declare function useWatchAtMost<T>(source: T, callback: UseWatchCallback<T>, options: UseWatchAtMostOptions): UseWatchAtMostReturn;
2048
+ //#endregion
2049
+ //#region useWatchDebounced/index.d.ts
2050
+ export interface UseWatchDebouncedOptions extends DebounceFilterOptions {
2051
+ /**
2052
+ * Debounce delay in milliseconds. Accepts a plain number or a ref-like
2053
+ * `{ current }` — re-read on every source change.
2054
+ *
2055
+ * @default 0
2056
+ */
2057
+ debounce?: RefOrValue<number>;
2058
+ /**
2059
+ * Fire the callback once on mount with the current value (still debounced).
2060
+ *
2061
+ * @default false
2062
+ */
2063
+ immediate?: boolean;
2064
+ }
2065
+ /**
2066
+ * Debounced watch — the callback fires only after the source stops changing
2067
+ * for the specified duration — React port of VueUse's `watchDebounced`.
2068
+ *
2069
+ * Map from @vueuse/shared `watchDebounced`
2070
+ * Mapping: upstream is a shorthand for
2071
+ * `watchWithFilter(source, cb, { eventFilter: debounceFilter(debounce, { maxWait }) })`.
2072
+ * This port composes the same pieces from house primitives: `useWatch` tracks
2073
+ * the source across renders (Vue's reactive dependency tracking becomes the
2074
+ * effect dependency list) and hands every change to `useDebounceFn`, which
2075
+ * implements the upstream `debounceFilter` (trailing edge + `maxWait`). Bursts
2076
+ * of changes collapse into a single call carrying the latest `(value, oldValue)`
2077
+ * pair captured at the last change.
2078
+ *
2079
+ * Divergences from upstream:
2080
+ * - Returns `void` — upstream returns a `WatchHandle`; here disposal follows the
2081
+ * component lifecycle and pending timers are cancelled on unmount (via
2082
+ * `useDebounceFn`).
2083
+ * - The source is a plain value (or array of values) tracked across renders —
2084
+ * deep-reactive object sources and `deep` / `flush` watch options don't apply.
2085
+ * - `rejectOnCancel` (inherited from `DebounceFilterOptions`) is forwarded to
2086
+ * `useDebounceFn` but has no observable effect — watch callbacks return
2087
+ * nothing, so there is no promise to reject.
2088
+ *
2089
+ * @example
2090
+ * ```ts
2091
+ * useWatchDebounced(input, (value, oldValue) => console.log(value, oldValue), { debounce: 500, maxWait: 1000 })
2092
+ * useWatchDebounced([count, name], (value, oldValue) => console.log(value, oldValue), { debounce: 200 })
2093
+ * ```
2094
+ */
2095
+ export declare function useWatchDebounced<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchDebouncedOptions): void;
2096
+ export declare function useWatchDebounced<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchDebouncedOptions): void;
2097
+ //#endregion
2098
+ //#region useWatchDeep/index.d.ts
2099
+ /**
2100
+ * Structural equality, mirroring the semantics of test `toEqual`: primitives
2101
+ * are compared with `Object.is`, and `Date`, `RegExp`, `Array`, `Map`, `Set`
2102
+ * and objects (plain or class instances) are compared by contents. Functions
2103
+ * compare by reference, and `Map` keys are matched by reference because key
2104
+ * lookups cannot deep-match, while `Map` values and `Set` items are compared
2105
+ * deeply.
2106
+ *
2107
+ * Shared single source of truth — used by {@link useWatchDeep} and imported
2108
+ * from `@reause/shared` by core hooks that need deep change detection
2109
+ * (e.g. `useCloned`).
2110
+ */
2111
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
2112
+ /**
2113
+ * Deep clone pairing with {@link deepEqual}'s type coverage — `Date`, `RegExp`,
2114
+ * `Array`, `Map`, `Set` and objects (plain or class instances) are copied
2115
+ * structurally, primitives and functions pass through. Used to snapshot a live
2116
+ * value into an isolated baseline for change detection (e.g. `useCloned`'s
2117
+ * source / cloned baselines, which must stay unaffected by in-place mutations).
2118
+ */
2119
+ export declare function deepClone<T>(value: T): T;
2120
+ /**
2121
+ * React port of VueUse's `watchDeep` — shorthand for watching a value with
2122
+ * `{ deep: true }`. Built on top of {@link useWatch}.
2123
+ *
2124
+ * Map from @vueuse/shared `watchDeep`
2125
+ * Mapping: Vue's deep watcher traverses reactive proxies and fires on in-place
2126
+ * mutation of any nested property. React state is immutable — a nested change
2127
+ * always arrives as a new top-level value — so `useWatchDeep` deep-compares
2128
+ * the newly rendered value against the previously rendered one and invokes the
2129
+ * callback only when they differ deeply. A re-render that replaces the value
2130
+ * with a deep-equal one stays silent (unlike `useWatch`, which fires on every
2131
+ * reference change).
2132
+ *
2133
+ * Documented divergences from Vue's deep watch:
2134
+ * - In-place mutation of a value that is never replaced cannot be observed
2135
+ * (React immutability) — replace the state instead; the callback then fires
2136
+ * when the next rendered value deep-differs from the previous one.
2137
+ * - Reassigning the state to a deep-equal value does not fire. Vue's ref-based
2138
+ * watch fires on every reassignment of the ref, even when deeply equal.
2139
+ *
2140
+ * @example
2141
+ * ```ts
2142
+ * const [obj, setObj] = useState({ foo: { bar: { deep: 5 } } })
2143
+ * useWatchDeep(obj, (value, oldValue) => console.log(value, oldValue))
2144
+ * setObj({ foo: { bar: { deep: 10 } } }) // fires — nested value changed
2145
+ * setObj({ foo: { bar: { deep: 10 } } }) // silent — deep-equal reassignment
2146
+ * ```
2147
+ */
2148
+ export declare function useWatchDeep<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchOptions): void;
2149
+ export declare function useWatchDeep<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchOptions): void;
2150
+ //#endregion
2151
+ //#region useWatchIgnorable/index.d.ts
2152
+ export type IgnoredUpdater = (updater: () => void) => void;
2153
+ export type IgnoredPrevAsyncUpdates = () => void;
2154
+ export interface UseWatchIgnorableReturn {
2155
+ /**
2156
+ * Run `updater`, ignoring the watch for the source changes it makes — as
2157
+ * long as no other changes follow, the callback is not fired for that batch.
2158
+ */
2159
+ ignoreUpdates: IgnoredUpdater;
2160
+ /**
2161
+ * Ignore the source changes made since the last time the callback fired —
2162
+ * as long as no other changes follow, the callback is not fired for that
2163
+ * batch.
2164
+ */
2165
+ ignorePrevAsyncUpdates: IgnoredPrevAsyncUpdates;
2166
+ /**
2167
+ * Stop watching — further source changes will not fire the callback.
2168
+ */
2169
+ stop: () => void;
2170
+ }
2171
+ export interface UseWatchIgnorableOptions {
2172
+ /**
2173
+ * Fire the callback once on mount with the current value.
2174
+ * @default false
2175
+ */
2176
+ immediate?: boolean;
2177
+ /**
2178
+ * Stop the watch after the callback has fired once (upstream: Vue's `once`
2179
+ * watch option). Ignored fires do not count towards the limit.
2180
+ * @default false
2181
+ */
2182
+ once?: boolean;
2183
+ }
2184
+ /**
2185
+ * Ignorable watch — extended watch that returns `ignoreUpdates(updater)` /
2186
+ * `ignorePrevAsyncUpdates()` / `stop` to ignore particular updates to the
2187
+ * source — React port of VueUse's `watchIgnorable`.
2188
+ * Map from @vueuse/shared watchIgnorable.
2189
+ *
2190
+ * The API follows the maintainer-directed adjustment of issue #263: the
2191
+ * source is the caller's own state value (house `useWatch` source convention)
2192
+ * and the return is the upstream `WatchIgnorableReturn` object shape — this
2193
+ * deliberately overrides the house array-destructure return convention.
2194
+ *
2195
+ * Mapping: upstream counts every source modification with a hidden
2196
+ * `flush: 'sync'` shadow watcher (`syncCounter`), accumulates the changes to
2197
+ * skip in `ignoreCounter`, and skips a trigger only when every counted change
2198
+ * came from `ignoreUpdates` (`ignoreCounter === syncCounter`, both counters
2199
+ * reset together). React offers no way to observe — let alone intercept — the
2200
+ * caller's `setSource`: changes only become visible at the next commit, where
2201
+ * automatic batching has already collapsed consecutive updates into a single
2202
+ * render. The port therefore approximates the counters with a one-shot
2203
+ * "ignore barrier": `ignoreUpdates(updater)` snapshots the latest observed
2204
+ * value, runs `updater` synchronously and arms the barrier; the next change
2205
+ * the watch observes is skipped (upstream skips it too when no other changes
2206
+ * follow) and the flag is consumed either way, so later genuine changes fire
2207
+ * again. `ignorePrevAsyncUpdates()` arms the same barrier for the changes
2208
+ * queued before the call (snapshot-style one-shot skip). A commit that
2209
+ * carries no source change disarms the barrier so a no-op updater cannot
2210
+ * consume a later genuine change.
2211
+ *
2212
+ * Divergences from upstream (React batching):
2213
+ * - Changes made inside `ignoreUpdates` and further changes made afterwards
2214
+ * in the same synchronous batch collapse into one render, which the barrier
2215
+ * skips as a whole — upstream would fire the trigger with the latest value.
2216
+ * Let the updater's batch commit (return from the event handler) before
2217
+ * making changes that must fire.
2218
+ * - If the updater produces no change and the very next commit carries a
2219
+ * source change, that change is skipped where upstream would fire it (a
2220
+ * commit without a source change disarms the barrier).
2221
+ * - The `flush` option is not ported — the callback fires in the effect after
2222
+ * commit (upstream `flush: 'pre'` timing); where upstream's
2223
+ * `flush: 'sync'` makes `ignorePrevAsyncUpdates` a no-op, here it always
2224
+ * applies.
2225
+ * - Upstream's other `WatchWithFilterOptions` members are rejected:
2226
+ * `deep` (no reactive graph to traverse — the source is compared by
2227
+ * identity), `flush` (React commits are not configurable), and
2228
+ * `eventFilter` (no filter pipeline); the option type does not accept them,
2229
+ * so passing them fails type checking. `once` IS ported — the watch stops
2230
+ * after the first fired change.
2231
+ * - `stop()` keeps the effect registered but the callback becomes a no-op —
2232
+ * observable behavior is identical (the callback never fires again).
2233
+ * - The deprecated upstream alias `ignorableWatch` is not ported (house
2234
+ * `useWatch*` naming convention).
2235
+ *
2236
+ * @example
2237
+ * ```ts
2238
+ * const [source, setSource] = useState('foo')
2239
+ * const { ignoreUpdates } = useWatchIgnorable(source, v => console.log(`Changed to ${v}!`))
2240
+ * setSource('bar') // logs: Changed to bar!
2241
+ * ignoreUpdates(() => setSource('foobar')) // (nothing logged)
2242
+ * ```
2243
+ */
2244
+ export declare function useWatchIgnorable<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchIgnorableOptions): UseWatchIgnorableReturn;
2245
+ export declare function useWatchIgnorable<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchIgnorableOptions): UseWatchIgnorableReturn;
2246
+ //#endregion
2247
+ //#region useWatchImmediate/index.d.ts
2248
+ /**
2249
+ * Shorthand for watching value with `{ immediate: true }` — React port of
2250
+ * VueUse's `watchImmediate`.
2251
+ *
2252
+ * Map from @vueuse/shared watchImmediate. Upstream is a shorthand for
2253
+ * `watch(source, cb, { ...options, immediate: true })`; this port composes
2254
+ * the same pieces from house primitives: `useWatch` tracks the source across
2255
+ * renders (Vue's reactive dependency tracking becomes the effect dependency
2256
+ * list) and the hardcoded `immediate: true` fires the callback once on mount
2257
+ * with the current value, then again on every subsequent change with
2258
+ * `(value, oldValue)`.
2259
+ *
2260
+ * Divergences from the upstream Vue API:
2261
+ * - Returns `void` — upstream returns a `WatchHandle`; here disposal follows
2262
+ * the component lifecycle.
2263
+ * - The source is a plain value (or array of values) tracked across renders —
2264
+ * Vue's `WatchSource` forms (ref / getter / reactive) have no React
2265
+ * equivalent, compute the value during render and pass it directly.
2266
+ * - The remaining upstream options are not ported — `immediate` is the whole
2267
+ * point of this shorthand and is always `true`, while `deep` and `flush`
2268
+ * don't apply (tracking is by `Object.is` identity, like a Vue ref
2269
+ * reassignment, and effects always run after commit).
2270
+ *
2271
+ * @example
2272
+ * ```ts
2273
+ * // logs on mount ('vue-use') and again on every change ('VueUse', ...)
2274
+ * useWatchImmediate(obj, updated => console.log(updated))
2275
+ * useWatchImmediate([count, name], (value, oldValue) => console.log(value, oldValue))
2276
+ * ```
2277
+ */
2278
+ export declare function useWatchImmediate<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>): void;
2279
+ export declare function useWatchImmediate<T>(source: T, callback: UseWatchCallback<T>): void;
2280
+ //#endregion
2281
+ //#region useWatchOnce/index.d.ts
2282
+ export interface UseWatchOnceReturn {
2283
+ /**
2284
+ * Stop watching before the callback has fired — further source changes are
2285
+ * ignored. Calling it after the callback fired is a no-op.
2286
+ */
2287
+ stop: () => void;
2288
+ }
2289
+ export declare function useWatchOnce<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchOptions): UseWatchOnceReturn;
2290
+ export declare function useWatchOnce<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchOptions): UseWatchOnceReturn;
2291
+ //#endregion
2292
+ //#region useWatchPausable/index.d.ts
2293
+ export interface UseWatchPausableOptions {
2294
+ /**
2295
+ * The initial state of the watcher.
2296
+ *
2297
+ * @default 'active'
2298
+ */
2299
+ initialState?: 'active' | 'paused';
2300
+ /**
2301
+ * Fire the callback once on mount with the current source value (still
2302
+ * subject to the pause state).
2303
+ *
2304
+ * @default false
2305
+ */
2306
+ immediate?: boolean;
2307
+ }
2308
+ export interface UseWatchPausableReturn {
2309
+ /**
2310
+ * Pause the watcher — source changes will not fire the callback while
2311
+ * paused. Changes made while paused are dropped.
2312
+ */
2313
+ pause: () => void;
2314
+ /**
2315
+ * Resume the watcher — re-activates the callback for future changes. It
2316
+ * does not replay changes made while paused.
2317
+ */
2318
+ resume: () => void;
2319
+ /**
2320
+ * Whether the watcher is currently active.
2321
+ */
2322
+ isActive: boolean;
2323
+ /**
2324
+ * Stop the watcher — the callback never fires again.
2325
+ */
2326
+ stop: () => void;
2327
+ }
2328
+ /**
2329
+ * Pausable watch — a watched value whose updates can be paused and resumed —
2330
+ * React port of VueUse's `watchPausable`.
2331
+ *
2332
+ * Map from @vueuse/shared watchPausable. Upstream wraps `watchWithFilter` with
2333
+ * `pausableFilter`: while paused the event filter drops invocations, and
2334
+ * `resume()` only re-activates the filter — changes made while paused are
2335
+ * never replayed, so the first change after resuming fires the callback with
2336
+ * the last change's value — the dropped one, if any — as `oldValue`: the
2337
+ * watch's tracked previous value advances through paused changes, matching
2338
+ * upstream, where the filter swallows the invocation but the underlying
2339
+ * watch's `oldValue` still moves. This port keeps those semantics on
2340
+ * house primitives: `useWatch` tracks the source across renders (Vue's
2341
+ * reactive dependency tracking becomes the effect dependency list, firing in
2342
+ * the effect after commit — upstream `flush: 'pre'` timing) and the callback
2343
+ * is skipped whenever the watcher is paused or stopped.
2344
+ *
2345
+ * The API follows the maintainer-directed watch-wrapper convention of issue
2346
+ * #263: the source is the caller's own state value (house `useWatch` source
2347
+ * convention) and the return is the upstream `WatchPausableReturn` object
2348
+ * shape.
2349
+ *
2350
+ * Divergences from upstream:
2351
+ * - `isActive` is a plain boolean state instead of a readonly ref — it updates
2352
+ * across renders, and `pause()` / `resume()` made in the same batch as a
2353
+ * source change are still honoured (the pause state is mirrored into a ref
2354
+ * read by the effect).
2355
+ * - Changes made while paused are dropped — upstream `pausableFilter` defers
2356
+ * nothing, so `resume()` does not replay them and never fires the callback
2357
+ * by itself.
2358
+ * - The `deep`, `flush`, `eventFilter` watch options and the `onTrack` /
2359
+ * `onTrigger` callbacks are not ported — tracking is by `Object.is`
2360
+ * identity, like a Vue ref reassignment (upstream `WatchPausableOptions` is
2361
+ * `WatchWithFilterOptions & PausableFilterOptions`; the `pausableFilter`
2362
+ * half carries no options of its own, so there is no `eventFilterOptions`
2363
+ * member).
2364
+ * - `stop()` keeps the effect registered but the callback becomes a no-op —
2365
+ * observable behavior is identical (the callback never fires again), and
2366
+ * `isActive` is unaffected, like upstream.
2367
+ *
2368
+ * @example
2369
+ * ```ts
2370
+ * const [source, setSource] = useState('foo')
2371
+ * const { pause, resume } = useWatchPausable(source, v => console.log(`Changed to ${v}!`))
2372
+ * setSource('bar') // logs: Changed to bar!
2373
+ * pause()
2374
+ * setSource('foobar') // (nothing logged)
2375
+ * resume()
2376
+ * setSource('hello') // logs: Changed to hello!
2377
+ * ```
2378
+ */
2379
+ export declare function useWatchPausable<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchPausableOptions): UseWatchPausableReturn;
2380
+ export declare function useWatchPausable<T>(source: T, callback: UseWatchCallback<NoInfer<T>>, options?: UseWatchPausableOptions): UseWatchPausableReturn;
2381
+ //#endregion
2382
+ //#region useWatchThrottled/index.d.ts
2383
+ export interface UseWatchThrottledOptions {
2384
+ /**
2385
+ * Throttle interval in milliseconds. Accepts a plain number or a ref-like
2386
+ * `{ current }` — re-read on every source change.
2387
+ *
2388
+ * @default 0
2389
+ */
2390
+ throttle?: RefOrValue<number>;
2391
+ /**
2392
+ * Invoke the callback on the trailing edge of the throttle window.
2393
+ *
2394
+ * @default true
2395
+ */
2396
+ trailing?: boolean;
2397
+ /**
2398
+ * Invoke the callback on the leading edge of the throttle window.
2399
+ *
2400
+ * @default true
2401
+ */
2402
+ leading?: boolean;
2403
+ /**
2404
+ * Fire the callback once on mount with the current value (still throttled).
2405
+ *
2406
+ * @default false
2407
+ */
2408
+ immediate?: boolean;
2409
+ }
2410
+ /**
2411
+ * Throttled watch — the callback is invoked at most once per specified
2412
+ * duration — React port of VueUse's `watchThrottled`.
2413
+ * Map from @vueuse/shared watchThrottled.
2414
+ *
2415
+ * Mapping: upstream is a shorthand for
2416
+ * `watchWithFilter(source, cb, { eventFilter: throttleFilter(throttle, trailing, leading) })`.
2417
+ * This port composes the same pieces from house primitives: `useWatch` tracks
2418
+ * the source across renders (Vue's reactive dependency tracking becomes the
2419
+ * effect dependency list) and hands every change to `useThrottleFn`, which
2420
+ * implements the upstream `throttleFilter` (leading/trailing edges with a
2421
+ * trailing invoke on window end). Changes inside the throttle window collapse
2422
+ * into a single call carrying the latest `(value, oldValue)` pair captured at
2423
+ * the last change.
2424
+ *
2425
+ * Divergences from upstream:
2426
+ * - Returns `void` — upstream returns a `WatchHandle`; here disposal follows the
2427
+ * component lifecycle and pending timers are cancelled on unmount (via
2428
+ * `useThrottleFn`).
2429
+ * - The source is a plain value (or array of values) tracked across renders —
2430
+ * deep-reactive object sources and `deep` / `flush` watch options don't apply.
2431
+ * - upstream's deprecated `throttledWatch` alias is not ported.
2432
+ *
2433
+ * @example
2434
+ * ```ts
2435
+ * useWatchThrottled(input, (value, oldValue) => console.log(value, oldValue), { throttle: 500 })
2436
+ * useWatchThrottled([count, name], (value, oldValue) => console.log(value, oldValue), { throttle: 200 })
2437
+ * ```
2438
+ */
2439
+ export declare function useWatchThrottled<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchThrottledOptions): void;
2440
+ export declare function useWatchThrottled<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchThrottledOptions): void;
2441
+ //#endregion
2442
+ //#region useWatchTriggerable/index.d.ts
2443
+ export type OnCleanup = (cleanupFn: () => void) => void;
2444
+ export interface UseWatchTriggerableCallback<V = any, OV = any, R = void> {
2445
+ (value: V, oldValue: OV, onCleanup: OnCleanup): R;
2446
+ }
2447
+ /** Per-element optional old value for array sources (upstream `MapOldSources<T, true>`). */
2448
+ export type UseWatchTriggerableOldValues<T extends readonly any[]> = { [K in keyof T]: T[K] | undefined; };
2449
+ export interface UseWatchTriggerableReturn<R = void> {
2450
+ /**
2451
+ * Execute the callback immediately with the current source value — the old
2452
+ * value is unknown (`undefined`, per-element for array sources) for a manual
2453
+ * call, and the invocation does not count as a source change: a source
2454
+ * change queued inside the callback is itself ignored.
2455
+ */
2456
+ trigger: () => R;
2457
+ /**
2458
+ * Run `updater`, ignoring the watch for the source changes it makes — as
2459
+ * long as no other changes follow, the callback is not fired for that batch.
2460
+ */
2461
+ ignoreUpdates: IgnoredUpdater;
2462
+ /**
2463
+ * Ignore the source changes made since the last time the callback fired —
2464
+ * as long as no other changes follow, the callback is not fired for that
2465
+ * batch.
2466
+ */
2467
+ ignorePrevAsyncUpdates: () => void;
2468
+ /**
2469
+ * Stop watching — further source changes will not fire the callback.
2470
+ */
2471
+ stop: () => void;
2472
+ }
2473
+ export interface UseWatchTriggerableOptions {
2474
+ /**
2475
+ * Fire the callback once on mount with the current value.
2476
+ * @default false
2477
+ */
2478
+ immediate?: boolean;
2479
+ }
2480
+ /**
2481
+ * Watch that can be triggered manually — extended watch that returns
2482
+ * `trigger()` to execute the callback immediately — React port of VueUse's
2483
+ * `watchTriggerable`.
2484
+ * Map from @vueuse/shared watchTriggerable.
2485
+ *
2486
+ * The API follows the maintainer-directed adjustment of issue #263: the
2487
+ * source is the caller's own state value (house `useWatch` source convention)
2488
+ * and the return is the upstream `WatchTriggerableReturn` object shape — this
2489
+ * deliberately overrides the house array-destructure return convention, and
2490
+ * the hook holds no observable state of its own (the internal render tick is
2491
+ * invisible to the caller).
2492
+ *
2493
+ * Mapping: upstream builds on `watchIgnorable`, which counts every source
2494
+ * modification with a hidden `flush: 'sync'` shadow watcher (`syncCounter`),
2495
+ * accumulates the changes to skip in `ignoreCounter`, and skips a trigger
2496
+ * only when every counted change came from `ignoreUpdates`
2497
+ * (`ignoreCounter === syncCounter`); `trigger()` calls the callback with the
2498
+ * current source value wrapped in `ignoreUpdates` so the manual invocation
2499
+ * does not disturb that accounting, and the previously registered `onCleanup`
2500
+ * side effect is cleaned up before every new invocation.
2501
+ *
2502
+ * React sees the caller's changes only at commit — there is no way to observe
2503
+ * (let alone intercept) `setSource`, and automatic batching has already
2504
+ * collapsed consecutive updates into a single render by then. The counters
2505
+ * are therefore approximated with a one-shot "ignore barrier":
2506
+ * `ignoreUpdates(updater)` snapshots the latest observed value, runs `updater`
2507
+ * synchronously and arms the barrier; the next change the watch observes is
2508
+ * skipped (upstream skips it too when no other changes follow) and the flag is
2509
+ * consumed either way, so later genuine changes fire again.
2510
+ * `ignorePrevAsyncUpdates()` arms the same barrier for the changes queued
2511
+ * before the call. The barrier is disarmed again when a commit carries no
2512
+ * source change (the updater produced nothing observable); an internal render
2513
+ * tick guarantees such a commit even when the updater is a no-op `setState`
2514
+ * that React would otherwise bail out of entirely — so a no-op updater can
2515
+ * never consume a later genuine change (upstream counts 0 changes and fires).
2516
+ *
2517
+ * `trigger()` fires synchronously at the call site — it does not wait for
2518
+ * React to commit and is unaffected by batching: it hands the current source
2519
+ * value straight to the callback with the old value `undefined` (upstream
2520
+ * cannot know it either; array sources get a per-element `undefined`) and
2521
+ * returns the callback's return value so async work can be awaited. Like
2522
+ * upstream, the invocation is wrapped in `ignoreUpdates`: a source change
2523
+ * queued by the callback inside `trigger()` is suppressed after its commit
2524
+ * (upstream counts it in `ignoreCounter`), and a callback that makes no
2525
+ * source change is disarmed by the forced commit, so a later genuine change
2526
+ * still fires.
2527
+ *
2528
+ * Divergences from upstream (React batching):
2529
+ * - Changes made inside `ignoreUpdates` and further changes made afterwards
2530
+ * in the same synchronous batch collapse into one render, which the
2531
+ * barrier skips as a whole — upstream would fire the callback with the
2532
+ * latest value. Let the updater's batch commit before making changes that
2533
+ * must fire.
2534
+ * - The `flush` option is not ported — the callback fires in the effect after
2535
+ * commit (upstream `flush: 'pre'` timing); `eventFilter` and the other
2536
+ * `WatchWithFilterOptions` members (`deep`, pause/resume) are not ported —
2537
+ * only `immediate`.
2538
+ * - `stop()` keeps the effect registered but the callback becomes a no-op —
2539
+ * observable behavior is identical (the callback never fires again).
2540
+ *
2541
+ * @example
2542
+ * ```ts
2543
+ * const [source, setSource] = useState('foo')
2544
+ * const { trigger, ignoreUpdates } = useWatchTriggerable(source, v => console.log(`Changed to ${v}!`))
2545
+ * setSource('bar') // logs: Changed to bar!
2546
+ * ignoreUpdates(() => setSource('foobar')) // (nothing logged)
2547
+ * trigger() // logs: Changed to foobar! — fired manually with the current value
2548
+ * ```
2549
+ */
2550
+ export declare function useWatchTriggerable<T extends any[], R>(source: readonly [...T], callback: UseWatchTriggerableCallback<[...T], UseWatchTriggerableOldValues<[...T]>, R>, options?: UseWatchTriggerableOptions): UseWatchTriggerableReturn<R>;
2551
+ export declare function useWatchTriggerable<T, R>(source: T, callback: UseWatchTriggerableCallback<T, T | undefined, R>, options?: UseWatchTriggerableOptions): UseWatchTriggerableReturn<R>;
2552
+ //#endregion
2553
+ //#region useWatchWithFilter/index.d.ts
2554
+ /**
2555
+ * Filter for if events should to be received — the house equivalent of
2556
+ * upstream's `EventFilter` (`@vueuse/shared` `utils/filters.ts`).
2557
+ *
2558
+ * Upstream is generic over the wrapped function
2559
+ * (`EventFilter<Args, This, Invoke>` returning
2560
+ * `ReturnType<Invoke> | Promisify<ReturnType<Invoke>>`); the watch path
2561
+ * discards the wrapped callback's return value, so the contract collapses
2562
+ * to `(invoke: FunctionArgs, options?: Record<string, unknown>) => void`.
2563
+ * The optional second argument mirrors upstream's placeholder
2564
+ * `FunctionWrapperOptions` (e.g. `useMouse` passes `{}`), so a chained
2565
+ * filter reads an object instead of `undefined`.
2566
+ */
2567
+ export type EventFilter = (invoke: FunctionArgs, options?: Record<string, unknown>) => void;
2568
+ /**
2569
+ * An `EventFilter` that carries cancellation controls (upstream:
2570
+ * `CancelableEventFilter`), as returned by `debounceFilter`.
2571
+ *
2572
+ * `isPending` is a plain (non-reactive) getter — React has no reactive refs,
2573
+ * read it imperatively.
2574
+ */
2575
+ export interface CancelableEventFilter extends EventFilter {
2576
+ cancel: () => void;
2577
+ flush: () => void;
2578
+ readonly isPending: boolean;
2579
+ }
2580
+ export interface UseWatchWithFilterOptions {
2581
+ /**
2582
+ * Filter for if events should to be received (upstream:
2583
+ * `ConfigurableEventFilter`).
2584
+ *
2585
+ * The filter instance is captured once on mount — like upstream, where the
2586
+ * watch options are evaluated once during setup — so an inline
2587
+ * `debounceFilter(300)` is safe; pass a getter-based delay
2588
+ * (`debounceFilter(() => ms)`) when the delay must change over time.
2589
+ *
2590
+ * @default bypassFilter (invoke directly)
2591
+ */
2592
+ eventFilter?: EventFilter;
2593
+ /**
2594
+ * Fire the callback once on mount with the current value (still filtered).
2595
+ * @default false
2596
+ */
2597
+ immediate?: boolean;
2598
+ }
2599
+ /**
2600
+ * The stop function returned by `useWatchWithFilter` — upstream's
2601
+ * `WatchHandle`, reduced to the stop capability (house `useWatch` has no
2602
+ * stop-handle infrastructure).
2603
+ */
2604
+ export type UseWatchWithFilterReturn = () => void;
2605
+ /**
2606
+ * Create an EventFilter that debounce the events — in-house port of upstream
2607
+ * `@vueuse/shared` `debounceFilter` (trailing edge + `maxWait`).
2608
+ *
2609
+ * Mapping: same collapsing semantics as upstream (a newer call supersedes the
2610
+ * pending one; the `maxWait` timer survives re-scheduling and forces the call
2611
+ * with the latest `invoke`). Divergences: the promise-settlement plumbing
2612
+ * (`lastRejector` / `rejectOnCancel`) is dropped — the house `EventFilter`
2613
+ * contract returns `void` and the watch path consumes no promise, so
2614
+ * `rejectOnCancel` has no observable effect — and `isPending` is a plain
2615
+ * getter instead of a reactive ref. `ms` accepts a plain number or a React
2616
+ * ref (upstream: `RefOrValue<number>`) and is re-read on every call. Pending
2617
+ * timers are cleared by `cancel()` — the `useWatchWithFilter` hook calls it
2618
+ * on stop / unmount.
2619
+ *
2620
+ * @example
2621
+ * ```ts
2622
+ * useWatchWithFilter(input, callback, { eventFilter: debounceFilter(300, { maxWait: 1000 }) })
2623
+ * ```
2624
+ */
2625
+ export declare function debounceFilter(ms?: RefOrValue<number>, options?: DebounceFilterOptions): CancelableEventFilter;
2626
+ /**
2627
+ * Create an EventFilter that throttle the events — in-house port of upstream
2628
+ * `@vueuse/shared` `throttleFilter` (leading/trailing edges with a trailing
2629
+ * invoke on window end).
2630
+ *
2631
+ * Mapping: same collapsing semantics as upstream — a call inside the throttle
2632
+ * window re-schedules the trailing timer with the remaining time, collapsing
2633
+ * bursts into one trailing call carrying the latest `invoke`. Divergences:
2634
+ * the promise-settlement plumbing (`rejectOnCancel`, upstream's fourth
2635
+ * parameter) is dropped — the house `EventFilter` contract returns `void` —
2636
+ * and the object options form is not ported (positional
2637
+ * `throttleFilter(ms, trailing, leading)` like the house `useThrottleFn`).
2638
+ * `ms` accepts a plain number or a React ref (upstream:
2639
+ * `RefOrValue<number>`) and is re-read on every call.
2640
+ *
2641
+ * @example
2642
+ * ```ts
2643
+ * useWatchWithFilter(scrollY, callback, { eventFilter: throttleFilter(100, true, false) })
2644
+ * ```
2645
+ */
2646
+ export declare function throttleFilter(ms?: RefOrValue<number>, trailing?: boolean, leading?: boolean): EventFilter;
2647
+ export declare function useWatchWithFilter<T extends any[]>(source: readonly [...T], callback: UseWatchCallback<[...T]>, options?: UseWatchWithFilterOptions): UseWatchWithFilterReturn;
2648
+ export declare function useWatchWithFilter<T>(source: T, callback: UseWatchCallback<T>, options?: UseWatchWithFilterOptions): UseWatchWithFilterReturn;
2649
+ //#endregion
2650
+ //#region useWhenever/index.d.ts
2651
+ export type Truthy<T> = T extends false | null | undefined ? never : T;
2652
+ export interface UseWheneverOptions {
2653
+ /**
2654
+ * Fire the callback on mount if the value is already truthy
2655
+ *
2656
+ * @default false
2657
+ */
2658
+ immediate?: boolean;
2659
+ /**
2660
+ * Only trigger once when the condition is met — the watch stops after the
2661
+ * first truthy fire
2662
+ *
2663
+ * @default false
2664
+ */
2665
+ once?: boolean;
2666
+ }
2667
+ /**
2668
+ * React port of VueUse's `whenever`.
2669
+ *
2670
+ * Map from @vueuse/shared `whenever`
2671
+ * Mapping: upstream `whenever` is Vue's `watch` plus a truthy guard — the
2672
+ * callback runs every time the source CHANGES to a truthy value (a re-render
2673
+ * with the same truthy value never fires). In React this becomes a `useEffect`
2674
+ * watching `[value]`: the initial mount is skipped unless `immediate` (which
2675
+ * fires with `oldValue` `undefined`), later runs fire when the value is truthy
2676
+ * and actually changed, and the previous value is tracked in a ref updated on
2677
+ * every run — mirroring `watch`'s `oldValue`, which advances through falsy
2678
+ * values too. The callback is kept in a ref so re-renders always invoke the
2679
+ * newest one.
2680
+ *
2681
+ * The `once` option stops the watch after the first truthy fire — expressible
2682
+ * in React as a one-shot flag consulted by the effect, mirroring upstream's
2683
+ * `if (options?.once) nextTick(() => stop())`.
2684
+ *
2685
+ * The return value is a `stop` function — upstream's `WatchHandle`, reduced to
2686
+ * the stop capability (house `useWatch` has no stop-handle infrastructure).
2687
+ * `stop()` is also called when the component unmounts.
2688
+ *
2689
+ * The upstream 3-arg callback `(value, oldValue, onInvalidate)` becomes a
2690
+ * 2-arg `(value, oldValue)` in this port — `onInvalidate` (Vue's effect
2691
+ * invalidation registration) has no React equivalent, so it is dropped.
2692
+ *
2693
+ * @see https://vueuse.org/shared/whenever/
2694
+ *
2695
+ * @example
2696
+ * useWhenever(ready, () => console.log(state))
2697
+ * useWhenever(ready, () => console.log(state), { immediate: true })
2698
+ * useWhenever(ready, () => console.log(state), { once: true })
2699
+ */
2700
+ export declare function useWhenever<T>(value: T, cb: (value: Truthy<T>, oldValue: T | undefined) => void, options?: UseWheneverOptions): () => void;
2701
+ //#endregion
2702
+ //#region index.d.ts
2703
+ /**
2704
+ * @reause/shared — React port of @vueuse/shared
2705
+ * Shared utilities shared across all reause packages.
2706
+ *
2707
+ * Mapping note: @vueuse/shared exposes pure utilities + composables that
2708
+ * don't depend on the renderer. In the React world those become either
2709
+ * plain functions (no hook) or hooks without rendering logic.
2710
+ */
2711
+ export declare const isClient: boolean;
2712
+ export declare function noop(): void;
2713
+ //#endregion