@kirill.konshin/react 0.0.1 → 0.0.3

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/.ctirc CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
- "addNewline": true,
3
- "fileExcludePatterns": [
4
- "*.stories.*",
5
- "*.test.*",
6
- "*.fixture.*"
7
- ],
8
- "verbose": false,
9
- "withoutBackupFile": true,
10
- "withoutComment": true
11
- }
2
+ "options": [
3
+ {
4
+ "mode": "create",
5
+ "project": "tsconfig.json",
6
+ "include": "src/**/*.{ts,tsx}",
7
+ "exclude": [
8
+ "**/*.stories.*",
9
+ "**/*.test.*",
10
+ "**/*.fixture.*"
11
+ ],
12
+ "startFrom": "src",
13
+ "backup": false,
14
+ "overwrite": true,
15
+ "generationStyle": "default-alias-named-star",
16
+ "output": "src",
17
+ "verbose": true
18
+ }
19
+ ]
20
+ }
@@ -1,44 +1,25 @@
1
1
  vite v7.0.6 building SSR bundle for production...
2
- create succeeded: /home/runner/work/utils/utils/packages/react/src
2
+ - ctix 'create' mode start, ...
3
+ ✔ /home/runner/work/utils/utils/packages/react/tsconfig.json loading complete!
4
+ ✔ analysis export statements completed!
5
+ - build "index.ts" file start
6
+ - output file exists check, ...
7
+
8
+
9
+ ✔ ctix 'create' mode complete!
3
10
  transforming...
4
11
  ✓ 8 modules transformed.
5
12
  rendering chunks...
6
13
 
7
14
  [vite:dts] Start generate declaration files...
8
- src/form/form.tsx:1:10 - error TS2724: '"zod"' has no exported member named 'typeToFlattenedError'. Did you mean 'ZodFlattenedError'?
9
-
10
- 1 import { typeToFlattenedError, z, SafeParseReturnType, TypeOf } from 'zod';
11
-    ~~~~~~~~~~~~~~~~~~~~
12
- src/form/form.tsx:1:35 - error TS2614: Module '"zod"' has no exported member 'SafeParseReturnType'. Did you mean to use 'import SafeParseReturnType from "zod"' instead?
13
-
14
- 1 import { typeToFlattenedError, z, SafeParseReturnType, TypeOf } from 'zod';
15
-    ~~~~~~~~~~~~~~~~~~~
16
- src/form/form.tsx:7:61 - error TS2769: No overload matches this call.
17
- Overload 1 of 2, '(params?: string | { error?: string | $ZodErrorMap<$ZodIssueInvalidType<unknown>> | undefined; message?: string | undefined; } | undefined): ZodString', gave the following error.
18
- Object literal may only specify known properties, and 'required_error' does not exist in type '{ error?: string | $ZodErrorMap<$ZodIssueInvalidType<unknown>> | undefined; message?: string | undefined; }'.
19
- Overload 2 of 2, '(params?: string | { error?: string | $ZodErrorMap<$ZodIssueInvalidType<unknown>> | undefined; message?: string | undefined; } | undefined): $ZodType<...>', gave the following error.
20
- Object literal may only specify known properties, and 'required_error' does not exist in type '{ error?: string | $ZodErrorMap<$ZodIssueInvalidType<unknown>> | undefined; message?: string | undefined; }'.
21
-
22
- 7 export const stringRequired = (): z.ZodString => z.string({ required_error: nonEmpty }).min(1, nonEmpty);
23
-    ~~~~~~~~~~~~~~
24
-
25
- src/form/form.tsx:12:46 - error TS2694: Namespace '"/home/runner/work/utils/utils/node_modules/zod/v4/classic/external"' has no exported member 'ZodEffects'.
26
-
27
- 12 export type ZodObject = z.ZodObject<any> | z.ZodEffects<z.ZodObject<any>>; // z.ZodType<any, any, any>
28
-    ~~~~~~~~~~
29
- src/form/form.tsx:43:56 - error TS2694: Namespace '"/home/runner/work/utils/utils/node_modules/zod/v4/classic/external"' has no exported member 'ZodEffects'.
30
-
31
- 43 (schema as z.ZodObject<any>).shape || (schema as z.ZodEffects<z.ZodObject<any>>).sourceType().shape;
32
-    ~~~~~~~~~~
33
-
34
- dist/useFetch.js 0.57 kB │ map: 1.69 kB
35
15
  dist/index.js 0.67 kB │ map: 0.10 kB
36
16
  dist/apiCall.js 0.69 kB │ map: 1.45 kB
37
17
  dist/useFetcher.js 1.18 kB │ map: 2.62 kB
38
- dist/keyboard.js 1.24 kB │ map: 2.61 kB
18
+ dist/keyboard.js 1.27 kB │ map: 2.81 kB
39
19
  dist/form/client.js 1.58 kB │ map: 3.88 kB
40
- dist/form/form.js 2.87 kB │ map: 7.95 kB
41
- [vite:dts] Declaration files built in 1680ms.
20
+ dist/useFetch.js 2.04 kB │ map: 5.62 kB
21
+ dist/form/form.js 2.89 kB map: 7.94 kB
22
+ [vite:dts] Declaration files built in 2092ms.
42
23
 
43
- ✓ built in 2.40s
24
+ ✓ built in 6.76s
44
25
  Updated package.json with exports
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # @kirill.konshin/react
2
+
3
+ ## 0.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Minor fixes
8
+
9
+ ## 0.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - 63fdba8: Agent-assisted refactoring
14
+ - 63fdba8: Divided core to browser/node/worker-specific packages, CTIX upgrade, etc.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # `useFetch`
2
+
3
+ ```tsx
4
+ import { useEffect } from 'react';
5
+ import { useFetch } from '@kirill.konshin/react';
6
+
7
+ const [data, actionFn, isPending, error] = useFetch(async (args) => {
8
+ return callToBackend(args);
9
+ }, defaultValue);
10
+
11
+ useEffect(() => {
12
+ actionFn({ id: 1 });
13
+ }, []);
14
+ ```
15
+
16
+ ```tsx
17
+ import { useEffect } from 'react';
18
+ import { useFetch } from '@kirill.konshin/react';
19
+
20
+ const dataRef = useRef(data);
21
+
22
+ const [data, actionFn, isPending, error] = useFetch(async (args) => {
23
+ const data = await callToBackend(args);
24
+ return [...dataRef.current, data];
25
+ }, defaultValue);
26
+
27
+ useEffect(() => {
28
+ dataRef.current = value;
29
+ }, [data]);
30
+
31
+ useEffect(async () => {
32
+ await actionFn({ id: 1 });
33
+ await actionFn({ id: 2 });
34
+ await actionFn({ id: 3 });
35
+ }, []);
36
+ ```
37
+
38
+ ```tsx
39
+ import { useEffect } from 'react';
40
+ import { useFetch } from '@kirill.konshin/react';
41
+
42
+ const [data, actionFn, isPending, error] = useFetch(
43
+ // first function has to be synchronous, second can be async
44
+ (args) => async (oldData) => {
45
+ const data = await callToBackend(args);
46
+ return [...oldData, data];
47
+ },
48
+ defaultValue,
49
+ );
50
+
51
+ useEffect(async () => {
52
+ await actionFn({ id: 1 });
53
+ await actionFn({ id: 2 });
54
+ await actionFn({ id: 3 });
55
+ }, []);
56
+ ```
@@ -1,13 +1,13 @@
1
- import { typeToFlattenedError, z, SafeParseReturnType, TypeOf } from 'zod';
1
+ import { z } from 'zod';
2
2
  import { Context, FC } from 'react';
