@faasjs/react 8.0.0-beta.2 → 8.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -68
- package/dist/index.d.ts +1571 -410
- package/dist/index.mjs +1796 -596
- package/package.json +18 -22
- package/dist/index.cjs +0 -652
package/dist/index.d.ts
CHANGED
|
@@ -1,191 +1,1368 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
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 { FaasAction, FaasAction as FaasAction$1, FaasActionUnionType, FaasActionUnionType as FaasActionUnionType$1, FaasData, FaasData as FaasData$1, FaasParams, FaasParams as FaasParams$1 } from "@faasjs/types";
|
|
8
5
|
|
|
6
|
+
//#region src/generateId.d.ts
|
|
9
7
|
/**
|
|
10
|
-
*
|
|
8
|
+
* Generate a random identifier with an optional prefix.
|
|
9
|
+
*
|
|
10
|
+
* @param prefix - Prefix prepended to the generated identifier.
|
|
11
|
+
* @param length - Length of the generated identifier excluding `prefix`. Must be between `8` and `18`.
|
|
12
|
+
* @returns Generated identifier string.
|
|
13
|
+
* @throws {Error} When `length` is outside the supported `8` to `18` range.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const id = generateId('prefix-')
|
|
18
|
+
*
|
|
19
|
+
* id.startsWith('prefix-') // true
|
|
20
|
+
* ```
|
|
11
21
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
declare function generateId(prefix?: string, length?: number): string;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/browser.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* Template literal type for URL strings that must end with a forward slash.
|
|
27
|
+
*
|
|
28
|
+
* Ensures that base URLs used in FaasJS requests always have a trailing '/' character,
|
|
29
|
+
* which is required for proper URL construction when appending action paths.
|
|
30
|
+
*
|
|
31
|
+
* Notes:
|
|
32
|
+
* - Type only accepts strings ending with '/' (e.g., 'https://api.example.com/', '/')
|
|
33
|
+
* - Strings without trailing '/' will fail TypeScript type checking
|
|
34
|
+
* - Used by FaasBrowserClient constructor and Options type
|
|
35
|
+
* - Ensures consistent URL formatting across the codebase
|
|
36
|
+
* - Throws Error at runtime if baseUrl doesn't end with '/'
|
|
37
|
+
*
|
|
38
|
+
* @see FaasBrowserClient for usage in client creation
|
|
39
|
+
* @see Options for usage in request options
|
|
40
|
+
*/
|
|
41
|
+
type BaseUrl = `${string}/`;
|
|
42
|
+
/**
|
|
43
|
+
* Configuration options for FaasJS requests.
|
|
44
|
+
*
|
|
45
|
+
* Extends the standard RequestInit interface with FaasJS-specific options for
|
|
46
|
+
* customizing request behavior, adding request hooks, and overriding defaults.
|
|
47
|
+
*
|
|
48
|
+
* Notes:
|
|
49
|
+
* - Options can be provided at client creation (defaultOptions) or per-request
|
|
50
|
+
* - Per-request options override client default options
|
|
51
|
+
* - headers are merged: per-request headers override default headers
|
|
52
|
+
* - beforeRequest hook is called before the request is sent, allowing modification
|
|
53
|
+
* - Custom request function completely replaces the default fetch implementation
|
|
54
|
+
* - baseUrl in options overrides the client's baseUrl for this specific request
|
|
55
|
+
* - When stream is true, returns the native fetch Response instead of wrapped Response
|
|
56
|
+
*
|
|
57
|
+
* @property {Record<string, string>} [headers] - Default headers to include in all requests.
|
|
58
|
+
* Merged with client default headers, with per-request headers taking precedence.
|
|
59
|
+
* Common headers include Content-Type, Authorization, and custom application headers.
|
|
60
|
+
*
|
|
61
|
+
* @property {Function} [beforeRequest] - Async hook called before sending each request.
|
|
62
|
+
* Receives action, params, options, and headers, allowing modification before the request is sent.
|
|
63
|
+
* Useful for logging, authentication, adding timestamps, or modifying headers dynamically.
|
|
64
|
+
* Any changes to the headers object will affect the actual request.
|
|
65
|
+
*
|
|
66
|
+
* @property {Function} [request] - Custom request function to replace the default fetch.
|
|
67
|
+
* Allows using alternative HTTP clients like axios, XMLHttpRequest, or custom implementations.
|
|
68
|
+
* Receives the URL and parsed options, must return a Promise resolving to a Response object.
|
|
69
|
+
* When provided, this function is used instead of the native fetch API.
|
|
70
|
+
*
|
|
71
|
+
* @property {BaseUrl} [baseUrl] - Optional override for the base URL for this specific request.
|
|
72
|
+
* If provided, overrides the client's baseUrl. Must end with '/'.
|
|
73
|
+
* Useful for making requests to different endpoints or environments from the same client instance.
|
|
74
|
+
*
|
|
75
|
+
* @property {boolean} [stream] - Enable streaming mode for large responses.
|
|
76
|
+
* When true, returns the raw fetch Response object instead of a wrapped Response.
|
|
77
|
+
* Useful for processing large data incrementally or working with binary data streams.
|
|
78
|
+
* When false or undefined, returns a wrapped Response with automatic JSON parsing.
|
|
79
|
+
*
|
|
80
|
+
* @augments RequestInit
|
|
81
|
+
* @see FaasBrowserClient for client creation
|
|
82
|
+
* @see Response for response object structure
|
|
83
|
+
*/
|
|
84
|
+
type Options = RequestInit & {
|
|
85
|
+
headers?: Record<string, string>; /** Async hook called after request options are merged but before the request is sent. */
|
|
86
|
+
beforeRequest?: ({
|
|
87
|
+
action,
|
|
88
|
+
params,
|
|
89
|
+
options,
|
|
90
|
+
headers
|
|
91
|
+
}: {
|
|
92
|
+
action: string;
|
|
93
|
+
params?: Record<string, any> | undefined;
|
|
94
|
+
options: Options;
|
|
95
|
+
headers: Record<string, string>;
|
|
96
|
+
}) => Promise<void>; /** Custom request implementation used instead of the native `fetch`. */
|
|
97
|
+
request?: <PathOrData extends FaasActionUnionType$1>(url: string, options: Options) => Promise<Response<FaasData$1<PathOrData>>>; /** Base URL override for the current request. */
|
|
98
|
+
baseUrl?: BaseUrl; /** When `true`, return the native fetch response so callers can consume the stream manually. */
|
|
99
|
+
stream?: boolean;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Simple key-value object for HTTP response headers.
|
|
103
|
+
*
|
|
104
|
+
* Represents headers as a plain object with string keys and string values.
|
|
105
|
+
* Used by Response, ResponseError, and Options types.
|
|
106
|
+
*
|
|
107
|
+
* @property {string} [key] - Dynamic string keys for header names (e.g., 'Content-Type', 'Authorization').
|
|
108
|
+
* Values must be strings. Multiple values for the same key are not supported.
|
|
109
|
+
*
|
|
110
|
+
* Notes:
|
|
111
|
+
* - Headers are case-insensitive in HTTP but stored with exact casing in this object
|
|
112
|
+
* - Common headers include: Content-Type, Authorization, X-Request-Id, X-Custom-Header
|
|
113
|
+
* - No support for multi-value headers (use comma-separated values instead)
|
|
114
|
+
* - Used in Response, ResponseError, and Options types
|
|
115
|
+
* - Simplified model compared to browser's Headers interface (no .get(), .set() methods)
|
|
116
|
+
*
|
|
117
|
+
* @see Response for usage in response objects
|
|
118
|
+
* @see ResponseError for usage in error objects
|
|
119
|
+
* @see Options for usage in request options
|
|
120
|
+
*/
|
|
121
|
+
type ResponseHeaders = {
|
|
122
|
+
[key: string]: string;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Type definition for the FaasBrowserClient.action method.
|
|
126
|
+
*
|
|
127
|
+
* Defines the signature of the method used to make requests to FaasJS functions.
|
|
128
|
+
* Provides type-safe parameter and return value handling.
|
|
129
|
+
*
|
|
130
|
+
* @template PathOrData - The function path or data type for type safety
|
|
131
|
+
*
|
|
132
|
+
* @param action - The function path to call.
|
|
133
|
+
* @param params - Optional parameters for the function.
|
|
134
|
+
* @param options - Optional request overrides.
|
|
135
|
+
* See {@link Options} for supported request fields such as `headers`, `beforeRequest`,
|
|
136
|
+
* `request`, `baseUrl`, and `stream`.
|
|
137
|
+
* @returns Promise resolving to the request response. In streaming mode the runtime returns the native fetch response.
|
|
138
|
+
*
|
|
139
|
+
* Notes:
|
|
140
|
+
* - Used internally by FaasBrowserClient.action method
|
|
141
|
+
* - Provides type-safe action method signature
|
|
142
|
+
* - Return type includes both typed and untyped Response variants
|
|
143
|
+
* - Params are optional and can be undefined
|
|
144
|
+
* - Options override client defaults when provided
|
|
145
|
+
*
|
|
146
|
+
* @see FaasBrowserClient for the class that uses this type
|
|
147
|
+
* @see Response for the return type
|
|
148
|
+
* @see Options for the options parameter type
|
|
149
|
+
*/
|
|
150
|
+
type FaasBrowserClientAction = <PathOrData extends FaasActionUnionType$1>(action: FaasAction$1<PathOrData>, params?: FaasParams$1<PathOrData>, options?: Options) => Promise<Response<FaasData$1<PathOrData>> | Response>;
|
|
151
|
+
/**
|
|
152
|
+
* Properties for creating a Response object.
|
|
153
|
+
*
|
|
154
|
+
* Defines the structure of response data that can be passed to the Response constructor
|
|
155
|
+
* or returned from mock handlers.
|
|
156
|
+
*
|
|
157
|
+
* @template T - The type of the data property for type-safe response creation
|
|
158
|
+
*
|
|
159
|
+
* @property {number} [status] - The HTTP status code for the response.
|
|
160
|
+
* Optional: defaults to 200 if data or body is provided, 204 otherwise.
|
|
161
|
+
*
|
|
162
|
+
* @property {ResponseHeaders} [headers] - The response headers as a key-value object.
|
|
163
|
+
* Optional: defaults to an empty object if not provided.
|
|
164
|
+
*
|
|
165
|
+
* @property {any} [body] - The raw response body as a string or object.
|
|
166
|
+
* Optional: if not provided, body is automatically populated from data using JSON.stringify.
|
|
167
|
+
*
|
|
168
|
+
* @property {T} [data] - The parsed JSON data to include in the response.
|
|
169
|
+
* Optional: contains the response payload when JSON data is provided.
|
|
170
|
+
*
|
|
171
|
+
* Notes:
|
|
172
|
+
* - All properties are optional
|
|
173
|
+
* - At least one of data or body should be provided for meaningful responses
|
|
174
|
+
* - The Response class automatically defaults status to 200 or 204 based on content
|
|
175
|
+
* - If data is provided without body, body is automatically JSON.stringify(data)
|
|
176
|
+
* - Used by Response constructor and mock handlers
|
|
177
|
+
*
|
|
178
|
+
* @see Response for the class that uses these properties
|
|
179
|
+
* @see ResponseErrorProps for error response properties
|
|
180
|
+
*/
|
|
181
|
+
type ResponseProps<T = any> = {
|
|
182
|
+
status?: number;
|
|
183
|
+
headers?: ResponseHeaders;
|
|
184
|
+
body?: any;
|
|
185
|
+
data?: T;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Wrapper class for HTTP responses from FaasJS functions.
|
|
189
|
+
*
|
|
190
|
+
* Provides a consistent interface for handling server responses with status code, headers,
|
|
191
|
+
* body, and parsed data. Automatically handles JSON serialization and status code defaults.
|
|
192
|
+
*
|
|
193
|
+
* @template T - The type of the data property for type-safe response handling
|
|
194
|
+
*
|
|
195
|
+
* @property {number} status - The HTTP status code of the response.
|
|
196
|
+
* Defaults to 200 if data or body is provided, 204 if neither is present.
|
|
197
|
+
* @property {ResponseHeaders} headers - The response headers as a key-value object.
|
|
198
|
+
* Empty object if no headers were provided.
|
|
199
|
+
* @property {any} body - The raw response body as a string or object.
|
|
200
|
+
* If data is provided without body, body is automatically set to JSON.stringify(data).
|
|
201
|
+
* @property {T} [data] - The parsed JSON data from the response.
|
|
202
|
+
* Optional property that contains the response payload when JSON is provided.
|
|
203
|
+
*
|
|
204
|
+
* Notes:
|
|
205
|
+
* - status defaults to 200 if data or body is present, 204 otherwise
|
|
206
|
+
* - body is automatically populated from data if not explicitly provided
|
|
207
|
+
* - headers defaults to an empty object if not provided
|
|
208
|
+
* - Use generic type parameter T for type-safe data access
|
|
209
|
+
* - Commonly used as the return type from client.action() method
|
|
210
|
+
* - Can be used in mock handlers to return structured responses
|
|
211
|
+
* - The data property is optional and may be undefined for responses without data
|
|
212
|
+
*
|
|
213
|
+
* @example Create successful response with data
|
|
214
|
+
* ```ts
|
|
215
|
+
* const response = new Response({
|
|
216
|
+
* status: 200,
|
|
217
|
+
* data: {
|
|
218
|
+
* id: 123,
|
|
219
|
+
* name: 'John Doe'
|
|
220
|
+
* }
|
|
221
|
+
* })
|
|
222
|
+
* console.log(response.status) // 200
|
|
223
|
+
* console.log(response.data.name) // 'John Doe'
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @example Create response with type safety
|
|
227
|
+
* ```ts
|
|
228
|
+
* interface User {
|
|
229
|
+
* id: number
|
|
230
|
+
* name: string
|
|
231
|
+
* email: string
|
|
232
|
+
* }
|
|
233
|
+
*
|
|
234
|
+
* const response = new Response<User>({
|
|
235
|
+
* data: {
|
|
236
|
+
* id: 123,
|
|
237
|
+
* name: 'John',
|
|
238
|
+
* email: 'john@example.com'
|
|
239
|
+
* }
|
|
240
|
+
* })
|
|
241
|
+
* // TypeScript knows response.data.name is a string
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @example Create response with headers
|
|
245
|
+
* ```ts
|
|
246
|
+
* const response = new Response({
|
|
247
|
+
* status: 201,
|
|
248
|
+
* data: { created: true },
|
|
249
|
+
* headers: {
|
|
250
|
+
* 'Content-Type': 'application/json',
|
|
251
|
+
* 'X-Request-Id': 'req-123',
|
|
252
|
+
* 'X-Cache-Key': 'user-123'
|
|
253
|
+
* }
|
|
254
|
+
* })
|
|
255
|
+
* ```
|
|
256
|
+
*
|
|
257
|
+
* @example Create response with custom body
|
|
258
|
+
* ```ts
|
|
259
|
+
* const response = new Response({
|
|
260
|
+
* status: 200,
|
|
261
|
+
* body: JSON.stringify({ custom: 'format' }),
|
|
262
|
+
* headers: { 'Content-Type': 'application/json' }
|
|
263
|
+
* })
|
|
264
|
+
* ```
|
|
265
|
+
*
|
|
266
|
+
* @example Create empty response (204 No Content)
|
|
267
|
+
* ```ts
|
|
268
|
+
* const response = new Response()
|
|
269
|
+
* // status: 204, headers: {}, body: undefined, data: undefined
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* @example Create error response
|
|
273
|
+
* ```ts
|
|
274
|
+
* const response = new Response({
|
|
275
|
+
* status: 404,
|
|
276
|
+
* data: {
|
|
277
|
+
* error: {
|
|
278
|
+
* message: 'User not found',
|
|
279
|
+
* code: 'USER_NOT_FOUND'
|
|
280
|
+
* }
|
|
281
|
+
* }
|
|
282
|
+
* })
|
|
283
|
+
* ```
|
|
284
|
+
*
|
|
285
|
+
* @example Use in mock handler
|
|
286
|
+
* ```ts
|
|
287
|
+
* setMock(async (action, params) => {
|
|
288
|
+
* if (action === 'user') {
|
|
289
|
+
* return new Response({
|
|
290
|
+
* status: 200,
|
|
291
|
+
* data: { id: params.id, name: 'Mock User' }
|
|
292
|
+
* })
|
|
293
|
+
* }
|
|
294
|
+
* return new Response({ status: 404, data: { error: 'Not found' } })
|
|
295
|
+
* })
|
|
296
|
+
* ```
|
|
297
|
+
*
|
|
298
|
+
* @see ResponseProps for response property type
|
|
299
|
+
* @see ResponseError for error response handling
|
|
300
|
+
* @see FaasBrowserClient.action for method returning Response
|
|
301
|
+
*/
|
|
302
|
+
declare class Response<T = any> {
|
|
303
|
+
/**
|
|
304
|
+
* HTTP status code exposed to callers.
|
|
305
|
+
*/
|
|
306
|
+
readonly status: number;
|
|
307
|
+
/**
|
|
308
|
+
* Response headers keyed by header name.
|
|
309
|
+
*/
|
|
310
|
+
readonly headers: ResponseHeaders;
|
|
311
|
+
/**
|
|
312
|
+
* Raw response body.
|
|
313
|
+
*/
|
|
314
|
+
readonly body: any;
|
|
315
|
+
/**
|
|
316
|
+
* Parsed response payload when JSON data is available.
|
|
317
|
+
*/
|
|
318
|
+
readonly data?: T;
|
|
319
|
+
/**
|
|
320
|
+
* Create a wrapped response object.
|
|
321
|
+
*
|
|
322
|
+
* @param props - Response properties including status, headers, body, and data.
|
|
323
|
+
* @param props.status - HTTP status code. Defaults to `200` when `data` or `body` exists, otherwise `204`.
|
|
324
|
+
* @param props.headers - Response headers keyed by header name.
|
|
325
|
+
* @param props.body - Raw response body to expose without additional parsing.
|
|
326
|
+
* @param props.data - Parsed response payload to expose on `response.data`.
|
|
327
|
+
* @returns Wrapped response instance.
|
|
328
|
+
*/
|
|
329
|
+
constructor(props?: ResponseProps<T>);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Input accepted by the {@link ResponseError} constructor.
|
|
333
|
+
*/
|
|
334
|
+
type ResponseErrorProps = {
|
|
335
|
+
/** User-facing error message. */message: string; /** HTTP status code reported for the error. @default 500 */
|
|
336
|
+
status?: number; /** Response headers returned with the error. @default {} */
|
|
337
|
+
headers?: ResponseHeaders; /** Raw error body or structured error payload. @default { error: { message } } */
|
|
338
|
+
body?: any; /** Original error preserved when this instance wraps another exception. */
|
|
339
|
+
originalError?: Error;
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Custom error class for handling HTTP response errors from FaasJS requests.
|
|
343
|
+
*
|
|
344
|
+
* Extends the built-in Error class to provide additional information about failed requests,
|
|
345
|
+
* including HTTP status code, response headers, response body, and the original error.
|
|
346
|
+
*
|
|
347
|
+
* @augments Error
|
|
348
|
+
*
|
|
349
|
+
* @property {number} status - The HTTP status code of the failed response. Defaults to 500 if not provided.
|
|
350
|
+
* @property {ResponseHeaders} headers - The response headers from the failed request.
|
|
351
|
+
* @property {any} body - The response body containing error details or the original error if available.
|
|
352
|
+
* @property {Error} [originalError] - The original Error object if this ResponseError was created from another Error.
|
|
353
|
+
*
|
|
354
|
+
* @example Basic error with message
|
|
355
|
+
* ```ts
|
|
356
|
+
* throw new ResponseError('User not found')
|
|
357
|
+
* // or inside action method:
|
|
358
|
+
* catch (error) {
|
|
359
|
+
* throw new ResponseError(error.message)
|
|
360
|
+
* }
|
|
361
|
+
* ```
|
|
362
|
+
*
|
|
363
|
+
* @example Error from existing Error
|
|
364
|
+
* ```ts
|
|
365
|
+
* try {
|
|
366
|
+
* await someOperation()
|
|
367
|
+
* } catch (error) {
|
|
368
|
+
* throw new ResponseError(error, {
|
|
369
|
+
* status: 500,
|
|
370
|
+
* headers: { 'X-Error-Type': 'internal' }
|
|
371
|
+
* })
|
|
372
|
+
* }
|
|
373
|
+
* ```
|
|
374
|
+
*
|
|
375
|
+
* @example Error with complete response details
|
|
376
|
+
* ```ts
|
|
377
|
+
* throw new ResponseError({
|
|
378
|
+
* message: 'Validation failed',
|
|
379
|
+
* status: 400,
|
|
380
|
+
* headers: { 'X-Error-Code': 'VALIDATION_ERROR' },
|
|
381
|
+
* body: {
|
|
382
|
+
* error: {
|
|
383
|
+
* message: 'Validation failed',
|
|
384
|
+
* fields: ['email', 'password']
|
|
385
|
+
* }
|
|
386
|
+
* }
|
|
387
|
+
* })
|
|
388
|
+
* ```
|
|
389
|
+
*
|
|
390
|
+
* @example Handling ResponseError in client
|
|
391
|
+
* ```ts
|
|
392
|
+
* try {
|
|
393
|
+
* const response = await client.action('user', { id: 123 })
|
|
394
|
+
* console.log(response.data)
|
|
395
|
+
* } catch (error) {
|
|
396
|
+
* if (error instanceof ResponseError) {
|
|
397
|
+
* console.error(`Request failed: ${error.message}`)
|
|
398
|
+
* console.error(`Status: ${error.status}`)
|
|
399
|
+
* if (error.body) {
|
|
400
|
+
* console.error('Error details:', error.body)
|
|
401
|
+
* }
|
|
402
|
+
* if (error.headers['X-Request-Id']) {
|
|
403
|
+
* console.error('Request ID:', error.headers['X-Request-Id'])
|
|
404
|
+
* }
|
|
405
|
+
* }
|
|
406
|
+
* }
|
|
407
|
+
* ```
|
|
408
|
+
*
|
|
409
|
+
* @example Throwing ResponseError from mock
|
|
410
|
+
* ```ts
|
|
411
|
+
* setMock(async (action, params) => {
|
|
412
|
+
* if (action === 'login') {
|
|
413
|
+
* if (!params.email || !params.password) {
|
|
414
|
+
* throw new ResponseError({
|
|
415
|
+
* message: 'Email and password are required',
|
|
416
|
+
* status: 400,
|
|
417
|
+
* body: { error: 'missing_fields' }
|
|
418
|
+
* })
|
|
419
|
+
* }
|
|
420
|
+
* return { data: { token: 'abc123' } }
|
|
421
|
+
* }
|
|
422
|
+
* })
|
|
423
|
+
* ```
|
|
424
|
+
*
|
|
425
|
+
* Notes:
|
|
426
|
+
* - ResponseError is automatically thrown by the action method when the server returns an error (status >= 400)
|
|
427
|
+
* - The error message from server responses is extracted from body.error.message if available
|
|
428
|
+
* - When created from an Error object, the original error is preserved in the originalError property
|
|
429
|
+
* - The status property defaults to 500 if not explicitly provided
|
|
430
|
+
* - Use instanceof ResponseError to distinguish FaasJS errors from other JavaScript errors
|
|
431
|
+
* - The body property can contain structured error information from the server response
|
|
432
|
+
*
|
|
433
|
+
* @see FaasBrowserClient.action for how ResponseError is thrown in requests
|
|
434
|
+
* @see ResponseProps for the structure of response data
|
|
435
|
+
* @see setMock for mocking errors in tests
|
|
436
|
+
*/
|
|
437
|
+
declare class ResponseError extends Error {
|
|
438
|
+
/**
|
|
439
|
+
* HTTP status code reported for the failed request.
|
|
440
|
+
*/
|
|
441
|
+
readonly status: number;
|
|
442
|
+
/**
|
|
443
|
+
* Response headers returned with the error.
|
|
444
|
+
*/
|
|
445
|
+
readonly headers: ResponseHeaders;
|
|
446
|
+
/**
|
|
447
|
+
* Raw error body or fallback error payload.
|
|
448
|
+
*/
|
|
449
|
+
readonly body: any;
|
|
450
|
+
/**
|
|
451
|
+
* Original error used to construct this instance, when available.
|
|
452
|
+
*/
|
|
453
|
+
readonly originalError?: Error;
|
|
454
|
+
/**
|
|
455
|
+
* Create a ResponseError from a message, Error, or structured response error payload.
|
|
456
|
+
*
|
|
457
|
+
* @param data - Error message, Error object, or structured response error props.
|
|
458
|
+
* @param data.message - User-facing error message when `data` is a structured object.
|
|
459
|
+
* @param data.status - HTTP status code when `data` is a structured object.
|
|
460
|
+
* @param data.headers - Response headers returned with the error when `data` is a structured object.
|
|
461
|
+
* @param data.body - Raw error body or structured error payload when `data` is a structured object.
|
|
462
|
+
* @param data.originalError - Original error preserved on the instance when `data` is a structured object.
|
|
463
|
+
* @param options - Additional options such as status, headers, and body.
|
|
464
|
+
* @param options.status - HTTP status override used when `data` is a string or `Error`.
|
|
465
|
+
* @param options.headers - Response headers override used when `data` is a string or `Error`.
|
|
466
|
+
* @param options.body - Raw error body override used when `data` is a string or `Error`.
|
|
467
|
+
* @returns ResponseError instance.
|
|
468
|
+
*/
|
|
469
|
+
constructor(data: string | Error, options?: Omit<ResponseErrorProps, 'message' | 'originalError'>);
|
|
470
|
+
constructor(data: ResponseErrorProps);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Mock handler function type for testing FaasJS requests.
|
|
474
|
+
*
|
|
475
|
+
* Defines the signature for functions that can mock API requests during testing.
|
|
476
|
+
* Mock handlers receive request parameters and return simulated responses or errors.
|
|
477
|
+
*
|
|
478
|
+
* @param action - The function path/action being requested (for example, `user` or `data/list`).
|
|
479
|
+
* Converted to lowercase by the client before being passed to the handler.
|
|
480
|
+
*
|
|
481
|
+
* @param params - The parameters passed to the action.
|
|
482
|
+
* May be undefined if the action was called without parameters.
|
|
483
|
+
* Parameters are passed as a plain object (already JSON-serialized if needed).
|
|
484
|
+
*
|
|
485
|
+
* @param options - The full request options including headers, beforeRequest hook, and other config.
|
|
486
|
+
* Includes X-FaasJS-Request-Id header in the headers object.
|
|
487
|
+
* Contains merged client defaults and per-request options.
|
|
488
|
+
* See {@link Options} for supported request fields such as `headers`, `beforeRequest`,
|
|
489
|
+
* `request`, `baseUrl`, and `stream`.
|
|
490
|
+
*
|
|
491
|
+
* @returns A promise resolving to:
|
|
492
|
+
* - ResponseProps: Mock response data (status, headers, body, data)
|
|
493
|
+
* - void: Returns an empty response (204 No Content)
|
|
494
|
+
* - Error: Throws ResponseError when returning an Error object
|
|
495
|
+
*
|
|
496
|
+
* Notes:
|
|
497
|
+
* - Used by setMock() function to mock API calls during tests
|
|
498
|
+
* - Affects all FaasBrowserClient instances when set globally
|
|
499
|
+
* - Can return different responses based on action or params
|
|
500
|
+
* - Returning an Error object causes the action() method to reject with ResponseError
|
|
501
|
+
* - Async function - must return a Promise
|
|
502
|
+
* - Receives the fully merged options including default headers
|
|
503
|
+
*
|
|
504
|
+
* @example Basic mock returning data
|
|
505
|
+
* ```ts
|
|
506
|
+
* setMock(async (action, params, options) => {
|
|
507
|
+
* if (action === 'user') {
|
|
508
|
+
* return {
|
|
509
|
+
* status: 200,
|
|
510
|
+
* data: { id: params.id, name: 'Mock User' }
|
|
511
|
+
* }
|
|
512
|
+
* }
|
|
513
|
+
* return { status: 404, data: { error: 'Not found' } }
|
|
514
|
+
* })
|
|
515
|
+
* ```
|
|
516
|
+
*
|
|
517
|
+
* @example Conditional mock based on parameters
|
|
518
|
+
* ```ts
|
|
519
|
+
* setMock(async (action, params) => {
|
|
520
|
+
* if (action === 'login') {
|
|
521
|
+
* if (params.email === 'admin@example.com' && params.password === 'admin') {
|
|
522
|
+
* return { data: { token: 'admin-token', role: 'admin' } }
|
|
523
|
+
* }
|
|
524
|
+
* return { status: 401, data: { error: 'Invalid credentials' } }
|
|
525
|
+
* }
|
|
526
|
+
* })
|
|
527
|
+
* ```
|
|
528
|
+
*
|
|
529
|
+
* @example Throwing error from mock
|
|
530
|
+
* ```ts
|
|
531
|
+
* setMock(async (action) => {
|
|
532
|
+
* if (action === 'protected') {
|
|
533
|
+
* return new Error('Unauthorized access')
|
|
534
|
+
* // This will be wrapped in ResponseError and thrown
|
|
535
|
+
* }
|
|
536
|
+
* })
|
|
537
|
+
* ```
|
|
538
|
+
*
|
|
539
|
+
* @example Returning void for empty response
|
|
540
|
+
* ```ts
|
|
541
|
+
* setMock(async (action) => {
|
|
542
|
+
* if (action === 'delete') {
|
|
543
|
+
* // Return void for 204 No Content
|
|
544
|
+
* return
|
|
545
|
+
* }
|
|
546
|
+
* return { data: { success: true } }
|
|
547
|
+
* })
|
|
548
|
+
* ```
|
|
549
|
+
*
|
|
550
|
+
* @see setMock for setting up mock handlers
|
|
551
|
+
* @see ResponseProps for response structure
|
|
552
|
+
* @see ResponseError for error handling
|
|
553
|
+
*/
|
|
554
|
+
type MockHandler = (action: string, params: Record<string, any> | undefined, options: Options) => Promise<ResponseProps> | Promise<void> | Promise<Error>;
|
|
555
|
+
/**
|
|
556
|
+
* Set the global mock handler used by all {@link FaasBrowserClient} instances.
|
|
557
|
+
*
|
|
558
|
+
* @param handler - Mock handler, can be:
|
|
559
|
+
* - MockHandler function: receives (action, params, options) and returns response data
|
|
560
|
+
* - ResponseProps object: static response data
|
|
561
|
+
* - Response instance: pre-configured Response object
|
|
562
|
+
* - null or undefined: clear mock
|
|
563
|
+
*
|
|
564
|
+
* @example Reset in Vitest shared setup
|
|
565
|
+
* ```ts
|
|
566
|
+
* import { afterEach } from 'vitest'
|
|
567
|
+
*
|
|
568
|
+
* afterEach(() => {
|
|
569
|
+
* setMock(null)
|
|
570
|
+
* })
|
|
571
|
+
* ```
|
|
572
|
+
*
|
|
573
|
+
* @example Use ResponseProps object
|
|
574
|
+
* ```ts
|
|
575
|
+
* setMock({
|
|
576
|
+
* data: { name: 'FaasJS' },
|
|
577
|
+
* })
|
|
578
|
+
*
|
|
579
|
+
* setMock({
|
|
580
|
+
* status: 500,
|
|
581
|
+
* data: { message: 'Internal Server Error' },
|
|
582
|
+
* })
|
|
583
|
+
* ```
|
|
584
|
+
*
|
|
585
|
+
* @example Use MockHandler function
|
|
586
|
+
* ```ts
|
|
587
|
+
* setMock(async (action) => {
|
|
588
|
+
* if (action === '/pages/users/get') {
|
|
589
|
+
* return { data: { id: 1, name: 'FaasJS' } }
|
|
590
|
+
* }
|
|
591
|
+
*
|
|
592
|
+
* return { status: 404, data: { message: 'Not Found' } }
|
|
593
|
+
* })
|
|
594
|
+
*
|
|
595
|
+
* const response = await client.action('/pages/users/get')
|
|
596
|
+
* ```
|
|
597
|
+
*
|
|
598
|
+
* @example Branch by action and params
|
|
599
|
+
* ```ts
|
|
600
|
+
* setMock(async (action, params) => {
|
|
601
|
+
* if (action === '/pages/users/get' && params?.id === 1) {
|
|
602
|
+
* return { data: { id: 1, name: 'Admin' } }
|
|
603
|
+
* }
|
|
604
|
+
*
|
|
605
|
+
* if (action === '/pages/users/get' && params?.id === 2) {
|
|
606
|
+
* return { data: { id: 2, name: 'Editor' } }
|
|
607
|
+
* }
|
|
608
|
+
*
|
|
609
|
+
* return { status: 404, data: { message: 'User not found' } }
|
|
610
|
+
* })
|
|
611
|
+
* ```
|
|
612
|
+
*
|
|
613
|
+
* @example Use Response instance
|
|
614
|
+
* ```ts
|
|
615
|
+
* setMock(new Response({
|
|
616
|
+
* status: 200,
|
|
617
|
+
* data: { result: 'success' }
|
|
618
|
+
* }))
|
|
619
|
+
* ```
|
|
620
|
+
*
|
|
621
|
+
* @example Streaming response
|
|
622
|
+
* ```ts
|
|
623
|
+
* setMock({
|
|
624
|
+
* body: new ReadableStream({
|
|
625
|
+
* start(controller) {
|
|
626
|
+
* controller.enqueue(new TextEncoder().encode('hello'))
|
|
627
|
+
* controller.enqueue(new TextEncoder().encode(' world'))
|
|
628
|
+
* controller.close()
|
|
629
|
+
* },
|
|
630
|
+
* }),
|
|
631
|
+
* })
|
|
632
|
+
* ```
|
|
633
|
+
*
|
|
634
|
+
* @example Clear mock
|
|
635
|
+
* ```ts
|
|
636
|
+
* setMock(null)
|
|
637
|
+
* ```
|
|
638
|
+
*
|
|
639
|
+
* @example Handle errors
|
|
640
|
+
* ```ts
|
|
641
|
+
* setMock(async () => {
|
|
642
|
+
* throw new Error('Internal error')
|
|
643
|
+
* })
|
|
644
|
+
* // This will reject with ResponseError
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
declare function setMock(handler: MockHandler | ResponseProps | Response | null | undefined): void;
|
|
648
|
+
/**
|
|
649
|
+
* Browser client for FaasJS - provides HTTP client functionality for making API requests from web applications.
|
|
650
|
+
*
|
|
651
|
+
* @template PathOrData - Type parameter extending FaasActionUnionType for type-safe requests
|
|
652
|
+
*
|
|
653
|
+
* Features:
|
|
654
|
+
* - Type-safe API requests with TypeScript support
|
|
655
|
+
* - Built-in mock support for testing
|
|
656
|
+
* - Custom request function support
|
|
657
|
+
* - Request/response hooks (beforeRequest)
|
|
658
|
+
* - Automatic error handling with ResponseError
|
|
659
|
+
* - Streaming support for large responses
|
|
660
|
+
* - Multiple instance support with unique IDs
|
|
661
|
+
*
|
|
662
|
+
* Notes:
|
|
663
|
+
* - All requests are POST requests by default
|
|
664
|
+
* - Automatically adds X-FaasJS-Request-Id header for request tracking
|
|
665
|
+
* - baseUrl must end with '/' (will throw Error if not)
|
|
666
|
+
* - Supports global mock via setMock() for testing all instances
|
|
667
|
+
*
|
|
668
|
+
* @example Basic usage
|
|
669
|
+
* ```ts
|
|
670
|
+
* import { FaasBrowserClient } from '@faasjs/react'
|
|
671
|
+
*
|
|
672
|
+
* const client = new FaasBrowserClient('http://localhost:8080/')
|
|
673
|
+
* const response = await client.action('func', { key: 'value' })
|
|
674
|
+
* console.log(response.data)
|
|
675
|
+
* ```
|
|
676
|
+
*
|
|
677
|
+
* @example With custom headers and options
|
|
678
|
+
* ```ts
|
|
679
|
+
* const client = new FaasBrowserClient('https://api.example.com/', {
|
|
680
|
+
* headers: { 'X-API-Key': 'secret' },
|
|
681
|
+
* beforeRequest: async ({ action, params, headers }) => {
|
|
682
|
+
* console.log(`Calling ${action} with params:`, params)
|
|
683
|
+
* }
|
|
684
|
+
* })
|
|
685
|
+
* ```
|
|
686
|
+
*
|
|
687
|
+
* @example Multiple instances
|
|
688
|
+
* ```ts
|
|
689
|
+
* const apiClient = new FaasBrowserClient('https://api.example.com/')
|
|
690
|
+
* const localClient = new FaasBrowserClient('http://localhost:3000/')
|
|
691
|
+
*
|
|
692
|
+
* const apiData = await apiClient.action('users')
|
|
693
|
+
* const localData = await localClient.action('data')
|
|
694
|
+
* ```
|
|
695
|
+
*
|
|
696
|
+
* @example Error handling
|
|
697
|
+
* ```ts
|
|
698
|
+
* const client = new FaasBrowserClient('https://api.example.com/')
|
|
699
|
+
*
|
|
700
|
+
* try {
|
|
701
|
+
* const response = await client.action('user', { id: 123 })
|
|
702
|
+
* console.log(response.data)
|
|
703
|
+
* } catch (error) {
|
|
704
|
+
* if (error instanceof ResponseError) {
|
|
705
|
+
* console.error(`Request failed: ${error.message}`, error.status)
|
|
706
|
+
* } else {
|
|
707
|
+
* console.error('Unexpected error:', error)
|
|
708
|
+
* }
|
|
709
|
+
* }
|
|
710
|
+
* ```
|
|
711
|
+
*
|
|
712
|
+
* @throws {Error} When baseUrl does not end with '/'
|
|
713
|
+
*
|
|
714
|
+
* @see setMock for testing support
|
|
715
|
+
* @see ResponseError for error handling
|
|
716
|
+
*/
|
|
717
|
+
declare class FaasBrowserClient {
|
|
718
|
+
/**
|
|
719
|
+
* Unique identifier for this client instance.
|
|
720
|
+
*/
|
|
721
|
+
readonly id: string;
|
|
722
|
+
/**
|
|
723
|
+
* Base URL used to build action request URLs.
|
|
724
|
+
*/
|
|
725
|
+
baseUrl: BaseUrl;
|
|
726
|
+
/**
|
|
727
|
+
* Default request options merged into every request.
|
|
728
|
+
*/
|
|
729
|
+
defaultOptions: Options;
|
|
730
|
+
/**
|
|
731
|
+
* Creates a new FaasBrowserClient instance.
|
|
732
|
+
*
|
|
733
|
+
* @param baseUrl - Base URL for all API requests. Must end with `/`. Defaults to `/` for relative requests.
|
|
734
|
+
* @param options - Default request options such as headers, hooks, request override, or stream mode.
|
|
735
|
+
* See {@link Options} for supported request fields such as `headers`, `beforeRequest`,
|
|
736
|
+
* `request`, `baseUrl`, and `stream`.
|
|
737
|
+
*
|
|
738
|
+
* @example Basic initialization
|
|
739
|
+
* ```ts
|
|
740
|
+
* const client = new FaasBrowserClient('/')
|
|
741
|
+
* ```
|
|
742
|
+
*
|
|
743
|
+
* @example With API endpoint
|
|
744
|
+
* ```ts
|
|
745
|
+
* const client = new FaasBrowserClient('https://api.example.com/')
|
|
746
|
+
* ```
|
|
747
|
+
*
|
|
748
|
+
* @example With custom headers
|
|
749
|
+
* ```ts
|
|
750
|
+
* const client = new FaasBrowserClient('https://api.example.com/', {
|
|
751
|
+
* headers: {
|
|
752
|
+
* 'Authorization': 'Bearer token123',
|
|
753
|
+
* 'X-Custom-Header': 'value'
|
|
754
|
+
* }
|
|
755
|
+
* })
|
|
756
|
+
* ```
|
|
757
|
+
*
|
|
758
|
+
* @example With beforeRequest hook
|
|
759
|
+
* ```ts
|
|
760
|
+
* const client = new FaasBrowserClient('https://api.example.com/', {
|
|
761
|
+
* beforeRequest: async ({ action, params, headers }) => {
|
|
762
|
+
* console.log(`Requesting ${action}`, params)
|
|
763
|
+
* // Modify headers before request
|
|
764
|
+
* headers['X-Timestamp'] = Date.now().toString()
|
|
765
|
+
* }
|
|
766
|
+
* })
|
|
767
|
+
* ```
|
|
768
|
+
*
|
|
769
|
+
* @example With custom request function
|
|
770
|
+
* ```ts
|
|
771
|
+
* import axios from 'axios'
|
|
772
|
+
*
|
|
773
|
+
* const client = new FaasBrowserClient('/', {
|
|
774
|
+
* request: async (url, options) => {
|
|
775
|
+
* const response = await axios.post(url, options.body, {
|
|
776
|
+
* headers: options.headers
|
|
777
|
+
* })
|
|
778
|
+
* return new Response({
|
|
779
|
+
* status: response.status,
|
|
780
|
+
* headers: response.headers,
|
|
781
|
+
* data: response.data
|
|
782
|
+
* })
|
|
783
|
+
* }
|
|
784
|
+
* })
|
|
785
|
+
* ```
|
|
786
|
+
*
|
|
787
|
+
* @throws {Error} When `baseUrl` does not end with `/`
|
|
788
|
+
*/
|
|
789
|
+
constructor(baseUrl?: BaseUrl, options?: Options);
|
|
790
|
+
/**
|
|
791
|
+
* Makes a request to a FaasJS function.
|
|
792
|
+
*
|
|
793
|
+
* @template PathOrData - The function path or data type for type safety
|
|
794
|
+
* @param action - The function path to call. Converted to lowercase when constructing the URL.
|
|
795
|
+
* Must be a non-empty string.
|
|
796
|
+
* @param params - The parameters to send to the function. Will be serialized as JSON.
|
|
797
|
+
* Optional if the function accepts no parameters.
|
|
798
|
+
* @param options - Optional request options that override client defaults.
|
|
799
|
+
* Supports headers, beforeRequest hook, custom request function, baseUrl override, and streaming mode.
|
|
800
|
+
* See {@link Options} for supported request fields such as `headers`, `beforeRequest`,
|
|
801
|
+
* `request`, `baseUrl`, and `stream`.
|
|
802
|
+
*
|
|
803
|
+
* @returns A promise resolving to the wrapped FaasJS response. When `options.stream`
|
|
804
|
+
* is `true`, the runtime returns the native fetch response so callers can read the stream.
|
|
805
|
+
*
|
|
806
|
+
* @throws {Error} When action is not provided or is empty
|
|
807
|
+
* @throws {ResponseError} When the server returns an error response (status >= 400 or body.error exists)
|
|
808
|
+
* @throws {Error} When the request fails before a response is received
|
|
809
|
+
*
|
|
810
|
+
* Notes:
|
|
811
|
+
* - All requests are POST requests by default
|
|
812
|
+
* - Action path is automatically converted to lowercase
|
|
813
|
+
* - A unique request ID is generated for each request and sent in X-FaasJS-Request-Id header
|
|
814
|
+
* - Headers are merged from client defaults and request options (request options take precedence)
|
|
815
|
+
* - If a global mock is set via setMock(), it will be used instead of making real requests
|
|
816
|
+
* - If a custom request function is provided in options, it will be used instead of fetch
|
|
817
|
+
* - When stream option is true, returns the native fetch Response instead of a wrapped Response
|
|
818
|
+
* - Response body is automatically parsed as JSON when possible
|
|
819
|
+
* - Server errors (body.error) are automatically converted to ResponseError
|
|
820
|
+
*
|
|
821
|
+
* @example Basic request
|
|
822
|
+
* ```ts
|
|
823
|
+
* const response = await client.action('user', { id: 123 })
|
|
824
|
+
* console.log(response.data)
|
|
825
|
+
* ```
|
|
826
|
+
*
|
|
827
|
+
* @example With no parameters
|
|
828
|
+
* ```ts
|
|
829
|
+
* const response = await client.action('status')
|
|
830
|
+
* console.log(response.data.status)
|
|
831
|
+
* ```
|
|
832
|
+
*
|
|
833
|
+
* @example With custom options
|
|
834
|
+
* ```ts
|
|
835
|
+
* const response = await client.action('data', {
|
|
836
|
+
* limit: 10,
|
|
837
|
+
* offset: 0
|
|
838
|
+
* }, {
|
|
839
|
+
* headers: { 'X-Custom-Header': 'value' }
|
|
840
|
+
* })
|
|
841
|
+
* ```
|
|
842
|
+
*
|
|
843
|
+
* @example Streaming large response
|
|
844
|
+
* ```ts
|
|
845
|
+
* const response = await client.action('stream', {
|
|
846
|
+
* format: 'json'
|
|
847
|
+
* }, {
|
|
848
|
+
* stream: true
|
|
849
|
+
* })
|
|
850
|
+
* // response is native fetch Response with streaming support
|
|
851
|
+
* const reader = response.body.getReader()
|
|
852
|
+
* ```
|
|
853
|
+
*
|
|
854
|
+
* @example With type safety
|
|
855
|
+
* ```ts
|
|
856
|
+
* interface UserData {
|
|
857
|
+
* id: number
|
|
858
|
+
* name: string
|
|
859
|
+
* email: string
|
|
860
|
+
* }
|
|
861
|
+
*
|
|
862
|
+
* const response = await client.action<UserData>('user', { id: 123 })
|
|
863
|
+
* console.log(response.data.name) // TypeScript knows it's a string
|
|
864
|
+
* ```
|
|
865
|
+
*
|
|
866
|
+
* @example Handling errors
|
|
867
|
+
* ```ts
|
|
868
|
+
* try {
|
|
869
|
+
* const response = await client.action('user', { id: 123 })
|
|
870
|
+
* console.log(response.data)
|
|
871
|
+
* } catch (error) {
|
|
872
|
+
* if (error instanceof ResponseError) {
|
|
873
|
+
* console.error(`Server error: ${error.message}`, error.status)
|
|
874
|
+
* if (error.body) console.error('Error details:', error.body)
|
|
875
|
+
* } else {
|
|
876
|
+
* console.error('Network error:', error)
|
|
877
|
+
* }
|
|
878
|
+
* }
|
|
879
|
+
* ```
|
|
880
|
+
*
|
|
881
|
+
* @example Chaining requests
|
|
882
|
+
* ```ts
|
|
883
|
+
* const userId = await client.action('createUser', {
|
|
884
|
+
* name: 'John',
|
|
885
|
+
* email: 'john@example.com'
|
|
886
|
+
* })
|
|
887
|
+
*
|
|
888
|
+
* const profile = await client.action('getProfile', {
|
|
889
|
+
* userId: userId.data.id
|
|
890
|
+
* })
|
|
891
|
+
* ```
|
|
892
|
+
*/
|
|
893
|
+
action<PathOrData extends FaasActionUnionType$1>(action: FaasAction$1<PathOrData>, params?: FaasParams$1<PathOrData>, options?: Options): Promise<Response<FaasData$1<PathOrData>>>;
|
|
894
|
+
}
|
|
895
|
+
//#endregion
|
|
896
|
+
//#region src/faas.d.ts
|
|
897
|
+
/**
|
|
898
|
+
* Call the currently configured FaasReactClient.
|
|
899
|
+
*
|
|
900
|
+
* This helper forwards the request to `getClient`. When the registered
|
|
901
|
+
* client defines `onError`, the hook is invoked before the promise rejects.
|
|
902
|
+
*
|
|
903
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
904
|
+
*
|
|
905
|
+
* @param action - Action path to invoke.
|
|
906
|
+
* @param params - Parameters sent to the action.
|
|
907
|
+
* @param options - Optional per-request overrides such as headers or base URL.
|
|
908
|
+
* See the request `Options` type for supported fields such as `headers`, `beforeRequest`,
|
|
909
|
+
* `request`, `baseUrl`, and `stream`.
|
|
910
|
+
* @returns Response returned by the active browser client.
|
|
911
|
+
* @throws {ResponseError} When the request fails and the active client does not recover inside `onError`.
|
|
912
|
+
*
|
|
913
|
+
* @example
|
|
914
|
+
* ```ts
|
|
915
|
+
* import { faas } from '@faasjs/react'
|
|
916
|
+
*
|
|
917
|
+
* const response = await faas('posts/get', { id: 1 })
|
|
918
|
+
*
|
|
919
|
+
* console.log(response.data.title)
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
declare function faas<PathOrData extends FaasActionUnionType$1>(action: FaasAction$1<PathOrData>, params: FaasParams$1<PathOrData>, options?: Options): Promise<Response<FaasData$1<PathOrData>>>;
|
|
923
|
+
//#endregion
|
|
924
|
+
//#region src/FaasDataWrapper.d.ts
|
|
925
|
+
/**
|
|
926
|
+
* Request state injected by {@link useFaas}, {@link FaasDataWrapper}, and {@link withFaasData}.
|
|
927
|
+
*
|
|
928
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
929
|
+
*/
|
|
930
|
+
type FaasDataInjection<PathOrData extends FaasActionUnionType$1 = any> = {
|
|
931
|
+
/** Action path associated with the current request state. */action: FaasAction$1<PathOrData>; /** Params used for the most recent request attempt. */
|
|
932
|
+
params: FaasParams$1<PathOrData>; /** Whether the request is currently in flight. */
|
|
933
|
+
loading: boolean; /** Number of times `reload()` has triggered a new request. */
|
|
934
|
+
reloadTimes: number; /** Current resolved data value. */
|
|
935
|
+
data: FaasData$1<PathOrData>; /** Last request error, if one occurred. */
|
|
936
|
+
error: any; /** Promise representing the latest request. */
|
|
937
|
+
promise: Promise<Response<FaasData$1<PathOrData>>>;
|
|
938
|
+
/**
|
|
939
|
+
* Reloads data with new or existing parameters.
|
|
940
|
+
*
|
|
941
|
+
* When the source hook is currently skipped, calling `reload` clears the skip
|
|
942
|
+
* flag before starting the next request.
|
|
943
|
+
*/
|
|
944
|
+
reload(params?: Record<string, any>): Promise<FaasData$1<PathOrData>>; /** Controlled or internal setter for the resolved data value. */
|
|
945
|
+
setData: React.Dispatch<React.SetStateAction<FaasData$1<PathOrData>>>; /** Setter for the loading flag. */
|
|
946
|
+
setLoading: React.Dispatch<React.SetStateAction<boolean>>; /** Setter for the latest request promise. */
|
|
947
|
+
setPromise: React.Dispatch<React.SetStateAction<Promise<Response<FaasData$1<PathOrData>>>>>; /** Setter for the last request error. */
|
|
948
|
+
setError: React.Dispatch<React.SetStateAction<any>>;
|
|
30
949
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
950
|
+
/**
|
|
951
|
+
* Props for the {@link FaasDataWrapper} render-prop component.
|
|
952
|
+
*
|
|
953
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
954
|
+
*/
|
|
955
|
+
type FaasDataWrapperProps<PathOrData extends FaasActionUnionType$1> = {
|
|
956
|
+
/** Render prop invoked with the resolved request state after the first load completes. */render?(args: FaasDataInjection<PathOrData>): JSX.Element | JSX.Element[]; /** Child element cloned with injected request state after the first load completes. */
|
|
957
|
+
children?: React.ReactElement<Partial<FaasDataInjection<PathOrData>>>; /** Element rendered before the first successful load. */
|
|
958
|
+
fallback?: JSX.Element | false; /** Action path to request. */
|
|
959
|
+
action: FaasAction$1<PathOrData>; /** Params sent to the action. */
|
|
960
|
+
params?: FaasParams$1<PathOrData>; /** Callback invoked whenever the resolved data value changes. */
|
|
961
|
+
onDataChange?(args: FaasDataInjection<PathOrData>): void; /** Controlled data value used instead of internal state. */
|
|
962
|
+
data?: FaasData$1<PathOrData>; /** Controlled setter used instead of internal state. */
|
|
963
|
+
setData?: React.Dispatch<React.SetStateAction<FaasData$1<PathOrData>>>; /** Base URL override used for this wrapper instance. */
|
|
964
|
+
baseUrl?: BaseUrl; /** Imperative ref exposing the current injected request state. */
|
|
965
|
+
ref?: React.Ref<FaasDataWrapperRef<PathOrData>>;
|
|
44
966
|
};
|
|
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
967
|
/**
|
|
48
|
-
*
|
|
968
|
+
* Imperative ref shape exposed by {@link FaasDataWrapper}.
|
|
969
|
+
*
|
|
970
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
971
|
+
*/
|
|
972
|
+
type FaasDataWrapperRef<PathOrData extends FaasActionUnionType$1 = any> = FaasDataInjection<PathOrData>;
|
|
973
|
+
/**
|
|
974
|
+
* Fetch FaasJS data and inject the result into a render prop or child element.
|
|
975
|
+
*
|
|
976
|
+
* The wrapper defers rendering `children` or `render` until the first request
|
|
977
|
+
* completes, then keeps passing the latest request state to the rendered output.
|
|
978
|
+
*
|
|
979
|
+
* @param props - Wrapper props controlling the request and rendered fallback.
|
|
980
|
+
* @param props.render - Render prop that receives the resolved Faas request state.
|
|
981
|
+
* @param props.children - Child element cloned with injected Faas request state.
|
|
982
|
+
* @param props.fallback - Element rendered before the first successful load.
|
|
983
|
+
* @param props.action - Action path to request.
|
|
984
|
+
* @param props.params - Params sent to the action.
|
|
985
|
+
* @param props.onDataChange - Callback invoked when the resolved data value changes.
|
|
986
|
+
* @param props.data - Controlled data value used instead of internal state.
|
|
987
|
+
* @param props.setData - Controlled setter used instead of internal state.
|
|
988
|
+
* @param props.baseUrl - Base URL override used for this wrapper instance.
|
|
49
989
|
*
|
|
50
990
|
* @example
|
|
51
991
|
* ```tsx
|
|
52
|
-
*
|
|
992
|
+
* import { FaasDataWrapper } from '@faasjs/react'
|
|
993
|
+
*
|
|
994
|
+
* type User = {
|
|
995
|
+
* name: string
|
|
996
|
+
* }
|
|
997
|
+
*
|
|
998
|
+
* function UserView(props: {
|
|
999
|
+
* data?: User
|
|
1000
|
+
* error?: Error
|
|
1001
|
+
* reload?: () => void
|
|
1002
|
+
* }) {
|
|
1003
|
+
* if (props.error) {
|
|
1004
|
+
* return (
|
|
1005
|
+
* <div>
|
|
1006
|
+
* <p>Failed to load user: {props.error.message}</p>
|
|
1007
|
+
* <button type="button" onClick={() => props.reload?.()}>
|
|
1008
|
+
* Retry
|
|
1009
|
+
* </button>
|
|
1010
|
+
* </div>
|
|
1011
|
+
* )
|
|
1012
|
+
* }
|
|
1013
|
+
*
|
|
1014
|
+
* return <div>Hello, {props.data?.name}</div>
|
|
1015
|
+
* }
|
|
1016
|
+
*
|
|
1017
|
+
* // Render-prop mode
|
|
1018
|
+
* export function UserProfile(props: { id: number }) {
|
|
1019
|
+
* return (
|
|
1020
|
+
* <FaasDataWrapper<User>
|
|
1021
|
+
* action="/pages/users/get"
|
|
1022
|
+
* params={{ id: props.id }}
|
|
1023
|
+
* fallback={<div>Loading user...</div>}
|
|
1024
|
+
* render={({ data, error, reload }) => {
|
|
1025
|
+
* if (error) {
|
|
1026
|
+
* return (
|
|
1027
|
+
* <div>
|
|
1028
|
+
* <p>Failed to load user: {error.message}</p>
|
|
1029
|
+
* <button type="button" onClick={() => reload()}>
|
|
1030
|
+
* Retry
|
|
1031
|
+
* </button>
|
|
1032
|
+
* </div>
|
|
1033
|
+
* )
|
|
1034
|
+
* }
|
|
1035
|
+
*
|
|
1036
|
+
* return <div>Hello, {data.name}</div>
|
|
1037
|
+
* }}
|
|
1038
|
+
* />
|
|
1039
|
+
* )
|
|
1040
|
+
* }
|
|
1041
|
+
*
|
|
1042
|
+
* // Children injection mode
|
|
1043
|
+
* export function UserProfileWithChildren(props: { id: number }) {
|
|
1044
|
+
* return (
|
|
1045
|
+
* <FaasDataWrapper<User>
|
|
1046
|
+
* action="/pages/users/get"
|
|
1047
|
+
* params={{ id: props.id }}
|
|
1048
|
+
* fallback={<div>Loading user...</div>}
|
|
1049
|
+
* >
|
|
1050
|
+
* <UserView />
|
|
1051
|
+
* </FaasDataWrapper>
|
|
1052
|
+
* )
|
|
1053
|
+
* }
|
|
53
1054
|
* ```
|
|
1055
|
+
*
|
|
1056
|
+
* When a ref is provided, it exposes the current Faas request state imperatively.
|
|
54
1057
|
*/
|
|
55
|
-
declare
|
|
56
|
-
|
|
1058
|
+
declare const FaasDataWrapper: <PathOrData extends FaasActionUnionType$1 = any>(props: FaasDataWrapperProps<PathOrData> & _$react.RefAttributes<FaasDataWrapperRef<PathOrData>>) => React.ReactElement | null;
|
|
57
1059
|
/**
|
|
58
|
-
*
|
|
1060
|
+
* Wrap a component with {@link FaasDataWrapper} and inject Faas request state as props.
|
|
1061
|
+
*
|
|
1062
|
+
* `withFaasData` is most useful for wrapper-style exports or compatibility with
|
|
1063
|
+
* an existing component boundary. For new code, prefer `useFaas` or
|
|
1064
|
+
* `FaasDataWrapper` when they express the request ownership more directly.
|
|
59
1065
|
*
|
|
60
|
-
* @
|
|
61
|
-
* @
|
|
62
|
-
* @
|
|
1066
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
1067
|
+
* @template TComponentProps - Component props including injected Faas data fields.
|
|
1068
|
+
* @param Component - Component that consumes injected Faas data props.
|
|
1069
|
+
* @param faasProps - Request configuration forwarded to `FaasDataWrapper`.
|
|
1070
|
+
* @returns Component that accepts the original props minus the injected Faas data fields.
|
|
63
1071
|
*
|
|
64
1072
|
* @example
|
|
65
|
-
* ```
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
1073
|
+
* ```tsx
|
|
1074
|
+
* import { withFaasData } from '@faasjs/react'
|
|
1075
|
+
*
|
|
1076
|
+
* const MyComponent = withFaasData(
|
|
1077
|
+
* ({ data, error, reload }) => {
|
|
1078
|
+
* if (error) {
|
|
1079
|
+
* return (
|
|
1080
|
+
* <button type="button" onClick={() => reload()}>
|
|
1081
|
+
* Retry
|
|
1082
|
+
* </button>
|
|
1083
|
+
* )
|
|
1084
|
+
* }
|
|
1085
|
+
*
|
|
1086
|
+
* return <div>{data.name}</div>
|
|
1087
|
+
* },
|
|
1088
|
+
* { action: '/pages/users/get', params: { id: 1 } },
|
|
1089
|
+
* )
|
|
69
1090
|
* ```
|
|
70
1091
|
*/
|
|
71
|
-
declare function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
1092
|
+
declare function withFaasData<PathOrData extends FaasActionUnionType$1, 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>>;
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/useFaas.d.ts
|
|
1095
|
+
/**
|
|
1096
|
+
* Options that customize the {@link useFaas} request lifecycle.
|
|
1097
|
+
*
|
|
1098
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
1099
|
+
*/
|
|
1100
|
+
type useFaasOptions<PathOrData extends FaasActionUnionType$1> = {
|
|
1101
|
+
/** Override the current request params without changing the hook's stored params state. */params?: FaasParams$1<PathOrData>; /** Controlled data value used instead of the hook's internal state. */
|
|
1102
|
+
data?: FaasData$1<PathOrData>; /** Controlled setter that is called instead of the hook's internal `setData`. */
|
|
1103
|
+
setData?: React.Dispatch<React.SetStateAction<FaasData$1<PathOrData>>>;
|
|
1104
|
+
/**
|
|
1105
|
+
* If skip is true, the request will not be sent.
|
|
1106
|
+
*
|
|
1107
|
+
* However, you can still use reload to send the request.
|
|
1108
|
+
*/
|
|
1109
|
+
skip?: boolean | ((params: FaasParams$1<PathOrData>) => boolean); /** Delay the latest automatic request by the given number of milliseconds. */
|
|
1110
|
+
debounce?: number; /** Override the default base URL for this hook instance. */
|
|
1111
|
+
baseUrl?: BaseUrl;
|
|
86
1112
|
};
|
|
87
1113
|
/**
|
|
88
|
-
* Request
|
|
1114
|
+
* Request FaasJS data and keep request state in React state.
|
|
1115
|
+
*
|
|
1116
|
+
* `useFaas` is the default hook for standard FaasJS request-response flows in React.
|
|
1117
|
+
* It sends an initial request unless `skip` is enabled, and returns request state
|
|
1118
|
+
* plus helpers for reloading, updating data, and handling errors.
|
|
89
1119
|
*
|
|
90
|
-
* @
|
|
91
|
-
*
|
|
92
|
-
* @
|
|
1120
|
+
* @template PathOrData - Action path or response data type used for inference.
|
|
1121
|
+
*
|
|
1122
|
+
* @param action - Action path to invoke.
|
|
1123
|
+
* @param defaultParams - Params used for the initial request and future reloads.
|
|
1124
|
+
* @param options - Optional hook configuration such as controlled data, debounce, and skip logic.
|
|
1125
|
+
* @param options.params - Request params override used without mutating the hook's stored params state.
|
|
1126
|
+
* @param options.data - Controlled data value used instead of the hook's internal state.
|
|
1127
|
+
* @param options.setData - Controlled setter used instead of the hook's internal `setData`.
|
|
1128
|
+
* @param options.skip - Boolean or predicate that suppresses the automatic request until `reload()` runs.
|
|
1129
|
+
* @param options.debounce - Milliseconds to wait before sending the latest request.
|
|
1130
|
+
* @param options.baseUrl - Base URL override used for this hook instance.
|
|
1131
|
+
* @returns Request state and helper methods described by {@link FaasDataInjection}.
|
|
93
1132
|
*
|
|
94
1133
|
* @example
|
|
95
1134
|
* ```tsx
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
1135
|
+
* import { useFaas } from '@faasjs/react'
|
|
1136
|
+
*
|
|
1137
|
+
* function Profile({ id }: { id: number }) {
|
|
1138
|
+
* const { data, error, loading, reload } = useFaas('/pages/users/get', { id })
|
|
1139
|
+
*
|
|
1140
|
+
* if (loading) return <div>Loading...</div>
|
|
1141
|
+
*
|
|
1142
|
+
* if (error) {
|
|
1143
|
+
* return (
|
|
1144
|
+
* <div>
|
|
1145
|
+
* <div>Load failed: {error.message}</div>
|
|
1146
|
+
* <button type="button" onClick={() => reload()}>
|
|
1147
|
+
* Retry
|
|
1148
|
+
* </button>
|
|
1149
|
+
* </div>
|
|
1150
|
+
* )
|
|
1151
|
+
* }
|
|
1152
|
+
*
|
|
1153
|
+
* return (
|
|
1154
|
+
* <div>
|
|
1155
|
+
* <span>{data.name}</span>
|
|
1156
|
+
* <button type="button" onClick={() => reload()}>
|
|
1157
|
+
* Refresh
|
|
1158
|
+
* </button>
|
|
1159
|
+
* </div>
|
|
1160
|
+
* )
|
|
99
1161
|
* }
|
|
100
1162
|
* ```
|
|
101
1163
|
*/
|
|
102
|
-
declare function useFaas<PathOrData extends FaasActionUnionType>(action: FaasAction<PathOrData>, defaultParams: FaasParams<PathOrData>, options?: useFaasOptions<PathOrData>): FaasDataInjection<PathOrData>;
|
|
103
|
-
|
|
1164
|
+
declare function useFaas<PathOrData extends FaasActionUnionType$1>(action: FaasAction$1<PathOrData>, defaultParams: FaasParams$1<PathOrData>, options?: useFaasOptions<PathOrData>): FaasDataInjection<PathOrData>;
|
|
1165
|
+
//#endregion
|
|
1166
|
+
//#region src/client.d.ts
|
|
1167
|
+
/**
|
|
1168
|
+
* Factory for per-request error handlers used by {@link FaasReactClient}.
|
|
1169
|
+
*
|
|
1170
|
+
* @param action - Action name that failed.
|
|
1171
|
+
* @param params - Params sent with the failed request.
|
|
1172
|
+
* @returns Async callback invoked with the resulting {@link ResponseError}.
|
|
1173
|
+
*/
|
|
104
1174
|
type OnError = (action: string, params: Record<string, any>) => (res: ResponseError) => Promise<void>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Options for creating a {@link FaasReactClient} instance.
|
|
1177
|
+
*/
|
|
105
1178
|
type FaasReactClientOptions = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
1179
|
+
/** @default `/` */baseUrl?: BaseUrl; /** Default request options forwarded to the underlying browser client. */
|
|
1180
|
+
options?: Options;
|
|
1181
|
+
/**
|
|
1182
|
+
* Error hook invoked when `faas` or `useFaas` receives a failed response.
|
|
1183
|
+
*
|
|
1184
|
+
* @example
|
|
1185
|
+
* ```ts
|
|
1186
|
+
* import { ResponseError } from '@faasjs/react'
|
|
1187
|
+
*
|
|
1188
|
+
* onError: (action, params) => async (res) => {
|
|
1189
|
+
* if (res instanceof ResponseError) {
|
|
1190
|
+
* reportErrorToSentry(res, {
|
|
1191
|
+
* tags: { action },
|
|
1192
|
+
* extra: { params },
|
|
1193
|
+
* })
|
|
1194
|
+
* }
|
|
1195
|
+
* }
|
|
1196
|
+
* ```
|
|
1197
|
+
*/
|
|
1198
|
+
onError?: OnError;
|
|
118
1199
|
};
|
|
1200
|
+
/**
|
|
1201
|
+
* Public interface returned by {@link FaasReactClient}.
|
|
1202
|
+
*/
|
|
119
1203
|
type FaasReactClientInstance = {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
1204
|
+
/** Unique identifier inherited from the underlying browser client. */id: string; /** Promise-based request helper bound to the registered base URL. */
|
|
1205
|
+
faas: typeof faas; /** Hook bound to the registered base URL. */
|
|
1206
|
+
useFaas: typeof useFaas; /** Wrapper component bound to the registered base URL. */
|
|
1207
|
+
FaasDataWrapper: typeof FaasDataWrapper; /** Optional error hook shared by `faas` and `useFaas`. */
|
|
1208
|
+
onError?: OnError; /** Underlying browser client used for the actual HTTP requests. */
|
|
1209
|
+
browserClient: FaasBrowserClient;
|
|
126
1210
|
};
|
|
127
1211
|
/**
|
|
128
|
-
*
|
|
1212
|
+
* Create and register a FaasReactClient instance.
|
|
1213
|
+
*
|
|
1214
|
+
* The returned client is stored by `baseUrl` and becomes the default client
|
|
1215
|
+
* used by helpers such as {@link faas} and {@link useFaas}.
|
|
129
1216
|
*
|
|
130
|
-
* @param
|
|
131
|
-
* @param
|
|
132
|
-
* @
|
|
1217
|
+
* @param options - Client configuration including base URL, default request options, and error hooks.
|
|
1218
|
+
* @param options.baseUrl - Base URL used to register and route the client instance.
|
|
1219
|
+
* @param options.options - Default browser-client request options forwarded to `FaasBrowserClient`.
|
|
1220
|
+
* @param options.onError - Hook factory used to handle failed `faas` and `useFaas` requests.
|
|
1221
|
+
* See {@link Options} for supported browser-client request fields such as `headers`,
|
|
1222
|
+
* `beforeRequest`, `request`, `baseUrl`, and `stream`.
|
|
1223
|
+
* @returns Registered FaasReactClient instance.
|
|
133
1224
|
*
|
|
134
1225
|
* @example
|
|
135
1226
|
* ```ts
|
|
1227
|
+
* import { FaasReactClient, ResponseError } from '@faasjs/react'
|
|
1228
|
+
*
|
|
136
1229
|
* const client = FaasReactClient({
|
|
137
|
-
* baseUrl: 'localhost:8080/api/'
|
|
1230
|
+
* baseUrl: 'http://localhost:8080/api/',
|
|
1231
|
+
* onError: (action, params) => async (res) => {
|
|
1232
|
+
* if (res instanceof ResponseError) {
|
|
1233
|
+
* reportErrorToSentry(res, {
|
|
1234
|
+
* tags: { action },
|
|
1235
|
+
* extra: { params },
|
|
1236
|
+
* })
|
|
1237
|
+
* }
|
|
1238
|
+
* },
|
|
138
1239
|
* })
|
|
139
1240
|
* ```
|
|
140
1241
|
*/
|
|
141
|
-
declare function FaasReactClient(
|
|
1242
|
+
declare function FaasReactClient(options?: FaasReactClientOptions): FaasReactClientInstance;
|
|
142
1243
|
/**
|
|
143
|
-
* Get FaasReactClient instance
|
|
1244
|
+
* Get a registered FaasReactClient instance.
|
|
1245
|
+
*
|
|
1246
|
+
* When `host` is omitted, the first registered client is returned. If no client
|
|
1247
|
+
* has been created yet, a default client is initialized automatically.
|
|
1248
|
+
* Use `getClient` only for special cases such as multiple Faas clients with
|
|
1249
|
+
* different base URLs. In normal single-client app code, prefer the default
|
|
1250
|
+
* `faas`, `useFaas`, or `FaasReactClient` setup directly.
|
|
144
1251
|
*
|
|
145
|
-
* @param host
|
|
146
|
-
* @returns
|
|
1252
|
+
* @param host - Registered base URL to look up. Omit it to use the default client.
|
|
1253
|
+
* @returns Registered or newly created FaasReactClient instance.
|
|
147
1254
|
*
|
|
148
1255
|
* @example
|
|
149
1256
|
* ```ts
|
|
150
|
-
* getClient
|
|
151
|
-
*
|
|
152
|
-
*
|
|
1257
|
+
* import { FaasReactClient, getClient } from '@faasjs/react'
|
|
1258
|
+
*
|
|
1259
|
+
* FaasReactClient({
|
|
1260
|
+
* baseUrl: 'https://service-a.example.com/api/',
|
|
1261
|
+
* })
|
|
1262
|
+
*
|
|
1263
|
+
* FaasReactClient({
|
|
1264
|
+
* baseUrl: 'https://service-b.example.com/api/',
|
|
1265
|
+
* })
|
|
1266
|
+
*
|
|
1267
|
+
* const client = getClient('https://service-b.example.com/api/')
|
|
1268
|
+
*
|
|
1269
|
+
* await client.faas('/pages/posts/get', { id: 1 })
|
|
153
1270
|
* ```
|
|
154
1271
|
*/
|
|
155
1272
|
declare function getClient(host?: string): FaasReactClientInstance;
|
|
156
|
-
|
|
1273
|
+
//#endregion
|
|
1274
|
+
//#region src/constant.d.ts
|
|
157
1275
|
/**
|
|
158
1276
|
* Returns a constant value that is created by the given function.
|
|
1277
|
+
*
|
|
1278
|
+
* @template T - Constant value type returned by the initializer.
|
|
1279
|
+
* @param fn - Initializer that runs only once for the current component instance.
|
|
1280
|
+
*
|
|
1281
|
+
* @example
|
|
1282
|
+
* ```tsx
|
|
1283
|
+
* import { useConstant } from '@faasjs/react'
|
|
1284
|
+
*
|
|
1285
|
+
* function Page() {
|
|
1286
|
+
* const requestId = useConstant(() => crypto.randomUUID())
|
|
1287
|
+
*
|
|
1288
|
+
* return <span>{requestId}</span>
|
|
1289
|
+
* }
|
|
1290
|
+
* ```
|
|
159
1291
|
*/
|
|
160
1292
|
declare function useConstant<T>(fn: () => T): T;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
1293
|
+
//#endregion
|
|
1294
|
+
//#region src/ErrorBoundary.d.ts
|
|
1295
|
+
/**
|
|
1296
|
+
* Props for the {@link ErrorBoundary} component.
|
|
1297
|
+
*/
|
|
165
1298
|
interface ErrorBoundaryProps {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
1299
|
+
/** Descendant elements protected by the boundary. */
|
|
1300
|
+
children?: ReactNode;
|
|
1301
|
+
/** Callback invoked after a descendant throws during rendering or lifecycle work. */
|
|
1302
|
+
onError?: (error: Error | null, info: any) => void;
|
|
1303
|
+
/** Custom fallback element cloned with captured error details. */
|
|
1304
|
+
errorChildren?: ReactElement<ErrorChildrenProps>;
|
|
169
1305
|
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Props injected into a custom error fallback element.
|
|
1308
|
+
*/
|
|
170
1309
|
type ErrorChildrenProps = {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
1310
|
+
/** Captured error instance. */error?: Error; /** React component stack metadata for the captured error. */
|
|
1311
|
+
info?: any; /** Stringified error message shown by the default fallback. */
|
|
1312
|
+
errorMessage?: string; /** Component stack description shown by the default fallback. */
|
|
1313
|
+
errorDescription?: string;
|
|
175
1314
|
};
|
|
1315
|
+
/**
|
|
1316
|
+
* React error boundary with an optional custom fallback element.
|
|
1317
|
+
*
|
|
1318
|
+
* The boundary renders its children until a descendant throws. After that it
|
|
1319
|
+
* either clones `errorChildren` with injected error details or renders a simple
|
|
1320
|
+
* built-in fallback.
|
|
1321
|
+
*
|
|
1322
|
+
* @example
|
|
1323
|
+
* ```tsx
|
|
1324
|
+
* import { ErrorBoundary } from '@faasjs/react'
|
|
1325
|
+
*
|
|
1326
|
+
* function Fallback({ errorMessage }: { errorMessage?: string }) {
|
|
1327
|
+
* return <div>{errorMessage}</div>
|
|
1328
|
+
* }
|
|
1329
|
+
*
|
|
1330
|
+
* <ErrorBoundary errorChildren={<Fallback />}>
|
|
1331
|
+
* <DangerousWidget />
|
|
1332
|
+
* </ErrorBoundary>
|
|
1333
|
+
* ```
|
|
1334
|
+
*/
|
|
176
1335
|
declare class ErrorBoundary extends Component<ErrorBoundaryProps, {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
componentStack?: string;
|
|
180
|
-
};
|
|
1336
|
+
error: Error | null;
|
|
1337
|
+
info: ErrorInfo;
|
|
181
1338
|
}> {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
1339
|
+
/**
|
|
1340
|
+
* Stable display name used by React DevTools.
|
|
1341
|
+
*/
|
|
1342
|
+
static displayName: string;
|
|
1343
|
+
/**
|
|
1344
|
+
* Create an error boundary with empty error state.
|
|
1345
|
+
*
|
|
1346
|
+
* @param props - Boundary props.
|
|
1347
|
+
* @param props.children - Descendant elements protected by the boundary.
|
|
1348
|
+
* @param props.onError - Callback invoked after a render error is captured.
|
|
1349
|
+
* @param props.errorChildren - Custom fallback element that receives error details.
|
|
1350
|
+
*/
|
|
1351
|
+
constructor(props: ErrorBoundaryProps);
|
|
1352
|
+
/**
|
|
1353
|
+
* Capture rendering errors from descendant components.
|
|
1354
|
+
*
|
|
1355
|
+
* @param error - Caught render error.
|
|
1356
|
+
* @param info - React component stack metadata.
|
|
1357
|
+
*/
|
|
1358
|
+
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
1359
|
+
/**
|
|
1360
|
+
* Render children or the configured fallback for the captured error.
|
|
1361
|
+
*/
|
|
1362
|
+
render(): string | number | bigint | boolean | _$react_jsx_runtime0.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | _$react.ReactPortal | ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null;
|
|
187
1363
|
}
|
|
188
|
-
|
|
1364
|
+
//#endregion
|
|
1365
|
+
//#region src/equal.d.ts
|
|
189
1366
|
/**
|
|
190
1367
|
* Compares two values for deep equality.
|
|
191
1368
|
*
|
|
@@ -196,6 +1373,14 @@ declare class ErrorBoundary extends Component<ErrorBoundaryProps, {
|
|
|
196
1373
|
* @param a - The first value to compare.
|
|
197
1374
|
* @param b - The second value to compare.
|
|
198
1375
|
* @returns `true` if the values are deeply equal, `false` otherwise.
|
|
1376
|
+
*
|
|
1377
|
+
* @example
|
|
1378
|
+
* ```ts
|
|
1379
|
+
* import { equal } from '@faasjs/react'
|
|
1380
|
+
*
|
|
1381
|
+
* equal({ page: 1, filters: ['a'] }, { page: 1, filters: ['a'] }) // true
|
|
1382
|
+
* equal({ page: 1 }, { page: 2 }) // false
|
|
1383
|
+
* ```
|
|
199
1384
|
*/
|
|
200
1385
|
declare function equal(a: any, b: any): boolean;
|
|
201
1386
|
/**
|
|
@@ -203,6 +1388,17 @@ declare function equal(a: any, b: any): boolean;
|
|
|
203
1388
|
*
|
|
204
1389
|
* @param value - The value to be memoized.
|
|
205
1390
|
* @returns The memoized value.
|
|
1391
|
+
*
|
|
1392
|
+
* @example
|
|
1393
|
+
* ```tsx
|
|
1394
|
+
* import { useEqualMemoize } from '@faasjs/react'
|
|
1395
|
+
*
|
|
1396
|
+
* function Filters({ filters }: { filters: Record<string, any> }) {
|
|
1397
|
+
* const memoizedFilters = useEqualMemoize(filters)
|
|
1398
|
+
*
|
|
1399
|
+
* return <pre>{JSON.stringify(memoizedFilters)}</pre>
|
|
1400
|
+
* }
|
|
1401
|
+
* ```
|
|
206
1402
|
*/
|
|
207
1403
|
declare function useEqualMemoize(value: any): any;
|
|
208
1404
|
/**
|
|
@@ -211,232 +1407,89 @@ declare function useEqualMemoize(value: any): any;
|
|
|
211
1407
|
* @param callback - The effect callback function to run.
|
|
212
1408
|
* @param dependencies - The list of dependencies for the effect.
|
|
213
1409
|
* @returns The result of the `useEffect` hook with memoized dependencies.
|
|
1410
|
+
*
|
|
1411
|
+
* @example
|
|
1412
|
+
* ```tsx
|
|
1413
|
+
* import { useEqualEffect } from '@faasjs/react'
|
|
1414
|
+
*
|
|
1415
|
+
* function Page({ filters }: { filters: Record<string, any> }) {
|
|
1416
|
+
* useEqualEffect(() => {
|
|
1417
|
+
* console.log('filters changed', filters)
|
|
1418
|
+
* }, [filters])
|
|
1419
|
+
*
|
|
1420
|
+
* return null
|
|
1421
|
+
* }
|
|
1422
|
+
* ```
|
|
214
1423
|
*/
|
|
215
1424
|
declare function useEqualEffect(callback: React.EffectCallback, dependencies: any[]): void;
|
|
216
1425
|
/**
|
|
217
1426
|
* Custom hook that works like `useMemo` but uses deep comparison on dependencies.
|
|
218
1427
|
*
|
|
1428
|
+
* @template T - Memoized value type returned by the callback.
|
|
1429
|
+
*
|
|
219
1430
|
* @param callback - The callback function to run.
|
|
220
1431
|
* @param dependencies - The list of dependencies.
|
|
221
1432
|
* @returns The result of the `useMemo` hook with memoized dependencies.
|
|
1433
|
+
*
|
|
1434
|
+
* @example
|
|
1435
|
+
* ```tsx
|
|
1436
|
+
* import { useEqualMemo } from '@faasjs/react'
|
|
1437
|
+
*
|
|
1438
|
+
* function Page({ filters }: { filters: Record<string, any> }) {
|
|
1439
|
+
* const queryString = useEqualMemo(() => JSON.stringify(filters), [filters])
|
|
1440
|
+
*
|
|
1441
|
+
* return <span>{queryString}</span>
|
|
1442
|
+
* }
|
|
1443
|
+
* ```
|
|
222
1444
|
*/
|
|
223
1445
|
declare function useEqualMemo<T>(callback: () => T, dependencies: any[]): T;
|
|
224
1446
|
/**
|
|
225
1447
|
* Custom hook that works like `useCallback` but uses deep comparison on dependencies.
|
|
226
1448
|
*
|
|
1449
|
+
* @template T - Callback signature to memoize.
|
|
1450
|
+
*
|
|
227
1451
|
* @param callback - The callback function to run.
|
|
228
1452
|
* @param dependencies - The list of dependencies.
|
|
229
1453
|
* @returns The result of the `useCallback` hook with memoized dependencies.
|
|
230
|
-
*/
|
|
231
|
-
declare function useEqualCallback<T extends (...args: any[]) => any>(callback: T, dependencies: any[]): T;
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Props for the FormButtonElement component.
|
|
235
|
-
*
|
|
236
|
-
* @property {React.ReactNode} [children] - The content to be displayed inside the button.
|
|
237
|
-
* @property {boolean} disabled - Indicates whether the button is disabled.
|
|
238
|
-
* @property {() => Promise<void>} submit - A function to be called when the button is clicked, which returns a promise.
|
|
239
|
-
*/
|
|
240
|
-
type FormButtonElementProps = {
|
|
241
|
-
children?: React.ReactNode;
|
|
242
|
-
submitting: boolean;
|
|
243
|
-
submit: () => Promise<void>;
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Props for the Form Input Element component.
|
|
248
1454
|
*
|
|
249
|
-
* @
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*/
|
|
253
|
-
type FormInputElementProps = {
|
|
254
|
-
name: string;
|
|
255
|
-
value: any;
|
|
256
|
-
onChange: (value: any) => void;
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Props for the FormLabelElement component.
|
|
261
|
-
*
|
|
262
|
-
* @typedef {Object} FormLabelElementProps
|
|
263
|
-
* @property {string} name - The name of the form element.
|
|
264
|
-
* @property {ReactNode} [title] - Optional title for the form element.
|
|
265
|
-
* @property {ReactNode} [description] - Optional description for the form element.
|
|
266
|
-
* @property {Error} [error] - Optional error associated with the form element.
|
|
267
|
-
* @property {ReactNode} children - The child elements, typically an input element.
|
|
268
|
-
*/
|
|
269
|
-
type FormLabelElementProps = {
|
|
270
|
-
name: string;
|
|
271
|
-
title?: ReactNode;
|
|
272
|
-
description?: ReactNode;
|
|
273
|
-
error?: Error;
|
|
274
|
-
/** as Input element */
|
|
275
|
-
children: ReactNode;
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Represents the types of form elements used in the form.
|
|
280
|
-
*
|
|
281
|
-
* @typedef {Object} FormElementTypes
|
|
282
|
-
* @property {ComponentType<FormLabelElementProps>} Label - The component type for the form label element.
|
|
283
|
-
* @property {ComponentType<FormInputElementProps>} Input - The component type for the form input element.
|
|
284
|
-
* @property {ComponentType<FormButtonElementProps>} Button - The component type for the form button element.
|
|
285
|
-
*/
|
|
286
|
-
type FormElementTypes = {
|
|
287
|
-
Label: ComponentType<FormLabelElementProps>;
|
|
288
|
-
Input: ComponentType<FormInputElementProps>;
|
|
289
|
-
Button: ComponentType<FormButtonElementProps>;
|
|
290
|
-
};
|
|
291
|
-
declare const FormDefaultElements: FormElementTypes;
|
|
292
|
-
|
|
293
|
-
declare const FormDefaultLang: {
|
|
294
|
-
submit: string;
|
|
295
|
-
required: string;
|
|
296
|
-
string: string;
|
|
297
|
-
number: string;
|
|
298
|
-
};
|
|
299
|
-
type FormLang = typeof FormDefaultLang;
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* A type representing a form validation rule.
|
|
303
|
-
*
|
|
304
|
-
* @template Options - The type of the options that can be passed to the rule.
|
|
305
|
-
*
|
|
306
|
-
* @param value - The value to be validated.
|
|
307
|
-
* @param options - Optional. Additional options that can be used in the validation.
|
|
308
|
-
* @param lang - Optional. The language settings that can be used in the validation.
|
|
1455
|
+
* @example
|
|
1456
|
+
* ```tsx
|
|
1457
|
+
* import { useEqualCallback } from '@faasjs/react'
|
|
309
1458
|
*
|
|
310
|
-
*
|
|
1459
|
+
* function Search({ filters }: { filters: Record<string, any> }) {
|
|
1460
|
+
* const handleSubmit = useEqualCallback(() => {
|
|
1461
|
+
* console.log(filters)
|
|
1462
|
+
* }, [filters])
|
|
311
1463
|
*
|
|
312
|
-
*
|
|
313
|
-
* ```ts
|
|
314
|
-
* async function required(value: any, options: boolean, lang?: FormLang) {
|
|
315
|
-
* if (value === null || value === undefined || value === '' || Number.isNaN(value))
|
|
316
|
-
* throw Error(lang?.required)
|
|
1464
|
+
* return <button onClick={handleSubmit}>Search</button>
|
|
317
1465
|
* }
|
|
318
1466
|
* ```
|
|
319
1467
|
*/
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
* A type representing a set of form validation rules.
|
|
324
|
-
*
|
|
325
|
-
* @typedef {Record<string, FormRule>} FormRules
|
|
326
|
-
*
|
|
327
|
-
* 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.
|
|
328
|
-
*/
|
|
329
|
-
type FormRules = Record<string, FormRule>;
|
|
330
|
-
type InferFormRulesOptions<T> = {
|
|
331
|
-
[K in keyof T]: InferRuleOption<T[K]>;
|
|
332
|
-
};
|
|
333
|
-
/**
|
|
334
|
-
* Default validation rules for a form.
|
|
335
|
-
*
|
|
336
|
-
* @constant
|
|
337
|
-
* @type {FormRules}
|
|
338
|
-
*/
|
|
339
|
-
declare const FormDefaultRules: FormRules;
|
|
340
|
-
type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
|
|
341
|
-
declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
|
|
342
|
-
|
|
343
|
-
type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
|
|
344
|
-
type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
|
|
345
|
-
Input?: ComponentType<FormInputElementProps>;
|
|
346
|
-
props?: InferFormInputProps<FormElements['Input']>;
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
type FormItemName = string;
|
|
350
|
-
type FormItemProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
|
|
351
|
-
name: FormItemName;
|
|
352
|
-
label?: Omit<FormLabelElementProps, 'name' | 'children'> & {
|
|
353
|
-
Label?: ComponentType<FormLabelElementProps>;
|
|
354
|
-
};
|
|
355
|
-
input?: FormInputProps<FormElements>;
|
|
356
|
-
rules?: FormRulesOptions;
|
|
357
|
-
};
|
|
358
|
-
declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
|
|
359
|
-
declare namespace FormItem {
|
|
360
|
-
var displayName: string;
|
|
361
|
-
var whyDidYouRender: boolean;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
365
|
-
items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
|
|
366
|
-
onSubmit?: (values: Values) => Promise<void>;
|
|
367
|
-
Elements?: Partial<FormElements>;
|
|
368
|
-
lang?: Partial<FormLang>;
|
|
369
|
-
defaultValues?: Values;
|
|
370
|
-
rules?: typeof FormDefaultRules & Rules;
|
|
371
|
-
};
|
|
1468
|
+
declare function useEqualCallback<T extends (...args: any[]) => any>(callback: T, dependencies: any[]): T;
|
|
1469
|
+
//#endregion
|
|
1470
|
+
//#region src/OptionalWrapper.d.ts
|
|
372
1471
|
/**
|
|
373
|
-
*
|
|
374
|
-
* It initializes form states such as values, errors, submitting status, elements, language, and rules.
|
|
375
|
-
*
|
|
376
|
-
* @template Values - The type of form values, defaults to Record<string, any>.
|
|
377
|
-
* @template FormElements - The type of form elements, defaults to FormElementTypes.
|
|
378
|
-
* @template Rules - The type of form rules, defaults to FormDefaultRules.
|
|
379
|
-
*
|
|
380
|
-
* @param {FormProps<Values, FormElements, Rules>} props - The properties for the FormContainer component.
|
|
381
|
-
* @param {Values} props.defaultValues - The default values for the form fields.
|
|
382
|
-
* @param {FormElements} props.Elements - The form elements to be used in the form.
|
|
383
|
-
* @param {Rules} props.rules - The validation rules for the form fields.
|
|
384
|
-
* @param {FormLang} props.lang - The language settings for the form.
|
|
385
|
-
* @param {Partial<FormContextProps>} props - Additional properties for the form context.
|
|
386
|
-
*
|
|
387
|
-
* @returns {JSX.Element} The FormContainer component.
|
|
1472
|
+
* Props for the {@link OptionalWrapper} helper component.
|
|
388
1473
|
*
|
|
389
|
-
* @
|
|
390
|
-
* ```tsx
|
|
391
|
-
* import { Form } from '@faasjs/react'
|
|
392
|
-
*
|
|
393
|
-
* function MyForm() {
|
|
394
|
-
* return <Form
|
|
395
|
-
* items={[
|
|
396
|
-
* { name: 'name' },
|
|
397
|
-
* ]}
|
|
398
|
-
* />
|
|
399
|
-
* }
|
|
400
|
-
* ```
|
|
1474
|
+
* @template TWrapper - Wrapper component type used when `condition` is true.
|
|
401
1475
|
*/
|
|
402
|
-
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;
|
|
403
|
-
declare namespace FormContainer {
|
|
404
|
-
var displayName: string;
|
|
405
|
-
var whyDidYouRender: boolean;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
type FormContextProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
409
|
-
items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
|
|
410
|
-
onSubmit: (values: Values) => Promise<void>;
|
|
411
|
-
Elements: FormElementTypes;
|
|
412
|
-
lang: FormLang;
|
|
413
|
-
rules: typeof FormDefaultRules & Rules;
|
|
414
|
-
submitting: boolean;
|
|
415
|
-
setSubmitting: Dispatch<SetStateAction<boolean>>;
|
|
416
|
-
values: Values;
|
|
417
|
-
setValues: Dispatch<SetStateAction<Values>>;
|
|
418
|
-
errors: Record<string, Error>;
|
|
419
|
-
setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
|
|
420
|
-
valuesRef: RefObject<Values>;
|
|
421
|
-
};
|
|
422
|
-
declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>(props: {
|
|
423
|
-
value?: Partial<NewT>;
|
|
424
|
-
children: react.ReactNode;
|
|
425
|
-
memo?: true | any[];
|
|
426
|
-
initializeStates?: Partial<NewT>;
|
|
427
|
-
}) => react.ReactNode;
|
|
428
|
-
declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormElementTypes, FormRules> = FormContextProps<Record<string, any>, FormElementTypes, FormRules>>() => Readonly<NewT>;
|
|
429
|
-
|
|
430
1476
|
type OptionalWrapperProps<TWrapper extends ComponentType<{
|
|
431
|
-
|
|
1477
|
+
children: ReactNode;
|
|
432
1478
|
}> = any> = {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
1479
|
+
/** When `true`, render `children` inside `Wrapper`. */condition: boolean; /** Wrapper component used when `condition` passes. */
|
|
1480
|
+
Wrapper: TWrapper; /** Props forwarded to `Wrapper` together with `children`. */
|
|
1481
|
+
wrapperProps?: ComponentProps<TWrapper>; /** Content rendered directly or inside the wrapper. */
|
|
1482
|
+
children: ReactNode;
|
|
437
1483
|
};
|
|
438
1484
|
/**
|
|
439
|
-
*
|
|
1485
|
+
* Conditionally wrap children with another component.
|
|
1486
|
+
*
|
|
1487
|
+
* @param props - Wrapper condition, wrapper component, and child content.
|
|
1488
|
+
* @param props.condition - When `true`, wrap children with `Wrapper`.
|
|
1489
|
+
* @param props.Wrapper - Component used as the wrapper when the condition passes.
|
|
1490
|
+
* @param props.wrapperProps - Props forwarded to the wrapper component.
|
|
1491
|
+
* @param props.children - Content rendered directly or inside the wrapper.
|
|
1492
|
+
* @returns Wrapped children or the original children when `condition` is false.
|
|
440
1493
|
*
|
|
441
1494
|
* @example
|
|
442
1495
|
* ```tsx
|
|
@@ -453,14 +1506,22 @@ type OptionalWrapperProps<TWrapper extends ComponentType<{
|
|
|
453
1506
|
* )
|
|
454
1507
|
* ```
|
|
455
1508
|
*/
|
|
456
|
-
declare
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
1509
|
+
declare function OptionalWrapper(props: OptionalWrapperProps): string | number | bigint | boolean | _$react_jsx_runtime0.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | _$react.ReactPortal | _$react.ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
1510
|
+
declare namespace OptionalWrapper {
|
|
1511
|
+
var displayName: string;
|
|
1512
|
+
}
|
|
1513
|
+
//#endregion
|
|
1514
|
+
//#region src/splittingContext.d.ts
|
|
460
1515
|
/**
|
|
461
|
-
*
|
|
1516
|
+
* Create a context whose keys can be consumed independently.
|
|
462
1517
|
*
|
|
463
|
-
*
|
|
1518
|
+
* `createSplittingContext` returns a `Provider` and a `use` hook. Each key in
|
|
1519
|
+
* the provided shape is backed by a separate React context so readers only
|
|
1520
|
+
* subscribe to the values they access.
|
|
1521
|
+
*
|
|
1522
|
+
* @template T - Context value shape exposed by the provider and hook.
|
|
1523
|
+
* @param defaultValue - Default value map or key list used to create split contexts.
|
|
1524
|
+
* @returns Provider and hook helpers for the split context.
|
|
464
1525
|
*
|
|
465
1526
|
* @example
|
|
466
1527
|
* ```tsx
|
|
@@ -500,125 +1561,225 @@ declare const OptionalWrapper: React.FC<OptionalWrapperProps> & {
|
|
|
500
1561
|
* }
|
|
501
1562
|
* ```
|
|
502
1563
|
*/
|
|
503
|
-
declare function createSplittingContext<T extends Record<string, any>>(defaultValue: {
|
|
504
|
-
|
|
505
|
-
|
|
1564
|
+
declare function createSplittingContext<T extends Record<string, any>>(defaultValue: { [K in keyof T]: Partial<T[K]> | null } | (keyof T)[]): {
|
|
1565
|
+
/**
|
|
1566
|
+
* The provider component of the splitting context.
|
|
1567
|
+
*
|
|
1568
|
+
* @see https://faasjs.com/doc/react/functions/createSplittingContext.html#provider
|
|
1569
|
+
*
|
|
1570
|
+
* @example
|
|
1571
|
+
* ```tsx
|
|
1572
|
+
* function App() {
|
|
1573
|
+
* const [value, setValue] = useState(0)
|
|
1574
|
+
*
|
|
1575
|
+
* return (
|
|
1576
|
+
* <Provider value={{ value, setValue }}>
|
|
1577
|
+
* <ReaderComponent />
|
|
1578
|
+
* <WriterComponent />
|
|
1579
|
+
* </Provider>
|
|
1580
|
+
* )
|
|
1581
|
+
* }
|
|
1582
|
+
* ```
|
|
1583
|
+
*/
|
|
1584
|
+
Provider<NewT extends T = T>(this: void, props: {
|
|
1585
|
+
/** Partial context value supplied by the caller. */value?: Partial<NewT>; /** Descendant elements that should read from the split contexts. */
|
|
1586
|
+
children: ReactNode;
|
|
506
1587
|
/**
|
|
507
|
-
*
|
|
1588
|
+
* Memoization mode for `children`.
|
|
508
1589
|
*
|
|
509
|
-
* @
|
|
1590
|
+
* @default false
|
|
510
1591
|
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
* function App() {
|
|
514
|
-
* const [value, setValue] = useState(0)
|
|
515
|
-
*
|
|
516
|
-
* return (
|
|
517
|
-
* <Provider value={{ value, setValue }}>
|
|
518
|
-
* <ReaderComponent />
|
|
519
|
-
* <WriterComponent />
|
|
520
|
-
* </Provider>
|
|
521
|
-
* )
|
|
522
|
-
* }
|
|
523
|
-
* ```
|
|
1592
|
+
* Pass `true` to memoize without dependencies or an array to control the
|
|
1593
|
+
* deep-equality dependency list manually.
|
|
524
1594
|
*/
|
|
525
|
-
|
|
526
|
-
value?: Partial<NewT>;
|
|
527
|
-
children: ReactNode;
|
|
528
|
-
/**
|
|
529
|
-
* Whether to use memoization for the children.
|
|
530
|
-
*
|
|
531
|
-
* @default false
|
|
532
|
-
*
|
|
533
|
-
* `true`: memoize the children without dependencies.
|
|
534
|
-
* `any[]`: memoize the children with specific dependencies.
|
|
535
|
-
*/
|
|
536
|
-
memo?: true | any[];
|
|
537
|
-
/**
|
|
538
|
-
* 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.
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```tsx
|
|
542
|
-
* <Provider
|
|
543
|
-
* initializeStates={{
|
|
544
|
-
* value: 0,
|
|
545
|
-
* }}
|
|
546
|
-
* >
|
|
547
|
-
* // Children will have access to: value, setValue
|
|
548
|
-
* </Provider>
|
|
549
|
-
*/
|
|
550
|
-
initializeStates?: Partial<NewT>;
|
|
551
|
-
}): ReactNode;
|
|
1595
|
+
memo?: true | any[];
|
|
552
1596
|
/**
|
|
553
|
-
*
|
|
1597
|
+
* Initial values converted into local state via `useSplittingState`.
|
|
554
1598
|
*
|
|
555
|
-
*
|
|
1599
|
+
* Each key produces both a state value and its matching setter using the
|
|
1600
|
+
* `value` / `setValue` naming convention.
|
|
556
1601
|
*
|
|
557
1602
|
* @example
|
|
558
1603
|
* ```tsx
|
|
559
|
-
*
|
|
560
|
-
*
|
|
1604
|
+
* <Provider initializeStates={{ value: 0 }}>
|
|
1605
|
+
* <Child />
|
|
1606
|
+
* </Provider>
|
|
561
1607
|
*
|
|
562
|
-
*
|
|
563
|
-
* }
|
|
1608
|
+
* // `Child` can read `value` and `setValue`
|
|
564
1609
|
* ```
|
|
565
1610
|
*/
|
|
566
|
-
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
1611
|
+
initializeStates?: Partial<NewT>;
|
|
1612
|
+
}): ReactNode;
|
|
1613
|
+
/**
|
|
1614
|
+
* Hook used to read values from the splitting context.
|
|
1615
|
+
*
|
|
1616
|
+
* @see https://faasjs.com/doc/react/functions/createSplittingContext.html#use
|
|
1617
|
+
*
|
|
1618
|
+
* @example
|
|
1619
|
+
* ```tsx
|
|
1620
|
+
* function ChildComponent() {
|
|
1621
|
+
* const { value, setValue } = use()
|
|
1622
|
+
*
|
|
1623
|
+
* return <div>{value}<button onClick={() => setValue(1)}>change value</button></div>
|
|
1624
|
+
* }
|
|
1625
|
+
* ```
|
|
1626
|
+
*/
|
|
1627
|
+
use: <NewT extends T = T>(this: void) => Readonly<NewT>;
|
|
572
1628
|
};
|
|
1629
|
+
//#endregion
|
|
1630
|
+
//#region src/splittingState.d.ts
|
|
1631
|
+
/**
|
|
1632
|
+
* Setter map generated by {@link useSplittingState} for each state key.
|
|
1633
|
+
*
|
|
1634
|
+
* @template T - Object shape whose keys receive generated setter functions.
|
|
1635
|
+
*/
|
|
1636
|
+
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]>> };
|
|
1637
|
+
/**
|
|
1638
|
+
* State object returned by {@link useSplittingState}, including generated setters.
|
|
1639
|
+
*
|
|
1640
|
+
* @template T - Object shape returned together with generated setter functions.
|
|
1641
|
+
*/
|
|
573
1642
|
type StatesWithSetters<T> = T & StateSetters<T>;
|
|
574
1643
|
/**
|
|
575
|
-
*
|
|
1644
|
+
* Create local state entries and matching setters for each key in an object.
|
|
576
1645
|
*
|
|
577
1646
|
* @template T - A generic type that extends a record with string keys and any values.
|
|
578
|
-
* @param
|
|
1647
|
+
* @param initialStates - Object whose keys become state values and `setXxx` setters.
|
|
1648
|
+
* @returns Object containing the original keys plus generated setter functions.
|
|
579
1649
|
*
|
|
580
1650
|
* @example
|
|
581
1651
|
* ```tsx
|
|
582
1652
|
* function Counter() {
|
|
583
|
-
* const { count, setCount, name, setName } = useSplittingState({ count: 0, name: 'John' })
|
|
1653
|
+
* const { count, setCount, name, setName } = useSplittingState({ count: 0, name: 'John' })
|
|
584
1654
|
*
|
|
585
1655
|
* return <>{name}: {count}</>
|
|
586
1656
|
* }
|
|
587
1657
|
* ```
|
|
588
1658
|
*/
|
|
589
1659
|
declare function useSplittingState<T extends Record<string, unknown>>(initialStates: T): StatesWithSetters<T>;
|
|
590
|
-
|
|
1660
|
+
//#endregion
|
|
1661
|
+
//#region src/useFaasStream.d.ts
|
|
1662
|
+
/**
|
|
1663
|
+
* Options that customize the {@link useFaasStream} request lifecycle.
|
|
1664
|
+
*/
|
|
1665
|
+
type UseFaasStreamOptions = {
|
|
1666
|
+
/** Override the current request params without changing the hook's stored params state. */params?: Record<string, any>; /** Controlled stream text used instead of the hook's internal state. */
|
|
1667
|
+
data?: string; /** Controlled setter that is called instead of the hook's internal `setData`. */
|
|
1668
|
+
setData?: React.Dispatch<React.SetStateAction<string>>;
|
|
1669
|
+
/**
|
|
1670
|
+
* If skip is true, the request will not be sent.
|
|
1671
|
+
*
|
|
1672
|
+
* However, you can still use reload to send the request.
|
|
1673
|
+
*/
|
|
1674
|
+
skip?: boolean | ((params: Record<string, any>) => boolean); /** Delay the latest automatic request by the given number of milliseconds. */
|
|
1675
|
+
debounce?: number; /** Override the default base URL for this hook instance. */
|
|
1676
|
+
baseUrl?: BaseUrl;
|
|
1677
|
+
};
|
|
1678
|
+
/**
|
|
1679
|
+
* Result returned by {@link useFaasStream}.
|
|
1680
|
+
*/
|
|
1681
|
+
type UseFaasStreamResult = {
|
|
1682
|
+
/** Action path currently associated with the stream request. */action: string; /** Params used for the most recent request attempt. */
|
|
1683
|
+
params: Record<string, any>; /** Whether the hook is currently waiting for stream data. */
|
|
1684
|
+
loading: boolean; /** Number of times `reload()` has triggered a new request. */
|
|
1685
|
+
reloadTimes: number; /** Accumulated text decoded from the stream response. */
|
|
1686
|
+
data: string; /** Last error raised while opening or consuming the stream. */
|
|
1687
|
+
error: any; /** Trigger a new streaming request with optional params. */
|
|
1688
|
+
reload: (params?: Record<string, any>) => Promise<string>; /** Controlled or internal setter for the accumulated text. */
|
|
1689
|
+
setData: React.Dispatch<React.SetStateAction<string>>; /** Setter for the loading flag. */
|
|
1690
|
+
setLoading: React.Dispatch<React.SetStateAction<boolean>>; /** Setter for the last stream error. */
|
|
1691
|
+
setError: React.Dispatch<React.SetStateAction<any>>;
|
|
1692
|
+
};
|
|
1693
|
+
/**
|
|
1694
|
+
* Stream a FaasJS response into React state.
|
|
1695
|
+
*
|
|
1696
|
+
* `useFaasStream` is the default hook for streaming FaasJS responses in React.
|
|
1697
|
+
* It sends a streaming request, appends decoded text chunks to `data`, and
|
|
1698
|
+
* exposes reload helpers for retrying the same action.
|
|
1699
|
+
*
|
|
1700
|
+
* @param action - Action path to invoke.
|
|
1701
|
+
* @param defaultParams - Params used for the initial request and future reloads.
|
|
1702
|
+
* @param options - Optional hook configuration such as controlled data, debounce, and skip logic.
|
|
1703
|
+
* @param options.params - Request params override used without mutating the hook's stored params state.
|
|
1704
|
+
* @param options.data - Controlled stream text used instead of the hook's internal state.
|
|
1705
|
+
* @param options.setData - Controlled setter used instead of the hook's internal `setData`.
|
|
1706
|
+
* @param options.skip - Boolean or predicate that suppresses the automatic request until `reload()` runs.
|
|
1707
|
+
* @param options.debounce - Milliseconds to wait before sending the latest request.
|
|
1708
|
+
* @param options.baseUrl - Base URL override used for this hook instance.
|
|
1709
|
+
* @returns Streaming request state and helper methods described by {@link UseFaasStreamResult}.
|
|
1710
|
+
*
|
|
1711
|
+
* @example
|
|
1712
|
+
* ```tsx
|
|
1713
|
+
* import { useFaasStream } from '@faasjs/react'
|
|
1714
|
+
*
|
|
1715
|
+
* function Chat({ prompt }: { prompt: string }) {
|
|
1716
|
+
* const { data, error, loading, reload } = useFaasStream('/pages/chat/stream', { prompt })
|
|
1717
|
+
*
|
|
1718
|
+
* if (loading) return <div>Streaming...</div>
|
|
1719
|
+
*
|
|
1720
|
+
* if (error) {
|
|
1721
|
+
* return (
|
|
1722
|
+
* <div>
|
|
1723
|
+
* <div>Stream failed: {error.message}</div>
|
|
1724
|
+
* <button type="button" onClick={() => reload()}>
|
|
1725
|
+
* Retry
|
|
1726
|
+
* </button>
|
|
1727
|
+
* </div>
|
|
1728
|
+
* )
|
|
1729
|
+
* }
|
|
1730
|
+
*
|
|
1731
|
+
* return <pre>{data}</pre>
|
|
1732
|
+
* }
|
|
1733
|
+
* ```
|
|
1734
|
+
*/
|
|
1735
|
+
declare function useFaasStream(action: string, defaultParams: Record<string, any>, options?: UseFaasStreamOptions): UseFaasStreamResult;
|
|
1736
|
+
//#endregion
|
|
1737
|
+
//#region src/usePrevious.d.ts
|
|
591
1738
|
/**
|
|
592
1739
|
* Hook to store the previous value of a state or prop.
|
|
593
1740
|
*
|
|
594
1741
|
* @template T - The type of the value.
|
|
595
|
-
* @param
|
|
596
|
-
* @returns
|
|
1742
|
+
* @param value - The current value to track.
|
|
1743
|
+
* @returns Previous value from the prior render, or `undefined` on the first render.
|
|
1744
|
+
*
|
|
1745
|
+
* @example
|
|
1746
|
+
* ```tsx
|
|
1747
|
+
* import { usePrevious } from '@faasjs/react'
|
|
1748
|
+
*
|
|
1749
|
+
* function Counter({ count }: { count: number }) {
|
|
1750
|
+
* const previous = usePrevious(count)
|
|
1751
|
+
*
|
|
1752
|
+
* return <span>{previous} -> {count}</span>
|
|
1753
|
+
* }
|
|
1754
|
+
* ```
|
|
597
1755
|
*/
|
|
598
1756
|
declare function usePrevious<T = any>(value: T): T | undefined;
|
|
599
|
-
|
|
1757
|
+
//#endregion
|
|
1758
|
+
//#region src/useStateRef.d.ts
|
|
600
1759
|
/**
|
|
601
1760
|
* Custom hook that returns a stateful value and a ref to that value.
|
|
602
1761
|
*
|
|
603
1762
|
* @template T - The type of the value.
|
|
604
|
-
* @param
|
|
605
|
-
* @returns
|
|
1763
|
+
* @param initialValue - Initial state value. When omitted, state starts as `null`.
|
|
1764
|
+
* @returns Tuple containing the current state, the state setter, and a ref that always points at the latest state.
|
|
606
1765
|
*
|
|
607
1766
|
* @example
|
|
608
1767
|
* ```tsx
|
|
609
1768
|
* import { useStateRef } from '@faasjs/react'
|
|
610
1769
|
*
|
|
611
1770
|
* function MyComponent() {
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
1771
|
+
* const [value, setValue, ref] = useStateRef(0)
|
|
1772
|
+
*
|
|
1773
|
+
* return (
|
|
1774
|
+
* <div>
|
|
1775
|
+
* <p>Value: {value}</p>
|
|
1776
|
+
* <button onClick={() => setValue(value + 1)}>Increment</button>
|
|
1777
|
+
* <button onClick={() => console.log(ref.current)}>Submit</button>
|
|
1778
|
+
* </div>
|
|
1779
|
+
* )
|
|
1780
|
+
* }
|
|
1781
|
+
* ```
|
|
621
1782
|
*/
|
|
622
|
-
declare function useStateRef<T = any>(initialValue?: T): [T, Dispatch<SetStateAction<T>>, RefObject<T>];
|
|
623
|
-
|
|
624
|
-
export { ErrorBoundary,
|
|
1783
|
+
declare function useStateRef<T = any>(initialValue?: T): [T | null, Dispatch<SetStateAction<T | null>>, RefObject<T | null>];
|
|
1784
|
+
//#endregion
|
|
1785
|
+
export { BaseUrl, ErrorBoundary, ErrorBoundaryProps, ErrorChildrenProps, type FaasAction, type FaasActionUnionType, FaasBrowserClient, FaasBrowserClientAction, type FaasData, FaasDataInjection, FaasDataWrapper, FaasDataWrapperProps, FaasDataWrapperRef, type FaasParams, FaasReactClient, FaasReactClientInstance, FaasReactClientOptions, MockHandler, OnError, OptionalWrapper, OptionalWrapperProps, Options, Response, ResponseError, ResponseErrorProps, ResponseHeaders, ResponseProps, StateSetters, StatesWithSetters, UseFaasStreamOptions, UseFaasStreamResult, createSplittingContext, equal, faas, generateId, getClient, setMock, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFaasOptions, useFaasStream, usePrevious, useSplittingState, useStateRef, withFaasData };
|