cross-state 0.9.0 → 0.9.2

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.
@@ -1,9 +1,79 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { createContext, useMemo, useContext, useState, useRef, useEffect, startTransition } from "react";
3
- import { u as useScope, a as useStore, b as useCache } from "../useCache.mjs";
4
- import { S, r, c } from "../useCache.mjs";
5
- import { b as castArrayPath, g as get, h as deepEqual, i as debounce, t as throttle } from "../store.mjs";
1
+ import { S as ScopeProvider, a as useScope, d as useStore, u as useCache } from "../useCache.mjs";
2
+ import { r, e } from "../useCache.mjs";
3
+ import { useMemo, useState, useEffect, createElement, createContext, useContext, useRef, startTransition } from "react";
4
+ import { b as castArrayPath, g as get, d as deepEqual, e as debounce, t as throttle } from "../store.mjs";
6
5
  import { S as Scope, h as hash } from "../scope.mjs";
6
+ import { jsx, Fragment } from "react/jsx-runtime";
7
+ function FormError({ name }) {
8
+ const { errors, isDirty } = this.useField(name);
9
+ return isDirty ? /* @__PURE__ */ jsx(Fragment, { children: errors.join(", ") }) : null;
10
+ }
11
+ function FormInput({
12
+ id,
13
+ name,
14
+ component = "input",
15
+ commitOnBlur,
16
+ commitDebounce,
17
+ inputFilter,
18
+ serialize = (x) => x,
19
+ deserialize = (x) => x,
20
+ ...restProps
21
+ }) {
22
+ const { value, setValue, errors } = this.useField(name);
23
+ const errorString = useMemo(() => errors.join("\n"), [errors]);
24
+ const [localValue, setLocalValue] = useState();
25
+ const _id = useMemo(
26
+ () => id || `f${Math.random().toString(36).slice(2, 15)}${Math.random().toString(36).slice(2, 15)}`,
27
+ [id]
28
+ );
29
+ useEffect(() => {
30
+ if (localValue === void 0 || !commitDebounce) {
31
+ return;
32
+ }
33
+ const timeout = setTimeout(() => {
34
+ setValue(deserialize(localValue));
35
+ setLocalValue(void 0);
36
+ }, commitDebounce);
37
+ return () => clearTimeout(timeout);
38
+ }, [localValue, commitDebounce]);
39
+ useEffect(() => {
40
+ const element = document.querySelector(
41
+ [`#${_id} input`, `#${_id} select`, `#${_id} textarea`, `#${_id}`].join(",")
42
+ );
43
+ if (!(element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement)) {
44
+ return;
45
+ }
46
+ element.setCustomValidity(errorString);
47
+ }, [_id, errorString]);
48
+ const props = {
49
+ ...restProps,
50
+ id: _id,
51
+ name,
52
+ value: localValue ?? serialize(value),
53
+ onChange: (event, ...moreArgs) => {
54
+ var _a;
55
+ const value2 = typeof event === "object" && event !== null && "target" in event ? event.target.value : event;
56
+ if (inputFilter && !inputFilter(value2)) {
57
+ return;
58
+ }
59
+ if (commitOnBlur || commitDebounce) {
60
+ setLocalValue(value2);
61
+ } else {
62
+ setValue(deserialize(value2));
63
+ }
64
+ (_a = restProps.onChange) == null ? void 0 : _a.call(restProps, event, ...moreArgs);
65
+ },
66
+ onBlur(...args) {
67
+ var _a;
68
+ if (localValue !== void 0) {
69
+ setValue(deserialize(localValue));
70
+ setLocalValue(void 0);
71
+ }
72
+ (_a = restProps.onBlur) == null ? void 0 : _a.call(restProps, ...args);
73
+ }
74
+ };
75
+ return createElement(component, props);
76
+ }
7
77
  function wildcardMatch(s, w) {
8
78
  if (typeof s === "string") {
9
79
  s = castArrayPath(s);
@@ -31,6 +101,21 @@ function getWildCardMatches(object, path) {
31
101
  }
32
102
  return matches;
33
103
  }
104
+ function FormContainer({ form, children }) {
105
+ const { validate } = form.useForm();
106
+ return /* @__PURE__ */ jsx(
107
+ "form",
108
+ {
109
+ noValidate: true,
110
+ onSubmit: (event) => {
111
+ event.preventDefault();
112
+ validate();
113
+ event.currentTarget.reportValidity();
114
+ },
115
+ children
116
+ }
117
+ );
118
+ }
34
119
  class Form {
35
120
  constructor(options) {
36
121
  this.options = options;
@@ -40,31 +125,43 @@ class Form {
40
125
  });
41
126
  this.state = new Scope({});
42
127
  this.Provider = this.Provider.bind(this);
128
+ this.useForm = this.useForm.bind(this);
129
+ this.useField = this.useField.bind(this);
130
+ this.useHasChanges = this.useHasChanges.bind(this);
131
+ this.useIsValid = this.useIsValid.bind(this);
132
+ this.Input = this.Input.bind(this);
133
+ this.Error = this.Error.bind(this);
43
134
  }
44
135
  Provider({
45
136
  children,
46
137
  original,
47
- defaultValue = this.options.defaultValue,
48
- validations = this.options.validations
138
+ defaultValue,
139
+ validations
49
140
  }) {
50
141
  const value = useMemo(
51
- () => ({ original, options: { defaultValue, validations } }),
142
+ () => ({
143
+ original,
144
+ options: {
145
+ defaultValue: { ...this.options.defaultValue, ...defaultValue },
146
+ validations: { ...this.options.validations, ...validations }
147
+ }
148
+ }),
52
149
  [original, defaultValue, validations]
53
150
  );
54
- return /* @__PURE__ */ jsx(this.context.Provider, { value, children: /* @__PURE__ */ jsx(this.state.Provider, { children }) });
151
+ return /* @__PURE__ */ jsx(this.context.Provider, { value, children: /* @__PURE__ */ jsx(ScopeProvider, { scope: this.state, children: /* @__PURE__ */ jsx(FormContainer, { form: this, children }) }) });
55
152
  }
56
153
  useForm() {
57
154
  const { original, options } = useContext(this.context);
58
155
  const state = useScope(this.state);
59
- return useMemo(
60
- () => ({
156
+ return useMemo(() => {
157
+ const instance = {
61
158
  original,
62
159
  draft: state.map(
63
160
  (state2) => state2.draft ?? original ?? options.defaultValue,
64
161
  (draft) => (state2) => ({ ...state2, draft })
65
162
  ),
66
- getField(path) {
67
- const { draft } = this;
163
+ getField: (path) => {
164
+ const { draft } = instance;
68
165
  return {
69
166
  get originalValue() {
70
167
  return original !== void 0 ? get(original, path) : void 0;
@@ -76,31 +173,33 @@ class Form {
76
173
  draft.set(path, update);
77
174
  },
78
175
  get isDirty() {
79
- return state.get().hasTriggeredValidations || !deepEqual(this.originalValue, this.value);
176
+ const comparisonValue = this.originalValue ?? get(options.defaultValue, path);
177
+ return state.get().hasTriggeredValidations || !deepEqual(comparisonValue, this.value);
80
178
  },
81
- get error() {
179
+ get errors() {
82
180
  const blocks = Object.entries(
83
181
  options.validations ?? {}
84
182
  ).filter(([key]) => wildcardMatch(path, key)).map(([, value2]) => value2);
85
183
  const value = this.value;
86
184
  const draftValue = draft.get();
185
+ const errors = [];
87
186
  for (const block of blocks ?? []) {
88
187
  for (const [validationName, validate] of Object.entries(block)) {
89
188
  if (!validate(value, { draft: draftValue, original, field: path })) {
90
- return validationName;
189
+ errors.push(validationName);
91
190
  }
92
191
  }
93
192
  }
94
- return void 0;
193
+ return errors;
95
194
  }
96
195
  };
97
196
  },
98
- hasChanges() {
197
+ get hasChanges() {
99
198
  const { draft } = state.get();
100
- return !!draft && !deepEqual(draft, original);
199
+ return !!draft && !deepEqual(draft, original ?? options.defaultValue);
101
200
  },
102
- getErrors() {
103
- const draft = this.draft.get();
201
+ get errors() {
202
+ const draft = instance.draft.get();
104
203
  const errors = /* @__PURE__ */ new Set();
105
204
  for (const [path, block] of Object.entries(options.validations ?? {})) {
106
205
  for (const [validationName, validate] of Object.entries(
@@ -115,19 +214,19 @@ class Form {
115
214
  }
116
215
  return [...errors];
117
216
  },
118
- isValid() {
119
- return this.getErrors().length === 0;
217
+ get isValid() {
218
+ return instance.errors.length === 0;
120
219
  },
121
- validate() {
220
+ validate: () => {
122
221
  state.set("hasTriggeredValidations", true);
123
- return this.isValid();
222
+ return instance.isValid;
124
223
  },
125
224
  reset() {
126
225
  state.set("draft", void 0);
127
226
  }
128
- }),
129
- [original, options, state]
130
- );
227
+ };
228
+ return instance;
229
+ }, [original, options, state]);
131
230
  }
132
231
  useField(path, useStoreOptions) {
133
232
  const form = this.useForm();
@@ -144,11 +243,17 @@ class Form {
144
243
  }
145
244
  useHasChanges() {
146
245
  const form = this.useForm();
147
- return useStore(form.draft.map(() => form.hasChanges()));
246
+ return useStore(form.draft.map(() => form.hasChanges));
148
247
  }
149
248
  useIsValid() {
150
249
  const form = this.useForm();
151
- return useStore(form.draft.map(() => form.isValid()));
250
+ return useStore(form.draft.map(() => form.isValid));
251
+ }
252
+ Input(props) {
253
+ return Reflect.apply(FormInput, this, [props]);
254
+ }
255
+ Error({ name }) {
256
+ return Reflect.apply(FormError, this, [{ name }]);
152
257
  }
153
258
  }
154
259
  function createForm(options) {
@@ -194,13 +299,13 @@ function useDecoupledState(value, onChange, options = {}) {
194
299
  }
195
300
  export {
196
301
  Form,
197
- S as ScopeProvider,
302
+ ScopeProvider,
198
303
  createForm,
199
304
  r as reactMethods,
200
305
  read,
201
306
  useCache,
202
307
  useDecoupledState,
203
- c as useProp,
308
+ e as useProp,
204
309
  useScope,
205
310
  useStore
206
311
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/lib/wildcardMatch.ts","../../../src/react/form.tsx","../../../src/react/read.ts","../../../src/react/useDecoupledState.ts"],"sourcesContent":["import { type KeyType } from './path';\nimport { castArrayPath } from './propAccess';\n\nexport function wildcardMatch(s: KeyType[] | string, w: KeyType[] | string): boolean {\n if (typeof s === 'string') {\n s = castArrayPath(s);\n }\n\n if (typeof w === 'string') {\n w = castArrayPath(w);\n }\n\n return s.length === w.length && s.every((s, i) => w[i] === '*' || s === w[i]);\n}\n\nexport function getWildCardMatches(object: any, path: KeyType[] | string): Record<KeyType, any> {\n const matches: Record<KeyType, any> = {};\n const [first, ...rest] = castArrayPath(path);\n\n if (first === undefined) {\n return object;\n }\n\n if (!(object instanceof Object)) {\n return {};\n }\n\n if (first === '*') {\n for (const [key, value] of Object.entries(object)) {\n matches[key] = getWildCardMatches(value, rest);\n }\n } else {\n matches[first] = getWildCardMatches(object[first], rest);\n }\n\n return matches;\n}\n","/* eslint-disable react-hooks/rules-of-hooks */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { useScope } from './scope';\nimport { useStore, type UseStoreOptions } from './useStore';\nimport { Scope } from '@core';\nimport { deepEqual } from '@lib/equals';\nimport {\n type PathAsString,\n type Value,\n type WildcardMatch,\n type WildcardPathAsString,\n type WildcardValue,\n} from '@lib/path';\nimport { get } from '@lib/propAccess';\nimport { getWildCardMatches, wildcardMatch } from '@lib/wildcardMatch';\n\nexport interface FormOptions<\n TDraft,\n TOriginal,\n TValidations extends Validations<TDraft, TOriginal>,\n> {\n defaultValue: TDraft;\n validations?: TValidations;\n}\n\nexport type Validation<TValue, TDraft, TOriginal> = (\n value: TValue,\n context: { draft: TDraft; original: TOriginal; field: PathAsString<TDraft> },\n) => boolean;\n\nexport type Validations<TDraft, TOriginal> = {\n [P in WildcardPathAsString<TDraft>]?: Record<\n string,\n Validation<WildcardValue<TDraft, P>, TDraft, TOriginal>\n >;\n};\n\nexport interface Field<\n TDraft,\n TOriginal,\n TPath extends PathAsString<TDraft>,\n TValidations extends Validations<TDraft, TOriginal>,\n> {\n originalValue: Value<TOriginal, TPath> | undefined;\n value: Value<TDraft, TPath>;\n setValue: (\n value: Value<TDraft, TPath> | ((value: Value<TDraft, TPath>) => Value<TDraft, TPath>),\n ) => void;\n isDirty: boolean;\n error?: keyof {\n [P in keyof TValidations as WildcardMatch<TPath, P> extends true\n ? keyof TValidations[P]\n : never]: 1;\n };\n}\n\nexport class Form<\n TDraft,\n TOriginal extends TDraft = TDraft,\n TValidations extends Validations<TDraft, TOriginal> = {},\n> {\n private context = createContext({\n original: undefined as TOriginal | undefined,\n options: this.options,\n });\n\n private state = new Scope<{\n draft?: TDraft;\n hasTriggeredValidations?: boolean;\n }>({});\n\n constructor(public readonly options: FormOptions<TDraft, TOriginal, TValidations>) {\n this.Provider = this.Provider.bind(this);\n }\n\n Provider({\n children,\n original,\n defaultValue = this.options.defaultValue,\n validations = this.options.validations,\n }: { children?: ReactNode; original?: TOriginal } & Partial<\n FormOptions<TDraft, TOriginal, TValidations>\n >) {\n const value = useMemo(\n () => ({ original, options: { defaultValue, validations } }),\n [original, defaultValue, validations],\n );\n\n return (\n <this.context.Provider value={value}>\n <this.state.Provider>{children}</this.state.Provider>\n </this.context.Provider>\n );\n }\n\n useForm() {\n const { original, options } = useContext(this.context);\n const state = useScope(this.state);\n\n return useMemo(\n () => ({\n original,\n\n draft: state.map(\n (state) => state.draft ?? original ?? options.defaultValue,\n (draft) => (state) => ({ ...state, draft }),\n ),\n\n getField<TPath extends PathAsString<TDraft>>(\n path: TPath,\n ): Field<TDraft, TOriginal, TPath, TValidations> {\n const { draft } = this;\n\n return {\n get originalValue() {\n return original !== undefined ? get(original as any, path as any) : undefined;\n },\n\n get value() {\n return get(draft.get(), path);\n },\n\n setValue(update) {\n draft.set(path, update);\n },\n\n get isDirty() {\n return (\n state.get().hasTriggeredValidations || !deepEqual(this.originalValue, this.value)\n );\n },\n\n get error() {\n const blocks: Record<string, Validation<any, any, any>>[] = Object.entries(\n options.validations ?? {},\n )\n .filter(([key]) => wildcardMatch(path, key))\n .map(([, value]) => value);\n\n const value = this.value;\n const draftValue = draft.get();\n\n for (const block of blocks ?? []) {\n for (const [validationName, validate] of Object.entries(block)) {\n if (!validate(value, { draft: draftValue, original, field: path })) {\n return validationName as any;\n }\n }\n }\n\n return undefined;\n },\n };\n },\n\n hasChanges() {\n const { draft } = state.get();\n return !!draft && !deepEqual(draft, original);\n },\n\n getErrors(): (keyof {\n [Field in PathAsString<TDraft> as keyof {\n [Pattern in keyof TValidations as WildcardMatch<Field, Pattern> extends true\n ? `${Field}.${keyof TValidations[Pattern] & string}`\n : never]: 1;\n }]: 1;\n })[] {\n const draft = this.draft.get();\n const errors = new Set<string>();\n\n for (const [path, block] of Object.entries(options.validations ?? {})) {\n for (const [validationName, validate] of Object.entries(\n block as Record<string, Validation<any, any, any>>,\n )) {\n for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {\n if (!validate(value, { draft, original, field })) {\n errors.add(`${field}.${validationName}`);\n }\n }\n }\n }\n\n return [...errors] as any;\n },\n\n isValid() {\n return this.getErrors().length === 0;\n },\n\n validate() {\n state.set('hasTriggeredValidations', true);\n return this.isValid();\n },\n\n reset() {\n state.set('draft', undefined);\n },\n }),\n [original, options, state],\n );\n }\n\n useField<TPath extends PathAsString<TDraft>>(path: TPath, useStoreOptions?: UseStoreOptions) {\n const form = this.useForm();\n const state = useScope(this.state);\n\n useStore(\n form.draft.map((draft) => get(draft, path)),\n useStoreOptions,\n );\n\n useStore(\n state.map((state) => state.hasTriggeredValidations),\n useStoreOptions,\n );\n\n return form.getField(path);\n }\n\n useHasChanges() {\n const form = this.useForm();\n\n return useStore(form.draft.map(() => form.hasChanges()));\n }\n\n useIsValid() {\n const form = this.useForm();\n\n return useStore(form.draft.map(() => form.isValid()));\n }\n}\n\nexport function createForm<\n TDraft,\n TOriginal extends TDraft = TDraft,\n TValidations extends Validations<TDraft, TOriginal> = {},\n>(options: FormOptions<TDraft, TOriginal, TValidations>) {\n return new Form(options);\n}\n\n/* eslint-enable react-hooks/rules-of-hooks */\n","import { useCache } from './useCache';\nimport type { UseStoreOptions } from './useStore';\nimport type { Cache } from '@core';\n\nexport function read<T>(cache: Cache<T>, options?: UseStoreOptions): T {\n const { status, value, error } = useCache(cache, options);\n\n if (status === 'value') {\n return value;\n }\n\n if (status === 'error') {\n throw error;\n }\n\n throw cache.state.once((state) => state.status !== 'pending');\n}\n","import { startTransition, useEffect, useMemo, useRef, useState } from 'react';\nimport { type Duration } from '@core';\nimport { debounce } from '@lib/debounce';\nimport { hash } from '@lib/hash';\nimport { throttle } from '@lib/throttle';\n\nexport interface UseDecoupledStateOptions<T> {\n debounce?: Duration;\n throttle?: Duration;\n onCommit?: (value: T) => void;\n}\n\nexport function useDecoupledState<T>(\n value: T,\n onChange: (value: T) => void,\n options: UseDecoupledStateOptions<T> = {},\n): [state: T, setState: (value: T) => void] {\n const [dirty, setDirty] = useState<{ v: T }>();\n const ref = useRef({ onChange, onCommit: options.onCommit });\n\n useEffect(() => {\n ref.current = { onChange, onCommit: options.onCommit };\n }, [onChange]);\n\n const update = useMemo(() => {\n const { onChange, onCommit } = ref.current;\n\n const update = (value: T) => {\n onChange(value);\n setDirty(undefined);\n onCommit?.(value);\n };\n\n let delayedUpdate: (value: T) => void;\n\n if (options.debounce) {\n delayedUpdate = debounce(update, options.debounce);\n } else if (options.throttle) {\n delayedUpdate = throttle(update, options.throttle);\n } else {\n delayedUpdate = (value) => startTransition(() => update(value));\n }\n\n return (value: T) => {\n setDirty({ v: value });\n delayedUpdate(value);\n };\n }, [hash([options.debounce, options.throttle])]);\n\n return [dirty ? dirty.v : value, update];\n}\n"],"names":["s","state","value","onChange","update"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/react/form/formError.tsx","../../../src/react/form/formInput.tsx","../../../src/lib/wildcardMatch.ts","../../../src/react/form/form.tsx","../../../src/react/read.ts","../../../src/react/useDecoupledState.ts"],"sourcesContent":["import { type Form } from './form';\nimport { type PathAsString } from '@lib/path';\n\nexport type FormErrorProps<TDraft, TPath extends PathAsString<TDraft>> = {\n name: TPath;\n};\n\nexport function FormError<TDraft, TPath extends PathAsString<TDraft>>(\n this: Form<TDraft, any>,\n { name }: FormErrorProps<TDraft, TPath>,\n) {\n const { errors, isDirty } = this.useField(name);\n\n return isDirty ? <>{errors.join(', ')}</> : null;\n}\n","import {\n createElement,\n useEffect,\n useMemo,\n useState,\n type ComponentPropsWithoutRef,\n type ElementType,\n type HTMLProps,\n} from 'react';\nimport { type Form } from './form';\nimport { type PathAsString } from '@index';\nimport { type Value } from '@lib/path';\n\nexport type FormInputComponent<T> = ElementType<{\n id: string;\n value: T;\n onChange: (event: { target: { value: T } } | T | undefined, ...args: any[]) => void;\n onBlur: (...args: any[]) => void;\n}>;\n\ntype InputValue<T extends FormInputComponent<any>> = ComponentPropsWithoutRef<T> extends {\n value: infer U;\n}\n ? U\n : ComponentPropsWithoutRef<T> extends {\n value?: infer U;\n }\n ? U | undefined\n : never;\n\ntype InputChangeValue<T extends FormInputComponent<any>> = ComponentPropsWithoutRef<T> extends {\n onChange?: (update: infer U) => void;\n}\n ? U extends { target: { value: infer V } }\n ? V\n : U\n : never;\n\nexport type FormInputProps<\n TDraft,\n TPath extends PathAsString<TDraft>,\n TComponent extends FormInputComponent<any>,\n> = {\n name: TPath;\n commitOnBlur?: boolean;\n commitDebounce?: number;\n inputFilter?: (value: InputChangeValue<TComponent>) => boolean;\n onChange?: ComponentPropsWithoutRef<TComponent>['onChange'];\n onBlur?: ComponentPropsWithoutRef<TComponent>['onBlur'];\n} & (TComponent extends 'input' | ((props: HTMLProps<HTMLInputElement>) => JSX.Element)\n ? { component?: TComponent }\n : { component: TComponent }) &\n Omit<\n ComponentPropsWithoutRef<TComponent>,\n | 'form'\n | 'name'\n | 'component'\n | 'commitOnBlur'\n | 'commitDebounce'\n | 'value'\n | 'onChange'\n | 'onBlur'\n > &\n (Value<TDraft, TPath> extends InputValue<TComponent>\n ? { serialize?: (value: Value<TDraft, TPath>) => InputValue<TComponent> }\n : { serialize: (value: Value<TDraft, TPath>) => InputValue<TComponent> }) &\n (InputChangeValue<TComponent> extends Value<TDraft, TPath>\n ? { deserialize?: (value: InputChangeValue<TComponent>) => Value<TDraft, TPath> }\n : { deserialize: (value: InputChangeValue<TComponent>) => Value<TDraft, TPath> });\n\nexport function FormInput<\n TDraft,\n TPath extends PathAsString<TDraft>,\n TComponent extends FormInputComponent<any>,\n>(\n this: Form<TDraft, any>,\n {\n id,\n name,\n component = 'input' as TComponent,\n commitOnBlur,\n commitDebounce,\n inputFilter,\n serialize = (x) => x as InputValue<TComponent>,\n deserialize = (x) => x as Value<TDraft, TPath>,\n ...restProps\n }: FormInputProps<TDraft, TPath, TComponent>,\n): JSX.Element {\n type T = InputChangeValue<TComponent>;\n\n const { value, setValue, errors } = this.useField(name);\n const errorString = useMemo(() => errors.join('\\n'), [errors]);\n const [localValue, setLocalValue] = useState<T>();\n const _id = useMemo(\n () =>\n id || `f${Math.random().toString(36).slice(2, 15)}${Math.random().toString(36).slice(2, 15)}`,\n\n [id],\n );\n\n useEffect(() => {\n if (localValue === undefined || !commitDebounce) {\n return;\n }\n\n const timeout = setTimeout(() => {\n setValue(deserialize(localValue));\n setLocalValue(undefined);\n }, commitDebounce);\n\n return () => clearTimeout(timeout);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [localValue, commitDebounce]);\n\n useEffect(() => {\n const element = document.querySelector(\n [`#${_id} input`, `#${_id} select`, `#${_id} textarea`, `#${_id}`].join(','),\n );\n\n if (\n !(\n element instanceof HTMLInputElement ||\n element instanceof HTMLSelectElement ||\n element instanceof HTMLTextAreaElement\n )\n ) {\n return;\n }\n\n element.setCustomValidity(errorString);\n }, [_id, errorString]);\n\n const props = {\n ...restProps,\n id: _id,\n name,\n value: localValue ?? serialize(value),\n onChange: (event: { target: { value: T } } | T, ...moreArgs: any[]) => {\n const value =\n typeof event === 'object' && event !== null && 'target' in event\n ? event.target.value\n : event;\n\n if (inputFilter && !inputFilter(value)) {\n return;\n }\n\n if (commitOnBlur || commitDebounce) {\n setLocalValue(value);\n } else {\n setValue(deserialize(value));\n }\n\n restProps.onChange?.(event, ...moreArgs);\n },\n onBlur(...args: any[]) {\n if (localValue !== undefined) {\n setValue(deserialize(localValue));\n setLocalValue(undefined);\n }\n\n restProps.onBlur?.(...(args as [any]));\n },\n };\n\n return createElement(component, props as any);\n}\n","import { type KeyType } from './path';\nimport { castArrayPath } from './propAccess';\n\nexport function wildcardMatch(s: KeyType[] | string, w: KeyType[] | string): boolean {\n if (typeof s === 'string') {\n s = castArrayPath(s);\n }\n\n if (typeof w === 'string') {\n w = castArrayPath(w);\n }\n\n return s.length === w.length && s.every((s, i) => w[i] === '*' || s === w[i]);\n}\n\nexport function getWildCardMatches(object: any, path: KeyType[] | string): Record<KeyType, any> {\n const matches: Record<KeyType, any> = {};\n const [first, ...rest] = castArrayPath(path);\n\n if (first === undefined) {\n return object;\n }\n\n if (!(object instanceof Object)) {\n return {};\n }\n\n if (first === '*') {\n for (const [key, value] of Object.entries(object)) {\n matches[key] = getWildCardMatches(value, rest);\n }\n } else {\n matches[first] = getWildCardMatches(object[first], rest);\n }\n\n return matches;\n}\n","/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n createContext,\n useContext,\n useMemo,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport { ScopeProvider, useScope } from '../scope';\nimport { useStore, type UseStoreOptions } from '../useStore';\nimport { FormError, type FormErrorProps } from './formError';\nimport { FormInput, type FormInputComponent, type FormInputProps } from './formInput';\nimport { Scope } from '@core';\nimport { deepEqual } from '@lib/equals';\nimport {\n type PathAsString,\n type Value,\n type WildcardPathAsString,\n type WildcardValue,\n} from '@lib/path';\nimport { get } from '@lib/propAccess';\nimport { getWildCardMatches, wildcardMatch } from '@lib/wildcardMatch';\n\n/// /////////////////////////////////////////////////////////////////////////////\n// Form types\n/// /////////////////////////////////////////////////////////////////////////////\n\nexport interface FormOptions<TDraft, TOriginal> {\n defaultValue: TDraft;\n validations?: Validations<TDraft, TOriginal>;\n}\n\nexport type Validations<TDraft, TOriginal> = {\n [P in WildcardPathAsString<TDraft>]?: Record<\n string,\n Validation<WildcardValue<TDraft, P>, TDraft, TOriginal>\n >;\n};\n\nexport type Validation<TValue, TDraft, TOriginal> = (\n value: TValue,\n context: { draft: TDraft; original: TOriginal; field: PathAsString<TDraft> },\n) => boolean;\n\nexport interface Field<TDraft, TOriginal, TPath extends PathAsString<TDraft>> {\n originalValue: Value<TOriginal, TPath> | undefined;\n value: Value<TDraft, TPath>;\n setValue: (\n value: Value<TDraft, TPath> | ((value: Value<TDraft, TPath>) => Value<TDraft, TPath>),\n ) => void;\n isDirty: boolean;\n errors: string[];\n}\n\n/// /////////////////////////////////////////////////////////////////////////////\n// Implementation\n/// /////////////////////////////////////////////////////////////////////////////\n\nfunction FormContainer({ form, children }: { form: Form<any, any>; children?: ReactNode }) {\n const { validate } = form.useForm();\n\n return (\n <form\n noValidate\n onSubmit={(event) => {\n event.preventDefault();\n\n validate();\n event.currentTarget.reportValidity();\n }}\n >\n {children}\n </form>\n );\n}\n\nexport class Form<TDraft, TOriginal extends TDraft = TDraft> {\n private context = createContext({\n original: undefined as TOriginal | undefined,\n options: this.options,\n });\n\n private state = new Scope<{\n draft?: TDraft;\n hasTriggeredValidations?: boolean;\n }>({});\n\n constructor(public readonly options: FormOptions<TDraft, TOriginal>) {\n this.Provider = this.Provider.bind(this);\n this.useForm = this.useForm.bind(this);\n this.useField = this.useField.bind(this);\n this.useHasChanges = this.useHasChanges.bind(this);\n this.useIsValid = this.useIsValid.bind(this);\n this.Input = this.Input.bind(this);\n this.Error = this.Error.bind(this);\n }\n\n Provider({\n children,\n original,\n defaultValue,\n validations,\n }: { children?: ReactNode; original?: TOriginal } & Partial<FormOptions<TDraft, TOriginal>>) {\n const value = useMemo(\n () => ({\n original,\n options: {\n defaultValue: { ...this.options.defaultValue, ...defaultValue },\n validations: { ...this.options.validations, ...validations } as Validations<\n TDraft,\n TOriginal\n >,\n },\n }),\n [original, defaultValue, validations],\n );\n\n return (\n <this.context.Provider value={value}>\n <ScopeProvider scope={this.state}>\n <FormContainer form={this}>{children}</FormContainer>\n </ScopeProvider>\n </this.context.Provider>\n );\n }\n\n useForm() {\n const { original, options } = useContext(this.context);\n const state = useScope(this.state);\n\n return useMemo(() => {\n const instance = {\n original,\n\n draft: state.map(\n (state) => state.draft ?? original ?? options.defaultValue,\n (draft) => (state) => ({ ...state, draft }),\n ),\n\n getField: <TPath extends PathAsString<TDraft>>(\n path: TPath,\n ): Field<TDraft, TOriginal, TPath> => {\n const { draft } = instance;\n\n return {\n get originalValue() {\n return original !== undefined ? get(original as any, path as any) : undefined;\n },\n\n get value() {\n return get(draft.get(), path);\n },\n\n setValue(update) {\n draft.set(path, update);\n },\n\n get isDirty() {\n const comparisonValue = this.originalValue ?? get(options.defaultValue, path);\n\n return state.get().hasTriggeredValidations || !deepEqual(comparisonValue, this.value);\n },\n\n get errors() {\n const blocks: Record<string, Validation<any, any, any>>[] = Object.entries(\n options.validations ?? {},\n )\n .filter(([key]) => wildcardMatch(path, key))\n .map(([, value]) => value);\n\n const value = this.value;\n const draftValue = draft.get();\n const errors: string[] = [];\n\n for (const block of blocks ?? []) {\n for (const [validationName, validate] of Object.entries(block)) {\n if (!validate(value, { draft: draftValue, original, field: path })) {\n errors.push(validationName);\n }\n }\n }\n\n return errors;\n },\n };\n },\n\n get hasChanges() {\n const { draft } = state.get();\n return !!draft && !deepEqual(draft, original ?? options.defaultValue);\n },\n\n get errors(): string[] {\n const draft = instance.draft.get();\n const errors = new Set<string>();\n\n for (const [path, block] of Object.entries(options.validations ?? {})) {\n for (const [validationName, validate] of Object.entries(\n block as Record<string, Validation<any, any, any>>,\n )) {\n for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {\n if (!validate(value, { draft, original, field })) {\n errors.add(`${field}.${validationName}`);\n }\n }\n }\n }\n\n return [...errors] as any;\n },\n\n get isValid() {\n return instance.errors.length === 0;\n },\n\n validate: () => {\n state.set('hasTriggeredValidations', true);\n return instance.isValid;\n },\n\n reset() {\n state.set('draft', undefined);\n },\n };\n\n return instance;\n }, [original, options, state]);\n }\n\n useField<TPath extends PathAsString<TDraft>>(path: TPath, useStoreOptions?: UseStoreOptions) {\n const form = this.useForm();\n const state = useScope(this.state);\n\n useStore(\n form.draft.map((draft) => get(draft, path)),\n useStoreOptions,\n );\n\n useStore(\n state.map((state) => state.hasTriggeredValidations),\n useStoreOptions,\n );\n\n return form.getField(path);\n }\n\n useHasChanges() {\n const form = this.useForm();\n\n return useStore(form.draft.map(() => form.hasChanges));\n }\n\n useIsValid() {\n const form = this.useForm();\n\n return useStore(form.draft.map(() => form.isValid));\n }\n\n Input<\n TPath extends PathAsString<TDraft>,\n TComponent extends FormInputComponent<any> = (\n props: ComponentPropsWithoutRef<'input'>,\n ) => JSX.Element,\n >(props: FormInputProps<TDraft, TPath, TComponent>): JSX.Element {\n return Reflect.apply(FormInput, this, [props]);\n }\n\n Error<TPath extends PathAsString<TDraft>>({ name }: FormErrorProps<TDraft, TPath>) {\n return Reflect.apply(FormError, this, [{ name }]);\n }\n}\n\nexport function createForm<TDraft, TOriginal extends TDraft = TDraft>(\n options: FormOptions<TDraft, TOriginal>,\n) {\n return new Form(options);\n}\n\n/* eslint-enable react-hooks/rules-of-hooks */\n","import { useCache } from './useCache';\nimport type { UseStoreOptions } from './useStore';\nimport type { Cache } from '@core';\n\nexport function read<T>(cache: Cache<T>, options?: UseStoreOptions): T {\n const { status, value, error } = useCache(cache, options);\n\n if (status === 'value') {\n return value;\n }\n\n if (status === 'error') {\n throw error;\n }\n\n throw cache.state.once((state) => state.status !== 'pending');\n}\n","import { startTransition, useEffect, useMemo, useRef, useState } from 'react';\nimport { type Duration } from '@core';\nimport { debounce } from '@lib/debounce';\nimport { hash } from '@lib/hash';\nimport { throttle } from '@lib/throttle';\n\nexport interface UseDecoupledStateOptions<T> {\n debounce?: Duration;\n throttle?: Duration;\n onCommit?: (value: T) => void;\n}\n\nexport function useDecoupledState<T>(\n value: T,\n onChange: (value: T) => void,\n options: UseDecoupledStateOptions<T> = {},\n): [state: T, setState: (value: T) => void] {\n const [dirty, setDirty] = useState<{ v: T }>();\n const ref = useRef({ onChange, onCommit: options.onCommit });\n\n useEffect(() => {\n ref.current = { onChange, onCommit: options.onCommit };\n }, [onChange]);\n\n const update = useMemo(() => {\n const { onChange, onCommit } = ref.current;\n\n const update = (value: T) => {\n onChange(value);\n setDirty(undefined);\n onCommit?.(value);\n };\n\n let delayedUpdate: (value: T) => void;\n\n if (options.debounce) {\n delayedUpdate = debounce(update, options.debounce);\n } else if (options.throttle) {\n delayedUpdate = throttle(update, options.throttle);\n } else {\n delayedUpdate = (value) => startTransition(() => update(value));\n }\n\n return (value: T) => {\n setDirty({ v: value });\n delayedUpdate(value);\n };\n }, [hash([options.debounce, options.throttle])]);\n\n return [dirty ? dirty.v : value, update];\n}\n"],"names":["value","s","state","onChange","update"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { r as reactMethods, b as useCache, u as useScope, d as useScopeStore, e as useScopeProp, S as ScopeProvider } from "../useCache.mjs";
1
+ import { r as reactMethods, u as useCache, a as useScope, b as useScopeStore, c as useScopeProp, S as ScopeProvider } from "../useCache.mjs";
2
2
  import { S as Store } from "../store.mjs";
3
3
  import { C as Cache } from "../cache.mjs";
4
4
  import { S as Scope } from "../scope.mjs";
package/dist/es/store.mjs CHANGED
@@ -726,14 +726,14 @@ export {
726
726
  calcDuration as a,
727
727
  castArrayPath as b,
728
728
  createStore as c,
729
- set as d,
730
- arrayMethods as e,
731
- setMethods as f,
729
+ deepEqual as d,
730
+ debounce as e,
731
+ set as f,
732
732
  get as g,
733
- deepEqual as h,
734
- debounce as i,
735
- makeSelector as j,
736
- mapMethods as m,
733
+ arrayMethods as h,
734
+ mapMethods as i,
735
+ setMethods as j,
736
+ makeSelector as m,
737
737
  queue as q,
738
738
  recordMethods as r,
739
739
  shallowEqual as s,
@@ -1,26 +1,10 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import require$$0, { useRef, useMemo, useCallback, useLayoutEffect, useDebugValue, useContext, createContext, useEffect } from "react";
3
- import { h as deepEqual, j as makeSelector, c as createStore } from "./store.mjs";
3
+ import { d as deepEqual, m as makeSelector, c as createStore } from "./store.mjs";
4
4
  import { h as hash } from "./scope.mjs";
5
- var withSelectorExports = {};
6
- var withSelector = {
7
- get exports() {
8
- return withSelectorExports;
9
- },
10
- set exports(v) {
11
- withSelectorExports = v;
12
- }
13
- };
5
+ var withSelector = { exports: {} };
14
6
  var withSelector_production_min = {};
15
- var shimExports = {};
16
- var shim = {
17
- get exports() {
18
- return shimExports;
19
- },
20
- set exports(v) {
21
- shimExports = v;
22
- }
23
- };
7
+ var shim = { exports: {} };
24
8
  var useSyncExternalStoreShim_production_min = {};
25
9
  /**
26
10
  * @license React
@@ -208,16 +192,14 @@ function requireUseSyncExternalStoreShim_development() {
208
192
  var hasRequiredShim;
209
193
  function requireShim() {
210
194
  if (hasRequiredShim)
211
- return shimExports;
195
+ return shim.exports;
212
196
  hasRequiredShim = 1;
213
- (function(module) {
214
- if (process.env.NODE_ENV === "production") {
215
- module.exports = requireUseSyncExternalStoreShim_production_min();
216
- } else {
217
- module.exports = requireUseSyncExternalStoreShim_development();
218
- }
219
- })(shim);
220
- return shimExports;
197
+ if (process.env.NODE_ENV === "production") {
198
+ shim.exports = requireUseSyncExternalStoreShim_production_min();
199
+ } else {
200
+ shim.exports = requireUseSyncExternalStoreShim_development();
201
+ }
202
+ return shim.exports;
221
203
  }
222
204
  /**
223
205
  * @license React
@@ -383,13 +365,12 @@ function requireWithSelector_development() {
383
365
  }
384
366
  return withSelector_development;
385
367
  }
386
- (function(module) {
387
- if (process.env.NODE_ENV === "production") {
388
- module.exports = requireWithSelector_production_min();
389
- } else {
390
- module.exports = requireWithSelector_development();
391
- }
392
- })(withSelector);
368
+ if (process.env.NODE_ENV === "production") {
369
+ withSelector.exports = requireWithSelector_production_min();
370
+ } else {
371
+ withSelector.exports = requireWithSelector_development();
372
+ }
373
+ var withSelectorExports = withSelector.exports;
393
374
  const unwrapProxySymbol = /* @__PURE__ */ Symbol("unwrapProxy");
394
375
  function isPlainObject(value) {
395
376
  return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
@@ -597,12 +578,12 @@ function useCache(cache, { passive, updateOnMount, ...options } = {}) {
597
578
  }
598
579
  export {
599
580
  ScopeProvider as S,
600
- useStore as a,
601
- useCache as b,
602
- useProp as c,
603
- useScopeStore as d,
604
- useScopeProp as e,
581
+ useScope as a,
582
+ useScopeStore as b,
583
+ useScopeProp as c,
584
+ useStore as d,
585
+ useProp as e,
605
586
  reactMethods as r,
606
- useScope as u
587
+ useCache as u
607
588
  };
608
589
  //# sourceMappingURL=useCache.mjs.map