@gaddario98/react-core 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/form/index.js +4566 -1
  2. package/dist/form/index.js.map +1 -1
  3. package/dist/form/index.mjs +4566 -1
  4. package/dist/form/index.mjs.map +1 -1
  5. package/dist/index.d.ts +2152 -7
  6. package/dist/index.js +20713 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +20713 -1
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/localization/index.js +318 -1
  11. package/dist/localization/index.js.map +1 -1
  12. package/dist/localization/index.mjs +318 -1
  13. package/dist/localization/index.mjs.map +1 -1
  14. package/dist/notifications/index.js +84 -0
  15. package/dist/notifications/index.js.map +1 -0
  16. package/dist/notifications/index.mjs +84 -0
  17. package/dist/notifications/index.mjs.map +1 -0
  18. package/dist/pages/index.js +4652 -1
  19. package/dist/pages/index.js.map +1 -1
  20. package/dist/pages/index.mjs +4652 -1
  21. package/dist/pages/index.mjs.map +1 -1
  22. package/dist/providers/index.d.ts +12 -1
  23. package/dist/providers/index.js +17 -1
  24. package/dist/providers/index.js.map +1 -1
  25. package/dist/providers/index.mjs +17 -1
  26. package/dist/providers/index.mjs.map +1 -1
  27. package/dist/queries/index.js +8903 -1
  28. package/dist/queries/index.js.map +1 -1
  29. package/dist/queries/index.mjs +8903 -1
  30. package/dist/queries/index.mjs.map +1 -1
  31. package/dist/state/index.js +1927 -1
  32. package/dist/state/index.js.map +1 -1
  33. package/dist/state/index.mjs +1927 -1
  34. package/dist/state/index.mjs.map +1 -1
  35. package/dist/utiles/index.d.ts +15 -1
  36. package/dist/utiles/index.js +2973 -1
  37. package/dist/utiles/index.js.map +1 -1
  38. package/dist/utiles/index.mjs +2973 -1
  39. package/dist/utiles/index.mjs.map +1 -1
  40. package/package.json +12 -6
  41. package/dist/form/index.d.ts +0 -1
  42. package/dist/localization/index.d.ts +0 -1
  43. package/dist/pages/index.d.ts +0 -1
  44. package/dist/queries/index.d.ts +0 -1
  45. package/dist/state/index.d.ts +0 -1
