@gaddario98/react-core 2.0.8 → 2.0.9
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/auth/index.d.ts +2 -2
- package/dist/auth/index.js +184 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +183 -1
- package/dist/auth/index.mjs.map +1 -1
- package/dist/form/index.js +263 -3959
- package/dist/form/index.js.map +1 -1
- package/dist/form/index.mjs +213 -3909
- package/dist/form/index.mjs.map +1 -1
- package/dist/index.d.ts +623 -93
- package/dist/index.js +5381 -16418
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5372 -16409
- package/dist/index.mjs.map +1 -1
- package/dist/localization/index.js +184 -2
- package/dist/localization/index.js.map +1 -1
- package/dist/localization/index.mjs +183 -1
- package/dist/localization/index.mjs.map +1 -1
- package/dist/notifications/index.d.ts +2 -2
- package/dist/notifications/index.js +185 -3
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/index.mjs +184 -2
- package/dist/notifications/index.mjs.map +1 -1
- package/dist/pages/index.js +1536 -1680
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/index.mjs +1522 -1666
- package/dist/pages/index.mjs.map +1 -1
- package/dist/queries/index.js +393 -7439
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/index.mjs +385 -7431
- package/dist/queries/index.mjs.map +1 -1
- package/dist/state/index.js +10 -1783
- package/dist/state/index.js.map +1 -1
- package/dist/state/index.mjs +2 -1775
- package/dist/state/index.mjs.map +1 -1
- package/package.json +8 -6
package/dist/pages/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import
|
|
1
|
+
import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {useRef,useEffect,useReducer,useCallback,useMemo,useState,memo,createContext,useContext}from'react';import {atom,useAtom,useSetAtom,useAtomValue,useStore}from'jotai';import {atomWithStorage,createJSONStorage,selectAtom}from'jotai/utils';import {inflateSync,strFromU8,strToU8,deflateSync}from'fflate';import {c}from'react/compiler-runtime';import {QueryClient,useQueries,QueryObserver}from'@tanstack/react-query';import axios from'axios';import equal from'fast-deep-equal';import {atomFamily}from'jotai-family';import {useForm}from'@tanstack/react-form';/******************************************************************************
|
|
2
2
|
Copyright (c) Microsoft Corporation.
|
|
3
3
|
|
|
4
4
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -25,839 +25,1594 @@ function __rest(s, e) {
|
|
|
25
25
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
26
26
|
var e = new Error(message);
|
|
27
27
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return "v" in atomState || "e" in atomState;
|
|
36
|
-
}
|
|
37
|
-
function returnAtomValue(atomState) {
|
|
38
|
-
if ("e" in atomState) {
|
|
39
|
-
throw atomState.e;
|
|
40
|
-
}
|
|
41
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !("v" in atomState)) {
|
|
42
|
-
throw new Error("[Bug] atom state is not initialized");
|
|
43
|
-
}
|
|
44
|
-
return atomState.v;
|
|
45
|
-
}
|
|
46
|
-
const promiseStateMap = /* @__PURE__ */ new WeakMap();
|
|
47
|
-
function isPendingPromise(value) {
|
|
48
|
-
var _a;
|
|
49
|
-
return isPromiseLike$1(value) && !!((_a = promiseStateMap.get(value)) == null ? void 0 : _a[0]);
|
|
50
|
-
}
|
|
51
|
-
function abortPromise(promise) {
|
|
52
|
-
const promiseState = promiseStateMap.get(promise);
|
|
53
|
-
if (promiseState == null ? void 0 : promiseState[0]) {
|
|
54
|
-
promiseState[0] = false;
|
|
55
|
-
promiseState[1].forEach((fn) => fn());
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function registerAbortHandler(promise, abortHandler) {
|
|
59
|
-
let promiseState = promiseStateMap.get(promise);
|
|
60
|
-
if (!promiseState) {
|
|
61
|
-
promiseState = [true, /* @__PURE__ */ new Set()];
|
|
62
|
-
promiseStateMap.set(promise, promiseState);
|
|
63
|
-
const settle = () => {
|
|
64
|
-
promiseState[0] = false;
|
|
65
|
-
};
|
|
66
|
-
promise.then(settle, settle);
|
|
67
|
-
}
|
|
68
|
-
promiseState[1].add(abortHandler);
|
|
69
|
-
}
|
|
70
|
-
function isPromiseLike$1(p) {
|
|
71
|
-
return typeof (p == null ? void 0 : p.then) === "function";
|
|
72
|
-
}
|
|
73
|
-
function addPendingPromiseToDependency(atom, promise, dependencyAtomState) {
|
|
74
|
-
if (!dependencyAtomState.p.has(atom)) {
|
|
75
|
-
dependencyAtomState.p.add(atom);
|
|
76
|
-
const cleanup = () => dependencyAtomState.p.delete(atom);
|
|
77
|
-
promise.then(cleanup, cleanup);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
function getMountedOrPendingDependents(atom, atomState, mountedMap) {
|
|
81
|
-
var _a;
|
|
82
|
-
const dependents = /* @__PURE__ */ new Set();
|
|
83
|
-
for (const a of ((_a = mountedMap.get(atom)) == null ? void 0 : _a.t) || []) {
|
|
84
|
-
dependents.add(a);
|
|
85
|
-
}
|
|
86
|
-
for (const atomWithPendingPromise of atomState.p) {
|
|
87
|
-
dependents.add(atomWithPendingPromise);
|
|
88
|
-
}
|
|
89
|
-
return dependents;
|
|
90
|
-
}
|
|
91
|
-
const BUILDING_BLOCK_atomRead = (_store, atom, ...params) => atom.read(...params);
|
|
92
|
-
const BUILDING_BLOCK_atomWrite = (_store, atom, ...params) => atom.write(...params);
|
|
93
|
-
const BUILDING_BLOCK_atomOnInit = (store, atom) => {
|
|
94
|
-
var _a;
|
|
95
|
-
return (_a = atom.INTERNAL_onInit) == null ? void 0 : _a.call(atom, store);
|
|
28
|
+
};const RAW_PREFIX = 'storage:raw:';
|
|
29
|
+
const DEFLATE_PREFIX = 'storage:deflate:v1:';
|
|
30
|
+
const isProbablyJson = value => {
|
|
31
|
+
if (!value) return false;
|
|
32
|
+
const c = value.charCodeAt(0);
|
|
33
|
+
// { [ " digits, t/f/n (true/false/null)
|
|
34
|
+
return c === 123 || c === 91 || c === 34 || c >= 48 && c <= 57 || c === 45 || c === 116 || c === 102 || c === 110;
|
|
96
35
|
};
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
36
|
+
const u8ToBase64 = bytes => {
|
|
37
|
+
let binary = '';
|
|
38
|
+
const chunkSize = 0x8000;
|
|
39
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
40
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
41
|
+
}
|
|
42
|
+
return btoa(binary);
|
|
100
43
|
};
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
throw new Error("Atom is undefined or null");
|
|
109
|
-
}
|
|
110
|
-
let atomState = atomStateMap.get(atom);
|
|
111
|
-
if (!atomState) {
|
|
112
|
-
atomState = { d: /* @__PURE__ */ new Map(), p: /* @__PURE__ */ new Set(), n: 0 };
|
|
113
|
-
atomStateMap.set(atom, atomState);
|
|
114
|
-
(_a = storeHooks.i) == null ? void 0 : _a.call(storeHooks, atom);
|
|
115
|
-
atomOnInit == null ? void 0 : atomOnInit(store, atom);
|
|
116
|
-
}
|
|
117
|
-
return atomState;
|
|
44
|
+
const base64ToU8 = base64 => {
|
|
45
|
+
const binary = atob(base64);
|
|
46
|
+
const bytes = new Uint8Array(binary.length);
|
|
47
|
+
for (let i = 0; i < binary.length; i++) {
|
|
48
|
+
bytes[i] = binary.charCodeAt(i);
|
|
49
|
+
}
|
|
50
|
+
return bytes;
|
|
118
51
|
};
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
52
|
+
const createCompressedStorage = (base, options = {}) => {
|
|
53
|
+
const {
|
|
54
|
+
minSizeToCompress = 1024,
|
|
55
|
+
deflateLevel = 1,
|
|
56
|
+
writeDebounceMs = 50
|
|
57
|
+
} = options;
|
|
58
|
+
const pendingWrites = new Map();
|
|
59
|
+
let flushTimer;
|
|
60
|
+
let lifecycleHooksInstalled = false;
|
|
61
|
+
const flush = () => {
|
|
62
|
+
flushTimer = undefined;
|
|
63
|
+
for (const [key, value] of pendingWrites) {
|
|
64
|
+
try {
|
|
65
|
+
if (value.length < minSizeToCompress) {
|
|
66
|
+
base.setItem(key, RAW_PREFIX + value);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const input = strToU8(value);
|
|
70
|
+
const compressed = deflateSync(input, {
|
|
71
|
+
level: deflateLevel
|
|
72
|
+
});
|
|
73
|
+
base.setItem(key, DEFLATE_PREFIX + u8ToBase64(compressed));
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('Error setting item:', error);
|
|
76
|
+
try {
|
|
77
|
+
base.setItem(key, RAW_PREFIX + value);
|
|
78
|
+
} catch (_a) {
|
|
79
|
+
// ignore
|
|
80
|
+
}
|
|
81
|
+
}
|
|
133
82
|
}
|
|
83
|
+
pendingWrites.clear();
|
|
134
84
|
};
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return (_a = mountedMap.get(atom)) == null ? void 0 : _a.l.forEach(add);
|
|
144
|
-
});
|
|
145
|
-
changedAtoms.clear();
|
|
146
|
-
unmountCallbacks.forEach(add);
|
|
147
|
-
unmountCallbacks.clear();
|
|
148
|
-
mountCallbacks.forEach(add);
|
|
149
|
-
mountCallbacks.clear();
|
|
150
|
-
callbacks.forEach(call);
|
|
151
|
-
if (changedAtoms.size) {
|
|
152
|
-
recomputeInvalidatedAtoms(store);
|
|
153
|
-
}
|
|
154
|
-
} while (changedAtoms.size || unmountCallbacks.size || mountCallbacks.size);
|
|
155
|
-
if (errors.length) {
|
|
156
|
-
throw new AggregateError(errors);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
const BUILDING_BLOCK_recomputeInvalidatedAtoms = (store) => {
|
|
160
|
-
const buildingBlocks = getInternalBuildingBlocks(store);
|
|
161
|
-
const mountedMap = buildingBlocks[1];
|
|
162
|
-
const invalidatedAtoms = buildingBlocks[2];
|
|
163
|
-
const changedAtoms = buildingBlocks[3];
|
|
164
|
-
const ensureAtomState = buildingBlocks[11];
|
|
165
|
-
const readAtomState = buildingBlocks[14];
|
|
166
|
-
const mountDependencies = buildingBlocks[17];
|
|
167
|
-
const topSortedReversed = [];
|
|
168
|
-
const visiting = /* @__PURE__ */ new WeakSet();
|
|
169
|
-
const visited = /* @__PURE__ */ new WeakSet();
|
|
170
|
-
const stack = Array.from(changedAtoms);
|
|
171
|
-
while (stack.length) {
|
|
172
|
-
const a = stack[stack.length - 1];
|
|
173
|
-
const aState = ensureAtomState(store, a);
|
|
174
|
-
if (visited.has(a)) {
|
|
175
|
-
stack.pop();
|
|
176
|
-
continue;
|
|
85
|
+
const scheduleFlush = () => {
|
|
86
|
+
if (flushTimer != null) return;
|
|
87
|
+
if (!lifecycleHooksInstalled && typeof window !== 'undefined') {
|
|
88
|
+
lifecycleHooksInstalled = true;
|
|
89
|
+
window.addEventListener('beforeunload', flush);
|
|
90
|
+
document.addEventListener('visibilitychange', () => {
|
|
91
|
+
if (document.visibilityState === 'hidden') flush();
|
|
92
|
+
});
|
|
177
93
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
94
|
+
flushTimer = globalThis.setTimeout(flush, writeDebounceMs);
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
getItem: key => {
|
|
98
|
+
try {
|
|
99
|
+
const stored = base.getItem(key);
|
|
100
|
+
if (!stored) return null;
|
|
101
|
+
if (stored.startsWith(RAW_PREFIX)) {
|
|
102
|
+
return stored.slice(RAW_PREFIX.length);
|
|
103
|
+
}
|
|
104
|
+
if (stored.startsWith(DEFLATE_PREFIX)) {
|
|
105
|
+
const b64 = stored.slice(DEFLATE_PREFIX.length);
|
|
106
|
+
const bytes = base64ToU8(b64);
|
|
107
|
+
const decompressed = inflateSync(bytes);
|
|
108
|
+
return strFromU8(decompressed);
|
|
109
|
+
}
|
|
110
|
+
// Back-compat: older versions may have stored raw JSON without any prefix
|
|
111
|
+
if (isProbablyJson(stored)) return stored;
|
|
112
|
+
return null;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('Error getting item:', error);
|
|
115
|
+
return null;
|
|
183
116
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
117
|
+
},
|
|
118
|
+
setItem: (key, value) => {
|
|
119
|
+
try {
|
|
120
|
+
// Some upstream serializers can return `undefined` (e.g. JSON.stringify(undefined)).
|
|
121
|
+
const rawValue = value;
|
|
122
|
+
if (rawValue == null) {
|
|
123
|
+
pendingWrites.delete(key);
|
|
124
|
+
base.removeItem(key);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const stringValue = typeof rawValue === 'string' ? rawValue : String(rawValue);
|
|
128
|
+
pendingWrites.set(key, stringValue);
|
|
129
|
+
scheduleFlush();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('Error setting item:', error);
|
|
192
132
|
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
hasChangedDeps = true;
|
|
201
|
-
break;
|
|
133
|
+
},
|
|
134
|
+
removeItem: key => {
|
|
135
|
+
try {
|
|
136
|
+
pendingWrites.delete(key);
|
|
137
|
+
base.removeItem(key);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error('Error removing item:', error);
|
|
202
140
|
}
|
|
203
141
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
const baseStorage = {
|
|
145
|
+
getItem: key => {
|
|
146
|
+
if (typeof localStorage === 'undefined') return null;
|
|
147
|
+
return localStorage.getItem(key);
|
|
148
|
+
},
|
|
149
|
+
setItem: (key, value) => {
|
|
150
|
+
if (typeof localStorage === 'undefined') return;
|
|
151
|
+
localStorage.setItem(key, value);
|
|
152
|
+
},
|
|
153
|
+
removeItem: key => {
|
|
154
|
+
if (typeof localStorage === 'undefined') return;
|
|
155
|
+
localStorage.removeItem(key);
|
|
209
156
|
}
|
|
210
157
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
158
|
+
let storage = createCompressedStorage(baseStorage);// Implementazione
|
|
159
|
+
function atomStateGenerator({
|
|
160
|
+
key,
|
|
161
|
+
defaultValue,
|
|
162
|
+
persist = false,
|
|
163
|
+
storage: customStorage
|
|
164
|
+
}) {
|
|
165
|
+
const resolvedStorage = customStorage || storage;
|
|
166
|
+
// Usa atomWithStorage solo se persist è true, altrimenti atom normale
|
|
167
|
+
const jotaiAtom = persist ? atomWithStorage(key, defaultValue, createJSONStorage(() => resolvedStorage)) : atom(defaultValue);
|
|
168
|
+
const useValue = () => {
|
|
169
|
+
const [value] = useAtom(jotaiAtom);
|
|
170
|
+
return value;
|
|
171
|
+
};
|
|
172
|
+
const useState = () => {
|
|
173
|
+
const $ = c(3);
|
|
174
|
+
const [value, setValue] = useAtom(jotaiAtom);
|
|
175
|
+
let t0;
|
|
176
|
+
if ($[0] !== setValue || $[1] !== value) {
|
|
177
|
+
t0 = [value, setValue];
|
|
178
|
+
$[0] = setValue;
|
|
179
|
+
$[1] = value;
|
|
180
|
+
$[2] = t0;
|
|
181
|
+
} else {
|
|
182
|
+
t0 = $[2];
|
|
238
183
|
}
|
|
239
|
-
|
|
240
|
-
|
|
184
|
+
return t0;
|
|
185
|
+
};
|
|
186
|
+
const useReset = () => {
|
|
187
|
+
const $ = c(2);
|
|
188
|
+
const [, setValue] = useAtom(jotaiAtom);
|
|
189
|
+
let t0;
|
|
190
|
+
if ($[0] !== setValue) {
|
|
191
|
+
t0 = () => {
|
|
192
|
+
setValue(defaultValue);
|
|
193
|
+
if (persist) {
|
|
194
|
+
resolvedStorage.removeItem(key);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
$[0] = setValue;
|
|
198
|
+
$[1] = t0;
|
|
199
|
+
} else {
|
|
200
|
+
t0 = $[1];
|
|
241
201
|
}
|
|
202
|
+
return t0;
|
|
203
|
+
};
|
|
204
|
+
return {
|
|
205
|
+
atom: jotaiAtom,
|
|
206
|
+
useValue,
|
|
207
|
+
useState,
|
|
208
|
+
useReset
|
|
209
|
+
};
|
|
210
|
+
}// ============================================================================
|
|
211
|
+
// Default Values
|
|
212
|
+
// ============================================================================
|
|
213
|
+
const DEFAULT_QUERY_ENTRY = Object.freeze({
|
|
214
|
+
data: undefined,
|
|
215
|
+
isLoading: false,
|
|
216
|
+
isLoadingMapped: false,
|
|
217
|
+
isFetching: false,
|
|
218
|
+
isPending: false,
|
|
219
|
+
isSuccess: false,
|
|
220
|
+
isError: false,
|
|
221
|
+
isStale: false,
|
|
222
|
+
error: null,
|
|
223
|
+
dataUpdatedAt: 0,
|
|
224
|
+
errorUpdatedAt: 0,
|
|
225
|
+
fetchStatus: 'idle',
|
|
226
|
+
refetch: () => Promise.resolve()
|
|
227
|
+
});
|
|
228
|
+
const DEFAULT_MUTATION_ENTRY = Object.freeze({
|
|
229
|
+
data: undefined,
|
|
230
|
+
status: 'idle',
|
|
231
|
+
error: null,
|
|
232
|
+
variables: undefined,
|
|
233
|
+
submittedAt: 0,
|
|
234
|
+
isIdle: true,
|
|
235
|
+
isPending: false,
|
|
236
|
+
isSuccess: false,
|
|
237
|
+
isError: false,
|
|
238
|
+
mutate: () => {},
|
|
239
|
+
mutateAsync: async () => Promise.resolve(undefined),
|
|
240
|
+
reset: () => {},
|
|
241
|
+
context: 0,
|
|
242
|
+
failureCount: 0,
|
|
243
|
+
failureReason: null,
|
|
244
|
+
isPaused: false
|
|
245
|
+
});
|
|
246
|
+
// ============================================================================
|
|
247
|
+
// Global Atoms (single atom for all queries, single atom for all mutations)
|
|
248
|
+
// ============================================================================
|
|
249
|
+
/**
|
|
250
|
+
* Global atom storing all query results.
|
|
251
|
+
* Key format: "scopeId:queryKey"
|
|
252
|
+
*/
|
|
253
|
+
const queriesAtom = atomWithStorage('queries-atom', {}, createJSONStorage(() => storage), {
|
|
254
|
+
getOnInit: true
|
|
255
|
+
});
|
|
256
|
+
/**
|
|
257
|
+
* Global atom storing all mutation results.
|
|
258
|
+
* Key format: "scopeId:mutationKey"
|
|
259
|
+
*/
|
|
260
|
+
const mutationsAtom = atom({});
|
|
261
|
+
// ============================================================================
|
|
262
|
+
// Helper to generate composite keys
|
|
263
|
+
// ============================================================================
|
|
264
|
+
const getCompositeKey = (scopeId, key) => `${scopeId}:${key}`;const apiClient = axios.create({
|
|
265
|
+
timeout: 30000,
|
|
266
|
+
headers: {
|
|
267
|
+
'Content-Type': 'application/json'
|
|
242
268
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
269
|
+
});
|
|
270
|
+
apiClient.interceptors.response.use(response => response, error => {
|
|
271
|
+
var _a, _b;
|
|
272
|
+
if (error.response) {
|
|
273
|
+
throw new Error(((_a = error.response.data) === null || _a === void 0 ? void 0 : _a.message) || ((_b = error.response.data) === null || _b === void 0 ? void 0 : _b.error) || `Error ${error.response.status}`);
|
|
274
|
+
} else if (error.request) {
|
|
275
|
+
throw new Error('No response from server - request timeout or network issue');
|
|
276
|
+
} else {
|
|
277
|
+
throw new Error('Request configuration error');
|
|
251
278
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (isPendingPromise(atomState.v)) {
|
|
271
|
-
addPendingPromiseToDependency(atom, atomState.v, aState);
|
|
272
|
-
}
|
|
273
|
-
if (mountedMap.has(atom)) {
|
|
274
|
-
(_a2 = mountedMap.get(a)) == null ? void 0 : _a2.t.add(atom);
|
|
275
|
-
}
|
|
276
|
-
if (!isSync) {
|
|
277
|
-
mountDependenciesIfAsync();
|
|
279
|
+
});
|
|
280
|
+
const apiRequest = async ({
|
|
281
|
+
method,
|
|
282
|
+
url,
|
|
283
|
+
body,
|
|
284
|
+
headers,
|
|
285
|
+
converter
|
|
286
|
+
}) => {
|
|
287
|
+
try {
|
|
288
|
+
const isPrimitive = typeof body === 'string' || typeof body === 'number' || typeof body === 'boolean';
|
|
289
|
+
let finalUrl = url;
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
291
|
+
let finalBody = body;
|
|
292
|
+
// 1. Primitive Body Handling (Append to URL)
|
|
293
|
+
if (isPrimitive && body) {
|
|
294
|
+
if (method !== 'POST') {
|
|
295
|
+
finalUrl = `${url}/${body}`;
|
|
296
|
+
finalBody = undefined;
|
|
278
297
|
}
|
|
279
298
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
console.warn("setSelf function cannot be used with read-only atom");
|
|
298
|
-
}
|
|
299
|
-
if (!setSelf && isActuallyWritableAtom(atom)) {
|
|
300
|
-
setSelf = (...args) => {
|
|
301
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && isSync) {
|
|
302
|
-
console.warn("setSelf function cannot be called in sync");
|
|
303
|
-
}
|
|
304
|
-
if (!isSync) {
|
|
305
|
-
try {
|
|
306
|
-
return writeAtomState(store, atom, ...args);
|
|
307
|
-
} finally {
|
|
308
|
-
recomputeInvalidatedAtoms(store);
|
|
309
|
-
flushCallbacks(store);
|
|
299
|
+
// 2. Object Body Handling (Path Param Replacement)
|
|
300
|
+
if (!isPrimitive && typeof body === 'object' && body !== null) {
|
|
301
|
+
// Look for :param in string
|
|
302
|
+
// e.g. /users/:uid/availability
|
|
303
|
+
const pathParams = finalUrl.match(/:[a-zA-Z0-9_]+/g);
|
|
304
|
+
if (pathParams) {
|
|
305
|
+
// Create shallow copy to avoid mutating original
|
|
306
|
+
finalBody = Object.assign({}, body);
|
|
307
|
+
pathParams.forEach(param => {
|
|
308
|
+
if (finalBody) {
|
|
309
|
+
const key = param.substring(1); // remove :
|
|
310
|
+
if (key in finalBody) {
|
|
311
|
+
finalUrl = finalUrl.replace(param, String(finalBody[key]));
|
|
312
|
+
// Optional: remove from body if it was used in path?
|
|
313
|
+
// Usually yes for simple IDs, maybe not for others.
|
|
314
|
+
// Let's remove to keep body clean.
|
|
315
|
+
delete finalBody[key];
|
|
310
316
|
}
|
|
311
317
|
}
|
|
312
|
-
};
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
// Also handle case where we append ID to end if URL ends with / and we have 'id' or 'uid' in body?
|
|
321
|
+
// No, explicit :param or explicit append logic is safer.
|
|
322
|
+
// But we have logic for 'updateUser' where we just set endpoint ['api', 'users'] and method PUT.
|
|
323
|
+
// We expect /users/123.
|
|
324
|
+
// If body is { uid: 123, ...data }, we want /users/123.
|
|
325
|
+
// If no :param is found, and method is PUT/DELETE/PATCH, and body has 'id' or 'uid', should we append?
|
|
326
|
+
// User asked to eliminate customRequest.
|
|
327
|
+
// Let's add: "If method is PUT/DELETE/PATCH, and no :param replacement happened, and body has (id|uid), append it."
|
|
328
|
+
const hasId = 'id' in finalBody || 'uid' in finalBody;
|
|
329
|
+
if ((method === 'PUT' || method === 'DELETE' || method === 'PATCH') && hasId && !pathParams) {
|
|
330
|
+
const id = finalBody.id || finalBody.uid;
|
|
331
|
+
if (id) {
|
|
332
|
+
finalUrl = `${finalUrl}/${id}`;
|
|
333
|
+
// We generally DON'T remove ID from body in this implicit case as it might be needed for validation
|
|
334
|
+
// But for cleaner API calls we might want to.
|
|
335
|
+
// Let's keep it safe: Don't remove ID here.
|
|
336
|
+
}
|
|
313
337
|
}
|
|
314
|
-
return setSelf;
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
const prevEpochNumber = atomState.n;
|
|
318
|
-
try {
|
|
319
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
|
320
|
-
storeMutationSet.delete(store);
|
|
321
|
-
}
|
|
322
|
-
const valueOrPromise = atomRead(store, atom, getter, options);
|
|
323
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && storeMutationSet.has(store)) {
|
|
324
|
-
console.warn(
|
|
325
|
-
"Detected store mutation during atom read. This is not supported."
|
|
326
|
-
);
|
|
327
338
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
339
|
+
const data = converter && finalBody ? converter(finalBody) : finalBody;
|
|
340
|
+
const response = await apiClient({
|
|
341
|
+
url: finalUrl,
|
|
342
|
+
method,
|
|
343
|
+
data,
|
|
344
|
+
headers
|
|
345
|
+
});
|
|
346
|
+
if (response.status >= 200 && response.status < 300) {
|
|
347
|
+
return response.data;
|
|
332
348
|
}
|
|
333
|
-
|
|
334
|
-
return atomState;
|
|
349
|
+
throw new Error(`Request failed with status ${response.status}`);
|
|
335
350
|
} catch (error) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return atomState;
|
|
340
|
-
} finally {
|
|
341
|
-
isSync = false;
|
|
342
|
-
if (prevEpochNumber !== atomState.n && invalidatedAtoms.get(atom) === prevEpochNumber) {
|
|
343
|
-
invalidatedAtoms.set(atom, atomState.n);
|
|
344
|
-
changedAtoms.add(atom);
|
|
345
|
-
(_b = storeHooks.c) == null ? void 0 : _b.call(storeHooks, atom);
|
|
351
|
+
console.error('API Request Error:', error);
|
|
352
|
+
if (error instanceof Error) {
|
|
353
|
+
throw error;
|
|
346
354
|
}
|
|
355
|
+
throw new Error('Unknown error occurred');
|
|
347
356
|
}
|
|
357
|
+
};const _endpoints = {
|
|
358
|
+
custom: '',
|
|
359
|
+
api: 'http://localhost:3000' // import.meta.env.VITE_API_URL ||
|
|
348
360
|
};
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const stack = [atom];
|
|
355
|
-
while (stack.length) {
|
|
356
|
-
const a = stack.pop();
|
|
357
|
-
const aState = ensureAtomState(store, a);
|
|
358
|
-
for (const d of getMountedOrPendingDependents(a, aState, mountedMap)) {
|
|
359
|
-
const dState = ensureAtomState(store, d);
|
|
360
|
-
invalidatedAtoms.set(d, dState.n);
|
|
361
|
-
stack.push(d);
|
|
361
|
+
const defaultQueryClient = new QueryClient({
|
|
362
|
+
defaultOptions: {
|
|
363
|
+
queries: {
|
|
364
|
+
retry: 2
|
|
365
|
+
// staleTime: 2 * 60 * 1000,
|
|
362
366
|
}
|
|
363
367
|
}
|
|
364
|
-
};
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
368
|
+
});
|
|
369
|
+
const {
|
|
370
|
+
useValue: useApiConfigValue} = atomStateGenerator({
|
|
371
|
+
key: 'apiConfig',
|
|
372
|
+
defaultValue: {
|
|
373
|
+
endpoints: _endpoints,
|
|
374
|
+
requestFn: apiRequest,
|
|
375
|
+
queryClient: defaultQueryClient
|
|
376
|
+
},
|
|
377
|
+
persist: false
|
|
378
|
+
});const useMultipleQuery = t0 => {
|
|
379
|
+
const $ = c(30);
|
|
380
|
+
let t1;
|
|
381
|
+
if ($[0] !== t0) {
|
|
382
|
+
t1 = t0 === undefined ? [] : t0;
|
|
383
|
+
$[0] = t0;
|
|
384
|
+
$[1] = t1;
|
|
385
|
+
} else {
|
|
386
|
+
t1 = $[1];
|
|
387
|
+
}
|
|
388
|
+
const settings = t1;
|
|
389
|
+
const {
|
|
390
|
+
requestFn,
|
|
391
|
+
validateAuthFn,
|
|
392
|
+
defaultHeaders,
|
|
393
|
+
queryClient,
|
|
394
|
+
endpoints
|
|
395
|
+
} = useApiConfigValue();
|
|
396
|
+
let t2;
|
|
397
|
+
if ($[2] !== endpoints) {
|
|
398
|
+
t2 = endpoint => {
|
|
399
|
+
const [key, path] = endpoint;
|
|
400
|
+
const baseUrl = endpoints[key];
|
|
401
|
+
return [baseUrl, path].filter(Boolean).join("/");
|
|
402
|
+
};
|
|
403
|
+
$[2] = endpoints;
|
|
404
|
+
$[3] = t2;
|
|
405
|
+
} else {
|
|
406
|
+
t2 = $[3];
|
|
407
|
+
}
|
|
408
|
+
const generateEndpoint = t2;
|
|
409
|
+
let t3;
|
|
410
|
+
if ($[4] !== validateAuthFn) {
|
|
411
|
+
t3 = validateAuthFn ? validateAuthFn() : true;
|
|
412
|
+
$[4] = validateAuthFn;
|
|
413
|
+
$[5] = t3;
|
|
414
|
+
} else {
|
|
415
|
+
t3 = $[5];
|
|
416
|
+
}
|
|
417
|
+
const isLogged = t3;
|
|
418
|
+
let t4;
|
|
419
|
+
if ($[6] !== defaultHeaders || $[7] !== generateEndpoint || $[8] !== requestFn) {
|
|
420
|
+
t4 = async t5 => {
|
|
421
|
+
const {
|
|
422
|
+
endpoint: endpoint_0,
|
|
423
|
+
customQueryFn,
|
|
424
|
+
headers
|
|
425
|
+
} = t5;
|
|
426
|
+
const fullEndpoint = generateEndpoint(endpoint_0);
|
|
427
|
+
if (customQueryFn) {
|
|
428
|
+
const res = await customQueryFn();
|
|
429
|
+
return res;
|
|
430
|
+
}
|
|
431
|
+
const mergedHeaders = Object.assign(Object.assign({}, defaultHeaders), headers);
|
|
432
|
+
return await requestFn({
|
|
433
|
+
url: fullEndpoint,
|
|
434
|
+
method: "GET",
|
|
435
|
+
headers: mergedHeaders
|
|
436
|
+
});
|
|
437
|
+
};
|
|
438
|
+
$[6] = defaultHeaders;
|
|
439
|
+
$[7] = generateEndpoint;
|
|
440
|
+
$[8] = requestFn;
|
|
441
|
+
$[9] = t4;
|
|
442
|
+
} else {
|
|
443
|
+
t4 = $[9];
|
|
444
|
+
}
|
|
445
|
+
const generateQueryFn = t4;
|
|
446
|
+
let t5;
|
|
447
|
+
let t6;
|
|
448
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
449
|
+
t5 = {};
|
|
450
|
+
t6 = {};
|
|
451
|
+
$[10] = t5;
|
|
452
|
+
$[11] = t6;
|
|
453
|
+
} else {
|
|
454
|
+
t5 = $[10];
|
|
455
|
+
t6 = $[11];
|
|
456
|
+
}
|
|
457
|
+
let t7;
|
|
458
|
+
if ($[12] !== settings) {
|
|
459
|
+
t7 = {
|
|
460
|
+
settings,
|
|
461
|
+
data: t5,
|
|
462
|
+
results: t6
|
|
463
|
+
};
|
|
464
|
+
$[12] = settings;
|
|
465
|
+
$[13] = t7;
|
|
466
|
+
} else {
|
|
467
|
+
t7 = $[13];
|
|
468
|
+
}
|
|
469
|
+
const ref = useRef(t7);
|
|
470
|
+
let t8;
|
|
471
|
+
let t9;
|
|
472
|
+
if ($[14] !== settings) {
|
|
473
|
+
t8 = () => {
|
|
474
|
+
ref.current.settings = settings;
|
|
475
|
+
};
|
|
476
|
+
t9 = [settings];
|
|
477
|
+
$[14] = settings;
|
|
478
|
+
$[15] = t8;
|
|
479
|
+
$[16] = t9;
|
|
480
|
+
} else {
|
|
481
|
+
t8 = $[15];
|
|
482
|
+
t9 = $[16];
|
|
483
|
+
}
|
|
484
|
+
useEffect(t8, t9);
|
|
485
|
+
let t10;
|
|
486
|
+
if ($[17] !== generateQueryFn || $[18] !== isLogged || $[19] !== settings) {
|
|
487
|
+
let t11;
|
|
488
|
+
if ($[21] !== generateQueryFn || $[22] !== isLogged) {
|
|
489
|
+
t11 = setting => {
|
|
490
|
+
const {
|
|
491
|
+
queryKey,
|
|
492
|
+
enabled: t12,
|
|
493
|
+
disableAuthControl
|
|
494
|
+
} = setting;
|
|
495
|
+
const enabled = t12 === undefined ? true : t12;
|
|
496
|
+
const rest = __rest(setting, ["queryKey", "enabled", "disableAuthControl"]);
|
|
497
|
+
return Object.assign({
|
|
498
|
+
queryKey,
|
|
499
|
+
queryFn: () => generateQueryFn(setting),
|
|
500
|
+
enabled: !!enabled && (disableAuthControl || !!isLogged)
|
|
501
|
+
}, rest);
|
|
502
|
+
};
|
|
503
|
+
$[21] = generateQueryFn;
|
|
504
|
+
$[22] = isLogged;
|
|
505
|
+
$[23] = t11;
|
|
506
|
+
} else {
|
|
507
|
+
t11 = $[23];
|
|
508
|
+
}
|
|
509
|
+
t10 = settings.map(t11);
|
|
510
|
+
$[17] = generateQueryFn;
|
|
511
|
+
$[18] = isLogged;
|
|
512
|
+
$[19] = settings;
|
|
513
|
+
$[20] = t10;
|
|
514
|
+
} else {
|
|
515
|
+
t10 = $[20];
|
|
516
|
+
}
|
|
517
|
+
const queries = t10;
|
|
518
|
+
let t11;
|
|
519
|
+
if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
|
|
520
|
+
t11 = results => results.reduce((prev, result, index) => {
|
|
521
|
+
const setting_0 = ref.current.settings[index];
|
|
522
|
+
const keyToMap = setting_0.keyToMap;
|
|
523
|
+
Object.assign(prev, {
|
|
524
|
+
[keyToMap]: {
|
|
525
|
+
data: result.data,
|
|
526
|
+
isLoadingMapped: !setting_0.disableLoading && result.isLoading,
|
|
527
|
+
isLoading: result.isLoading,
|
|
528
|
+
isFetching: result.isFetching,
|
|
529
|
+
isPending: result.isPending,
|
|
530
|
+
error: result.error,
|
|
531
|
+
refetch: result.refetch
|
|
387
532
|
}
|
|
388
|
-
|
|
389
|
-
|
|
533
|
+
});
|
|
534
|
+
return prev;
|
|
535
|
+
}, {});
|
|
536
|
+
$[24] = t11;
|
|
537
|
+
} else {
|
|
538
|
+
t11 = $[24];
|
|
539
|
+
}
|
|
540
|
+
const combine = t11;
|
|
541
|
+
let t12;
|
|
542
|
+
if ($[25] !== queries) {
|
|
543
|
+
t12 = {
|
|
544
|
+
queries,
|
|
545
|
+
combine
|
|
546
|
+
};
|
|
547
|
+
$[25] = queries;
|
|
548
|
+
$[26] = t12;
|
|
549
|
+
} else {
|
|
550
|
+
t12 = $[26];
|
|
551
|
+
}
|
|
552
|
+
const result_0 = useQueries(t12, queryClient);
|
|
553
|
+
let t13;
|
|
554
|
+
let t14;
|
|
555
|
+
if ($[27] !== result_0) {
|
|
556
|
+
t13 = () => {
|
|
557
|
+
ref.current.settings.forEach(setting_1 => {
|
|
558
|
+
const {
|
|
559
|
+
keyToMap: keyToMap_0,
|
|
560
|
+
onDataChanged,
|
|
561
|
+
onStateChange
|
|
562
|
+
} = setting_1;
|
|
563
|
+
if (!onDataChanged && !onStateChange) {
|
|
564
|
+
return;
|
|
390
565
|
}
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
(_a = storeHooks.c) == null ? void 0 : _a.call(storeHooks, a);
|
|
566
|
+
const currentResult = result_0[keyToMap_0];
|
|
567
|
+
const prevResult = ref.current.results[keyToMap_0];
|
|
568
|
+
if (onStateChange) {
|
|
569
|
+
if (!prevResult || prevResult.data !== currentResult.data || prevResult.isLoading !== currentResult.isLoading || prevResult.isLoadingMapped !== currentResult.isLoadingMapped || prevResult.isFetching !== currentResult.isFetching || prevResult.isPending !== currentResult.isPending || prevResult.error !== currentResult.error) {
|
|
570
|
+
ref.current.results[keyToMap_0] = currentResult;
|
|
571
|
+
onStateChange(currentResult);
|
|
572
|
+
}
|
|
399
573
|
}
|
|
400
|
-
|
|
574
|
+
if (onDataChanged) {
|
|
575
|
+
const currentData = currentResult.data;
|
|
576
|
+
const prevData = ref.current.data[keyToMap_0];
|
|
577
|
+
if (currentData !== undefined && currentData !== prevData) {
|
|
578
|
+
ref.current.data[keyToMap_0] = currentData;
|
|
579
|
+
onDataChanged(currentData);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
};
|
|
584
|
+
t14 = [result_0];
|
|
585
|
+
$[27] = result_0;
|
|
586
|
+
$[28] = t13;
|
|
587
|
+
$[29] = t14;
|
|
588
|
+
} else {
|
|
589
|
+
t13 = $[28];
|
|
590
|
+
t14 = $[29];
|
|
591
|
+
}
|
|
592
|
+
useEffect(t13, t14);
|
|
593
|
+
return result_0;
|
|
594
|
+
};/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
595
|
+
const defaultState = DEFAULT_MUTATION_ENTRY;
|
|
596
|
+
const mutationReducer = (state, action) => {
|
|
597
|
+
switch (action.type) {
|
|
598
|
+
case "RESET":
|
|
599
|
+
return Object.assign(Object.assign({}, state), {
|
|
600
|
+
[action.key]: Object.assign({}, defaultState)
|
|
601
|
+
});
|
|
602
|
+
case "PENDING":
|
|
603
|
+
return Object.assign(Object.assign({}, state), {
|
|
604
|
+
[action.key]: {
|
|
605
|
+
status: "pending",
|
|
606
|
+
data: undefined,
|
|
607
|
+
error: null,
|
|
608
|
+
submittedAt: action.submittedAt,
|
|
609
|
+
variables: action.variables
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
case "SUCCESS":
|
|
613
|
+
return Object.assign(Object.assign({}, state), {
|
|
614
|
+
[action.key]: Object.assign(Object.assign({}, state[action.key]), {
|
|
615
|
+
status: "success",
|
|
616
|
+
data: action.data,
|
|
617
|
+
error: null
|
|
618
|
+
})
|
|
619
|
+
});
|
|
620
|
+
case "ERROR":
|
|
621
|
+
return Object.assign(Object.assign({}, state), {
|
|
622
|
+
[action.key]: Object.assign(Object.assign({}, state[action.key]), {
|
|
623
|
+
status: "error",
|
|
624
|
+
error: action.error
|
|
625
|
+
})
|
|
626
|
+
});
|
|
627
|
+
default:
|
|
628
|
+
return state;
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
const initMutationStates = configs => {
|
|
632
|
+
const states = {};
|
|
633
|
+
configs.forEach(config => {
|
|
634
|
+
states[config.key] = Object.assign({}, defaultState);
|
|
635
|
+
});
|
|
636
|
+
return states;
|
|
637
|
+
};
|
|
638
|
+
const useMultipleMutation = configs => {
|
|
639
|
+
const {
|
|
640
|
+
requestFn,
|
|
641
|
+
validateAuthFn,
|
|
642
|
+
defaultHeaders,
|
|
643
|
+
queryClient,
|
|
644
|
+
showNotification,
|
|
645
|
+
endpoints
|
|
646
|
+
} = useApiConfigValue();
|
|
647
|
+
const [reducerStates, dispatchReducer] = useReducer(mutationReducer, configs, initMutationStates);
|
|
648
|
+
// Accessor for current state
|
|
649
|
+
const getState = useCallback(key => {
|
|
650
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
651
|
+
return reducerStates[key] || defaultState;
|
|
652
|
+
}, [reducerStates]);
|
|
653
|
+
// Dispatcher that handles both modes
|
|
654
|
+
const dispatch = useCallback(action => {
|
|
655
|
+
dispatchReducer(action);
|
|
656
|
+
}, []);
|
|
657
|
+
const executeMutation = useCallback(async (key_0, config, data, mutationOptions) => {
|
|
658
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
659
|
+
const {
|
|
660
|
+
endpoint,
|
|
661
|
+
method,
|
|
662
|
+
headers,
|
|
663
|
+
queryKeyToInvalidate,
|
|
664
|
+
customRequest,
|
|
665
|
+
converter,
|
|
666
|
+
isTest,
|
|
667
|
+
notification,
|
|
668
|
+
mutateOptions
|
|
669
|
+
} = config;
|
|
670
|
+
dispatch({
|
|
671
|
+
type: "PENDING",
|
|
672
|
+
key: key_0,
|
|
673
|
+
submittedAt: Date.now(),
|
|
674
|
+
variables: data
|
|
675
|
+
});
|
|
676
|
+
let context;
|
|
677
|
+
try {
|
|
678
|
+
// Auth validation
|
|
679
|
+
const isValidAuth = validateAuthFn ? validateAuthFn() : true;
|
|
680
|
+
if (!isValidAuth) {
|
|
681
|
+
throw new Error("Utente non autenticato");
|
|
682
|
+
}
|
|
683
|
+
// Build endpoint
|
|
684
|
+
const [endpointKey, path] = endpoint;
|
|
685
|
+
const baseUrl = (_a = endpoints[endpointKey]) !== null && _a !== void 0 ? _a : "";
|
|
686
|
+
const fullEndpoint = [baseUrl, path].filter(Boolean).join("/");
|
|
687
|
+
// Merge headers
|
|
688
|
+
const mergedHeaders = Object.assign(Object.assign({}, defaultHeaders), headers);
|
|
689
|
+
// Execute request
|
|
690
|
+
let result;
|
|
691
|
+
if (isTest) {
|
|
692
|
+
result = "test";
|
|
693
|
+
} else if (customRequest) {
|
|
694
|
+
result = await customRequest(fullEndpoint, method, data);
|
|
401
695
|
} else {
|
|
402
|
-
|
|
696
|
+
result = await requestFn({
|
|
697
|
+
url: fullEndpoint,
|
|
698
|
+
method,
|
|
699
|
+
body: data,
|
|
700
|
+
headers: mergedHeaders,
|
|
701
|
+
converter
|
|
702
|
+
});
|
|
403
703
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
704
|
+
dispatch({
|
|
705
|
+
type: "SUCCESS",
|
|
706
|
+
key: key_0,
|
|
707
|
+
data: result
|
|
708
|
+
});
|
|
709
|
+
// Invalidate queries
|
|
710
|
+
if (queryKeyToInvalidate) {
|
|
711
|
+
queryKeyToInvalidate.forEach(qKey => {
|
|
712
|
+
queryClient.invalidateQueries({
|
|
713
|
+
queryKey: [qKey],
|
|
714
|
+
exact: false
|
|
715
|
+
});
|
|
716
|
+
});
|
|
408
717
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
};
|
|
417
|
-
const BUILDING_BLOCK_mountDependencies = (store, atom) => {
|
|
418
|
-
var _a;
|
|
419
|
-
const buildingBlocks = getInternalBuildingBlocks(store);
|
|
420
|
-
const mountedMap = buildingBlocks[1];
|
|
421
|
-
const changedAtoms = buildingBlocks[3];
|
|
422
|
-
const storeHooks = buildingBlocks[6];
|
|
423
|
-
const ensureAtomState = buildingBlocks[11];
|
|
424
|
-
const invalidateDependents = buildingBlocks[15];
|
|
425
|
-
const mountAtom = buildingBlocks[18];
|
|
426
|
-
const unmountAtom = buildingBlocks[19];
|
|
427
|
-
const atomState = ensureAtomState(store, atom);
|
|
428
|
-
const mounted = mountedMap.get(atom);
|
|
429
|
-
if (mounted && !isPendingPromise(atomState.v)) {
|
|
430
|
-
for (const [a, n] of atomState.d) {
|
|
431
|
-
if (!mounted.d.has(a)) {
|
|
432
|
-
const aState = ensureAtomState(store, a);
|
|
433
|
-
const aMounted = mountAtom(store, a);
|
|
434
|
-
aMounted.t.add(atom);
|
|
435
|
-
mounted.d.add(a);
|
|
436
|
-
if (n !== aState.n) {
|
|
437
|
-
changedAtoms.add(a);
|
|
438
|
-
invalidateDependents(store, a);
|
|
439
|
-
(_a = storeHooks.c) == null ? void 0 : _a.call(storeHooks, a);
|
|
440
|
-
}
|
|
718
|
+
// Success notification
|
|
719
|
+
const notificationProps_0 = typeof (notification === null || notification === void 0 ? void 0 : notification.success) === "function" ? notification.success(result) : notification === null || notification === void 0 ? void 0 : notification.success;
|
|
720
|
+
if (notificationProps_0 === null || notificationProps_0 === void 0 ? void 0 : notificationProps_0.message) {
|
|
721
|
+
showNotification === null || showNotification === void 0 ? void 0 : showNotification(Object.assign({
|
|
722
|
+
message: notificationProps_0.message,
|
|
723
|
+
type: (_b = notificationProps_0.type) !== null && _b !== void 0 ? _b : "success"
|
|
724
|
+
}, notificationProps_0));
|
|
441
725
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
726
|
+
// Callbacks
|
|
727
|
+
// @ts-expect-error - MutateOptions callback signature varies by TanStack Query version
|
|
728
|
+
(_c = mutateOptions === null || mutateOptions === void 0 ? void 0 : mutateOptions.onSuccess) === null || _c === void 0 ? void 0 : _c.call(mutateOptions, result, data, context);
|
|
729
|
+
(_d = mutationOptions === null || mutationOptions === void 0 ? void 0 : mutationOptions.onSuccess) === null || _d === void 0 ? void 0 : _d.call(mutationOptions, result, data, undefined, context);
|
|
730
|
+
return result;
|
|
731
|
+
} catch (error) {
|
|
732
|
+
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
733
|
+
dispatch({
|
|
734
|
+
type: "ERROR",
|
|
735
|
+
key: key_0,
|
|
736
|
+
error: err
|
|
737
|
+
});
|
|
738
|
+
// Error notification
|
|
739
|
+
const notificationProps = typeof (notification === null || notification === void 0 ? void 0 : notification.error) === "function" ? notification.error(err.message) : notification === null || notification === void 0 ? void 0 : notification.error;
|
|
740
|
+
if ((notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) || err.message) {
|
|
741
|
+
showNotification === null || showNotification === void 0 ? void 0 : showNotification(Object.assign({
|
|
742
|
+
message: (notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) || err.message || "An unexpected error occurred",
|
|
743
|
+
type: (_e = notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.type) !== null && _e !== void 0 ? _e : "error"
|
|
744
|
+
}, notificationProps));
|
|
448
745
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const atomState = ensureAtomState(store, atom);
|
|
466
|
-
let mounted = mountedMap.get(atom);
|
|
467
|
-
if (!mounted) {
|
|
468
|
-
readAtomState(store, atom);
|
|
469
|
-
for (const a of atomState.d.keys()) {
|
|
470
|
-
const aMounted = mountAtom(store, a);
|
|
471
|
-
aMounted.t.add(atom);
|
|
472
|
-
}
|
|
473
|
-
mounted = {
|
|
474
|
-
l: /* @__PURE__ */ new Set(),
|
|
475
|
-
d: new Set(atomState.d.keys()),
|
|
476
|
-
t: /* @__PURE__ */ new Set()
|
|
746
|
+
// Callbacks
|
|
747
|
+
// @ts-expect-error - MutateOptions callback signature varies by TanStack Query version
|
|
748
|
+
(_f = mutateOptions === null || mutateOptions === void 0 ? void 0 : mutateOptions.onError) === null || _f === void 0 ? void 0 : _f.call(mutateOptions, err, data, context);
|
|
749
|
+
(_g = mutationOptions === null || mutationOptions === void 0 ? void 0 : mutationOptions.onError) === null || _g === void 0 ? void 0 : _g.call(mutationOptions, err, data, undefined, context);
|
|
750
|
+
throw err;
|
|
751
|
+
}
|
|
752
|
+
}, [queryClient, validateAuthFn, defaultHeaders, endpoints, requestFn, showNotification, dispatch // dispatch is now stable/wrapped
|
|
753
|
+
]);
|
|
754
|
+
const ref = useRef({
|
|
755
|
+
dispatch,
|
|
756
|
+
executeMutation
|
|
757
|
+
});
|
|
758
|
+
useEffect(() => {
|
|
759
|
+
ref.current = {
|
|
760
|
+
dispatch,
|
|
761
|
+
executeMutation
|
|
477
762
|
};
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
763
|
+
}, [dispatch, executeMutation]);
|
|
764
|
+
const allMutation = useMemo(() => {
|
|
765
|
+
const result_0 = {};
|
|
766
|
+
configs.forEach(item => {
|
|
767
|
+
var _a_0, _b_0, _c_0;
|
|
768
|
+
// In silent mode, this is just the INITIAL state (or whatever triggered last render).
|
|
769
|
+
// The real data comes from Proxy if used.
|
|
770
|
+
const state = getState(item.key);
|
|
771
|
+
const mutationConfig = item.mutationConfig;
|
|
772
|
+
const mutationKey = item.key;
|
|
773
|
+
result_0[mutationKey] = {
|
|
774
|
+
// State
|
|
775
|
+
data: state.data,
|
|
776
|
+
error: state.error,
|
|
777
|
+
isIdle: state.status === "idle",
|
|
778
|
+
isPending: state.status === "pending",
|
|
779
|
+
isSuccess: state.status === "success",
|
|
780
|
+
isError: state.status === "error",
|
|
781
|
+
status: state.status,
|
|
782
|
+
variables: state.variables,
|
|
783
|
+
submittedAt: (_a_0 = state.submittedAt) !== null && _a_0 !== void 0 ? _a_0 : 0,
|
|
784
|
+
endpoint: mutationConfig.endpoint,
|
|
785
|
+
// Methods
|
|
786
|
+
mutate: (data_0, mutationOptions_0) => {
|
|
787
|
+
ref.current.executeMutation(item.key, mutationConfig, data_0, mutationOptions_0);
|
|
788
|
+
},
|
|
789
|
+
mutateAsync: (data_1, mutationOptions_1) => {
|
|
790
|
+
return ref.current.executeMutation(item.key, mutationConfig, data_1, mutationOptions_1);
|
|
791
|
+
},
|
|
792
|
+
reset: () => ref.current.dispatch({
|
|
793
|
+
type: "RESET",
|
|
794
|
+
key: item.key
|
|
795
|
+
}),
|
|
796
|
+
// Compatibility fields
|
|
797
|
+
failureCount: 0,
|
|
798
|
+
failureReason: null,
|
|
799
|
+
context: undefined,
|
|
800
|
+
isPaused: false
|
|
801
|
+
};
|
|
802
|
+
(_c_0 = (_b_0 = item.mutationConfig).onStateChange) === null || _c_0 === void 0 ? void 0 : _c_0.call(_b_0, result_0[mutationKey]);
|
|
803
|
+
});
|
|
804
|
+
return result_0;
|
|
805
|
+
}, [getState, configs]);
|
|
806
|
+
return allMutation;
|
|
807
|
+
};const useMultipleWebSocket = (configs = []) => {
|
|
808
|
+
const {
|
|
809
|
+
websocketConfig
|
|
810
|
+
} = useApiConfigValue();
|
|
811
|
+
const {
|
|
812
|
+
queryClient
|
|
813
|
+
} = useApiConfigValue();
|
|
814
|
+
const socketsRef = useRef(new Map());
|
|
815
|
+
const [statuses, setStatuses] = useState(new Map());
|
|
816
|
+
const [lastMessages, setLastMessages] = useState(new Map());
|
|
817
|
+
// Stabilize configs reference
|
|
818
|
+
const stableConfigs = useMemo(() => configs, [configs]);
|
|
819
|
+
useEffect(() => {
|
|
820
|
+
const sockets = socketsRef.current;
|
|
821
|
+
stableConfigs.forEach(config => {
|
|
822
|
+
const url = config.endpoint || (websocketConfig === null || websocketConfig === void 0 ? void 0 : websocketConfig.url);
|
|
823
|
+
const shouldConnect = config.autoConnect !== false && ((websocketConfig === null || websocketConfig === void 0 ? void 0 : websocketConfig.autoConnect) || config.endpoint);
|
|
824
|
+
if (!url || !shouldConnect) return;
|
|
825
|
+
// Skip if already connected
|
|
826
|
+
if (sockets.has(config.key)) return;
|
|
827
|
+
setStatuses(prev => new Map(prev).set(config.key, 'connecting'));
|
|
828
|
+
const ws = new WebSocket(url);
|
|
829
|
+
sockets.set(config.key, ws);
|
|
830
|
+
ws.onopen = () => {
|
|
831
|
+
setStatuses(prev_0 => new Map(prev_0).set(config.key, 'open'));
|
|
832
|
+
console.log(`WebSocket [${config.key}] connected`);
|
|
833
|
+
};
|
|
834
|
+
ws.onmessage = event => {
|
|
835
|
+
var _a, _b;
|
|
492
836
|
try {
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
837
|
+
const data = JSON.parse(event.data);
|
|
838
|
+
setLastMessages(prev_1 => new Map(prev_1).set(config.key, data));
|
|
839
|
+
// Global handler
|
|
840
|
+
(_a = websocketConfig === null || websocketConfig === void 0 ? void 0 : websocketConfig.onMessage) === null || _a === void 0 ? void 0 : _a.call(websocketConfig, data);
|
|
841
|
+
// Local handler
|
|
842
|
+
(_b = config.onMessage) === null || _b === void 0 ? void 0 : _b.call(config, data);
|
|
843
|
+
// Auto invalidation
|
|
844
|
+
if (config.invalidateQueriesOnMessage && Array.isArray(config.invalidateQueriesOnMessage)) {
|
|
845
|
+
config.invalidateQueriesOnMessage.forEach(key => {
|
|
846
|
+
queryClient.invalidateQueries({
|
|
847
|
+
queryKey: [key],
|
|
848
|
+
exact: false
|
|
849
|
+
});
|
|
850
|
+
});
|
|
503
851
|
}
|
|
504
|
-
}
|
|
505
|
-
|
|
852
|
+
} catch (e) {
|
|
853
|
+
console.error(`WebSocket [${config.key}] message parse error`, e);
|
|
506
854
|
}
|
|
507
855
|
};
|
|
508
|
-
|
|
856
|
+
ws.onclose = () => {
|
|
857
|
+
setStatuses(prev_2 => new Map(prev_2).set(config.key, 'closed'));
|
|
858
|
+
console.log(`WebSocket [${config.key}] disconnected`);
|
|
859
|
+
sockets.delete(config.key);
|
|
860
|
+
};
|
|
861
|
+
});
|
|
862
|
+
return () => {
|
|
863
|
+
sockets.forEach((ws_0, key_0) => {
|
|
864
|
+
ws_0.close();
|
|
865
|
+
sockets.delete(key_0);
|
|
866
|
+
});
|
|
867
|
+
};
|
|
868
|
+
}, [stableConfigs, websocketConfig, queryClient]);
|
|
869
|
+
const createSendMessage = useCallback(key_1 => message => {
|
|
870
|
+
const ws_1 = socketsRef.current.get(key_1);
|
|
871
|
+
if ((ws_1 === null || ws_1 === void 0 ? void 0 : ws_1.readyState) === WebSocket.OPEN) {
|
|
872
|
+
ws_1.send(JSON.stringify(message));
|
|
873
|
+
} else {
|
|
874
|
+
console.warn(`WebSocket [${key_1}] is not open`);
|
|
875
|
+
}
|
|
876
|
+
}, []);
|
|
877
|
+
const result = useMemo(() => {
|
|
878
|
+
const mapped = {};
|
|
879
|
+
stableConfigs.forEach(config_0 => {
|
|
880
|
+
var _a_0, _b_0;
|
|
881
|
+
mapped[config_0.key] = {
|
|
882
|
+
lastMessage: (_a_0 = lastMessages.get(config_0.key)) !== null && _a_0 !== void 0 ? _a_0 : null,
|
|
883
|
+
sendMessage: createSendMessage(config_0.key),
|
|
884
|
+
status: (_b_0 = statuses.get(config_0.key)) !== null && _b_0 !== void 0 ? _b_0 : 'closed'
|
|
885
|
+
};
|
|
886
|
+
});
|
|
887
|
+
return mapped;
|
|
888
|
+
}, [stableConfigs, lastMessages, statuses, createSendMessage]);
|
|
889
|
+
return result;
|
|
890
|
+
};function useApi(configs, optionsOrId) {
|
|
891
|
+
const options = typeof optionsOrId === 'string' ? {
|
|
892
|
+
scopeId: optionsOrId
|
|
893
|
+
} : optionsOrId !== null && optionsOrId !== void 0 ? optionsOrId : {};
|
|
894
|
+
const {
|
|
895
|
+
scopeId = 'default',
|
|
896
|
+
persistToAtoms = true
|
|
897
|
+
} = options;
|
|
898
|
+
// Global atom setters
|
|
899
|
+
const setQueriesAtom = useSetAtom(queriesAtom);
|
|
900
|
+
const setMutationsAtom = useSetAtom(mutationsAtom);
|
|
901
|
+
// Update a single query in the global atom
|
|
902
|
+
const updateQueryAtom = useCallback((key, state) => {
|
|
903
|
+
const compositeKey = getCompositeKey(scopeId, key);
|
|
904
|
+
setQueriesAtom(prev => Object.assign(Object.assign({}, prev), {
|
|
905
|
+
[compositeKey]: state
|
|
906
|
+
}));
|
|
907
|
+
}, [setQueriesAtom, scopeId]);
|
|
908
|
+
// Update a single mutation in the global atom
|
|
909
|
+
const updateMutationAtom = useCallback((key, state) => {
|
|
910
|
+
const compositeKey = getCompositeKey(scopeId, key);
|
|
911
|
+
setMutationsAtom(prev => Object.assign(Object.assign({}, prev), {
|
|
912
|
+
[compositeKey]: state
|
|
913
|
+
}));
|
|
914
|
+
}, [setMutationsAtom, scopeId]);
|
|
915
|
+
// Enhanced query configs with atom persistence
|
|
916
|
+
const enhancedQueryConfigs = useMemo(() => {
|
|
917
|
+
const items = configs.filter(q => q.type === 'query');
|
|
918
|
+
return items.map(item => {
|
|
919
|
+
if (!item.queryConfig) return null;
|
|
920
|
+
const key = item.key;
|
|
921
|
+
const originalOnStateChange = item.queryConfig.onStateChange;
|
|
922
|
+
return Object.assign(Object.assign({}, item.queryConfig), {
|
|
923
|
+
keyToMap: key,
|
|
924
|
+
onStateChange: state => {
|
|
925
|
+
if (persistToAtoms) {
|
|
926
|
+
updateQueryAtom(key, state);
|
|
927
|
+
}
|
|
928
|
+
originalOnStateChange === null || originalOnStateChange === void 0 ? void 0 : originalOnStateChange(state);
|
|
929
|
+
},
|
|
930
|
+
options: item.queryConfig.options
|
|
931
|
+
});
|
|
932
|
+
}).filter(Boolean);
|
|
933
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
934
|
+
}, [
|
|
935
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
936
|
+
JSON.stringify(configs), persistToAtoms, updateQueryAtom]);
|
|
937
|
+
// Enhanced mutation configs with atom persistence
|
|
938
|
+
const enhancedMutationItems = useMemo(() => {
|
|
939
|
+
const items = configs.filter(q => q.type === 'mutation' && !!q.mutationConfig);
|
|
940
|
+
return items.map(item => {
|
|
941
|
+
const key = item.key;
|
|
942
|
+
const originalOnStateChange = item.mutationConfig.onStateChange;
|
|
943
|
+
return Object.assign(Object.assign({}, item), {
|
|
944
|
+
mutationConfig: Object.assign(Object.assign({}, item.mutationConfig), {
|
|
945
|
+
onStateChange: state => {
|
|
946
|
+
if (persistToAtoms) {
|
|
947
|
+
updateMutationAtom(key, state);
|
|
948
|
+
}
|
|
949
|
+
originalOnStateChange === null || originalOnStateChange === void 0 ? void 0 : originalOnStateChange(state);
|
|
950
|
+
}
|
|
951
|
+
})
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
955
|
+
}, [JSON.stringify(configs), persistToAtoms, updateMutationAtom]);
|
|
956
|
+
const webSocketItems = useMemo(() => configs.filter(q => q.type === 'websocket'),
|
|
957
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
958
|
+
[JSON.stringify(configs)]);
|
|
959
|
+
// Execute hooks
|
|
960
|
+
const allQuery = useMultipleQuery(enhancedQueryConfigs);
|
|
961
|
+
const allMutation = useMultipleMutation(enhancedMutationItems);
|
|
962
|
+
const allWebSocket = useMultipleWebSocket(webSocketItems);
|
|
963
|
+
const queryKeys = enhancedQueryConfigs.map(el => el.keyToMap);
|
|
964
|
+
const mutationKeys = enhancedMutationItems.map(el => el.key);
|
|
965
|
+
const ref = useRef({
|
|
966
|
+
allQuery,
|
|
967
|
+
allMutation,
|
|
968
|
+
queryKeys,
|
|
969
|
+
mutationKeys
|
|
970
|
+
});
|
|
971
|
+
useEffect(() => {
|
|
972
|
+
ref.current = {
|
|
973
|
+
allQuery,
|
|
974
|
+
allMutation,
|
|
975
|
+
queryKeys,
|
|
976
|
+
mutationKeys
|
|
977
|
+
};
|
|
978
|
+
}, [allQuery, allMutation, queryKeys, mutationKeys]);
|
|
979
|
+
const refreshQueries = useCallback(() => {
|
|
980
|
+
ref.current.queryKeys.forEach(k => {
|
|
981
|
+
ref.current.allQuery[k].refetch();
|
|
982
|
+
});
|
|
983
|
+
}, []);
|
|
984
|
+
return {
|
|
985
|
+
allQuery,
|
|
986
|
+
allMutation,
|
|
987
|
+
allWebSocket,
|
|
988
|
+
refreshQueries
|
|
989
|
+
};
|
|
990
|
+
}// ============================================================================
|
|
991
|
+
// Bulk Query/Mutation Hooks
|
|
992
|
+
// ============================================================================
|
|
993
|
+
/**
|
|
994
|
+
* Hook to read all queries for a scope.
|
|
995
|
+
*/
|
|
996
|
+
function useJotaiQueries(options) {
|
|
997
|
+
const $ = c(3);
|
|
998
|
+
const {
|
|
999
|
+
scopeId
|
|
1000
|
+
} = options;
|
|
1001
|
+
const allQueries = useAtomValue(queriesAtom);
|
|
1002
|
+
const prefix = `${scopeId}:`;
|
|
1003
|
+
let scopeQueries;
|
|
1004
|
+
if ($[0] !== allQueries || $[1] !== prefix) {
|
|
1005
|
+
scopeQueries = {};
|
|
1006
|
+
for (const [key, value] of Object.entries(allQueries)) {
|
|
1007
|
+
if (key.startsWith(prefix)) {
|
|
1008
|
+
scopeQueries[key.slice(prefix.length)] = value;
|
|
1009
|
+
}
|
|
509
1010
|
}
|
|
510
|
-
|
|
1011
|
+
$[0] = allQueries;
|
|
1012
|
+
$[1] = prefix;
|
|
1013
|
+
$[2] = scopeQueries;
|
|
1014
|
+
} else {
|
|
1015
|
+
scopeQueries = $[2];
|
|
511
1016
|
}
|
|
512
|
-
return
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
break;
|
|
1017
|
+
return scopeQueries;
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Hook to read all mutations for a scope.
|
|
1021
|
+
*/
|
|
1022
|
+
function useJotaiMutations(options) {
|
|
1023
|
+
const $ = c(3);
|
|
1024
|
+
const {
|
|
1025
|
+
scopeId
|
|
1026
|
+
} = options;
|
|
1027
|
+
const allMutations = useAtomValue(mutationsAtom);
|
|
1028
|
+
const prefix = `${scopeId}:`;
|
|
1029
|
+
let scopeMutations;
|
|
1030
|
+
if ($[0] !== allMutations || $[1] !== prefix) {
|
|
1031
|
+
scopeMutations = {};
|
|
1032
|
+
for (const [key, value] of Object.entries(allMutations)) {
|
|
1033
|
+
if (key.startsWith(prefix)) {
|
|
1034
|
+
scopeMutations[key.slice(prefix.length)] = value;
|
|
1035
|
+
}
|
|
532
1036
|
}
|
|
1037
|
+
$[0] = allMutations;
|
|
1038
|
+
$[1] = prefix;
|
|
1039
|
+
$[2] = scopeMutations;
|
|
1040
|
+
} else {
|
|
1041
|
+
scopeMutations = $[2];
|
|
533
1042
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
1043
|
+
return scopeMutations;
|
|
1044
|
+
}const getValueAtPath$2 = (obj, path, defaultObj) => {
|
|
1045
|
+
if (!path) return undefined;
|
|
1046
|
+
const normalized = path.replace(/\[(\d+)\]/g, ".$1");
|
|
1047
|
+
const parts = normalized.split(".").filter(Boolean);
|
|
1048
|
+
let current = obj;
|
|
1049
|
+
for (let index = 0; index < parts.length; index++) {
|
|
1050
|
+
const part = parts[index];
|
|
1051
|
+
if (current == null) return undefined;
|
|
1052
|
+
if (typeof current !== "object") return undefined;
|
|
1053
|
+
const record = current;
|
|
1054
|
+
// Only apply the default entry when the *root* key is missing (e.g. queryKey not found).
|
|
1055
|
+
// For deeper missing paths, return undefined so callers can use the provided defaultValue.
|
|
1056
|
+
if (!(part in record)) {
|
|
1057
|
+
if (index === 0 && defaultObj !== undefined) {
|
|
1058
|
+
current = defaultObj;
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
return undefined;
|
|
543
1062
|
}
|
|
544
|
-
|
|
545
|
-
return void 0;
|
|
1063
|
+
current = record[part];
|
|
546
1064
|
}
|
|
547
|
-
return
|
|
1065
|
+
return current;
|
|
548
1066
|
};
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
1067
|
+
const useApiValues = ({
|
|
1068
|
+
scopeId
|
|
1069
|
+
}) => {
|
|
1070
|
+
const allQuery = useJotaiQueries({
|
|
1071
|
+
scopeId
|
|
1072
|
+
});
|
|
1073
|
+
const allMutation = useJotaiMutations({
|
|
1074
|
+
scopeId
|
|
1075
|
+
});
|
|
1076
|
+
const subscriptions = useRef(new Map());
|
|
1077
|
+
const [trigger, setTrigger] = useState(0);
|
|
1078
|
+
const dataRef = useRef({
|
|
1079
|
+
query: allQuery,
|
|
1080
|
+
mutation: allMutation
|
|
1081
|
+
});
|
|
1082
|
+
// Sync dataRef with latest values
|
|
1083
|
+
useEffect(() => {
|
|
1084
|
+
let internalTrigger = false;
|
|
1085
|
+
const currentQuery = dataRef.current.query;
|
|
1086
|
+
subscriptions.current.forEach((_, key) => {
|
|
1087
|
+
const [type, keyPath] = key.split(":");
|
|
1088
|
+
if (type === "query") {
|
|
1089
|
+
const newValue = getValueAtPath$2(allQuery, keyPath);
|
|
1090
|
+
const oldValue = getValueAtPath$2(currentQuery, keyPath);
|
|
1091
|
+
// console.log(key, !equal(newValue, oldValue), newValue, oldValue)
|
|
1092
|
+
if (!equal(newValue, oldValue)) {
|
|
1093
|
+
internalTrigger = true;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
if (type === "mutation") {
|
|
1097
|
+
const newValue = getValueAtPath$2(allMutation, keyPath);
|
|
1098
|
+
const oldValue = getValueAtPath$2(dataRef.current.mutation, keyPath);
|
|
1099
|
+
if (!equal(newValue, oldValue)) {
|
|
1100
|
+
internalTrigger = true;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
dataRef.current = {
|
|
1105
|
+
query: allQuery,
|
|
1106
|
+
mutation: allMutation
|
|
1107
|
+
};
|
|
1108
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1109
|
+
if (internalTrigger) {
|
|
1110
|
+
setTrigger(v => v + 1);
|
|
569
1111
|
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
};
|
|
588
|
-
const BUILDING_BLOCK_storeSub = (store, atom, listener) => {
|
|
589
|
-
const buildingBlocks = getInternalBuildingBlocks(store);
|
|
590
|
-
const flushCallbacks = buildingBlocks[12];
|
|
591
|
-
const mountAtom = buildingBlocks[18];
|
|
592
|
-
const unmountAtom = buildingBlocks[19];
|
|
593
|
-
const mounted = mountAtom(store, atom);
|
|
594
|
-
const listeners = mounted.l;
|
|
595
|
-
listeners.add(listener);
|
|
596
|
-
flushCallbacks(store);
|
|
597
|
-
return () => {
|
|
598
|
-
listeners.delete(listener);
|
|
599
|
-
unmountAtom(store, atom);
|
|
600
|
-
flushCallbacks(store);
|
|
1112
|
+
}, [allQuery, allMutation]);
|
|
1113
|
+
// get che legge dallo store e registra le dipendenze
|
|
1114
|
+
const get = useCallback((type, key, defaultValue) => {
|
|
1115
|
+
var _a;
|
|
1116
|
+
const keyMap = `${type}:${key}`;
|
|
1117
|
+
const defaultQueries = type === "query" ? DEFAULT_QUERY_ENTRY :
|
|
1118
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1119
|
+
type === "mutation" ? DEFAULT_MUTATION_ENTRY : undefined;
|
|
1120
|
+
const value = (_a = getValueAtPath$2(dataRef.current[type], String(key), defaultQueries)) !== null && _a !== void 0 ? _a : defaultValue;
|
|
1121
|
+
subscriptions.current.set(keyMap, value);
|
|
1122
|
+
return subscriptions.current.get(keyMap);
|
|
1123
|
+
},
|
|
1124
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1125
|
+
[trigger]);
|
|
1126
|
+
return {
|
|
1127
|
+
get
|
|
601
1128
|
};
|
|
1129
|
+
};new TextEncoder();
|
|
1130
|
+
new TextDecoder();const DefaultContainer$1 = ({
|
|
1131
|
+
children
|
|
1132
|
+
}) => {
|
|
1133
|
+
return children;
|
|
602
1134
|
};
|
|
603
|
-
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !buildingBlocks) {
|
|
607
|
-
throw new Error(
|
|
608
|
-
"Store must be created by buildStore to read its building blocks"
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
return buildingBlocks;
|
|
1135
|
+
// Lazy initialization to avoid side effects at module load time
|
|
1136
|
+
const _formConfig = {
|
|
1137
|
+
formFieldContainer: DefaultContainer$1
|
|
612
1138
|
};
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
1139
|
+
const {
|
|
1140
|
+
useValue: useFormConfigValue} = atomStateGenerator({
|
|
1141
|
+
key: 'formConfig',
|
|
1142
|
+
defaultValue: _formConfig,
|
|
1143
|
+
persist: false
|
|
1144
|
+
});/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1145
|
+
function useJotaiForm(formOptions) {
|
|
1146
|
+
const form = useForm(formOptions);
|
|
1147
|
+
return form;
|
|
1148
|
+
}const FormField = ({
|
|
1149
|
+
config,
|
|
1150
|
+
onFieldChange,
|
|
1151
|
+
ns: globalNs,
|
|
1152
|
+
globalErrorNs
|
|
1153
|
+
}) => {
|
|
1154
|
+
var _a, _b;
|
|
1155
|
+
const ns = (_a = config.ns) !== null && _a !== void 0 ? _a : globalNs;
|
|
1156
|
+
const errorNs = (_b = config.errorNs) !== null && _b !== void 0 ? _b : globalErrorNs;
|
|
1157
|
+
const {
|
|
1158
|
+
formFieldContainer,
|
|
1159
|
+
translateText
|
|
1160
|
+
} = useFormConfigValue();
|
|
1161
|
+
// TanStack Form uses field.state.meta.errors which is an array of ValidationError
|
|
1162
|
+
const firstError = config.field.state.meta.errors.length > 0 ? config.field.state.meta.errors[0] : undefined;
|
|
1163
|
+
const errorMessageStr = firstError ? String(firstError) : undefined;
|
|
1164
|
+
const errorMessage = useMemo(() => {
|
|
1165
|
+
if (!errorMessageStr) return undefined;
|
|
1166
|
+
return errorNs ? translateText === null || translateText === void 0 ? void 0 : translateText(errorMessageStr, {
|
|
1167
|
+
ns: errorNs || '',
|
|
1168
|
+
defaultValue: ''
|
|
1169
|
+
}) : errorMessageStr;
|
|
1170
|
+
}, [errorMessageStr, errorNs, translateText]);
|
|
1171
|
+
const label = useMemo(() => {
|
|
1172
|
+
var _a_0;
|
|
1173
|
+
return ns ? translateText === null || translateText === void 0 ? void 0 : translateText((_a_0 = config.label) !== null && _a_0 !== void 0 ? _a_0 : '') : config.label;
|
|
1174
|
+
}, [ns, config.label, translateText]);
|
|
1175
|
+
const helperMessage = useMemo(() => {
|
|
1176
|
+
var _a_1;
|
|
1177
|
+
return ((_a_1 = config.helper) === null || _a_1 === void 0 ? void 0 : _a_1.text) ? translateText === null || translateText === void 0 ? void 0 : translateText(config.helper.text, config.helper.translationOption) : '';
|
|
1178
|
+
}, [config.helper, translateText]);
|
|
1179
|
+
const ref = useRef({
|
|
1180
|
+
onFieldChange,
|
|
1181
|
+
handleChange: config.field.handleChange
|
|
1182
|
+
});
|
|
1183
|
+
useEffect(() => {
|
|
1184
|
+
ref.current = {
|
|
1185
|
+
onFieldChange,
|
|
1186
|
+
handleChange: config.field.handleChange
|
|
1187
|
+
};
|
|
1188
|
+
}, [config.field.handleChange, onFieldChange]);
|
|
1189
|
+
const handleChange = useCallback(value => {
|
|
1190
|
+
var _a_2, _b_0;
|
|
1191
|
+
// TanStack Form handleChange usually expects just the value for input
|
|
1192
|
+
// but if we are manually calling it we should pass the value.
|
|
1193
|
+
ref.current.handleChange(value);
|
|
1194
|
+
(_b_0 = (_a_2 = ref.current).onFieldChange) === null || _b_0 === void 0 ? void 0 : _b_0.call(_a_2, value);
|
|
1195
|
+
}, []);
|
|
1196
|
+
const handleBlur = useCallback(() => {
|
|
1197
|
+
config.field.handleBlur();
|
|
1198
|
+
}, [config.field]);
|
|
1199
|
+
const baseProps = useMemo(() => ({
|
|
1200
|
+
value: config.field.state.value,
|
|
1201
|
+
onChange: handleChange,
|
|
1202
|
+
onBlur: handleBlur,
|
|
1203
|
+
error: config.field.state.meta.errors.length > 0,
|
|
1204
|
+
errorMessage,
|
|
1205
|
+
label,
|
|
1206
|
+
helperMessage
|
|
1207
|
+
}), [config.field.state.value, handleChange, handleBlur, config.field.state.meta.errors.length, errorMessage, label, helperMessage]);
|
|
1208
|
+
const ConfigContainer = useMemo(() => config.container, [config.container]);
|
|
1209
|
+
const FormFieldContainer = useMemo(() => formFieldContainer, [formFieldContainer]);
|
|
1210
|
+
if (ConfigContainer) {
|
|
1211
|
+
return jsx(ConfigContainer, {
|
|
1212
|
+
children: config.component(baseProps)
|
|
1213
|
+
});
|
|
681
1214
|
}
|
|
682
|
-
|
|
683
|
-
config.
|
|
1215
|
+
return jsx(FormFieldContainer, {
|
|
1216
|
+
children: config.component(baseProps)
|
|
1217
|
+
});
|
|
1218
|
+
};const DEFAULT_FORM_ENTRY = Object.freeze({
|
|
1219
|
+
formValues: {},
|
|
1220
|
+
setValue: () => {}
|
|
1221
|
+
});
|
|
1222
|
+
/**
|
|
1223
|
+
* Global atom storing all form state.
|
|
1224
|
+
* Key format: "scopeId:formId" or just "formId" for backward compatibility.
|
|
1225
|
+
*/
|
|
1226
|
+
const formAtom = atom({});
|
|
1227
|
+
const createFormSelector = formId => selectAtom(formAtom, forms => {
|
|
1228
|
+
const entry = forms[formId];
|
|
1229
|
+
return entry !== null && entry !== void 0 ? entry : DEFAULT_FORM_ENTRY;
|
|
1230
|
+
}, (a, b) => a === b || a.formValues === b.formValues && a.setValue === b.setValue);
|
|
1231
|
+
const useFormValue = formId => {
|
|
1232
|
+
const $ = c(2);
|
|
1233
|
+
let t0;
|
|
1234
|
+
if ($[0] !== formId) {
|
|
1235
|
+
t0 = createFormSelector(formId);
|
|
1236
|
+
$[0] = formId;
|
|
1237
|
+
$[1] = t0;
|
|
1238
|
+
} else {
|
|
1239
|
+
t0 = $[1];
|
|
684
1240
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
"Detected multiple Jotai instances. It may cause unexpected behavior with the default store. https://github.com/pmndrs/jotai/discussions/2044"
|
|
708
|
-
);
|
|
709
|
-
}
|
|
1241
|
+
const selectorAtom = t0;
|
|
1242
|
+
return useAtomValue(selectorAtom);
|
|
1243
|
+
};
|
|
1244
|
+
const useSetFormState = formId => {
|
|
1245
|
+
const setForms = useSetAtom(formAtom);
|
|
1246
|
+
return useCallback(val => {
|
|
1247
|
+
setForms(prev => {
|
|
1248
|
+
var _a;
|
|
1249
|
+
const prevEntry = (_a = prev[formId]) !== null && _a !== void 0 ? _a : DEFAULT_FORM_ENTRY;
|
|
1250
|
+
return Object.assign(Object.assign({}, prev), {
|
|
1251
|
+
[formId]: Object.assign(Object.assign({}, prevEntry), val)
|
|
1252
|
+
});
|
|
1253
|
+
});
|
|
1254
|
+
}, [formId, setForms]);
|
|
1255
|
+
};const getValueAtPath$1 = (obj, path, defaultObj) => {
|
|
1256
|
+
if (!path) return undefined;
|
|
1257
|
+
const normalized = path.replace(/\[(\d+)\]/g, '.$1');
|
|
1258
|
+
const parts = normalized.split('.').filter(Boolean);
|
|
1259
|
+
let current = obj;
|
|
1260
|
+
for (const part of parts) {
|
|
1261
|
+
if (!current || !Object.keys(current).length) {
|
|
1262
|
+
return undefined;
|
|
710
1263
|
}
|
|
1264
|
+
if (typeof current !== 'object') return undefined;
|
|
1265
|
+
current = current[part];
|
|
711
1266
|
}
|
|
712
|
-
return
|
|
713
|
-
}const StoreContext = createContext(
|
|
714
|
-
void 0
|
|
715
|
-
);
|
|
716
|
-
function useStore(options) {
|
|
717
|
-
const store = useContext(StoreContext);
|
|
718
|
-
return store || getDefaultStore();
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const isPromiseLike = (x) => typeof (x == null ? void 0 : x.then) === "function";
|
|
722
|
-
const attachPromiseStatus = (promise) => {
|
|
723
|
-
if (!promise.status) {
|
|
724
|
-
promise.status = "pending";
|
|
725
|
-
promise.then(
|
|
726
|
-
(v) => {
|
|
727
|
-
promise.status = "fulfilled";
|
|
728
|
-
promise.value = v;
|
|
729
|
-
},
|
|
730
|
-
(e) => {
|
|
731
|
-
promise.status = "rejected";
|
|
732
|
-
promise.reason = e;
|
|
733
|
-
}
|
|
734
|
-
);
|
|
735
|
-
}
|
|
1267
|
+
return current;
|
|
736
1268
|
};
|
|
737
|
-
const
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1269
|
+
const useFormValues = ({
|
|
1270
|
+
formId
|
|
1271
|
+
}) => {
|
|
1272
|
+
// We subscribe to the specific form entry in the atoms
|
|
1273
|
+
// Note: This subscription is a bit coarse (entire form entry), but we optimize re-renders locally
|
|
1274
|
+
// Ideally we would want to subscribe only to specific paths, but Jotai atoms are per-form.
|
|
1275
|
+
const formEntry = useFormValue(formId);
|
|
1276
|
+
const currentValues = useMemo(() => formEntry.formValues, [formEntry.formValues]);
|
|
1277
|
+
const subscriptions = useRef(new Map());
|
|
1278
|
+
// trigger state is used to force re-render when a subscribed value changes
|
|
1279
|
+
const [trigger, setTrigger] = useState(0);
|
|
1280
|
+
// Ref to hold the latest values without causing re-renders itself
|
|
1281
|
+
const formRef = useRef({
|
|
1282
|
+
formValues: formEntry.formValues,
|
|
1283
|
+
setValue: formEntry.setValue
|
|
1284
|
+
});
|
|
1285
|
+
useEffect(() => {
|
|
1286
|
+
formRef.current.setValue = formEntry.setValue;
|
|
1287
|
+
}, [formEntry.setValue]);
|
|
1288
|
+
useEffect(() => {
|
|
1289
|
+
let shouldTrigger = false;
|
|
1290
|
+
subscriptions.current.forEach((_, path) => {
|
|
1291
|
+
const newValue = getValueAtPath$1(currentValues, path);
|
|
1292
|
+
const oldValue = getValueAtPath$1(formRef.current.formValues, path);
|
|
1293
|
+
if (!equal(newValue, oldValue)) {
|
|
1294
|
+
shouldTrigger = true;
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
formRef.current.formValues = currentValues;
|
|
1298
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1299
|
+
if (shouldTrigger) {
|
|
1300
|
+
setTrigger(c => c + 1);
|
|
1301
|
+
}
|
|
1302
|
+
}, [currentValues]);
|
|
1303
|
+
const get = useCallback((key, defaultValue) => {
|
|
1304
|
+
var _a;
|
|
1305
|
+
const val = (_a = getValueAtPath$1(formRef.current.formValues, key)) !== null && _a !== void 0 ? _a : defaultValue;
|
|
1306
|
+
subscriptions.current.set(key, val);
|
|
1307
|
+
return subscriptions.current.get(key);
|
|
1308
|
+
},
|
|
1309
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1310
|
+
[trigger]);
|
|
1311
|
+
const set = useCallback((field, value) => {
|
|
1312
|
+
formRef.current.setValue(field, value);
|
|
1313
|
+
}, []);
|
|
1314
|
+
return {
|
|
1315
|
+
get,
|
|
1316
|
+
set
|
|
1317
|
+
};
|
|
1318
|
+
};const trimObject = obj => Object.entries(obj !== null && obj !== void 0 ? obj : {}).reduce((prev, [key, val]) => Object.assign(Object.assign({}, prev), {
|
|
1319
|
+
[key]: typeof val === 'string' && !['password', 'pPassword'].includes(key) ? val.trim() : val
|
|
1320
|
+
}), {});
|
|
1321
|
+
const RenderField = t0 => {
|
|
1322
|
+
const $ = c(9);
|
|
1323
|
+
const {
|
|
1324
|
+
field,
|
|
1325
|
+
fieldState,
|
|
1326
|
+
fieldProps,
|
|
1327
|
+
onFieldChange
|
|
1328
|
+
} = t0;
|
|
1329
|
+
let t1;
|
|
1330
|
+
if ($[0] !== field || $[1] !== fieldProps || $[2] !== fieldState) {
|
|
1331
|
+
t1 = Object.assign(Object.assign({}, fieldProps), {
|
|
1332
|
+
field,
|
|
1333
|
+
fieldState
|
|
1334
|
+
});
|
|
1335
|
+
$[0] = field;
|
|
1336
|
+
$[1] = fieldProps;
|
|
1337
|
+
$[2] = fieldState;
|
|
1338
|
+
$[3] = t1;
|
|
745
1339
|
} else {
|
|
746
|
-
|
|
747
|
-
throw promise;
|
|
1340
|
+
t1 = $[3];
|
|
748
1341
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
if (curr === me) {
|
|
758
|
-
resolve(v);
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
const onRejected = (me) => (e) => {
|
|
762
|
-
if (curr === me) {
|
|
763
|
-
reject(e);
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
const onAbort = () => {
|
|
767
|
-
try {
|
|
768
|
-
const nextValue = getValue();
|
|
769
|
-
if (isPromiseLike(nextValue)) {
|
|
770
|
-
continuablePromiseMap.set(nextValue, continuablePromise);
|
|
771
|
-
curr = nextValue;
|
|
772
|
-
nextValue.then(onFulfilled(nextValue), onRejected(nextValue));
|
|
773
|
-
registerAbortHandler(nextValue, onAbort);
|
|
774
|
-
} else {
|
|
775
|
-
resolve(nextValue);
|
|
776
|
-
}
|
|
777
|
-
} catch (e) {
|
|
778
|
-
reject(e);
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
promise.then(onFulfilled(promise), onRejected(promise));
|
|
782
|
-
registerAbortHandler(promise, onAbort);
|
|
1342
|
+
const config = t1;
|
|
1343
|
+
let t2;
|
|
1344
|
+
if ($[4] !== config || $[5] !== fieldProps.errorNs || $[6] !== fieldProps.ns || $[7] !== onFieldChange) {
|
|
1345
|
+
t2 = jsx(FormField, {
|
|
1346
|
+
config,
|
|
1347
|
+
ns: fieldProps.ns,
|
|
1348
|
+
globalErrorNs: fieldProps.errorNs,
|
|
1349
|
+
onFieldChange
|
|
783
1350
|
});
|
|
784
|
-
|
|
1351
|
+
$[4] = config;
|
|
1352
|
+
$[5] = fieldProps.errorNs;
|
|
1353
|
+
$[6] = fieldProps.ns;
|
|
1354
|
+
$[7] = onFieldChange;
|
|
1355
|
+
$[8] = t2;
|
|
1356
|
+
} else {
|
|
1357
|
+
t2 = $[8];
|
|
785
1358
|
}
|
|
786
|
-
return
|
|
1359
|
+
return t2;
|
|
787
1360
|
};
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1361
|
+
const DynamicFieldItem = ({
|
|
1362
|
+
item,
|
|
1363
|
+
form,
|
|
1364
|
+
globalErrorNs,
|
|
1365
|
+
formId
|
|
1366
|
+
}) => {
|
|
1367
|
+
const {
|
|
1368
|
+
get,
|
|
1369
|
+
set
|
|
1370
|
+
} = useFormValues({
|
|
1371
|
+
formId
|
|
1372
|
+
});
|
|
1373
|
+
const fieldProps = useMemo(() => {
|
|
1374
|
+
if (typeof item === 'function') {
|
|
1375
|
+
return item({
|
|
1376
|
+
get,
|
|
1377
|
+
set
|
|
1378
|
+
});
|
|
1379
|
+
} else {
|
|
1380
|
+
return item;
|
|
1381
|
+
}
|
|
1382
|
+
}, [get, set, item]);
|
|
1383
|
+
const isHidden = useMemo(() => {
|
|
1384
|
+
if (!fieldProps.hidden) {
|
|
1385
|
+
return false;
|
|
1386
|
+
} else if (typeof fieldProps.hidden === 'function') {
|
|
1387
|
+
return fieldProps.hidden({
|
|
1388
|
+
get,
|
|
1389
|
+
set
|
|
1390
|
+
});
|
|
1391
|
+
} else {
|
|
1392
|
+
return !!fieldProps.hidden;
|
|
1393
|
+
}
|
|
1394
|
+
}, [get, set, fieldProps]);
|
|
1395
|
+
const rules = useMemo(() => {
|
|
1396
|
+
if (!fieldProps.rules) {
|
|
1397
|
+
return undefined;
|
|
1398
|
+
} else if (typeof fieldProps.rules === 'function') {
|
|
1399
|
+
return fieldProps.rules({
|
|
1400
|
+
get,
|
|
1401
|
+
set
|
|
1402
|
+
});
|
|
1403
|
+
} else {
|
|
1404
|
+
return fieldProps.rules;
|
|
1405
|
+
}
|
|
1406
|
+
}, [get, set, fieldProps]);
|
|
1407
|
+
const props = useMemo(() => {
|
|
1408
|
+
var _a;
|
|
1409
|
+
return Object.assign(Object.assign({}, fieldProps), {
|
|
1410
|
+
errorNs: (_a = fieldProps.errorNs) !== null && _a !== void 0 ? _a : globalErrorNs
|
|
1411
|
+
});
|
|
1412
|
+
}, [fieldProps, globalErrorNs]);
|
|
1413
|
+
if (isHidden) {
|
|
1414
|
+
return jsx(Fragment, {});
|
|
1415
|
+
}
|
|
1416
|
+
return jsx(form.Field, {
|
|
1417
|
+
name: props.name,
|
|
1418
|
+
validators: rules,
|
|
1419
|
+
// eslint-disable-next-line react/no-children-prop
|
|
1420
|
+
children: field => jsx(RenderField, {
|
|
1421
|
+
field: field,
|
|
1422
|
+
fieldState: field.state,
|
|
1423
|
+
fieldProps: props,
|
|
1424
|
+
onFieldChange: props.onFieldChange
|
|
1425
|
+
})
|
|
1426
|
+
});
|
|
1427
|
+
};
|
|
1428
|
+
const SubmitItem = ({
|
|
1429
|
+
item,
|
|
1430
|
+
index,
|
|
1431
|
+
handlersRef
|
|
1432
|
+
}) => {
|
|
1433
|
+
const handleClick = useCallback(async () => {
|
|
1434
|
+
const {
|
|
1435
|
+
formControl,
|
|
1436
|
+
createSubmitHandler,
|
|
1437
|
+
onInvalidHandle
|
|
1438
|
+
} = handlersRef.current;
|
|
1439
|
+
// Partial or full validation logic
|
|
1440
|
+
let isValid = true;
|
|
1441
|
+
const keys = item.values;
|
|
1442
|
+
if (keys && keys.length > 0) {
|
|
1443
|
+
// Validate only specific fields
|
|
1444
|
+
await Promise.all(keys.map(key => formControl.validateField(key, 'change')));
|
|
1445
|
+
const hasError = keys.some(key_0 => {
|
|
1446
|
+
// This is a simplified check. TanStack form errors might be structured differently.
|
|
1447
|
+
// You might need deep checking if errors are nested objects.
|
|
1448
|
+
// For now assume flat or use lodash get if possible, but state.errors is usually flat-ish map in newer versions or object.
|
|
1449
|
+
// Checking standard TanStack: form.state.fieldMeta[key]?.errors
|
|
1450
|
+
const meta = formControl.getFieldMeta(key_0);
|
|
1451
|
+
return (meta === null || meta === void 0 ? void 0 : meta.errors) && meta.errors.length > 0;
|
|
1452
|
+
});
|
|
1453
|
+
isValid = !hasError;
|
|
1454
|
+
} else {
|
|
1455
|
+
// Validate all
|
|
1456
|
+
await formControl.validateAllFields('submit');
|
|
1457
|
+
isValid = formControl.state.isValid;
|
|
1458
|
+
}
|
|
1459
|
+
if (!isValid) {
|
|
1460
|
+
onInvalidHandle(formControl.state.errors, item);
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
const values = formControl.state.values;
|
|
1464
|
+
// Call handlers
|
|
1465
|
+
await createSubmitHandler(item)(values);
|
|
1466
|
+
}, [item, handlersRef]);
|
|
1467
|
+
const Component = useMemo(() => item.component, [item]);
|
|
1468
|
+
if (item.hidden || !Component) return jsx(Fragment, {});
|
|
1469
|
+
return jsx(Component, {
|
|
1470
|
+
onClick: handleClick,
|
|
1471
|
+
index: index,
|
|
1472
|
+
type: item.type || 'button'
|
|
1473
|
+
}, `submit-${index}`);
|
|
1474
|
+
};
|
|
1475
|
+
const useFormManager = ({
|
|
1476
|
+
data,
|
|
1477
|
+
onInvalid,
|
|
1478
|
+
submit = [],
|
|
1479
|
+
notification,
|
|
1480
|
+
formOptions,
|
|
1481
|
+
onValuesChange,
|
|
1482
|
+
globalErrorNs,
|
|
1483
|
+
id = 'form-manager'
|
|
1484
|
+
}) => {
|
|
1485
|
+
const formControl = useJotaiForm(formOptions);
|
|
1486
|
+
const formState = useMemo(() => formControl.state, [formControl.state]);
|
|
1487
|
+
const errors = useMemo(() => formState.errors, [formState.errors]);
|
|
1488
|
+
const values = useMemo(() => formState.values, [formState.values]);
|
|
1489
|
+
const setFormState = useSetFormState(id);
|
|
1490
|
+
const {
|
|
1491
|
+
showNotification
|
|
1492
|
+
} = useFormConfigValue();
|
|
1493
|
+
const setValue = useCallback((field, updater) => formControl.setFieldValue(field, updater), [formControl]);
|
|
807
1494
|
useEffect(() => {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
const value2 = store.get(atom);
|
|
812
|
-
if (isPromiseLike(value2)) {
|
|
813
|
-
attachPromiseStatus(
|
|
814
|
-
createContinuablePromise(value2, () => store.get(atom))
|
|
815
|
-
);
|
|
816
|
-
}
|
|
817
|
-
} catch (e) {
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
if (typeof delay === "number") {
|
|
821
|
-
setTimeout(rerender, delay);
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
|
-
rerender();
|
|
1495
|
+
setFormState({
|
|
1496
|
+
setValue,
|
|
1497
|
+
formValues: formState.values
|
|
825
1498
|
});
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
1499
|
+
const unsubscribe = formControl.store.subscribe(store => {
|
|
1500
|
+
setFormState({
|
|
1501
|
+
formValues: store.currentVal.values
|
|
1502
|
+
});
|
|
1503
|
+
});
|
|
1504
|
+
return () => {
|
|
1505
|
+
unsubscribe();
|
|
1506
|
+
}; /**/
|
|
1507
|
+
}, [formControl.store, setValue, formState.values, setFormState]);
|
|
1508
|
+
const handleNotification = useCallback(props => {
|
|
1509
|
+
if (props.message) {
|
|
1510
|
+
showNotification === null || showNotification === void 0 ? void 0 : showNotification(props);
|
|
1511
|
+
}
|
|
1512
|
+
}, [showNotification]);
|
|
1513
|
+
const filterFormData = useCallback((v, submitConfig) => {
|
|
1514
|
+
const keys = submitConfig.values;
|
|
1515
|
+
if (!keys || keys.length === 0) {
|
|
1516
|
+
return v;
|
|
1517
|
+
}
|
|
1518
|
+
const out = {};
|
|
1519
|
+
for (const key of keys) {
|
|
1520
|
+
if (key in v) {
|
|
1521
|
+
out[key] = v[key];
|
|
1522
|
+
}
|
|
834
1523
|
}
|
|
835
|
-
return
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
1524
|
+
return out;
|
|
1525
|
+
}, []);
|
|
1526
|
+
const processSubmit = useCallback(async (d, submitConfig_0) => {
|
|
1527
|
+
const filteredData = filterFormData(d, submitConfig_0);
|
|
1528
|
+
if (submitConfig_0.onSuccess) {
|
|
1529
|
+
return await submitConfig_0.onSuccess(filteredData);
|
|
1530
|
+
}
|
|
1531
|
+
throw new Error('No submit handler provided');
|
|
1532
|
+
}, [filterFormData]);
|
|
1533
|
+
const handleError = useCallback((error, submitConfig_1) => {
|
|
1534
|
+
if (submitConfig_1.onError) {
|
|
1535
|
+
submitConfig_1.onError(error);
|
|
1536
|
+
}
|
|
1537
|
+
const notificationProps = typeof (notification === null || notification === void 0 ? void 0 : notification.error) === 'function' ? notification.error(error.message) : notification === null || notification === void 0 ? void 0 : notification.error;
|
|
1538
|
+
if (notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) {
|
|
1539
|
+
handleNotification(notificationProps);
|
|
1540
|
+
}
|
|
1541
|
+
}, [handleNotification, notification]);
|
|
1542
|
+
const createSubmitHandler = useCallback(submitConfig_2 => async dataSubmit => {
|
|
1543
|
+
try {
|
|
1544
|
+
const res = await processSubmit(trimObject(dataSubmit), submitConfig_2);
|
|
1545
|
+
const notificationProps_0 = typeof (notification === null || notification === void 0 ? void 0 : notification.success) === 'function' ? notification.success(res) : notification === null || notification === void 0 ? void 0 : notification.success;
|
|
1546
|
+
if (notificationProps_0 === null || notificationProps_0 === void 0 ? void 0 : notificationProps_0.message) {
|
|
1547
|
+
handleNotification(notificationProps_0);
|
|
846
1548
|
}
|
|
847
|
-
return
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1549
|
+
return res;
|
|
1550
|
+
} catch (error_0) {
|
|
1551
|
+
handleError(error_0, submitConfig_2);
|
|
1552
|
+
throw error_0;
|
|
1553
|
+
}
|
|
1554
|
+
}, [processSubmit, notification, handleNotification, handleError]);
|
|
1555
|
+
const onInvalidHandle = useCallback((err, submitConfig_3) => {
|
|
1556
|
+
onInvalid === null || onInvalid === void 0 ? void 0 : onInvalid(err);
|
|
1557
|
+
handleError(new Error('invalidData'), submitConfig_3);
|
|
1558
|
+
}, [handleError, onInvalid]);
|
|
1559
|
+
const handlersRef = useRef({
|
|
1560
|
+
formControl,
|
|
1561
|
+
onInvalidHandle,
|
|
1562
|
+
createSubmitHandler,
|
|
1563
|
+
setValue: formControl.setFieldValue,
|
|
1564
|
+
trigger: formControl.validateField,
|
|
1565
|
+
onValuesChange
|
|
1566
|
+
});
|
|
1567
|
+
useEffect(() => {
|
|
1568
|
+
handlersRef.current.onInvalidHandle = onInvalidHandle;
|
|
1569
|
+
handlersRef.current.createSubmitHandler = createSubmitHandler;
|
|
1570
|
+
handlersRef.current.setValue = formControl.setFieldValue;
|
|
1571
|
+
handlersRef.current.trigger = formControl.validateField;
|
|
1572
|
+
handlersRef.current.onValuesChange = onValuesChange;
|
|
1573
|
+
}, [onInvalidHandle, createSubmitHandler, formControl, onValuesChange]);
|
|
1574
|
+
const fields = useMemo(() => data.map((item, index) => {
|
|
1575
|
+
var _a, _b;
|
|
1576
|
+
const staticItem = typeof item === 'function' ? null : item;
|
|
1577
|
+
return {
|
|
1578
|
+
index: (_a = staticItem === null || staticItem === void 0 ? void 0 : staticItem.index) !== null && _a !== void 0 ? _a : index,
|
|
1579
|
+
element: jsx(DynamicFieldItem, {
|
|
1580
|
+
item: item,
|
|
1581
|
+
form: formControl,
|
|
1582
|
+
globalErrorNs: globalErrorNs,
|
|
1583
|
+
formId: id
|
|
1584
|
+
}, (_b = staticItem === null || staticItem === void 0 ? void 0 : staticItem.name) !== null && _b !== void 0 ? _b : index),
|
|
1585
|
+
renderInFooter: !!(staticItem === null || staticItem === void 0 ? void 0 : staticItem.renderInFooter),
|
|
1586
|
+
renderInHeader: !!(staticItem === null || staticItem === void 0 ? void 0 : staticItem.renderInHeader)
|
|
1587
|
+
};
|
|
1588
|
+
}), [data, formControl, globalErrorNs, id]);
|
|
1589
|
+
const submits = useMemo(() => submit.map((submitConfig_4, index_0) => {
|
|
1590
|
+
return {
|
|
1591
|
+
index: submitConfig_4.index === undefined ? index_0 : submitConfig_4.index,
|
|
1592
|
+
element: jsx(SubmitItem, {
|
|
1593
|
+
item: submitConfig_4,
|
|
1594
|
+
index: index_0,
|
|
1595
|
+
handlersRef: handlersRef
|
|
1596
|
+
}, `submit-${index_0}`),
|
|
1597
|
+
renderInFooter: !!submitConfig_4.renderInFooter,
|
|
1598
|
+
renderInHeader: !!submitConfig_4.renderInHeader,
|
|
1599
|
+
isSubmit: true
|
|
1600
|
+
};
|
|
1601
|
+
}), [submit]);
|
|
1602
|
+
const elements = useMemo(() => fields.concat(submits), [fields, submits]);
|
|
1603
|
+
const formContents = useMemo(() => [...data, ...submit], [data, submit]);
|
|
1604
|
+
useEffect(() => {
|
|
1605
|
+
var _a_0, _b_0;
|
|
1606
|
+
(_b_0 = (_a_0 = handlersRef.current).onValuesChange) === null || _b_0 === void 0 ? void 0 : _b_0.call(_a_0, values, handlersRef.current.setValue);
|
|
1607
|
+
}, [values]);
|
|
1608
|
+
return {
|
|
1609
|
+
elements,
|
|
1610
|
+
formContents,
|
|
1611
|
+
errors,
|
|
1612
|
+
formValues: values,
|
|
1613
|
+
setValue
|
|
1614
|
+
};
|
|
1615
|
+
};/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
861
1616
|
/**
|
|
862
1617
|
* Optimized shallow equality check for objects and functions
|
|
863
1618
|
* @param objA - First object to compare
|
|
@@ -982,61 +1737,6 @@ function memoize(fn, cacheKeyFn) {
|
|
|
982
1737
|
cache.set(cacheKey, result);
|
|
983
1738
|
return result;
|
|
984
1739
|
};
|
|
985
|
-
}function atomFamily(initializeAtom, areEqual) {
|
|
986
|
-
let shouldRemove = null;
|
|
987
|
-
const atoms = new Map();
|
|
988
|
-
const listeners = new Set();
|
|
989
|
-
function createAtom(param) {
|
|
990
|
-
let item;
|
|
991
|
-
{
|
|
992
|
-
item = atoms.get(param);
|
|
993
|
-
}
|
|
994
|
-
if (item !== undefined) {
|
|
995
|
-
if (shouldRemove?.(item[1], param)) {
|
|
996
|
-
createAtom.remove(param);
|
|
997
|
-
}
|
|
998
|
-
else {
|
|
999
|
-
return item[0];
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
const newAtom = initializeAtom(param);
|
|
1003
|
-
atoms.set(param, [newAtom, Date.now()]);
|
|
1004
|
-
notifyListeners('CREATE', param, newAtom);
|
|
1005
|
-
return newAtom;
|
|
1006
|
-
}
|
|
1007
|
-
function notifyListeners(type, param, atom) {
|
|
1008
|
-
for (const listener of listeners) {
|
|
1009
|
-
listener({ type, param, atom });
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
createAtom.unstable_listen = (callback) => {
|
|
1013
|
-
listeners.add(callback);
|
|
1014
|
-
return () => {
|
|
1015
|
-
listeners.delete(callback);
|
|
1016
|
-
};
|
|
1017
|
-
};
|
|
1018
|
-
createAtom.getParams = () => atoms.keys();
|
|
1019
|
-
createAtom.remove = (param) => {
|
|
1020
|
-
{
|
|
1021
|
-
if (!atoms.has(param))
|
|
1022
|
-
return;
|
|
1023
|
-
const [atom] = atoms.get(param);
|
|
1024
|
-
atoms.delete(param);
|
|
1025
|
-
notifyListeners('REMOVE', param, atom);
|
|
1026
|
-
}
|
|
1027
|
-
};
|
|
1028
|
-
createAtom.setShouldRemove = (fn) => {
|
|
1029
|
-
shouldRemove = fn;
|
|
1030
|
-
if (!shouldRemove)
|
|
1031
|
-
return;
|
|
1032
|
-
for (const [key, [atom, createdAt]] of atoms) {
|
|
1033
|
-
if (shouldRemove(createdAt, key)) {
|
|
1034
|
-
atoms.delete(key);
|
|
1035
|
-
notifyListeners('REMOVE', key, atom);
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
};
|
|
1039
|
-
return createAtom;
|
|
1040
1740
|
}const pageVariablesAtomFamily = atomFamily(_pageId => atom({}));
|
|
1041
1741
|
/**
|
|
1042
1742
|
* Global atom storing all page variables.
|
|
@@ -2377,850 +3077,6 @@ function useFormData({
|
|
|
2377
3077
|
mappedFormData,
|
|
2378
3078
|
formSubmit
|
|
2379
3079
|
};
|
|
2380
|
-
}// src/subscribable.ts
|
|
2381
|
-
var Subscribable = class {
|
|
2382
|
-
constructor() {
|
|
2383
|
-
this.listeners = /* @__PURE__ */new Set();
|
|
2384
|
-
this.subscribe = this.subscribe.bind(this);
|
|
2385
|
-
}
|
|
2386
|
-
subscribe(listener) {
|
|
2387
|
-
this.listeners.add(listener);
|
|
2388
|
-
this.onSubscribe();
|
|
2389
|
-
return () => {
|
|
2390
|
-
this.listeners.delete(listener);
|
|
2391
|
-
this.onUnsubscribe();
|
|
2392
|
-
};
|
|
2393
|
-
}
|
|
2394
|
-
hasListeners() {
|
|
2395
|
-
return this.listeners.size > 0;
|
|
2396
|
-
}
|
|
2397
|
-
onSubscribe() {}
|
|
2398
|
-
onUnsubscribe() {}
|
|
2399
|
-
};// src/timeoutManager.ts
|
|
2400
|
-
var defaultTimeoutProvider = {
|
|
2401
|
-
// We need the wrapper function syntax below instead of direct references to
|
|
2402
|
-
// global setTimeout etc.
|
|
2403
|
-
//
|
|
2404
|
-
// BAD: `setTimeout: setTimeout`
|
|
2405
|
-
// GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`
|
|
2406
|
-
//
|
|
2407
|
-
// If we use direct references here, then anything that wants to spy on or
|
|
2408
|
-
// replace the global setTimeout (like tests) won't work since we'll already
|
|
2409
|
-
// have a hard reference to the original implementation at the time when this
|
|
2410
|
-
// file was imported.
|
|
2411
|
-
setTimeout: (callback, delay) => setTimeout(callback, delay),
|
|
2412
|
-
clearTimeout: timeoutId => clearTimeout(timeoutId),
|
|
2413
|
-
setInterval: (callback, delay) => setInterval(callback, delay),
|
|
2414
|
-
clearInterval: intervalId => clearInterval(intervalId)
|
|
2415
|
-
};
|
|
2416
|
-
var TimeoutManager = class {
|
|
2417
|
-
// We cannot have TimeoutManager<T> as we must instantiate it with a concrete
|
|
2418
|
-
// type at app boot; and if we leave that type, then any new timer provider
|
|
2419
|
-
// would need to support ReturnType<typeof setTimeout>, which is infeasible.
|
|
2420
|
-
//
|
|
2421
|
-
// We settle for type safety for the TimeoutProvider type, and accept that
|
|
2422
|
-
// this class is unsafe internally to allow for extension.
|
|
2423
|
-
#provider = defaultTimeoutProvider;
|
|
2424
|
-
#providerCalled = false;
|
|
2425
|
-
setTimeoutProvider(provider) {
|
|
2426
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2427
|
-
if (this.#providerCalled && provider !== this.#provider) {
|
|
2428
|
-
console.error(`[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`, {
|
|
2429
|
-
previous: this.#provider,
|
|
2430
|
-
provider
|
|
2431
|
-
});
|
|
2432
|
-
}
|
|
2433
|
-
}
|
|
2434
|
-
this.#provider = provider;
|
|
2435
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2436
|
-
this.#providerCalled = false;
|
|
2437
|
-
}
|
|
2438
|
-
}
|
|
2439
|
-
setTimeout(callback, delay) {
|
|
2440
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2441
|
-
this.#providerCalled = true;
|
|
2442
|
-
}
|
|
2443
|
-
return this.#provider.setTimeout(callback, delay);
|
|
2444
|
-
}
|
|
2445
|
-
clearTimeout(timeoutId) {
|
|
2446
|
-
this.#provider.clearTimeout(timeoutId);
|
|
2447
|
-
}
|
|
2448
|
-
setInterval(callback, delay) {
|
|
2449
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2450
|
-
this.#providerCalled = true;
|
|
2451
|
-
}
|
|
2452
|
-
return this.#provider.setInterval(callback, delay);
|
|
2453
|
-
}
|
|
2454
|
-
clearInterval(intervalId) {
|
|
2455
|
-
this.#provider.clearInterval(intervalId);
|
|
2456
|
-
}
|
|
2457
|
-
};
|
|
2458
|
-
var timeoutManager = new TimeoutManager();
|
|
2459
|
-
function systemSetTimeoutZero(callback) {
|
|
2460
|
-
setTimeout(callback, 0);
|
|
2461
|
-
}// src/utils.ts
|
|
2462
|
-
var isServer = typeof window === "undefined" || "Deno" in globalThis;
|
|
2463
|
-
function noop() {}
|
|
2464
|
-
function isValidTimeout(value) {
|
|
2465
|
-
return typeof value === "number" && value >= 0 && value !== Infinity;
|
|
2466
|
-
}
|
|
2467
|
-
function timeUntilStale(updatedAt, staleTime) {
|
|
2468
|
-
return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0);
|
|
2469
|
-
}
|
|
2470
|
-
function resolveStaleTime(staleTime, query) {
|
|
2471
|
-
return typeof staleTime === "function" ? staleTime(query) : staleTime;
|
|
2472
|
-
}
|
|
2473
|
-
function resolveEnabled(enabled, query) {
|
|
2474
|
-
return typeof enabled === "function" ? enabled(query) : enabled;
|
|
2475
|
-
}
|
|
2476
|
-
var hasOwn = Object.prototype.hasOwnProperty;
|
|
2477
|
-
function replaceEqualDeep(a, b, depth = 0) {
|
|
2478
|
-
if (a === b) {
|
|
2479
|
-
return a;
|
|
2480
|
-
}
|
|
2481
|
-
if (depth > 500) return b;
|
|
2482
|
-
const array = isPlainArray(a) && isPlainArray(b);
|
|
2483
|
-
if (!array && !(isPlainObject(a) && isPlainObject(b))) return b;
|
|
2484
|
-
const aItems = array ? a : Object.keys(a);
|
|
2485
|
-
const aSize = aItems.length;
|
|
2486
|
-
const bItems = array ? b : Object.keys(b);
|
|
2487
|
-
const bSize = bItems.length;
|
|
2488
|
-
const copy = array ? new Array(bSize) : {};
|
|
2489
|
-
let equalItems = 0;
|
|
2490
|
-
for (let i = 0; i < bSize; i++) {
|
|
2491
|
-
const key = array ? i : bItems[i];
|
|
2492
|
-
const aItem = a[key];
|
|
2493
|
-
const bItem = b[key];
|
|
2494
|
-
if (aItem === bItem) {
|
|
2495
|
-
copy[key] = aItem;
|
|
2496
|
-
if (array ? i < aSize : hasOwn.call(a, key)) equalItems++;
|
|
2497
|
-
continue;
|
|
2498
|
-
}
|
|
2499
|
-
if (aItem === null || bItem === null || typeof aItem !== "object" || typeof bItem !== "object") {
|
|
2500
|
-
copy[key] = bItem;
|
|
2501
|
-
continue;
|
|
2502
|
-
}
|
|
2503
|
-
const v = replaceEqualDeep(aItem, bItem, depth + 1);
|
|
2504
|
-
copy[key] = v;
|
|
2505
|
-
if (v === aItem) equalItems++;
|
|
2506
|
-
}
|
|
2507
|
-
return aSize === bSize && equalItems === aSize ? a : copy;
|
|
2508
|
-
}
|
|
2509
|
-
function shallowEqualObjects(a, b) {
|
|
2510
|
-
if (!b || Object.keys(a).length !== Object.keys(b).length) {
|
|
2511
|
-
return false;
|
|
2512
|
-
}
|
|
2513
|
-
for (const key in a) {
|
|
2514
|
-
if (a[key] !== b[key]) {
|
|
2515
|
-
return false;
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
return true;
|
|
2519
|
-
}
|
|
2520
|
-
function isPlainArray(value) {
|
|
2521
|
-
return Array.isArray(value) && value.length === Object.keys(value).length;
|
|
2522
|
-
}
|
|
2523
|
-
function isPlainObject(o) {
|
|
2524
|
-
if (!hasObjectPrototype(o)) {
|
|
2525
|
-
return false;
|
|
2526
|
-
}
|
|
2527
|
-
const ctor = o.constructor;
|
|
2528
|
-
if (ctor === void 0) {
|
|
2529
|
-
return true;
|
|
2530
|
-
}
|
|
2531
|
-
const prot = ctor.prototype;
|
|
2532
|
-
if (!hasObjectPrototype(prot)) {
|
|
2533
|
-
return false;
|
|
2534
|
-
}
|
|
2535
|
-
if (!prot.hasOwnProperty("isPrototypeOf")) {
|
|
2536
|
-
return false;
|
|
2537
|
-
}
|
|
2538
|
-
if (Object.getPrototypeOf(o) !== Object.prototype) {
|
|
2539
|
-
return false;
|
|
2540
|
-
}
|
|
2541
|
-
return true;
|
|
2542
|
-
}
|
|
2543
|
-
function hasObjectPrototype(o) {
|
|
2544
|
-
return Object.prototype.toString.call(o) === "[object Object]";
|
|
2545
|
-
}
|
|
2546
|
-
function replaceData(prevData, data, options) {
|
|
2547
|
-
if (typeof options.structuralSharing === "function") {
|
|
2548
|
-
return options.structuralSharing(prevData, data);
|
|
2549
|
-
} else if (options.structuralSharing !== false) {
|
|
2550
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2551
|
-
try {
|
|
2552
|
-
return replaceEqualDeep(prevData, data);
|
|
2553
|
-
} catch (error) {
|
|
2554
|
-
console.error(`Structural sharing requires data to be JSON serializable. To fix this, turn off structuralSharing or return JSON-serializable data from your queryFn. [${options.queryHash}]: ${error}`);
|
|
2555
|
-
throw error;
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
return replaceEqualDeep(prevData, data);
|
|
2559
|
-
}
|
|
2560
|
-
return data;
|
|
2561
|
-
}// src/focusManager.ts
|
|
2562
|
-
var FocusManager = class extends Subscribable {
|
|
2563
|
-
#focused;
|
|
2564
|
-
#cleanup;
|
|
2565
|
-
#setup;
|
|
2566
|
-
constructor() {
|
|
2567
|
-
super();
|
|
2568
|
-
this.#setup = onFocus => {
|
|
2569
|
-
if (!isServer && window.addEventListener) {
|
|
2570
|
-
const listener = () => onFocus();
|
|
2571
|
-
window.addEventListener("visibilitychange", listener, false);
|
|
2572
|
-
return () => {
|
|
2573
|
-
window.removeEventListener("visibilitychange", listener);
|
|
2574
|
-
};
|
|
2575
|
-
}
|
|
2576
|
-
return;
|
|
2577
|
-
};
|
|
2578
|
-
}
|
|
2579
|
-
onSubscribe() {
|
|
2580
|
-
if (!this.#cleanup) {
|
|
2581
|
-
this.setEventListener(this.#setup);
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
|
-
onUnsubscribe() {
|
|
2585
|
-
if (!this.hasListeners()) {
|
|
2586
|
-
this.#cleanup?.();
|
|
2587
|
-
this.#cleanup = void 0;
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
setEventListener(setup) {
|
|
2591
|
-
this.#setup = setup;
|
|
2592
|
-
this.#cleanup?.();
|
|
2593
|
-
this.#cleanup = setup(focused => {
|
|
2594
|
-
if (typeof focused === "boolean") {
|
|
2595
|
-
this.setFocused(focused);
|
|
2596
|
-
} else {
|
|
2597
|
-
this.onFocus();
|
|
2598
|
-
}
|
|
2599
|
-
});
|
|
2600
|
-
}
|
|
2601
|
-
setFocused(focused) {
|
|
2602
|
-
const changed = this.#focused !== focused;
|
|
2603
|
-
if (changed) {
|
|
2604
|
-
this.#focused = focused;
|
|
2605
|
-
this.onFocus();
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
onFocus() {
|
|
2609
|
-
const isFocused = this.isFocused();
|
|
2610
|
-
this.listeners.forEach(listener => {
|
|
2611
|
-
listener(isFocused);
|
|
2612
|
-
});
|
|
2613
|
-
}
|
|
2614
|
-
isFocused() {
|
|
2615
|
-
if (typeof this.#focused === "boolean") {
|
|
2616
|
-
return this.#focused;
|
|
2617
|
-
}
|
|
2618
|
-
return globalThis.document?.visibilityState !== "hidden";
|
|
2619
|
-
}
|
|
2620
|
-
};
|
|
2621
|
-
var focusManager = new FocusManager();// src/thenable.ts
|
|
2622
|
-
function pendingThenable() {
|
|
2623
|
-
let resolve;
|
|
2624
|
-
let reject;
|
|
2625
|
-
const thenable = new Promise((_resolve, _reject) => {
|
|
2626
|
-
resolve = _resolve;
|
|
2627
|
-
reject = _reject;
|
|
2628
|
-
});
|
|
2629
|
-
thenable.status = "pending";
|
|
2630
|
-
thenable.catch(() => {});
|
|
2631
|
-
function finalize(data) {
|
|
2632
|
-
Object.assign(thenable, data);
|
|
2633
|
-
delete thenable.resolve;
|
|
2634
|
-
delete thenable.reject;
|
|
2635
|
-
}
|
|
2636
|
-
thenable.resolve = value => {
|
|
2637
|
-
finalize({
|
|
2638
|
-
status: "fulfilled",
|
|
2639
|
-
value
|
|
2640
|
-
});
|
|
2641
|
-
resolve(value);
|
|
2642
|
-
};
|
|
2643
|
-
thenable.reject = reason => {
|
|
2644
|
-
finalize({
|
|
2645
|
-
status: "rejected",
|
|
2646
|
-
reason
|
|
2647
|
-
});
|
|
2648
|
-
reject(reason);
|
|
2649
|
-
};
|
|
2650
|
-
return thenable;
|
|
2651
|
-
}// src/notifyManager.ts
|
|
2652
|
-
var defaultScheduler = systemSetTimeoutZero;
|
|
2653
|
-
function createNotifyManager() {
|
|
2654
|
-
let queue = [];
|
|
2655
|
-
let transactions = 0;
|
|
2656
|
-
let notifyFn = callback => {
|
|
2657
|
-
callback();
|
|
2658
|
-
};
|
|
2659
|
-
let batchNotifyFn = callback => {
|
|
2660
|
-
callback();
|
|
2661
|
-
};
|
|
2662
|
-
let scheduleFn = defaultScheduler;
|
|
2663
|
-
const schedule = callback => {
|
|
2664
|
-
if (transactions) {
|
|
2665
|
-
queue.push(callback);
|
|
2666
|
-
} else {
|
|
2667
|
-
scheduleFn(() => {
|
|
2668
|
-
notifyFn(callback);
|
|
2669
|
-
});
|
|
2670
|
-
}
|
|
2671
|
-
};
|
|
2672
|
-
const flush = () => {
|
|
2673
|
-
const originalQueue = queue;
|
|
2674
|
-
queue = [];
|
|
2675
|
-
if (originalQueue.length) {
|
|
2676
|
-
scheduleFn(() => {
|
|
2677
|
-
batchNotifyFn(() => {
|
|
2678
|
-
originalQueue.forEach(callback => {
|
|
2679
|
-
notifyFn(callback);
|
|
2680
|
-
});
|
|
2681
|
-
});
|
|
2682
|
-
});
|
|
2683
|
-
}
|
|
2684
|
-
};
|
|
2685
|
-
return {
|
|
2686
|
-
batch: callback => {
|
|
2687
|
-
let result;
|
|
2688
|
-
transactions++;
|
|
2689
|
-
try {
|
|
2690
|
-
result = callback();
|
|
2691
|
-
} finally {
|
|
2692
|
-
transactions--;
|
|
2693
|
-
if (!transactions) {
|
|
2694
|
-
flush();
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
return result;
|
|
2698
|
-
},
|
|
2699
|
-
/**
|
|
2700
|
-
* All calls to the wrapped function will be batched.
|
|
2701
|
-
*/
|
|
2702
|
-
batchCalls: callback => {
|
|
2703
|
-
return (...args) => {
|
|
2704
|
-
schedule(() => {
|
|
2705
|
-
callback(...args);
|
|
2706
|
-
});
|
|
2707
|
-
};
|
|
2708
|
-
},
|
|
2709
|
-
schedule,
|
|
2710
|
-
/**
|
|
2711
|
-
* Use this method to set a custom notify function.
|
|
2712
|
-
* This can be used to for example wrap notifications with `React.act` while running tests.
|
|
2713
|
-
*/
|
|
2714
|
-
setNotifyFunction: fn => {
|
|
2715
|
-
notifyFn = fn;
|
|
2716
|
-
},
|
|
2717
|
-
/**
|
|
2718
|
-
* Use this method to set a custom function to batch notifications together into a single tick.
|
|
2719
|
-
* By default React Query will use the batch function provided by ReactDOM or React Native.
|
|
2720
|
-
*/
|
|
2721
|
-
setBatchNotifyFunction: fn => {
|
|
2722
|
-
batchNotifyFn = fn;
|
|
2723
|
-
},
|
|
2724
|
-
setScheduler: fn => {
|
|
2725
|
-
scheduleFn = fn;
|
|
2726
|
-
}
|
|
2727
|
-
};
|
|
2728
|
-
}
|
|
2729
|
-
var notifyManager = createNotifyManager();// src/onlineManager.ts
|
|
2730
|
-
var OnlineManager = class extends Subscribable {
|
|
2731
|
-
#online = true;
|
|
2732
|
-
#cleanup;
|
|
2733
|
-
#setup;
|
|
2734
|
-
constructor() {
|
|
2735
|
-
super();
|
|
2736
|
-
this.#setup = onOnline => {
|
|
2737
|
-
if (!isServer && window.addEventListener) {
|
|
2738
|
-
const onlineListener = () => onOnline(true);
|
|
2739
|
-
const offlineListener = () => onOnline(false);
|
|
2740
|
-
window.addEventListener("online", onlineListener, false);
|
|
2741
|
-
window.addEventListener("offline", offlineListener, false);
|
|
2742
|
-
return () => {
|
|
2743
|
-
window.removeEventListener("online", onlineListener);
|
|
2744
|
-
window.removeEventListener("offline", offlineListener);
|
|
2745
|
-
};
|
|
2746
|
-
}
|
|
2747
|
-
return;
|
|
2748
|
-
};
|
|
2749
|
-
}
|
|
2750
|
-
onSubscribe() {
|
|
2751
|
-
if (!this.#cleanup) {
|
|
2752
|
-
this.setEventListener(this.#setup);
|
|
2753
|
-
}
|
|
2754
|
-
}
|
|
2755
|
-
onUnsubscribe() {
|
|
2756
|
-
if (!this.hasListeners()) {
|
|
2757
|
-
this.#cleanup?.();
|
|
2758
|
-
this.#cleanup = void 0;
|
|
2759
|
-
}
|
|
2760
|
-
}
|
|
2761
|
-
setEventListener(setup) {
|
|
2762
|
-
this.#setup = setup;
|
|
2763
|
-
this.#cleanup?.();
|
|
2764
|
-
this.#cleanup = setup(this.setOnline.bind(this));
|
|
2765
|
-
}
|
|
2766
|
-
setOnline(online) {
|
|
2767
|
-
const changed = this.#online !== online;
|
|
2768
|
-
if (changed) {
|
|
2769
|
-
this.#online = online;
|
|
2770
|
-
this.listeners.forEach(listener => {
|
|
2771
|
-
listener(online);
|
|
2772
|
-
});
|
|
2773
|
-
}
|
|
2774
|
-
}
|
|
2775
|
-
isOnline() {
|
|
2776
|
-
return this.#online;
|
|
2777
|
-
}
|
|
2778
|
-
};
|
|
2779
|
-
var onlineManager = new OnlineManager();// src/retryer.ts
|
|
2780
|
-
function canFetch(networkMode) {
|
|
2781
|
-
return (networkMode ?? "online") === "online" ? onlineManager.isOnline() : true;
|
|
2782
|
-
}// src/query.ts
|
|
2783
|
-
function fetchState(data, options) {
|
|
2784
|
-
return {
|
|
2785
|
-
fetchFailureCount: 0,
|
|
2786
|
-
fetchFailureReason: null,
|
|
2787
|
-
fetchStatus: canFetch(options.networkMode) ? "fetching" : "paused",
|
|
2788
|
-
...(data === void 0 && {
|
|
2789
|
-
error: null,
|
|
2790
|
-
status: "pending"
|
|
2791
|
-
})
|
|
2792
|
-
};
|
|
2793
|
-
}// src/queryObserver.ts
|
|
2794
|
-
var QueryObserver = class extends Subscribable {
|
|
2795
|
-
constructor(client, options) {
|
|
2796
|
-
super();
|
|
2797
|
-
this.options = options;
|
|
2798
|
-
this.#client = client;
|
|
2799
|
-
this.#selectError = null;
|
|
2800
|
-
this.#currentThenable = pendingThenable();
|
|
2801
|
-
this.bindMethods();
|
|
2802
|
-
this.setOptions(options);
|
|
2803
|
-
}
|
|
2804
|
-
#client;
|
|
2805
|
-
#currentQuery = void 0;
|
|
2806
|
-
#currentQueryInitialState = void 0;
|
|
2807
|
-
#currentResult = void 0;
|
|
2808
|
-
#currentResultState;
|
|
2809
|
-
#currentResultOptions;
|
|
2810
|
-
#currentThenable;
|
|
2811
|
-
#selectError;
|
|
2812
|
-
#selectFn;
|
|
2813
|
-
#selectResult;
|
|
2814
|
-
// This property keeps track of the last query with defined data.
|
|
2815
|
-
// It will be used to pass the previous data and query to the placeholder function between renders.
|
|
2816
|
-
#lastQueryWithDefinedData;
|
|
2817
|
-
#staleTimeoutId;
|
|
2818
|
-
#refetchIntervalId;
|
|
2819
|
-
#currentRefetchInterval;
|
|
2820
|
-
#trackedProps = /* @__PURE__ */new Set();
|
|
2821
|
-
bindMethods() {
|
|
2822
|
-
this.refetch = this.refetch.bind(this);
|
|
2823
|
-
}
|
|
2824
|
-
onSubscribe() {
|
|
2825
|
-
if (this.listeners.size === 1) {
|
|
2826
|
-
this.#currentQuery.addObserver(this);
|
|
2827
|
-
if (shouldFetchOnMount(this.#currentQuery, this.options)) {
|
|
2828
|
-
this.#executeFetch();
|
|
2829
|
-
} else {
|
|
2830
|
-
this.updateResult();
|
|
2831
|
-
}
|
|
2832
|
-
this.#updateTimers();
|
|
2833
|
-
}
|
|
2834
|
-
}
|
|
2835
|
-
onUnsubscribe() {
|
|
2836
|
-
if (!this.hasListeners()) {
|
|
2837
|
-
this.destroy();
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
shouldFetchOnReconnect() {
|
|
2841
|
-
return shouldFetchOn(this.#currentQuery, this.options, this.options.refetchOnReconnect);
|
|
2842
|
-
}
|
|
2843
|
-
shouldFetchOnWindowFocus() {
|
|
2844
|
-
return shouldFetchOn(this.#currentQuery, this.options, this.options.refetchOnWindowFocus);
|
|
2845
|
-
}
|
|
2846
|
-
destroy() {
|
|
2847
|
-
this.listeners = /* @__PURE__ */new Set();
|
|
2848
|
-
this.#clearStaleTimeout();
|
|
2849
|
-
this.#clearRefetchInterval();
|
|
2850
|
-
this.#currentQuery.removeObserver(this);
|
|
2851
|
-
}
|
|
2852
|
-
setOptions(options) {
|
|
2853
|
-
const prevOptions = this.options;
|
|
2854
|
-
const prevQuery = this.#currentQuery;
|
|
2855
|
-
this.options = this.#client.defaultQueryOptions(options);
|
|
2856
|
-
if (this.options.enabled !== void 0 && typeof this.options.enabled !== "boolean" && typeof this.options.enabled !== "function" && typeof resolveEnabled(this.options.enabled, this.#currentQuery) !== "boolean") {
|
|
2857
|
-
throw new Error("Expected enabled to be a boolean or a callback that returns a boolean");
|
|
2858
|
-
}
|
|
2859
|
-
this.#updateQuery();
|
|
2860
|
-
this.#currentQuery.setOptions(this.options);
|
|
2861
|
-
if (prevOptions._defaulted && !shallowEqualObjects(this.options, prevOptions)) {
|
|
2862
|
-
this.#client.getQueryCache().notify({
|
|
2863
|
-
type: "observerOptionsUpdated",
|
|
2864
|
-
query: this.#currentQuery,
|
|
2865
|
-
observer: this
|
|
2866
|
-
});
|
|
2867
|
-
}
|
|
2868
|
-
const mounted = this.hasListeners();
|
|
2869
|
-
if (mounted && shouldFetchOptionally(this.#currentQuery, prevQuery, this.options, prevOptions)) {
|
|
2870
|
-
this.#executeFetch();
|
|
2871
|
-
}
|
|
2872
|
-
this.updateResult();
|
|
2873
|
-
if (mounted && (this.#currentQuery !== prevQuery || resolveEnabled(this.options.enabled, this.#currentQuery) !== resolveEnabled(prevOptions.enabled, this.#currentQuery) || resolveStaleTime(this.options.staleTime, this.#currentQuery) !== resolveStaleTime(prevOptions.staleTime, this.#currentQuery))) {
|
|
2874
|
-
this.#updateStaleTimeout();
|
|
2875
|
-
}
|
|
2876
|
-
const nextRefetchInterval = this.#computeRefetchInterval();
|
|
2877
|
-
if (mounted && (this.#currentQuery !== prevQuery || resolveEnabled(this.options.enabled, this.#currentQuery) !== resolveEnabled(prevOptions.enabled, this.#currentQuery) || nextRefetchInterval !== this.#currentRefetchInterval)) {
|
|
2878
|
-
this.#updateRefetchInterval(nextRefetchInterval);
|
|
2879
|
-
}
|
|
2880
|
-
}
|
|
2881
|
-
getOptimisticResult(options) {
|
|
2882
|
-
const query = this.#client.getQueryCache().build(this.#client, options);
|
|
2883
|
-
const result = this.createResult(query, options);
|
|
2884
|
-
if (shouldAssignObserverCurrentProperties(this, result)) {
|
|
2885
|
-
this.#currentResult = result;
|
|
2886
|
-
this.#currentResultOptions = this.options;
|
|
2887
|
-
this.#currentResultState = this.#currentQuery.state;
|
|
2888
|
-
}
|
|
2889
|
-
return result;
|
|
2890
|
-
}
|
|
2891
|
-
getCurrentResult() {
|
|
2892
|
-
return this.#currentResult;
|
|
2893
|
-
}
|
|
2894
|
-
trackResult(result, onPropTracked) {
|
|
2895
|
-
return new Proxy(result, {
|
|
2896
|
-
get: (target, key) => {
|
|
2897
|
-
this.trackProp(key);
|
|
2898
|
-
onPropTracked?.(key);
|
|
2899
|
-
if (key === "promise") {
|
|
2900
|
-
this.trackProp("data");
|
|
2901
|
-
if (!this.options.experimental_prefetchInRender && this.#currentThenable.status === "pending") {
|
|
2902
|
-
this.#currentThenable.reject(new Error("experimental_prefetchInRender feature flag is not enabled"));
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
return Reflect.get(target, key);
|
|
2906
|
-
}
|
|
2907
|
-
});
|
|
2908
|
-
}
|
|
2909
|
-
trackProp(key) {
|
|
2910
|
-
this.#trackedProps.add(key);
|
|
2911
|
-
}
|
|
2912
|
-
getCurrentQuery() {
|
|
2913
|
-
return this.#currentQuery;
|
|
2914
|
-
}
|
|
2915
|
-
refetch({
|
|
2916
|
-
...options
|
|
2917
|
-
} = {}) {
|
|
2918
|
-
return this.fetch({
|
|
2919
|
-
...options
|
|
2920
|
-
});
|
|
2921
|
-
}
|
|
2922
|
-
fetchOptimistic(options) {
|
|
2923
|
-
const defaultedOptions = this.#client.defaultQueryOptions(options);
|
|
2924
|
-
const query = this.#client.getQueryCache().build(this.#client, defaultedOptions);
|
|
2925
|
-
return query.fetch().then(() => this.createResult(query, defaultedOptions));
|
|
2926
|
-
}
|
|
2927
|
-
fetch(fetchOptions) {
|
|
2928
|
-
return this.#executeFetch({
|
|
2929
|
-
...fetchOptions,
|
|
2930
|
-
cancelRefetch: fetchOptions.cancelRefetch ?? true
|
|
2931
|
-
}).then(() => {
|
|
2932
|
-
this.updateResult();
|
|
2933
|
-
return this.#currentResult;
|
|
2934
|
-
});
|
|
2935
|
-
}
|
|
2936
|
-
#executeFetch(fetchOptions) {
|
|
2937
|
-
this.#updateQuery();
|
|
2938
|
-
let promise = this.#currentQuery.fetch(this.options, fetchOptions);
|
|
2939
|
-
if (!fetchOptions?.throwOnError) {
|
|
2940
|
-
promise = promise.catch(noop);
|
|
2941
|
-
}
|
|
2942
|
-
return promise;
|
|
2943
|
-
}
|
|
2944
|
-
#updateStaleTimeout() {
|
|
2945
|
-
this.#clearStaleTimeout();
|
|
2946
|
-
const staleTime = resolveStaleTime(this.options.staleTime, this.#currentQuery);
|
|
2947
|
-
if (isServer || this.#currentResult.isStale || !isValidTimeout(staleTime)) {
|
|
2948
|
-
return;
|
|
2949
|
-
}
|
|
2950
|
-
const time = timeUntilStale(this.#currentResult.dataUpdatedAt, staleTime);
|
|
2951
|
-
const timeout = time + 1;
|
|
2952
|
-
this.#staleTimeoutId = timeoutManager.setTimeout(() => {
|
|
2953
|
-
if (!this.#currentResult.isStale) {
|
|
2954
|
-
this.updateResult();
|
|
2955
|
-
}
|
|
2956
|
-
}, timeout);
|
|
2957
|
-
}
|
|
2958
|
-
#computeRefetchInterval() {
|
|
2959
|
-
return (typeof this.options.refetchInterval === "function" ? this.options.refetchInterval(this.#currentQuery) : this.options.refetchInterval) ?? false;
|
|
2960
|
-
}
|
|
2961
|
-
#updateRefetchInterval(nextInterval) {
|
|
2962
|
-
this.#clearRefetchInterval();
|
|
2963
|
-
this.#currentRefetchInterval = nextInterval;
|
|
2964
|
-
if (isServer || resolveEnabled(this.options.enabled, this.#currentQuery) === false || !isValidTimeout(this.#currentRefetchInterval) || this.#currentRefetchInterval === 0) {
|
|
2965
|
-
return;
|
|
2966
|
-
}
|
|
2967
|
-
this.#refetchIntervalId = timeoutManager.setInterval(() => {
|
|
2968
|
-
if (this.options.refetchIntervalInBackground || focusManager.isFocused()) {
|
|
2969
|
-
this.#executeFetch();
|
|
2970
|
-
}
|
|
2971
|
-
}, this.#currentRefetchInterval);
|
|
2972
|
-
}
|
|
2973
|
-
#updateTimers() {
|
|
2974
|
-
this.#updateStaleTimeout();
|
|
2975
|
-
this.#updateRefetchInterval(this.#computeRefetchInterval());
|
|
2976
|
-
}
|
|
2977
|
-
#clearStaleTimeout() {
|
|
2978
|
-
if (this.#staleTimeoutId) {
|
|
2979
|
-
timeoutManager.clearTimeout(this.#staleTimeoutId);
|
|
2980
|
-
this.#staleTimeoutId = void 0;
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
#clearRefetchInterval() {
|
|
2984
|
-
if (this.#refetchIntervalId) {
|
|
2985
|
-
timeoutManager.clearInterval(this.#refetchIntervalId);
|
|
2986
|
-
this.#refetchIntervalId = void 0;
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
createResult(query, options) {
|
|
2990
|
-
const prevQuery = this.#currentQuery;
|
|
2991
|
-
const prevOptions = this.options;
|
|
2992
|
-
const prevResult = this.#currentResult;
|
|
2993
|
-
const prevResultState = this.#currentResultState;
|
|
2994
|
-
const prevResultOptions = this.#currentResultOptions;
|
|
2995
|
-
const queryChange = query !== prevQuery;
|
|
2996
|
-
const queryInitialState = queryChange ? query.state : this.#currentQueryInitialState;
|
|
2997
|
-
const {
|
|
2998
|
-
state
|
|
2999
|
-
} = query;
|
|
3000
|
-
let newState = {
|
|
3001
|
-
...state
|
|
3002
|
-
};
|
|
3003
|
-
let isPlaceholderData = false;
|
|
3004
|
-
let data;
|
|
3005
|
-
if (options._optimisticResults) {
|
|
3006
|
-
const mounted = this.hasListeners();
|
|
3007
|
-
const fetchOnMount = !mounted && shouldFetchOnMount(query, options);
|
|
3008
|
-
const fetchOptionally = mounted && shouldFetchOptionally(query, prevQuery, options, prevOptions);
|
|
3009
|
-
if (fetchOnMount || fetchOptionally) {
|
|
3010
|
-
newState = {
|
|
3011
|
-
...newState,
|
|
3012
|
-
...fetchState(state.data, query.options)
|
|
3013
|
-
};
|
|
3014
|
-
}
|
|
3015
|
-
if (options._optimisticResults === "isRestoring") {
|
|
3016
|
-
newState.fetchStatus = "idle";
|
|
3017
|
-
}
|
|
3018
|
-
}
|
|
3019
|
-
let {
|
|
3020
|
-
error,
|
|
3021
|
-
errorUpdatedAt,
|
|
3022
|
-
status
|
|
3023
|
-
} = newState;
|
|
3024
|
-
data = newState.data;
|
|
3025
|
-
let skipSelect = false;
|
|
3026
|
-
if (options.placeholderData !== void 0 && data === void 0 && status === "pending") {
|
|
3027
|
-
let placeholderData;
|
|
3028
|
-
if (prevResult?.isPlaceholderData && options.placeholderData === prevResultOptions?.placeholderData) {
|
|
3029
|
-
placeholderData = prevResult.data;
|
|
3030
|
-
skipSelect = true;
|
|
3031
|
-
} else {
|
|
3032
|
-
placeholderData = typeof options.placeholderData === "function" ? options.placeholderData(this.#lastQueryWithDefinedData?.state.data, this.#lastQueryWithDefinedData) : options.placeholderData;
|
|
3033
|
-
}
|
|
3034
|
-
if (placeholderData !== void 0) {
|
|
3035
|
-
status = "success";
|
|
3036
|
-
data = replaceData(prevResult?.data, placeholderData, options);
|
|
3037
|
-
isPlaceholderData = true;
|
|
3038
|
-
}
|
|
3039
|
-
}
|
|
3040
|
-
if (options.select && data !== void 0 && !skipSelect) {
|
|
3041
|
-
if (prevResult && data === prevResultState?.data && options.select === this.#selectFn) {
|
|
3042
|
-
data = this.#selectResult;
|
|
3043
|
-
} else {
|
|
3044
|
-
try {
|
|
3045
|
-
this.#selectFn = options.select;
|
|
3046
|
-
data = options.select(data);
|
|
3047
|
-
data = replaceData(prevResult?.data, data, options);
|
|
3048
|
-
this.#selectResult = data;
|
|
3049
|
-
this.#selectError = null;
|
|
3050
|
-
} catch (selectError) {
|
|
3051
|
-
this.#selectError = selectError;
|
|
3052
|
-
}
|
|
3053
|
-
}
|
|
3054
|
-
}
|
|
3055
|
-
if (this.#selectError) {
|
|
3056
|
-
error = this.#selectError;
|
|
3057
|
-
data = this.#selectResult;
|
|
3058
|
-
errorUpdatedAt = Date.now();
|
|
3059
|
-
status = "error";
|
|
3060
|
-
}
|
|
3061
|
-
const isFetching = newState.fetchStatus === "fetching";
|
|
3062
|
-
const isPending = status === "pending";
|
|
3063
|
-
const isError = status === "error";
|
|
3064
|
-
const isLoading = isPending && isFetching;
|
|
3065
|
-
const hasData = data !== void 0;
|
|
3066
|
-
const result = {
|
|
3067
|
-
status,
|
|
3068
|
-
fetchStatus: newState.fetchStatus,
|
|
3069
|
-
isPending,
|
|
3070
|
-
isSuccess: status === "success",
|
|
3071
|
-
isError,
|
|
3072
|
-
isInitialLoading: isLoading,
|
|
3073
|
-
isLoading,
|
|
3074
|
-
data,
|
|
3075
|
-
dataUpdatedAt: newState.dataUpdatedAt,
|
|
3076
|
-
error,
|
|
3077
|
-
errorUpdatedAt,
|
|
3078
|
-
failureCount: newState.fetchFailureCount,
|
|
3079
|
-
failureReason: newState.fetchFailureReason,
|
|
3080
|
-
errorUpdateCount: newState.errorUpdateCount,
|
|
3081
|
-
isFetched: newState.dataUpdateCount > 0 || newState.errorUpdateCount > 0,
|
|
3082
|
-
isFetchedAfterMount: newState.dataUpdateCount > queryInitialState.dataUpdateCount || newState.errorUpdateCount > queryInitialState.errorUpdateCount,
|
|
3083
|
-
isFetching,
|
|
3084
|
-
isRefetching: isFetching && !isPending,
|
|
3085
|
-
isLoadingError: isError && !hasData,
|
|
3086
|
-
isPaused: newState.fetchStatus === "paused",
|
|
3087
|
-
isPlaceholderData,
|
|
3088
|
-
isRefetchError: isError && hasData,
|
|
3089
|
-
isStale: isStale(query, options),
|
|
3090
|
-
refetch: this.refetch,
|
|
3091
|
-
promise: this.#currentThenable,
|
|
3092
|
-
isEnabled: resolveEnabled(options.enabled, query) !== false
|
|
3093
|
-
};
|
|
3094
|
-
const nextResult = result;
|
|
3095
|
-
if (this.options.experimental_prefetchInRender) {
|
|
3096
|
-
const hasResultData = nextResult.data !== void 0;
|
|
3097
|
-
const isErrorWithoutData = nextResult.status === "error" && !hasResultData;
|
|
3098
|
-
const finalizeThenableIfPossible = thenable => {
|
|
3099
|
-
if (isErrorWithoutData) {
|
|
3100
|
-
thenable.reject(nextResult.error);
|
|
3101
|
-
} else if (hasResultData) {
|
|
3102
|
-
thenable.resolve(nextResult.data);
|
|
3103
|
-
}
|
|
3104
|
-
};
|
|
3105
|
-
const recreateThenable = () => {
|
|
3106
|
-
const pending = this.#currentThenable = nextResult.promise = pendingThenable();
|
|
3107
|
-
finalizeThenableIfPossible(pending);
|
|
3108
|
-
};
|
|
3109
|
-
const prevThenable = this.#currentThenable;
|
|
3110
|
-
switch (prevThenable.status) {
|
|
3111
|
-
case "pending":
|
|
3112
|
-
if (query.queryHash === prevQuery.queryHash) {
|
|
3113
|
-
finalizeThenableIfPossible(prevThenable);
|
|
3114
|
-
}
|
|
3115
|
-
break;
|
|
3116
|
-
case "fulfilled":
|
|
3117
|
-
if (isErrorWithoutData || nextResult.data !== prevThenable.value) {
|
|
3118
|
-
recreateThenable();
|
|
3119
|
-
}
|
|
3120
|
-
break;
|
|
3121
|
-
case "rejected":
|
|
3122
|
-
if (!isErrorWithoutData || nextResult.error !== prevThenable.reason) {
|
|
3123
|
-
recreateThenable();
|
|
3124
|
-
}
|
|
3125
|
-
break;
|
|
3126
|
-
}
|
|
3127
|
-
}
|
|
3128
|
-
return nextResult;
|
|
3129
|
-
}
|
|
3130
|
-
updateResult() {
|
|
3131
|
-
const prevResult = this.#currentResult;
|
|
3132
|
-
const nextResult = this.createResult(this.#currentQuery, this.options);
|
|
3133
|
-
this.#currentResultState = this.#currentQuery.state;
|
|
3134
|
-
this.#currentResultOptions = this.options;
|
|
3135
|
-
if (this.#currentResultState.data !== void 0) {
|
|
3136
|
-
this.#lastQueryWithDefinedData = this.#currentQuery;
|
|
3137
|
-
}
|
|
3138
|
-
if (shallowEqualObjects(nextResult, prevResult)) {
|
|
3139
|
-
return;
|
|
3140
|
-
}
|
|
3141
|
-
this.#currentResult = nextResult;
|
|
3142
|
-
const shouldNotifyListeners = () => {
|
|
3143
|
-
if (!prevResult) {
|
|
3144
|
-
return true;
|
|
3145
|
-
}
|
|
3146
|
-
const {
|
|
3147
|
-
notifyOnChangeProps
|
|
3148
|
-
} = this.options;
|
|
3149
|
-
const notifyOnChangePropsValue = typeof notifyOnChangeProps === "function" ? notifyOnChangeProps() : notifyOnChangeProps;
|
|
3150
|
-
if (notifyOnChangePropsValue === "all" || !notifyOnChangePropsValue && !this.#trackedProps.size) {
|
|
3151
|
-
return true;
|
|
3152
|
-
}
|
|
3153
|
-
const includedProps = new Set(notifyOnChangePropsValue ?? this.#trackedProps);
|
|
3154
|
-
if (this.options.throwOnError) {
|
|
3155
|
-
includedProps.add("error");
|
|
3156
|
-
}
|
|
3157
|
-
return Object.keys(this.#currentResult).some(key => {
|
|
3158
|
-
const typedKey = key;
|
|
3159
|
-
const changed = this.#currentResult[typedKey] !== prevResult[typedKey];
|
|
3160
|
-
return changed && includedProps.has(typedKey);
|
|
3161
|
-
});
|
|
3162
|
-
};
|
|
3163
|
-
this.#notify({
|
|
3164
|
-
listeners: shouldNotifyListeners()
|
|
3165
|
-
});
|
|
3166
|
-
}
|
|
3167
|
-
#updateQuery() {
|
|
3168
|
-
const query = this.#client.getQueryCache().build(this.#client, this.options);
|
|
3169
|
-
if (query === this.#currentQuery) {
|
|
3170
|
-
return;
|
|
3171
|
-
}
|
|
3172
|
-
const prevQuery = this.#currentQuery;
|
|
3173
|
-
this.#currentQuery = query;
|
|
3174
|
-
this.#currentQueryInitialState = query.state;
|
|
3175
|
-
if (this.hasListeners()) {
|
|
3176
|
-
prevQuery?.removeObserver(this);
|
|
3177
|
-
query.addObserver(this);
|
|
3178
|
-
}
|
|
3179
|
-
}
|
|
3180
|
-
onQueryUpdate() {
|
|
3181
|
-
this.updateResult();
|
|
3182
|
-
if (this.hasListeners()) {
|
|
3183
|
-
this.#updateTimers();
|
|
3184
|
-
}
|
|
3185
|
-
}
|
|
3186
|
-
#notify(notifyOptions) {
|
|
3187
|
-
notifyManager.batch(() => {
|
|
3188
|
-
if (notifyOptions.listeners) {
|
|
3189
|
-
this.listeners.forEach(listener => {
|
|
3190
|
-
listener(this.#currentResult);
|
|
3191
|
-
});
|
|
3192
|
-
}
|
|
3193
|
-
this.#client.getQueryCache().notify({
|
|
3194
|
-
query: this.#currentQuery,
|
|
3195
|
-
type: "observerResultsUpdated"
|
|
3196
|
-
});
|
|
3197
|
-
});
|
|
3198
|
-
}
|
|
3199
|
-
};
|
|
3200
|
-
function shouldLoadOnMount(query, options) {
|
|
3201
|
-
return resolveEnabled(options.enabled, query) !== false && query.state.data === void 0 && !(query.state.status === "error" && options.retryOnMount === false);
|
|
3202
|
-
}
|
|
3203
|
-
function shouldFetchOnMount(query, options) {
|
|
3204
|
-
return shouldLoadOnMount(query, options) || query.state.data !== void 0 && shouldFetchOn(query, options, options.refetchOnMount);
|
|
3205
|
-
}
|
|
3206
|
-
function shouldFetchOn(query, options, field) {
|
|
3207
|
-
if (resolveEnabled(options.enabled, query) !== false && resolveStaleTime(options.staleTime, query) !== "static") {
|
|
3208
|
-
const value = typeof field === "function" ? field(query) : field;
|
|
3209
|
-
return value === "always" || value !== false && isStale(query, options);
|
|
3210
|
-
}
|
|
3211
|
-
return false;
|
|
3212
|
-
}
|
|
3213
|
-
function shouldFetchOptionally(query, prevQuery, options, prevOptions) {
|
|
3214
|
-
return (query !== prevQuery || resolveEnabled(prevOptions.enabled, query) === false) && (!options.suspense || query.state.status !== "error") && isStale(query, options);
|
|
3215
|
-
}
|
|
3216
|
-
function isStale(query, options) {
|
|
3217
|
-
return resolveEnabled(options.enabled, query) !== false && query.isStaleByTime(resolveStaleTime(options.staleTime, query));
|
|
3218
|
-
}
|
|
3219
|
-
function shouldAssignObserverCurrentProperties(observer, optimisticResult) {
|
|
3220
|
-
if (!shallowEqualObjects(observer.getCurrentResult(), optimisticResult)) {
|
|
3221
|
-
return true;
|
|
3222
|
-
}
|
|
3223
|
-
return false;
|
|
3224
3080
|
}const usePageFormManager = ({
|
|
3225
3081
|
form,
|
|
3226
3082
|
pageId,
|