@faasjs/react 8.0.0-beta.3 → 8.0.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,187 +1,665 @@
1
- import { Response, BaseUrl, Options, ResponseError, FaasBrowserClient } from '@faasjs/browser';
2
- export { Options, Response, ResponseError, ResponseHeaders } from '@faasjs/browser';
3
- import { FaasActionUnionType, FaasAction, FaasParams, FaasData } from '@faasjs/types';
4
- export { FaasAction, FaasActionUnionType, FaasData, FaasParams } from '@faasjs/types';
5
- import * as react from 'react';
6
- import { JSX, Component, ReactNode, ReactElement, ComponentType, JSXElementConstructor, ComponentProps, Dispatch, SetStateAction, RefObject } from 'react';
7
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as _$react from "react";
2
+ import { Component, ComponentProps, ComponentType, Dispatch, ErrorInfo, JSX, ReactElement, ReactNode, RefObject, SetStateAction } from "react";
3
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
+ import { FaasActionPaths, FaasData, FaasParams } from "@faasjs/types";
8
5
 
6
+ //#region src/generate-id/index.d.ts
9
7
  /**
10
- * Injects FaasData props.
8
+ * Generate a random identifier with an optional prefix.
9
+ *
10
+ * @param {string} [prefix] - Prefix prepended to the generated identifier.
11
+ * @param {number} [length] - Length of the generated identifier excluding `prefix`. Must be between `8` and `18`.
12
+ * @returns {string} Generated identifier string.
13
+ * @throws {Error} When `length` is outside the supported `8` to `18` range.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { generateId } from '@faasjs/react'
18
+ *
19
+ * const id = generateId('prefix-')
20
+ *
21
+ * id.startsWith('prefix-') // true
22
+ * ```
11
23
  */
