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