cross-state 0.8.6 → 0.9.0
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/dist/cjs/cache.cjs +386 -0
- package/dist/cjs/cache.cjs.map +1 -0
- package/dist/cjs/index.cjs +21 -16
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/react/index.cjs +163 -11
- package/dist/cjs/react/index.cjs.map +1 -1
- package/dist/cjs/react/register.cjs +12 -12
- package/dist/cjs/react/register.cjs.map +1 -1
- package/dist/cjs/scope.cjs +11 -379
- package/dist/cjs/scope.cjs.map +1 -1
- package/dist/cjs/store.cjs.map +1 -1
- package/dist/cjs/{scope2.cjs → useCache.cjs} +54 -40
- package/dist/cjs/useCache.cjs.map +1 -0
- package/dist/es/cache.mjs +387 -0
- package/dist/es/cache.mjs.map +1 -0
- package/dist/es/index.mjs +16 -11
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react/index.mjs +161 -9
- package/dist/es/react/index.mjs.map +1 -1
- package/dist/es/react/register.mjs +4 -4
- package/dist/es/scope.mjs +12 -380
- package/dist/es/scope.mjs.map +1 -1
- package/dist/es/store.mjs +3 -3
- package/dist/es/store.mjs.map +1 -1
- package/dist/es/{scope2.mjs → useCache.mjs} +58 -44
- package/dist/es/useCache.mjs.map +1 -0
- package/dist/types/lib/castArray.d.ts +1 -0
- package/dist/types/lib/path.d.ts +5 -7
- package/dist/types/lib/propAccess.d.ts +1 -1
- package/dist/types/lib/typeHelpers.d.ts +2 -1
- package/dist/types/lib/wildcardMatch.d.ts +3 -0
- package/dist/types/persist/persist.d.ts +6 -4
- package/dist/types/react/form.d.ts +48 -0
- package/dist/types/react/index.d.ts +1 -0
- package/dist/types/react/useProp.d.ts +5 -1
- package/dist/types/react/useStore.d.ts +5 -2
- package/package.json +23 -11
- package/dist/cjs/hash.cjs +0 -18
- package/dist/cjs/hash.cjs.map +0 -1
- package/dist/cjs/scope2.cjs.map +0 -1
- package/dist/es/hash.mjs +0 -19
- package/dist/es/hash.mjs.map +0 -1
- package/dist/es/scope2.mjs.map +0 -1
package/dist/es/react/index.mjs
CHANGED
|
@@ -1,9 +1,159 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { h as
|
|
6
|
-
import "
|
|
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";
|
|
6
|
+
import { S as Scope, h as hash } from "../scope.mjs";
|
|
7
|
+
function wildcardMatch(s, w) {
|
|
8
|
+
if (typeof s === "string") {
|
|
9
|
+
s = castArrayPath(s);
|
|
10
|
+
}
|
|
11
|
+
if (typeof w === "string") {
|
|
12
|
+
w = castArrayPath(w);
|
|
13
|
+
}
|
|
14
|
+
return s.length === w.length && s.every((s2, i) => w[i] === "*" || s2 === w[i]);
|
|
15
|
+
}
|
|
16
|
+
function getWildCardMatches(object, path) {
|
|
17
|
+
const matches = {};
|
|
18
|
+
const [first, ...rest] = castArrayPath(path);
|
|
19
|
+
if (first === void 0) {
|
|
20
|
+
return object;
|
|
21
|
+
}
|
|
22
|
+
if (!(object instanceof Object)) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
if (first === "*") {
|
|
26
|
+
for (const [key, value] of Object.entries(object)) {
|
|
27
|
+
matches[key] = getWildCardMatches(value, rest);
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
matches[first] = getWildCardMatches(object[first], rest);
|
|
31
|
+
}
|
|
32
|
+
return matches;
|
|
33
|
+
}
|
|
34
|
+
class Form {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.context = createContext({
|
|
38
|
+
original: void 0,
|
|
39
|
+
options: this.options
|
|
40
|
+
});
|
|
41
|
+
this.state = new Scope({});
|
|
42
|
+
this.Provider = this.Provider.bind(this);
|
|
43
|
+
}
|
|
44
|
+
Provider({
|
|
45
|
+
children,
|
|
46
|
+
original,
|
|
47
|
+
defaultValue = this.options.defaultValue,
|
|
48
|
+
validations = this.options.validations
|
|
49
|
+
}) {
|
|
50
|
+
const value = useMemo(
|
|
51
|
+
() => ({ original, options: { defaultValue, validations } }),
|
|
52
|
+
[original, defaultValue, validations]
|
|
53
|
+
);
|
|
54
|
+
return /* @__PURE__ */ jsx(this.context.Provider, { value, children: /* @__PURE__ */ jsx(this.state.Provider, { children }) });
|
|
55
|
+
}
|
|
56
|
+
useForm() {
|
|
57
|
+
const { original, options } = useContext(this.context);
|
|
58
|
+
const state = useScope(this.state);
|
|
59
|
+
return useMemo(
|
|
60
|
+
() => ({
|
|
61
|
+
original,
|
|
62
|
+
draft: state.map(
|
|
63
|
+
(state2) => state2.draft ?? original ?? options.defaultValue,
|
|
64
|
+
(draft) => (state2) => ({ ...state2, draft })
|
|
65
|
+
),
|
|
66
|
+
getField(path) {
|
|
67
|
+
const { draft } = this;
|
|
68
|
+
return {
|
|
69
|
+
get originalValue() {
|
|
70
|
+
return original !== void 0 ? get(original, path) : void 0;
|
|
71
|
+
},
|
|
72
|
+
get value() {
|
|
73
|
+
return get(draft.get(), path);
|
|
74
|
+
},
|
|
75
|
+
setValue(update) {
|
|
76
|
+
draft.set(path, update);
|
|
77
|
+
},
|
|
78
|
+
get isDirty() {
|
|
79
|
+
return state.get().hasTriggeredValidations || !deepEqual(this.originalValue, this.value);
|
|
80
|
+
},
|
|
81
|
+
get error() {
|
|
82
|
+
const blocks = Object.entries(
|
|
83
|
+
options.validations ?? {}
|
|
84
|
+
).filter(([key]) => wildcardMatch(path, key)).map(([, value2]) => value2);
|
|
85
|
+
const value = this.value;
|
|
86
|
+
const draftValue = draft.get();
|
|
87
|
+
for (const block of blocks ?? []) {
|
|
88
|
+
for (const [validationName, validate] of Object.entries(block)) {
|
|
89
|
+
if (!validate(value, { draft: draftValue, original, field: path })) {
|
|
90
|
+
return validationName;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
hasChanges() {
|
|
99
|
+
const { draft } = state.get();
|
|
100
|
+
return !!draft && !deepEqual(draft, original);
|
|
101
|
+
},
|
|
102
|
+
getErrors() {
|
|
103
|
+
const draft = this.draft.get();
|
|
104
|
+
const errors = /* @__PURE__ */ new Set();
|
|
105
|
+
for (const [path, block] of Object.entries(options.validations ?? {})) {
|
|
106
|
+
for (const [validationName, validate] of Object.entries(
|
|
107
|
+
block
|
|
108
|
+
)) {
|
|
109
|
+
for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {
|
|
110
|
+
if (!validate(value, { draft, original, field })) {
|
|
111
|
+
errors.add(`${field}.${validationName}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return [...errors];
|
|
117
|
+
},
|
|
118
|
+
isValid() {
|
|
119
|
+
return this.getErrors().length === 0;
|
|
120
|
+
},
|
|
121
|
+
validate() {
|
|
122
|
+
state.set("hasTriggeredValidations", true);
|
|
123
|
+
return this.isValid();
|
|
124
|
+
},
|
|
125
|
+
reset() {
|
|
126
|
+
state.set("draft", void 0);
|
|
127
|
+
}
|
|
128
|
+
}),
|
|
129
|
+
[original, options, state]
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
useField(path, useStoreOptions) {
|
|
133
|
+
const form = this.useForm();
|
|
134
|
+
const state = useScope(this.state);
|
|
135
|
+
useStore(
|
|
136
|
+
form.draft.map((draft) => get(draft, path)),
|
|
137
|
+
useStoreOptions
|
|
138
|
+
);
|
|
139
|
+
useStore(
|
|
140
|
+
state.map((state2) => state2.hasTriggeredValidations),
|
|
141
|
+
useStoreOptions
|
|
142
|
+
);
|
|
143
|
+
return form.getField(path);
|
|
144
|
+
}
|
|
145
|
+
useHasChanges() {
|
|
146
|
+
const form = this.useForm();
|
|
147
|
+
return useStore(form.draft.map(() => form.hasChanges()));
|
|
148
|
+
}
|
|
149
|
+
useIsValid() {
|
|
150
|
+
const form = this.useForm();
|
|
151
|
+
return useStore(form.draft.map(() => form.isValid()));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function createForm(options) {
|
|
155
|
+
return new Form(options);
|
|
156
|
+
}
|
|
7
157
|
function read(cache, options) {
|
|
8
158
|
const { status, value, error } = useCache(cache, options);
|
|
9
159
|
if (status === "value") {
|
|
@@ -43,13 +193,15 @@ function useDecoupledState(value, onChange, options = {}) {
|
|
|
43
193
|
return [dirty ? dirty.v : value, update];
|
|
44
194
|
}
|
|
45
195
|
export {
|
|
196
|
+
Form,
|
|
46
197
|
S as ScopeProvider,
|
|
198
|
+
createForm,
|
|
47
199
|
r as reactMethods,
|
|
48
200
|
read,
|
|
49
201
|
useCache,
|
|
50
202
|
useDecoupledState,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
203
|
+
c as useProp,
|
|
204
|
+
useScope,
|
|
205
|
+
useStore
|
|
54
206
|
};
|
|
55
207
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../src/react/read.ts","../../../src/react/useDecoupledState.ts"],"sourcesContent":["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":["onChange","update","value"],"mappings":";;;;;;AAIgB,SAAA,KAAQ,OAAiB,SAA8B;AACrE,QAAM,EAAE,QAAQ,OAAO,MAAU,IAAA,SAAS,OAAO,OAAO;AAExD,MAAI,WAAW,SAAS;AACf,WAAA;AAAA,EACT;AAEA,MAAI,WAAW,SAAS;AAChB,UAAA;AAAA,EACR;AAEA,QAAM,MAAM,MAAM,KAAK,CAAC,UAAU,MAAM,WAAW,SAAS;AAC9D;ACJO,SAAS,kBACd,OACA,UACA,UAAuC,CAAA,GACG;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB;AAC7C,QAAM,MAAM,OAAO,EAAE,UAAU,UAAU,QAAQ,UAAU;AAE3D,YAAU,MAAM;AACd,QAAI,UAAU,EAAE,UAAU,UAAU,QAAQ;EAAS,GACpD,CAAC,QAAQ,CAAC;AAEP,QAAA,SAAS,QAAQ,MAAM;AAC3B,UAAM,EAAE,UAAAA,WAAU,SAAA,IAAa,IAAI;AAE7BC,UAAAA,UAAS,CAACC,WAAa;AAC3BF,gBAASE,MAAK;AACd,eAAS,MAAS;AAClB,2CAAWA;AAAAA,IAAK;AAGd,QAAA;AAEJ,QAAI,QAAQ,UAAU;AACJ,sBAAA,SAASD,SAAQ,QAAQ,QAAQ;AAAA,IAAA,WACxC,QAAQ,UAAU;AACX,sBAAA,SAASA,SAAQ,QAAQ,QAAQ;AAAA,IAAA,OAC5C;AACL,sBAAgB,CAACC,WAAU,gBAAgB,MAAMD,QAAOC,MAAK,CAAC;AAAA,IAChE;AAEA,WAAO,CAACA,WAAa;AACV,eAAA,EAAE,GAAGA,OAAAA,CAAO;AACrB,oBAAcA,MAAK;AAAA,IAAA;AAAA,EACrB,GACC,CAAC,KAAK,CAAC,QAAQ,UAAU,QAAQ,QAAQ,CAAC,CAAC,CAAC;AAE/C,SAAO,CAAC,QAAQ,MAAM,IAAI,OAAO,MAAM;AACzC;"}
|
|
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,9 +1,9 @@
|
|
|
1
|
-
import { r as reactMethods,
|
|
1
|
+
import { r as reactMethods, b as useCache, u as useScope, d as useScopeStore, e as useScopeProp, S as ScopeProvider } from "../useCache.mjs";
|
|
2
2
|
import { S as Store } from "../store.mjs";
|
|
3
|
-
import { C as Cache
|
|
4
|
-
import "
|
|
3
|
+
import { C as Cache } from "../cache.mjs";
|
|
4
|
+
import { S as Scope } from "../scope.mjs";
|
|
5
5
|
import "react/jsx-runtime";
|
|
6
|
-
import "
|
|
6
|
+
import "react";
|
|
7
7
|
const cacheMethods = {
|
|
8
8
|
useCache(options) {
|
|
9
9
|
return useCache(this, options);
|
package/dist/es/scope.mjs
CHANGED
|
@@ -1,381 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
constructor(name) {
|
|
5
|
-
this.name = name;
|
|
6
|
-
this.refMap = /* @__PURE__ */ new WeakMap();
|
|
7
|
-
this.refSet = /* @__PURE__ */ new Set();
|
|
8
|
-
this.add = this.add.bind(this);
|
|
9
|
-
this.delete = this.delete.bind(this);
|
|
10
|
-
this.invalidateAll = this.invalidateAll.bind(this);
|
|
11
|
-
this.clearAll = this.clearAll.bind(this);
|
|
1
|
+
function hash(value) {
|
|
2
|
+
if (value instanceof Set) {
|
|
3
|
+
return `s[${[...value].map(hash).sort().join(",")}]`;
|
|
12
4
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.refMap.set(resource, ref);
|
|
16
|
-
this.refSet.add(ref);
|
|
5
|
+
if (value instanceof Map) {
|
|
6
|
+
return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
|
|
17
7
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (ref) {
|
|
21
|
-
this.refMap.delete(resource);
|
|
22
|
-
this.refSet.delete(ref);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
invalidateAll() {
|
|
26
|
-
for (const ref of this.refSet) {
|
|
27
|
-
const resource = ref.deref();
|
|
28
|
-
if (resource) {
|
|
29
|
-
resource.invalidateAll();
|
|
30
|
-
} else {
|
|
31
|
-
this.refSet.delete(ref);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
clearAll() {
|
|
36
|
-
for (const ref of this.refSet) {
|
|
37
|
-
const resource = ref.deref();
|
|
38
|
-
if (resource) {
|
|
39
|
-
resource.clearAll();
|
|
40
|
-
} else {
|
|
41
|
-
this.refSet.delete(ref);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const allResources = /* @__PURE__ */ new ResourceGroup();
|
|
47
|
-
function createResourceGroup(name) {
|
|
48
|
-
return new ResourceGroup(name);
|
|
49
|
-
}
|
|
50
|
-
class InstanceCache {
|
|
51
|
-
constructor(factory, cacheTime) {
|
|
52
|
-
this.factory = factory;
|
|
53
|
-
this.cacheTime = cacheTime;
|
|
54
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
55
|
-
this.interval = this.cacheTime ? setInterval(() => this.cleanup(), Math.max(this.cacheTime / 10, 1)) : void 0;
|
|
56
|
-
}
|
|
57
|
-
cleanup() {
|
|
58
|
-
var _a;
|
|
59
|
-
const cutoff = this.now() - (this.cacheTime ?? 0);
|
|
60
|
-
for (const [key, entry] of this.cache.entries()) {
|
|
61
|
-
if (entry.ref && entry.t <= cutoff) {
|
|
62
|
-
delete entry.ref;
|
|
63
|
-
}
|
|
64
|
-
if (!entry.ref && !((_a = entry.weakRef) == null ? void 0 : _a.deref())) {
|
|
65
|
-
this.cache.delete(key);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
get(...args) {
|
|
70
|
-
var _a;
|
|
71
|
-
const key = hash(args);
|
|
72
|
-
let entry = this.cache.get(key);
|
|
73
|
-
let value = (entry == null ? void 0 : entry.ref) ?? ((_a = entry == null ? void 0 : entry.weakRef) == null ? void 0 : _a.deref());
|
|
74
|
-
if (!entry || !value) {
|
|
75
|
-
value = this.factory(...args);
|
|
76
|
-
entry = {
|
|
77
|
-
t: this.now(),
|
|
78
|
-
ref: value,
|
|
79
|
-
weakRef: new WeakRef(value)
|
|
80
|
-
};
|
|
81
|
-
this.cache.set(key, entry);
|
|
82
|
-
} else {
|
|
83
|
-
entry.t = this.now();
|
|
84
|
-
entry.ref ?? (entry.ref = value);
|
|
85
|
-
}
|
|
86
|
-
return value;
|
|
87
|
-
}
|
|
88
|
-
values() {
|
|
89
|
-
return [...this.cache.values()].map((entry) => {
|
|
90
|
-
var _a;
|
|
91
|
-
return entry.ref ?? ((_a = entry.weakRef) == null ? void 0 : _a.deref());
|
|
92
|
-
}).filter((value) => !!value);
|
|
93
|
-
}
|
|
94
|
-
stop() {
|
|
95
|
-
if (this.interval) {
|
|
96
|
-
clearInterval(this.interval);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
stats() {
|
|
100
|
-
return {
|
|
101
|
-
count: this.cache.size,
|
|
102
|
-
withRef: [...this.cache.values()].filter((x) => !!x.ref).length,
|
|
103
|
-
withWeakRef: [...this.cache.values()].filter((x) => {
|
|
104
|
-
var _a;
|
|
105
|
-
return !!((_a = x.weakRef) == null ? void 0 : _a.deref());
|
|
106
|
-
}).length
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
now() {
|
|
110
|
-
return performance.now();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
class PromiseWithState extends Promise {
|
|
114
|
-
constructor(value, state = { status: "pending" }) {
|
|
115
|
-
super((resolve) => resolve(value));
|
|
116
|
-
this.state = state;
|
|
117
|
-
value.then((value2) => {
|
|
118
|
-
this.state = { status: "value", value: value2 };
|
|
119
|
-
}).catch((error) => {
|
|
120
|
-
this.state = { status: "error", error };
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
static resolve(value) {
|
|
124
|
-
return new PromiseWithState(Promise.resolve(value), {
|
|
125
|
-
status: "value",
|
|
126
|
-
value
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
static reject(error) {
|
|
130
|
-
return new PromiseWithState(Promise.reject(error), { status: "error", error });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
class Cache extends Store {
|
|
134
|
-
constructor(getter, options = {}, derivedFromCache, _call) {
|
|
135
|
-
super(
|
|
136
|
-
function() {
|
|
137
|
-
let result = getter.apply(this);
|
|
138
|
-
if (result instanceof Function) {
|
|
139
|
-
result = result(this);
|
|
140
|
-
}
|
|
141
|
-
return result;
|
|
142
|
-
},
|
|
143
|
-
options,
|
|
144
|
-
void 0,
|
|
145
|
-
_call
|
|
146
|
-
);
|
|
147
|
-
this.options = options;
|
|
148
|
-
this.derivedFromCache = derivedFromCache;
|
|
149
|
-
this.state = createStore({
|
|
150
|
-
status: "pending",
|
|
151
|
-
isStale: true,
|
|
152
|
-
isUpdating: false
|
|
153
|
-
});
|
|
154
|
-
this.invalidate = this.invalidate.bind(this);
|
|
155
|
-
this.clear = this.clear.bind(this);
|
|
156
|
-
this.mapValue = this.mapValue.bind(this);
|
|
157
|
-
this.calculationHelper.options.onInvalidate = () => this.invalidate({ invalidateDependencies: false });
|
|
158
|
-
this.watchPromise();
|
|
159
|
-
this.watchFocus();
|
|
160
|
-
}
|
|
161
|
-
get({ update = "whenStale", backgroundUpdate = false } = {}) {
|
|
162
|
-
var _a;
|
|
163
|
-
const promise = (_a = this._value) == null ? void 0 : _a.v;
|
|
164
|
-
const stalePromise = this.stalePromise;
|
|
165
|
-
if (update === "whenMissing" && !promise && !stalePromise || update === "whenStale" && !promise || update === "force") {
|
|
166
|
-
this.calculationHelper.execute();
|
|
167
|
-
if (!promise && !stalePromise || !backgroundUpdate) {
|
|
168
|
-
return super.get();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
if (!promise || stalePromise && backgroundUpdate) {
|
|
172
|
-
return stalePromise;
|
|
173
|
-
}
|
|
174
|
-
return promise;
|
|
175
|
-
}
|
|
176
|
-
updateValue(value) {
|
|
177
|
-
this.set(PromiseWithState.resolve(value));
|
|
178
|
-
}
|
|
179
|
-
updateError(error) {
|
|
180
|
-
this.set(PromiseWithState.reject(error));
|
|
181
|
-
}
|
|
182
|
-
invalidate({ invalidateDependencies = true } = {}) {
|
|
183
|
-
var _a;
|
|
184
|
-
const { clearOnInvalidate = createCache.defaultOptions.clearOnInvalidate } = this.options;
|
|
185
|
-
if (clearOnInvalidate) {
|
|
186
|
-
return this.clear({ invalidateDependencies });
|
|
187
|
-
}
|
|
188
|
-
if (invalidateDependencies) {
|
|
189
|
-
this.calculationHelper.invalidateDependencies();
|
|
190
|
-
}
|
|
191
|
-
const { status, isStale, isUpdating } = this.state.get();
|
|
192
|
-
if (status !== "pending" && !isStale && !isUpdating) {
|
|
193
|
-
this.stalePromise = (_a = this._value) == null ? void 0 : _a.v;
|
|
194
|
-
}
|
|
195
|
-
this.state.set((state) => ({
|
|
196
|
-
...state,
|
|
197
|
-
isStale: true,
|
|
198
|
-
isUpdating: false
|
|
199
|
-
}));
|
|
200
|
-
this.calculationHelper.stop();
|
|
201
|
-
super.reset();
|
|
202
|
-
}
|
|
203
|
-
clear({ invalidateDependencies = true } = {}) {
|
|
204
|
-
if (invalidateDependencies) {
|
|
205
|
-
this.calculationHelper.invalidateDependencies();
|
|
206
|
-
}
|
|
207
|
-
this.state.set({
|
|
208
|
-
status: "pending",
|
|
209
|
-
isStale: true,
|
|
210
|
-
isUpdating: false
|
|
211
|
-
});
|
|
212
|
-
delete this.stalePromise;
|
|
213
|
-
this.calculationHelper.stop();
|
|
214
|
-
super.reset();
|
|
215
|
-
}
|
|
216
|
-
mapValue(_selector) {
|
|
217
|
-
const selector = makeSelector(_selector);
|
|
218
|
-
const derivedFromCache = {
|
|
219
|
-
cache: this.derivedFromCache ? this.derivedFromCache.cache : this,
|
|
220
|
-
selectors: this.derivedFromCache ? [...this.derivedFromCache.selectors, _selector] : [_selector]
|
|
221
|
-
};
|
|
222
|
-
const that = this;
|
|
223
|
-
return new Cache(
|
|
224
|
-
async function() {
|
|
225
|
-
const value = await this.use(that);
|
|
226
|
-
return selector(value);
|
|
227
|
-
},
|
|
228
|
-
{},
|
|
229
|
-
derivedFromCache
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
watchPromise() {
|
|
233
|
-
this.subscribe(
|
|
234
|
-
async (promise) => {
|
|
235
|
-
var _a, _b;
|
|
236
|
-
if (promise instanceof PromiseWithState) {
|
|
237
|
-
this.state.set({
|
|
238
|
-
...promise.state,
|
|
239
|
-
isStale: false,
|
|
240
|
-
isUpdating: false
|
|
241
|
-
});
|
|
242
|
-
delete this.stalePromise;
|
|
243
|
-
this.setTimers();
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
this.state.set((state) => ({
|
|
247
|
-
...state,
|
|
248
|
-
isUpdating: true
|
|
249
|
-
}));
|
|
250
|
-
this.setTimers();
|
|
251
|
-
try {
|
|
252
|
-
const value = await promise;
|
|
253
|
-
if (promise !== ((_a = this._value) == null ? void 0 : _a.v)) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
this.state.set({
|
|
257
|
-
status: "value",
|
|
258
|
-
value,
|
|
259
|
-
isStale: false,
|
|
260
|
-
isUpdating: false
|
|
261
|
-
});
|
|
262
|
-
delete this.stalePromise;
|
|
263
|
-
this.setTimers();
|
|
264
|
-
} catch (error) {
|
|
265
|
-
if (promise !== ((_b = this._value) == null ? void 0 : _b.v)) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
this.state.set({
|
|
269
|
-
status: "error",
|
|
270
|
-
error,
|
|
271
|
-
isStale: false,
|
|
272
|
-
isUpdating: false
|
|
273
|
-
});
|
|
274
|
-
delete this.stalePromise;
|
|
275
|
-
this.setTimers();
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
{ passive: true }
|
|
279
|
-
);
|
|
8
|
+
if (Array.isArray(value)) {
|
|
9
|
+
return `[${value.map(hash).join(",")}]`;
|
|
280
10
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
clearTimeout(this.invalidationTimer);
|
|
284
|
-
}
|
|
285
|
-
this.invalidationTimer = void 0;
|
|
286
|
-
const state = this.state.get();
|
|
287
|
-
let { invalidateAfter = createCache.defaultOptions.invalidateAfter } = this.options;
|
|
288
|
-
const ref = new WeakRef(this);
|
|
289
|
-
if (state.status === "pending") {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
if (invalidateAfter instanceof Function) {
|
|
293
|
-
invalidateAfter = invalidateAfter(state);
|
|
294
|
-
}
|
|
295
|
-
if (invalidateAfter !== null && invalidateAfter !== void 0) {
|
|
296
|
-
this.invalidationTimer = setTimeout(
|
|
297
|
-
() => {
|
|
298
|
-
var _a;
|
|
299
|
-
return (_a = ref == null ? void 0 : ref.deref()) == null ? void 0 : _a.invalidate();
|
|
300
|
-
},
|
|
301
|
-
calcDuration(invalidateAfter)
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
watchFocus() {
|
|
306
|
-
const { invalidateOnWindowFocus = createCache.defaultOptions.invalidateOnWindowFocus } = this.options;
|
|
307
|
-
if (!invalidateOnWindowFocus || typeof document === "undefined" || typeof document.addEventListener === "undefined") {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
const ref = new WeakRef(this);
|
|
311
|
-
const onFocus = () => {
|
|
312
|
-
const that = ref == null ? void 0 : ref.deref();
|
|
313
|
-
if (!that) {
|
|
314
|
-
document.removeEventListener("visibilitychange", onFocus);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
if (!document.hidden) {
|
|
318
|
-
that.invalidate();
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
document.addEventListener("visibilitychange", onFocus);
|
|
11
|
+
if (value instanceof Object) {
|
|
12
|
+
return `o[${Object.entries(value).map(hash).sort().join(",")}]`;
|
|
322
13
|
}
|
|
14
|
+
return JSON.stringify(value);
|
|
323
15
|
}
|
|
324
|
-
function create(cacheFunction, options) {
|
|
325
|
-
const { clearUnusedAfter = createCache.defaultOptions.clearUnusedAfter, resourceGroup } = options ?? {};
|
|
326
|
-
let baseInstance;
|
|
327
|
-
const instanceCache = new InstanceCache(
|
|
328
|
-
(...args) => {
|
|
329
|
-
if (args.length === 0 && baseInstance) {
|
|
330
|
-
return baseInstance;
|
|
331
|
-
}
|
|
332
|
-
return new Cache(function() {
|
|
333
|
-
return cacheFunction.apply(this, args);
|
|
334
|
-
}, options);
|
|
335
|
-
},
|
|
336
|
-
clearUnusedAfter ? calcDuration(clearUnusedAfter) : void 0
|
|
337
|
-
);
|
|
338
|
-
const get = (...args) => {
|
|
339
|
-
return instanceCache.get(...args);
|
|
340
|
-
};
|
|
341
|
-
const invalidateAll = () => {
|
|
342
|
-
for (const instance of instanceCache.values()) {
|
|
343
|
-
instance.invalidate();
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
const clearAll = () => {
|
|
347
|
-
for (const instance of instanceCache.values()) {
|
|
348
|
-
instance.clear();
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
baseInstance = Object.assign(
|
|
352
|
-
new Cache(
|
|
353
|
-
function() {
|
|
354
|
-
return cacheFunction.apply(this);
|
|
355
|
-
},
|
|
356
|
-
options,
|
|
357
|
-
void 0,
|
|
358
|
-
get
|
|
359
|
-
),
|
|
360
|
-
{
|
|
361
|
-
invalidateAll,
|
|
362
|
-
clearAll
|
|
363
|
-
}
|
|
364
|
-
);
|
|
365
|
-
const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
|
|
366
|
-
for (const group of groups.concat(allResources)) {
|
|
367
|
-
group.add(baseInstance);
|
|
368
|
-
}
|
|
369
|
-
get(...[]);
|
|
370
|
-
return baseInstance;
|
|
371
|
-
}
|
|
372
|
-
const createCache = /* @__PURE__ */ Object.assign(create, {
|
|
373
|
-
defaultOptions: {
|
|
374
|
-
invalidateOnWindowFocus: true,
|
|
375
|
-
invalidateOnActivation: true,
|
|
376
|
-
clearUnusedAfter: { days: 1 }
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
16
|
class Scope {
|
|
380
17
|
constructor(defaultValue) {
|
|
381
18
|
this.defaultValue = defaultValue;
|
|
@@ -388,13 +25,8 @@ function createScope(defaultValue) {
|
|
|
388
25
|
return new Scope(defaultValue);
|
|
389
26
|
}
|
|
390
27
|
export {
|
|
391
|
-
Cache as C,
|
|
392
|
-
InstanceCache as I,
|
|
393
|
-
ResourceGroup as R,
|
|
394
28
|
Scope as S,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
createCache as c,
|
|
398
|
-
createScope as d
|
|
29
|
+
createScope as c,
|
|
30
|
+
hash as h
|
|
399
31
|
};
|
|
400
32
|
//# sourceMappingURL=scope.mjs.map
|