12
- type FaasDataInjection<PathOrData extends FaasActionUnionType = any> = {
13
- action: FaasAction<PathOrData>;
14
- params: FaasParams<PathOrData>;
15
- loading: boolean;
16
- reloadTimes: number;
17
- data: FaasData<PathOrData>;
18
- error: any;
19
- promise: Promise<Response<FaasData<PathOrData>>>;
20
- /**
21
- * Reloads data with new or existing parameters.
22
- *
23
- * **Note**: It will sets skip to false before loading data.
24
- */
25
- reload(params?: Record<string, any>): Promise<FaasData<PathOrData>>;
26
- setData: React.Dispatch<React.SetStateAction<FaasData<PathOrData>>>;
27
- setLoading: React.Dispatch<React.SetStateAction<boolean>>;
28
- setPromise: React.Dispatch<React.SetStateAction<Promise<Response<FaasData<PathOrData>>>>>;
29
- setError: React.Dispatch<React.SetStateAction<any>>;
24
+ declare function generateId(prefix?: string, length?: number): string;
25
+ //#endregion
26
+ //#region src/browser/response.d.ts
27
+ /**
28
+ * Wrapper class for HTTP responses from FaasJS functions.
29
+ *
30
+ * Provides a consistent interface for handling server responses with status code, headers,
31
+ * body, and parsed data. Automatically handles JSON serialization and status code defaults.
32
+ *
33
+ * @template T - The type of the data property for type-safe response handling
34
+ */
35
+ declare class Response<T = any> {
36
+ /**
37
+ * HTTP status code exposed to callers.
38
+ */
39
+ readonly status: number;
40
+ /**
41
+ * Response headers keyed by header name.
42
+ */
43
+ readonly headers: ResponseHeaders;
44
+ /**
45
+ * Raw response body.
46
+ */
47
+ readonly body: any;
48
+ /**
49
+ * Parsed response payload when JSON data is available.
50
+ */
51
+ readonly data?: T;
52
+ /**
53
+ * Create a wrapped response object.
54
+ */
55
+ constructor(props?: ResponseProps<T>);
56
+ }
57
+ /**
58
+ * Custom error class for handling HTTP response errors from FaasJS requests.
59
+ *
60
+ * Extends the built-in Error class to provide additional information about failed requests,
61
+ * including HTTP status code, response headers, response body, and the original error.
62
+ */
63
+ declare class ResponseError extends Error {
64
+ /**
65
+ * HTTP status code reported for the failed request.
66
+ */
67
+ readonly status: number;
68
+ /**
69
+ * Response headers returned with the error.
70
+ */
71
+ readonly headers: ResponseHeaders;
72
+ /**
73
+ * Raw error body or fallback error payload.
74
+ */
75
+ readonly body: any;
76
+ /**
77
+ * Original error used to construct this instance, when available.
78
+ */
79
+ readonly originalError?: Error;
80
+ /**
81
+ * Create a ResponseError from a message, Error, or structured response error payload.
82
+ */
83
+ constructor(data: string | Error, options?: Omit<ResponseErrorProps, 'message' | 'originalError'>);
84
+ constructor(data: ResponseErrorProps);
85
+ }
86
+ //#endregion
87
+ //#region src/browser/types.d.ts
88
+ /**
89
+ * Template literal type for URL strings that must end with a forward slash.
90
+ */
91
+ type BaseUrl = `${string}/`;
92
+ /**
93
+ * Configuration options for FaasJS requests.
94
+ *
95
+ * Extends the standard RequestInit interface with FaasJS-specific options for
96
+ * customizing request behavior, adding request hooks, and overriding defaults.
97
+ */
98
+ type Options = RequestInit & {
99
+ headers?: Record<string, string>; /** Async hook called after request options are merged but before the request is sent. */
100
+ beforeRequest?: ({
101
+ action,
102
+ params,
103
+ options,
104
+ headers
105
+ }: {
106
+ action: string;
107
+ params?: Record<string, any> | undefined;
108
+ options: Options;
109
+ headers: Record<string, string>;
110
+ }) => Promise<void>; /** Custom request implementation used instead of the native `fetch`. */
111
+ request?: (url: string, options: Options) => Promise<Response>; /** Base URL override for the current request. */
112
+ baseUrl?: BaseUrl; /** When `true`, return the native fetch response so callers can consume the stream manually. */
113
+ stream?: boolean;
114
+ };
115
+ /**
116
+ * Simple key-value object for HTTP response headers.
117
+ */
118
+ type ResponseHeaders = {
119
+ [key: string]: string;
120
+ };
121
+ /**
122
+ * Type definition for the FaasBrowserClient.action method.
123
+ */
124
+ type FaasBrowserClientAction = <Path extends FaasActionPaths>(action: Path, params?: FaasParams<Path>, options?: Options) => Promise<Response<FaasData<Path>> | Response>;
125
+ /**
126
+ * Properties for creating a Response object.
127
+ */
128
+ type ResponseProps<T = any> = {
129
+ status?: number;
130
+ headers?: ResponseHeaders;
131
+ body?: any;
132
+ data?: T;
133
+ };
134
+ /**
135
+ * Input accepted by the {@link ResponseError} constructor.
136
+ */
137
+ type ResponseErrorProps = {
138
+ /** User-facing error message. */message: string; /** HTTP status code reported for the error. @default 500 */
139
+ status?: number; /** Response headers returned with the error. @default {} */
140
+ headers?: ResponseHeaders; /** Raw error body or structured error payload. @default { error: { message } } */
141
+ body?: any; /** Original error preserved when this instance wraps another exception. */
142
+ originalError?: Error;
143
+ };
144
+ /**
145
+ * Mock handler function type for testing FaasJS requests.
146
+ */
147
+ type MockHandler = (action: string, params: Record<string, any> | undefined, options: Options) => Promise<ResponseProps> | Promise<void> | Promise<Error>;
148
+ //#endregion
149
+ //#region src/browser/mock.d.ts
150
+ /**
151
+ * Set the global mock handler used by all {@link FaasBrowserClient} instances.
152
+ */
153
+ declare function setMock(handler: MockHandler | ResponseProps | Response | null | undefined): void;
154
+ //#endregion
155
+ //#region src/browser/client.d.ts
156
+ /**
157
+ * Browser client for FaasJS - provides HTTP client functionality for making API requests from web applications.
158
+ */
159
+ declare class FaasBrowserClient {
160
+ /**
161
+ * Unique identifier for this client instance.
162
+ */
163
+ readonly id: string;
164
+ /**
165
+ * Base URL used to build action request URLs.
166
+ */
167
+ baseUrl: BaseUrl;
168
+ /**
169
+ * Default request options merged into every request.
170
+ */
171
+ defaultOptions: Options;
172
+ /**
173
+ * Creates a new FaasBrowserClient instance.
174
+ */
175
+ constructor(baseUrl?: BaseUrl, options?: Options);
176
+ /**
177
+ * Makes a request to a FaasJS function.
178
+ */
179
+ action<Path extends FaasActionPaths>(action: Path, params: FaasParams<Path>, options?: Options): Promise<Response<FaasData<Path>>>;
180
+ }
181
+ //#endregion
182
+ //#region src/faas/index.d.ts
183
+ /**
184
+ * Call the currently configured FaasReactClient.
185
+ *
186
+ * This helper forwards the request to `getClient`. When the registered
187
+ * client defines `onError`, the hook is invoked before the promise rejects.
188
+ *
189
+ * @template Path - Action path or response data type used for inference.
190
+ *
191
+ * @param {Path} action - Action path to invoke.
192
+ * @param {FaasParams<Path>} params - Parameters sent to the action.
193
+ * @param {Options} [options] - Optional per-request overrides such as headers or base URL.
194
+ * See the browser-client `Options` type for supported fields such as `headers`, `beforeRequest`,
195
+ * `request`, `baseUrl`, and `stream`.
196
+ * @returns {Promise<Response<FaasData<Path>>>} Response returned by the active browser client.
197
+ * @throws {ResponseError} When the request fails and the active client does not recover inside `onError`.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * import { faas } from '@faasjs/react'
202
+ *
203
+ * const response = await faas('posts/get', { id: 1 })
204
+ *
205
+ * console.log(response.data.title)
206
+ * ```
207
+ */
208
+ declare function faas<Path extends FaasActionPaths>(action: Path, params: FaasParams<Path>, options?: Options): Promise<Response<FaasData<Path>>>;
209
+ //#endregion
210
+ //#region src/FaasDataWrapper/index.d.ts
211
+ /**
212
+ * Request state injected by {@link useFaas}, {@link FaasDataWrapper}, and {@link withFaasData}.
213
+ *
214
+ * @template Path - Action path or response data type used for inference.
215
+ */
216
+ type FaasDataInjection<Path extends FaasActionPaths> = {
217
+ /** Action path associated with the current request state. */action: Path; /** Params used for the most recent request attempt. */
218
+ params: FaasParams<Path>; /** Whether the request is currently in flight and should block the main UI. */
219
+ loading: boolean; /** Whether a background refresh request is currently in flight. */
220
+ refreshing: boolean; /** Number of times `reload()` or polling has triggered a new request. */
221
+ reloadTimes: number; /** Current resolved data value. */
222
+ data: FaasData<Path>; /** Last request error, if one occurred. */
223
+ error: any; /** Promise representing the latest request. */
224
+ promise: Promise<Response<FaasData<Path>>>;
225
+ /**
226
+ * Reloads data with new or existing parameters.
227
+ *
228
+ * When the source hook is currently skipped, calling `reload` clears the skip
229
+ * flag before starting the next request.
230
+ */
231
+ reload(params?: FaasParams<Path>, options?: {
232
+ silent?: boolean;
233
+ }): Promise<FaasData<Path>>; /** Controlled or internal setter for the resolved data value. */
234
+ setData: React.Dispatch<React.SetStateAction<FaasData<Path>>>; /** Setter for the loading flag. */
235
+ setLoading: React.Dispatch<React.SetStateAction<boolean>>; /** Setter for the latest request promise. */
236
+ setPromise: React.Dispatch<React.SetStateAction<Promise<Response<FaasData<Path>>>>>; /** Setter for the last request error. */
237
+ setError: React.Dispatch<React.SetStateAction<any>>;
30
238
  };
31
- type FaasDataWrapperProps<PathOrData extends FaasActionUnionType> = {
32
- render?(args: FaasDataInjection<PathOrData>): JSX.Element | JSX.Element[];
33
- children?: React.ReactElement<Partial<FaasDataInjection<PathOrData>>>;
34
- fallback?: JSX.Element | false;
35
- action: FaasAction<PathOrData>;
36
- params?: FaasParams<PathOrData>;
37
- onDataChange?(args: FaasDataInjection<PathOrData>): void;
38
- /** use custom data, should work with setData */
39
- data?: FaasData<PathOrData>;
40
- /** use custom setData, should work with data */
41
- setData?: React.Dispatch<React.SetStateAction<FaasData<PathOrData>>>;
42
- baseUrl?: BaseUrl;
43
- ref?: React.Ref<FaasDataWrapperRef<PathOrData>>;
239
+ /**
240
+ * Props for the {@link FaasDataWrapper} render-prop component.
241
+ *
242
+ * @template Path - Action path or response data type used for inference.
243
+ */
244
+ type FaasDataWrapperProps<Path extends FaasActionPaths> = {
245
+ /** Render prop invoked with the resolved request state after the first load completes. */render?(args: FaasDataInjection<Path>): JSX.Element | JSX.Element[]; /** Child element cloned with injected request state after the first load completes. */
246
+ children?: React.ReactElement<Partial<FaasDataInjection<Path>>>; /** Element rendered before the first successful load. */
247
+ fallback?: JSX.Element | false; /** Action path to request. */
248
+ action: Path; /** Params sent to the action. */
249
+ params?: FaasParams<Path>; /** Milliseconds to wait after each completed request before refreshing data in the background. */
250
+ polling?: number | false; /** Callback invoked whenever the resolved data value changes. */
251
+ onDataChange?(args: FaasDataInjection<Path>): void; /** Controlled data value used instead of internal state. */
252
+ data?: FaasData<Path>; /** Controlled setter used instead of internal state. */
253
+ setData?: React.Dispatch<React.SetStateAction<FaasData<Path>>>; /** Base URL override used for this wrapper instance. */
254
+ baseUrl?: BaseUrl; /** Imperative ref exposing the current injected request state. */
255
+ ref?: React.Ref<FaasDataWrapperRef<Path>>;
44
256
  };
45
- type FaasDataWrapperRef<PathOrData extends FaasActionUnionType = any> = FaasDataInjection<PathOrData>;
46
- declare const FaasDataWrapper: <PathOrData extends FaasActionUnionType = any>(props: FaasDataWrapperProps<PathOrData> & react.RefAttributes<FaasDataWrapperRef<PathOrData>>) => React.ReactElement | null;
47
257
  /**
48
- * HOC to wrap a component with FaasDataWrapper
258
+ * Imperative ref shape exposed by {@link FaasDataWrapper}.
259
+ *
260
+ * @template Path - Action path or response data type used for inference.
261
+ */
262
+ type FaasDataWrapperRef<Path extends FaasActionPaths> = FaasDataInjection<Path>;
263
+ /**
264
+ * Fetch FaasJS data and inject the result into a render prop or child element.
265
+ *
266
+ * The wrapper defers rendering `children` or `render` until the first request
267
+ * completes, then keeps passing the latest request state to the rendered output.
268
+ *
269
+ * @param {FaasDataWrapperProps<Path>} props - Wrapper props controlling the request and rendered fallback.
270
+ * @param {(args: FaasDataInjection<Path>) => JSX.Element | JSX.Element[]} [props.render] - Render prop that receives the resolved Faas request state.
271
+ * @param {React.ReactElement<Partial<FaasDataInjection<Path>>>} [props.children] - Child element cloned with injected Faas request state.
272
+ * @param {JSX.Element | false} [props.fallback] - Element rendered before the first successful load.
273
+ * @param {Path} props.action - Action path to request.
274
+ * @param {FaasParams<Path>} [props.params] - Params sent to the action.
275
+ * @param {number | false} [props.polling] - Milliseconds to wait after each completed request before refreshing data in the background.
276
+ * @param {(args: FaasDataInjection<Path>) => void} [props.onDataChange] - Callback invoked when the resolved data value changes.
277
+ * @param {FaasData<Path>} [props.data] - Controlled data value used instead of internal state.
278
+ * @param {React.Dispatch<React.SetStateAction<FaasData<Path>>>} [props.setData] - Controlled setter used instead of internal state.
279
+ * @param {BaseUrl} [props.baseUrl] - Base URL override used for this wrapper instance.
49
280
  *
50
281
  * @example
51
282
  * ```tsx
52
- * const MyComponent = withFaasData(({ data }) => <div>{data.name}</div>, { action: 'test', params: { a: 1 } })
283
+ * import { FaasDataWrapper } from '@faasjs/react'
284
+ *
285
+ * type User = {
286
+ * name: string
287
+ * }
288
+ *
289
+ * function UserView(props: {
290
+ * data?: User
291
+ * error?: Error
292
+ * reload?: () => void
293
+ * }) {
294
+ * if (props.error) {
295
+ * return (
296
+ * <div>
297
+ * <p>Failed to load user: {props.error.message}</p>
298
+ * <button type="button" onClick={() => props.reload?.()}>
299
+ * Retry
300
+ * </button>
301
+ * </div>
302
+ * )
303
+ * }
304
+ *
305
+ * return <div>Hello, {props.data?.name}</div>
306
+ * }
307
+ *
308
+ * // Render-prop mode
309
+ * export function UserProfile(props: { id: number }) {
310
+ * return (
311
+ * <FaasDataWrapper<User>
312
+ * action="/pages/users/get"
313
+ * params={{ id: props.id }}
314
+ * fallback={<div>Loading user...</div>}
315
+ * render={({ data, error, reload }) => {
316
+ * if (error) {
317
+ * return (
318
+ * <div>
319
+ * <p>Failed to load user: {error.message}</p>
320
+ * <button type="button" onClick={() => reload()}>
321
+ * Retry
322
+ * </button>
323
+ * </div>
324
+ * )
325
+ * }
326
+ *
327
+ * return <div>Hello, {data.name}</div>
328
+ * }}
329
+ * />
330
+ * )
331
+ * }
332
+ *
333
+ * // Children injection mode
334
+ * export function UserProfileWithChildren(props: { id: number }) {
335
+ * return (
336
+ * <FaasDataWrapper<User>
337
+ * action="/pages/users/get"
338
+ * params={{ id: props.id }}
339
+ * fallback={<div>Loading user...</div>}
340
+ * >
341
+ * <UserView />
342
+ * </FaasDataWrapper>
343
+ * )
344
+ * }
53
345
  * ```
346
+ *
347
+ * When a ref is provided, it exposes the current Faas request state imperatively.
54
348
  */
55
- declare function withFaasData<PathOrData extends FaasActionUnionType, TComponentProps extends Required<FaasDataInjection<PathOrData>> = Required<FaasDataInjection<PathOrData>>>(Component: React.FC<TComponentProps>, faasProps: FaasDataWrapperProps<PathOrData>): React.FC<Omit<TComponentProps, keyof FaasDataInjection<PathOrData>> & Record<string, any>>;
56
-
349
+ declare const FaasDataWrapper: <Path extends FaasActionPaths>(props: FaasDataWrapperProps<Path> & _$react.RefAttributes<FaasDataWrapperRef<Path>>) => React.ReactElement | null;
57
350
  /**
58
- * Request faas server
351
+ * Wrap a component with {@link FaasDataWrapper} and inject Faas request state as props.
59
352
  *
60
- * @param action {string} action name
61
- * @param params {object} action params
62
- * @returns {Promise<Response<any>>}
353
+ * `withFaasData` is most useful for wrapper-style exports or when you want to
354
+ * preserve an existing component boundary. For new code, prefer `useFaas` or
355
+ * `FaasDataWrapper` when they express the request ownership more directly.
356
+ *
357
+ * @template Path - Action path or response data type used for inference.
358
+ * @template TComponentProps - Component props including injected Faas data fields.
359
+ * @param {React.FC<TComponentProps>} Component - Component that consumes injected Faas data props.
360
+ * @param {FaasDataWrapperProps<Path>} faasProps - Request configuration forwarded to `FaasDataWrapper`.
361
+ * @returns {React.FC<Omit<TComponentProps, keyof FaasDataInjection<Path>> & Record<string, any>>} Component that accepts the original props minus the injected Faas data fields.
63
362
  *
64
363
  * @example
65
- * ```ts
66
- * faas<{ title: string }>('post/get', { id: 1 }).then(res => {
67
- * console.log(res.data.title)
68
- * })
364
+ * ```tsx
365
+ * import { withFaasData } from '@faasjs/react'
366
+ *
367
+ * const MyComponent = withFaasData(
368
+ * ({ data, error, reload }) => {
369
+ * if (error) {
370
+ * return (
371
+ * <button type="button" onClick={() => reload()}>
372
+ * Retry
373
+ * </button>
374
+ * )
375
+ * }
376
+ *
377
+ * return <div>{data.name}</div>
378
+ * },
379
+ * { action: '/pages/users/get', params: { id: 1 } },
380
+ * )
69
381
  * ```
70
382
  */
71
- declare function faas<PathOrData extends FaasActionUnionType>(action: FaasAction<PathOrData>, params: FaasParams<PathOrData>, options?: Options): Promise<Response<FaasData<PathOrData>>>;
72
-
73
- type useFaasOptions<PathOrData extends FaasActionUnionType> = {
74
- params?: FaasParams<PathOrData>;
75
- data?: FaasData<PathOrData>;
76
- setData?: React.Dispatch<React.SetStateAction<FaasData<PathOrData>>>;
77
- /**
78
- * If skip is true, the request will not be sent.
79
- *
80
- * However, you can still use reload to send the request.
81
- */
82
- skip?: boolean | ((params: FaasParams<PathOrData>) => boolean);
83
- /** Send the last request after milliseconds */
84
- debounce?: number;
85
- baseUrl?: BaseUrl;
383
+ declare function withFaasData<Path extends FaasActionPaths, TComponentProps extends Required<FaasDataInjection<Path>> = Required<FaasDataInjection<Path>>>(Component: React.FC<TComponentProps>, faasProps: FaasDataWrapperProps<Path>): React.FC<Omit<TComponentProps, keyof FaasDataInjection<Path>> & Record<string, any>>;
384
+ //#endregion
385
+ //#region src/useFaasRequest.d.ts
386
+ /**
387
+ * Shared request options consumed by `useFaas` and `useFaasStream`.
388
+ *
389
+ * @property {Params} [params] - Controlled params override sent with the request without mutating local params state.
390
+ * @property {Data} [data] - Controlled data value used by higher-level hooks.
391
+ * @property {React.Dispatch<React.SetStateAction<Data>>} [setData] - Controlled setter paired with `data`.
392
+ * @property {boolean | ((params: Params) => boolean)} [skip] - Boolean or predicate that suppresses the automatic request.
393
+ * @property {number} [debounce] - Milliseconds to wait before sending the latest request.
394
+ * @property {number | false} [polling] - Milliseconds to wait after each completed request before refreshing data in the background.
395
+ * @property {BaseUrl} [baseUrl] - Base URL override used for this request lifecycle.
396
+ */
397
+ type SharedUseFaasOptions<Params, Data> = {
398
+ params?: Params;
399
+ data?: Data;
400
+ setData?: React.Dispatch<React.SetStateAction<Data>>;
401
+ skip?: boolean | ((params: Partial<Params>) => boolean);
402
+ debounce?: number;
403
+ polling?: number | false;
404
+ baseUrl?: BaseUrl;
86
405
  };
406
+ //#endregion
407
+ //#region src/useFaas/index.d.ts
87
408
  /**
88
- * Request faas server with React hook
409
+ * Options that customize the {@link useFaas} request lifecycle.
89
410
  *
90
- * @param action {string} action name
91
- * @param defaultParams {object} initial action params
92
- * @returns {FaasDataInjection<any>}
411
+ * @template Path - Action path or response data type used for inference.
412
+ */
413
+ type UseFaasOptions<Path extends FaasActionPaths> = SharedUseFaasOptions<FaasParams<Path>, FaasData<Path>>;
414
+ /**
415
+ * Request FaasJS data and keep request state in React state.
416
+ *
417
+ * `useFaas` is the default hook for standard FaasJS request-response flows in React.
418
+ * It sends an initial request unless `skip` is enabled, and returns request state
419
+ * plus helpers for reloading, background refreshing, updating data, and handling errors.
420
+ *
421
+ * @template Path - Action path or response data type used for inference.
422
+ *
423
+ * @param {Path} action - Action path to invoke.
424
+ * @param {FaasParams<Path>} defaultParams - Params used for the initial request and future reloads.
425
+ * @param {UseFaasOptions<Path>} [options] - Optional hook configuration such as controlled data, skip logic, debounce timing, polling, and base URL overrides.
426
+ * See the `UseFaasOptions` type for `params`, `data`, `setData`, `skip`, `debounce`, `polling`, and `baseUrl`.
427
+ * @returns {FaasDataInjection<Path>} Request state and helper methods described by {@link FaasDataInjection}.
93
428
  *
94
429
  * @example
95
430
  * ```tsx
96
- * function Post ({ id }) {
97
- * const { data } = useFaas<{ title: string }>('post/get', { id })
98
- * return <h1>{data.title}</h1>
431
+ * import { useFaas } from '@faasjs/react'
432
+ *
433
+ * function Profile({ id }: { id: number }) {
434
+ * const { data, error, loading, reload } = useFaas('/pages/users/get', { id })
435
+ *
436
+ * if (loading) return <div>Loading...</div>
437
+ *
438
+ * if (error) {
439
+ * return (
440
+ * <div>
441
+ * <div>Load failed: {error.message}</div>
442
+ * <button type="button" onClick={() => reload()}>
443
+ * Retry
444
+ * </button>
445
+ * </div>
446
+ * )
447
+ * }
448
+ *
449
+ * return (
450
+ * <div>
451
+ * <span>{data.name}</span>
452
+ * <button type="button" onClick={() => reload()}>
453
+ * Refresh
454
+ * </button>
455
+ * </div>
456
+ * )
99
457
  * }
100
458
  * ```
101
459
  */
102
- declare function useFaas<PathOrData extends FaasActionUnionType>(action: FaasAction<PathOrData>, defaultParams: FaasParams<PathOrData>, options?: useFaasOptions<PathOrData>): FaasDataInjection<PathOrData>;
103
-
460
+ declare function useFaas<Path extends FaasActionPaths>(action: Path, defaultParams: FaasParams<Path>, options?: UseFaasOptions<Path>): FaasDataInjection<Path>;
461
+ //#endregion
462
+ //#region src/client.d.ts
463
+ /**
464
+ * Factory for per-request error handlers used by {@link FaasReactClient}.
465
+ *
466
+ * @param {string} action - Action name that failed.
467
+ * @param {Record<string, any>} params - Params sent with the failed request.
468
+ * @returns {(res: ResponseError) => Promise<void>} Async callback invoked with the resulting {@link ResponseError}.
469
+ */
104
470
  type OnError = (action: string, params: Record<string, any>) => (res: ResponseError) => Promise<void>;
471
+ /**
472
+ * Options for creating a {@link FaasReactClient} instance.
473
+ */
105
474
  type FaasReactClientOptions = {
106
- /** @default `/` */
107
- baseUrl?: BaseUrl;
108
- options?: Options;
109
- /**
110
- * @example
111
- * ```ts
112
- * onError: (action, params) => async (res) => {
113
- * console.error(action, params, res)
114
- * }
115
- * ```
116
- */
117
- onError?: OnError;
475
+ /** @default `/` */baseUrl?: BaseUrl; /** Default request options forwarded to the underlying browser client. */
476
+ options?: Options;
477
+ /**
478
+ * Error hook invoked when `faas` or `useFaas` receives a failed response.
479
+ *
480
+ * @example
481
+ * ```ts
482
+ * import { ResponseError } from '@faasjs/react'
483
+ *
484
+ * onError: (action, params) => async (res) => {
485
+ * if (res instanceof ResponseError) {
486
+ * reportErrorToSentry(res, {
487
+ * tags: { action },
488
+ * extra: { params },
489
+ * })
490
+ * }
491
+ * }
492
+ * ```
493
+ */
494
+ onError?: OnError;
118
495
  };
496
+ /**
497
+ * Public interface returned by {@link FaasReactClient}.
498
+ */
119
499
  type FaasReactClientInstance = {
120
- id: string;
121
- faas: typeof faas;
122
- useFaas: typeof useFaas;
123
- FaasDataWrapper: typeof FaasDataWrapper;
124
- onError?: OnError;
125
- browserClient: FaasBrowserClient;
500
+ /** Unique identifier inherited from the underlying browser client. */id: string; /** Promise-based request helper bound to the registered base URL. */
501
+ faas: typeof faas; /** Hook bound to the registered base URL. */
502
+ useFaas: typeof useFaas; /** Wrapper component bound to the registered base URL. */
503
+ FaasDataWrapper: typeof FaasDataWrapper; /** Optional error hook shared by `faas` and `useFaas`. */
504
+ onError?: OnError; /** Underlying browser client used for the actual HTTP requests. */
505
+ browserClient: FaasBrowserClient;
126
506
  };
127
507
  /**
128
- * Before use faas, you should initialize a FaasReactClient.
508
+ * Create and register a FaasReactClient instance.
509
+ *
510
+ * The returned client is stored by `baseUrl` and becomes the default client
511
+ * used by helpers such as {@link faas} and {@link useFaas}.
129
512
  *
130
- * @param props.baseUrl {string} The baseUrl of your faas server
131
- * @param props.options {Options} The options of client
132
- * @returns {FaasReactClientInstance}
513
+ * @param {FaasReactClientOptions} [options] - Client configuration including base URL, default request options, and error hooks.
514
+ * @param {BaseUrl} [options.baseUrl] - Base URL used to register and route the client instance.
515
+ * @param {Options} [options.options] - Default browser-client request options forwarded to `FaasBrowserClient`.
516
+ * @param {OnError} [options.onError] - Hook factory used to handle failed `faas` and `useFaas` requests.
517
+ * See {@link Options} for supported browser-client request fields such as `headers`,
518
+ * `beforeRequest`, `request`, `baseUrl`, and `stream`.
519
+ * @returns {FaasReactClientInstance} Registered FaasReactClient instance.
133
520
  *
134
521
  * @example
135
522
  * ```ts
523
+ * import { FaasReactClient, ResponseError } from '@faasjs/react'
524
+ *
136
525
  * const client = FaasReactClient({
137
- * baseUrl: 'localhost:8080/api/'
526
+ * baseUrl: 'http://localhost:8080/api/',
527
+ * onError: (action, params) => async (res) => {
528
+ * if (res instanceof ResponseError) {
529
+ * reportErrorToSentry(res, {
530
+ * tags: { action },
531
+ * extra: { params },
532
+ * })
533
+ * }
534
+ * },
138
535
  * })
139
536
  * ```
140
537
  */
141
- declare function FaasReactClient({ baseUrl, options, onError }?: FaasReactClientOptions): FaasReactClientInstance;
538
+ declare function FaasReactClient(options?: FaasReactClientOptions): FaasReactClientInstance;
142
539
  /**
143
- * Get FaasReactClient instance
540
+ * Get a registered FaasReactClient instance.
144
541
  *
145
- * @param host {string} empty string for default host
146
- * @returns {FaasReactClientInstance}
542
+ * When `host` is omitted, the first registered client is returned. If no client
543
+ * has been created yet, a default client is initialized automatically.
544
+ * Use `getClient` only for special cases such as multiple Faas clients with
545
+ * different base URLs. In normal single-client app code, prefer the default
546
+ * `faas`, `useFaas`, or `FaasReactClient` setup directly.
547
+ *
548
+ * @param {string} [host] - Registered base URL to look up. Omit it to use the default client.
549
+ * @returns {FaasReactClientInstance} Registered or newly created FaasReactClient instance.
147
550
  *
148
551
  * @example
149
552
  * ```ts
150
- * getClient()
151
- * // or
152
- * getClient('another-host')
553
+ * import { FaasReactClient, getClient } from '@faasjs/react'
554
+ *
555
+ * FaasReactClient({
556
+ * baseUrl: 'https://service-a.example.com/api/',
557
+ * })
558
+ *
559
+ * FaasReactClient({
560
+ * baseUrl: 'https://service-b.example.com/api/',
561
+ * })
562
+ *
563
+ * const client = getClient('https://service-b.example.com/api/')
564
+ *
565
+ * await client.faas('/pages/posts/get', { id: 1 })
153
566
  * ```
154
567
  */
155
568
  declare function getClient(host?: string): FaasReactClientInstance;
156
-
569
+ //#endregion
570
+ //#region src/constants/index.d.ts
157
571
  /**
158
572
  * Returns a constant value that is created by the given function.
573
+ *
574
+ * @template T - Constant value type returned by the initializer.
575
+ * @param {() => T} fn - Initializer that runs only once for the current component instance.
576
+ * @returns {T} Stable value returned by the initializer.
577
+ *
578
+ * @example
579
+ * ```tsx
580
+ * import { useConstant } from '@faasjs/react'
581
+ *
582
+ * function Page() {
583
+ * const requestId = useConstant(() => crypto.randomUUID())
584
+ *
585
+ * return <span>{requestId}</span>
586
+ * }
587
+ * ```
159
588
  */
160
589
  declare function useConstant<T>(fn: () => T): T;
161
-
590
+ //#endregion
591
+ //#region src/ErrorBoundary/index.d.ts
592
+ /**
593
+ * Props for the {@link ErrorBoundary} component.
594
+ */
162
595
  interface ErrorBoundaryProps {
163
- children?: ReactNode;
164
- onError?: (error: Error | null, info: any) => void;
165
- errorChildren?: ReactElement<ErrorChildrenProps>;
596
+ /** Descendant elements protected by the boundary. */
597
+ children?: ReactNode;
598
+ /** Callback invoked after a descendant throws during rendering or lifecycle work. */
599
+ onError?: (error: Error | null, info: any) => void;
600
+ /** Custom fallback element cloned with captured error details. */
601
+ errorChildren?: ReactElement<ErrorChildrenProps>;
166
602
  }
603
+ /**
604
+ * Props injected into a custom error fallback element.
605
+ */
167
606
  type ErrorChildrenProps = {
168
- error?: Error;
169
- info?: any;
170
- errorMessage?: string;
171
- errorDescription?: string;
607
+ /** Captured error instance. */error?: Error; /** React component stack metadata for the captured error. */
608
+ info?: any; /** Stringified error message shown by the default fallback. */
609
+ errorMessage?: string; /** Component stack description shown by the default fallback. */
610
+ errorDescription?: string;
172
611
  };
612
+ /**
613
+ * React error boundary with an optional custom fallback element.
614
+ *
615
+ * The boundary renders its children until a descendant throws. After that it
616
+ * either clones `errorChildren` with injected error details or renders a simple
617
+ * built-in fallback.
618
+ *
619
+ * @example
620
+ * ```tsx
621
+ * import { ErrorBoundary } from '@faasjs/react'
622
+ *
623
+ * function Fallback({ errorMessage }: { errorMessage?: string }) {
624
+ * return <div>{errorMessage}</div>
625
+ * }
626
+ *
627
+ * <ErrorBoundary errorChildren={<Fallback />}>
628
+ * <DangerousWidget />
629
+ * </ErrorBoundary>
630
+ * ```
631
+ */
173
632
  declare class ErrorBoundary extends Component<ErrorBoundaryProps, {
174
- error?: Error;
175
- info?: {
176
- componentStack?: string;
177
- };
633
+ error: Error | null;
634
+ info: ErrorInfo;
178
635
  }> {
179
- static displayName: string;
180
- constructor(props: ErrorBoundaryProps);
181
- componentDidCatch(error: Error | null, info: any): void;
182
- render(): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode>>;
636
+ /**
637
+ * Stable display name used by React DevTools.
638
+ */
639
+ static displayName: string;
640
+ /**
641
+ * Create an error boundary with empty error state.
642
+ *
643
+ * @param {ErrorBoundaryProps} props - Boundary props.
644
+ * @param {ReactNode} [props.children] - Descendant elements protected by the boundary.
645
+ * @param {(error: Error | null, info: any) => void} [props.onError] - Callback invoked after a render error is captured.
646
+ * @param {ReactElement<ErrorChildrenProps>} [props.errorChildren] - Custom fallback element that receives error details.
647
+ */
648
+ constructor(props: ErrorBoundaryProps);
649
+ /**
650
+ * Capture rendering errors from descendant components.
651
+ *
652
+ * @param {Error} error - Caught render error.
653
+ * @param {ErrorInfo} info - React component stack metadata.
654
+ */
655
+ componentDidCatch(error: Error, info: ErrorInfo): void;
656
+ /**
657
+ * Render children or the configured fallback for the captured error.
658
+ */
659
+ render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | _$react.ReactPortal | ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | _$react_jsx_runtime0.JSX.Element | null;
183
660
  }
184
-
661
+ //#endregion
662
+ //#region src/equal/index.d.ts
185
663
  /**
186
664
  * Compares two values for deep equality.
187
665
  *
@@ -189,248 +667,126 @@ declare class ErrorBoundary extends Component<ErrorBoundaryProps, {
189
667
  * It handles various data types including primitives, arrays, dates, regular expressions, functions,
190
668
  * maps, sets, and promises.
191
669
  *
192
- * @param a - The first value to compare.
193
- * @param b - The second value to compare.
194
- * @returns `true` if the values are deeply equal, `false` otherwise.
670
+ * @param {any} a - The first value to compare.
671
+ * @param {any} b - The second value to compare.
672
+ * @returns {boolean} `true` if the values are deeply equal, `false` otherwise.
673
+ *
674
+ * @example
675
+ * ```ts
676
+ * import { equal } from '@faasjs/react'
677
+ *
678
+ * equal({ page: 1, filters: ['a'] }, { page: 1, filters: ['a'] }) // true
679
+ * equal({ page: 1 }, { page: 2 }) // false
680
+ * ```
195
681
  */
196
682
  declare function equal(a: any, b: any): boolean;
197
683
  /**
198
684
  * Custom hook that memoizes a value using deep equality comparison.
199
685
  *
200
- * @param value - The value to be memoized.
201
- * @returns The memoized value.
686
+ * @param {any} value - The value to be memoized.
687
+ * @returns {any} The memoized value.
688
+ *
689
+ * @example
690
+ * ```tsx
691
+ * import { useEqualMemoize } from '@faasjs/react'
692
+ *
693
+ * function Filters({ filters }: { filters: Record<string, any> }) {
694
+ * const memoizedFilters = useEqualMemoize(filters)
695
+ *
696
+ * return <pre>{JSON.stringify(memoizedFilters)}</pre>
697
+ * }
698
+ * ```
202
699
  */
203
700
  declare function useEqualMemoize(value: any): any;
204
701
  /**
205
702
  * Custom hook that works like `useEffect` but uses deep comparison on dependencies.
206
703
  *
207
- * @param callback - The effect callback function to run.
208
- * @param dependencies - The list of dependencies for the effect.
209
- * @returns The result of the `useEffect` hook with memoized dependencies.
210
- */
211
- declare function useEqualEffect(callback: React.EffectCallback, dependencies: any[]): void;
212
- /**
213
- * Custom hook that works like `useMemo` but uses deep comparison on dependencies.
704
+ * @param {React.EffectCallback} callback - The effect callback function to run.
705
+ * @param {any[]} dependencies - The list of dependencies for the effect.
706
+ * @returns {void} The result of the `useEffect` hook with memoized dependencies.
214
707
  *
215
- * @param callback - The callback function to run.
216
- * @param dependencies - The list of dependencies.
217
- * @returns The result of the `useMemo` hook with memoized dependencies.
218
- */
219
- declare function useEqualMemo<T>(callback: () => T, dependencies: any[]): T;
220
- /**
221
- * Custom hook that works like `useCallback` but uses deep comparison on dependencies.
708
+ * @example
709
+ * ```tsx
710
+ * import { useEqualEffect } from '@faasjs/react'
222
711
  *
223
- * @param callback - The callback function to run.
224
- * @param dependencies - The list of dependencies.
225
- * @returns The result of the `useCallback` hook with memoized dependencies.
226
- */
227
- declare function useEqualCallback<T extends (...args: any[]) => any>(callback: T, dependencies: any[]): T;
228
-
229
- /**
230
- * Props for the FormButtonElement component.
712
+ * function Page({ filters }: { filters: Record<string, any> }) {
713
+ * useEqualEffect(() => {
714
+ * console.log('filters changed', filters)
715
+ * }, [filters])
231
716
  *
232
- * @property {React.ReactNode} [children] - The content to be displayed inside the button.
233
- * @property {boolean} disabled - Indicates whether the button is disabled.
234
- * @property {() => Promise<void>} submit - A function to be called when the button is clicked, which returns a promise.
235
- */
236
- type FormButtonElementProps = {
237
- children?: React.ReactNode;
238
- submitting: boolean;
239
- submit: () => Promise<void>;
240
- };
241
-
242
- /**
243
- * Props for the Form Input Element component.
244
- *
245
- * @property {string} name - The name of the input element.
246
- * @property {any} value - The current value of the input element.
247
- * @property {(value: any) => void} onChange - Callback function to handle changes to the input value.
717
+ * return null
718
+ * }
719
+ * ```
248
720
  */
249
- type FormInputElementProps = {
250
- name: string;
251
- value: any;
252
- onChange: (value: any) => void;
253
- };
254
-
255
- /**
256
- * Props for the FormLabelElement component.
257
- *
258
- * @typedef {Object} FormLabelElementProps
259
- * @property {string} name - The name of the form element.
260
- * @property {ReactNode} [title] - Optional title for the form element.
261
- * @property {ReactNode} [description] - Optional description for the form element.
262
- * @property {Error} [error] - Optional error associated with the form element.
263
- * @property {ReactNode} children - The child elements, typically an input element.
264
- */
265
- type FormLabelElementProps = {
266
- name: string;
267
- title?: ReactNode;
268
- description?: ReactNode;
269
- error?: Error;
270
- /** as Input element */
271
- children: ReactNode;
272
- };
273
-
721
+ declare function useEqualEffect(callback: React.EffectCallback, dependencies: any[]): void;
274
722
  /**
275
- * Represents the types of form elements used in the form.
723
+ * Custom hook that works like `useMemo` but uses deep comparison on dependencies.
276
724
  *
277
- * @typedef {Object} FormElementTypes
278
- * @property {ComponentType<FormLabelElementProps>} Label - The component type for the form label element.
279
- * @property {ComponentType<FormInputElementProps>} Input - The component type for the form input element.
280
- * @property {ComponentType<FormButtonElementProps>} Button - The component type for the form button element.
281
- */
282
- type FormElementTypes = {
283
- Label: ComponentType<FormLabelElementProps>;
284
- Input: ComponentType<FormInputElementProps>;
285
- Button: ComponentType<FormButtonElementProps>;
286
- };
287
- declare const FormDefaultElements: FormElementTypes;
288
-
289
- declare const FormDefaultLang: {
290
- submit: string;
291
- required: string;
292
- string: string;
293
- number: string;
294
- };
295
- type FormLang = typeof FormDefaultLang;
296
-
297
- /**
298
- * A type representing a form validation rule.
725
+ * @template T - Memoized value type returned by the callback.
299
726
  *
300
- * @template Options - The type of the options that can be passed to the rule.
727
+ * @param {() => T} callback - The callback function to run.
728
+ * @param {any[]} dependencies - The list of dependencies.
729
+ * @returns {T} The result of the `useMemo` hook with memoized dependencies.
301
730
  *
302
- * @param value - The value to be validated.
303
- * @param options - Optional. Additional options that can be used in the validation.
304
- * @param lang - Optional. The language settings that can be used in the validation.
731
+ * @example
732
+ * ```tsx
733
+ * import { useEqualMemo } from '@faasjs/react'
305
734
  *
306
- * @returns A promise that resolves if the validation is successful, or rejects with an error if the validation fails.
735
+ * function Page({ filters }: { filters: Record<string, any> }) {
736
+ * const queryString = useEqualMemo(() => JSON.stringify(filters), [filters])
307
737
  *
308
- * @example
309
- * ```ts
310
- * async function required(value: any, options: boolean, lang?: FormLang) {
311
- * if (value === null || value === undefined || value === '' || Number.isNaN(value))
312
- * throw Error(lang?.required)
738
+ * return <span>{queryString}</span>
313
739
  * }
314
740
  * ```
315
741
  */
316
- type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<void>;
317
- type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<void> ? O : never;
318
- /**
319
- * A type representing a set of form validation rules.
320
- *
321
- * @typedef {Record<string, FormRule>} FormRules
322
- *
323
- * Each key in the record represents the name of a form field, and the corresponding value is a `FormRule` object that defines the validation rules for that field.
324
- */
325
- type FormRules = Record<string, FormRule>;
326
- type InferFormRulesOptions<T> = {
327
- [K in keyof T]: InferRuleOption<T[K]>;
328
- };
329
- /**
330
- * Default validation rules for a form.
331
- *
332
- * @constant
333
- * @type {FormRules}
334
- */
335
- declare const FormDefaultRules: FormRules;
336
- type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
337
- declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
338
-
339
- type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
340
- type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
341
- Input?: ComponentType<FormInputElementProps>;
342
- props?: InferFormInputProps<FormElements['Input']>;
343
- };
344
-
345
- type FormItemName = string;
346
- type FormItemProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
347
- name: FormItemName;
348
- label?: Omit<FormLabelElementProps, 'name' | 'children'> & {
349
- Label?: ComponentType<FormLabelElementProps>;
350
- };
351
- input?: FormInputProps<FormElements>;
352
- rules?: FormRulesOptions;
353
- };
354
- declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
355
- declare namespace FormItem {
356
- var displayName: string;
357
- }
358
-
359
- type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
360
- items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
361
- onSubmit?: (values: Values) => Promise<void>;
362
- Elements?: Partial<FormElements>;
363
- lang?: Partial<FormLang>;
364
- defaultValues?: Values;
365
- rules?: typeof FormDefaultRules & Rules;
366
- };
742
+ declare function useEqualMemo<T>(callback: () => T, dependencies: any[]): T;
367
743
  /**
368
- * FormContainer component is a wrapper that provides context and state management for form elements.
369
- * It initializes form states such as values, errors, submitting status, elements, language, and rules.
370
- *
371
- * @template Values - The type of form values, defaults to Record<string, any>.
372
- * @template FormElements - The type of form elements, defaults to FormElementTypes.
373
- * @template Rules - The type of form rules, defaults to FormDefaultRules.
744
+ * Custom hook that works like `useCallback` but uses deep comparison on dependencies.
374
745
  *
375
- * @param {FormProps<Values, FormElements, Rules>} props - The properties for the FormContainer component.
376
- * @param {Values} props.defaultValues - The default values for the form fields.
377
- * @param {FormElements} props.Elements - The form elements to be used in the form.
378
- * @param {Rules} props.rules - The validation rules for the form fields.
379
- * @param {FormLang} props.lang - The language settings for the form.
380
- * @param {Partial<FormContextProps>} props - Additional properties for the form context.
746
+ * @template T - Callback signature to memoize.
381
747
  *
382
- * @returns {JSX.Element} The FormContainer component.
748
+ * @param {T} callback - The callback function to run.
749
+ * @param {any[]} dependencies - The list of dependencies.
750
+ * @returns {T} The result of the `useCallback` hook with memoized dependencies.
383
751
  *
384
752
  * @example
385
753
  * ```tsx
386
- * import { Form } from '@faasjs/react'
387
- *
388
- * function MyForm() {
389
- * return <Form
390
- * items={[
391
- * { name: 'name' },
392
- * ]}
393
- * />
754
+ * import { useEqualCallback } from '@faasjs/react'
755
+ *
756
+ * function Search({ filters }: { filters: Record<string, any> }) {
757
+ * const handleSubmit = useEqualCallback(() => {
758
+ * console.log(filters)
759
+ * }, [filters])
760
+ *
761
+ * return <button onClick={handleSubmit}>Search</button>
394
762
  * }
395
763
  * ```
396
764
  */
