@faasjs/react 3.7.0-beta.1 → 3.7.0-beta.10
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 -1
- package/dist/index.d.mts +120 -29
- package/dist/index.d.ts +120 -29
- package/dist/index.js +200 -91
- package/dist/index.mjs +197 -93
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useRef, useMemo, useEffect, useCallback,
|
|
1
|
+
import { forwardRef, useRef, useMemo, useEffect, useCallback, useState, createContext, cloneElement, Component, useContext } from 'react';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { FaasBrowserClient } from '@faasjs/browser';
|
|
4
4
|
|
|
@@ -18,6 +18,7 @@ function equal(a, b) {
|
|
|
18
18
|
if ((a === null || a === void 0) && (b === null || b === void 0))
|
|
19
19
|
return true;
|
|
20
20
|
if (typeof a !== typeof b) return false;
|
|
21
|
+
if (b === null || b === void 0) return false;
|
|
21
22
|
const ctor = a.constructor;
|
|
22
23
|
if (ctor !== b.constructor) return false;
|
|
23
24
|
switch (ctor) {
|
|
@@ -45,11 +46,8 @@ function equal(a, b) {
|
|
|
45
46
|
case Promise:
|
|
46
47
|
return a === b;
|
|
47
48
|
case Object: {
|
|
48
|
-
const
|
|
49
|
-
if (keys.length !== Object.keys(b).length) return false;
|
|
50
|
-
for (const key of keys) {
|
|
49
|
+
for (const key of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]))
|
|
51
50
|
if (!equal(a[key], b[key])) return false;
|
|
52
|
-
}
|
|
53
51
|
return true;
|
|
54
52
|
}
|
|
55
53
|
default:
|
|
@@ -77,6 +75,24 @@ function useEqualCallback(callback, dependencies) {
|
|
|
77
75
|
useEqualMemoize(dependencies)
|
|
78
76
|
);
|
|
79
77
|
}
|
|
78
|
+
function usePrevious(value) {
|
|
79
|
+
const ref = useRef();
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
ref.current = value;
|
|
82
|
+
});
|
|
83
|
+
return ref.current;
|
|
84
|
+
}
|
|
85
|
+
function useSplittingState(initialStates) {
|
|
86
|
+
const states = {};
|
|
87
|
+
for (const key of Object.keys(initialStates)) {
|
|
88
|
+
const state = useState(initialStates[key]);
|
|
89
|
+
Object.assign(states, {
|
|
90
|
+
[key]: state[0],
|
|
91
|
+
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return states;
|
|
95
|
+
}
|
|
80
96
|
function createSplittingContext(defaultValue) {
|
|
81
97
|
const keys = Array.isArray(defaultValue) ? defaultValue : Object.keys(defaultValue);
|
|
82
98
|
const defaultValues = Array.isArray(defaultValue) ? keys.reduce((prev, cur) => {
|
|
@@ -86,17 +102,20 @@ function createSplittingContext(defaultValue) {
|
|
|
86
102
|
const contexts = {};
|
|
87
103
|
for (const key of keys) contexts[key] = createContext(defaultValues[key]);
|
|
88
104
|
function Provider(props) {
|
|
105
|
+
const states = props.initializeStates ? useSplittingState(props.initializeStates) : {};
|
|
89
106
|
let children = props.memo ? useEqualMemo(
|
|
90
107
|
() => props.children,
|
|
91
108
|
props.memo === true ? [] : props.memo
|
|
92
109
|
) : props.children;
|
|
93
110
|
for (const key of keys) {
|
|
94
111
|
const Context = contexts[key];
|
|
95
|
-
const value = props.value?.[key] ?? defaultValues[key];
|
|
112
|
+
const value = props.value?.[key] ?? states[key] ?? defaultValues[key];
|
|
96
113
|
children = /* @__PURE__ */ jsx(Context.Provider, { value, children });
|
|
97
114
|
}
|
|
98
115
|
return children;
|
|
99
116
|
}
|
|
117
|
+
Provider.displayName = "SplittingContextProvider";
|
|
118
|
+
Provider.whyDidYouRender = true;
|
|
100
119
|
function use() {
|
|
101
120
|
return useConstant(() => {
|
|
102
121
|
const obj = /* @__PURE__ */ Object.create(null);
|
|
@@ -108,19 +127,12 @@ function createSplittingContext(defaultValue) {
|
|
|
108
127
|
return Object.freeze(obj);
|
|
109
128
|
});
|
|
110
129
|
}
|
|
130
|
+
use.whyDidYouRender = true;
|
|
111
131
|
return {
|
|
112
132
|
Provider,
|
|
113
133
|
use
|
|
114
134
|
};
|
|
115
135
|
}
|
|
116
|
-
function useSplittingState(initialStates) {
|
|
117
|
-
const states = {};
|
|
118
|
-
for (const key of Object.keys(initialStates)) {
|
|
119
|
-
const state = useState(initialStates[key]);
|
|
120
|
-
Object.assign(states, { [key]: state[0], [`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1] });
|
|
121
|
-
}
|
|
122
|
-
return states;
|
|
123
|
-
}
|
|
124
136
|
function FaasDataWrapper(props) {
|
|
125
137
|
const request = getClient(props.baseUrl).useFaas(
|
|
126
138
|
props.action,
|
|
@@ -153,10 +165,22 @@ function FaasDataWrapper(props) {
|
|
|
153
165
|
]);
|
|
154
166
|
return child;
|
|
155
167
|
}
|
|
168
|
+
FaasDataWrapper.displayName = "FaasDataWrapper";
|
|
156
169
|
FaasDataWrapper.whyDidYouRender = true;
|
|
157
170
|
function withFaasData(Component2, faasProps) {
|
|
158
171
|
return (props) => /* @__PURE__ */ jsx(FaasDataWrapper, { ...faasProps, children: /* @__PURE__ */ jsx(Component2, { ...props }) });
|
|
159
172
|
}
|
|
173
|
+
|
|
174
|
+
// src/faas.ts
|
|
175
|
+
async function faas(action, params, options) {
|
|
176
|
+
const client = getClient(options?.baseUrl);
|
|
177
|
+
if (client.onError)
|
|
178
|
+
return client.browserClient.action(action, params, options).catch(async (res) => {
|
|
179
|
+
await client.onError(action, params)(res);
|
|
180
|
+
return Promise.reject(res);
|
|
181
|
+
});
|
|
182
|
+
return client.browserClient.action(action, params, options);
|
|
183
|
+
}
|
|
160
184
|
function useFaas(action, defaultParams, options = {}) {
|
|
161
185
|
const [loading, setLoading] = useState(true);
|
|
162
186
|
const [data, setData] = useState();
|
|
@@ -255,17 +279,6 @@ function useFaas(action, defaultParams, options = {}) {
|
|
|
255
279
|
};
|
|
256
280
|
}
|
|
257
281
|
useFaas.whyDidYouRender = true;
|
|
258
|
-
|
|
259
|
-
// src/faas.ts
|
|
260
|
-
async function faas(action, params, options) {
|
|
261
|
-
const client = getClient(options?.baseUrl);
|
|
262
|
-
if (client.onError)
|
|
263
|
-
return client.browserClient.action(action, params, options).catch(async (res) => {
|
|
264
|
-
await client.onError(action, params)(res);
|
|
265
|
-
return Promise.reject(res);
|
|
266
|
-
});
|
|
267
|
-
return client.browserClient.action(action, params, options);
|
|
268
|
-
}
|
|
269
282
|
var clients = {};
|
|
270
283
|
function FaasReactClient({ baseUrl, options, onError } = {
|
|
271
284
|
baseUrl: "/"
|
|
@@ -291,6 +304,7 @@ function getClient(host) {
|
|
|
291
304
|
return client;
|
|
292
305
|
}
|
|
293
306
|
var ErrorBoundary = class extends Component {
|
|
307
|
+
static displayName = "ErrorBoundary";
|
|
294
308
|
static whyDidYouRender = true;
|
|
295
309
|
constructor(props) {
|
|
296
310
|
super(props);
|
|
@@ -326,72 +340,156 @@ var ErrorBoundary = class extends Component {
|
|
|
326
340
|
return this.props.children;
|
|
327
341
|
}
|
|
328
342
|
};
|
|
329
|
-
ErrorBoundary.whyDidYouRender = true;
|
|
330
343
|
var OptionalWrapper = ({ condition, Wrapper, wrapperProps, children }) => {
|
|
331
344
|
return condition ? /* @__PURE__ */ jsx(Wrapper, { ...wrapperProps, children }) : /* @__PURE__ */ jsx(Fragment, { children });
|
|
332
345
|
};
|
|
346
|
+
OptionalWrapper.displayName = "OptionalWrapper";
|
|
333
347
|
OptionalWrapper.whyDidYouRender = true;
|
|
334
348
|
|
|
335
349
|
// src/Form/context.tsx
|
|
336
|
-
var FormContext = createSplittingContext([
|
|
350
|
+
var FormContext = createSplittingContext([
|
|
351
|
+
"items",
|
|
352
|
+
"onSubmit",
|
|
353
|
+
"Elements",
|
|
354
|
+
"lang",
|
|
355
|
+
"submitting",
|
|
356
|
+
"setSubmitting",
|
|
357
|
+
"values",
|
|
358
|
+
"setValues",
|
|
359
|
+
"errors",
|
|
360
|
+
"setErrors",
|
|
361
|
+
"rules"
|
|
362
|
+
]);
|
|
337
363
|
var FormContextProvider = FormContext.Provider;
|
|
338
364
|
var useFormContext = FormContext.use;
|
|
339
|
-
function
|
|
340
|
-
const { Elements } = useFormContext();
|
|
341
|
-
|
|
342
|
-
|
|
365
|
+
function FormItem(props) {
|
|
366
|
+
const { Elements, values, setValues, errors } = useFormContext();
|
|
367
|
+
const Label = props.label?.Label ?? Elements.Label;
|
|
368
|
+
const Input = props.input?.Input ?? Elements.Input;
|
|
369
|
+
return /* @__PURE__ */ jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsx(
|
|
370
|
+
Input,
|
|
371
|
+
{
|
|
372
|
+
name: props.name,
|
|
373
|
+
value: values[props.name],
|
|
374
|
+
onChange: (v) => setValues((prev) => ({
|
|
375
|
+
...prev,
|
|
376
|
+
[props.name]: v
|
|
377
|
+
}))
|
|
378
|
+
}
|
|
379
|
+
) });
|
|
343
380
|
}
|
|
381
|
+
FormItem.displayName = "FormItem";
|
|
382
|
+
FormItem.whyDidYouRender = true;
|
|
344
383
|
function FormBody() {
|
|
345
384
|
const { items } = useFormContext();
|
|
346
|
-
return items.map((item) => /* @__PURE__ */ jsx(
|
|
385
|
+
return items.map((item) => /* @__PURE__ */ jsx(FormItem, { ...item }, item.name));
|
|
347
386
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
value
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
FormInputElement,
|
|
372
|
-
{
|
|
373
|
-
name,
|
|
374
|
-
value: values[name],
|
|
375
|
-
onChange: (v) => setValues((prev) => ({
|
|
376
|
-
...prev,
|
|
377
|
-
[name]: v
|
|
378
|
-
}))
|
|
379
|
-
}
|
|
380
|
-
),
|
|
381
|
-
description
|
|
382
|
-
] });
|
|
387
|
+
FormBody.displayName = "FormBody";
|
|
388
|
+
FormBody.whyDidYouRender = true;
|
|
389
|
+
|
|
390
|
+
// src/Form/rules.ts
|
|
391
|
+
var FormDefaultRules = {
|
|
392
|
+
required: async (value, _, lang) => {
|
|
393
|
+
if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
|
|
394
|
+
throw Error(lang?.required);
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
type: async (value, options, lang) => {
|
|
398
|
+
switch (options) {
|
|
399
|
+
case "string":
|
|
400
|
+
if (typeof value !== "string") throw Error(lang?.string);
|
|
401
|
+
break;
|
|
402
|
+
case "number":
|
|
403
|
+
if (Number.isNaN(Number(value))) throw Error(lang?.number);
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
custom: async (value, options) => {
|
|
408
|
+
return options(value);
|
|
409
|
+
}
|
|
383
410
|
};
|
|
384
|
-
|
|
411
|
+
async function validValues(rules, items, values, lang) {
|
|
412
|
+
const errors = {};
|
|
413
|
+
for (const item of items) {
|
|
414
|
+
const value = values[item.name];
|
|
415
|
+
const rulesOptions = item.rules;
|
|
416
|
+
if (rulesOptions) {
|
|
417
|
+
for (const [name, options] of Object.entries(rulesOptions)) {
|
|
418
|
+
try {
|
|
419
|
+
await rules[name](value, options, lang);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
errors[item.name] = error;
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return errors;
|
|
428
|
+
}
|
|
429
|
+
function FormFooter() {
|
|
430
|
+
const {
|
|
431
|
+
submitting,
|
|
432
|
+
setSubmitting,
|
|
433
|
+
onSubmit,
|
|
434
|
+
values,
|
|
435
|
+
Elements,
|
|
436
|
+
items,
|
|
437
|
+
setErrors,
|
|
438
|
+
lang,
|
|
439
|
+
rules
|
|
440
|
+
} = useFormContext();
|
|
441
|
+
return /* @__PURE__ */ jsx(
|
|
442
|
+
Elements.Button,
|
|
443
|
+
{
|
|
444
|
+
disabled: submitting,
|
|
445
|
+
submit: async () => {
|
|
446
|
+
setSubmitting(true);
|
|
447
|
+
const errors = await validValues(rules, items, values, lang);
|
|
448
|
+
if (Object.keys(errors).length) {
|
|
449
|
+
setErrors(errors);
|
|
450
|
+
setSubmitting(false);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
onSubmit(values).finally(() => setSubmitting(false));
|
|
454
|
+
},
|
|
455
|
+
children: lang.submit
|
|
456
|
+
}
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
FormFooter.displayName = "FormFooter";
|
|
460
|
+
FormFooter.whyDidYouRender = true;
|
|
461
|
+
var FormButtonElement = forwardRef(({ disabled, children, submit, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
385
462
|
"button",
|
|
386
463
|
{
|
|
387
464
|
type: "button",
|
|
388
465
|
disabled,
|
|
389
|
-
onClick,
|
|
466
|
+
onClick: submit,
|
|
390
467
|
...props,
|
|
391
468
|
ref,
|
|
392
469
|
children
|
|
393
470
|
}
|
|
394
471
|
));
|
|
472
|
+
FormButtonElement.displayName = "FormButtonElement";
|
|
473
|
+
FormButtonElement.whyDidYouRender = true;
|
|
474
|
+
var FormInputElement = forwardRef(({ onChange, ...props }, ref) => /* @__PURE__ */ jsx("input", { ...props, onChange: (e) => onChange(e.target.value), ref }));
|
|
475
|
+
FormInputElement.displayName = "FormInputElement";
|
|
476
|
+
FormInputElement.whyDidYouRender = true;
|
|
477
|
+
var FormLabelElement = ({
|
|
478
|
+
name,
|
|
479
|
+
title,
|
|
480
|
+
description,
|
|
481
|
+
error,
|
|
482
|
+
children
|
|
483
|
+
}) => {
|
|
484
|
+
return /* @__PURE__ */ jsxs("label", { children: [
|
|
485
|
+
title ?? name,
|
|
486
|
+
children,
|
|
487
|
+
description,
|
|
488
|
+
error && /* @__PURE__ */ jsx("div", { style: { color: "red" }, children: error.message })
|
|
489
|
+
] });
|
|
490
|
+
};
|
|
491
|
+
FormLabelElement.displayName = "FormLabelElement";
|
|
492
|
+
FormLabelElement.whyDidYouRender = true;
|
|
395
493
|
|
|
396
494
|
// src/Form/elements/index.ts
|
|
397
495
|
var FormDefaultElements = {
|
|
@@ -399,39 +497,43 @@ var FormDefaultElements = {
|
|
|
399
497
|
Input: FormInputElement,
|
|
400
498
|
Button: FormButtonElement
|
|
401
499
|
};
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
onSubmit(values).finally(() => setSubmitting(false));
|
|
411
|
-
},
|
|
412
|
-
children: "Submit"
|
|
413
|
-
}
|
|
414
|
-
);
|
|
415
|
-
}
|
|
500
|
+
|
|
501
|
+
// src/Form/lang.ts
|
|
502
|
+
var FormDefaultLang = {
|
|
503
|
+
submit: "Submit",
|
|
504
|
+
required: "This field is required",
|
|
505
|
+
string: "This field must be a string",
|
|
506
|
+
number: "This field must be a number"
|
|
507
|
+
};
|
|
416
508
|
function mergeValues(items, defaultValues = {}) {
|
|
417
509
|
const values = {};
|
|
418
510
|
for (const item of items)
|
|
419
511
|
values[item.name] = defaultValues[item.name] ?? "";
|
|
420
512
|
return values;
|
|
421
513
|
}
|
|
422
|
-
function FormContainer({
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
514
|
+
function FormContainer({
|
|
515
|
+
defaultValues,
|
|
516
|
+
Elements,
|
|
517
|
+
rules,
|
|
518
|
+
lang,
|
|
519
|
+
...props
|
|
520
|
+
}) {
|
|
428
521
|
return /* @__PURE__ */ jsxs(
|
|
429
522
|
FormContextProvider,
|
|
430
523
|
{
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
524
|
+
initializeStates: {
|
|
525
|
+
values: mergeValues(props.items, defaultValues),
|
|
526
|
+
errors: {},
|
|
527
|
+
submitting: false,
|
|
528
|
+
Elements: Object.assign(
|
|
529
|
+
FormDefaultElements,
|
|
530
|
+
Elements
|
|
531
|
+
),
|
|
532
|
+
lang: Object.assign(FormDefaultLang, lang),
|
|
533
|
+
rules: Object.assign(FormDefaultRules, rules)
|
|
434
534
|
},
|
|
535
|
+
value: props,
|
|
536
|
+
memo: true,
|
|
435
537
|
children: [
|
|
436
538
|
/* @__PURE__ */ jsx(FormBody, {}),
|
|
437
539
|
/* @__PURE__ */ jsx(FormFooter, {})
|
|
@@ -439,5 +541,7 @@ function FormContainer({ defaultValues, elements, ...props }) {
|
|
|
439
541
|
}
|
|
440
542
|
);
|
|
441
543
|
}
|
|
544
|
+
FormContainer.displayName = "FormContainer";
|
|
545
|
+
FormContainer.whyDidYouRender = true;
|
|
442
546
|
|
|
443
|
-
export { ErrorBoundary, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, OptionalWrapper, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFormContext, useSplittingState, withFaasData };
|
|
547
|
+
export { ErrorBoundary, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, FormDefaultLang, FormDefaultRules, FormItem, OptionalWrapper, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFormContext, usePrevious, useSplittingState, validValues, withFaasData };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faasjs/react",
|
|
3
|
-
"version": "3.7.0-beta.
|
|
3
|
+
"version": "3.7.0-beta.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"dist"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@faasjs/browser": "3.7.0-beta.
|
|
37
|
+
"@faasjs/browser": "3.7.0-beta.10"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@faasjs/browser": "3.7.0-beta.
|
|
40
|
+
"@faasjs/browser": "3.7.0-beta.10",
|
|
41
41
|
"@types/react": "*",
|
|
42
42
|
"react": "*"
|
|
43
43
|
},
|