@@ -1 +1,4566 @@
1
- 'use strict';var reactForm=require('@gaddario98/react-form');Object.keys(reactForm).forEach(function(k){if(k!=='default'&&!Object.prototype.hasOwnProperty.call(exports,k))Object.defineProperty(exports,k,{enumerable:true,get:function(){return reactForm[k]}})});//# sourceMappingURL=index.js.map
1
+ 'use strict';var reactState=require('@gaddario98/react-state'),compilerRuntime=require('react/compiler-runtime'),jsxRuntime=require('react/jsx-runtime'),React=require('react'),equal=require('fast-deep-equal'),withSelector_js=require('use-sync-external-store/shim/with-selector.js');function _interopNamespaceDefault(e){var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var React__namespace=/*#__PURE__*/_interopNamespaceDefault(React);const DefaultContainer = ({
2
+ children
3
+ }) => {
4
+ return children;
5
+ };
6
+ // Lazy initialization to avoid side effects at module load time
7
+ const _formConfig = {
8
+ formFieldContainer: DefaultContainer
9
+ };
10
+ const {
11
+ atom: formConfigAtom,
12
+ useValue: useFormConfigValue,
13
+ useState: useFormConfigState,
14
+ useReset: useFormConfigReset
15
+ } = reactState.atomStateGenerator({
16
+ key: 'formConfig',
17
+ defaultValue: _formConfig,
18
+ persist: false
19
+ });const createDefaultContainer = () => {
20
+ return ({
21
+ children
22
+ }) => {
23
+ return children;
24
+ };
25
+ };
26
+ exports.DefaultContainer = createDefaultContainer();
27
+ const setDefaultFormContainer = val => {
28
+ exports.DefaultContainer = val;
29
+ };
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
+ const DefaultFormContainer = t0 => {
32
+ const $ = compilerRuntime.c(2);
33
+ const {
34
+ children
35
+ } = t0;
36
+ const handleSubmit = _temp$1;
37
+ let t1;
38
+ if ($[0] !== children) {
39
+ t1 = jsxRuntime.jsx("form", {
40
+ onSubmit: handleSubmit,
41
+ className: "gap-3 flex flex-col",
42
+ children
43
+ });
44
+ $[0] = children;
45
+ $[1] = t1;
46
+ } else {
47
+ t1 = $[1];
48
+ }
49
+ return t1;
50
+ };
51
+ function _temp$1(e) {
52
+ e.preventDefault();
53
+ const form = e.currentTarget;
54
+ const submitButton = form.querySelector("button[type=\"submit\"]");
55
+ submitButton === null || submitButton === void 0 ? void 0 : submitButton.click();
56
+ }const __storeToDerived = /* @__PURE__ */new WeakMap();
57
+ const __derivedToStore = /* @__PURE__ */new WeakMap();
58
+ const __depsThatHaveWrittenThisTick = {
59
+ current: []
60
+ };
61
+ let __isFlushing = false;
62
+ let __batchDepth = 0;
63
+ const __pendingUpdates = /* @__PURE__ */new Set();
64
+ const __initialBatchValues = /* @__PURE__ */new Map();
65
+ function __flush_internals(relatedVals) {
66
+ const sorted = Array.from(relatedVals).sort((a, b) => {
67
+ if (a instanceof Derived && a.options.deps.includes(b)) return 1;
68
+ if (b instanceof Derived && b.options.deps.includes(a)) return -1;
69
+ return 0;
70
+ });
71
+ for (const derived of sorted) {
72
+ if (__depsThatHaveWrittenThisTick.current.includes(derived)) {
73
+ continue;
74
+ }
75
+ __depsThatHaveWrittenThisTick.current.push(derived);
76
+ derived.recompute();
77
+ const stores = __derivedToStore.get(derived);
78
+ if (stores) {
79
+ for (const store of stores) {
80
+ const relatedLinkedDerivedVals = __storeToDerived.get(store);
81
+ if (!relatedLinkedDerivedVals) continue;
82
+ __flush_internals(relatedLinkedDerivedVals);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ function __notifyListeners(store) {
88
+ const value = {
89
+ prevVal: store.prevState,
90
+ currentVal: store.state
91
+ };
92
+ for (const listener of store.listeners) {
93
+ listener(value);
94
+ }
95
+ }
96
+ function __notifyDerivedListeners(derived) {
97
+ const value = {
98
+ prevVal: derived.prevState,
99
+ currentVal: derived.state
100
+ };
101
+ for (const listener of derived.listeners) {
102
+ listener(value);
103
+ }
104
+ }
105
+ function __flush(store) {
106
+ if (__batchDepth > 0 && !__initialBatchValues.has(store)) {
107
+ __initialBatchValues.set(store, store.prevState);
108
+ }
109
+ __pendingUpdates.add(store);
110
+ if (__batchDepth > 0) return;
111
+ if (__isFlushing) return;
112
+ try {
113
+ __isFlushing = true;
114
+ while (__pendingUpdates.size > 0) {
115
+ const stores = Array.from(__pendingUpdates);
116
+ __pendingUpdates.clear();
117
+ for (const store2 of stores) {
118
+ const prevState = __initialBatchValues.get(store2) ?? store2.prevState;
119
+ store2.prevState = prevState;
120
+ __notifyListeners(store2);
121
+ }
122
+ for (const store2 of stores) {
123
+ const derivedVals = __storeToDerived.get(store2);
124
+ if (!derivedVals) continue;
125
+ __depsThatHaveWrittenThisTick.current.push(store2);
126
+ __flush_internals(derivedVals);
127
+ }
128
+ for (const store2 of stores) {
129
+ const derivedVals = __storeToDerived.get(store2);
130
+ if (!derivedVals) continue;
131
+ for (const derived of derivedVals) {
132
+ __notifyDerivedListeners(derived);
133
+ }
134
+ }
135
+ }
136
+ } finally {
137
+ __isFlushing = false;
138
+ __depsThatHaveWrittenThisTick.current = [];
139
+ __initialBatchValues.clear();
140
+ }
141
+ }
142
+ function batch(fn) {
143
+ __batchDepth++;
144
+ try {
145
+ fn();
146
+ } finally {
147
+ __batchDepth--;
148
+ if (__batchDepth === 0) {
149
+ const pendingUpdateToFlush = __pendingUpdates.values().next().value;
150
+ if (pendingUpdateToFlush) {
151
+ __flush(pendingUpdateToFlush);
152
+ }
153
+ }
154
+ }
155
+ }function isUpdaterFunction(updater) {
156
+ return typeof updater === "function";
157
+ }class Store {
158
+ constructor(initialState, options) {
159
+ this.listeners = /* @__PURE__ */new Set();
160
+ this.subscribe = listener => {
161
+ var _a, _b;
162
+ this.listeners.add(listener);
163
+ const unsub = (_b = (_a = this.options) == null ? void 0 : _a.onSubscribe) == null ? void 0 : _b.call(_a, listener, this);
164
+ return () => {
165
+ this.listeners.delete(listener);
166
+ unsub == null ? void 0 : unsub();
167
+ };
168
+ };
169
+ this.prevState = initialState;
170
+ this.state = initialState;
171
+ this.options = options;
172
+ }
173
+ setState(updater) {
174
+ var _a, _b, _c;
175
+ this.prevState = this.state;
176
+ if ((_a = this.options) == null ? void 0 : _a.updateFn) {
177
+ this.state = this.options.updateFn(this.prevState)(updater);
178
+ } else {
179
+ if (isUpdaterFunction(updater)) {
180
+ this.state = updater(this.prevState);
181
+ } else {
182
+ this.state = updater;
183
+ }
184
+ }
185
+ (_c = (_b = this.options) == null ? void 0 : _b.onUpdate) == null ? void 0 : _c.call(_b);
186
+ __flush(this);
187
+ }
188
+ }class Derived {
189
+ constructor(options) {
190
+ this.listeners = /* @__PURE__ */new Set();
191
+ this._subscriptions = [];
192
+ this.lastSeenDepValues = [];
193
+ this.getDepVals = () => {
194
+ const l = this.options.deps.length;
195
+ const prevDepVals = new Array(l);
196
+ const currDepVals = new Array(l);
197
+ for (let i = 0; i < l; i++) {
198
+ const dep = this.options.deps[i];
199
+ prevDepVals[i] = dep.prevState;
200
+ currDepVals[i] = dep.state;
201
+ }
202
+ this.lastSeenDepValues = currDepVals;
203
+ return {
204
+ prevDepVals,
205
+ currDepVals,
206
+ prevVal: this.prevState ?? void 0
207
+ };
208
+ };
209
+ this.recompute = () => {
210
+ var _a, _b;
211
+ this.prevState = this.state;
212
+ const depVals = this.getDepVals();
213
+ this.state = this.options.fn(depVals);
214
+ (_b = (_a = this.options).onUpdate) == null ? void 0 : _b.call(_a);
215
+ };
216
+ this.checkIfRecalculationNeededDeeply = () => {
217
+ for (const dep of this.options.deps) {
218
+ if (dep instanceof Derived) {
219
+ dep.checkIfRecalculationNeededDeeply();
220
+ }
221
+ }
222
+ let shouldRecompute = false;
223
+ const lastSeenDepValues = this.lastSeenDepValues;
224
+ const {
225
+ currDepVals
226
+ } = this.getDepVals();
227
+ for (let i = 0; i < currDepVals.length; i++) {
228
+ if (currDepVals[i] !== lastSeenDepValues[i]) {
229
+ shouldRecompute = true;
230
+ break;
231
+ }
232
+ }
233
+ if (shouldRecompute) {
234
+ this.recompute();
235
+ }
236
+ };
237
+ this.mount = () => {
238
+ this.registerOnGraph();
239
+ this.checkIfRecalculationNeededDeeply();
240
+ return () => {
241
+ this.unregisterFromGraph();
242
+ for (const cleanup of this._subscriptions) {
243
+ cleanup();
244
+ }
245
+ };
246
+ };
247
+ this.subscribe = listener => {
248
+ var _a, _b;
249
+ this.listeners.add(listener);
250
+ const unsub = (_b = (_a = this.options).onSubscribe) == null ? void 0 : _b.call(_a, listener, this);
251
+ return () => {
252
+ this.listeners.delete(listener);
253
+ unsub == null ? void 0 : unsub();
254
+ };
255
+ };
256
+ this.options = options;
257
+ this.state = options.fn({
258
+ prevDepVals: void 0,
259
+ prevVal: void 0,
260
+ currDepVals: this.getDepVals().currDepVals
261
+ });
262
+ }
263
+ registerOnGraph(deps = this.options.deps) {
264
+ for (const dep of deps) {
265
+ if (dep instanceof Derived) {
266
+ dep.registerOnGraph();
267
+ this.registerOnGraph(dep.options.deps);
268
+ } else if (dep instanceof Store) {
269
+ let relatedLinkedDerivedVals = __storeToDerived.get(dep);
270
+ if (!relatedLinkedDerivedVals) {
271
+ relatedLinkedDerivedVals = /* @__PURE__ */new Set();
272
+ __storeToDerived.set(dep, relatedLinkedDerivedVals);
273
+ }
274
+ relatedLinkedDerivedVals.add(this);
275
+ let relatedStores = __derivedToStore.get(this);
276
+ if (!relatedStores) {
277
+ relatedStores = /* @__PURE__ */new Set();
278
+ __derivedToStore.set(this, relatedStores);
279
+ }
280
+ relatedStores.add(dep);
281
+ }
282
+ }
283
+ }
284
+ unregisterFromGraph(deps = this.options.deps) {
285
+ for (const dep of deps) {
286
+ if (dep instanceof Derived) {
287
+ this.unregisterFromGraph(dep.options.deps);
288
+ } else if (dep instanceof Store) {
289
+ const relatedLinkedDerivedVals = __storeToDerived.get(dep);
290
+ if (relatedLinkedDerivedVals) {
291
+ relatedLinkedDerivedVals.delete(this);
292
+ }
293
+ const relatedStores = __derivedToStore.get(this);
294
+ if (relatedStores) {
295
+ relatedStores.delete(dep);
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }//#region src/lite-throttler.ts
301
+ /**
302
+ * A lightweight class that creates a throttled function.
303
+ *
304
+ * This is an alternative to the Throttler in the core @tanstack/pacer package, but is more
305
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core Throttler,
306
+ * this version does not use TanStack Store for state management, has no devtools integration,
307
+ * and provides only essential throttling functionality.
308
+ *
309
+ * Throttling ensures a function is called at most once within a specified time window.
310
+ * Unlike debouncing which waits for a pause in calls, throttling guarantees consistent
311
+ * execution timing regardless of call frequency.
312
+ *
313
+ * Supports both leading and trailing edge execution:
314
+ * - Leading: Execute immediately on first call (default: true)
315
+ * - Trailing: Execute after wait period if called during throttle (default: true)
316
+ *
317
+ * Features:
318
+ * - Zero dependencies - no external libraries required
319
+ * - Minimal API surface - only essential methods (maybeExecute, flush, cancel)
320
+ * - Simple state management - uses basic private properties instead of reactive stores
321
+ * - Callback support for monitoring execution events
322
+ * - Lightweight - designed for use in npm packages where bundle size matters
323
+ *
324
+ * @example
325
+ * ```ts
326
+ * const throttler = new LiteThrottler((scrollY: number) => {
327
+ * updateScrollPosition(scrollY);
328
+ * }, {
329
+ * wait: 100,
330
+ * onExecute: (args, throttler) => {
331
+ * console.log('Updated scroll position:', args[0]);
332
+ * }
333
+ * });
334
+ *
335
+ * // Will execute at most once per 100ms
336
+ * window.addEventListener('scroll', () => {
337
+ * throttler.maybeExecute(window.scrollY);
338
+ * });
339
+ * ```
340
+ */
341
+ var LiteThrottler = class {
342
+ constructor(fn, options) {
343
+ this.fn = fn;
344
+ this.options = options;
345
+ this.lastExecutionTime = 0;
346
+ this.isPending = false;
347
+ this.maybeExecute = (...args) => {
348
+ const timeSinceLastExecution = Date.now() - this.lastExecutionTime;
349
+ if (this.options.leading && timeSinceLastExecution >= this.options.wait) this.execute(...args);else {
350
+ this.lastArgs = args;
351
+ if (!this.timeoutId && this.options.trailing) {
352
+ const timeoutDuration = this.options.wait - timeSinceLastExecution;
353
+ this.isPending = true;
354
+ this.timeoutId = setTimeout(() => {
355
+ if (this.lastArgs !== void 0) this.execute(...this.lastArgs);
356
+ }, timeoutDuration);
357
+ }
358
+ }
359
+ };
360
+ this.execute = (...args) => {
361
+ this.fn(...args);
362
+ this.options.onExecute?.(args, this);
363
+ this.lastExecutionTime = Date.now();
364
+ this.clearTimeout();
365
+ this.lastArgs = void 0;
366
+ this.isPending = false;
367
+ };
368
+ this.flush = () => {
369
+ if (this.isPending && this.lastArgs) this.execute(...this.lastArgs);
370
+ };
371
+ this.cancel = () => {
372
+ this.clearTimeout();
373
+ this.lastArgs = void 0;
374
+ this.isPending = false;
375
+ };
376
+ this.clearTimeout = () => {
377
+ if (this.timeoutId) {
378
+ clearTimeout(this.timeoutId);
379
+ this.timeoutId = void 0;
380
+ }
381
+ };
382
+ if (this.options.leading === void 0 && this.options.trailing === void 0) {
383
+ this.options.leading = true;
384
+ this.options.trailing = true;
385
+ }
386
+ }
387
+ };
388
+ /**
389
+ * Creates a lightweight throttled function that limits how often the provided function can execute.
390
+ *
391
+ * This is an alternative to the throttle function in the core @tanstack/pacer package, but is more
392
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,
393
+ * this function creates a throttler with no external dependencies, devtools integration, or reactive state.
394
+ *
395
+ * Throttling ensures a function executes at most once within a specified time window,
396
+ * regardless of how many times it is called. This is useful for rate-limiting
397
+ * expensive operations or UI updates.
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * const throttledScroll = liteThrottle(() => {
402
+ * updateScrollIndicator();
403
+ * }, { wait: 100 });
404
+ *
405
+ * // Will execute at most once per 100ms
406
+ * window.addEventListener('scroll', throttledScroll);
407
+ * ```
408
+ *
409
+ * @example
410
+ * ```ts
411
+ * // Leading edge execution - fires immediately then throttles
412
+ * const throttledResize = liteThrottle(() => {
413
+ * recalculateLayout();
414
+ * }, { wait: 250, leading: true, trailing: false });
415
+ * ```
416
+ */
417
+ function liteThrottle(fn, options) {
418
+ return new LiteThrottler(fn, options).maybeExecute;
419
+ }class EventClient {
420
+ #enabled = true;
421
+ #pluginId;
422
+ #eventTarget;
423
+ #debug;
424
+ #queuedEvents;
425
+ #connected;
426
+ #connectIntervalId;
427
+ #connectEveryMs;
428
+ #retryCount = 0;
429
+ #maxRetries = 5;
430
+ #connecting = false;
431
+ #failedToConnect = false;
432
+ #internalEventTarget = null;
433
+ #onConnected = () => {
434
+ this.debugLog("Connected to event bus");
435
+ this.#connected = true;
436
+ this.#connecting = false;
437
+ this.debugLog("Emitting queued events", this.#queuedEvents);
438
+ this.#queuedEvents.forEach(event => this.emitEventToBus(event));
439
+ this.#queuedEvents = [];
440
+ this.stopConnectLoop();
441
+ this.#eventTarget().removeEventListener("tanstack-connect-success", this.#onConnected);
442
+ };
443
+ // fired off right away and then at intervals
444
+ #retryConnection = () => {
445
+ if (this.#retryCount < this.#maxRetries) {
446
+ this.#retryCount++;
447
+ this.dispatchCustomEvent("tanstack-connect", {});
448
+ return;
449
+ }
450
+ this.#eventTarget().removeEventListener("tanstack-connect", this.#retryConnection);
451
+ this.#failedToConnect = true;
452
+ this.debugLog("Max retries reached, giving up on connection");
453
+ this.stopConnectLoop();
454
+ };
455
+ // This is run to register connection handlers on first emit attempt
456
+ #connectFunction = () => {
457
+ if (this.#connecting) return;
458
+ this.#connecting = true;
459
+ this.#eventTarget().addEventListener("tanstack-connect-success", this.#onConnected);
460
+ this.#retryConnection();
461
+ };
462
+ constructor({
463
+ pluginId,
464
+ debug = false,
465
+ enabled = true,
466
+ reconnectEveryMs = 300
467
+ }) {
468
+ this.#pluginId = pluginId;
469
+ this.#enabled = enabled;
470
+ this.#eventTarget = this.getGlobalTarget;
471
+ this.#debug = debug;
472
+ this.debugLog(" Initializing event subscription for plugin", this.#pluginId);
473
+ this.#queuedEvents = [];
474
+ this.#connected = false;
475
+ this.#failedToConnect = false;
476
+ this.#connectIntervalId = null;
477
+ this.#connectEveryMs = reconnectEveryMs;
478
+ }
479
+ startConnectLoop() {
480
+ if (this.#connectIntervalId !== null || this.#connected) return;
481
+ this.debugLog(`Starting connect loop (every ${this.#connectEveryMs}ms)`);
482
+ this.#connectIntervalId = setInterval(this.#retryConnection, this.#connectEveryMs);
483
+ }
484
+ stopConnectLoop() {
485
+ this.#connecting = false;
486
+ if (this.#connectIntervalId === null) {
487
+ return;
488
+ }
489
+ clearInterval(this.#connectIntervalId);
490
+ this.#connectIntervalId = null;
491
+ this.#queuedEvents = [];
492
+ this.debugLog("Stopped connect loop");
493
+ }
494
+ debugLog(...args) {
495
+ if (this.#debug) {
496
+ console.log(`🌴 [tanstack-devtools:${this.#pluginId}-plugin]`, ...args);
497
+ }
498
+ }
499
+ getGlobalTarget() {
500
+ if (typeof globalThis !== "undefined" && globalThis.__TANSTACK_EVENT_TARGET__) {
501
+ this.debugLog("Using global event target");
502
+ return globalThis.__TANSTACK_EVENT_TARGET__;
503
+ }
504
+ if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
505
+ this.debugLog("Using window as event target");
506
+ return window;
507
+ }
508
+ const eventTarget = typeof EventTarget !== "undefined" ? new EventTarget() : void 0;
509
+ if (typeof eventTarget === "undefined" || typeof eventTarget.addEventListener === "undefined") {
510
+ this.debugLog("No event mechanism available, running in non-web environment");
511
+ return {
512
+ addEventListener: () => {},
513
+ removeEventListener: () => {},
514
+ dispatchEvent: () => false
515
+ };
516
+ }
517
+ this.debugLog("Using new EventTarget as fallback");
518
+ return eventTarget;
519
+ }
520
+ getPluginId() {
521
+ return this.#pluginId;
522
+ }
523
+ dispatchCustomEventShim(eventName, detail) {
524
+ try {
525
+ const event = new Event(eventName, {
526
+ detail
527
+ });
528
+ this.#eventTarget().dispatchEvent(event);
529
+ } catch (e) {
530
+ this.debugLog("Failed to dispatch shim event");
531
+ }
532
+ }
533
+ dispatchCustomEvent(eventName, detail) {
534
+ try {
535
+ this.#eventTarget().dispatchEvent(new CustomEvent(eventName, {
536
+ detail
537
+ }));
538
+ } catch (e) {
539
+ this.dispatchCustomEventShim(eventName, detail);
540
+ }
541
+ }
542
+ emitEventToBus(event) {
543
+ this.debugLog("Emitting event to client bus", event);
544
+ this.dispatchCustomEvent("tanstack-dispatch-event", event);
545
+ }
546
+ createEventPayload(eventSuffix, payload) {
547
+ return {
548
+ type: `${this.#pluginId}:${eventSuffix}`,
549
+ payload,
550
+ pluginId: this.#pluginId
551
+ };
552
+ }
553
+ emit(eventSuffix, payload) {
554
+ if (!this.#enabled) {
555
+ this.debugLog("Event bus client is disabled, not emitting event", eventSuffix, payload);
556
+ return;
557
+ }
558
+ if (this.#internalEventTarget) {
559
+ this.debugLog("Emitting event to internal event target", eventSuffix, payload);
560
+ this.#internalEventTarget.dispatchEvent(new CustomEvent(`${this.#pluginId}:${eventSuffix}`, {
561
+ detail: this.createEventPayload(eventSuffix, payload)
562
+ }));
563
+ }
564
+ if (this.#failedToConnect) {
565
+ this.debugLog("Previously failed to connect, not emitting to bus");
566
+ return;
567
+ }
568
+ if (!this.#connected) {
569
+ this.debugLog("Bus not available, will be pushed as soon as connected");
570
+ this.#queuedEvents.push(this.createEventPayload(eventSuffix, payload));
571
+ if (typeof CustomEvent !== "undefined" && !this.#connecting) {
572
+ this.#connectFunction();
573
+ this.startConnectLoop();
574
+ }
575
+ return;
576
+ }
577
+ return this.emitEventToBus(this.createEventPayload(eventSuffix, payload));
578
+ }
579
+ on(eventSuffix, cb, options) {
580
+ const withEventTarget = options?.withEventTarget ?? false;
581
+ const eventName = `${this.#pluginId}:${eventSuffix}`;
582
+ if (withEventTarget) {
583
+ if (!this.#internalEventTarget) {
584
+ this.#internalEventTarget = new EventTarget();
585
+ }
586
+ this.#internalEventTarget.addEventListener(eventName, e => {
587
+ cb(e.detail);
588
+ });
589
+ }
590
+ if (!this.#enabled) {
591
+ this.debugLog("Event bus client is disabled, not registering event", eventName);
592
+ return () => {};
593
+ }
594
+ const handler = e => {
595
+ this.debugLog("Received event from bus", e.detail);
596
+ cb(e.detail);
597
+ };
598
+ this.#eventTarget().addEventListener(eventName, handler);
599
+ this.debugLog("Registered event to bus", eventName);
600
+ return () => {
601
+ if (withEventTarget) {
602
+ this.#internalEventTarget?.removeEventListener(eventName, handler);
603
+ }
604
+ this.#eventTarget().removeEventListener(eventName, handler);
605
+ };
606
+ }
607
+ onAll(cb) {
608
+ if (!this.#enabled) {
609
+ this.debugLog("Event bus client is disabled, not registering event");
610
+ return () => {};
611
+ }
612
+ const handler = e => {
613
+ const event = e.detail;
614
+ cb(event);
615
+ };
616
+ this.#eventTarget().addEventListener("tanstack-devtools-global", handler);
617
+ return () => this.#eventTarget().removeEventListener("tanstack-devtools-global", handler);
618
+ }
619
+ onAllPluginEvents(cb) {
620
+ if (!this.#enabled) {
621
+ this.debugLog("Event bus client is disabled, not registering event");
622
+ return () => {};
623
+ }
624
+ const handler = e => {
625
+ const event = e.detail;
626
+ if (this.#pluginId && event.pluginId !== this.#pluginId) {
627
+ return;
628
+ }
629
+ cb(event);
630
+ };
631
+ this.#eventTarget().addEventListener("tanstack-devtools-global", handler);
632
+ return () => this.#eventTarget().removeEventListener("tanstack-devtools-global", handler);
633
+ }
634
+ }class FormEventClient extends EventClient {
635
+ constructor() {
636
+ super({
637
+ pluginId: "form-devtools",
638
+ reconnectEveryMs: 1e3
639
+ });
640
+ }
641
+ }
642
+ const formEventClient = new FormEventClient();function functionalUpdate(updater, input) {
643
+ return typeof updater === "function" ? updater(input) : updater;
644
+ }
645
+ function getBy(obj, path) {
646
+ const pathObj = makePathArray(path);
647
+ return pathObj.reduce((current, pathPart) => {
648
+ if (current === null) return null;
649
+ if (typeof current !== "undefined") {
650
+ return current[pathPart];
651
+ }
652
+ return void 0;
653
+ }, obj);
654
+ }
655
+ function setBy(obj, _path, updater) {
656
+ const path = makePathArray(_path);
657
+ function doSet(parent) {
658
+ if (!path.length) {
659
+ return functionalUpdate(updater, parent);
660
+ }
661
+ const key = path.shift();
662
+ if (typeof key === "string" || typeof key === "number" && !Array.isArray(parent)) {
663
+ if (typeof parent === "object") {
664
+ if (parent === null) {
665
+ parent = {};
666
+ }
667
+ return {
668
+ ...parent,
669
+ [key]: doSet(parent[key])
670
+ };
671
+ }
672
+ return {
673
+ [key]: doSet()
674
+ };
675
+ }
676
+ if (Array.isArray(parent) && typeof key === "number") {
677
+ const prefix = parent.slice(0, key);
678
+ return [...(prefix.length ? prefix : new Array(key)), doSet(parent[key]), ...parent.slice(key + 1)];
679
+ }
680
+ return [...new Array(key), doSet()];
681
+ }
682
+ return doSet(obj);
683
+ }
684
+ function deleteBy(obj, _path) {
685
+ const path = makePathArray(_path);
686
+ function doDelete(parent) {
687
+ if (!parent) return;
688
+ if (path.length === 1) {
689
+ const finalPath = path[0];
690
+ if (Array.isArray(parent) && typeof finalPath === "number") {
691
+ return parent.filter((_, i) => i !== finalPath);
692
+ }
693
+ const {
694
+ [finalPath]: remove,
695
+ ...rest
696
+ } = parent;
697
+ return rest;
698
+ }
699
+ const key = path.shift();
700
+ if (typeof key === "string" || typeof key === "number" && !Array.isArray(parent)) {
701
+ if (typeof parent === "object") {
702
+ return {
703
+ ...parent,
704
+ [key]: doDelete(parent[key])
705
+ };
706
+ }
707
+ }
708
+ if (typeof key === "number") {
709
+ if (Array.isArray(parent)) {
710
+ if (key >= parent.length) {
711
+ return parent;
712
+ }
713
+ const prefix = parent.slice(0, key);
714
+ return [...(prefix.length ? prefix : new Array(key)), doDelete(parent[key]), ...parent.slice(key + 1)];
715
+ }
716
+ }
717
+ throw new Error("It seems we have created an infinite loop in deleteBy. ");
718
+ }
719
+ return doDelete(obj);
720
+ }
721
+ const reLineOfOnlyDigits = /^(\d+)$/gm;
722
+ const reDigitsBetweenDots = /\.(\d+)(?=\.)/gm;
723
+ const reStartWithDigitThenDot = /^(\d+)\./gm;
724
+ const reDotWithDigitsToEnd = /\.(\d+$)/gm;
725
+ const reMultipleDots = /\.{2,}/gm;
726
+ const intPrefix = "__int__";
727
+ const intReplace = `${intPrefix}$1`;
728
+ function makePathArray(str) {
729
+ if (Array.isArray(str)) {
730
+ return [...str];
731
+ }
732
+ if (typeof str !== "string") {
733
+ throw new Error("Path must be a string.");
734
+ }
735
+ return str.replace(/(^\[)|]/gm, "").replace(/\[/g, ".").replace(reLineOfOnlyDigits, intReplace).replace(reDigitsBetweenDots, `.${intReplace}.`).replace(reStartWithDigitThenDot, `${intReplace}.`).replace(reDotWithDigitsToEnd, `.${intReplace}`).replace(reMultipleDots, ".").split(".").map(d => {
736
+ if (d.startsWith(intPrefix)) {
737
+ const numStr = d.substring(intPrefix.length);
738
+ const num = parseInt(numStr, 10);
739
+ if (String(num) === numStr) {
740
+ return num;
741
+ }
742
+ return numStr;
743
+ }
744
+ return d;
745
+ });
746
+ }
747
+ function isNonEmptyArray(obj) {
748
+ return !(Array.isArray(obj) && obj.length === 0);
749
+ }
750
+ function getSyncValidatorArray(cause, options) {
751
+ const runValidation = props => {
752
+ return props.validators.filter(Boolean).map(validator => {
753
+ return {
754
+ cause: validator.cause,
755
+ validate: validator.fn
756
+ };
757
+ });
758
+ };
759
+ return options.validationLogic({
760
+ form: options.form,
761
+ validators: options.validators,
762
+ event: {
763
+ type: cause,
764
+ async: false
765
+ },
766
+ runValidation
767
+ });
768
+ }
769
+ function getAsyncValidatorArray(cause, options) {
770
+ const {
771
+ asyncDebounceMs
772
+ } = options;
773
+ const {
774
+ onBlurAsyncDebounceMs,
775
+ onChangeAsyncDebounceMs,
776
+ onDynamicAsyncDebounceMs
777
+ } = options.validators || {};
778
+ const defaultDebounceMs = asyncDebounceMs ?? 0;
779
+ const runValidation = props => {
780
+ return props.validators.filter(Boolean).map(validator => {
781
+ const validatorCause = validator?.cause || cause;
782
+ let debounceMs = defaultDebounceMs;
783
+ switch (validatorCause) {
784
+ case "change":
785
+ debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs;
786
+ break;
787
+ case "blur":
788
+ debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs;
789
+ break;
790
+ case "dynamic":
791
+ debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs;
792
+ break;
793
+ case "submit":
794
+ debounceMs = 0;
795
+ break;
796
+ }
797
+ if (cause === "submit") {
798
+ debounceMs = 0;
799
+ }
800
+ return {
801
+ cause: validatorCause,
802
+ validate: validator.fn,
803
+ debounceMs
804
+ };
805
+ });
806
+ };
807
+ return options.validationLogic({
808
+ form: options.form,
809
+ validators: options.validators,
810
+ event: {
811
+ type: cause,
812
+ async: true
813
+ },
814
+ runValidation
815
+ });
816
+ }
817
+ const isGlobalFormValidationError = error => {
818
+ return !!error && typeof error === "object" && "fields" in error;
819
+ };
820
+ function evaluate(objA, objB) {
821
+ if (Object.is(objA, objB)) {
822
+ return true;
823
+ }
824
+ if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
825
+ return false;
826
+ }
827
+ if (objA instanceof Date && objB instanceof Date) {
828
+ return objA.getTime() === objB.getTime();
829
+ }
830
+ if (objA instanceof Map && objB instanceof Map) {
831
+ if (objA.size !== objB.size) return false;
832
+ for (const [k, v] of objA) {
833
+ if (!objB.has(k) || !Object.is(v, objB.get(k))) return false;
834
+ }
835
+ return true;
836
+ }
837
+ if (objA instanceof Set && objB instanceof Set) {
838
+ if (objA.size !== objB.size) return false;
839
+ for (const v of objA) {
840
+ if (!objB.has(v)) return false;
841
+ }
842
+ return true;
843
+ }
844
+ const keysA = Object.keys(objA);
845
+ const keysB = Object.keys(objB);
846
+ if (keysA.length !== keysB.length) {
847
+ return false;
848
+ }
849
+ for (const key of keysA) {
850
+ if (!keysB.includes(key) || !evaluate(objA[key], objB[key])) {
851
+ return false;
852
+ }
853
+ }
854
+ return true;
855
+ }
856
+ const determineFormLevelErrorSourceAndValue = ({
857
+ newFormValidatorError,
858
+ isPreviousErrorFromFormValidator,
859
+ previousErrorValue
860
+ }) => {
861
+ if (newFormValidatorError) {
862
+ return {
863
+ newErrorValue: newFormValidatorError,
864
+ newSource: "form"
865
+ };
866
+ }
867
+ if (isPreviousErrorFromFormValidator) {
868
+ return {
869
+ newErrorValue: void 0,
870
+ newSource: void 0
871
+ };
872
+ }
873
+ if (previousErrorValue) {
874
+ return {
875
+ newErrorValue: previousErrorValue,
876
+ newSource: "field"
877
+ };
878
+ }
879
+ return {
880
+ newErrorValue: void 0,
881
+ newSource: void 0
882
+ };
883
+ };
884
+ const determineFieldLevelErrorSourceAndValue = ({
885
+ formLevelError,
886
+ fieldLevelError
887
+ }) => {
888
+ if (fieldLevelError) {
889
+ return {
890
+ newErrorValue: fieldLevelError,
891
+ newSource: "field"
892
+ };
893
+ }
894
+ if (formLevelError) {
895
+ return {
896
+ newErrorValue: formLevelError,
897
+ newSource: "form"
898
+ };
899
+ }
900
+ return {
901
+ newErrorValue: void 0,
902
+ newSource: void 0
903
+ };
904
+ };
905
+ function mergeOpts(originalOpts, overrides) {
906
+ if (originalOpts === void 0 || originalOpts === null) {
907
+ return overrides;
908
+ }
909
+ return {
910
+ ...originalOpts,
911
+ ...overrides
912
+ };
913
+ }
914
+ let IDX = 256;
915
+ const HEX = [];
916
+ let BUFFER;
917
+ while (IDX--) {
918
+ HEX[IDX] = (IDX + 256).toString(16).substring(1);
919
+ }
920
+ function uuid() {
921
+ let i = 0;
922
+ let num;
923
+ let out = "";
924
+ if (!BUFFER || IDX + 16 > 256) {
925
+ BUFFER = new Array(256);
926
+ i = 256;
927
+ while (i--) {
928
+ BUFFER[i] = 256 * Math.random() | 0;
929
+ }
930
+ i = 0;
931
+ IDX = 0;
932
+ }
933
+ for (; i < 16; i++) {
934
+ num = BUFFER[IDX + i];
935
+ if (i === 6) out += HEX[num & 15 | 64];else if (i === 8) out += HEX[num & 63 | 128];else out += HEX[num];
936
+ if (i & 1 && i > 1 && i < 11) out += "-";
937
+ }
938
+ IDX++;
939
+ return out;
940
+ }
941
+ const throttleFormState = liteThrottle(form => formEventClient.emit("form-state", {
942
+ id: form.formId,
943
+ state: form.store.state
944
+ }), {
945
+ wait: 300
946
+ });const defaultValidationLogic = props => {
947
+ if (!props.validators) {
948
+ return props.runValidation({
949
+ validators: [],
950
+ form: props.form
951
+ });
952
+ }
953
+ const isAsync = props.event.async;
954
+ const onMountValidator = isAsync ? void 0 : {
955
+ fn: props.validators.onMount,
956
+ cause: "mount"
957
+ };
958
+ const onChangeValidator = {
959
+ fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,
960
+ cause: "change"
961
+ };
962
+ const onBlurValidator = {
963
+ fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,
964
+ cause: "blur"
965
+ };
966
+ const onSubmitValidator = {
967
+ fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,
968
+ cause: "submit"
969
+ };
970
+ const onServerValidator = isAsync ? void 0 : {
971
+ fn: () => void 0,
972
+ cause: "server"
973
+ };
974
+ switch (props.event.type) {
975
+ case "mount":
976
+ {
977
+ return props.runValidation({
978
+ validators: [onMountValidator],
979
+ form: props.form
980
+ });
981
+ }
982
+ case "submit":
983
+ {
984
+ return props.runValidation({
985
+ validators: [onChangeValidator, onBlurValidator, onSubmitValidator, onServerValidator],
986
+ form: props.form
987
+ });
988
+ }
989
+ case "server":
990
+ {
991
+ return props.runValidation({
992
+ validators: [],
993
+ form: props.form
994
+ });
995
+ }
996
+ case "blur":
997
+ {
998
+ return props.runValidation({
999
+ validators: [onBlurValidator, onServerValidator],
1000
+ form: props.form
1001
+ });
1002
+ }
1003
+ case "change":
1004
+ {
1005
+ return props.runValidation({
1006
+ validators: [onChangeValidator, onServerValidator],
1007
+ form: props.form
1008
+ });
1009
+ }
1010
+ default:
1011
+ {
1012
+ throw new Error(`Unknown validation event type: ${props.event.type}`);
1013
+ }
1014
+ }
1015
+ };function prefixSchemaToErrors(issues, formValue) {
1016
+ const schema = /* @__PURE__ */new Map();
1017
+ for (const issue of issues) {
1018
+ const issuePath = issue.path ?? [];
1019
+ let currentFormValue = formValue;
1020
+ let path = "";
1021
+ for (let i = 0; i < issuePath.length; i++) {
1022
+ const pathSegment = issuePath[i];
1023
+ if (pathSegment === void 0) continue;
1024
+ const segment = typeof pathSegment === "object" ? pathSegment.key : pathSegment;
1025
+ const segmentAsNumber = Number(segment);
1026
+ if (Array.isArray(currentFormValue) && !Number.isNaN(segmentAsNumber)) {
1027
+ path += `[${segmentAsNumber}]`;
1028
+ } else {
1029
+ path += (i > 0 ? "." : "") + String(segment);
1030
+ }
1031
+ if (typeof currentFormValue === "object" && currentFormValue !== null) {
1032
+ currentFormValue = currentFormValue[segment];
1033
+ } else {
1034
+ currentFormValue = void 0;
1035
+ }
1036
+ }
1037
+ schema.set(path, (schema.get(path) ?? []).concat(issue));
1038
+ }
1039
+ return Object.fromEntries(schema);
1040
+ }
1041
+ const transformFormIssues = (issues, formValue) => {
1042
+ const schemaErrors = prefixSchemaToErrors(issues, formValue);
1043
+ return {
1044
+ form: schemaErrors,
1045
+ fields: schemaErrors
1046
+ };
1047
+ };
1048
+ const standardSchemaValidators = {
1049
+ validate({
1050
+ value,
1051
+ validationSource
1052
+ }, schema) {
1053
+ const result = schema["~standard"].validate(value);
1054
+ if (result instanceof Promise) {
1055
+ throw new Error("async function passed to sync validator");
1056
+ }
1057
+ if (!result.issues) return;
1058
+ if (validationSource === "field") return result.issues;
1059
+ return transformFormIssues(result.issues, value);
1060
+ },
1061
+ async validateAsync({
1062
+ value,
1063
+ validationSource
1064
+ }, schema) {
1065
+ const result = await schema["~standard"].validate(value);
1066
+ if (!result.issues) return;
1067
+ if (validationSource === "field") return result.issues;
1068
+ return transformFormIssues(result.issues, value);
1069
+ }
1070
+ };
1071
+ const isStandardSchemaValidator = validator => !!validator && "~standard" in validator;const defaultFieldMeta = {
1072
+ isValidating: false,
1073
+ isTouched: false,
1074
+ isBlurred: false,
1075
+ isDirty: false,
1076
+ isPristine: true,
1077
+ isValid: true,
1078
+ isDefaultValue: true,
1079
+ errors: [],
1080
+ errorMap: {},
1081
+ errorSourceMap: {}
1082
+ };
1083
+ function metaHelper(formApi) {
1084
+ function handleArrayMove(field, fromIndex, toIndex) {
1085
+ const affectedFields = getAffectedFields(field, fromIndex, "move", toIndex);
1086
+ const startIndex = Math.min(fromIndex, toIndex);
1087
+ const endIndex = Math.max(fromIndex, toIndex);
1088
+ for (let i = startIndex; i <= endIndex; i++) {
1089
+ affectedFields.push(getFieldPath(field, i));
1090
+ }
1091
+ const fromFields = Object.keys(formApi.fieldInfo).reduce((fieldMap, fieldKey) => {
1092
+ if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {
1093
+ fieldMap.set(fieldKey, formApi.getFieldMeta(fieldKey));
1094
+ }
1095
+ return fieldMap;
1096
+ }, /* @__PURE__ */new Map());
1097
+ shiftMeta(affectedFields, fromIndex < toIndex ? "up" : "down");
1098
+ Object.keys(formApi.fieldInfo).filter(fieldKey => fieldKey.startsWith(getFieldPath(field, toIndex))).forEach(fieldKey => {
1099
+ const fromKey = fieldKey.replace(getFieldPath(field, toIndex), getFieldPath(field, fromIndex));
1100
+ const fromMeta = fromFields.get(fromKey);
1101
+ if (fromMeta) {
1102
+ formApi.setFieldMeta(fieldKey, fromMeta);
1103
+ }
1104
+ });
1105
+ }
1106
+ function handleArrayRemove(field, index) {
1107
+ const affectedFields = getAffectedFields(field, index, "remove");
1108
+ shiftMeta(affectedFields, "up");
1109
+ }
1110
+ function handleArraySwap(field, index, secondIndex) {
1111
+ const affectedFields = getAffectedFields(field, index, "swap", secondIndex);
1112
+ affectedFields.forEach(fieldKey => {
1113
+ if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {
1114
+ return;
1115
+ }
1116
+ const swappedKey = fieldKey.toString().replace(getFieldPath(field, index), getFieldPath(field, secondIndex));
1117
+ const [meta1, meta2] = [formApi.getFieldMeta(fieldKey), formApi.getFieldMeta(swappedKey)];
1118
+ if (meta1) formApi.setFieldMeta(swappedKey, meta1);
1119
+ if (meta2) formApi.setFieldMeta(fieldKey, meta2);
1120
+ });
1121
+ }
1122
+ function handleArrayInsert(field, insertIndex) {
1123
+ const affectedFields = getAffectedFields(field, insertIndex, "insert");
1124
+ shiftMeta(affectedFields, "down");
1125
+ affectedFields.forEach(fieldKey => {
1126
+ if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {
1127
+ formApi.setFieldMeta(fieldKey, getEmptyFieldMeta());
1128
+ }
1129
+ });
1130
+ }
1131
+ function getFieldPath(field, index) {
1132
+ return `${field}[${index}]`;
1133
+ }
1134
+ function getAffectedFields(field, index, mode, secondIndex) {
1135
+ const affectedFieldKeys = [getFieldPath(field, index)];
1136
+ switch (mode) {
1137
+ case "swap":
1138
+ affectedFieldKeys.push(getFieldPath(field, secondIndex));
1139
+ break;
1140
+ case "move":
1141
+ {
1142
+ const [startIndex, endIndex] = [Math.min(index, secondIndex), Math.max(index, secondIndex)];
1143
+ for (let i = startIndex; i <= endIndex; i++) {
1144
+ affectedFieldKeys.push(getFieldPath(field, i));
1145
+ }
1146
+ break;
1147
+ }
1148
+ default:
1149
+ {
1150
+ const currentValue = formApi.getFieldValue(field);
1151
+ const fieldItems = Array.isArray(currentValue) ? currentValue.length : 0;
1152
+ for (let i = index + 1; i < fieldItems; i++) {
1153
+ affectedFieldKeys.push(getFieldPath(field, i));
1154
+ }
1155
+ break;
1156
+ }
1157
+ }
1158
+ return Object.keys(formApi.fieldInfo).filter(fieldKey => affectedFieldKeys.some(key => fieldKey.startsWith(key)));
1159
+ }
1160
+ function updateIndex(fieldKey, direction) {
1161
+ return fieldKey.replace(/\[(\d+)\]/, (_, num) => {
1162
+ const currIndex = parseInt(num, 10);
1163
+ const newIndex = direction === "up" ? currIndex + 1 : Math.max(0, currIndex - 1);
1164
+ return `[${newIndex}]`;
1165
+ });
1166
+ }
1167
+ function shiftMeta(fields, direction) {
1168
+ const sortedFields = direction === "up" ? fields : [...fields].reverse();
1169
+ sortedFields.forEach(fieldKey => {
1170
+ const nextFieldKey = updateIndex(fieldKey.toString(), direction);
1171
+ const nextFieldMeta = formApi.getFieldMeta(nextFieldKey);
1172
+ if (nextFieldMeta) {
1173
+ formApi.setFieldMeta(fieldKey, nextFieldMeta);
1174
+ } else {
1175
+ formApi.setFieldMeta(fieldKey, getEmptyFieldMeta());
1176
+ }
1177
+ });
1178
+ }
1179
+ const getEmptyFieldMeta = () => defaultFieldMeta;
1180
+ return {
1181
+ handleArrayMove,
1182
+ handleArrayRemove,
1183
+ handleArraySwap,
1184
+ handleArrayInsert
1185
+ };
1186
+ }function getDefaultFormState(defaultState) {
1187
+ return {
1188
+ values: defaultState.values ?? {},
1189
+ errorMap: defaultState.errorMap ?? {},
1190
+ fieldMetaBase: defaultState.fieldMetaBase ?? {},
1191
+ isSubmitted: defaultState.isSubmitted ?? false,
1192
+ isSubmitting: defaultState.isSubmitting ?? false,
1193
+ isValidating: defaultState.isValidating ?? false,
1194
+ submissionAttempts: defaultState.submissionAttempts ?? 0,
1195
+ isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,
1196
+ validationMetaMap: defaultState.validationMetaMap ?? {
1197
+ onChange: void 0,
1198
+ onBlur: void 0,
1199
+ onSubmit: void 0,
1200
+ onMount: void 0,
1201
+ onServer: void 0,
1202
+ onDynamic: void 0
1203
+ }
1204
+ };
1205
+ }
1206
+ class FormApi {
1207
+ /**
1208
+ * Constructs a new `FormApi` instance with the given form options.
1209
+ */
1210
+ constructor(opts) {
1211
+ this.options = {};
1212
+ this.fieldInfo = {};
1213
+ this.prevTransformArray = [];
1214
+ this.mount = () => {
1215
+ const cleanupFieldMetaDerived = this.fieldMetaDerived.mount();
1216
+ const cleanupStoreDerived = this.store.mount();
1217
+ const cleanupDevtoolBroadcast = this.store.subscribe(() => {
1218
+ throttleFormState(this);
1219
+ });
1220
+ const cleanupFormStateListener = formEventClient.on("request-form-state", e => {
1221
+ if (e.payload.id === this._formId) {
1222
+ formEventClient.emit("form-api", {
1223
+ id: this._formId,
1224
+ state: this.store.state,
1225
+ options: this.options
1226
+ });
1227
+ }
1228
+ });
1229
+ const cleanupFormResetListener = formEventClient.on("request-form-reset", e => {
1230
+ if (e.payload.id === this._formId) {
1231
+ this.reset();
1232
+ }
1233
+ });
1234
+ const cleanupFormForceSubmitListener = formEventClient.on("request-form-force-submit", e => {
1235
+ if (e.payload.id === this._formId) {
1236
+ this._devtoolsSubmissionOverride = true;
1237
+ this.handleSubmit();
1238
+ this._devtoolsSubmissionOverride = false;
1239
+ }
1240
+ });
1241
+ const cleanup = () => {
1242
+ cleanupFormForceSubmitListener();
1243
+ cleanupFormResetListener();
1244
+ cleanupFormStateListener();
1245
+ cleanupDevtoolBroadcast();
1246
+ cleanupFieldMetaDerived();
1247
+ cleanupStoreDerived();
1248
+ formEventClient.emit("form-unmounted", {
1249
+ id: this._formId
1250
+ });
1251
+ };
1252
+ this.options.listeners?.onMount?.({
1253
+ formApi: this
1254
+ });
1255
+ const {
1256
+ onMount
1257
+ } = this.options.validators || {};
1258
+ formEventClient.emit("form-api", {
1259
+ id: this._formId,
1260
+ state: this.store.state,
1261
+ options: this.options
1262
+ });
1263
+ if (!onMount) return cleanup;
1264
+ this.validateSync("mount");
1265
+ return cleanup;
1266
+ };
1267
+ this.update = options => {
1268
+ if (!options) return;
1269
+ const oldOptions = this.options;
1270
+ this.options = options;
1271
+ const shouldUpdateReeval = !!options.transform?.deps?.some((val, i) => val !== this.prevTransformArray[i]);
1272
+ const shouldUpdateValues = options.defaultValues && !evaluate(options.defaultValues, oldOptions.defaultValues) && !this.state.isTouched;
1273
+ const shouldUpdateState = !evaluate(options.defaultState, oldOptions.defaultState) && !this.state.isTouched;
1274
+ if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return;
1275
+ batch(() => {
1276
+ this.baseStore.setState(() => getDefaultFormState(Object.assign({}, this.state, shouldUpdateState ? options.defaultState : {}, shouldUpdateValues ? {
1277
+ values: options.defaultValues
1278
+ } : {}, shouldUpdateReeval ? {
1279
+ _force_re_eval: !this.state._force_re_eval
1280
+ } : {})));
1281
+ });
1282
+ formEventClient.emit("form-api", {
1283
+ id: this._formId,
1284
+ state: this.store.state,
1285
+ options: this.options
1286
+ });
1287
+ };
1288
+ this.reset = (values, opts2) => {
1289
+ const {
1290
+ fieldMeta: currentFieldMeta
1291
+ } = this.state;
1292
+ const fieldMetaBase = this.resetFieldMeta(currentFieldMeta);
1293
+ if (values && !opts2?.keepDefaultValues) {
1294
+ this.options = {
1295
+ ...this.options,
1296
+ defaultValues: values
1297
+ };
1298
+ }
1299
+ this.baseStore.setState(() => getDefaultFormState({
1300
+ ...this.options.defaultState,
1301
+ values: values ?? this.options.defaultValues ?? this.options.defaultState?.values,
1302
+ fieldMetaBase
1303
+ }));
1304
+ };
1305
+ this.validateAllFields = async cause => {
1306
+ const fieldValidationPromises = [];
1307
+ batch(() => {
1308
+ void Object.values(this.fieldInfo).forEach(field => {
1309
+ if (!field.instance) return;
1310
+ const fieldInstance = field.instance;
1311
+ fieldValidationPromises.push(
1312
+ // Remember, `validate` is either a sync operation or a promise
1313
+ Promise.resolve().then(() => fieldInstance.validate(cause, {
1314
+ skipFormValidation: true
1315
+ })));
1316
+ if (!field.instance.state.meta.isTouched) {
1317
+ field.instance.setMeta(prev => ({
1318
+ ...prev,
1319
+ isTouched: true
1320
+ }));
1321
+ }
1322
+ });
1323
+ });
1324
+ const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
1325
+ return fieldErrorMapMap.flat();
1326
+ };
1327
+ this.validateArrayFieldsStartingFrom = async (field, index, cause) => {
1328
+ const currentValue = this.getFieldValue(field);
1329
+ const lastIndex = Array.isArray(currentValue) ? Math.max(currentValue.length - 1, 0) : null;
1330
+ const fieldKeysToValidate = [`${field}[${index}]`];
1331
+ for (let i = index + 1; i <= (lastIndex ?? 0); i++) {
1332
+ fieldKeysToValidate.push(`${field}[${i}]`);
1333
+ }
1334
+ const fieldsToValidate = Object.keys(this.fieldInfo).filter(fieldKey => fieldKeysToValidate.some(key => fieldKey.startsWith(key)));
1335
+ const fieldValidationPromises = [];
1336
+ batch(() => {
1337
+ fieldsToValidate.forEach(nestedField => {
1338
+ fieldValidationPromises.push(Promise.resolve().then(() => this.validateField(nestedField, cause)));
1339
+ });
1340
+ });
1341
+ const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
1342
+ return fieldErrorMapMap.flat();
1343
+ };
1344
+ this.validateField = (field, cause) => {
1345
+ const fieldInstance = this.fieldInfo[field]?.instance;
1346
+ if (!fieldInstance) return [];
1347
+ if (!fieldInstance.state.meta.isTouched) {
1348
+ fieldInstance.setMeta(prev => ({
1349
+ ...prev,
1350
+ isTouched: true
1351
+ }));
1352
+ }
1353
+ return fieldInstance.validate(cause);
1354
+ };
1355
+ this.validateSync = cause => {
1356
+ const validates = getSyncValidatorArray(cause, {
1357
+ ...this.options,
1358
+ form: this,
1359
+ validationLogic: this.options.validationLogic || defaultValidationLogic
1360
+ });
1361
+ let hasErrored = false;
1362
+ const currentValidationErrorMap = {};
1363
+ batch(() => {
1364
+ for (const validateObj of validates) {
1365
+ if (!validateObj.validate) continue;
1366
+ const rawError = this.runValidator({
1367
+ validate: validateObj.validate,
1368
+ value: {
1369
+ value: this.state.values,
1370
+ formApi: this,
1371
+ validationSource: "form"
1372
+ },
1373
+ type: "validate"
1374
+ });
1375
+ const {
1376
+ formError,
1377
+ fieldErrors
1378
+ } = normalizeError$1(rawError);
1379
+ const errorMapKey = getErrorMapKey$1(validateObj.cause);
1380
+ const allFieldsToProcess = /* @__PURE__ */new Set([...Object.keys(this.state.fieldMeta), ...Object.keys(fieldErrors || {})]);
1381
+ for (const field of allFieldsToProcess) {
1382
+ if (this.baseStore.state.fieldMetaBase[field] === void 0 && !fieldErrors?.[field]) {
1383
+ continue;
1384
+ }
1385
+ const fieldMeta = this.getFieldMeta(field) ?? defaultFieldMeta;
1386
+ const {
1387
+ errorMap: currentErrorMap,
1388
+ errorSourceMap: currentErrorMapSource
1389
+ } = fieldMeta;
1390
+ const newFormValidatorError = fieldErrors?.[field];
1391
+ const {
1392
+ newErrorValue,
1393
+ newSource
1394
+ } = determineFormLevelErrorSourceAndValue({
1395
+ newFormValidatorError,
1396
+ isPreviousErrorFromFormValidator:
1397
+ // These conditional checks are required, otherwise we get runtime errors.
1398
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1399
+ currentErrorMapSource?.[errorMapKey] === "form",
1400
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1401
+ previousErrorValue: currentErrorMap?.[errorMapKey]
1402
+ });
1403
+ if (newSource === "form") {
1404
+ currentValidationErrorMap[field] = {
1405
+ ...currentValidationErrorMap[field],
1406
+ [errorMapKey]: newFormValidatorError
1407
+ };
1408
+ }
1409
+ if (currentErrorMap?.[errorMapKey] !== newErrorValue) {
1410
+ this.setFieldMeta(field, (prev = defaultFieldMeta) => ({
1411
+ ...prev,
1412
+ errorMap: {
1413
+ ...prev.errorMap,
1414
+ [errorMapKey]: newErrorValue
1415
+ },
1416
+ errorSourceMap: {
1417
+ ...prev.errorSourceMap,
1418
+ [errorMapKey]: newSource
1419
+ }
1420
+ }));
1421
+ }
1422
+ }
1423
+ if (this.state.errorMap?.[errorMapKey] !== formError) {
1424
+ this.baseStore.setState(prev => ({
1425
+ ...prev,
1426
+ errorMap: {
1427
+ ...prev.errorMap,
1428
+ [errorMapKey]: formError
1429
+ }
1430
+ }));
1431
+ }
1432
+ if (formError || fieldErrors) {
1433
+ hasErrored = true;
1434
+ }
1435
+ }
1436
+ const submitErrKey = getErrorMapKey$1("submit");
1437
+ if (
1438
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1439
+ this.state.errorMap?.[submitErrKey] && cause !== "submit" && !hasErrored) {
1440
+ this.baseStore.setState(prev => ({
1441
+ ...prev,
1442
+ errorMap: {
1443
+ ...prev.errorMap,
1444
+ [submitErrKey]: void 0
1445
+ }
1446
+ }));
1447
+ }
1448
+ const serverErrKey = getErrorMapKey$1("server");
1449
+ if (
1450
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1451
+ this.state.errorMap?.[serverErrKey] && cause !== "server" && !hasErrored) {
1452
+ this.baseStore.setState(prev => ({
1453
+ ...prev,
1454
+ errorMap: {
1455
+ ...prev.errorMap,
1456
+ [serverErrKey]: void 0
1457
+ }
1458
+ }));
1459
+ }
1460
+ });
1461
+ return {
1462
+ hasErrored,
1463
+ fieldsErrorMap: currentValidationErrorMap
1464
+ };
1465
+ };
1466
+ this.validateAsync = async cause => {
1467
+ const validates = getAsyncValidatorArray(cause, {
1468
+ ...this.options,
1469
+ form: this,
1470
+ validationLogic: this.options.validationLogic || defaultValidationLogic
1471
+ });
1472
+ if (!this.state.isFormValidating) {
1473
+ this.baseStore.setState(prev => ({
1474
+ ...prev,
1475
+ isFormValidating: true
1476
+ }));
1477
+ }
1478
+ const promises = [];
1479
+ let fieldErrorsFromFormValidators;
1480
+ for (const validateObj of validates) {
1481
+ if (!validateObj.validate) continue;
1482
+ const key = getErrorMapKey$1(validateObj.cause);
1483
+ const fieldValidatorMeta = this.state.validationMetaMap[key];
1484
+ fieldValidatorMeta?.lastAbortController.abort();
1485
+ const controller = new AbortController();
1486
+ this.state.validationMetaMap[key] = {
1487
+ lastAbortController: controller
1488
+ };
1489
+ promises.push(new Promise(async resolve => {
1490
+ let rawError;
1491
+ try {
1492
+ rawError = await new Promise((rawResolve, rawReject) => {
1493
+ setTimeout(async () => {
1494
+ if (controller.signal.aborted) return rawResolve(void 0);
1495
+ try {
1496
+ rawResolve(await this.runValidator({
1497
+ validate: validateObj.validate,
1498
+ value: {
1499
+ value: this.state.values,
1500
+ formApi: this,
1501
+ validationSource: "form",
1502
+ signal: controller.signal
1503
+ },
1504
+ type: "validateAsync"
1505
+ }));
1506
+ } catch (e) {
1507
+ rawReject(e);
1508
+ }
1509
+ }, validateObj.debounceMs);
1510
+ });
1511
+ } catch (e) {
1512
+ rawError = e;
1513
+ }
1514
+ const {
1515
+ formError,
1516
+ fieldErrors: fieldErrorsFromNormalizeError
1517
+ } = normalizeError$1(rawError);
1518
+ if (fieldErrorsFromNormalizeError) {
1519
+ fieldErrorsFromFormValidators = fieldErrorsFromFormValidators ? {
1520
+ ...fieldErrorsFromFormValidators,
1521
+ ...fieldErrorsFromNormalizeError
1522
+ } : fieldErrorsFromNormalizeError;
1523
+ }
1524
+ const errorMapKey = getErrorMapKey$1(validateObj.cause);
1525
+ for (const field of Object.keys(this.state.fieldMeta)) {
1526
+ if (this.baseStore.state.fieldMetaBase[field] === void 0) {
1527
+ continue;
1528
+ }
1529
+ const fieldMeta = this.getFieldMeta(field);
1530
+ if (!fieldMeta) continue;
1531
+ const {
1532
+ errorMap: currentErrorMap,
1533
+ errorSourceMap: currentErrorMapSource
1534
+ } = fieldMeta;
1535
+ const newFormValidatorError = fieldErrorsFromFormValidators?.[field];
1536
+ const {
1537
+ newErrorValue,
1538
+ newSource
1539
+ } = determineFormLevelErrorSourceAndValue({
1540
+ newFormValidatorError,
1541
+ isPreviousErrorFromFormValidator:
1542
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1543
+ currentErrorMapSource?.[errorMapKey] === "form",
1544
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1545
+ previousErrorValue: currentErrorMap?.[errorMapKey]
1546
+ });
1547
+ if (
1548
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1549
+ currentErrorMap?.[errorMapKey] !== newErrorValue) {
1550
+ this.setFieldMeta(field, prev => ({
1551
+ ...prev,
1552
+ errorMap: {
1553
+ ...prev.errorMap,
1554
+ [errorMapKey]: newErrorValue
1555
+ },
1556
+ errorSourceMap: {
1557
+ ...prev.errorSourceMap,
1558
+ [errorMapKey]: newSource
1559
+ }
1560
+ }));
1561
+ }
1562
+ }
1563
+ this.baseStore.setState(prev => ({
1564
+ ...prev,
1565
+ errorMap: {
1566
+ ...prev.errorMap,
1567
+ [errorMapKey]: formError
1568
+ }
1569
+ }));
1570
+ resolve(fieldErrorsFromFormValidators ? {
1571
+ fieldErrors: fieldErrorsFromFormValidators,
1572
+ errorMapKey
1573
+ } : void 0);
1574
+ }));
1575
+ }
1576
+ let results = [];
1577
+ const fieldsErrorMap = {};
1578
+ if (promises.length) {
1579
+ results = await Promise.all(promises);
1580
+ for (const fieldValidationResult of results) {
1581
+ if (fieldValidationResult?.fieldErrors) {
1582
+ const {
1583
+ errorMapKey
1584
+ } = fieldValidationResult;
1585
+ for (const [field, fieldError] of Object.entries(fieldValidationResult.fieldErrors)) {
1586
+ const oldErrorMap = fieldsErrorMap[field] || {};
1587
+ const newErrorMap = {
1588
+ ...oldErrorMap,
1589
+ [errorMapKey]: fieldError
1590
+ };
1591
+ fieldsErrorMap[field] = newErrorMap;
1592
+ }
1593
+ }
1594
+ }
1595
+ }
1596
+ this.baseStore.setState(prev => ({
1597
+ ...prev,
1598
+ isFormValidating: false
1599
+ }));
1600
+ return fieldsErrorMap;
1601
+ };
1602
+ this.validate = cause => {
1603
+ const {
1604
+ hasErrored,
1605
+ fieldsErrorMap
1606
+ } = this.validateSync(cause);
1607
+ if (hasErrored && !this.options.asyncAlways) {
1608
+ return fieldsErrorMap;
1609
+ }
1610
+ return this.validateAsync(cause);
1611
+ };
1612
+ this._handleSubmit = async submitMeta => {
1613
+ this.baseStore.setState(old => ({
1614
+ ...old,
1615
+ // Submission attempts mark the form as not submitted
1616
+ isSubmitted: false,
1617
+ // Count submission attempts
1618
+ submissionAttempts: old.submissionAttempts + 1,
1619
+ isSubmitSuccessful: false
1620
+ // Reset isSubmitSuccessful at the start of submission
1621
+ }));
1622
+ batch(() => {
1623
+ void Object.values(this.fieldInfo).forEach(field => {
1624
+ if (!field.instance) return;
1625
+ if (!field.instance.state.meta.isTouched) {
1626
+ field.instance.setMeta(prev => ({
1627
+ ...prev,
1628
+ isTouched: true
1629
+ }));
1630
+ }
1631
+ });
1632
+ });
1633
+ const submitMetaArg = submitMeta ?? this.options.onSubmitMeta;
1634
+ if (!this.state.canSubmit && !this._devtoolsSubmissionOverride) {
1635
+ this.options.onSubmitInvalid?.({
1636
+ value: this.state.values,
1637
+ formApi: this,
1638
+ meta: submitMetaArg
1639
+ });
1640
+ return;
1641
+ }
1642
+ this.baseStore.setState(d => ({
1643
+ ...d,
1644
+ isSubmitting: true
1645
+ }));
1646
+ const done = () => {
1647
+ this.baseStore.setState(prev => ({
1648
+ ...prev,
1649
+ isSubmitting: false
1650
+ }));
1651
+ };
1652
+ await this.validateAllFields("submit");
1653
+ if (!this.state.isFieldsValid) {
1654
+ done();
1655
+ this.options.onSubmitInvalid?.({
1656
+ value: this.state.values,
1657
+ formApi: this,
1658
+ meta: submitMetaArg
1659
+ });
1660
+ formEventClient.emit("form-submission", {
1661
+ id: this._formId,
1662
+ submissionAttempt: this.state.submissionAttempts,
1663
+ successful: false,
1664
+ stage: "validateAllFields",
1665
+ errors: Object.values(this.state.fieldMeta).map(meta => meta.errors).flat()
1666
+ });
1667
+ return;
1668
+ }
1669
+ await this.validate("submit");
1670
+ if (!this.state.isValid) {
1671
+ done();
1672
+ this.options.onSubmitInvalid?.({
1673
+ value: this.state.values,
1674
+ formApi: this,
1675
+ meta: submitMetaArg
1676
+ });
1677
+ formEventClient.emit("form-submission", {
1678
+ id: this._formId,
1679
+ submissionAttempt: this.state.submissionAttempts,
1680
+ successful: false,
1681
+ stage: "validate",
1682
+ errors: this.state.errors
1683
+ });
1684
+ return;
1685
+ }
1686
+ batch(() => {
1687
+ void Object.values(this.fieldInfo).forEach(field => {
1688
+ field.instance?.options.listeners?.onSubmit?.({
1689
+ value: field.instance.state.value,
1690
+ fieldApi: field.instance
1691
+ });
1692
+ });
1693
+ });
1694
+ this.options.listeners?.onSubmit?.({
1695
+ formApi: this,
1696
+ meta: submitMetaArg
1697
+ });
1698
+ try {
1699
+ await this.options.onSubmit?.({
1700
+ value: this.state.values,
1701
+ formApi: this,
1702
+ meta: submitMetaArg
1703
+ });
1704
+ batch(() => {
1705
+ this.baseStore.setState(prev => ({
1706
+ ...prev,
1707
+ isSubmitted: true,
1708
+ isSubmitSuccessful: true
1709
+ // Set isSubmitSuccessful to true on successful submission
1710
+ }));
1711
+ formEventClient.emit("form-submission", {
1712
+ id: this._formId,
1713
+ submissionAttempt: this.state.submissionAttempts,
1714
+ successful: true
1715
+ });
1716
+ done();
1717
+ });
1718
+ } catch (err) {
1719
+ this.baseStore.setState(prev => ({
1720
+ ...prev,
1721
+ isSubmitSuccessful: false
1722
+ // Ensure isSubmitSuccessful is false if an error occurs
1723
+ }));
1724
+ formEventClient.emit("form-submission", {
1725
+ id: this._formId,
1726
+ submissionAttempt: this.state.submissionAttempts,
1727
+ successful: false,
1728
+ stage: "inflight",
1729
+ onError: err
1730
+ });
1731
+ done();
1732
+ throw err;
1733
+ }
1734
+ };
1735
+ this.getFieldValue = field => getBy(this.state.values, field);
1736
+ this.getFieldMeta = field => {
1737
+ return this.state.fieldMeta[field];
1738
+ };
1739
+ this.getFieldInfo = field => {
1740
+ return this.fieldInfo[field] ||= {
1741
+ instance: null,
1742
+ validationMetaMap: {
1743
+ onChange: void 0,
1744
+ onBlur: void 0,
1745
+ onSubmit: void 0,
1746
+ onMount: void 0,
1747
+ onServer: void 0,
1748
+ onDynamic: void 0
1749
+ }
1750
+ };
1751
+ };
1752
+ this.setFieldMeta = (field, updater) => {
1753
+ this.baseStore.setState(prev => {
1754
+ return {
1755
+ ...prev,
1756
+ fieldMetaBase: {
1757
+ ...prev.fieldMetaBase,
1758
+ [field]: functionalUpdate(updater, prev.fieldMetaBase[field])
1759
+ }
1760
+ };
1761
+ });
1762
+ };
1763
+ this.resetFieldMeta = fieldMeta => {
1764
+ return Object.keys(fieldMeta).reduce((acc, key) => {
1765
+ const fieldKey = key;
1766
+ acc[fieldKey] = defaultFieldMeta;
1767
+ return acc;
1768
+ }, {});
1769
+ };
1770
+ this.setFieldValue = (field, updater, opts2) => {
1771
+ const dontUpdateMeta = opts2?.dontUpdateMeta ?? false;
1772
+ const dontRunListeners = opts2?.dontRunListeners ?? false;
1773
+ const dontValidate = opts2?.dontValidate ?? false;
1774
+ batch(() => {
1775
+ if (!dontUpdateMeta) {
1776
+ this.setFieldMeta(field, prev => ({
1777
+ ...prev,
1778
+ isTouched: true,
1779
+ isDirty: true,
1780
+ errorMap: {
1781
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1782
+ ...prev?.errorMap,
1783
+ onMount: void 0
1784
+ }
1785
+ }));
1786
+ }
1787
+ this.baseStore.setState(prev => {
1788
+ return {
1789
+ ...prev,
1790
+ values: setBy(prev.values, field, updater)
1791
+ };
1792
+ });
1793
+ });
1794
+ if (!dontRunListeners) {
1795
+ this.getFieldInfo(field).instance?.triggerOnChangeListener();
1796
+ }
1797
+ if (!dontValidate) {
1798
+ this.validateField(field, "change");
1799
+ }
1800
+ };
1801
+ this.deleteField = field => {
1802
+ const subFieldsToDelete = Object.keys(this.fieldInfo).filter(f => {
1803
+ const fieldStr = field.toString();
1804
+ return f !== fieldStr && f.startsWith(fieldStr);
1805
+ });
1806
+ const fieldsToDelete = [...subFieldsToDelete, field];
1807
+ this.baseStore.setState(prev => {
1808
+ const newState = {
1809
+ ...prev
1810
+ };
1811
+ fieldsToDelete.forEach(f => {
1812
+ newState.values = deleteBy(newState.values, f);
1813
+ delete this.fieldInfo[f];
1814
+ delete newState.fieldMetaBase[f];
1815
+ });
1816
+ return newState;
1817
+ });
1818
+ };
1819
+ this.pushFieldValue = (field, value, options) => {
1820
+ this.setFieldValue(field, prev => [...(Array.isArray(prev) ? prev : []), value], options);
1821
+ };
1822
+ this.insertFieldValue = async (field, index, value, options) => {
1823
+ this.setFieldValue(field, prev => {
1824
+ return [...prev.slice(0, index), value, ...prev.slice(index)];
1825
+ }, mergeOpts(options, {
1826
+ dontValidate: true
1827
+ }));
1828
+ const dontValidate = options?.dontValidate ?? false;
1829
+ if (!dontValidate) {
1830
+ await this.validateField(field, "change");
1831
+ }
1832
+ metaHelper(this).handleArrayInsert(field, index);
1833
+ if (!dontValidate) {
1834
+ await this.validateArrayFieldsStartingFrom(field, index, "change");
1835
+ }
1836
+ };
1837
+ this.replaceFieldValue = async (field, index, value, options) => {
1838
+ this.setFieldValue(field, prev => {
1839
+ return prev.map((d, i) => i === index ? value : d);
1840
+ }, mergeOpts(options, {
1841
+ dontValidate: true
1842
+ }));
1843
+ const dontValidate = options?.dontValidate ?? false;
1844
+ if (!dontValidate) {
1845
+ await this.validateField(field, "change");
1846
+ await this.validateArrayFieldsStartingFrom(field, index, "change");
1847
+ }
1848
+ };
1849
+ this.removeFieldValue = async (field, index, options) => {
1850
+ const fieldValue = this.getFieldValue(field);
1851
+ const lastIndex = Array.isArray(fieldValue) ? Math.max(fieldValue.length - 1, 0) : null;
1852
+ this.setFieldValue(field, prev => {
1853
+ return prev.filter((_d, i) => i !== index);
1854
+ }, mergeOpts(options, {
1855
+ dontValidate: true
1856
+ }));
1857
+ metaHelper(this).handleArrayRemove(field, index);
1858
+ if (lastIndex !== null) {
1859
+ const start = `${field}[${lastIndex}]`;
1860
+ this.deleteField(start);
1861
+ }
1862
+ const dontValidate = options?.dontValidate ?? false;
1863
+ if (!dontValidate) {
1864
+ await this.validateField(field, "change");
1865
+ await this.validateArrayFieldsStartingFrom(field, index, "change");
1866
+ }
1867
+ };
1868
+ this.swapFieldValues = (field, index1, index2, options) => {
1869
+ this.setFieldValue(field, prev => {
1870
+ const prev1 = prev[index1];
1871
+ const prev2 = prev[index2];
1872
+ return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1);
1873
+ }, mergeOpts(options, {
1874
+ dontValidate: true
1875
+ }));
1876
+ metaHelper(this).handleArraySwap(field, index1, index2);
1877
+ const dontValidate = options?.dontValidate ?? false;
1878
+ if (!dontValidate) {
1879
+ this.validateField(field, "change");
1880
+ this.validateField(`${field}[${index1}]`, "change");
1881
+ this.validateField(`${field}[${index2}]`, "change");
1882
+ }
1883
+ };
1884
+ this.moveFieldValues = (field, index1, index2, options) => {
1885
+ this.setFieldValue(field, prev => {
1886
+ const next = [...prev];
1887
+ next.splice(index2, 0, next.splice(index1, 1)[0]);
1888
+ return next;
1889
+ }, mergeOpts(options, {
1890
+ dontValidate: true
1891
+ }));
1892
+ metaHelper(this).handleArrayMove(field, index1, index2);
1893
+ const dontValidate = options?.dontValidate ?? false;
1894
+ if (!dontValidate) {
1895
+ this.validateField(field, "change");
1896
+ this.validateField(`${field}[${index1}]`, "change");
1897
+ this.validateField(`${field}[${index2}]`, "change");
1898
+ }
1899
+ };
1900
+ this.clearFieldValues = (field, options) => {
1901
+ const fieldValue = this.getFieldValue(field);
1902
+ const lastIndex = Array.isArray(fieldValue) ? Math.max(fieldValue.length - 1, 0) : null;
1903
+ this.setFieldValue(field, [], mergeOpts(options, {
1904
+ dontValidate: true
1905
+ }));
1906
+ if (lastIndex !== null) {
1907
+ for (let i = 0; i <= lastIndex; i++) {
1908
+ const fieldKey = `${field}[${i}]`;
1909
+ this.deleteField(fieldKey);
1910
+ }
1911
+ }
1912
+ const dontValidate = options?.dontValidate ?? false;
1913
+ if (!dontValidate) {
1914
+ this.validateField(field, "change");
1915
+ }
1916
+ };
1917
+ this.resetField = field => {
1918
+ this.baseStore.setState(prev => {
1919
+ return {
1920
+ ...prev,
1921
+ fieldMetaBase: {
1922
+ ...prev.fieldMetaBase,
1923
+ [field]: defaultFieldMeta
1924
+ },
1925
+ values: this.options.defaultValues ? setBy(prev.values, field, getBy(this.options.defaultValues, field)) : prev.values
1926
+ };
1927
+ });
1928
+ };
1929
+ this.setErrorMap = errorMap => {
1930
+ batch(() => {
1931
+ Object.entries(errorMap).forEach(([key, value]) => {
1932
+ const errorMapKey = key;
1933
+ if (isGlobalFormValidationError(value)) {
1934
+ const {
1935
+ formError,
1936
+ fieldErrors
1937
+ } = normalizeError$1(value);
1938
+ for (const fieldName of Object.keys(this.fieldInfo)) {
1939
+ const fieldMeta = this.getFieldMeta(fieldName);
1940
+ if (!fieldMeta) continue;
1941
+ this.setFieldMeta(fieldName, prev => ({
1942
+ ...prev,
1943
+ errorMap: {
1944
+ ...prev.errorMap,
1945
+ [errorMapKey]: fieldErrors?.[fieldName]
1946
+ },
1947
+ errorSourceMap: {
1948
+ ...prev.errorSourceMap,
1949
+ [errorMapKey]: "form"
1950
+ }
1951
+ }));
1952
+ }
1953
+ this.baseStore.setState(prev => ({
1954
+ ...prev,
1955
+ errorMap: {
1956
+ ...prev.errorMap,
1957
+ [errorMapKey]: formError
1958
+ }
1959
+ }));
1960
+ } else {
1961
+ this.baseStore.setState(prev => ({
1962
+ ...prev,
1963
+ errorMap: {
1964
+ ...prev.errorMap,
1965
+ [errorMapKey]: value
1966
+ }
1967
+ }));
1968
+ }
1969
+ });
1970
+ });
1971
+ };
1972
+ this.getAllErrors = () => {
1973
+ return {
1974
+ form: {
1975
+ errors: this.state.errors,
1976
+ errorMap: this.state.errorMap
1977
+ },
1978
+ fields: Object.entries(this.state.fieldMeta).reduce((acc, [fieldName, fieldMeta]) => {
1979
+ if (Object.keys(fieldMeta).length && fieldMeta.errors.length) {
1980
+ acc[fieldName] = {
1981
+ errors: fieldMeta.errors,
1982
+ errorMap: fieldMeta.errorMap
1983
+ };
1984
+ }
1985
+ return acc;
1986
+ }, {})
1987
+ };
1988
+ };
1989
+ this.parseValuesWithSchema = schema => {
1990
+ return standardSchemaValidators.validate({
1991
+ value: this.state.values,
1992
+ validationSource: "form"
1993
+ }, schema);
1994
+ };
1995
+ this.parseValuesWithSchemaAsync = schema => {
1996
+ return standardSchemaValidators.validateAsync({
1997
+ value: this.state.values,
1998
+ validationSource: "form"
1999
+ }, schema);
2000
+ };
2001
+ this.timeoutIds = {
2002
+ validations: {},
2003
+ listeners: {},
2004
+ formListeners: {}
2005
+ };
2006
+ this._formId = opts?.formId ?? uuid();
2007
+ this._devtoolsSubmissionOverride = false;
2008
+ this.baseStore = new Store(getDefaultFormState({
2009
+ ...opts?.defaultState,
2010
+ values: opts?.defaultValues ?? opts?.defaultState?.values
2011
+ }));
2012
+ this.fieldMetaDerived = new Derived({
2013
+ deps: [this.baseStore],
2014
+ fn: ({
2015
+ prevDepVals,
2016
+ currDepVals,
2017
+ prevVal: _prevVal
2018
+ }) => {
2019
+ const prevVal = _prevVal;
2020
+ const prevBaseStore = prevDepVals?.[0];
2021
+ const currBaseStore = currDepVals[0];
2022
+ let originalMetaCount = 0;
2023
+ const fieldMeta = {};
2024
+ for (const fieldName of Object.keys(currBaseStore.fieldMetaBase)) {
2025
+ const currBaseMeta = currBaseStore.fieldMetaBase[fieldName];
2026
+ const prevBaseMeta = prevBaseStore?.fieldMetaBase[fieldName];
2027
+ const prevFieldInfo = prevVal?.[fieldName];
2028
+ const curFieldVal = getBy(currBaseStore.values, fieldName);
2029
+ let fieldErrors = prevFieldInfo?.errors;
2030
+ if (!prevBaseMeta || currBaseMeta.errorMap !== prevBaseMeta.errorMap) {
2031
+ fieldErrors = Object.values(currBaseMeta.errorMap ?? {}).filter(val => val !== void 0);
2032
+ const fieldInstance = this.getFieldInfo(fieldName)?.instance;
2033
+ if (fieldInstance && !fieldInstance.options.disableErrorFlat) {
2034
+ fieldErrors = fieldErrors.flat(1);
2035
+ }
2036
+ }
2037
+ const isFieldValid = !isNonEmptyArray(fieldErrors);
2038
+ const isFieldPristine = !currBaseMeta.isDirty;
2039
+ const isDefaultValue = evaluate(curFieldVal, getBy(this.options.defaultValues, fieldName)) || evaluate(curFieldVal,
2040
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2041
+ this.getFieldInfo(fieldName)?.instance?.options.defaultValue);
2042
+ if (prevFieldInfo && prevFieldInfo.isPristine === isFieldPristine && prevFieldInfo.isValid === isFieldValid && prevFieldInfo.isDefaultValue === isDefaultValue && prevFieldInfo.errors === fieldErrors && currBaseMeta === prevBaseMeta) {
2043
+ fieldMeta[fieldName] = prevFieldInfo;
2044
+ originalMetaCount++;
2045
+ continue;
2046
+ }
2047
+ fieldMeta[fieldName] = {
2048
+ ...currBaseMeta,
2049
+ errors: fieldErrors ?? [],
2050
+ isPristine: isFieldPristine,
2051
+ isValid: isFieldValid,
2052
+ isDefaultValue
2053
+ };
2054
+ }
2055
+ if (!Object.keys(currBaseStore.fieldMetaBase).length) return fieldMeta;
2056
+ if (prevVal && originalMetaCount === Object.keys(currBaseStore.fieldMetaBase).length) {
2057
+ return prevVal;
2058
+ }
2059
+ return fieldMeta;
2060
+ }
2061
+ });
2062
+ this.store = new Derived({
2063
+ deps: [this.baseStore, this.fieldMetaDerived],
2064
+ fn: ({
2065
+ prevDepVals,
2066
+ currDepVals,
2067
+ prevVal: _prevVal
2068
+ }) => {
2069
+ const prevVal = _prevVal;
2070
+ const prevBaseStore = prevDepVals?.[0];
2071
+ const currBaseStore = currDepVals[0];
2072
+ const currFieldMeta = currDepVals[1];
2073
+ const fieldMetaValues = Object.values(currFieldMeta).filter(Boolean);
2074
+ const isFieldsValidating = fieldMetaValues.some(field => field.isValidating);
2075
+ const isFieldsValid = fieldMetaValues.every(field => field.isValid);
2076
+ const isTouched = fieldMetaValues.some(field => field.isTouched);
2077
+ const isBlurred = fieldMetaValues.some(field => field.isBlurred);
2078
+ const isDefaultValue = fieldMetaValues.every(field => field.isDefaultValue);
2079
+ const shouldInvalidateOnMount =
2080
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2081
+ isTouched && currBaseStore.errorMap?.onMount;
2082
+ const isDirty = fieldMetaValues.some(field => field.isDirty);
2083
+ const isPristine = !isDirty;
2084
+ const hasOnMountError = Boolean(
2085
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2086
+ currBaseStore.errorMap?.onMount ||
2087
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2088
+ fieldMetaValues.some(f => f?.errorMap?.onMount));
2089
+ const isValidating = !!isFieldsValidating;
2090
+ let errors = prevVal?.errors ?? [];
2091
+ if (!prevBaseStore || currBaseStore.errorMap !== prevBaseStore.errorMap) {
2092
+ errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => {
2093
+ if (curr === void 0) return prev;
2094
+ if (curr && isGlobalFormValidationError(curr)) {
2095
+ prev.push(curr.form);
2096
+ return prev;
2097
+ }
2098
+ prev.push(curr);
2099
+ return prev;
2100
+ }, []);
2101
+ }
2102
+ const isFormValid = errors.length === 0;
2103
+ const isValid = isFieldsValid && isFormValid;
2104
+ const submitInvalid = this.options.canSubmitWhenInvalid ?? false;
2105
+ const canSubmit = currBaseStore.submissionAttempts === 0 && !isTouched && !hasOnMountError || !isValidating && !currBaseStore.isSubmitting && isValid || submitInvalid;
2106
+ let errorMap = currBaseStore.errorMap;
2107
+ if (shouldInvalidateOnMount) {
2108
+ errors = errors.filter(err => err !== currBaseStore.errorMap.onMount);
2109
+ errorMap = Object.assign(errorMap, {
2110
+ onMount: void 0
2111
+ });
2112
+ }
2113
+ if (prevVal && prevBaseStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && evaluate(prevBaseStore, currBaseStore)) {
2114
+ return prevVal;
2115
+ }
2116
+ let state = {
2117
+ ...currBaseStore,
2118
+ errorMap,
2119
+ fieldMeta: this.fieldMetaDerived.state,
2120
+ errors,
2121
+ isFieldsValidating,
2122
+ isFieldsValid,
2123
+ isFormValid,
2124
+ isValid,
2125
+ canSubmit,
2126
+ isTouched,
2127
+ isBlurred,
2128
+ isPristine,
2129
+ isDefaultValue,
2130
+ isDirty
2131
+ };
2132
+ const transformArray = this.options.transform?.deps ?? [];
2133
+ const shouldTransform = transformArray.length !== this.prevTransformArray.length || transformArray.some((val, i) => val !== this.prevTransformArray[i]);
2134
+ if (shouldTransform) {
2135
+ const newObj = Object.assign({}, this, {
2136
+ state
2137
+ });
2138
+ this.options.transform?.fn(newObj);
2139
+ state = newObj.state;
2140
+ this.prevTransformArray = transformArray;
2141
+ }
2142
+ return state;
2143
+ }
2144
+ });
2145
+ this.handleSubmit = this.handleSubmit.bind(this);
2146
+ this.update(opts || {});
2147
+ }
2148
+ get state() {
2149
+ return this.store.state;
2150
+ }
2151
+ get formId() {
2152
+ return this._formId;
2153
+ }
2154
+ /**
2155
+ * @private
2156
+ */
2157
+ runValidator(props) {
2158
+ if (isStandardSchemaValidator(props.validate)) {
2159
+ return standardSchemaValidators[props.type](props.value, props.validate);
2160
+ }
2161
+ return props.validate(props.value);
2162
+ }
2163
+ handleSubmit(submitMeta) {
2164
+ return this._handleSubmit(submitMeta);
2165
+ }
2166
+ }
2167
+ function normalizeError$1(rawError) {
2168
+ if (rawError) {
2169
+ if (isGlobalFormValidationError(rawError)) {
2170
+ const formError = normalizeError$1(rawError.form).formError;
2171
+ const fieldErrors = rawError.fields;
2172
+ return {
2173
+ formError,
2174
+ fieldErrors
2175
+ };
2176
+ }
2177
+ return {
2178
+ formError: rawError
2179
+ };
2180
+ }
2181
+ return {
2182
+ formError: void 0
2183
+ };
2184
+ }
2185
+ function getErrorMapKey$1(cause) {
2186
+ switch (cause) {
2187
+ case "submit":
2188
+ return "onSubmit";
2189
+ case "blur":
2190
+ return "onBlur";
2191
+ case "mount":
2192
+ return "onMount";
2193
+ case "server":
2194
+ return "onServer";
2195
+ case "dynamic":
2196
+ return "onDynamic";
2197
+ case "change":
2198
+ default:
2199
+ return "onChange";
2200
+ }
2201
+ }class FieldApi {
2202
+ /**
2203
+ * Initializes a new `FieldApi` instance.
2204
+ */
2205
+ constructor(opts) {
2206
+ this.options = {};
2207
+ this.mount = () => {
2208
+ const cleanup = this.store.mount();
2209
+ if (this.options.defaultValue !== void 0 && !this.getMeta().isTouched) {
2210
+ this.form.setFieldValue(this.name, this.options.defaultValue, {
2211
+ dontUpdateMeta: true
2212
+ });
2213
+ }
2214
+ const info = this.getInfo();
2215
+ info.instance = this;
2216
+ this.update(this.options);
2217
+ const {
2218
+ onMount
2219
+ } = this.options.validators || {};
2220
+ if (onMount) {
2221
+ const error = this.runValidator({
2222
+ validate: onMount,
2223
+ value: {
2224
+ value: this.state.value,
2225
+ fieldApi: this,
2226
+ validationSource: "field"
2227
+ },
2228
+ type: "validate"
2229
+ });
2230
+ if (error) {
2231
+ this.setMeta(prev => ({
2232
+ ...prev,
2233
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2234
+ errorMap: {
2235
+ ...prev?.errorMap,
2236
+ onMount: error
2237
+ },
2238
+ errorSourceMap: {
2239
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2240
+ ...prev?.errorSourceMap,
2241
+ onMount: "field"
2242
+ }
2243
+ }));
2244
+ }
2245
+ }
2246
+ this.options.listeners?.onMount?.({
2247
+ value: this.state.value,
2248
+ fieldApi: this
2249
+ });
2250
+ return cleanup;
2251
+ };
2252
+ this.update = opts2 => {
2253
+ this.options = opts2;
2254
+ this.name = opts2.name;
2255
+ if (!this.state.meta.isTouched && this.options.defaultValue !== void 0) {
2256
+ const formField = this.form.getFieldValue(this.name);
2257
+ if (!evaluate(formField, opts2.defaultValue)) {
2258
+ this.form.setFieldValue(this.name, opts2.defaultValue, {
2259
+ dontUpdateMeta: true,
2260
+ dontValidate: true,
2261
+ dontRunListeners: true
2262
+ });
2263
+ }
2264
+ }
2265
+ if (!this.form.getFieldMeta(this.name)) {
2266
+ this.form.setFieldMeta(this.name, this.state.meta);
2267
+ }
2268
+ };
2269
+ this.getValue = () => {
2270
+ return this.form.getFieldValue(this.name);
2271
+ };
2272
+ this.setValue = (updater, options) => {
2273
+ this.form.setFieldValue(this.name, updater, mergeOpts(options, {
2274
+ dontRunListeners: true,
2275
+ dontValidate: true
2276
+ }));
2277
+ if (!options?.dontRunListeners) {
2278
+ this.triggerOnChangeListener();
2279
+ }
2280
+ if (!options?.dontValidate) {
2281
+ this.validate("change");
2282
+ }
2283
+ };
2284
+ this.getMeta = () => this.store.state.meta;
2285
+ this.setMeta = updater => this.form.setFieldMeta(this.name, updater);
2286
+ this.getInfo = () => this.form.getFieldInfo(this.name);
2287
+ this.pushValue = (value, options) => {
2288
+ this.form.pushFieldValue(this.name, value, mergeOpts(options, {
2289
+ dontRunListeners: true
2290
+ }));
2291
+ if (!options?.dontRunListeners) {
2292
+ this.triggerOnChangeListener();
2293
+ }
2294
+ };
2295
+ this.insertValue = (index, value, options) => {
2296
+ this.form.insertFieldValue(this.name, index, value, mergeOpts(options, {
2297
+ dontRunListeners: true
2298
+ }));
2299
+ if (!options?.dontRunListeners) {
2300
+ this.triggerOnChangeListener();
2301
+ }
2302
+ };
2303
+ this.replaceValue = (index, value, options) => {
2304
+ this.form.replaceFieldValue(this.name, index, value, mergeOpts(options, {
2305
+ dontRunListeners: true
2306
+ }));
2307
+ if (!options?.dontRunListeners) {
2308
+ this.triggerOnChangeListener();
2309
+ }
2310
+ };
2311
+ this.removeValue = (index, options) => {
2312
+ this.form.removeFieldValue(this.name, index, mergeOpts(options, {
2313
+ dontRunListeners: true
2314
+ }));
2315
+ if (!options?.dontRunListeners) {
2316
+ this.triggerOnChangeListener();
2317
+ }
2318
+ };
2319
+ this.swapValues = (aIndex, bIndex, options) => {
2320
+ this.form.swapFieldValues(this.name, aIndex, bIndex, mergeOpts(options, {
2321
+ dontRunListeners: true
2322
+ }));
2323
+ if (!options?.dontRunListeners) {
2324
+ this.triggerOnChangeListener();
2325
+ }
2326
+ };
2327
+ this.moveValue = (aIndex, bIndex, options) => {
2328
+ this.form.moveFieldValues(this.name, aIndex, bIndex, mergeOpts(options, {
2329
+ dontRunListeners: true
2330
+ }));
2331
+ if (!options?.dontRunListeners) {
2332
+ this.triggerOnChangeListener();
2333
+ }
2334
+ };
2335
+ this.clearValues = options => {
2336
+ this.form.clearFieldValues(this.name, mergeOpts(options, {
2337
+ dontRunListeners: true
2338
+ }));
2339
+ if (!options?.dontRunListeners) {
2340
+ this.triggerOnChangeListener();
2341
+ }
2342
+ };
2343
+ this.getLinkedFields = cause => {
2344
+ const fields = Object.values(this.form.fieldInfo);
2345
+ const linkedFields = [];
2346
+ for (const field of fields) {
2347
+ if (!field.instance) continue;
2348
+ const {
2349
+ onChangeListenTo,
2350
+ onBlurListenTo
2351
+ } = field.instance.options.validators || {};
2352
+ if (cause === "change" && onChangeListenTo?.includes(this.name)) {
2353
+ linkedFields.push(field.instance);
2354
+ }
2355
+ if (cause === "blur" && onBlurListenTo?.includes(this.name)) {
2356
+ linkedFields.push(field.instance);
2357
+ }
2358
+ }
2359
+ return linkedFields;
2360
+ };
2361
+ this.validateSync = (cause, errorFromForm) => {
2362
+ const validates = getSyncValidatorArray(cause, {
2363
+ ...this.options,
2364
+ form: this.form,
2365
+ validationLogic: this.form.options.validationLogic || defaultValidationLogic
2366
+ });
2367
+ const linkedFields = this.getLinkedFields(cause);
2368
+ const linkedFieldValidates = linkedFields.reduce((acc, field) => {
2369
+ const fieldValidates = getSyncValidatorArray(cause, {
2370
+ ...field.options,
2371
+ form: field.form,
2372
+ validationLogic: field.form.options.validationLogic || defaultValidationLogic
2373
+ });
2374
+ fieldValidates.forEach(validate => {
2375
+ validate.field = field;
2376
+ });
2377
+ return acc.concat(fieldValidates);
2378
+ }, []);
2379
+ let hasErrored = false;
2380
+ batch(() => {
2381
+ const validateFieldFn = (field, validateObj) => {
2382
+ const errorMapKey = getErrorMapKey(validateObj.cause);
2383
+ const fieldLevelError = validateObj.validate ? normalizeError(field.runValidator({
2384
+ validate: validateObj.validate,
2385
+ value: {
2386
+ value: field.store.state.value,
2387
+ validationSource: "field",
2388
+ fieldApi: field
2389
+ },
2390
+ type: "validate"
2391
+ })) : void 0;
2392
+ const formLevelError = errorFromForm[errorMapKey];
2393
+ const {
2394
+ newErrorValue,
2395
+ newSource
2396
+ } = determineFieldLevelErrorSourceAndValue({
2397
+ formLevelError,
2398
+ fieldLevelError
2399
+ });
2400
+ if (field.state.meta.errorMap?.[errorMapKey] !== newErrorValue) {
2401
+ field.setMeta(prev => ({
2402
+ ...prev,
2403
+ errorMap: {
2404
+ ...prev.errorMap,
2405
+ [errorMapKey]: newErrorValue
2406
+ },
2407
+ errorSourceMap: {
2408
+ ...prev.errorSourceMap,
2409
+ [errorMapKey]: newSource
2410
+ }
2411
+ }));
2412
+ }
2413
+ if (newErrorValue) {
2414
+ hasErrored = true;
2415
+ }
2416
+ };
2417
+ for (const validateObj of validates) {
2418
+ validateFieldFn(this, validateObj);
2419
+ }
2420
+ for (const fieldValitateObj of linkedFieldValidates) {
2421
+ if (!fieldValitateObj.validate) continue;
2422
+ validateFieldFn(fieldValitateObj.field, fieldValitateObj);
2423
+ }
2424
+ });
2425
+ const submitErrKey = getErrorMapKey("submit");
2426
+ if (
2427
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2428
+ this.state.meta.errorMap?.[submitErrKey] && cause !== "submit" && !hasErrored) {
2429
+ this.setMeta(prev => ({
2430
+ ...prev,
2431
+ errorMap: {
2432
+ ...prev.errorMap,
2433
+ [submitErrKey]: void 0
2434
+ },
2435
+ errorSourceMap: {
2436
+ ...prev.errorSourceMap,
2437
+ [submitErrKey]: void 0
2438
+ }
2439
+ }));
2440
+ }
2441
+ return {
2442
+ hasErrored
2443
+ };
2444
+ };
2445
+ this.validateAsync = async (cause, formValidationResultPromise) => {
2446
+ const validates = getAsyncValidatorArray(cause, {
2447
+ ...this.options,
2448
+ form: this.form,
2449
+ validationLogic: this.form.options.validationLogic || defaultValidationLogic
2450
+ });
2451
+ const asyncFormValidationResults = await formValidationResultPromise;
2452
+ const linkedFields = this.getLinkedFields(cause);
2453
+ const linkedFieldValidates = linkedFields.reduce((acc, field) => {
2454
+ const fieldValidates = getAsyncValidatorArray(cause, {
2455
+ ...field.options,
2456
+ form: field.form,
2457
+ validationLogic: field.form.options.validationLogic || defaultValidationLogic
2458
+ });
2459
+ fieldValidates.forEach(validate => {
2460
+ validate.field = field;
2461
+ });
2462
+ return acc.concat(fieldValidates);
2463
+ }, []);
2464
+ const validatesPromises = [];
2465
+ const linkedPromises = [];
2466
+ const hasAsyncValidators = validates.some(v => v.validate) || linkedFieldValidates.some(v => v.validate);
2467
+ if (hasAsyncValidators) {
2468
+ if (!this.state.meta.isValidating) {
2469
+ this.setMeta(prev => ({
2470
+ ...prev,
2471
+ isValidating: true
2472
+ }));
2473
+ }
2474
+ for (const linkedField of linkedFields) {
2475
+ linkedField.setMeta(prev => ({
2476
+ ...prev,
2477
+ isValidating: true
2478
+ }));
2479
+ }
2480
+ }
2481
+ const validateFieldAsyncFn = (field, validateObj, promises) => {
2482
+ const errorMapKey = getErrorMapKey(validateObj.cause);
2483
+ const fieldValidatorMeta = field.getInfo().validationMetaMap[errorMapKey];
2484
+ fieldValidatorMeta?.lastAbortController.abort();
2485
+ const controller = new AbortController();
2486
+ this.getInfo().validationMetaMap[errorMapKey] = {
2487
+ lastAbortController: controller
2488
+ };
2489
+ promises.push(new Promise(async resolve => {
2490
+ let rawError;
2491
+ try {
2492
+ rawError = await new Promise((rawResolve, rawReject) => {
2493
+ if (this.timeoutIds.validations[validateObj.cause]) {
2494
+ clearTimeout(this.timeoutIds.validations[validateObj.cause]);
2495
+ }
2496
+ this.timeoutIds.validations[validateObj.cause] = setTimeout(async () => {
2497
+ if (controller.signal.aborted) return rawResolve(void 0);
2498
+ try {
2499
+ rawResolve(await this.runValidator({
2500
+ validate: validateObj.validate,
2501
+ value: {
2502
+ value: field.store.state.value,
2503
+ fieldApi: field,
2504
+ signal: controller.signal,
2505
+ validationSource: "field"
2506
+ },
2507
+ type: "validateAsync"
2508
+ }));
2509
+ } catch (e) {
2510
+ rawReject(e);
2511
+ }
2512
+ }, validateObj.debounceMs);
2513
+ });
2514
+ } catch (e) {
2515
+ rawError = e;
2516
+ }
2517
+ if (controller.signal.aborted) return resolve(void 0);
2518
+ const fieldLevelError = normalizeError(rawError);
2519
+ const formLevelError = asyncFormValidationResults[this.name]?.[errorMapKey];
2520
+ const {
2521
+ newErrorValue,
2522
+ newSource
2523
+ } = determineFieldLevelErrorSourceAndValue({
2524
+ formLevelError,
2525
+ fieldLevelError
2526
+ });
2527
+ field.setMeta(prev => {
2528
+ return {
2529
+ ...prev,
2530
+ errorMap: {
2531
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2532
+ ...prev?.errorMap,
2533
+ [errorMapKey]: newErrorValue
2534
+ },
2535
+ errorSourceMap: {
2536
+ ...prev.errorSourceMap,
2537
+ [errorMapKey]: newSource
2538
+ }
2539
+ };
2540
+ });
2541
+ resolve(newErrorValue);
2542
+ }));
2543
+ };
2544
+ for (const validateObj of validates) {
2545
+ if (!validateObj.validate) continue;
2546
+ validateFieldAsyncFn(this, validateObj, validatesPromises);
2547
+ }
2548
+ for (const fieldValitateObj of linkedFieldValidates) {
2549
+ if (!fieldValitateObj.validate) continue;
2550
+ validateFieldAsyncFn(fieldValitateObj.field, fieldValitateObj, linkedPromises);
2551
+ }
2552
+ let results = [];
2553
+ if (validatesPromises.length || linkedPromises.length) {
2554
+ results = await Promise.all(validatesPromises);
2555
+ await Promise.all(linkedPromises);
2556
+ }
2557
+ if (hasAsyncValidators) {
2558
+ this.setMeta(prev => ({
2559
+ ...prev,
2560
+ isValidating: false
2561
+ }));
2562
+ for (const linkedField of linkedFields) {
2563
+ linkedField.setMeta(prev => ({
2564
+ ...prev,
2565
+ isValidating: false
2566
+ }));
2567
+ }
2568
+ }
2569
+ return results.filter(Boolean);
2570
+ };
2571
+ this.validate = (cause, opts2) => {
2572
+ if (!this.state.meta.isTouched) return [];
2573
+ const {
2574
+ fieldsErrorMap
2575
+ } = opts2?.skipFormValidation ? {
2576
+ fieldsErrorMap: {}
2577
+ } : this.form.validateSync(cause);
2578
+ const {
2579
+ hasErrored
2580
+ } = this.validateSync(cause, fieldsErrorMap[this.name] ?? {});
2581
+ if (hasErrored && !this.options.asyncAlways) {
2582
+ this.getInfo().validationMetaMap[getErrorMapKey(cause)]?.lastAbortController.abort();
2583
+ return this.state.meta.errors;
2584
+ }
2585
+ const formValidationResultPromise = opts2?.skipFormValidation ? Promise.resolve({}) : this.form.validateAsync(cause);
2586
+ return this.validateAsync(cause, formValidationResultPromise);
2587
+ };
2588
+ this.handleChange = updater => {
2589
+ this.setValue(updater);
2590
+ };
2591
+ this.handleBlur = () => {
2592
+ const prevTouched = this.state.meta.isTouched;
2593
+ if (!prevTouched) {
2594
+ this.setMeta(prev => ({
2595
+ ...prev,
2596
+ isTouched: true
2597
+ }));
2598
+ }
2599
+ if (!this.state.meta.isBlurred) {
2600
+ this.setMeta(prev => ({
2601
+ ...prev,
2602
+ isBlurred: true
2603
+ }));
2604
+ }
2605
+ this.validate("blur");
2606
+ this.triggerOnBlurListener();
2607
+ };
2608
+ this.setErrorMap = errorMap => {
2609
+ this.setMeta(prev => ({
2610
+ ...prev,
2611
+ errorMap: {
2612
+ ...prev.errorMap,
2613
+ ...errorMap
2614
+ }
2615
+ }));
2616
+ };
2617
+ this.parseValueWithSchema = schema => {
2618
+ return standardSchemaValidators.validate({
2619
+ value: this.state.value,
2620
+ validationSource: "field"
2621
+ }, schema);
2622
+ };
2623
+ this.parseValueWithSchemaAsync = schema => {
2624
+ return standardSchemaValidators.validateAsync({
2625
+ value: this.state.value,
2626
+ validationSource: "field"
2627
+ }, schema);
2628
+ };
2629
+ this.triggerOnChangeListener = () => {
2630
+ const formDebounceMs = this.form.options.listeners?.onChangeDebounceMs;
2631
+ if (formDebounceMs && formDebounceMs > 0) {
2632
+ if (this.timeoutIds.formListeners.change) {
2633
+ clearTimeout(this.timeoutIds.formListeners.change);
2634
+ }
2635
+ this.timeoutIds.formListeners.change = setTimeout(() => {
2636
+ this.form.options.listeners?.onChange?.({
2637
+ formApi: this.form,
2638
+ fieldApi: this
2639
+ });
2640
+ }, formDebounceMs);
2641
+ } else {
2642
+ this.form.options.listeners?.onChange?.({
2643
+ formApi: this.form,
2644
+ fieldApi: this
2645
+ });
2646
+ }
2647
+ const fieldDebounceMs = this.options.listeners?.onChangeDebounceMs;
2648
+ if (fieldDebounceMs && fieldDebounceMs > 0) {
2649
+ if (this.timeoutIds.listeners.change) {
2650
+ clearTimeout(this.timeoutIds.listeners.change);
2651
+ }
2652
+ this.timeoutIds.listeners.change = setTimeout(() => {
2653
+ this.options.listeners?.onChange?.({
2654
+ value: this.state.value,
2655
+ fieldApi: this
2656
+ });
2657
+ }, fieldDebounceMs);
2658
+ } else {
2659
+ this.options.listeners?.onChange?.({
2660
+ value: this.state.value,
2661
+ fieldApi: this
2662
+ });
2663
+ }
2664
+ };
2665
+ this.form = opts.form;
2666
+ this.name = opts.name;
2667
+ this.options = opts;
2668
+ this.timeoutIds = {
2669
+ validations: {},
2670
+ listeners: {},
2671
+ formListeners: {}
2672
+ };
2673
+ this.store = new Derived({
2674
+ deps: [this.form.store],
2675
+ fn: ({
2676
+ prevVal: _prevVal
2677
+ }) => {
2678
+ const prevVal = _prevVal;
2679
+ const meta = this.form.getFieldMeta(this.name) ?? {
2680
+ ...defaultFieldMeta,
2681
+ ...opts.defaultMeta
2682
+ };
2683
+ let value = this.form.getFieldValue(this.name);
2684
+ if (!meta.isTouched && value === void 0 && this.options.defaultValue !== void 0 && !evaluate(value, this.options.defaultValue)) {
2685
+ value = this.options.defaultValue;
2686
+ }
2687
+ if (prevVal && prevVal.value === value && prevVal.meta === meta) {
2688
+ return prevVal;
2689
+ }
2690
+ return {
2691
+ value,
2692
+ meta
2693
+ };
2694
+ }
2695
+ });
2696
+ }
2697
+ /**
2698
+ * The current field state.
2699
+ */
2700
+ get state() {
2701
+ return this.store.state;
2702
+ }
2703
+ /**
2704
+ * @private
2705
+ */
2706
+ runValidator(props) {
2707
+ if (isStandardSchemaValidator(props.validate)) {
2708
+ return standardSchemaValidators[props.type](props.value, props.validate);
2709
+ }
2710
+ return props.validate(props.value);
2711
+ }
2712
+ triggerOnBlurListener() {
2713
+ const formDebounceMs = this.form.options.listeners?.onBlurDebounceMs;
2714
+ if (formDebounceMs && formDebounceMs > 0) {
2715
+ if (this.timeoutIds.formListeners.blur) {
2716
+ clearTimeout(this.timeoutIds.formListeners.blur);
2717
+ }
2718
+ this.timeoutIds.formListeners.blur = setTimeout(() => {
2719
+ this.form.options.listeners?.onBlur?.({
2720
+ formApi: this.form,
2721
+ fieldApi: this
2722
+ });
2723
+ }, formDebounceMs);
2724
+ } else {
2725
+ this.form.options.listeners?.onBlur?.({
2726
+ formApi: this.form,
2727
+ fieldApi: this
2728
+ });
2729
+ }
2730
+ const fieldDebounceMs = this.options.listeners?.onBlurDebounceMs;
2731
+ if (fieldDebounceMs && fieldDebounceMs > 0) {
2732
+ if (this.timeoutIds.listeners.blur) {
2733
+ clearTimeout(this.timeoutIds.listeners.blur);
2734
+ }
2735
+ this.timeoutIds.listeners.blur = setTimeout(() => {
2736
+ this.options.listeners?.onBlur?.({
2737
+ value: this.state.value,
2738
+ fieldApi: this
2739
+ });
2740
+ }, fieldDebounceMs);
2741
+ } else {
2742
+ this.options.listeners?.onBlur?.({
2743
+ value: this.state.value,
2744
+ fieldApi: this
2745
+ });
2746
+ }
2747
+ }
2748
+ }
2749
+ function normalizeError(rawError) {
2750
+ if (rawError) {
2751
+ return rawError;
2752
+ }
2753
+ return void 0;
2754
+ }
2755
+ function getErrorMapKey(cause) {
2756
+ switch (cause) {
2757
+ case "submit":
2758
+ return "onSubmit";
2759
+ case "blur":
2760
+ return "onBlur";
2761
+ case "mount":
2762
+ return "onMount";
2763
+ case "server":
2764
+ return "onServer";
2765
+ case "dynamic":
2766
+ return "onDynamic";
2767
+ case "change":
2768
+ default:
2769
+ return "onChange";
2770
+ }
2771
+ }function useStore$1(store, selector = (d) => d, options = {}) {
2772
+ const equal = options.equal ?? shallow;
2773
+ const slice = withSelector_js.useSyncExternalStoreWithSelector(
2774
+ store.subscribe,
2775
+ () => store.state,
2776
+ () => store.state,
2777
+ selector,
2778
+ equal
2779
+ );
2780
+ return slice;
2781
+ }
2782
+ function shallow(objA, objB) {
2783
+ if (Object.is(objA, objB)) {
2784
+ return true;
2785
+ }
2786
+ if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
2787
+ return false;
2788
+ }
2789
+ if (objA instanceof Map && objB instanceof Map) {
2790
+ if (objA.size !== objB.size) return false;
2791
+ for (const [k, v] of objA) {
2792
+ if (!objB.has(k) || !Object.is(v, objB.get(k))) return false;
2793
+ }
2794
+ return true;
2795
+ }
2796
+ if (objA instanceof Set && objB instanceof Set) {
2797
+ if (objA.size !== objB.size) return false;
2798
+ for (const v of objA) {
2799
+ if (!objB.has(v)) return false;
2800
+ }
2801
+ return true;
2802
+ }
2803
+ if (objA instanceof Date && objB instanceof Date) {
2804
+ if (objA.getTime() !== objB.getTime()) return false;
2805
+ return true;
2806
+ }
2807
+ const keysA = getOwnKeys(objA);
2808
+ if (keysA.length !== getOwnKeys(objB).length) {
2809
+ return false;
2810
+ }
2811
+ for (let i = 0; i < keysA.length; i++) {
2812
+ if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
2813
+ return false;
2814
+ }
2815
+ }
2816
+ return true;
2817
+ }
2818
+ function getOwnKeys(obj) {
2819
+ return Object.keys(obj).concat(
2820
+ Object.getOwnPropertySymbols(obj)
2821
+ );
2822
+ }const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;function useField(opts) {
2823
+ const [prevOptions, setPrevOptions] = React.useState(() => ({
2824
+ form: opts.form,
2825
+ name: opts.name
2826
+ }));
2827
+ const [fieldApi, setFieldApi] = React.useState(() => {
2828
+ return new FieldApi({
2829
+ ...opts
2830
+ });
2831
+ });
2832
+ if (prevOptions.form !== opts.form || prevOptions.name !== opts.name) {
2833
+ setFieldApi(
2834
+ new FieldApi({
2835
+ ...opts
2836
+ })
2837
+ );
2838
+ setPrevOptions({ form: opts.form, name: opts.name });
2839
+ }
2840
+ const reactiveStateValue = useStore$1(
2841
+ fieldApi.store,
2842
+ opts.mode === "array" ? (state) => Object.keys(state.value ?? []).length : (state) => state.value
2843
+ );
2844
+ const reactiveMetaIsTouched = useStore$1(
2845
+ fieldApi.store,
2846
+ (state) => state.meta.isTouched
2847
+ );
2848
+ const reactiveMetaIsBlurred = useStore$1(
2849
+ fieldApi.store,
2850
+ (state) => state.meta.isBlurred
2851
+ );
2852
+ const reactiveMetaIsDirty = useStore$1(
2853
+ fieldApi.store,
2854
+ (state) => state.meta.isDirty
2855
+ );
2856
+ const reactiveMetaErrorMap = useStore$1(
2857
+ fieldApi.store,
2858
+ (state) => state.meta.errorMap
2859
+ );
2860
+ const reactiveMetaErrorSourceMap = useStore$1(
2861
+ fieldApi.store,
2862
+ (state) => state.meta.errorSourceMap
2863
+ );
2864
+ const reactiveMetaIsValidating = useStore$1(
2865
+ fieldApi.store,
2866
+ (state) => state.meta.isValidating
2867
+ );
2868
+ const extendedFieldApi = React.useMemo(() => {
2869
+ const reactiveFieldApi = {
2870
+ ...fieldApi,
2871
+ get state() {
2872
+ return {
2873
+ // For array mode, reactiveStateValue is the length (for reactivity tracking),
2874
+ // so we need to get the actual value from fieldApi
2875
+ value: opts.mode === "array" ? fieldApi.state.value : reactiveStateValue,
2876
+ get meta() {
2877
+ return {
2878
+ ...fieldApi.state.meta,
2879
+ isTouched: reactiveMetaIsTouched,
2880
+ isBlurred: reactiveMetaIsBlurred,
2881
+ isDirty: reactiveMetaIsDirty,
2882
+ errorMap: reactiveMetaErrorMap,
2883
+ errorSourceMap: reactiveMetaErrorSourceMap,
2884
+ isValidating: reactiveMetaIsValidating
2885
+ };
2886
+ }
2887
+ };
2888
+ }
2889
+ };
2890
+ const extendedApi = reactiveFieldApi;
2891
+ extendedApi.Field = Field;
2892
+ return extendedApi;
2893
+ }, [
2894
+ fieldApi,
2895
+ opts.mode,
2896
+ reactiveStateValue,
2897
+ reactiveMetaIsTouched,
2898
+ reactiveMetaIsBlurred,
2899
+ reactiveMetaIsDirty,
2900
+ reactiveMetaErrorMap,
2901
+ reactiveMetaErrorSourceMap,
2902
+ reactiveMetaIsValidating
2903
+ ]);
2904
+ useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi]);
2905
+ useIsomorphicLayoutEffect(() => {
2906
+ fieldApi.update(opts);
2907
+ });
2908
+ return extendedFieldApi;
2909
+ }
2910
+ const Field = (({
2911
+ children,
2912
+ ...fieldOptions
2913
+ }) => {
2914
+ const fieldApi = useField(fieldOptions);
2915
+ const jsxToDisplay = React.useMemo(
2916
+ () => functionalUpdate(children, fieldApi),
2917
+ [children, fieldApi]
2918
+ );
2919
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxToDisplay });
2920
+ });function useUUID() {
2921
+ return React.useState(() => uuid())[0];
2922
+ }const useFormId = React__namespace.version.split(".")[0] === "17" ? useUUID : React__namespace.useId;function LocalSubscribe({
2923
+ form,
2924
+ selector,
2925
+ children
2926
+ }) {
2927
+ const data = useStore$1(form.store, selector);
2928
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: functionalUpdate(children, data) });
2929
+ }
2930
+ function useForm(opts) {
2931
+ const fallbackFormId = useFormId();
2932
+ const [prevFormId, setPrevFormId] = React.useState(opts?.formId);
2933
+ const [formApi, setFormApi] = React.useState(() => {
2934
+ return new FormApi({ ...opts, formId: opts?.formId ?? fallbackFormId });
2935
+ });
2936
+ if (prevFormId !== opts?.formId) {
2937
+ const formId = opts?.formId ?? fallbackFormId;
2938
+ setFormApi(new FormApi({ ...opts, formId }));
2939
+ setPrevFormId(formId);
2940
+ }
2941
+ const extendedFormApi = React.useMemo(() => {
2942
+ const extendedApi = {
2943
+ ...formApi,
2944
+ handleSubmit: ((...props) => {
2945
+ return formApi._handleSubmit(...props);
2946
+ }),
2947
+ // We must add all `get`ters from `core`'s `FormApi` here, as otherwise the spread operator won't catch those
2948
+ get formId() {
2949
+ return formApi._formId;
2950
+ },
2951
+ get state() {
2952
+ return formApi.store.state;
2953
+ }
2954
+ };
2955
+ extendedApi.Field = function APIField(props) {
2956
+ return /* @__PURE__ */ jsxRuntime.jsx(Field, { ...props, form: formApi });
2957
+ };
2958
+ extendedApi.Subscribe = function Subscribe(props) {
2959
+ return /* @__PURE__ */ jsxRuntime.jsx(
2960
+ LocalSubscribe,
2961
+ {
2962
+ form: formApi,
2963
+ selector: props.selector,
2964
+ children: props.children
2965
+ }
2966
+ );
2967
+ };
2968
+ return extendedApi;
2969
+ }, [formApi]);
2970
+ useIsomorphicLayoutEffect(formApi.mount, []);
2971
+ useIsomorphicLayoutEffect(() => {
2972
+ formApi.update(opts);
2973
+ });
2974
+ return extendedFormApi;
2975
+ }/* eslint-disable @typescript-eslint/no-explicit-any */
2976
+ function useJotaiForm(formOptions) {
2977
+ const form = useForm(formOptions);
2978
+ return form;
2979
+ }const FormField = ({
2980
+ config,
2981
+ onFieldChange,
2982
+ ns: globalNs,
2983
+ globalErrorNs
2984
+ }) => {
2985
+ var _a, _b;
2986
+ const ns = (_a = config.ns) !== null && _a !== void 0 ? _a : globalNs;
2987
+ const errorNs = (_b = config.errorNs) !== null && _b !== void 0 ? _b : globalErrorNs;
2988
+ const {
2989
+ formFieldContainer,
2990
+ translateText
2991
+ } = useFormConfigValue();
2992
+ // TanStack Form uses field.state.meta.errors which is an array of ValidationError
2993
+ const firstError = config.field.state.meta.errors.length > 0 ? config.field.state.meta.errors[0] : undefined;
2994
+ const errorMessageStr = firstError ? String(firstError) : undefined;
2995
+ const errorMessage = React.useMemo(() => {
2996
+ if (!errorMessageStr) return undefined;
2997
+ return errorNs ? translateText === null || translateText === void 0 ? void 0 : translateText(errorMessageStr, {
2998
+ ns: errorNs || '',
2999
+ defaultValue: ''
3000
+ }) : errorMessageStr;
3001
+ }, [errorMessageStr, errorNs, translateText]);
3002
+ const label = React.useMemo(() => {
3003
+ var _a_0;
3004
+ return ns ? translateText === null || translateText === void 0 ? void 0 : translateText((_a_0 = config.label) !== null && _a_0 !== void 0 ? _a_0 : '') : config.label;
3005
+ }, [ns, config.label, translateText]);
3006
+ const helperMessage = React.useMemo(() => {
3007
+ var _a_1;
3008
+ 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) : '';
3009
+ }, [config.helper, translateText]);
3010
+ const ref = React.useRef({
3011
+ onFieldChange,
3012
+ handleChange: config.field.handleChange
3013
+ });
3014
+ React.useEffect(() => {
3015
+ ref.current = {
3016
+ onFieldChange,
3017
+ handleChange: config.field.handleChange
3018
+ };
3019
+ }, [config.field.handleChange, onFieldChange]);
3020
+ const handleChange = React.useCallback(value => {
3021
+ var _a_2, _b_0;
3022
+ // TanStack Form handleChange usually expects just the value for input
3023
+ // but if we are manually calling it we should pass the value.
3024
+ ref.current.handleChange(value);
3025
+ (_b_0 = (_a_2 = ref.current).onFieldChange) === null || _b_0 === void 0 ? void 0 : _b_0.call(_a_2, value);
3026
+ }, []);
3027
+ const handleBlur = React.useCallback(() => {
3028
+ config.field.handleBlur();
3029
+ }, [config.field]);
3030
+ const baseProps = React.useMemo(() => ({
3031
+ value: config.field.state.value,
3032
+ onChange: handleChange,
3033
+ onBlur: handleBlur,
3034
+ error: config.field.state.meta.errors.length > 0,
3035
+ errorMessage,
3036
+ label,
3037
+ helperMessage
3038
+ }), [config.field.state.value, handleChange, handleBlur, config.field.state.meta.errors.length, errorMessage, label, helperMessage]);
3039
+ const ConfigContainer = React.useMemo(() => config.container, [config.container]);
3040
+ const FormFieldContainer = React.useMemo(() => formFieldContainer, [formFieldContainer]);
3041
+ if (ConfigContainer) {
3042
+ return jsxRuntime.jsx(ConfigContainer, {
3043
+ children: config.component(baseProps)
3044
+ });
3045
+ }
3046
+ return jsxRuntime.jsx(FormFieldContainer, {
3047
+ children: config.component(baseProps)
3048
+ });
3049
+ };function hasInitialValue(atom) {
3050
+ return "init" in atom;
3051
+ }
3052
+ function isActuallyWritableAtom(atom) {
3053
+ return !!atom.write;
3054
+ }
3055
+ function isAtomStateInitialized(atomState) {
3056
+ return "v" in atomState || "e" in atomState;
3057
+ }
3058
+ function returnAtomValue(atomState) {
3059
+ if ("e" in atomState) {
3060
+ throw atomState.e;
3061
+ }
3062
+ if ((undefined ? undefined.MODE : void 0) !== "production" && !("v" in atomState)) {
3063
+ throw new Error("[Bug] atom state is not initialized");
3064
+ }
3065
+ return atomState.v;
3066
+ }
3067
+ const promiseStateMap = /* @__PURE__ */ new WeakMap();
3068
+ function isPendingPromise(value) {
3069
+ var _a;
3070
+ return isPromiseLike$1(value) && !!((_a = promiseStateMap.get(value)) == null ? void 0 : _a[0]);
3071
+ }
3072
+ function abortPromise(promise) {
3073
+ const promiseState = promiseStateMap.get(promise);
3074
+ if (promiseState == null ? void 0 : promiseState[0]) {
3075
+ promiseState[0] = false;
3076
+ promiseState[1].forEach((fn) => fn());
3077
+ }
3078
+ }
3079
+ function registerAbortHandler(promise, abortHandler) {
3080
+ let promiseState = promiseStateMap.get(promise);
3081
+ if (!promiseState) {
3082
+ promiseState = [true, /* @__PURE__ */ new Set()];
3083
+ promiseStateMap.set(promise, promiseState);
3084
+ const settle = () => {
3085
+ promiseState[0] = false;
3086
+ };
3087
+ promise.then(settle, settle);
3088
+ }
3089
+ promiseState[1].add(abortHandler);
3090
+ }
3091
+ function isPromiseLike$1(p) {
3092
+ return typeof (p == null ? void 0 : p.then) === "function";
3093
+ }
3094
+ function addPendingPromiseToDependency(atom, promise, dependencyAtomState) {
3095
+ if (!dependencyAtomState.p.has(atom)) {
3096
+ dependencyAtomState.p.add(atom);
3097
+ const cleanup = () => dependencyAtomState.p.delete(atom);
3098
+ promise.then(cleanup, cleanup);
3099
+ }
3100
+ }
3101
+ function getMountedOrPendingDependents(atom, atomState, mountedMap) {
3102
+ var _a;
3103
+ const dependents = /* @__PURE__ */ new Set();
3104
+ for (const a of ((_a = mountedMap.get(atom)) == null ? void 0 : _a.t) || []) {
3105
+ dependents.add(a);
3106
+ }
3107
+ for (const atomWithPendingPromise of atomState.p) {
3108
+ dependents.add(atomWithPendingPromise);
3109
+ }
3110
+ return dependents;
3111
+ }
3112
+ const atomRead = (_store, atom, ...params) => atom.read(...params);
3113
+ const atomWrite = (_store, atom, ...params) => atom.write(...params);
3114
+ const atomOnInit = (store, atom) => {
3115
+ if (atom.INTERNAL_onInit) {
3116
+ return atom.INTERNAL_onInit(store);
3117
+ }
3118
+ if (atom.unstable_onInit) {
3119
+ console.warn(
3120
+ "[DEPRECATED] atom.unstable_onInit is renamed to atom.INTERNAL_onInit."
3121
+ );
3122
+ return atom.unstable_onInit(store);
3123
+ }
3124
+ };
3125
+ const atomOnMount = (_store, atom, setAtom) => {
3126
+ var _a;
3127
+ return (_a = atom.onMount) == null ? void 0 : _a.call(atom, setAtom);
3128
+ };
3129
+ const ensureAtomState = (store, atom) => {
3130
+ var _a;
3131
+ const buildingBlocks = getInternalBuildingBlocks(store);
3132
+ const atomStateMap = buildingBlocks[0];
3133
+ const storeHooks = buildingBlocks[6];
3134
+ const atomOnInit2 = buildingBlocks[9];
3135
+ if ((undefined ? undefined.MODE : void 0) !== "production" && !atom) {
3136
+ throw new Error("Atom is undefined or null");
3137
+ }
3138
+ let atomState = atomStateMap.get(atom);
3139
+ if (!atomState) {
3140
+ atomState = { d: /* @__PURE__ */ new Map(), p: /* @__PURE__ */ new Set(), n: 0 };
3141
+ atomStateMap.set(atom, atomState);
3142
+ (_a = storeHooks.i) == null ? void 0 : _a.call(storeHooks, atom);
3143
+ atomOnInit2 == null ? void 0 : atomOnInit2(store, atom);
3144
+ }
3145
+ return atomState;
3146
+ };
3147
+ const flushCallbacks = (store) => {
3148
+ const buildingBlocks = getInternalBuildingBlocks(store);
3149
+ const mountedMap = buildingBlocks[1];
3150
+ const changedAtoms = buildingBlocks[3];
3151
+ const mountCallbacks = buildingBlocks[4];
3152
+ const unmountCallbacks = buildingBlocks[5];
3153
+ const storeHooks = buildingBlocks[6];
3154
+ const recomputeInvalidatedAtoms2 = buildingBlocks[13];
3155
+ const errors = [];
3156
+ const call = (fn) => {
3157
+ try {
3158
+ fn();
3159
+ } catch (e) {
3160
+ errors.push(e);
3161
+ }
3162
+ };
3163
+ do {
3164
+ if (storeHooks.f) {
3165
+ call(storeHooks.f);
3166
+ }
3167
+ const callbacks = /* @__PURE__ */ new Set();
3168
+ const add = callbacks.add.bind(callbacks);
3169
+ changedAtoms.forEach((atom) => {
3170
+ var _a;
3171
+ return (_a = mountedMap.get(atom)) == null ? void 0 : _a.l.forEach(add);
3172
+ });
3173
+ changedAtoms.clear();
3174
+ unmountCallbacks.forEach(add);
3175
+ unmountCallbacks.clear();
3176
+ mountCallbacks.forEach(add);
3177
+ mountCallbacks.clear();
3178
+ callbacks.forEach(call);
3179
+ if (changedAtoms.size) {
3180
+ recomputeInvalidatedAtoms2(store);
3181
+ }
3182
+ } while (changedAtoms.size || unmountCallbacks.size || mountCallbacks.size);
3183
+ if (errors.length) {
3184
+ throw new AggregateError(errors);
3185
+ }
3186
+ };
3187
+ const recomputeInvalidatedAtoms = (store) => {
3188
+ const buildingBlocks = getInternalBuildingBlocks(store);
3189
+ const mountedMap = buildingBlocks[1];
3190
+ const invalidatedAtoms = buildingBlocks[2];
3191
+ const changedAtoms = buildingBlocks[3];
3192
+ const ensureAtomState2 = buildingBlocks[11];
3193
+ const readAtomState2 = buildingBlocks[14];
3194
+ const mountDependencies2 = buildingBlocks[17];
3195
+ const topSortedReversed = [];
3196
+ const visiting = /* @__PURE__ */ new WeakSet();
3197
+ const visited = /* @__PURE__ */ new WeakSet();
3198
+ const stack = Array.from(changedAtoms);
3199
+ while (stack.length) {
3200
+ const a = stack[stack.length - 1];
3201
+ const aState = ensureAtomState2(store, a);
3202
+ if (visited.has(a)) {
3203
+ stack.pop();
3204
+ continue;
3205
+ }
3206
+ if (visiting.has(a)) {
3207
+ if (invalidatedAtoms.get(a) === aState.n) {
3208
+ topSortedReversed.push([a, aState]);
3209
+ } else if ((undefined ? undefined.MODE : void 0) !== "production" && invalidatedAtoms.has(a)) {
3210
+ throw new Error("[Bug] invalidated atom exists");
3211
+ }
3212
+ visited.add(a);
3213
+ stack.pop();
3214
+ continue;
3215
+ }
3216
+ visiting.add(a);
3217
+ for (const d of getMountedOrPendingDependents(a, aState, mountedMap)) {
3218
+ if (!visiting.has(d)) {
3219
+ stack.push(d);
3220
+ }
3221
+ }
3222
+ }
3223
+ for (let i = topSortedReversed.length - 1; i >= 0; --i) {
3224
+ const [a, aState] = topSortedReversed[i];
3225
+ let hasChangedDeps = false;
3226
+ for (const dep of aState.d.keys()) {
3227
+ if (dep !== a && changedAtoms.has(dep)) {
3228
+ hasChangedDeps = true;
3229
+ break;
3230
+ }
3231
+ }
3232
+ if (hasChangedDeps) {
3233
+ readAtomState2(store, a);
3234
+ mountDependencies2(store, a);
3235
+ }
3236
+ invalidatedAtoms.delete(a);
3237
+ }
3238
+ };
3239
+ const storeMutationSet = /* @__PURE__ */ new WeakSet();
3240
+ const readAtomState = (store, atom) => {
3241
+ var _a, _b;
3242
+ const buildingBlocks = getInternalBuildingBlocks(store);
3243
+ const mountedMap = buildingBlocks[1];
3244
+ const invalidatedAtoms = buildingBlocks[2];
3245
+ const changedAtoms = buildingBlocks[3];
3246
+ const storeHooks = buildingBlocks[6];
3247
+ const atomRead2 = buildingBlocks[7];
3248
+ const ensureAtomState2 = buildingBlocks[11];
3249
+ const flushCallbacks2 = buildingBlocks[12];
3250
+ const recomputeInvalidatedAtoms2 = buildingBlocks[13];
3251
+ const readAtomState2 = buildingBlocks[14];
3252
+ const writeAtomState2 = buildingBlocks[16];
3253
+ const mountDependencies2 = buildingBlocks[17];
3254
+ const atomState = ensureAtomState2(store, atom);
3255
+ if (isAtomStateInitialized(atomState)) {
3256
+ if (mountedMap.has(atom) && invalidatedAtoms.get(atom) !== atomState.n) {
3257
+ return atomState;
3258
+ }
3259
+ let hasChangedDeps = false;
3260
+ for (const [a, n] of atomState.d) {
3261
+ if (readAtomState2(store, a).n !== n) {
3262
+ hasChangedDeps = true;
3263
+ break;
3264
+ }
3265
+ }
3266
+ if (!hasChangedDeps) {
3267
+ return atomState;
3268
+ }
3269
+ }
3270
+ atomState.d.clear();
3271
+ let isSync = true;
3272
+ function mountDependenciesIfAsync() {
3273
+ if (mountedMap.has(atom)) {
3274
+ mountDependencies2(store, atom);
3275
+ recomputeInvalidatedAtoms2(store);
3276
+ flushCallbacks2(store);
3277
+ }
3278
+ }
3279
+ function getter(a) {
3280
+ var _a2;
3281
+ if (a === atom) {
3282
+ const aState2 = ensureAtomState2(store, a);
3283
+ if (!isAtomStateInitialized(aState2)) {
3284
+ if (hasInitialValue(a)) {
3285
+ setAtomStateValueOrPromise(store, a, a.init);
3286
+ } else {
3287
+ throw new Error("no atom init");
3288
+ }
3289
+ }
3290
+ return returnAtomValue(aState2);
3291
+ }
3292
+ const aState = readAtomState2(store, a);
3293
+ try {
3294
+ return returnAtomValue(aState);
3295
+ } finally {
3296
+ atomState.d.set(a, aState.n);
3297
+ if (isPendingPromise(atomState.v)) {
3298
+ addPendingPromiseToDependency(atom, atomState.v, aState);
3299
+ }
3300
+ if (mountedMap.has(atom)) {
3301
+ (_a2 = mountedMap.get(a)) == null ? void 0 : _a2.t.add(atom);
3302
+ }
3303
+ if (!isSync) {
3304
+ mountDependenciesIfAsync();
3305
+ }
3306
+ }
3307
+ }
3308
+ let controller;
3309
+ let setSelf;
3310
+ const options = {
3311
+ get signal() {
3312
+ if (!controller) {
3313
+ controller = new AbortController();
3314
+ }
3315
+ return controller.signal;
3316
+ },
3317
+ get setSelf() {
3318
+ if ((undefined ? undefined.MODE : void 0) !== "production" && !isActuallyWritableAtom(atom)) {
3319
+ console.warn("setSelf function cannot be used with read-only atom");
3320
+ }
3321
+ if (!setSelf && isActuallyWritableAtom(atom)) {
3322
+ setSelf = (...args) => {
3323
+ if ((undefined ? undefined.MODE : void 0) !== "production" && isSync) {
3324
+ console.warn("setSelf function cannot be called in sync");
3325
+ }
3326
+ if (!isSync) {
3327
+ try {
3328
+ return writeAtomState2(store, atom, ...args);
3329
+ } finally {
3330
+ recomputeInvalidatedAtoms2(store);
3331
+ flushCallbacks2(store);
3332
+ }
3333
+ }
3334
+ };
3335
+ }
3336
+ return setSelf;
3337
+ }
3338
+ };
3339
+ const prevEpochNumber = atomState.n;
3340
+ try {
3341
+ if ((undefined ? undefined.MODE : void 0) !== "production") {
3342
+ storeMutationSet.delete(store);
3343
+ }
3344
+ const valueOrPromise = atomRead2(store, atom, getter, options);
3345
+ if ((undefined ? undefined.MODE : void 0) !== "production" && storeMutationSet.has(store)) {
3346
+ console.warn(
3347
+ "Detected store mutation during atom read. This is not supported."
3348
+ );
3349
+ }
3350
+ setAtomStateValueOrPromise(store, atom, valueOrPromise);
3351
+ if (isPromiseLike$1(valueOrPromise)) {
3352
+ registerAbortHandler(valueOrPromise, () => controller == null ? void 0 : controller.abort());
3353
+ valueOrPromise.then(mountDependenciesIfAsync, mountDependenciesIfAsync);
3354
+ }
3355
+ (_a = storeHooks.r) == null ? void 0 : _a.call(storeHooks, atom);
3356
+ return atomState;
3357
+ } catch (error) {
3358
+ delete atomState.v;
3359
+ atomState.e = error;
3360
+ ++atomState.n;
3361
+ return atomState;
3362
+ } finally {
3363
+ isSync = false;
3364
+ if (prevEpochNumber !== atomState.n && invalidatedAtoms.get(atom) === prevEpochNumber) {
3365
+ invalidatedAtoms.set(atom, atomState.n);
3366
+ changedAtoms.add(atom);
3367
+ (_b = storeHooks.c) == null ? void 0 : _b.call(storeHooks, atom);
3368
+ }
3369
+ }
3370
+ };
3371
+ const invalidateDependents = (store, atom) => {
3372
+ const buildingBlocks = getInternalBuildingBlocks(store);
3373
+ const mountedMap = buildingBlocks[1];
3374
+ const invalidatedAtoms = buildingBlocks[2];
3375
+ const ensureAtomState2 = buildingBlocks[11];
3376
+ const stack = [atom];
3377
+ while (stack.length) {
3378
+ const a = stack.pop();
3379
+ const aState = ensureAtomState2(store, a);
3380
+ for (const d of getMountedOrPendingDependents(a, aState, mountedMap)) {
3381
+ const dState = ensureAtomState2(store, d);
3382
+ invalidatedAtoms.set(d, dState.n);
3383
+ stack.push(d);
3384
+ }
3385
+ }
3386
+ };
3387
+ const writeAtomState = (store, atom, ...args) => {
3388
+ const buildingBlocks = getInternalBuildingBlocks(store);
3389
+ const changedAtoms = buildingBlocks[3];
3390
+ const storeHooks = buildingBlocks[6];
3391
+ const atomWrite2 = buildingBlocks[8];
3392
+ const ensureAtomState2 = buildingBlocks[11];
3393
+ const flushCallbacks2 = buildingBlocks[12];
3394
+ const recomputeInvalidatedAtoms2 = buildingBlocks[13];
3395
+ const readAtomState2 = buildingBlocks[14];
3396
+ const invalidateDependents2 = buildingBlocks[15];
3397
+ const mountDependencies2 = buildingBlocks[17];
3398
+ let isSync = true;
3399
+ const getter = (a) => returnAtomValue(readAtomState2(store, a));
3400
+ const setter = (a, ...args2) => {
3401
+ var _a;
3402
+ const aState = ensureAtomState2(store, a);
3403
+ try {
3404
+ if (a === atom) {
3405
+ if (!hasInitialValue(a)) {
3406
+ throw new Error("atom not writable");
3407
+ }
3408
+ if ((undefined ? undefined.MODE : void 0) !== "production") {
3409
+ storeMutationSet.add(store);
3410
+ }
3411
+ const prevEpochNumber = aState.n;
3412
+ const v = args2[0];
3413
+ setAtomStateValueOrPromise(store, a, v);
3414
+ mountDependencies2(store, a);
3415
+ if (prevEpochNumber !== aState.n) {
3416
+ changedAtoms.add(a);
3417
+ invalidateDependents2(store, a);
3418
+ (_a = storeHooks.c) == null ? void 0 : _a.call(storeHooks, a);
3419
+ }
3420
+ return void 0;
3421
+ } else {
3422
+ return writeAtomState(store, a, ...args2);
3423
+ }
3424
+ } finally {
3425
+ if (!isSync) {
3426
+ recomputeInvalidatedAtoms2(store);
3427
+ flushCallbacks2(store);
3428
+ }
3429
+ }
3430
+ };
3431
+ try {
3432
+ return atomWrite2(store, atom, getter, setter, ...args);
3433
+ } finally {
3434
+ isSync = false;
3435
+ }
3436
+ };
3437
+ const mountDependencies = (store, atom) => {
3438
+ var _a;
3439
+ const buildingBlocks = getInternalBuildingBlocks(store);
3440
+ const mountedMap = buildingBlocks[1];
3441
+ const changedAtoms = buildingBlocks[3];
3442
+ const storeHooks = buildingBlocks[6];
3443
+ const ensureAtomState2 = buildingBlocks[11];
3444
+ const invalidateDependents2 = buildingBlocks[15];
3445
+ const mountAtom2 = buildingBlocks[18];
3446
+ const unmountAtom2 = buildingBlocks[19];
3447
+ const atomState = ensureAtomState2(store, atom);
3448
+ const mounted = mountedMap.get(atom);
3449
+ if (mounted && !isPendingPromise(atomState.v)) {
3450
+ for (const [a, n] of atomState.d) {
3451
+ if (!mounted.d.has(a)) {
3452
+ const aState = ensureAtomState2(store, a);
3453
+ const aMounted = mountAtom2(store, a);
3454
+ aMounted.t.add(atom);
3455
+ mounted.d.add(a);
3456
+ if (n !== aState.n) {
3457
+ changedAtoms.add(a);
3458
+ invalidateDependents2(store, a);
3459
+ (_a = storeHooks.c) == null ? void 0 : _a.call(storeHooks, a);
3460
+ }
3461
+ }
3462
+ }
3463
+ for (const a of mounted.d) {
3464
+ if (!atomState.d.has(a)) {
3465
+ mounted.d.delete(a);
3466
+ const aMounted = unmountAtom2(store, a);
3467
+ aMounted == null ? void 0 : aMounted.t.delete(atom);
3468
+ }
3469
+ }
3470
+ }
3471
+ };
3472
+ const mountAtom = (store, atom) => {
3473
+ var _a;
3474
+ const buildingBlocks = getInternalBuildingBlocks(store);
3475
+ const mountedMap = buildingBlocks[1];
3476
+ const mountCallbacks = buildingBlocks[4];
3477
+ const storeHooks = buildingBlocks[6];
3478
+ const atomOnMount2 = buildingBlocks[10];
3479
+ const ensureAtomState2 = buildingBlocks[11];
3480
+ const flushCallbacks2 = buildingBlocks[12];
3481
+ const recomputeInvalidatedAtoms2 = buildingBlocks[13];
3482
+ const readAtomState2 = buildingBlocks[14];
3483
+ const writeAtomState2 = buildingBlocks[16];
3484
+ const atomState = ensureAtomState2(store, atom);
3485
+ let mounted = mountedMap.get(atom);
3486
+ if (!mounted) {
3487
+ readAtomState2(store, atom);
3488
+ for (const a of atomState.d.keys()) {
3489
+ const aMounted = mountAtom(store, a);
3490
+ aMounted.t.add(atom);
3491
+ }
3492
+ mounted = {
3493
+ l: /* @__PURE__ */ new Set(),
3494
+ d: new Set(atomState.d.keys()),
3495
+ t: /* @__PURE__ */ new Set()
3496
+ };
3497
+ mountedMap.set(atom, mounted);
3498
+ if (isActuallyWritableAtom(atom)) {
3499
+ const processOnMount = () => {
3500
+ let isSync = true;
3501
+ const setAtom = (...args) => {
3502
+ try {
3503
+ return writeAtomState2(store, atom, ...args);
3504
+ } finally {
3505
+ if (!isSync) {
3506
+ recomputeInvalidatedAtoms2(store);
3507
+ flushCallbacks2(store);
3508
+ }
3509
+ }
3510
+ };
3511
+ try {
3512
+ const onUnmount = atomOnMount2(store, atom, setAtom);
3513
+ if (onUnmount) {
3514
+ mounted.u = () => {
3515
+ isSync = true;
3516
+ try {
3517
+ onUnmount();
3518
+ } finally {
3519
+ isSync = false;
3520
+ }
3521
+ };
3522
+ }
3523
+ } finally {
3524
+ isSync = false;
3525
+ }
3526
+ };
3527
+ mountCallbacks.add(processOnMount);
3528
+ }
3529
+ (_a = storeHooks.m) == null ? void 0 : _a.call(storeHooks, atom);
3530
+ }
3531
+ return mounted;
3532
+ };
3533
+ const unmountAtom = (store, atom) => {
3534
+ var _a, _b;
3535
+ const buildingBlocks = getInternalBuildingBlocks(store);
3536
+ const mountedMap = buildingBlocks[1];
3537
+ const unmountCallbacks = buildingBlocks[5];
3538
+ const storeHooks = buildingBlocks[6];
3539
+ const ensureAtomState2 = buildingBlocks[11];
3540
+ const unmountAtom2 = buildingBlocks[19];
3541
+ const atomState = ensureAtomState2(store, atom);
3542
+ let mounted = mountedMap.get(atom);
3543
+ if (!mounted || mounted.l.size) {
3544
+ return mounted;
3545
+ }
3546
+ let isDependent = false;
3547
+ for (const a of mounted.t) {
3548
+ if ((_a = mountedMap.get(a)) == null ? void 0 : _a.d.has(atom)) {
3549
+ isDependent = true;
3550
+ break;
3551
+ }
3552
+ }
3553
+ if (!isDependent) {
3554
+ if (mounted.u) {
3555
+ unmountCallbacks.add(mounted.u);
3556
+ }
3557
+ mounted = void 0;
3558
+ mountedMap.delete(atom);
3559
+ for (const a of atomState.d.keys()) {
3560
+ const aMounted = unmountAtom2(store, a);
3561
+ aMounted == null ? void 0 : aMounted.t.delete(atom);
3562
+ }
3563
+ (_b = storeHooks.u) == null ? void 0 : _b.call(storeHooks, atom);
3564
+ return void 0;
3565
+ }
3566
+ return mounted;
3567
+ };
3568
+ const setAtomStateValueOrPromise = (store, atom, valueOrPromise) => {
3569
+ const ensureAtomState2 = getInternalBuildingBlocks(store)[11];
3570
+ const atomState = ensureAtomState2(store, atom);
3571
+ const hasPrevValue = "v" in atomState;
3572
+ const prevValue = atomState.v;
3573
+ if (isPromiseLike$1(valueOrPromise)) {
3574
+ for (const a of atomState.d.keys()) {
3575
+ addPendingPromiseToDependency(
3576
+ atom,
3577
+ valueOrPromise,
3578
+ ensureAtomState2(store, a)
3579
+ );
3580
+ }
3581
+ }
3582
+ atomState.v = valueOrPromise;
3583
+ delete atomState.e;
3584
+ if (!hasPrevValue || !Object.is(prevValue, atomState.v)) {
3585
+ ++atomState.n;
3586
+ if (isPromiseLike$1(prevValue)) {
3587
+ abortPromise(prevValue);
3588
+ }
3589
+ }
3590
+ };
3591
+ const storeGet = (store, atom) => {
3592
+ const readAtomState2 = getInternalBuildingBlocks(store)[14];
3593
+ return returnAtomValue(readAtomState2(store, atom));
3594
+ };
3595
+ const storeSet = (store, atom, ...args) => {
3596
+ const buildingBlocks = getInternalBuildingBlocks(store);
3597
+ const flushCallbacks2 = buildingBlocks[12];
3598
+ const recomputeInvalidatedAtoms2 = buildingBlocks[13];
3599
+ const writeAtomState2 = buildingBlocks[16];
3600
+ try {
3601
+ return writeAtomState2(store, atom, ...args);
3602
+ } finally {
3603
+ recomputeInvalidatedAtoms2(store);
3604
+ flushCallbacks2(store);
3605
+ }
3606
+ };
3607
+ const storeSub = (store, atom, listener) => {
3608
+ const buildingBlocks = getInternalBuildingBlocks(store);
3609
+ const flushCallbacks2 = buildingBlocks[12];
3610
+ const mountAtom2 = buildingBlocks[18];
3611
+ const unmountAtom2 = buildingBlocks[19];
3612
+ const mounted = mountAtom2(store, atom);
3613
+ const listeners = mounted.l;
3614
+ listeners.add(listener);
3615
+ flushCallbacks2(store);
3616
+ return () => {
3617
+ listeners.delete(listener);
3618
+ unmountAtom2(store, atom);
3619
+ flushCallbacks2(store);
3620
+ };
3621
+ };
3622
+ const buildingBlockMap = /* @__PURE__ */ new WeakMap();
3623
+ const getInternalBuildingBlocks = (store) => {
3624
+ const buildingBlocks = buildingBlockMap.get(store);
3625
+ if ((undefined ? undefined.MODE : void 0) !== "production" && !buildingBlocks) {
3626
+ throw new Error(
3627
+ "Store must be created by buildStore to read its building blocks"
3628
+ );
3629
+ }
3630
+ return buildingBlocks;
3631
+ };
3632
+ function buildStore(...buildArgs) {
3633
+ const store = {
3634
+ get(atom) {
3635
+ const storeGet2 = getInternalBuildingBlocks(store)[21];
3636
+ return storeGet2(store, atom);
3637
+ },
3638
+ set(atom, ...args) {
3639
+ const storeSet2 = getInternalBuildingBlocks(store)[22];
3640
+ return storeSet2(store, atom, ...args);
3641
+ },
3642
+ sub(atom, listener) {
3643
+ const storeSub2 = getInternalBuildingBlocks(store)[23];
3644
+ return storeSub2(store, atom, listener);
3645
+ }
3646
+ };
3647
+ const buildingBlocks = [
3648
+ // store state
3649
+ /* @__PURE__ */ new WeakMap(),
3650
+ // atomStateMap
3651
+ /* @__PURE__ */ new WeakMap(),
3652
+ // mountedMap
3653
+ /* @__PURE__ */ new WeakMap(),
3654
+ // invalidatedAtoms
3655
+ /* @__PURE__ */ new Set(),
3656
+ // changedAtoms
3657
+ /* @__PURE__ */ new Set(),
3658
+ // mountCallbacks
3659
+ /* @__PURE__ */ new Set(),
3660
+ // unmountCallbacks
3661
+ {},
3662
+ // storeHooks
3663
+ // atom interceptors
3664
+ atomRead,
3665
+ atomWrite,
3666
+ atomOnInit,
3667
+ atomOnMount,
3668
+ // building-block functions
3669
+ ensureAtomState,
3670
+ flushCallbacks,
3671
+ recomputeInvalidatedAtoms,
3672
+ readAtomState,
3673
+ invalidateDependents,
3674
+ writeAtomState,
3675
+ mountDependencies,
3676
+ mountAtom,
3677
+ unmountAtom,
3678
+ setAtomStateValueOrPromise,
3679
+ storeGet,
3680
+ storeSet,
3681
+ storeSub,
3682
+ void 0
3683
+ ].map((fn, i) => buildArgs[i] || fn);
3684
+ buildingBlockMap.set(store, Object.freeze(buildingBlocks));
3685
+ return store;
3686
+ }let keyCount = 0;
3687
+ function atom(read, write) {
3688
+ const key = `atom${++keyCount}`;
3689
+ const config = {
3690
+ toString() {
3691
+ return (undefined ? undefined.MODE : void 0) !== "production" && this.debugLabel ? key + ":" + this.debugLabel : key;
3692
+ }
3693
+ };
3694
+ if (typeof read === "function") {
3695
+ config.read = read;
3696
+ } else {
3697
+ config.init = read;
3698
+ config.read = defaultRead;
3699
+ config.write = defaultWrite;
3700
+ }
3701
+ if (write) {
3702
+ config.write = write;
3703
+ }
3704
+ return config;
3705
+ }
3706
+ function defaultRead(get) {
3707
+ return get(this);
3708
+ }
3709
+ function defaultWrite(get, set, arg) {
3710
+ return set(
3711
+ this,
3712
+ typeof arg === "function" ? arg(get(this)) : arg
3713
+ );
3714
+ }
3715
+ function createStore() {
3716
+ return buildStore();
3717
+ }
3718
+ let defaultStore;
3719
+ function getDefaultStore() {
3720
+ if (!defaultStore) {
3721
+ defaultStore = createStore();
3722
+ if ((undefined ? undefined.MODE : void 0) !== "production") {
3723
+ globalThis.__JOTAI_DEFAULT_STORE__ || (globalThis.__JOTAI_DEFAULT_STORE__ = defaultStore);
3724
+ if (globalThis.__JOTAI_DEFAULT_STORE__ !== defaultStore) {
3725
+ console.warn(
3726
+ "Detected multiple Jotai instances. It may cause unexpected behavior with the default store. https://github.com/pmndrs/jotai/discussions/2044"
3727
+ );
3728
+ }
3729
+ }
3730
+ }
3731
+ return defaultStore;
3732
+ }const StoreContext = React.createContext(
3733
+ void 0
3734
+ );
3735
+ function useStore(options) {
3736
+ const store = React.useContext(StoreContext);
3737
+ return store || getDefaultStore();
3738
+ }
3739
+
3740
+ const isPromiseLike = (x) => typeof (x == null ? void 0 : x.then) === "function";
3741
+ const attachPromiseStatus = (promise) => {
3742
+ if (!promise.status) {
3743
+ promise.status = "pending";
3744
+ promise.then(
3745
+ (v) => {
3746
+ promise.status = "fulfilled";
3747
+ promise.value = v;
3748
+ },
3749
+ (e) => {
3750
+ promise.status = "rejected";
3751
+ promise.reason = e;
3752
+ }
3753
+ );
3754
+ }
3755
+ };
3756
+ const use = React.use || // A shim for older React versions
3757
+ ((promise) => {
3758
+ if (promise.status === "pending") {
3759
+ throw promise;
3760
+ } else if (promise.status === "fulfilled") {
3761
+ return promise.value;
3762
+ } else if (promise.status === "rejected") {
3763
+ throw promise.reason;
3764
+ } else {
3765
+ attachPromiseStatus(promise);
3766
+ throw promise;
3767
+ }
3768
+ });
3769
+ const continuablePromiseMap = /* @__PURE__ */ new WeakMap();
3770
+ const createContinuablePromise = (promise, getValue) => {
3771
+ let continuablePromise = continuablePromiseMap.get(promise);
3772
+ if (!continuablePromise) {
3773
+ continuablePromise = new Promise((resolve, reject) => {
3774
+ let curr = promise;
3775
+ const onFulfilled = (me) => (v) => {
3776
+ if (curr === me) {
3777
+ resolve(v);
3778
+ }
3779
+ };
3780
+ const onRejected = (me) => (e) => {
3781
+ if (curr === me) {
3782
+ reject(e);
3783
+ }
3784
+ };
3785
+ const onAbort = () => {
3786
+ try {
3787
+ const nextValue = getValue();
3788
+ if (isPromiseLike(nextValue)) {
3789
+ continuablePromiseMap.set(nextValue, continuablePromise);
3790
+ curr = nextValue;
3791
+ nextValue.then(onFulfilled(nextValue), onRejected(nextValue));
3792
+ registerAbortHandler(nextValue, onAbort);
3793
+ } else {
3794
+ resolve(nextValue);
3795
+ }
3796
+ } catch (e) {
3797
+ reject(e);
3798
+ }
3799
+ };
3800
+ promise.then(onFulfilled(promise), onRejected(promise));
3801
+ registerAbortHandler(promise, onAbort);
3802
+ });
3803
+ continuablePromiseMap.set(promise, continuablePromise);
3804
+ }
3805
+ return continuablePromise;
3806
+ };
3807
+ function useAtomValue(atom, options) {
3808
+ const { delay, unstable_promiseStatus: promiseStatus = !React.use } = {};
3809
+ const store = useStore();
3810
+ const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] = React.useReducer(
3811
+ (prev) => {
3812
+ const nextValue = store.get(atom);
3813
+ if (Object.is(prev[0], nextValue) && prev[1] === store && prev[2] === atom) {
3814
+ return prev;
3815
+ }
3816
+ return [nextValue, store, atom];
3817
+ },
3818
+ void 0,
3819
+ () => [store.get(atom), store, atom]
3820
+ );
3821
+ let value = valueFromReducer;
3822
+ if (storeFromReducer !== store || atomFromReducer !== atom) {
3823
+ rerender();
3824
+ value = store.get(atom);
3825
+ }
3826
+ React.useEffect(() => {
3827
+ const unsub = store.sub(atom, () => {
3828
+ if (promiseStatus) {
3829
+ try {
3830
+ const value2 = store.get(atom);
3831
+ if (isPromiseLike(value2)) {
3832
+ attachPromiseStatus(
3833
+ createContinuablePromise(value2, () => store.get(atom))
3834
+ );
3835
+ }
3836
+ } catch (e) {
3837
+ }
3838
+ }
3839
+ if (typeof delay === "number") {
3840
+ setTimeout(rerender, delay);
3841
+ return;
3842
+ }
3843
+ rerender();
3844
+ });
3845
+ rerender();
3846
+ return unsub;
3847
+ }, [store, atom, delay, promiseStatus]);
3848
+ React.useDebugValue(value);
3849
+ if (isPromiseLike(value)) {
3850
+ const promise = createContinuablePromise(value, () => store.get(atom));
3851
+ if (promiseStatus) {
3852
+ attachPromiseStatus(promise);
3853
+ }
3854
+ return use(promise);
3855
+ }
3856
+ return value;
3857
+ }
3858
+
3859
+ function useSetAtom(atom, options) {
3860
+ const store = useStore();
3861
+ const setAtom = React.useCallback(
3862
+ (...args) => {
3863
+ if ((undefined ? undefined.MODE : void 0) !== "production" && !("write" in atom)) {
3864
+ throw new Error("not writable atom");
3865
+ }
3866
+ return store.set(atom, ...args);
3867
+ },
3868
+ [store, atom]
3869
+ );
3870
+ return setAtom;
3871
+ }
3872
+
3873
+ function useAtom(atom, options) {
3874
+ return [
3875
+ useAtomValue(atom),
3876
+ // We do wrong type assertion here, which results in throwing an error.
3877
+ useSetAtom(atom)
3878
+ ];
3879
+ }const getCached$2 = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k);
3880
+ const cache1$3 = /* @__PURE__ */ new WeakMap();
3881
+ const memo3 = (create, dep1, dep2, dep3) => {
3882
+ const cache2 = getCached$2(() => /* @__PURE__ */ new WeakMap(), cache1$3, dep1);
3883
+ const cache3 = getCached$2(() => /* @__PURE__ */ new WeakMap(), cache2, dep2);
3884
+ return getCached$2(create, cache3, dep3);
3885
+ };
3886
+ function selectAtom(anAtom, selector, equalityFn = Object.is) {
3887
+ return memo3(
3888
+ () => {
3889
+ const EMPTY = /* @__PURE__ */ Symbol();
3890
+ const selectValue = ([value, prevSlice]) => {
3891
+ if (prevSlice === EMPTY) {
3892
+ return selector(value);
3893
+ }
3894
+ const slice = selector(value, prevSlice);
3895
+ return equalityFn(prevSlice, slice) ? prevSlice : slice;
3896
+ };
3897
+ const derivedAtom = atom((get) => {
3898
+ const prev = get(derivedAtom);
3899
+ const value = get(anAtom);
3900
+ return selectValue([value, prev]);
3901
+ });
3902
+ derivedAtom.init = EMPTY;
3903
+ return derivedAtom;
3904
+ },
3905
+ anAtom,
3906
+ selector,
3907
+ equalityFn
3908
+ );
3909
+ }
3910
+
3911
+ const isPromiseLike$3 = (x) => typeof (x == null ? void 0 : x.then) === "function";
3912
+ function createJSONStorage(getStringStorage = () => {
3913
+ try {
3914
+ return window.localStorage;
3915
+ } catch (e) {
3916
+ if ((undefined ? undefined.MODE : void 0) !== "production") {
3917
+ if (typeof window !== "undefined") {
3918
+ console.warn(e);
3919
+ }
3920
+ }
3921
+ return void 0;
3922
+ }
3923
+ }, options) {
3924
+ var _a;
3925
+ let lastStr;
3926
+ let lastValue;
3927
+ const storage = {
3928
+ getItem: (key, initialValue) => {
3929
+ var _a2, _b;
3930
+ const parse = (str2) => {
3931
+ str2 = str2 || "";
3932
+ if (lastStr !== str2) {
3933
+ try {
3934
+ lastValue = JSON.parse(str2, void 0 );
3935
+ } catch (e) {
3936
+ return initialValue;
3937
+ }
3938
+ lastStr = str2;
3939
+ }
3940
+ return lastValue;
3941
+ };
3942
+ const str = (_b = (_a2 = getStringStorage()) == null ? void 0 : _a2.getItem(key)) != null ? _b : null;
3943
+ if (isPromiseLike$3(str)) {
3944
+ return str.then(parse);
3945
+ }
3946
+ return parse(str);
3947
+ },
3948
+ setItem: (key, newValue) => {
3949
+ var _a2;
3950
+ return (_a2 = getStringStorage()) == null ? void 0 : _a2.setItem(
3951
+ key,
3952
+ JSON.stringify(newValue, void 0 )
3953
+ );
3954
+ },
3955
+ removeItem: (key) => {
3956
+ var _a2;
3957
+ return (_a2 = getStringStorage()) == null ? void 0 : _a2.removeItem(key);
3958
+ }
3959
+ };
3960
+ const createHandleSubscribe = (subscriber2) => (key, callback, initialValue) => subscriber2(key, (v) => {
3961
+ let newValue;
3962
+ try {
3963
+ newValue = JSON.parse(v || "");
3964
+ } catch (e) {
3965
+ newValue = initialValue;
3966
+ }
3967
+ callback(newValue);
3968
+ });
3969
+ let subscriber;
3970
+ try {
3971
+ subscriber = (_a = getStringStorage()) == null ? void 0 : _a.subscribe;
3972
+ } catch (e) {
3973
+ }
3974
+ if (!subscriber && typeof window !== "undefined" && typeof window.addEventListener === "function" && window.Storage) {
3975
+ subscriber = (key, callback) => {
3976
+ if (!(getStringStorage() instanceof window.Storage)) {
3977
+ return () => {
3978
+ };
3979
+ }
3980
+ const storageEventCallback = (e) => {
3981
+ if (e.storageArea === getStringStorage() && e.key === key) {
3982
+ callback(e.newValue);
3983
+ }
3984
+ };
3985
+ window.addEventListener("storage", storageEventCallback);
3986
+ return () => {
3987
+ window.removeEventListener("storage", storageEventCallback);
3988
+ };
3989
+ };
3990
+ }
3991
+ if (subscriber) {
3992
+ storage.subscribe = createHandleSubscribe(subscriber);
3993
+ }
3994
+ return storage;
3995
+ }
3996
+ createJSONStorage();const DEFAULT_FORM_ENTRY = Object.freeze({
3997
+ formValues: {},
3998
+ setValue: () => {}
3999
+ });
4000
+ /**
4001
+ * Global atom storing all form state.
4002
+ * Key format: "scopeId:formId" or just "formId" for backward compatibility.
4003
+ */
4004
+ const formAtom = atom({});
4005
+ /**
4006
+ * Helper to generate composite keys for forms.
4007
+ */
4008
+ const getFormCompositeKey = (scopeId, key) => `${scopeId}:${key}`;
4009
+ /**
4010
+ * Creates a derived atom for accessing forms of a specific scope.
4011
+ */
4012
+ const createScopeFormsAtom = scopeId => atom(get => {
4013
+ const allForms = get(formAtom);
4014
+ const prefix = `${scopeId}:`;
4015
+ const scopeForms = {};
4016
+ for (const [key, value] of Object.entries(allForms)) {
4017
+ if (key.startsWith(prefix)) {
4018
+ scopeForms[key.slice(prefix.length)] = value;
4019
+ }
4020
+ }
4021
+ return scopeForms;
4022
+ }, (get, set, update) => {
4023
+ const allForms = get(formAtom);
4024
+ const prefix = `${scopeId}:`;
4025
+ const newForms = Object.assign({}, allForms);
4026
+ // Remove old scope entries
4027
+ for (const key of Object.keys(newForms)) {
4028
+ if (key.startsWith(prefix)) {
4029
+ delete newForms[key];
4030
+ }
4031
+ }
4032
+ // Add new scope entries
4033
+ for (const [key, value] of Object.entries(update)) {
4034
+ newForms[`${prefix}${key}`] = value;
4035
+ }
4036
+ set(formAtom, newForms);
4037
+ });
4038
+ const createFormSelector = formId => selectAtom(formAtom, forms => {
4039
+ const entry = forms[formId];
4040
+ return entry !== null && entry !== void 0 ? entry : DEFAULT_FORM_ENTRY;
4041
+ }, (a, b) => a === b || a.formValues === b.formValues && a.setValue === b.setValue);
4042
+ const useFormValue = formId => {
4043
+ const $ = compilerRuntime.c(2);
4044
+ let t0;
4045
+ if ($[0] !== formId) {
4046
+ t0 = createFormSelector(formId);
4047
+ $[0] = formId;
4048
+ $[1] = t0;
4049
+ } else {
4050
+ t0 = $[1];
4051
+ }
4052
+ const selectorAtom = t0;
4053
+ return useAtomValue(selectorAtom);
4054
+ };
4055
+ const useFormState = () => {
4056
+ return useAtom(formAtom);
4057
+ };
4058
+ const useSetFormState = formId => {
4059
+ const setForms = useSetAtom(formAtom);
4060
+ return React.useCallback(val => {
4061
+ setForms(prev => {
4062
+ var _a;
4063
+ const prevEntry = (_a = prev[formId]) !== null && _a !== void 0 ? _a : DEFAULT_FORM_ENTRY;
4064
+ return Object.assign(Object.assign({}, prev), {
4065
+ [formId]: Object.assign(Object.assign({}, prevEntry), val)
4066
+ });
4067
+ });
4068
+ }, [formId, setForms]);
4069
+ };const getValueAtPath = (obj, path, defaultObj) => {
4070
+ if (!path) return undefined;
4071
+ const normalized = path.replace(/\[(\d+)\]/g, '.$1');
4072
+ const parts = normalized.split('.').filter(Boolean);
4073
+ let current = obj;
4074
+ for (const part of parts) {
4075
+ if (!current || !Object.keys(current).length) {
4076
+ return undefined;
4077
+ }
4078
+ if (typeof current !== 'object') return undefined;
4079
+ current = current[part];
4080
+ }
4081
+ return current;
4082
+ };
4083
+ const useFormValues = ({
4084
+ formId
4085
+ }) => {
4086
+ // We subscribe to the specific form entry in the atoms
4087
+ // Note: This subscription is a bit coarse (entire form entry), but we optimize re-renders locally
4088
+ // Ideally we would want to subscribe only to specific paths, but Jotai atoms are per-form.
4089
+ const formEntry = useFormValue(formId);
4090
+ const currentValues = React.useMemo(() => formEntry.formValues, [formEntry.formValues]);
4091
+ const subscriptions = React.useRef(new Map());
4092
+ // trigger state is used to force re-render when a subscribed value changes
4093
+ const [trigger, setTrigger] = React.useState(0);
4094
+ // Ref to hold the latest values without causing re-renders itself
4095
+ const formRef = React.useRef({
4096
+ formValues: formEntry.formValues,
4097
+ setValue: formEntry.setValue
4098
+ });
4099
+ React.useEffect(() => {
4100
+ formRef.current.setValue = formEntry.setValue;
4101
+ }, [formEntry.setValue]);
4102
+ React.useEffect(() => {
4103
+ let shouldTrigger = false;
4104
+ subscriptions.current.forEach((_, path) => {
4105
+ const newValue = getValueAtPath(currentValues, path);
4106
+ const oldValue = getValueAtPath(formRef.current.formValues, path);
4107
+ if (!equal(newValue, oldValue)) {
4108
+ shouldTrigger = true;
4109
+ }
4110
+ });
4111
+ formRef.current.formValues = currentValues;
4112
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
4113
+ if (shouldTrigger) {
4114
+ setTrigger(c => c + 1);
4115
+ }
4116
+ }, [currentValues]);
4117
+ const get = React.useCallback((key, defaultValue) => {
4118
+ var _a;
4119
+ const val = (_a = getValueAtPath(formRef.current.formValues, key)) !== null && _a !== void 0 ? _a : defaultValue;
4120
+ subscriptions.current.set(key, val);
4121
+ return subscriptions.current.get(key);
4122
+ },
4123
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4124
+ [trigger]);
4125
+ const set = React.useCallback((field, value) => {
4126
+ formRef.current.setValue(field, value);
4127
+ }, []);
4128
+ return {
4129
+ get,
4130
+ set
4131
+ };
4132
+ };const trimObject = obj => Object.entries(obj !== null && obj !== void 0 ? obj : {}).reduce((prev, [key, val]) => Object.assign(Object.assign({}, prev), {
4133
+ [key]: typeof val === 'string' && !['password', 'pPassword'].includes(key) ? val.trim() : val
4134
+ }), {});
4135
+ const RenderField = t0 => {
4136
+ const $ = compilerRuntime.c(9);
4137
+ const {
4138
+ field,
4139
+ fieldState,
4140
+ fieldProps,
4141
+ onFieldChange
4142
+ } = t0;
4143
+ let t1;
4144
+ if ($[0] !== field || $[1] !== fieldProps || $[2] !== fieldState) {
4145
+ t1 = Object.assign(Object.assign({}, fieldProps), {
4146
+ field,
4147
+ fieldState
4148
+ });
4149
+ $[0] = field;
4150
+ $[1] = fieldProps;
4151
+ $[2] = fieldState;
4152
+ $[3] = t1;
4153
+ } else {
4154
+ t1 = $[3];
4155
+ }
4156
+ const config = t1;
4157
+ let t2;
4158
+ if ($[4] !== config || $[5] !== fieldProps.errorNs || $[6] !== fieldProps.ns || $[7] !== onFieldChange) {
4159
+ t2 = jsxRuntime.jsx(FormField, {
4160
+ config,
4161
+ ns: fieldProps.ns,
4162
+ globalErrorNs: fieldProps.errorNs,
4163
+ onFieldChange
4164
+ });
4165
+ $[4] = config;
4166
+ $[5] = fieldProps.errorNs;
4167
+ $[6] = fieldProps.ns;
4168
+ $[7] = onFieldChange;
4169
+ $[8] = t2;
4170
+ } else {
4171
+ t2 = $[8];
4172
+ }
4173
+ return t2;
4174
+ };
4175
+ const DynamicFieldItem = ({
4176
+ item,
4177
+ form,
4178
+ globalErrorNs,
4179
+ formId
4180
+ }) => {
4181
+ const {
4182
+ get,
4183
+ set
4184
+ } = useFormValues({
4185
+ formId
4186
+ });
4187
+ const fieldProps = React.useMemo(() => {
4188
+ if (typeof item === 'function') {
4189
+ return item({
4190
+ get,
4191
+ set
4192
+ });
4193
+ } else {
4194
+ return item;
4195
+ }
4196
+ }, [get, set, item]);
4197
+ const isHidden = React.useMemo(() => {
4198
+ if (!fieldProps.hidden) {
4199
+ return false;
4200
+ } else if (typeof fieldProps.hidden === 'function') {
4201
+ return fieldProps.hidden({
4202
+ get,
4203
+ set
4204
+ });
4205
+ } else {
4206
+ return !!fieldProps.hidden;
4207
+ }
4208
+ }, [get, set, fieldProps]);
4209
+ const rules = React.useMemo(() => {
4210
+ if (!fieldProps.rules) {
4211
+ return undefined;
4212
+ } else if (typeof fieldProps.rules === 'function') {
4213
+ return fieldProps.rules({
4214
+ get,
4215
+ set
4216
+ });
4217
+ } else {
4218
+ return fieldProps.rules;
4219
+ }
4220
+ }, [get, set, fieldProps]);
4221
+ const props = React.useMemo(() => {
4222
+ var _a;
4223
+ return Object.assign(Object.assign({}, fieldProps), {
4224
+ errorNs: (_a = fieldProps.errorNs) !== null && _a !== void 0 ? _a : globalErrorNs
4225
+ });
4226
+ }, [fieldProps, globalErrorNs]);
4227
+ if (isHidden) {
4228
+ return jsxRuntime.jsx(jsxRuntime.Fragment, {});
4229
+ }
4230
+ return jsxRuntime.jsx(form.Field, {
4231
+ name: props.name,
4232
+ validators: rules,
4233
+ // eslint-disable-next-line react/no-children-prop
4234
+ children: field => jsxRuntime.jsx(RenderField, {
4235
+ field: field,
4236
+ fieldState: field.state,
4237
+ fieldProps: props,
4238
+ onFieldChange: props.onFieldChange
4239
+ })
4240
+ });
4241
+ };
4242
+ const SubmitItem = ({
4243
+ item,
4244
+ index,
4245
+ handlersRef
4246
+ }) => {
4247
+ const handleClick = React.useCallback(async () => {
4248
+ const {
4249
+ formControl,
4250
+ createSubmitHandler,
4251
+ onInvalidHandle
4252
+ } = handlersRef.current;
4253
+ // Partial or full validation logic
4254
+ let isValid = true;
4255
+ const keys = item.values;
4256
+ if (keys && keys.length > 0) {
4257
+ // Validate only specific fields
4258
+ await Promise.all(keys.map(key => formControl.validateField(key, 'change')));
4259
+ const hasError = keys.some(key_0 => {
4260
+ // This is a simplified check. TanStack form errors might be structured differently.
4261
+ // You might need deep checking if errors are nested objects.
4262
+ // For now assume flat or use lodash get if possible, but state.errors is usually flat-ish map in newer versions or object.
4263
+ // Checking standard TanStack: form.state.fieldMeta[key]?.errors
4264
+ const meta = formControl.getFieldMeta(key_0);
4265
+ return (meta === null || meta === void 0 ? void 0 : meta.errors) && meta.errors.length > 0;
4266
+ });
4267
+ isValid = !hasError;
4268
+ } else {
4269
+ // Validate all
4270
+ await formControl.validateAllFields('submit');
4271
+ isValid = formControl.state.isValid;
4272
+ }
4273
+ if (!isValid) {
4274
+ onInvalidHandle(formControl.state.errors, item);
4275
+ return;
4276
+ }
4277
+ const values = formControl.state.values;
4278
+ // Call handlers
4279
+ await createSubmitHandler(item)(values);
4280
+ }, [item, handlersRef]);
4281
+ const Component = React.useMemo(() => item.component, [item]);
4282
+ if (item.hidden || !Component) return jsxRuntime.jsx(jsxRuntime.Fragment, {});
4283
+ return jsxRuntime.jsx(Component, {
4284
+ onClick: handleClick,
4285
+ index: index,
4286
+ type: item.type || 'button'
4287
+ }, `submit-${index}`);
4288
+ };
4289
+ const useFormManager = ({
4290
+ data,
4291
+ onInvalid,
4292
+ submit = [],
4293
+ notification,
4294
+ formOptions,
4295
+ onValuesChange,
4296
+ globalErrorNs,
4297
+ id = 'form-manager'
4298
+ }) => {
4299
+ const formControl = useJotaiForm(formOptions);
4300
+ const formState = React.useMemo(() => formControl.state, [formControl.state]);
4301
+ const errors = React.useMemo(() => formState.errors, [formState.errors]);
4302
+ const values = React.useMemo(() => formState.values, [formState.values]);
4303
+ const setFormState = useSetFormState(id);
4304
+ const {
4305
+ showNotification
4306
+ } = useFormConfigValue();
4307
+ const setValue = React.useCallback((field, updater) => formControl.setFieldValue(field, updater), [formControl]);
4308
+ React.useEffect(() => {
4309
+ setFormState({
4310
+ setValue,
4311
+ formValues: formState.values
4312
+ });
4313
+ const unsubscribe = formControl.store.subscribe(store => {
4314
+ setFormState({
4315
+ formValues: store.currentVal.values
4316
+ });
4317
+ });
4318
+ return () => {
4319
+ unsubscribe();
4320
+ }; /**/
4321
+ }, [formControl.store, setValue, formState.values, setFormState]);
4322
+ const handleNotification = React.useCallback(props => {
4323
+ if (props.message) {
4324
+ showNotification === null || showNotification === void 0 ? void 0 : showNotification(props);
4325
+ }
4326
+ }, [showNotification]);
4327
+ const filterFormData = React.useCallback((v, submitConfig) => {
4328
+ const keys = submitConfig.values;
4329
+ if (!keys || keys.length === 0) {
4330
+ return v;
4331
+ }
4332
+ const out = {};
4333
+ for (const key of keys) {
4334
+ if (key in v) {
4335
+ out[key] = v[key];
4336
+ }
4337
+ }
4338
+ return out;
4339
+ }, []);
4340
+ const processSubmit = React.useCallback(async (d, submitConfig_0) => {
4341
+ const filteredData = filterFormData(d, submitConfig_0);
4342
+ if (submitConfig_0.onSuccess) {
4343
+ return await submitConfig_0.onSuccess(filteredData);
4344
+ }
4345
+ throw new Error('No submit handler provided');
4346
+ }, [filterFormData]);
4347
+ const handleError = React.useCallback((error, submitConfig_1) => {
4348
+ if (submitConfig_1.onError) {
4349
+ submitConfig_1.onError(error);
4350
+ }
4351
+ 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;
4352
+ if (notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) {
4353
+ handleNotification(notificationProps);
4354
+ }
4355
+ }, [handleNotification, notification]);
4356
+ const createSubmitHandler = React.useCallback(submitConfig_2 => async dataSubmit => {
4357
+ try {
4358
+ const res = await processSubmit(trimObject(dataSubmit), submitConfig_2);
4359
+ 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;
4360
+ if (notificationProps_0 === null || notificationProps_0 === void 0 ? void 0 : notificationProps_0.message) {
4361
+ handleNotification(notificationProps_0);
4362
+ }
4363
+ return res;
4364
+ } catch (error_0) {
4365
+ handleError(error_0, submitConfig_2);
4366
+ throw error_0;
4367
+ }
4368
+ }, [processSubmit, notification, handleNotification, handleError]);
4369
+ const onInvalidHandle = React.useCallback((err, submitConfig_3) => {
4370
+ onInvalid === null || onInvalid === void 0 ? void 0 : onInvalid(err);
4371
+ handleError(new Error('invalidData'), submitConfig_3);
4372
+ }, [handleError, onInvalid]);
4373
+ const handlersRef = React.useRef({
4374
+ formControl,
4375
+ onInvalidHandle,
4376
+ createSubmitHandler,
4377
+ setValue: formControl.setFieldValue,
4378
+ trigger: formControl.validateField,
4379
+ onValuesChange
4380
+ });
4381
+ React.useEffect(() => {
4382
+ handlersRef.current.onInvalidHandle = onInvalidHandle;
4383
+ handlersRef.current.createSubmitHandler = createSubmitHandler;
4384
+ handlersRef.current.setValue = formControl.setFieldValue;
4385
+ handlersRef.current.trigger = formControl.validateField;
4386
+ handlersRef.current.onValuesChange = onValuesChange;
4387
+ }, [onInvalidHandle, createSubmitHandler, formControl, onValuesChange]);
4388
+ const fields = React.useMemo(() => data.map((item, index) => {
4389
+ var _a, _b;
4390
+ const staticItem = typeof item === 'function' ? null : item;
4391
+ return {
4392
+ index: (_a = staticItem === null || staticItem === void 0 ? void 0 : staticItem.index) !== null && _a !== void 0 ? _a : index,
4393
+ element: jsxRuntime.jsx(DynamicFieldItem, {
4394
+ item: item,
4395
+ form: formControl,
4396
+ globalErrorNs: globalErrorNs,
4397
+ formId: id
4398
+ }, (_b = staticItem === null || staticItem === void 0 ? void 0 : staticItem.name) !== null && _b !== void 0 ? _b : index),
4399
+ renderInFooter: !!(staticItem === null || staticItem === void 0 ? void 0 : staticItem.renderInFooter),
4400
+ renderInHeader: !!(staticItem === null || staticItem === void 0 ? void 0 : staticItem.renderInHeader)
4401
+ };
4402
+ }), [data, formControl, globalErrorNs, id]);
4403
+ const submits = React.useMemo(() => submit.map((submitConfig_4, index_0) => {
4404
+ return {
4405
+ index: submitConfig_4.index === undefined ? index_0 : submitConfig_4.index,
4406
+ element: jsxRuntime.jsx(SubmitItem, {
4407
+ item: submitConfig_4,
4408
+ index: index_0,
4409
+ handlersRef: handlersRef
4410
+ }, `submit-${index_0}`),
4411
+ renderInFooter: !!submitConfig_4.renderInFooter,
4412
+ renderInHeader: !!submitConfig_4.renderInHeader,
4413
+ isSubmit: true
4414
+ };
4415
+ }), [submit]);
4416
+ const elements = React.useMemo(() => fields.concat(submits), [fields, submits]);
4417
+ const formContents = React.useMemo(() => [...data, ...submit], [data, submit]);
4418
+ React.useEffect(() => {
4419
+ var _a_0, _b_0;
4420
+ (_b_0 = (_a_0 = handlersRef.current).onValuesChange) === null || _b_0 === void 0 ? void 0 : _b_0.call(_a_0, values, handlersRef.current.setValue);
4421
+ }, [values]);
4422
+ return {
4423
+ elements,
4424
+ formContents,
4425
+ errors,
4426
+ formValues: values,
4427
+ setValue
4428
+ };
4429
+ };// eslint-disable-next-line @typescript-eslint/no-explicit-any
4430
+ const FormManager = t0 => {
4431
+ const $ = compilerRuntime.c(29);
4432
+ const {
4433
+ data,
4434
+ defaultValues,
4435
+ onInvalid,
4436
+ submit: t1,
4437
+ ns,
4438
+ globalErrorNs,
4439
+ notification,
4440
+ formSettings,
4441
+ viewSettings,
4442
+ onValuesChange,
4443
+ id: t2
4444
+ } = t0;
4445
+ let t3;
4446
+ if ($[0] !== t1) {
4447
+ t3 = t1 === undefined ? [] : t1;
4448
+ $[0] = t1;
4449
+ $[1] = t3;
4450
+ } else {
4451
+ t3 = $[1];
4452
+ }
4453
+ const submit = t3;
4454
+ const id = t2 === undefined ? "form-manager" : t2;
4455
+ let t4;
4456
+ if ($[2] !== defaultValues || $[3] !== formSettings || $[4] !== id) {
4457
+ t4 = Object.assign(Object.assign({
4458
+ defaultValues
4459
+ }, formSettings), {
4460
+ formId: id
4461
+ });
4462
+ $[2] = defaultValues;
4463
+ $[3] = formSettings;
4464
+ $[4] = id;
4465
+ $[5] = t4;
4466
+ } else {
4467
+ t4 = $[5];
4468
+ }
4469
+ let t5;
4470
+ if ($[6] !== data || $[7] !== globalErrorNs || $[8] !== id || $[9] !== notification || $[10] !== ns || $[11] !== onInvalid || $[12] !== onValuesChange || $[13] !== submit || $[14] !== t4) {
4471
+ t5 = {
4472
+ data,
4473
+ globalErrorNs,
4474
+ notification,
4475
+ ns,
4476
+ onInvalid,
4477
+ submit,
4478
+ onValuesChange,
4479
+ id,
4480
+ formOptions: t4
4481
+ };
4482
+ $[6] = data;
4483
+ $[7] = globalErrorNs;
4484
+ $[8] = id;
4485
+ $[9] = notification;
4486
+ $[10] = ns;
4487
+ $[11] = onInvalid;
4488
+ $[12] = onValuesChange;
4489
+ $[13] = submit;
4490
+ $[14] = t4;
4491
+ $[15] = t5;
4492
+ } else {
4493
+ t5 = $[15];
4494
+ }
4495
+ const {
4496
+ elements: t6
4497
+ } = useFormManager(t5);
4498
+ let t7;
4499
+ if ($[16] !== t6) {
4500
+ t7 = t6 === undefined ? [] : t6;
4501
+ $[16] = t6;
4502
+ $[17] = t7;
4503
+ } else {
4504
+ t7 = $[17];
4505
+ }
4506
+ const elements = t7;
4507
+ let t8;
4508
+ if ($[18] !== elements) {
4509
+ t8 = elements.filter(_temp).sort(_temp2).map(_temp3);
4510
+ $[18] = elements;
4511
+ $[19] = t8;
4512
+ } else {
4513
+ t8 = $[19];
4514
+ }
4515
+ const render = t8;
4516
+ let t9;
4517
+ if ($[20] !== elements) {
4518
+ t9 = elements.filter(_temp4).sort(_temp5).map(_temp6);
4519
+ $[20] = elements;
4520
+ $[21] = t9;
4521
+ } else {
4522
+ t9 = $[21];
4523
+ }
4524
+ const renderSubmit = t9;
4525
+ const Container = (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.container) || DefaultFormContainer;
4526
+ const BodyContainer = (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.bodyContainer) || exports.DefaultContainer;
4527
+ const SubmitContainer = (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.submitContainer) || exports.DefaultContainer;
4528
+ let t10;
4529
+ if ($[22] !== BodyContainer || $[23] !== Container || $[24] !== SubmitContainer || $[25] !== render || $[26] !== renderSubmit || $[27] !== viewSettings) {
4530
+ t10 = jsxRuntime.jsxs(Container, Object.assign({}, (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.containerProps) || {}, {
4531
+ children: [jsxRuntime.jsx(BodyContainer, Object.assign({}, (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.bodyContainerProps) || {}, {
4532
+ children: render
4533
+ })), jsxRuntime.jsx(SubmitContainer, Object.assign({}, (viewSettings === null || viewSettings === void 0 ? void 0 : viewSettings.submitContainerProps) || {}, {
4534
+ children: renderSubmit
4535
+ }))]
4536
+ }));
4537
+ $[22] = BodyContainer;
4538
+ $[23] = Container;
4539
+ $[24] = SubmitContainer;
4540
+ $[25] = render;
4541
+ $[26] = renderSubmit;
4542
+ $[27] = viewSettings;
4543
+ $[28] = t10;
4544
+ } else {
4545
+ t10 = $[28];
4546
+ }
4547
+ return t10;
4548
+ };
4549
+ function _temp(el) {
4550
+ return !el.isSubmit;
4551
+ }
4552
+ function _temp2(a, b) {
4553
+ return a.index - b.index;
4554
+ }
4555
+ function _temp3(el_0) {
4556
+ return el_0.element;
4557
+ }
4558
+ function _temp4(el_1) {
4559
+ return el_1.isSubmit;
4560
+ }
4561
+ function _temp5(a_0, b_0) {
4562
+ return a_0.index - b_0.index;
4563
+ }
4564
+ function _temp6(el_2) {
4565
+ return el_2.element;
4566
+ }exports.DEFAULT_FORM_ENTRY=DEFAULT_FORM_ENTRY;exports.DefaultFormContainer=DefaultFormContainer;exports.FormField=FormField;exports.FormManager=FormManager;exports.createFormSelector=createFormSelector;exports.createScopeFormsAtom=createScopeFormsAtom;exports.formAtom=formAtom;exports.formConfigAtom=formConfigAtom;exports.getFormCompositeKey=getFormCompositeKey;exports.setDefaultFormContainer=setDefaultFormContainer;exports.useFormConfigReset=useFormConfigReset;exports.useFormConfigState=useFormConfigState;exports.useFormConfigValue=useFormConfigValue;exports.useFormManager=useFormManager;exports.useFormState=useFormState;exports.useFormValue=useFormValue;exports.useFormValues=useFormValues;exports.useJotaiForm=useJotaiForm;exports.useSetFormState=useSetFormState;//# sourceMappingURL=index.js.map