3
3
  export declare const stringRequired: () => z.ZodString;
4
4
  export declare const maxLength: (schema: z.ZodString) => number;
5
5
  export declare const minLength: (schema: z.ZodString) => number;
6
6
  export declare const isRequired: (schema: z.ZodString) => boolean;
7
- export type ZodObject = z.ZodObject<any> | z.ZodEffects<z.ZodObject<any>>;
8
- export type MaybeTypeOf<S extends ZodObject> = Partial<TypeOf<S>>;
9
- export type SafeTypeOf<S extends ZodObject> = SafeParseReturnType<TypeOf<S>, TypeOf<S>>['data'];
10
- export type Errors<S extends ZodObject> = typeToFlattenedError<TypeOf<S>>['fieldErrors'];
7
+ export type ZodObject = z.ZodObject<any> | z.ZodPipe<any, any>;
8
+ export type MaybeTypeOf<S extends ZodObject> = Partial<z.output<S>>;
9
+ export type SafeTypeOf<S extends ZodObject> = z.core.util.SafeParseResult<z.output<S>>['data'];
10
+ export type Errors<S extends ZodObject> = z.core.$ZodFlattenedError<z.output<S>>['fieldErrors'];
11
11
  export type Validation<S extends ZodObject> = {
12
12
  success: true;
13
13
  data: SafeTypeOf<S>;
@@ -26,23 +26,23 @@ export interface FormProps<S extends ZodObject> {
26
26
  }
27
27
  export declare const Form: FC<FormProps<any>>;
28
28
  export declare function create<S extends ZodObject>(schema: S): {
29
- register: (name: keyof TypeOf<S>, data?: MaybeTypeOf<S>, errors?: Errors<S>, mui?: boolean) => {
29
+ register: (name: keyof z.output<S>, data?: MaybeTypeOf<S>, errors?: Errors<S>, mui?: boolean) => {
30
30
  label?: any;
31
31
  helperText?: string;
32
32
  error?: boolean;
33
- name: keyof z.TypeOf<S>;
34
- id: keyof z.TypeOf<S>;
33
+ name: keyof z.output<S>;
34
+ id: keyof z.output<S>;
35
35
  required: boolean;
36
36
  maxLength: number;
37
37
  type: string;
38
- defaultValue?: Partial<z.TypeOf<S>>[keyof z.TypeOf<S>];
38
+ defaultValue?: Partial<z.output<S>>[keyof z.output<S>];
39
39
  };
40
40
  validate: (formData: FormData) => Validation<S>;
41
41
  validationError: (data: MaybeTypeOf<S>, errors: Errors<S>) => Validation<S>;
42
42
  };
43
43
  interface FieldProps<S extends ZodObject> {
44
44
  children?: any;
45
- name: keyof TypeOf<S>;
45
+ name: keyof z.output<S>;
46
46
  errors?: Validation<S>['errors'];
47
47
  hint?: string;
48
48
  className?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/form/form.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/form/form.tsx"],"names":[],"mappings":"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"}
package/dist/form/form.js CHANGED
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  import { createContext, memo, useMemo, useContext } from "react";
4
4
  import clsx from "clsx";
5
5
  const nonEmpty = "This field cannot be empty";
6
- const stringRequired = () => z.string({ required_error: nonEmpty }).min(1, nonEmpty);
6
+ const stringRequired = () => z.string({ error: nonEmpty }).min(1, { error: nonEmpty });
7
7
  const maxLength = (schema) => schema.maxLength || 0;
8
8
  const minLength = (schema) => schema.minLength || 0;
9
9
  const isRequired = (schema) => minLength(schema) > 0;
@@ -12,7 +12,7 @@ const Form = memo(function Form2({ schema, children }) {
12
12
  const value = useMemo(() => ({ schema }), [schema]);
13
13
  return /* @__PURE__ */ jsx(FormContext.Provider, { value, children });
14
14
  });
15
- const getShape = (schema) => schema.shape || schema.sourceType().shape;
15
+ const getShape = (schema) => schema.shape || schema.in.shape;
16
16
  function create(schema) {
17
17
  if (!getShape(schema)) {
18
18
  throw new Error("Invalid schema: only z.object() or z.object().refine() are supported");
@@ -44,11 +44,11 @@ function create(schema) {
44
44
  }
45
45
  function validate(formData) {
46
46
  const rawData = Object.fromEntries(formData);
47
- const { error, data } = schema.safeParse(rawData);
48
- if (error) {
49
- return validationError(rawData, error.flatten().fieldErrors);
47
+ const result = schema.safeParse(rawData);
48
+ if (!result.success) {
49
+ return validationError(rawData, z.flattenError(result.error).fieldErrors);
50
50
  }
51
- return { success: true, data };
51
+ return { success: true, data: result.data };
52
52
  }
53
53
  return { register, validate, validationError };
54
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","sources":["../../src/form/form.tsx"],"sourcesContent":["import { typeToFlattenedError, z, SafeParseReturnType, TypeOf } from 'zod';\nimport { Context, createContext, useContext, useMemo, JSX, FC, memo } from 'react';\nimport clsx from 'clsx';\n\nconst nonEmpty = 'This field cannot be empty';\n\nexport const stringRequired = (): z.ZodString => z.string({ required_error: nonEmpty }).min(1, nonEmpty);\nexport const maxLength = (schema: z.ZodString): number => schema.maxLength || 0;\nexport const minLength = (schema: z.ZodString): number => schema.minLength || 0;\nexport const isRequired = (schema: z.ZodString): boolean => minLength(schema) > 0;\n\nexport type ZodObject = z.ZodObject<any> | z.ZodEffects<z.ZodObject<any>>; // z.ZodType<any, any, any>\nexport type MaybeTypeOf<S extends ZodObject> = Partial<TypeOf<S>>;\nexport type SafeTypeOf<S extends ZodObject> = SafeParseReturnType<TypeOf<S>, TypeOf<S>>['data'];\nexport type Errors<S extends ZodObject> = typeToFlattenedError<TypeOf<S>>['fieldErrors'];\nexport type Validation<S extends ZodObject> =\n | {\n success: true; // this is true only if form was validated successfully\n data: SafeTypeOf<S>;\n errors?: never;\n }\n | {\n success: false;\n data?: MaybeTypeOf<S>;\n errors?: Errors<S>;\n };\n\nexport const FormContext: Context<{\n schema: ZodObject;\n}> = createContext(null as never);\n\nexport interface FormProps<S extends ZodObject> {\n schema: S;\n children: any;\n}\n\nexport const Form: FC<FormProps<any>> = memo(function Form({ schema, children }) {\n const value = useMemo(() => ({ schema }), [schema]);\n return <FormContext.Provider value={value}>{children}</FormContext.Provider>;\n});\n\nconst getShape = <S extends ZodObject>(schema: S) =>\n (schema as z.ZodObject<any>).shape || (schema as z.ZodEffects<z.ZodObject<any>>).sourceType().shape;\n\nexport function create<S extends ZodObject>(\n schema: S,\n): {\n register: (\n name: keyof TypeOf<S>,\n data?: MaybeTypeOf<S>,\n errors?: Errors<S>,\n mui?: boolean,\n ) => {\n label?: any;\n helperText?: string;\n error?: boolean;\n name: keyof z.TypeOf<S>;\n id: keyof z.TypeOf<S>;\n required: boolean;\n maxLength: number;\n type: string;\n defaultValue?: Partial<z.TypeOf<S>>[keyof z.TypeOf<S>];\n };\n validate: (formData: FormData) => Validation<S>;\n validationError: (data: MaybeTypeOf<S>, errors: Errors<S>) => Validation<S>;\n} {\n if (!getShape(schema)) {\n throw new Error('Invalid schema: only z.object() or z.object().refine() are supported');\n }\n\n function register(\n name: keyof TypeOf<S>,\n data?: MaybeTypeOf<S>,\n errors?: Errors<S>,\n mui: boolean = false,\n ): {\n label?: any;\n helperText?: string;\n error?: boolean;\n name: keyof z.TypeOf<S>;\n id: keyof z.TypeOf<S>;\n required: boolean;\n maxLength: number;\n type: string;\n defaultValue?: Partial<z.TypeOf<S>>[keyof z.TypeOf<S>];\n } {\n const field = getShape(schema)[name];\n return {\n name,\n id: name,\n required: isRequired(field),\n maxLength: maxLength(field),\n type: field.isEmail ? 'email' : (name as string).includes('password') ? 'password' : 'text',\n defaultValue: data?.[name],\n ...(mui\n ? {\n label: field.description,\n helperText: errors?.[name]?.join(', '),\n error: !!errors?.[name]?.length,\n }\n : {}),\n };\n }\n\n function validationError(data: MaybeTypeOf<S>, errors: Errors<S>): Validation<S> {\n return {\n success: false,\n data, // data is undefined if there are errors\n errors, // Next.js will butcher error object, so we provide something more primitive\n };\n }\n\n function validate(formData: FormData): Validation<S> {\n const rawData = Object.fromEntries(formData) as TypeOf<S>;\n const { error, data } = schema.safeParse(rawData);\n\n // console.log('Validate result', { error, data, rawData });\n\n if (error) {\n // data is undefined if there are errors\n // Next.js will butcher error object, so we provide something more primitive\n return validationError(rawData, error.flatten().fieldErrors as any);\n }\n\n return { success: true, data };\n }\n\n return { register, validate, validationError };\n}\n\ninterface FieldProps<S extends ZodObject> {\n children?: any;\n name: keyof TypeOf<S>;\n errors?: Validation<S>['errors'];\n hint?: string;\n className?: string;\n labelProps?: any;\n [key: string]: any;\n}\n\nexport const Field: FC<FieldProps<any>> = memo(function Field({\n children,\n name,\n errors,\n hint,\n className,\n labelProps,\n ...props\n}) {\n const { schema } = useContext(FormContext);\n const { description } = getShape(schema)[name];\n\n return (\n <div {...props} className={clsx('form-row', className)}>\n {description && (\n <label {...labelProps} htmlFor={name}>\n {description}\n </label>\n )}\n {children}\n {hint && <Hint>{hint}</Hint>}\n {errors?.[name]?.map((e: string) => (\n <Hint error key={e}>\n {e}\n </Hint>\n ))}\n </div>\n );\n});\n\nexport interface HintProps {\n children: any;\n error?: boolean;\n}\n\nexport const Hint: FC<HintProps> = memo(function Hint({ children, error }) {\n return <div className={`hint ${error ? 'hint-error' : ''}`}>{children}</div>;\n});\n"],"names":["Form","Field","Hint"],"mappings":";;;;AAIA,MAAM,WAAW;AAEV,MAAM,iBAAiB,MAAmB,EAAE,OAAO,EAAE,gBAAgB,UAAU,EAAE,IAAI,GAAG,QAAQ;AAChG,MAAM,YAAY,CAAC,WAAgC,OAAO,aAAa;AACvE,MAAM,YAAY,CAAC,WAAgC,OAAO,aAAa;AACvE,MAAM,aAAa,CAAC,WAAiC,UAAU,MAAM,IAAI;AAkBzE,MAAM,cAER,cAAc,IAAa;AAOzB,MAAM,OAA2B,KAAK,SAASA,MAAK,EAAE,QAAQ,YAAY;AAC7E,QAAM,QAAQ,QAAQ,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;AAClD,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,SAAA,CAAS;AACzD,CAAC;AAED,MAAM,WAAW,CAAsB,WAClC,OAA4B,SAAU,OAA0C,aAAa;AAE3F,SAAS,OACZ,QAoBF;AACE,MAAI,CAAC,SAAS,MAAM,GAAG;AACnB,UAAM,IAAI,MAAM,sEAAsE;AAAA,EAC1F;AAEA,WAAS,SACL,MACA,MACA,QACA,MAAe,OAWjB;AACE,UAAM,QAAQ,SAAS,MAAM,EAAE,IAAI;AACnC,WAAO;AAAA,MACH;AAAA,MACA,IAAI;AAAA,MACJ,UAAU,WAAW,KAAK;AAAA,MAC1B,WAAW,UAAU,KAAK;AAAA,MAC1B,MAAM,MAAM,UAAU,UAAW,KAAgB,SAAS,UAAU,IAAI,aAAa;AAAA,MACrF,cAAc,OAAO,IAAI;AAAA,MACzB,GAAI,MACE;AAAA,QACI,OAAO,MAAM;AAAA,QACb,YAAY,SAAS,IAAI,GAAG,KAAK,IAAI;AAAA,QACrC,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG;AAAA,MAAA,IAE7B,CAAA;AAAA,IAAC;AAAA,EAEf;AAEA,WAAS,gBAAgB,MAAsB,QAAkC;AAC7E,WAAO;AAAA,MACH,SAAS;AAAA,MACT;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EAER;AAEA,WAAS,SAAS,UAAmC;AACjD,UAAM,UAAU,OAAO,YAAY,QAAQ;AAC3C,UAAM,EAAE,OAAO,KAAA,IAAS,OAAO,UAAU,OAAO;AAIhD,QAAI,OAAO;AAGP,aAAO,gBAAgB,SAAS,MAAM,QAAA,EAAU,WAAkB;AAAA,IACtE;AAEA,WAAO,EAAE,SAAS,MAAM,KAAA;AAAA,EAC5B;AAEA,SAAO,EAAE,UAAU,UAAU,gBAAA;AACjC;AAYO,MAAM,QAA6B,KAAK,SAASC,OAAM;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAG;AACC,QAAM,EAAE,OAAA,IAAW,WAAW,WAAW;AACzC,QAAM,EAAE,YAAA,IAAgB,SAAS,MAAM,EAAE,IAAI;AAE7C,SACI,qBAAC,SAAK,GAAG,OAAO,WAAW,KAAK,YAAY,SAAS,GAChD,UAAA;AAAA,IAAA,mCACI,SAAA,EAAO,GAAG,YAAY,SAAS,MAC3B,UAAA,aACL;AAAA,IAEH;AAAA,IACA,QAAQ,oBAAC,MAAA,EAAM,UAAA,KAAA,CAAK;AAAA,IACpB,SAAS,IAAI,GAAG,IAAI,CAAC,MAClB,oBAAC,MAAA,EAAK,OAAK,MACN,UAAA,EAAA,GADY,CAEjB,CACH;AAAA,EAAA,GACL;AAER,CAAC;AAOM,MAAM,OAAsB,KAAK,SAASC,MAAK,EAAE,UAAU,SAAS;AACvE,SAAO,oBAAC,SAAI,WAAW,QAAQ,QAAQ,eAAe,EAAE,IAAK,SAAA,CAAS;AAC1E,CAAC;"}
1
+ {"version":3,"file":"form.js","sources":["../../src/form/form.tsx"],"sourcesContent":["import { z } from 'zod';\nimport { Context, createContext, useContext, useMemo, JSX, FC, memo } from 'react';\nimport clsx from 'clsx';\n\nconst nonEmpty = 'This field cannot be empty';\n\nexport const stringRequired = (): z.ZodString => z.string({ error: nonEmpty }).min(1, { error: nonEmpty });\nexport const maxLength = (schema: z.ZodString): number => schema.maxLength || 0;\nexport const minLength = (schema: z.ZodString): number => schema.minLength || 0;\nexport const isRequired = (schema: z.ZodString): boolean => minLength(schema) > 0;\n\nexport type ZodObject = z.ZodObject<any> | z.ZodPipe<any, any>; // z.ZodType<any, any, any>\nexport type MaybeTypeOf<S extends ZodObject> = Partial<z.output<S>>;\nexport type SafeTypeOf<S extends ZodObject> = z.core.util.SafeParseResult<z.output<S>>['data'];\nexport type Errors<S extends ZodObject> = z.core.$ZodFlattenedError<z.output<S>>['fieldErrors'];\nexport type Validation<S extends ZodObject> =\n | {\n success: true; // this is true only if form was validated successfully\n data: SafeTypeOf<S>;\n errors?: never;\n }\n | {\n success: false;\n data?: MaybeTypeOf<S>;\n errors?: Errors<S>;\n };\n\nexport const FormContext: Context<{\n schema: ZodObject;\n}> = createContext(null as never);\n\nexport interface FormProps<S extends ZodObject> {\n schema: S;\n children: any;\n}\n\nexport const Form: FC<FormProps<any>> = memo(function Form({ schema, children }) {\n const value = useMemo(() => ({ schema }), [schema]);\n return <FormContext.Provider value={value}>{children}</FormContext.Provider>;\n});\n\nconst getShape = <S extends ZodObject>(schema: S) =>\n (schema as z.ZodObject<any>).shape || (schema as z.ZodPipe<any, any>).in.shape;\n\nexport function create<S extends ZodObject>(\n schema: S,\n): {\n register: (\n name: keyof z.output<S>,\n data?: MaybeTypeOf<S>,\n errors?: Errors<S>,\n mui?: boolean,\n ) => {\n label?: any;\n helperText?: string;\n error?: boolean;\n name: keyof z.output<S>;\n id: keyof z.output<S>;\n required: boolean;\n maxLength: number;\n type: string;\n defaultValue?: Partial<z.output<S>>[keyof z.output<S>];\n };\n validate: (formData: FormData) => Validation<S>;\n validationError: (data: MaybeTypeOf<S>, errors: Errors<S>) => Validation<S>;\n} {\n if (!getShape(schema)) {\n throw new Error('Invalid schema: only z.object() or z.object().refine() are supported');\n }\n\n function register(\n name: keyof z.output<S>,\n data?: MaybeTypeOf<S>,\n errors?: Errors<S>,\n mui: boolean = false,\n ): {\n label?: any;\n helperText?: string;\n error?: boolean;\n name: keyof z.output<S>;\n id: keyof z.output<S>;\n required: boolean;\n maxLength: number;\n type: string;\n defaultValue?: Partial<z.output<S>>[keyof z.output<S>];\n } {\n const field = getShape(schema)[name];\n return {\n name,\n id: name,\n required: isRequired(field),\n maxLength: maxLength(field),\n type: field.isEmail ? 'email' : (name as string).includes('password') ? 'password' : 'text',\n defaultValue: data?.[name],\n ...(mui\n ? {\n label: field.description,\n helperText: errors?.[name]?.join(', '),\n error: !!errors?.[name]?.length,\n }\n : {}),\n };\n }\n\n function validationError(data: MaybeTypeOf<S>, errors: Errors<S>): Validation<S> {\n return {\n success: false,\n data, // data is undefined if there are errors\n errors, // Next.js will butcher error object, so we provide something more primitive\n };\n }\n\n function validate(formData: FormData): Validation<S> {\n const rawData = Object.fromEntries(formData) as z.output<S>;\n const result = schema.safeParse(rawData);\n\n // console.log('Validate result', { error, data, rawData });\n\n if (!result.success) {\n // data is undefined if there are errors\n // Next.js will butcher error object, so we provide something more primitive\n return validationError(rawData, z.flattenError(result.error).fieldErrors as any);\n }\n\n return { success: true, data: result.data };\n }\n\n return { register, validate, validationError };\n}\n\ninterface FieldProps<S extends ZodObject> {\n children?: any;\n name: keyof z.output<S>;\n errors?: Validation<S>['errors'];\n hint?: string;\n className?: string;\n labelProps?: any;\n [key: string]: any;\n}\n\nexport const Field: FC<FieldProps<any>> = memo(function Field({\n children,\n name,\n errors,\n hint,\n className,\n labelProps,\n ...props\n}) {\n const { schema } = useContext(FormContext);\n const { description } = getShape(schema)[name];\n\n return (\n <div {...props} className={clsx('form-row', className)}>\n {description && (\n <label {...labelProps} htmlFor={name}>\n {description}\n </label>\n )}\n {children}\n {hint && <Hint>{hint}</Hint>}\n {errors?.[name as any]?.map((e: string) => (\n <Hint error key={e}>\n {e}\n </Hint>\n ))}\n </div>\n );\n});\n\nexport interface HintProps {\n children: any;\n error?: boolean;\n}\n\nexport const Hint: FC<HintProps> = memo(function Hint({ children, error }) {\n return <div className={`hint ${error ? 'hint-error' : ''}`}>{children}</div>;\n});\n"],"names":["Form","Field","Hint"],"mappings":";;;;AAIA,MAAM,WAAW;AAEV,MAAM,iBAAiB,MAAmB,EAAE,OAAO,EAAE,OAAO,UAAU,EAAE,IAAI,GAAG,EAAE,OAAO,UAAU;AAClG,MAAM,YAAY,CAAC,WAAgC,OAAO,aAAa;AACvE,MAAM,YAAY,CAAC,WAAgC,OAAO,aAAa;AACvE,MAAM,aAAa,CAAC,WAAiC,UAAU,MAAM,IAAI;AAkBzE,MAAM,cAER,cAAc,IAAa;AAOzB,MAAM,OAA2B,KAAK,SAASA,MAAK,EAAE,QAAQ,YAAY;AAC7E,QAAM,QAAQ,QAAQ,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;AAClD,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,SAAA,CAAS;AACzD,CAAC;AAED,MAAM,WAAW,CAAsB,WAClC,OAA4B,SAAU,OAA+B,GAAG;AAEtE,SAAS,OACZ,QAoBF;AACE,MAAI,CAAC,SAAS,MAAM,GAAG;AACnB,UAAM,IAAI,MAAM,sEAAsE;AAAA,EAC1F;AAEA,WAAS,SACL,MACA,MACA,QACA,MAAe,OAWjB;AACE,UAAM,QAAQ,SAAS,MAAM,EAAE,IAAI;AACnC,WAAO;AAAA,MACH;AAAA,MACA,IAAI;AAAA,MACJ,UAAU,WAAW,KAAK;AAAA,MAC1B,WAAW,UAAU,KAAK;AAAA,MAC1B,MAAM,MAAM,UAAU,UAAW,KAAgB,SAAS,UAAU,IAAI,aAAa;AAAA,MACrF,cAAc,OAAO,IAAI;AAAA,MACzB,GAAI,MACE;AAAA,QACI,OAAO,MAAM;AAAA,QACb,YAAY,SAAS,IAAI,GAAG,KAAK,IAAI;AAAA,QACrC,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG;AAAA,MAAA,IAE7B,CAAA;AAAA,IAAC;AAAA,EAEf;AAEA,WAAS,gBAAgB,MAAsB,QAAkC;AAC7E,WAAO;AAAA,MACH,SAAS;AAAA,MACT;AAAA;AAAA,MACA;AAAA;AAAA,IAAA;AAAA,EAER;AAEA,WAAS,SAAS,UAAmC;AACjD,UAAM,UAAU,OAAO,YAAY,QAAQ;AAC3C,UAAM,SAAS,OAAO,UAAU,OAAO;AAIvC,QAAI,CAAC,OAAO,SAAS;AAGjB,aAAO,gBAAgB,SAAS,EAAE,aAAa,OAAO,KAAK,EAAE,WAAkB;AAAA,IACnF;AAEA,WAAO,EAAE,SAAS,MAAM,MAAM,OAAO,KAAA;AAAA,EACzC;AAEA,SAAO,EAAE,UAAU,UAAU,gBAAA;AACjC;AAYO,MAAM,QAA6B,KAAK,SAASC,OAAM;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAG;AACC,QAAM,EAAE,OAAA,IAAW,WAAW,WAAW;AACzC,QAAM,EAAE,YAAA,IAAgB,SAAS,MAAM,EAAE,IAAI;AAE7C,SACI,qBAAC,SAAK,GAAG,OAAO,WAAW,KAAK,YAAY,SAAS,GAChD,UAAA;AAAA,IAAA,mCACI,SAAA,EAAO,GAAG,YAAY,SAAS,MAC3B,UAAA,aACL;AAAA,IAEH;AAAA,IACA,QAAQ,oBAAC,MAAA,EAAM,UAAA,KAAA,CAAK;AAAA,IACpB,SAAS,IAAW,GAAG,IAAI,CAAC,MACzB,oBAAC,MAAA,EAAK,OAAK,MACN,UAAA,EAAA,GADY,CAEjB,CACH;AAAA,EAAA,GACL;AAER,CAAC;AAOM,MAAM,OAAsB,KAAK,SAASC,MAAK,EAAE,UAAU,SAAS;AACvE,SAAO,oBAAC,SAAI,WAAW,QAAQ,QAAQ,eAAe,EAAE,IAAK,SAAA,CAAS;AAC1E,CAAC;"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export * from './form';
2
1
  export * from './apiCall';
3
2
  export * from './keyboard';
4
3
  export * from './useFetch';
5
4
  export * from './useFetcher';
5
+ export * from './form';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createClient } from "./form/client.js";
2
- import { Field, Form, FormContext, Hint, create, isRequired, maxLength, minLength, stringRequired } from "./form/form.js";
3
1
  import { apiCall, jsonContentType } from "./apiCall.js";
4
2
  import { HotkeysContext, HotkeysProvider, useHotkeys } from "./keyboard.js";
5
3
  import { useFetch } from "./useFetch.js";
6
4
  import { useFetcher } from "./useFetcher.js";
5
+ import { createClient } from "./form/client.js";
6
+ import { Field, Form, FormContext, Hint, create, isRequired, maxLength, minLength, stringRequired } from "./form/form.js";
7
7
  export {
8
8
  Field,
9
9
  Form,
@@ -5,6 +5,9 @@ export type HotkeyContextType = {
5
5
  setEnabled: Dispatch<SetStateAction<boolean>>;
6
6
  };
7
7
  export declare const HotkeysContext: Context<HotkeyContextType>;
8
- export declare const HotkeysProvider: FC<any>;
8
+ export type HotkeysProviderProps = {
9
+ children: any;
10
+ };
11
+ export declare const HotkeysProvider: FC<HotkeysProviderProps>;
9
12
  export declare const useHotkeys: (hotkeys: Hotkeys) => void;
10
13
  //# sourceMappingURL=keyboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../src/keyboard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+C,QAAQ,EAAE,cAAc,EAAc,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAMvH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC;AAEhF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,iBAAiB,CAGrC,CAAC;AAElB,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,GAAG,CAMnC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,OAAO,KAAG,IA6B7C,CAAC"}
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../src/keyboard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKH,QAAQ,EACR,cAAc,EAEd,EAAE,EAEF,OAAO,EACV,MAAM,OAAO,CAAC;AAMf,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC;AAEhF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,iBAAiB,CAGrC,CAAC;AAElB,MAAM,MAAM,oBAAoB,GAAG;IAC/B,QAAQ,EAAE,GAAG,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAMnD,CAAC;AAEH,eAAO,MAAM,UAAU,GAAI,SAAS,OAAO,KAAG,IA6B7C,CAAC"}
package/dist/keyboard.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { createContext, useState, useMemo, useContext, useEffect } from "react";
3
+ import { createContext, memo, useState, useMemo, useContext, useEffect } from "react";
4
4
  const isCtrlOrMeta = (e) => e.metaKey || e.ctrlKey;
5
5
  const EVENT = "keydown";
6
6
  const HotkeysContext = createContext(null);
7
- const HotkeysProvider = ({ children }) => {
7
+ const HotkeysProvider = memo(function HotkeysProvider2({ children }) {
8
8
  const [enabled, setEnabled] = useState(true);
9
9
  const control = useMemo(() => ({ enabled, setEnabled }), [enabled, setEnabled]);
10
10
  return /* @__PURE__ */ jsx(HotkeysContext.Provider, { value: control, children });
11
- };
11
+ });
12
12
  const useHotkeys = (hotkeys) => {
13
13
  const { enabled } = useContext(HotkeysContext);
14
14
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard.js","sources":["../src/keyboard.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, createContext, useMemo, useState, Dispatch, SetStateAction, useContext, FC, Context } from 'react';\n\nconst isCtrlOrMeta = (e: KeyboardEvent) => e.metaKey || e.ctrlKey;\n\nconst EVENT = 'keydown';\n\nexport type Hotkeys = Record<KeyboardEvent['code'], (e: KeyboardEvent) => void>;\n\nexport type HotkeyContextType = {\n enabled: boolean;\n setEnabled: Dispatch<SetStateAction<boolean>>;\n};\n\nexport const HotkeysContext: Context<HotkeyContextType> = createContext<{\n enabled: boolean;\n setEnabled: Dispatch<SetStateAction<boolean>>;\n}>(null as never);\n\nexport const HotkeysProvider: FC<any> = ({ children }) => {\n const [enabled, setEnabled] = useState(true);\n\n const control = useMemo(() => ({ enabled, setEnabled }), [enabled, setEnabled]);\n\n return <HotkeysContext.Provider value={control}>{children}</HotkeysContext.Provider>;\n};\n\nexport const useHotkeys = (hotkeys: Hotkeys): void => {\n const { enabled } = useContext(HotkeysContext);\n\n useEffect(() => {\n if (typeof document === 'undefined' || !enabled) {\n return;\n }\n\n const ctrl = new AbortController();\n\n window.addEventListener(\n EVENT,\n (e: KeyboardEvent) => {\n if (!isCtrlOrMeta(e)) return;\n\n for (const [code, callback] of Object.entries(hotkeys)) {\n if (e.code === code) {\n callback(e);\n return;\n }\n }\n },\n { signal: ctrl.signal, capture: true },\n );\n\n return () => {\n ctrl.abort();\n };\n }, [hotkeys, enabled]);\n};\n"],"names":[],"mappings":";;;AAIA,MAAM,eAAe,CAAC,MAAqB,EAAE,WAAW,EAAE;AAE1D,MAAM,QAAQ;AASP,MAAM,iBAA6C,cAGvD,IAAa;AAET,MAAM,kBAA2B,CAAC,EAAE,eAAe;AACtD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAE3C,QAAM,UAAU,QAAQ,OAAO,EAAE,SAAS,eAAe,CAAC,SAAS,UAAU,CAAC;AAE9E,6BAAQ,eAAe,UAAf,EAAwB,OAAO,SAAU,UAAS;AAC9D;AAEO,MAAM,aAAa,CAAC,YAA2B;AAClD,QAAM,EAAE,QAAA,IAAY,WAAW,cAAc;AAE7C,YAAU,MAAM;AACZ,QAAI,OAAO,aAAa,eAAe,CAAC,SAAS;AAC7C;AAAA,IACJ;AAEA,UAAM,OAAO,IAAI,gBAAA;AAEjB,WAAO;AAAA,MACH;AAAA,MACA,CAAC,MAAqB;AAClB,YAAI,CAAC,aAAa,CAAC,EAAG;AAEtB,mBAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,cAAI,EAAE,SAAS,MAAM;AACjB,qBAAS,CAAC;AACV;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,MACA,EAAE,QAAQ,KAAK,QAAQ,SAAS,KAAA;AAAA,IAAK;AAGzC,WAAO,MAAM;AACT,WAAK,MAAA;AAAA,IACT;AAAA,EACJ,GAAG,CAAC,SAAS,OAAO,CAAC;AACzB;"}
1
+ {"version":3,"file":"keyboard.js","sources":["../src/keyboard.tsx"],"sourcesContent":["'use client';\n\nimport {\n useEffect,\n createContext,\n useMemo,\n useState,\n Dispatch,\n SetStateAction,\n useContext,\n FC,\n memo,\n Context,\n} from 'react';\n\nconst isCtrlOrMeta = (e: KeyboardEvent) => e.metaKey || e.ctrlKey;\n\nconst EVENT = 'keydown';\n\nexport type Hotkeys = Record<KeyboardEvent['code'], (e: KeyboardEvent) => void>;\n\nexport type HotkeyContextType = {\n enabled: boolean;\n setEnabled: Dispatch<SetStateAction<boolean>>;\n};\n\nexport const HotkeysContext: Context<HotkeyContextType> = createContext<{\n enabled: boolean;\n setEnabled: Dispatch<SetStateAction<boolean>>;\n}>(null as never);\n\nexport type HotkeysProviderProps = {\n children: any;\n};\n\nexport const HotkeysProvider: FC<HotkeysProviderProps> = memo(function HotkeysProvider({ children }) {\n const [enabled, setEnabled] = useState(true);\n\n const control = useMemo(() => ({ enabled, setEnabled }), [enabled, setEnabled]);\n\n return <HotkeysContext.Provider value={control}>{children}</HotkeysContext.Provider>;\n});\n\nexport const useHotkeys = (hotkeys: Hotkeys): void => {\n const { enabled } = useContext(HotkeysContext);\n\n useEffect(() => {\n if (typeof document === 'undefined' || !enabled) {\n return;\n }\n\n const ctrl = new AbortController();\n\n window.addEventListener(\n EVENT,\n (e: KeyboardEvent) => {\n if (!isCtrlOrMeta(e)) return;\n\n for (const [code, callback] of Object.entries(hotkeys)) {\n if (e.code === code) {\n callback(e);\n return;\n }\n }\n },\n { signal: ctrl.signal, capture: true },\n );\n\n return () => {\n ctrl.abort();\n };\n }, [hotkeys, enabled]);\n};\n"],"names":["HotkeysProvider"],"mappings":";;;AAeA,MAAM,eAAe,CAAC,MAAqB,EAAE,WAAW,EAAE;AAE1D,MAAM,QAAQ;AASP,MAAM,iBAA6C,cAGvD,IAAa;AAMT,MAAM,kBAA4C,KAAK,SAASA,iBAAgB,EAAE,YAAY;AACjG,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAE3C,QAAM,UAAU,QAAQ,OAAO,EAAE,SAAS,eAAe,CAAC,SAAS,UAAU,CAAC;AAE9E,6BAAQ,eAAe,UAAf,EAAwB,OAAO,SAAU,UAAS;AAC9D,CAAC;AAEM,MAAM,aAAa,CAAC,YAA2B;AAClD,QAAM,EAAE,QAAA,IAAY,WAAW,cAAc;AAE7C,YAAU,MAAM;AACZ,QAAI,OAAO,aAAa,eAAe,CAAC,SAAS;AAC7C;AAAA,IACJ;AAEA,UAAM,OAAO,IAAI,gBAAA;AAEjB,WAAO;AAAA,MACH;AAAA,MACA,CAAC,MAAqB;AAClB,YAAI,CAAC,aAAa,CAAC,EAAG;AAEtB,mBAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,cAAI,EAAE,SAAS,MAAM;AACjB,qBAAS,CAAC;AACV;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,MACA,EAAE,QAAQ,KAAK,QAAQ,SAAS,KAAA;AAAA,IAAK;AAGzC,WAAO,MAAM;AACT,WAAK,MAAA;AAAA,IACT;AAAA,EACJ,GAAG,CAAC,SAAS,OAAO,CAAC;AACzB;"}
@@ -1,2 +1,29 @@
1
- export declare function useFetch<R>(fn: (...args: any[]) => Promise<R>, defaultValue?: R | null): [R | null, typeof fn, boolean, Error | undefined];
1
+ /**
2
+ * TODO useFetch https://use-http.com
3
+ * TODO SWR?
4
+ * TODO Tanstack Query?
5
+ *
6
+ * Uses same return array patterns as useActionState https://react.dev/reference/react/useActionState + error,
7
+ * reason: simple var rename
8
+ *
9
+ * Function can be async, then it will be awaited and result set to state.
10
+ *
11
+ * Function can be sync, then it will be called args, and it should return another function,which will be called with
12
+ * old data and result set to state. This is useful for pagination and merging data.
13
+ *
14
+ * @param {(...args: any[]) => Promise<R> | R | ((oldData: R) => Promise<R> | R))} fn
15
+ * @param {any} defaultValue
16
+ * @param fetchOnMount
17
+ * @param throwAfterUnmount - throw if component is unmounted after fetch completed
18
+ * @returns {[R, (...args: any[]) => Promise<R>, boolean, Error | undefined]} //, ReturnType<typeof useState>, ReturnType<typeof useState>
19
+ */
20
+ export declare function useFetch<R>(fn: (...args: any[]) => Promise<R> | R | ((oldData: R) => Promise<R> | R), defaultValue: R, { fetchOnMount, throwAfterUnmount, }?: {
21
+ fetchOnMount?: boolean;
22
+ throwAfterUnmount?: boolean;
23
+ }): [
24
+ R,
25
+ (...args: Parameters<typeof fn>) => Promise<R>,
26
+ boolean,
27
+ Error | undefined
28
+ ];
2
29
  //# sourceMappingURL=useFetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFetch.d.ts","sourceRoot":"","sources":["../src/useFetch.ts"],"names":[],"mappings":"AAOA,wBAAgB,QAAQ,CAAC,CAAC,EACtB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,YAAY,GAAE,CAAC,GAAG,IAAW,GAC9B,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,GAAG,SAAS,CAAC,CAkBnD"}
1
+ {"version":3,"file":"useFetch.d.ts","sourceRoot":"","sources":["../src/useFetch.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACtB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACzE,YAAY,EAAE,CAAC,EACf,EACI,YAAoB,EACpB,iBAAyB,GAC5B,GAAE;IACC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACP;IACC,CAAC;IACD,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IAC9C,OAAO;IACP,KAAK,GAAG,SAAS;CAGpB,CAkEA"}
package/dist/useFetch.js CHANGED
@@ -1,18 +1,64 @@
1
1
  "use client";
2
- import { useTransition, useState, useCallback } from "react";
3
- function useFetch(fn, defaultValue = null) {
2
+ import { useTransition, useState, useRef, useCallback, useEffect } from "react";
3
+ const unmountError = "Component is unmounted after fetch completed";
4
+ function useFetch(fn, defaultValue, {
5
+ fetchOnMount = false,
6
+ throwAfterUnmount = false
7
+ } = {}) {
4
8
  const [isPending, startTransition] = useTransition();
5
9
  const [data, setData] = useState(defaultValue);
6
10
  const [error, setError] = useState();
11
+ const [loading, setLoading] = useState(fetchOnMount);
12
+ const isMounted = useRef(false);
13
+ const oldData = useRef(data);
14
+ const throwAfterUnmountRef = useRef(throwAfterUnmount);
7
15
  const actionFn = useCallback(
8
16
  (...args) => {
9
- const promise = fn(...args);
10
- startTransition(() => promise.then(setData).catch(setError));
17
+ const res = fn(...args);
18
+ const promise = typeof res === "function" ? res(oldData.current) : res;
19
+ startTransition(async () => {
20
+ try {
21
+ const newData = await promise;
22
+ if (!isMounted.current) {
23
+ if (throwAfterUnmountRef.current) throw new Error(unmountError);
24
+ return;
25
+ }
26
+ oldData.current = newData;
27
+ setData(newData);
28
+ setError(void 0);
29
+ } catch (e) {
30
+ if (!isMounted.current) {
31
+ if (throwAfterUnmountRef.current) {
32
+ if (e.message !== unmountError) throw new Error("Component is unmounted", { cause: e });
33
+ else throw e;
34
+ }
35
+ return;
36
+ }
37
+ setError(e);
38
+ } finally {
39
+ if (isMounted.current) {
40
+ setLoading(false);
41
+ }
42
+ }
43
+ });
11
44
  return promise;
12
45
  },
13
46
  [fn]
14
47
  );
15
- return [data, actionFn, isPending, error];
48
+ useEffect(() => {
49
+ if (!fetchOnMount) return;
50
+ actionFn().catch((e) => console.error("Fetch on mount failed", e));
51
+ }, [fetchOnMount, fn, actionFn]);
52
+ useEffect(() => {
53
+ throwAfterUnmountRef.current = throwAfterUnmount;
54
+ }, [throwAfterUnmount]);
55
+ useEffect(() => {
56
+ isMounted.current = true;
57
+ return () => {
58
+ isMounted.current = false;
59
+ };
60
+ });
61
+ return [data, actionFn, isPending || loading, error];
16
62
  }
17
63
  export {
18
64
  useFetch
@@ -1 +1 @@
1
- {"version":3,"file":"useFetch.js","sources":["../src/useFetch.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useState, useTransition } from 'react';\n\n//TODO useFetch https://use-http.com\n//TODO SWR?\n//TODO Tanstack Query?\nexport function useFetch<R>(\n fn: (...args: any[]) => Promise<R>,\n defaultValue: R | null = null,\n): [R | null, typeof fn, boolean, Error | undefined] {\n // An async function was passed to useActionState, but it was dispatched outside of an action context.\n // This is likely not what you intended. Either pass the dispatch function to an `action` prop, or dispatch manually inside `startTransition`\n const [isPending, startTransition] = useTransition();\n const [data, setData] = useState<R | null>(defaultValue);\n const [error, setError] = useState<Error>();\n\n const actionFn = useCallback(\n (...args: Parameters<typeof fn>) => {\n const promise = fn(...args);\n // https://react.dev/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition\n startTransition(() => promise.then(setData).catch(setError)); //FIXME sub-chain...\n return promise;\n },\n [fn],\n );\n\n return [data, actionFn, isPending, error];\n}\n"],"names":[],"mappings":";;AAOO,SAAS,SACZ,IACA,eAAyB,MACwB;AAGjD,QAAM,CAAC,WAAW,eAAe,IAAI,cAAA;AACrC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAmB,YAAY;AACvD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAA;AAE1B,QAAM,WAAW;AAAA,IACb,IAAI,SAAgC;AAChC,YAAM,UAAU,GAAG,GAAG,IAAI;AAE1B,sBAAgB,MAAM,QAAQ,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC3D,aAAO;AAAA,IACX;AAAA,IACA,CAAC,EAAE;AAAA,EAAA;AAGP,SAAO,CAAC,MAAM,UAAU,WAAW,KAAK;AAC5C;"}
1
+ {"version":3,"file":"useFetch.js","sources":["../src/useFetch.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef, useState, useTransition } from 'react';\n\nconst unmountError = 'Component is unmounted after fetch completed';\n\n/**\n * TODO useFetch https://use-http.com\n * TODO SWR?\n * TODO Tanstack Query?\n *\n * Uses same return array patterns as useActionState https://react.dev/reference/react/useActionState + error,\n * reason: simple var rename\n *\n * Function can be async, then it will be awaited and result set to state.\n *\n * Function can be sync, then it will be called args, and it should return another function,which will be called with\n * old data and result set to state. This is useful for pagination and merging data.\n *\n * @param {(...args: any[]) => Promise<R> | R | ((oldData: R) => Promise<R> | R))} fn\n * @param {any} defaultValue\n * @param fetchOnMount\n * @param throwAfterUnmount - throw if component is unmounted after fetch completed\n * @returns {[R, (...args: any[]) => Promise<R>, boolean, Error | undefined]} //, ReturnType<typeof useState>, ReturnType<typeof useState>\n */\nexport function useFetch<R>(\n fn: (...args: any[]) => Promise<R> | R | ((oldData: R) => Promise<R> | R),\n defaultValue: R,\n {\n fetchOnMount = false,\n throwAfterUnmount = false,\n }: {\n fetchOnMount?: boolean;\n throwAfterUnmount?: boolean;\n } = {},\n): [\n R,\n (...args: Parameters<typeof fn>) => Promise<R>,\n boolean,\n Error | undefined,\n // ReturnType<typeof useState<R>>[1],\n // ReturnType<typeof useState<Error>>[1],\n] {\n // An async function was passed to useActionState, but it was dispatched outside of an action context.\n // This is likely not what you intended. Either pass the dispatch function to an `action` prop, or dispatch manually inside `startTransition`\n const [isPending, startTransition] = useTransition();\n const [data, setData] = useState<R>(defaultValue);\n const [error, setError] = useState<Error>();\n const [loading, setLoading] = useState(fetchOnMount);\n const isMounted = useRef(false);\n const oldData = useRef(data);\n const throwAfterUnmountRef = useRef(throwAfterUnmount);\n\n const actionFn = useCallback(\n (...args: Parameters<typeof fn>) => {\n const res = fn(...args);\n\n const promise: Promise<R> = typeof res === 'function' ? (res as any)(oldData.current) : (res as Promise<R>);\n\n // https://react.dev/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition\n startTransition(async () => {\n try {\n const newData = await promise;\n if (!isMounted.current) {\n if (throwAfterUnmountRef.current) throw new Error(unmountError);\n return;\n }\n oldData.current = newData;\n setData(newData);\n setError(undefined);\n } catch (e) {\n if (!isMounted.current) {\n if (throwAfterUnmountRef.current) {\n if (e.message !== unmountError) throw new Error('Component is unmounted', { cause: e });\n else throw e;\n }\n return;\n }\n setError(e);\n } finally {\n if (isMounted.current) {\n setLoading(false);\n }\n }\n });\n\n return promise;\n },\n [fn],\n );\n\n useEffect(() => {\n if (!fetchOnMount) return;\n actionFn().catch((e) => console.error('Fetch on mount failed', e)); // catch actually will never happen\n }, [fetchOnMount, fn, actionFn]);\n\n useEffect(() => {\n throwAfterUnmountRef.current = throwAfterUnmount;\n }, [throwAfterUnmount]);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n });\n\n return [data, actionFn, isPending || loading, error]; // , setData, setError\n}\n"],"names":[],"mappings":";;AAIA,MAAM,eAAe;AAqBd,SAAS,SACZ,IACA,cACA;AAAA,EACI,eAAe;AAAA,EACf,oBAAoB;AACxB,IAGI,IAQN;AAGE,QAAM,CAAC,WAAW,eAAe,IAAI,cAAA;AACrC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAY,YAAY;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAA;AAC1B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,YAAY;AACnD,QAAM,YAAY,OAAO,KAAK;AAC9B,QAAM,UAAU,OAAO,IAAI;AAC3B,QAAM,uBAAuB,OAAO,iBAAiB;AAErD,QAAM,WAAW;AAAA,IACb,IAAI,SAAgC;AAChC,YAAM,MAAM,GAAG,GAAG,IAAI;AAEtB,YAAM,UAAsB,OAAO,QAAQ,aAAc,IAAY,QAAQ,OAAO,IAAK;AAGzF,sBAAgB,YAAY;AACxB,YAAI;AACA,gBAAM,UAAU,MAAM;AACtB,cAAI,CAAC,UAAU,SAAS;AACpB,gBAAI,qBAAqB,QAAS,OAAM,IAAI,MAAM,YAAY;AAC9D;AAAA,UACJ;AACA,kBAAQ,UAAU;AAClB,kBAAQ,OAAO;AACf,mBAAS,MAAS;AAAA,QACtB,SAAS,GAAG;AACR,cAAI,CAAC,UAAU,SAAS;AACpB,gBAAI,qBAAqB,SAAS;AAC9B,kBAAI,EAAE,YAAY,aAAc,OAAM,IAAI,MAAM,0BAA0B,EAAE,OAAO,GAAG;AAAA,kBACjF,OAAM;AAAA,YACf;AACA;AAAA,UACJ;AACA,mBAAS,CAAC;AAAA,QACd,UAAA;AACI,cAAI,UAAU,SAAS;AACnB,uBAAW,KAAK;AAAA,UACpB;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,aAAO;AAAA,IACX;AAAA,IACA,CAAC,EAAE;AAAA,EAAA;AAGP,YAAU,MAAM;AACZ,QAAI,CAAC,aAAc;AACnB,aAAA,EAAW,MAAM,CAAC,MAAM,QAAQ,MAAM,yBAAyB,CAAC,CAAC;AAAA,EACrE,GAAG,CAAC,cAAc,IAAI,QAAQ,CAAC;AAE/B,YAAU,MAAM;AACZ,yBAAqB,UAAU;AAAA,EACnC,GAAG,CAAC,iBAAiB,CAAC;AAEtB,YAAU,MAAM;AACZ,cAAU,UAAU;AACpB,WAAO,MAAM;AACT,gBAAU,UAAU;AAAA,IACxB;AAAA,EACJ,CAAC;AAED,SAAO,CAAC,MAAM,UAAU,aAAa,SAAS,KAAK;AACvD;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useFetch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFetch.test.d.ts","sourceRoot":"","sources":["../src/useFetch.test.tsx"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@kirill.konshin/react",
3
3
  "description": "Utilities",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "----- BUILD -----": "",
8
8
  "clean": "rm -rf dist .tscache tsconfig.tsbuildinfo",
9
9
  "build": "vite build",
10
- "build:index": "cti create ./src",
10
+ "build:index": "ctix build",
11
11
  "build:check-types": "attw --pack .",
12
12
  "start": "yarn build --watch",
13
13
  "wait": "wait-on ./dist/index.js",
@@ -24,7 +24,13 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@kirill.konshin/utils-private": "*",
27
- "react": "^19.1.1"
27
+ "@testing-library/dom": "^10.4.1",
28
+ "@testing-library/react": "^16.3.2",
29
+ "@testing-library/react-hooks": "^8.0.1",
30
+ "@types/react-dom": "^19",
31
+ "jsdom": "^29.0.1",
32
+ "react": "^19.1.1",
33
+ "react-dom": "19.1.1"
28
34
  },
29
35
  "peerDependencies": {
30
36
  "react": "^19"
@@ -35,7 +41,8 @@
35
41
  }
36
42
  },
37
43
  "publishConfig": {
38
- "access": "public"
44
+ "access": "public",
45
+ "provenance": true
39
46
  },
40
47
  "author": "Kirill Konshin <kirill@konshin.org> (https://konshin.org)",
41
48
  "license": "MIT",
@@ -55,5 +62,10 @@
55
62
  },
56
63
  "main": "./dist/index.js",
57
64
  "module": "./dist/index.js",
58
- "types": "./dist/index.d.ts"
65
+ "types": "./dist/index.d.ts",
66
+ "repository": {
67
+ "type": "git",
68
+ "url": "https://github.com/kirill-konshin/utils.git",
69
+ "directory": "packages/react"
70
+ }
59
71
  }