397
- declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules>({ defaultValues, Elements, rules, lang, items, ...props }: FormProps<Values, FormElements, Rules>): react_jsx_runtime.JSX.Element;
398
- declare namespace FormContainer {
399
- var displayName: string;
400
- }
401
-
402
- type FormContextProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
403
- items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
404
- onSubmit: (values: Values) => Promise<void>;
405
- Elements: FormElementTypes;
406
- lang: FormLang;
407
- rules: typeof FormDefaultRules & Rules;
408
- submitting: boolean;
409
- setSubmitting: Dispatch<SetStateAction<boolean>>;
410
- values: Values;
411
- setValues: Dispatch<SetStateAction<Values>>;
412
- errors: Record<string, Error>;
413
- setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
414
- valuesRef: RefObject<Values>;
415
- };
416
- declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>(props: {
417
- value?: Partial<NewT>;
418
- children: react.ReactNode;
419
- memo?: true | any[];
420
- initializeStates?: Partial<NewT>;
421
- }) => react.ReactNode;
422
- declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>() => Readonly<NewT>;
423
-
765
+ declare function useEqualCallback<T extends (...args: any[]) => any>(callback: T, dependencies: any[]): T;
766
+ //#endregion
767
+ //#region src/OptionalWrapper/index.d.ts
768
+ /**
769
+ * Props for the {@link OptionalWrapper} helper component.
770
+ *
771
+ * @template TWrapper - Wrapper component type used when `condition` is true.
772
+ */
424
773
  type OptionalWrapperProps<TWrapper extends ComponentType<{
425
- children: ReactNode;
774
+ children: ReactNode;
426
775
  }> = any> = {
427
- condition: boolean;
428
- Wrapper: TWrapper;
429
- wrapperProps?: ComponentProps<TWrapper>;
430
- children: ReactNode;
776
+ /** When `true`, render `children` inside `Wrapper`. */condition: boolean; /** Wrapper component used when `condition` passes. */
777
+ Wrapper: TWrapper; /** Props forwarded to `Wrapper` together with `children`. */
778
+ wrapperProps?: ComponentProps<TWrapper>; /** Content rendered directly or inside the wrapper. */
779
+ children: ReactNode;
431
780
  };
432
781
  /**
433
- * A wrapper component that conditionally wraps its children with a provided wrapper component.
782
+ * Conditionally wrap children with another component.
783
+ *
784
+ * @param {OptionalWrapperProps} props - Wrapper condition, wrapper component, and child content.
785
+ * @param {boolean} props.condition - When `true`, wrap children with `Wrapper`.
786
+ * @param {OptionalWrapperProps['Wrapper']} props.Wrapper - Component used as the wrapper when the condition passes.
787
+ * @param {OptionalWrapperProps['wrapperProps']} [props.wrapperProps] - Props forwarded to the wrapper component.
788
+ * @param {ReactNode} props.children - Content rendered directly or inside the wrapper.
789
+ * @returns {ReactNode} Wrapped children or the original children when `condition` is false.
434
790
  *
435
791
  * @example
436
792
  * ```tsx
@@ -447,15 +803,22 @@ type OptionalWrapperProps<TWrapper extends ComponentType<{
447
803
  * )
448
804
  * ```
449
805
  */
450
- declare function OptionalWrapper({ condition, Wrapper, wrapperProps, children, }: OptionalWrapperProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode>>;
806
+ declare function OptionalWrapper(props: OptionalWrapperProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | _$react.ReactPortal | _$react.ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | _$react_jsx_runtime0.JSX.Element | null | undefined;
451
807
  declare namespace OptionalWrapper {
452
- var displayName: string;
808
+ var displayName: string;
453
809
  }
454
-
810
+ //#endregion
811
+ //#region src/splitting-context/index.d.ts
455
812
  /**
456
- * Creates a splitting context with the given default value.
813
+ * Create a context whose keys can be consumed independently.
814
+ *
815
+ * `createSplittingContext` returns a `Provider` and a `use` hook. Each key in
816
+ * the provided shape is backed by a separate React context so readers only
817
+ * subscribe to the values they access.
457
818
  *
458
- * @param defaultValue The default value of the splitting context.
819
+ * @template T - Context value shape exposed by the provider and hook.
820
+ * @param {Record<string, any> | (keyof T)[]} defaultValue - Default value map or key list used to create split contexts.
821
+ * @returns {{ Provider<NewT extends T = T>(this: void, props: { value?: Partial<NewT>; children: ReactNode; memo?: true | any[]; initializeStates?: Partial<NewT> }): ReactNode; use<NewT extends T = T>(this: void): Readonly<NewT> }} Provider and hook helpers for the split context.
459
822
  *
460
823
  * @example
461
824
  * ```tsx
@@ -495,176 +858,213 @@ declare namespace OptionalWrapper {
495
858
  * }
496
859
  * ```
497
860
  */
498
- declare function createSplittingContext<T extends Record<string, any>>(defaultValue: {
499
- [K in keyof T]: Partial<T[K]> | null;
500
- } | (keyof T)[]): {
861
+ declare function createSplittingContext<T extends Record<string, any>>(defaultValue: { [K in keyof T]: Partial<T[K]> | null } | (keyof T)[]): {
862
+ /**
863
+ * The provider component of the splitting context.
864
+ *
865
+ * @see [Provider docs](https://faasjs.com/doc/react/functions/createSplittingContext.html#provider)
866
+ *
867
+ * @example
868
+ * ```tsx
869
+ * function App() {
870
+ * const [value, setValue] = useState(0)
871
+ *
872
+ * return (
873
+ * <Provider value={{ value, setValue }}>
874
+ * <ReaderComponent />
875
+ * <WriterComponent />
876
+ * </Provider>
877
+ * )
878
+ * }
879
+ * ```
880
+ */
881
+ Provider<NewT extends T = T>(this: void, props: {
882
+ /** Partial context value supplied by the caller. */value?: Partial<NewT>; /** Descendant elements that should read from the split contexts. */
883
+ children: ReactNode;
501
884
  /**
502
- * The provider component of the splitting context.
885
+ * Memoization mode for `children`.
503
886
  *
504
- * @see https://faasjs.com/doc/react/functions/createSplittingContext.html#provider
887
+ * @default false
505
888
  *
506
- * @example
507
- * ```tsx
508
- * function App() {
509
- * const [value, setValue] = useState(0)
510
- *
511
- * return (
512
- * <Provider value={{ value, setValue }}>
513
- * <ReaderComponent />
514
- * <WriterComponent />
515
- * </Provider>
516
- * )
517
- * }
518
- * ```
889
+ * Pass `true` to memoize without dependencies or an array to control the
890
+ * deep-equality dependency list manually.
519
891
  */
520
- Provider<NewT extends T = T>(props: {
521
- value?: Partial<NewT>;
522
- children: ReactNode;
523
- /**
524
- * Whether to use memoization for the children.
525
- *
526
- * @default false
527
- *
528
- * `true`: memoize the children without dependencies.
529
- * `any[]`: memoize the children with specific dependencies.
530
- */
531
- memo?: true | any[];
532
- /**
533
- * An object containing initial values that will be automatically converted into state variables using {@link useSplittingState} hook. Each property will create both a state value and its setter following the pattern: value/setValue.
534
- *
535
- * @example
536
- * ```tsx
537
- * <Provider
538
- * initializeStates={{
539
- * value: 0,
540
- * }}
541
- * >
542
- * // Children will have access to: value, setValue
543
- * </Provider>
544
- */
545
- initializeStates?: Partial<NewT>;
546
- }): ReactNode;
892
+ memo?: true | any[];
547
893
  /**
548
- * The hook to use the splitting context.
894
+ * Initial values converted into local state via `useSplittingState`.
549
895
  *
550
- * @see https://faasjs.com/doc/react/functions/createSplittingContext.html#use
896
+ * Each key produces both a state value and its matching setter using the
897
+ * `value` / `setValue` naming convention.
551
898
  *
552
899
  * @example
553
900
  * ```tsx
554
- * function ChildComponent() {
555
- * const { value, setValue } = use()
901
+ * <Provider initializeStates={{ value: 0 }}>
902
+ * <Child />
903
+ * </Provider>
556
904
  *
557
- * return <div>{value}<button onClick={() => setValue(1)}>change value</button></div>
558
- * }
905
+ * // `Child` can read `value` and `setValue`
559
906
  * ```
560
907
  */
561
- use: <NewT extends T = T>() => Readonly<NewT>;
562
- };
563
-
564
- type SetPrefix<S extends string | number | symbol> = S extends string ? S extends `${infer First}${infer Rest}` ? `set${Capitalize<First>}${Rest}` : never : never;
565
- type StateSetters<T> = {
566
- [K in keyof T as SetPrefix<K>]: Dispatch<SetStateAction<T[K]>>;
908
+ initializeStates?: Partial<NewT>;
909
+ }): ReactNode;
910
+ /**
911
+ * Hook used to read values from the splitting context.
912
+ *
913
+ * @see [Hook docs](https://faasjs.com/doc/react/functions/createSplittingContext.html#use)
914
+ *
915
+ * @example
916
+ * ```tsx
917
+ * function ChildComponent() {
918
+ * const { value, setValue } = use()
919
+ *
920
+ * return <div>{value}<button onClick={() => setValue(1)}>change value</button></div>
921
+ * }
922
+ * ```
923
+ */
924
+ use: <NewT extends T = T>(this: void) => Readonly<NewT>;
567
925
  };
926
+ //#endregion
927
+ //#region src/splitting-state/index.d.ts
928
+ /**
929
+ * Setter map generated by {@link useSplittingState} for each state key.
930
+ *
931
+ * @template T - Object shape whose keys receive generated setter functions.
932
+ */
933
+ type StateSetters<T> = { [K in keyof T as K extends string ? K extends `${infer First}${infer Rest}` ? `set${Capitalize<First>}${Rest}` : never : never]: Dispatch<SetStateAction<T[K]>> };
934
+ /**
935
+ * State object returned by {@link useSplittingState}, including generated setters.
936
+ *
937
+ * @template T - Object shape returned together with generated setter functions.
938
+ */
568
939
  type StatesWithSetters<T> = T & StateSetters<T>;
569
940
  /**
570
- * A hook that initializes and splits state variables and their corresponding setters.
941
+ * Create local state entries and matching setters for each key in an object.
571
942
  *
572
943
  * @template T - A generic type that extends a record with string keys and any values.
573
- * @param {T} initialStates - An object containing the initial states.
944
+ * @param {T} initialStates - Object whose keys become state values and `setXxx` setters.
945
+ * @returns {StatesWithSetters<T>} Object containing the original keys plus generated setter functions.
574
946
  *
575
947
  * @example
576
948
  * ```tsx
577
949
  * function Counter() {
578
- * const { count, setCount, name, setName } = useSplittingState({ count: 0, name: 'John' });
950
+ * const { count, setCount, name, setName } = useSplittingState({ count: 0, name: 'John' })
579
951
  *
580
952
  * return <>{name}: {count}</>
581
953
  * }
582
954
  * ```
583
955
  */
584
956
  declare function useSplittingState<T extends Record<string, unknown>>(initialStates: T): StatesWithSetters<T>;
585
-
586
- type UseFaasStreamOptions = {
587
- params?: Record<string, any>;
588
- data?: string;
589
- setData?: React.Dispatch<React.SetStateAction<string>>;
590
- /**
591
- * If skip is true, the request will not be sent.
592
- *
593
- * However, you can still use reload to send the request.
594
- */
595
- skip?: boolean | ((params: Record<string, any>) => boolean);
596
- /** Send the last request after milliseconds */
597
- debounce?: number;
598
- baseUrl?: BaseUrl;
599
- };
600
- type UseFaasStreamResult = {
601
- action: string;
602
- params: Record<string, any>;
603
- loading: boolean;
604
- reloadTimes: number;
605
- data: string;
606
- error: any;
607
- reload: (params?: Record<string, any>) => Promise<string>;
608
- setData: React.Dispatch<React.SetStateAction<string>>;
609
- setLoading: React.Dispatch<React.SetStateAction<boolean>>;
610
- setError: React.Dispatch<React.SetStateAction<any>>;
957
+ //#endregion
958
+ //#region src/useFaasStream/index.d.ts
959
+ /**
960
+ * Options that customize the {@link useFaasStream} request lifecycle.
961
+ */
962
+ type UseFaasStreamOptions = SharedUseFaasOptions<Record<string, any>, string>;
963
+ /**
964
+ * Result returned by {@link useFaasStream}.
965
+ *
966
+ * @template Path - Action path used for params inference.
967
+ */
968
+ type UseFaasStreamResult<Path extends FaasActionPaths> = {
969
+ /** Action path currently associated with the stream request. */action: Path; /** Params used for the most recent request attempt. */
970
+ params: FaasParams<Path>; /** Whether the hook is currently waiting for stream data and should block the main UI. */
971
+ loading: boolean; /** Whether a background stream refresh is currently in flight. */
972
+ refreshing: boolean; /** Number of times `reload()` or polling has triggered a new request. */
973
+ reloadTimes: number; /** Accumulated text decoded from the stream response. */
974
+ data: string; /** Last error raised while opening or consuming the stream. */
975
+ error: any; /** Trigger a new streaming request with optional params. */
976
+ reload: (params?: FaasParams<Path>, options?: {
977
+ silent?: boolean;
978
+ }) => Promise<string>; /** Controlled or internal setter for the accumulated text. */
979
+ setData: React.Dispatch<React.SetStateAction<string>>; /** Setter for the loading flag. */
980
+ setLoading: React.Dispatch<React.SetStateAction<boolean>>; /** Setter for the last stream error. */
981
+ setError: React.Dispatch<React.SetStateAction<any>>;
611
982
  };
612
983
  /**
613
- * Stream faas server response with React hook
984
+ * Stream a FaasJS response into React state.
985
+ *
986
+ * `useFaasStream` is the default hook for streaming FaasJS responses in React.
987
+ * It sends a streaming request, appends decoded text chunks to `data`, and
988
+ * exposes reload helpers for retrying the same action.
614
989
  *
615
- * @param action {string} action name
616
- * @param defaultParams {object} initial action params
617
- * @returns {UseFaasStreamResult}
990
+ * @param {string} action - Action path to invoke.
991
+ * @param {Record<string, any>} defaultParams - Params used for the initial request and future reloads.
992
+ * @param {UseFaasStreamOptions} [options] - Optional hook configuration such as controlled stream text, skip logic, debounce timing, polling, and base URL overrides.
993
+ * See the `UseFaasStreamOptions` type for `params`, `data`, `setData`, `skip`, `debounce`, `polling`, and `baseUrl`.
994
+ * @returns {UseFaasStreamResult} Streaming request state and helper methods described by {@link UseFaasStreamResult}.
618
995
  *
619
996
  * @example
620
997
  * ```tsx
621
- * function Chat() {
622
- * const [prompt, setPrompt] = useState('')
623
- * const { data, loading, reload } = useFaasStream('chat', { prompt })
998
+ * import { useFaasStream } from '@faasjs/react'
624
999
  *
625
- * return (
626
- * <div>
627
- * <textarea value={prompt} onChange={e => setPrompt(e.target.value)} />
628
- * <button onClick={reload} disabled={loading}>Send</button>
629
- * <div>{data}</div>
630
- * </div>
631
- * )
1000
+ * function Chat({ prompt }: { prompt: string }) {
1001
+ * const { data, error, loading, reload } = useFaasStream('/pages/chat/stream', { prompt })
1002
+ *
1003
+ * if (loading) return <div>Streaming...</div>
1004
+ *
1005
+ * if (error) {
1006
+ * return (
1007
+ * <div>
1008
+ * <div>Stream failed: {error.message}</div>
1009
+ * <button type="button" onClick={() => reload()}>
1010
+ * Retry
1011
+ * </button>
1012
+ * </div>
1013
+ * )
1014
+ * }
1015
+ *
1016
+ * return <pre>{data}</pre>
632
1017
  * }
633
1018
  * ```
634
1019
  */
635
- declare function useFaasStream(action: string, defaultParams: Record<string, any>, options?: UseFaasStreamOptions): UseFaasStreamResult;
636
-
1020
+ declare function useFaasStream<Path extends FaasActionPaths>(action: Path, defaultParams: FaasParams<Path>, options?: UseFaasStreamOptions): UseFaasStreamResult<Path>;
1021
+ //#endregion
1022
+ //#region src/usePrevious/index.d.ts
637
1023
  /**
638
1024
  * Hook to store the previous value of a state or prop.
639
1025
  *
640
1026
  * @template T - The type of the value.
641
- * @param {T} value - The current value to be stored.
642
- * @returns {T | undefined} - The previous value, or undefined if there is no previous value.
1027
+ * @param {T} value - The current value to track.
1028
+ * @returns {T | undefined} Previous value from the prior render, or `undefined` on the first render.
1029
+ *
1030
+ * @example
1031
+ * ```tsx
1032
+ * import { usePrevious } from '@faasjs/react'
1033
+ *
1034
+ * function Counter({ count }: { count: number }) {
1035
+ * const previous = usePrevious(count)
1036
+ *
1037
+ * return <span>{previous} -> {count}</span>
1038
+ * }
1039
+ * ```
643
1040
  */
644
1041
  declare function usePrevious<T = any>(value: T): T | undefined;
645
-
1042
+ //#endregion
1043
+ //#region src/useStateRef/index.d.ts
646
1044
  /**
647
1045
  * Custom hook that returns a stateful value and a ref to that value.
648
1046
  *
649
1047
  * @template T - The type of the value.
650
- * @param {T} initialValue - The initial value of the state.
651
- * @returns {[T, (value: T) => void, RefObject<T>]} - The stateful value, a function to set the value, and a ref to the value.
1048
+ * @param {T} [initialValue] - Initial state value. When omitted, state starts as `null`.
1049
+ * @returns {[T | null, Dispatch<SetStateAction<T | null>>, RefObject<T | null>]} Tuple containing the current state, the state setter, and a ref that always points at the latest state.
652
1050
  *
653
1051
  * @example
654
1052
  * ```tsx
655
1053
  * import { useStateRef } from '@faasjs/react'
656
1054
  *
657
1055
  * function MyComponent() {
658
- * const [value, setValue, ref] = useStateRef(0)
659
- *
660
- * return (
661
- * <div>
662
- * <p>Value: {value}</p>
663
- * <button onClick={() => setValue(value + 1)}>Increment</button>
664
- * <button onClick={() => console.log(ref.current)}>Submit</button>
665
- * </div>
666
- * )
1056
+ * const [value, setValue, ref] = useStateRef(0)
1057
+ *
1058
+ * return (
1059
+ * <div>
1060
+ * <p>Value: {value}</p>
1061
+ * <button onClick={() => setValue(value + 1)}>Increment</button>
1062
+ * <button onClick={() => console.log(ref.current)}>Submit</button>
1063
+ * </div>
1064
+ * )
1065
+ * }
1066
+ * ```
667
1067
  */
668
- declare function useStateRef<T = any>(initialValue?: T): [T, Dispatch<SetStateAction<T>>, RefObject<T>];
669
-
670
- export { ErrorBoundary, type ErrorBoundaryProps, type ErrorChildrenProps, type FaasDataInjection, FaasDataWrapper, type FaasDataWrapperProps, type FaasDataWrapperRef, FaasReactClient, type FaasReactClientInstance, type FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, type FormContextProps, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, type FormDefaultRulesOptions, type FormElementTypes, type FormInputElementProps, FormItem, type FormItemName, type FormItemProps, type FormLabelElementProps, type FormLang, type FormProps, type FormRule, type FormRules, type InferFormRulesOptions, type OnError, OptionalWrapper, type OptionalWrapperProps, type UseFaasStreamOptions, type UseFaasStreamResult, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, type useFaasOptions, useFaasStream, useFormContext, usePrevious, useSplittingState, useStateRef, validValues, withFaasData };
1068
+ declare function useStateRef<T = any>(initialValue?: T): [T | null, Dispatch<SetStateAction<T | null>>, RefObject<T | null>];
1069
+ //#endregion
1070
+ export { type BaseUrl, ErrorBoundary, ErrorBoundaryProps, ErrorChildrenProps, FaasBrowserClient, type FaasBrowserClientAction, FaasDataInjection, FaasDataWrapper, FaasDataWrapperProps, FaasDataWrapperRef, FaasReactClient, FaasReactClientInstance, FaasReactClientOptions, type MockHandler, OnError, OptionalWrapper, OptionalWrapperProps, type Options, Response, ResponseError, type ResponseErrorProps, type ResponseHeaders, type ResponseProps, StateSetters, StatesWithSetters, UseFaasOptions, UseFaasStreamOptions, UseFaasStreamResult, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasStream, usePrevious, useSplittingState, useStateRef, withFaasData };