@lehnihon/bit-form 2.0.1 → 2.1.1

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 (66) hide show
  1. package/README.md +1 -0
  2. package/dist/angular/index.cjs +1 -1
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.d.cts +74 -37
  5. package/dist/angular/index.d.ts +74 -37
  6. package/dist/angular/index.js +1 -1
  7. package/dist/angular/index.js.map +1 -1
  8. package/dist/bus-C1xKmQdw.d.cts +144 -0
  9. package/dist/bus-C1xKmQdw.d.ts +144 -0
  10. package/dist/chunk-5JV3QKOT.js +2 -0
  11. package/dist/chunk-5JV3QKOT.js.map +1 -0
  12. package/dist/{chunk-VCHMCHED.cjs → chunk-CPFHKRLU.cjs} +2 -2
  13. package/dist/chunk-CPFHKRLU.cjs.map +1 -0
  14. package/dist/{chunk-4MPIKMTH.cjs → chunk-SIM4YIOW.cjs} +7 -7
  15. package/dist/chunk-SIM4YIOW.cjs.map +1 -0
  16. package/dist/chunk-XHZAMKSZ.js +133 -0
  17. package/dist/chunk-XHZAMKSZ.js.map +1 -0
  18. package/dist/devtools/bridge.cjs +1 -1
  19. package/dist/devtools/bridge.js +1 -1
  20. package/dist/devtools/index.cjs +1 -1
  21. package/dist/devtools/index.js +1 -1
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.d.cts +6 -24
  24. package/dist/index.d.ts +6 -24
  25. package/dist/index.js +1 -1
  26. package/dist/public-types-B3jU1R2E.d.cts +70 -0
  27. package/dist/public-types-By_9Weno.d.ts +70 -0
  28. package/dist/react/index.cjs +1 -1
  29. package/dist/react/index.cjs.map +1 -1
  30. package/dist/react/index.d.cts +31 -38
  31. package/dist/react/index.d.ts +31 -38
  32. package/dist/react/index.js +1 -1
  33. package/dist/react/index.js.map +1 -1
  34. package/dist/react-native/index.cjs +1 -1
  35. package/dist/react-native/index.cjs.map +1 -1
  36. package/dist/react-native/index.d.cts +15 -4
  37. package/dist/react-native/index.d.ts +15 -4
  38. package/dist/react-native/index.js +1 -1
  39. package/dist/react-native/index.js.map +1 -1
  40. package/dist/resolvers/joi.d.cts +1 -1
  41. package/dist/resolvers/joi.d.ts +1 -1
  42. package/dist/resolvers/yup.d.cts +1 -1
  43. package/dist/resolvers/yup.d.ts +1 -1
  44. package/dist/resolvers/zod.d.cts +1 -1
  45. package/dist/resolvers/zod.d.ts +1 -1
  46. package/dist/types-C2mpfhp1.d.cts +17 -0
  47. package/dist/types-C2mpfhp1.d.ts +17 -0
  48. package/dist/{use-bit-watch-CtdglHvd.d.cts → use-bit-watch-DVxSlp2A.d.ts} +92 -28
  49. package/dist/{use-bit-watch-B_ket_j5.d.ts → use-bit-watch-v4eamRCT.d.cts} +92 -28
  50. package/dist/vue/index.cjs +1 -1
  51. package/dist/vue/index.cjs.map +1 -1
  52. package/dist/vue/index.d.cts +74 -36
  53. package/dist/vue/index.d.ts +74 -36
  54. package/dist/vue/index.js +1 -1
  55. package/dist/vue/index.js.map +1 -1
  56. package/package.json +7 -2
  57. package/dist/bus-CnqfsZpc.d.cts +0 -286
  58. package/dist/bus-CnqfsZpc.d.ts +0 -286
  59. package/dist/chunk-4MPIKMTH.cjs.map +0 -1
  60. package/dist/chunk-OZOSKSJA.js +0 -2
  61. package/dist/chunk-OZOSKSJA.js.map +0 -1
  62. package/dist/chunk-VCHMCHED.cjs.map +0 -1
  63. package/dist/chunk-ZWLZ4XDF.js +0 -133
  64. package/dist/chunk-ZWLZ4XDF.js.map +0 -1
  65. package/dist/index-BAOM6INR.d.ts +0 -206
  66. package/dist/index-BdLuC0wS.d.cts +0 -206
@@ -1,286 +0,0 @@
1
- interface BitMask {
2
- format: (value: any) => string;
3
- parse: (value: string) => any;
4
- }
5
- interface PatternMaskOptions {
6
- allowChars?: string;
7
- customParse?: (value: string) => any;
8
- saveRaw?: boolean;
9
- guide?: boolean;
10
- placeholderChar?: string;
11
- }
12
- interface CurrencyMaskConfig {
13
- prefix?: string;
14
- suffix?: string;
15
- thousand: string;
16
- decimal: string;
17
- precision?: number;
18
- allowNegative?: boolean;
19
- saveRaw?: boolean;
20
- }
21
- interface DateMaskConfig extends PatternMaskOptions {
22
- format?: "DD/MM/YYYY" | "YYYY-MM-DD";
23
- }
24
-
25
- declare class BitDependencyManager<T extends object = any> {
26
- fieldConfigs: Map<string, BitFieldDefinition<T>>;
27
- dependencies: Map<string, Set<string>>;
28
- hiddenFields: Set<string>;
29
- register(path: string, config: BitFieldDefinition<T>, currentValues: T): void;
30
- isHidden(path: string): boolean;
31
- isRequired(path: string, values: T): boolean;
32
- getRequiredErrors(values: T): Record<string, string>;
33
- evaluateAll(values: T): void;
34
- updateDependencies(changedPath: string, newValues: T): string[];
35
- unregister(path: string): void;
36
- unregisterPrefix(prefix: string): void;
37
- private evaluateFieldCondition;
38
- private isEmpty;
39
- }
40
-
41
- declare class BitHistoryManager<T extends object = any> {
42
- private enableHistory;
43
- private maxHistory;
44
- private history;
45
- private historyIndex;
46
- constructor(enableHistory: boolean, maxHistory?: number);
47
- saveSnapshot(values: T): void;
48
- get canUndo(): boolean;
49
- get canRedo(): boolean;
50
- undo(): T | null;
51
- redo(): T | null;
52
- reset(initialValues: T): void;
53
- getMetadata(): {
54
- enabled: boolean;
55
- canUndo: boolean;
56
- canRedo: boolean;
57
- historyIndex: number;
58
- historySize: number;
59
- };
60
- }
61
-
62
- declare class BitValidationManager<T extends object> {
63
- private store;
64
- private validationTimeout?;
65
- private currentValidationId;
66
- private asyncTimers;
67
- private asyncRequests;
68
- asyncErrors: Record<string, string>;
69
- constructor(store: BitValidationAdapter<T>);
70
- handleAsync(path: string, value: any): void;
71
- trigger(scopeFields?: string[]): void;
72
- validate(options?: {
73
- scope?: string;
74
- scopeFields?: string[];
75
- }): Promise<boolean>;
76
- clear(path: string): void;
77
- cancelAll(): void;
78
- }
79
-
80
- /**
81
- * BitDirtyManager
82
- *
83
- * Manages dirty state tracking for form fields.
84
- * Tracks which fields have been modified from their initial values.
85
- */
86
- declare class BitDirtyManager<T extends object = any> {
87
- private dirtyPaths;
88
- /**
89
- * Updates dirty state for a single path change.
90
- * Automatically removes child paths when parent changes.
91
- * @returns true if any fields are dirty
92
- */
93
- updateForPath(path: string, values: T, initialValues: T): boolean;
94
- /**
95
- * Rebuilds dirty paths from full state comparison.
96
- * Used for undo/redo and bulk updates.
97
- * @returns true if any fields are dirty
98
- */
99
- rebuild(values: T, initialValues: T): boolean;
100
- /**
101
- * Clears all dirty tracking.
102
- * Used when resetting form or updating initial values.
103
- */
104
- clear(): void;
105
- /**
106
- * Returns current dirty state.
107
- */
108
- get isDirty(): boolean;
109
- /**
110
- * Returns readonly set of dirty paths (for debugging/devtools).
111
- */
112
- getDirtyPaths(): ReadonlySet<string>;
113
- /**
114
- * Builds a partial object containing only dirty values.
115
- * For arrays, returns the entire array if any index changed.
116
- * @param values - current form values (already cleaned/transformed)
117
- */
118
- buildDirtyValues<T extends object>(values: T): Partial<T>;
119
- private getNestedValue;
120
- private setNestedValue;
121
- }
122
-
123
- type DeepPartial<T> = T extends object ? {
124
- [P in keyof T]?: DeepPartial<T[P]>;
125
- } : T;
126
- type BitErrors<T> = {
127
- [key: string]: string | undefined;
128
- };
129
- type BitTouched<T> = {
130
- [key: string]: boolean | undefined;
131
- };
132
- type BitComputedFn<T> = (values: T) => any;
133
- type BitTransformFn<T> = (value: any, allValues: T) => any;
134
- interface BitState<T> {
135
- values: T;
136
- errors: BitErrors<T>;
137
- touched: BitTouched<T>;
138
- isValidating: Record<string, boolean>;
139
- isValid: boolean;
140
- isSubmitting: boolean;
141
- isDirty: boolean;
142
- }
143
- type ValidatorFn<T> = (values: T, options?: {
144
- scopeFields?: string[];
145
- }) => Promise<BitErrors<T>> | BitErrors<T>;
146
- /** Conditional logic: visibility and dynamic required. */
147
- interface BitFieldConditional<T extends object = any> {
148
- dependsOn?: string[];
149
- showIf?: (values: T) => boolean;
150
- requiredIf?: (values: T) => boolean;
151
- /** Custom message when field is required but empty. Fallback: "required field". */
152
- requiredMessage?: string;
153
- }
154
- /** Field-level validation: async validation only. */
155
- interface BitFieldValidation<T extends object = any> {
156
- asyncValidate?: (value: any, values: T) => Promise<string | null | undefined>;
157
- asyncValidateDelay?: number;
158
- }
159
- /** Full field definition: conditional, validation, transform, computed, mask, scope. */
160
- interface BitFieldDefinition<T extends object = any> {
161
- conditional?: BitFieldConditional<T>;
162
- validation?: BitFieldValidation<T>;
163
- transform?: BitTransformFn<T>;
164
- computed?: BitComputedFn<T>;
165
- /** Mask name (from registry) or BitMask instance. */
166
- mask?: BitMask | string;
167
- /** Scope name (e.g. wizard step). */
168
- scope?: string;
169
- }
170
- interface DevToolsOptions {
171
- enabled?: boolean;
172
- mode?: "local" | "remote";
173
- url?: string;
174
- }
175
- /** Validation config. */
176
- interface BitValidationConfig<T> {
177
- resolver?: ValidatorFn<T>;
178
- delay?: number;
179
- }
180
- /** History config. */
181
- interface BitHistoryConfig {
182
- enabled?: boolean;
183
- limit?: number;
184
- }
185
- /**
186
- * BitConfig - store configuration.
187
- * @see CHANGELOG for migration from features to fields in 2.0.
188
- */
189
- interface BitConfig<T extends object = any> {
190
- /** Core */
191
- name?: string;
192
- initialValues?: T;
193
- /** Central field config: conditional, validation, transform, computed, mask, scope. */
194
- fields?: Record<string, BitFieldDefinition<T>>;
195
- /** Schema-level validation */
196
- validation?: BitValidationConfig<T>;
197
- /** History (undo/redo) */
198
- history?: BitHistoryConfig;
199
- /** DevTools */
200
- devTools?: boolean | DevToolsOptions;
201
- }
202
- /** Internal config produced by normalizeConfig from BitConfig. */
203
- interface BitResolvedConfig<T extends object> {
204
- name?: string;
205
- initialValues: T;
206
- resolver?: ValidatorFn<T>;
207
- validationDelay: number;
208
- enableHistory: boolean;
209
- historyLimit: number;
210
- /** Derived from fields where field.computed exists. */
211
- computed?: Record<string, BitComputedFn<T>>;
212
- /** Derived from fields where field.transform exists. */
213
- transform?: Partial<Record<string, BitTransformFn<T>>>;
214
- /** Derived from fields where field.scope exists. */
215
- scopes?: Record<string, string[]>;
216
- masks?: Record<string, BitMask>;
217
- fields?: Record<string, BitFieldDefinition<T>>;
218
- devTools?: boolean | DevToolsOptions;
219
- }
220
- interface BitFieldOptions {
221
- mask?: BitMask | string;
222
- }
223
- /** Return type of BitStore.getStepStatus, used by useBitScope/injectBitScope. */
224
- interface ScopeStatus {
225
- hasErrors: boolean;
226
- isDirty: boolean;
227
- errors: Record<string, string>;
228
- }
229
- /** Return type of validateStep, used by useBitScope/injectBitScope. */
230
- interface ValidateScopeResult {
231
- valid: boolean;
232
- errors: Record<string, string>;
233
- }
234
- interface BitLifecycleAdapter<T extends object> {
235
- getState: () => BitState<T>;
236
- internalUpdateState: (partial: Partial<BitState<T>>) => void;
237
- internalSaveSnapshot: () => void;
238
- config: BitResolvedConfig<T>;
239
- depsMg: BitDependencyManager<T>;
240
- validatorMg: BitValidationManager<T>;
241
- historyMg: BitHistoryManager<T>;
242
- dirtyMg: BitDirtyManager<T>;
243
- }
244
- interface BitStoreAdapter<T extends object = any> {
245
- getState: () => BitState<T>;
246
- getConfig(): BitResolvedConfig<T>;
247
- setField(path: string, value: any): void;
248
- internalUpdateState(partialState: any): void;
249
- internalSaveSnapshot(): void;
250
- unregisterPrefix?: (prefix: string) => void;
251
- validate?: () => Promise<boolean>;
252
- dirtyMg: BitDirtyManager<T>;
253
- }
254
- interface BitValidationAdapter<T extends object> {
255
- getState: () => BitState<T>;
256
- internalUpdateState: (partial: Partial<BitState<T>>) => void;
257
- setError: (path: string, message: string | undefined) => void;
258
- config: BitResolvedConfig<T>;
259
- depsMg: BitDependencyManager<T>;
260
- }
261
- /**
262
- * Type-safe path utilities
263
- *
264
- * These are used to strengthen typing for field paths (e.g. "user.email", "items.0.name").
265
- */
266
- type Primitive = string | number | boolean | bigint | symbol | null | undefined;
267
- type BitPath<T, Prefix extends string = ""> = T extends Primitive ? never : T extends readonly (infer U)[] ? Prefix extends "" ? `${number}` | `${number}.${BitPath<U>}` : `${Prefix}.${number}` | `${Prefix}.${number}.${BitPath<U>}` : {
268
- [K in keyof T & (string | number)]: T[K] extends Primitive ? Prefix extends "" ? `${K & (string | number)}` : `${Prefix}.${K & (string | number)}` : Prefix extends "" ? `${K & (string | number)}` | `${K & (string | number)}.${BitPath<T[K]>}` : `${Prefix}.${K & (string | number)}` | `${Prefix}.${K & (string | number)}.${BitPath<T[K]>}`;
269
- }[keyof T & (string | number)];
270
- type BitPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends `${number}` ? T extends readonly (infer U)[] ? BitPathValue<U, Rest> : never : K extends keyof T ? BitPathValue<T[K], Rest> : never : P extends `${number}` ? T extends readonly (infer U)[] ? U : never : P extends keyof T ? T[P] : never;
271
- type BitArrayPath<T> = BitPath<T> extends infer P ? P extends string ? BitPathValue<T, P> extends readonly any[] ? P : never : never : never;
272
- type BitArrayItem<A> = A extends readonly (infer U)[] ? U : A extends (infer U)[] ? U : never;
273
-
274
- type BitBusListener = (storeId: string, newState: any) => void;
275
- interface BitFormGlobal {
276
- stores: Record<string, any>;
277
- listeners: Set<BitBusListener>;
278
- dispatch: (storeId: string, state: any) => void;
279
- subscribe: (fn: BitBusListener) => () => void;
280
- }
281
- declare global {
282
- var __BIT_FORM__: BitFormGlobal | undefined;
283
- }
284
- declare const bitBus: BitFormGlobal;
285
-
286
- export { BitHistoryManager as A, type BitResolvedConfig as B, type CurrencyMaskConfig as C, type DateMaskConfig as D, type PatternMaskOptions as P, type ScopeStatus as S, type ValidateScopeResult as V, type BitState as a, type BitPath as b, type BitPathValue as c, type BitErrors as d, type BitMask as e, type BitConfig as f, type BitArrayItem as g, type BitArrayPath as h, type BitComputedFn as i, type BitFieldConditional as j, type BitFieldDefinition as k, type BitFieldOptions as l, type BitFieldValidation as m, type BitHistoryConfig as n, type BitTouched as o, type BitTransformFn as p, type BitValidationConfig as q, type DeepPartial as r, type ValidatorFn as s, bitBus as t, type BitStoreAdapter as u, type BitLifecycleAdapter as v, BitDependencyManager as w, type BitValidationAdapter as x, BitValidationManager as y, BitDirtyManager as z };
@@ -1,286 +0,0 @@
1
- interface BitMask {
2
- format: (value: any) => string;
3
- parse: (value: string) => any;
4
- }
5
- interface PatternMaskOptions {
6
- allowChars?: string;
7
- customParse?: (value: string) => any;
8
- saveRaw?: boolean;
9
- guide?: boolean;
10
- placeholderChar?: string;
11
- }
12
- interface CurrencyMaskConfig {
13
- prefix?: string;
14
- suffix?: string;
15
- thousand: string;
16
- decimal: string;
17
- precision?: number;
18
- allowNegative?: boolean;
19
- saveRaw?: boolean;
20
- }
21
- interface DateMaskConfig extends PatternMaskOptions {
22
- format?: "DD/MM/YYYY" | "YYYY-MM-DD";
23
- }
24
-
25
- declare class BitDependencyManager<T extends object = any> {
26
- fieldConfigs: Map<string, BitFieldDefinition<T>>;
27
- dependencies: Map<string, Set<string>>;
28
- hiddenFields: Set<string>;
29
- register(path: string, config: BitFieldDefinition<T>, currentValues: T): void;
30
- isHidden(path: string): boolean;
31
- isRequired(path: string, values: T): boolean;
32
- getRequiredErrors(values: T): Record<string, string>;
33
- evaluateAll(values: T): void;
34
- updateDependencies(changedPath: string, newValues: T): string[];
35
- unregister(path: string): void;
36
- unregisterPrefix(prefix: string): void;
37
- private evaluateFieldCondition;
38
- private isEmpty;
39
- }
40
-
41
- declare class BitHistoryManager<T extends object = any> {
42
- private enableHistory;
43
- private maxHistory;
44
- private history;
45
- private historyIndex;
46
- constructor(enableHistory: boolean, maxHistory?: number);
47
- saveSnapshot(values: T): void;
48
- get canUndo(): boolean;
49
- get canRedo(): boolean;
50
- undo(): T | null;
51
- redo(): T | null;
52
- reset(initialValues: T): void;
53
- getMetadata(): {
54
- enabled: boolean;
55
- canUndo: boolean;
56
- canRedo: boolean;
57
- historyIndex: number;
58
- historySize: number;
59
- };
60
- }
61
-
62
- declare class BitValidationManager<T extends object> {
63
- private store;
64
- private validationTimeout?;
65
- private currentValidationId;
66
- private asyncTimers;
67
- private asyncRequests;
68
- asyncErrors: Record<string, string>;
69
- constructor(store: BitValidationAdapter<T>);
70
- handleAsync(path: string, value: any): void;
71
- trigger(scopeFields?: string[]): void;
72
- validate(options?: {
73
- scope?: string;
74
- scopeFields?: string[];
75
- }): Promise<boolean>;
76
- clear(path: string): void;
77
- cancelAll(): void;
78
- }
79
-
80
- /**
81
- * BitDirtyManager
82
- *
83
- * Manages dirty state tracking for form fields.
84
- * Tracks which fields have been modified from their initial values.
85
- */
86
- declare class BitDirtyManager<T extends object = any> {
87
- private dirtyPaths;
88
- /**
89
- * Updates dirty state for a single path change.
90
- * Automatically removes child paths when parent changes.
91
- * @returns true if any fields are dirty
92
- */
93
- updateForPath(path: string, values: T, initialValues: T): boolean;
94
- /**
95
- * Rebuilds dirty paths from full state comparison.
96
- * Used for undo/redo and bulk updates.
97
- * @returns true if any fields are dirty
98
- */
99
- rebuild(values: T, initialValues: T): boolean;
100
- /**
101
- * Clears all dirty tracking.
102
- * Used when resetting form or updating initial values.
103
- */
104
- clear(): void;
105
- /**
106
- * Returns current dirty state.
107
- */
108
- get isDirty(): boolean;
109
- /**
110
- * Returns readonly set of dirty paths (for debugging/devtools).
111
- */
112
- getDirtyPaths(): ReadonlySet<string>;
113
- /**
114
- * Builds a partial object containing only dirty values.
115
- * For arrays, returns the entire array if any index changed.
116
- * @param values - current form values (already cleaned/transformed)
117
- */
118
- buildDirtyValues<T extends object>(values: T): Partial<T>;
119
- private getNestedValue;
120
- private setNestedValue;
121
- }
122
-
123
- type DeepPartial<T> = T extends object ? {
124
- [P in keyof T]?: DeepPartial<T[P]>;
125
- } : T;
126
- type BitErrors<T> = {
127
- [key: string]: string | undefined;
128
- };
129
- type BitTouched<T> = {
130
- [key: string]: boolean | undefined;
131
- };
132
- type BitComputedFn<T> = (values: T) => any;
133
- type BitTransformFn<T> = (value: any, allValues: T) => any;
134
- interface BitState<T> {
135
- values: T;
136
- errors: BitErrors<T>;
137
- touched: BitTouched<T>;
138
- isValidating: Record<string, boolean>;
139
- isValid: boolean;
140
- isSubmitting: boolean;
141
- isDirty: boolean;
142
- }
143
- type ValidatorFn<T> = (values: T, options?: {
144
- scopeFields?: string[];
145
- }) => Promise<BitErrors<T>> | BitErrors<T>;
146
- /** Conditional logic: visibility and dynamic required. */
147
- interface BitFieldConditional<T extends object = any> {
148
- dependsOn?: string[];
149
- showIf?: (values: T) => boolean;
150
- requiredIf?: (values: T) => boolean;
151
- /** Custom message when field is required but empty. Fallback: "required field". */
152
- requiredMessage?: string;
153
- }
154
- /** Field-level validation: async validation only. */
155
- interface BitFieldValidation<T extends object = any> {
156
- asyncValidate?: (value: any, values: T) => Promise<string | null | undefined>;
157
- asyncValidateDelay?: number;
158
- }
159
- /** Full field definition: conditional, validation, transform, computed, mask, scope. */
160
- interface BitFieldDefinition<T extends object = any> {
161
- conditional?: BitFieldConditional<T>;
162
- validation?: BitFieldValidation<T>;
163
- transform?: BitTransformFn<T>;
164
- computed?: BitComputedFn<T>;
165
- /** Mask name (from registry) or BitMask instance. */
166
- mask?: BitMask | string;
167
- /** Scope name (e.g. wizard step). */
168
- scope?: string;
169
- }
170
- interface DevToolsOptions {
171
- enabled?: boolean;
172
- mode?: "local" | "remote";
173
- url?: string;
174
- }
175
- /** Validation config. */
176
- interface BitValidationConfig<T> {
177
- resolver?: ValidatorFn<T>;
178
- delay?: number;
179
- }
180
- /** History config. */
181
- interface BitHistoryConfig {
182
- enabled?: boolean;
183
- limit?: number;
184
- }
185
- /**
186
- * BitConfig - store configuration.
187
- * @see CHANGELOG for migration from features to fields in 2.0.
188
- */
189
- interface BitConfig<T extends object = any> {
190
- /** Core */
191
- name?: string;
192
- initialValues?: T;
193
- /** Central field config: conditional, validation, transform, computed, mask, scope. */
194
- fields?: Record<string, BitFieldDefinition<T>>;
195
- /** Schema-level validation */
196
- validation?: BitValidationConfig<T>;
197
- /** History (undo/redo) */
198
- history?: BitHistoryConfig;
199
- /** DevTools */
200
- devTools?: boolean | DevToolsOptions;
201
- }
202
- /** Internal config produced by normalizeConfig from BitConfig. */
203
- interface BitResolvedConfig<T extends object> {
204
- name?: string;
205
- initialValues: T;
206
- resolver?: ValidatorFn<T>;
207
- validationDelay: number;
208
- enableHistory: boolean;
209
- historyLimit: number;
210
- /** Derived from fields where field.computed exists. */
211
- computed?: Record<string, BitComputedFn<T>>;
212
- /** Derived from fields where field.transform exists. */
213
- transform?: Partial<Record<string, BitTransformFn<T>>>;
214
- /** Derived from fields where field.scope exists. */
215
- scopes?: Record<string, string[]>;
216
- masks?: Record<string, BitMask>;
217
- fields?: Record<string, BitFieldDefinition<T>>;
218
- devTools?: boolean | DevToolsOptions;
219
- }
220
- interface BitFieldOptions {
221
- mask?: BitMask | string;
222
- }
223
- /** Return type of BitStore.getStepStatus, used by useBitScope/injectBitScope. */
224
- interface ScopeStatus {
225
- hasErrors: boolean;
226
- isDirty: boolean;
227
- errors: Record<string, string>;
228
- }
229
- /** Return type of validateStep, used by useBitScope/injectBitScope. */
230
- interface ValidateScopeResult {
231
- valid: boolean;
232
- errors: Record<string, string>;
233
- }
234
- interface BitLifecycleAdapter<T extends object> {
235
- getState: () => BitState<T>;
236
- internalUpdateState: (partial: Partial<BitState<T>>) => void;
237
- internalSaveSnapshot: () => void;
238
- config: BitResolvedConfig<T>;
239
- depsMg: BitDependencyManager<T>;
240
- validatorMg: BitValidationManager<T>;
241
- historyMg: BitHistoryManager<T>;
242
- dirtyMg: BitDirtyManager<T>;
243
- }
244
- interface BitStoreAdapter<T extends object = any> {
245
- getState: () => BitState<T>;
246
- getConfig(): BitResolvedConfig<T>;
247
- setField(path: string, value: any): void;
248
- internalUpdateState(partialState: any): void;
249
- internalSaveSnapshot(): void;
250
- unregisterPrefix?: (prefix: string) => void;
251
- validate?: () => Promise<boolean>;
252
- dirtyMg: BitDirtyManager<T>;
253
- }
254
- interface BitValidationAdapter<T extends object> {
255
- getState: () => BitState<T>;
256
- internalUpdateState: (partial: Partial<BitState<T>>) => void;
257
- setError: (path: string, message: string | undefined) => void;
258
- config: BitResolvedConfig<T>;
259
- depsMg: BitDependencyManager<T>;
260
- }
261
- /**
262
- * Type-safe path utilities
263
- *
264
- * These are used to strengthen typing for field paths (e.g. "user.email", "items.0.name").
265
- */
266
- type Primitive = string | number | boolean | bigint | symbol | null | undefined;
267
- type BitPath<T, Prefix extends string = ""> = T extends Primitive ? never : T extends readonly (infer U)[] ? Prefix extends "" ? `${number}` | `${number}.${BitPath<U>}` : `${Prefix}.${number}` | `${Prefix}.${number}.${BitPath<U>}` : {
268
- [K in keyof T & (string | number)]: T[K] extends Primitive ? Prefix extends "" ? `${K & (string | number)}` : `${Prefix}.${K & (string | number)}` : Prefix extends "" ? `${K & (string | number)}` | `${K & (string | number)}.${BitPath<T[K]>}` : `${Prefix}.${K & (string | number)}` | `${Prefix}.${K & (string | number)}.${BitPath<T[K]>}`;
269
- }[keyof T & (string | number)];
270
- type BitPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends `${number}` ? T extends readonly (infer U)[] ? BitPathValue<U, Rest> : never : K extends keyof T ? BitPathValue<T[K], Rest> : never : P extends `${number}` ? T extends readonly (infer U)[] ? U : never : P extends keyof T ? T[P] : never;
271
- type BitArrayPath<T> = BitPath<T> extends infer P ? P extends string ? BitPathValue<T, P> extends readonly any[] ? P : never : never : never;
272
- type BitArrayItem<A> = A extends readonly (infer U)[] ? U : A extends (infer U)[] ? U : never;
273
-
274
- type BitBusListener = (storeId: string, newState: any) => void;
275
- interface BitFormGlobal {
276
- stores: Record<string, any>;
277
- listeners: Set<BitBusListener>;
278
- dispatch: (storeId: string, state: any) => void;
279
- subscribe: (fn: BitBusListener) => () => void;
280
- }
281
- declare global {
282
- var __BIT_FORM__: BitFormGlobal | undefined;
283
- }
284
- declare const bitBus: BitFormGlobal;
285
-
286
- export { BitHistoryManager as A, type BitResolvedConfig as B, type CurrencyMaskConfig as C, type DateMaskConfig as D, type PatternMaskOptions as P, type ScopeStatus as S, type ValidateScopeResult as V, type BitState as a, type BitPath as b, type BitPathValue as c, type BitErrors as d, type BitMask as e, type BitConfig as f, type BitArrayItem as g, type BitArrayPath as h, type BitComputedFn as i, type BitFieldConditional as j, type BitFieldDefinition as k, type BitFieldOptions as l, type BitFieldValidation as m, type BitHistoryConfig as n, type BitTouched as o, type BitTransformFn as p, type BitValidationConfig as q, type DeepPartial as r, type ValidatorFn as s, bitBus as t, type BitStoreAdapter as u, type BitLifecycleAdapter as v, BitDependencyManager as w, type BitValidationAdapter as x, BitValidationManager as y, BitDirtyManager as z };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/store/bus.ts","../src/core/utils.ts","../src/devtools/ui/styles.ts","../src/devtools/ui/index.ts","../src/devtools/init-dev-tools.ts"],"names":["rootGlobal","id","state","fn","bitBus","deepClone","obj","item","clone","key","valueEqual","a","b","deepEqual","keysA","keysB","collectDirtyPaths","initial","prefix","result","allKeys","k","p"],"mappings":"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","file":"/home/runner/work/bit-form/bit-form/dist/chunk-4MPIKMTH.cjs","sourcesContent":["export type BitBusListener = (storeId: string, newState: any) => void;\n\ninterface BitFormGlobal {\n stores: Record<string, any>;\n listeners: Set<BitBusListener>;\n dispatch: (storeId: string, state: any) => void;\n subscribe: (fn: BitBusListener) => () => void;\n}\n\ndeclare global {\n var __BIT_FORM__: BitFormGlobal | undefined;\n}\n\nconst rootGlobal =\n typeof globalThis !== \"undefined\"\n ? globalThis\n : ((typeof global !== \"undefined\" ? global : window) as any);\n\nif (!rootGlobal.__BIT_FORM__) {\n rootGlobal.__BIT_FORM__ = {\n stores: {},\n listeners: new Set<BitBusListener>(),\n\n dispatch(id: string, state: any) {\n this.listeners.forEach((fn: BitBusListener) => fn(id, state));\n },\n\n subscribe(fn: BitBusListener) {\n this.listeners.add(fn);\n return () => {\n this.listeners.delete(fn);\n };\n },\n };\n}\n\nexport const bitBus = rootGlobal.__BIT_FORM__ as BitFormGlobal;\n","export function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as any as T;\n }\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as any as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => deepClone(item)) as any as T;\n }\n\n const clone: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n clone[key] = deepClone((obj as any)[key]);\n }\n }\n return clone as T;\n}\n\n/**\n * Fast equality for single values. Uses === for primitives, deepEqual for objects/arrays.\n * Prefer over deepEqual when comparing a single field value (e.g. isFieldDirty, getStepStatus).\n */\nexport function valueEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (\n a === null ||\n typeof a !== \"object\" ||\n b === null ||\n typeof b !== \"object\"\n ) {\n return false;\n }\n return deepEqual(a, b);\n}\n\nexport function deepEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (\n a === null ||\n typeof a !== \"object\" ||\n b === null ||\n typeof b !== \"object\"\n ) {\n return false;\n }\n\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n if (a instanceof RegExp && b instanceof RegExp)\n return a.toString() === b.toString();\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(b, key) ||\n !deepEqual(a[key], b[key])\n ) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Collects all paths where obj differs from initial. Used to rebuild dirtyPaths after full state replacement.\n */\nexport function collectDirtyPaths(\n obj: any,\n initial: any,\n prefix = \"\",\n result: Set<string> = new Set(),\n): Set<string> {\n if (valueEqual(obj, initial)) return result;\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n initial === null ||\n typeof initial !== \"object\"\n ) {\n if (prefix) result.add(prefix);\n return result;\n }\n if (Array.isArray(obj) || Array.isArray(initial)) {\n if (!valueEqual(obj, initial) && prefix) result.add(prefix);\n return result;\n }\n const allKeys = new Set([\n ...Object.keys(obj || {}),\n ...Object.keys(initial || {}),\n ]);\n for (const k of allKeys) {\n const p = prefix ? `${prefix}.${k}` : k;\n collectDirtyPaths((obj as any)?.[k], (initial as any)?.[k], p, result);\n }\n return result;\n}\n\nconst pathCache = new Map<string, string[]>();\n\nexport function getDeepValue(obj: any, path: string): any {\n if (!path) return obj;\n\n const keys = pathCache.get(path) || path.split(\".\");\n if (!pathCache.has(path)) pathCache.set(path, keys);\n\n let current = obj;\n for (const key of keys) {\n if (current === null || current === undefined) return undefined;\n current = current[key];\n }\n return current;\n}\n\nexport function setDeepValue(obj: any, path: string, value: any): any {\n if (!path) return value;\n\n const keys = pathCache.get(path) || path.split(\".\");\n if (!pathCache.has(path)) pathCache.set(path, keys);\n\n const result = Array.isArray(obj) ? [...obj] : { ...obj };\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n const nextKey = keys[i + 1];\n\n const isNextNumeric = /^\\d+$/.test(nextKey);\n const currentValue = current[key];\n\n if (currentValue === null || currentValue === undefined) {\n current[key] = isNextNumeric ? [] : {};\n } else {\n current[key] = Array.isArray(currentValue)\n ? [...currentValue]\n : { ...currentValue };\n }\n\n current = current[key];\n }\n\n current[keys[keys.length - 1]] = value;\n\n return result;\n}\n\nexport function cleanPrefixedKeys(\n obj: Record<string, any>,\n prefix: string,\n): Record<string, any> {\n const newObj: Record<string, any> = {};\n const prefixWithDot = `${prefix}.`;\n\n for (const key in obj) {\n if (key !== prefix && !key.startsWith(prefixWithDot)) {\n newObj[key] = obj[key];\n }\n }\n return newObj;\n}\n\nexport const shiftKeys = (\n obj: Record<string, any>,\n path: string,\n removedIndex: number,\n) => {\n const newObj: Record<string, any> = {};\n const prefix = `${path}.`;\n\n Object.keys(obj).forEach((key) => {\n if (!key.startsWith(prefix)) {\n newObj[key] = obj[key];\n return;\n }\n const remaining = key.substring(prefix.length);\n const parts = remaining.split(\".\");\n const currentIdx = parseInt(parts[0], 10);\n const rest = parts.slice(1).join(\".\");\n\n if (currentIdx === removedIndex) return;\n\n if (currentIdx > removedIndex) {\n const newIdx = currentIdx - 1;\n const newKey = rest ? `${prefix}${newIdx}.${rest}` : `${prefix}${newIdx}`;\n newObj[newKey] = obj[key];\n } else {\n newObj[key] = obj[key];\n }\n });\n return newObj;\n};\n\nexport const swapKeys = (\n obj: Record<string, any>,\n path: string,\n indexA: number,\n indexB: number,\n) => {\n const newObj: Record<string, any> = {};\n const prefix = `${path}.`;\n\n Object.keys(obj).forEach((key) => {\n if (!key.startsWith(prefix)) {\n newObj[key] = obj[key];\n return;\n }\n const remaining = key.substring(prefix.length);\n const parts = remaining.split(\".\");\n const currentIdx = parseInt(parts[0], 10);\n const rest = parts.slice(1).join(\".\");\n\n if (currentIdx === indexA) {\n const newKey = rest ? `${prefix}${indexB}.${rest}` : `${prefix}${indexB}`;\n newObj[newKey] = obj[key];\n } else if (currentIdx === indexB) {\n const newKey = rest ? `${prefix}${indexA}.${rest}` : `${prefix}${indexA}`;\n newObj[newKey] = obj[key];\n } else {\n newObj[key] = obj[key];\n }\n });\n return newObj;\n};\n\nexport const moveKeys = (\n obj: Record<string, any>,\n path: string,\n from: number,\n to: number,\n) => {\n const newObj: Record<string, any> = {};\n const prefix = `${path}.`;\n\n Object.keys(obj).forEach((key) => {\n if (!key.startsWith(prefix)) {\n newObj[key] = obj[key];\n return;\n }\n const remaining = key.substring(prefix.length);\n const parts = remaining.split(\".\");\n const currentIdx = parseInt(parts[0], 10);\n const rest = parts.slice(1).join(\".\");\n\n let newIdx = currentIdx;\n if (currentIdx === from) {\n newIdx = to;\n } else if (from < to && currentIdx > from && currentIdx <= to) {\n newIdx = currentIdx - 1;\n } else if (from > to && currentIdx >= to && currentIdx < from) {\n newIdx = currentIdx + 1;\n }\n\n const newKey = rest ? `${prefix}${newIdx}.${rest}` : `${prefix}${newIdx}`;\n newObj[newKey] = obj[key];\n });\n return newObj;\n};\n\n/**\n * Checks if a value looks like a server validation error response.\n * Handles shapes like { email: \"Taken\" }, { errors: { email: [\"Taken\"] } }, etc.\n */\nexport function isValidationErrorShape(\n x: unknown,\n): x is Record<string, string | string[]> {\n if (typeof x !== \"object\" || x === null || Array.isArray(x)) return false;\n\n const obj = (x as Record<string, unknown>).errors ?? x;\n if (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) return false;\n\n return Object.values(obj as Record<string, unknown>).every(\n (v) =>\n typeof v === \"string\" ||\n (Array.isArray(v) && v.every((i) => typeof i === \"string\")),\n );\n}\n\n/**\n * Extracts server errors in the format expected by setServerErrors.\n */\nexport function extractServerErrors(\n x: unknown,\n): Record<string, string | string[]> {\n if (!isValidationErrorShape(x)) return {};\n\n const obj = (x as Record<string, unknown>).errors ?? x;\n return obj as Record<string, string | string[]>;\n}\n","export function getDevToolsCSS(): string {\n return `\n .bit-devtools-container {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 9999;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n .bit-devtools-trigger {\n background: #10b981;\n color: #fff;\n border: none;\n border-radius: 50%;\n width: 48px;\n height: 48px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);\n font-weight: bold;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s;\n font-size: 16px;\n margin-top: 16px;\n }\n .bit-devtools-trigger:hover { transform: scale(1.05); }\n\n .bit-devtools-panel {\n width: 450px;\n max-height: 80vh;\n background: #0f172a;\n color: #f8fafc;\n border-radius: 8px;\n padding: 16px;\n overflow-y: auto;\n box-shadow: 0 20px 25px -5px rgba(0,0,0,0.5), 0 8px 10px -6px rgba(0,0,0,0.5);\n border: 1px solid #334155;\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n\n .bit-devtools-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 12px;\n border-bottom: 1px solid #1e293b;\n }\n .bit-devtools-header h2 { margin: 0; font-size: 16px; display: flex; align-items: center; gap: 8px; }\n\n .bit-store-block {\n background: #1e293b;\n border-radius: 6px;\n padding: 12px;\n border: 1px solid #334155;\n }\n\n .bit-store-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n }\n .bit-store-title { margin: 0; color: #38bdf8; font-size: 14px; font-weight: bold; }\n\n .bit-badge-group { display: flex; gap: 6px; flex-wrap: wrap; }\n .bit-badge { font-size: 10px; padding: 2px 6px; border-radius: 4px; text-transform: uppercase; font-weight: bold; }\n .badge-success { background: rgba(16, 185, 129, 0.2); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.2); }\n .badge-error { background: rgba(239, 68, 68, 0.2); color: #f87171; border: 1px solid rgba(239, 68, 68, 0.2); }\n .badge-warn { background: rgba(245, 158, 11, 0.2); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.2); }\n .badge-info { background: rgba(56, 189, 248, 0.2); color: #7dd3fc; border: 1px solid rgba(56, 189, 248, 0.2); }\n\n .bit-section-title { font-size: 11px; color: #94a3b8; text-transform: uppercase; letter-spacing: 1px; margin: 12px 0 4px 0; display: block; }\n\n .bit-controls { display: flex; gap: 6px; margin-bottom: 12px; background: #0f172a; padding: 8px; border-radius: 6px; }\n .bit-action-btn { flex: 1; background: #334155; color: #e2e8f0; border: 1px solid #475569; padding: 6px 0; border-radius: 4px; cursor: pointer; font-size: 11px; display: flex; align-items: center; justify-content: center; gap: 4px; transition: all 0.2s; }\n .bit-action-btn:hover:not(:disabled) { background: #475569; }\n .bit-action-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .bit-btn-reset { color: #fca5a5; border-color: rgba(239,68,68,0.3); }\n .bit-btn-reset:hover { background: rgba(239,68,68,0.1) !important; }\n\n pre.bit-pre { background: #020617; padding: 10px; border-radius: 4px; font-size: 11px; overflow-x: auto; border: 1px solid #1e293b; margin: 0; color: #e2e8f0; }\n pre.bit-error-box { background: rgba(239, 68, 68, 0.05); padding: 10px; border-radius: 4px; font-size: 11px; border: 1px dashed #ef4444; color: #fca5a5; margin: 0; overflow-x: auto; }\n `;\n}\n","import { getDevToolsCSS } from \"./styles\";\nimport type { DevToolsActions } from \"../types\";\n\nexport type { DevToolsActions };\n\nexport class BitFormDevToolsUI {\n private container: HTMLElement;\n private actions: DevToolsActions;\n private rootElement: HTMLDivElement;\n private currentStoresState: Record<string, any> = {};\n private isOpen: boolean = false;\n\n constructor(container: HTMLElement, actions: DevToolsActions) {\n this.container = container;\n this.actions = actions;\n\n if (!document.getElementById(\"bit-devtools-styles\")) {\n const style = document.createElement(\"style\");\n style.id = \"bit-devtools-styles\";\n style.textContent = getDevToolsCSS();\n document.head.appendChild(style);\n }\n\n this.rootElement = document.createElement(\"div\");\n this.rootElement.className = \"bit-devtools-container\";\n this.container.appendChild(this.rootElement);\n\n this.rootElement.addEventListener(\"click\", (e) => {\n const target = e.target as HTMLElement;\n\n // Evento do botão flutuante\n if (target.closest(\".bit-devtools-trigger\")) {\n this.isOpen = !this.isOpen;\n this.render();\n return;\n }\n\n // Eventos dos botões de ação\n const btn = target.closest(\".bit-action-btn\");\n if (btn && !btn.hasAttribute(\"disabled\")) {\n const action = btn.getAttribute(\"data-action\");\n const storeId = btn.getAttribute(\"data-store\");\n\n if (action && storeId) {\n if (action === \"undo\") this.actions.onUndo(storeId);\n if (action === \"redo\") this.actions.onRedo(storeId);\n if (action === \"reset\") this.actions.onReset(storeId);\n }\n }\n });\n }\n\n public updateState(storesState: Record<string, any>) {\n this.currentStoresState = storesState;\n this.render();\n }\n\n private render() {\n const storeEntries = Object.entries(this.currentStoresState);\n if (storeEntries.length === 0) {\n this.rootElement.innerHTML = \"\";\n return;\n }\n\n let panelHtml = \"\";\n\n if (this.isOpen) {\n panelHtml = `\n <div class=\"bit-devtools-panel\">\n <div class=\"bit-devtools-header\">\n <h2><span style=\"font-size: 20px;\">🛠</span> Bit-Form DevTools</h2>\n <span style=\"font-size: 11px; color: #64748b;\">v1.0.0</span>\n </div>\n `;\n\n for (const [id, state] of storeEntries) {\n const hasErrors = Object.keys(state.errors || {}).length > 0;\n\n // Lemos os metadados do histórico que o adaptador injetou\n const meta = state._meta || {\n totalSteps: 0,\n currentIndex: -1,\n canUndo: false,\n canRedo: false,\n };\n const currentStep = meta.currentIndex + 1;\n const totalSteps = meta.totalSteps;\n\n panelHtml += `\n <div class=\"bit-store-block\">\n <div class=\"bit-store-header\">\n <h3 class=\"bit-store-title\">${id}</h3>\n <div class=\"bit-badge-group\">\n <span class=\"bit-badge ${state.isValid ? \"badge-success\" : \"badge-error\"}\">\n ${state.isValid ? \"✓ Valid\" : \"✕ Invalid\"}\n </span>\n ${state.isDirty ? `<span class=\"bit-badge badge-warn\">Dirty</span>` : \"\"}\n ${state.isSubmitting ? `<span class=\"bit-badge badge-info\">⏳ Submitting</span>` : \"\"}\n </div>\n </div>\n\n <span class=\"bit-section-title\">Time Travel (${currentStep}/${totalSteps})</span>\n \n <div class=\"bit-controls\">\n <button class=\"bit-action-btn\" data-action=\"undo\" data-store=\"${id}\" ${meta.canUndo ? \"\" : \"disabled\"}>\n <span>↺</span> Undo\n </button>\n <button class=\"bit-action-btn\" data-action=\"redo\" data-store=\"${id}\" ${meta.canRedo ? \"\" : \"disabled\"}>\n <span>↻</span> Redo\n </button>\n <button class=\"bit-action-btn bit-btn-reset\" data-action=\"reset\" data-store=\"${id}\">\n <span>🗑</span> Reset\n </button>\n </div>\n `;\n\n if (hasErrors) {\n panelHtml += `\n <span class=\"bit-section-title\" style=\"color: #f87171;\">⚠️ Validations Failing</span>\n <pre class=\"bit-error-box\">${JSON.stringify(state.errors, null, 2)}</pre>\n `;\n }\n\n panelHtml += `\n <span class=\"bit-section-title\">Values</span>\n <pre class=\"bit-pre\">${JSON.stringify(state.values, null, 2)}</pre>\n </div>\n `;\n }\n\n panelHtml += `</div>`;\n }\n\n // Botão Flutuante (sempre renderizado)\n const triggerHtml = `\n <button class=\"bit-devtools-trigger\" style=\"transform: ${this.isOpen ? \"scale(0.9)\" : \"scale(1)\"};\" title=\"Abrir DevTools\">\n ${this.isOpen ? \"✖\" : \"Bit\"}\n </button>\n `;\n\n this.rootElement.innerHTML = panelHtml + triggerHtml;\n }\n}\n","import { setupLocalDevTools } from \"./adapters/local\";\nimport { setupRemoteDevTools } from \"./adapters/remote\";\nimport type { BitDevToolsOptions } from \"./types\";\n\nexport type { BitDevToolsOptions };\n\nexport function initDevTools(options: BitDevToolsOptions = {}) {\n const { mode = \"local\", url } = options;\n let containerEl: HTMLElement;\n\n let isAutoCreated = false;\n\n if (typeof options.container === \"string\") {\n const el = document.querySelector<HTMLElement>(options.container);\n if (!el)\n throw new Error(\n `[bit-form] Container '${options.container}' não encontrado na página.`,\n );\n containerEl = el;\n } else if (options.container instanceof HTMLElement) {\n containerEl = options.container;\n } else {\n containerEl = document.createElement(\"div\");\n containerEl.id = \"bit-form-devtools-root\";\n containerEl.style.position = \"fixed\";\n containerEl.style.bottom = \"20px\";\n containerEl.style.right = \"20px\";\n containerEl.style.zIndex = \"9999\";\n containerEl.style.maxHeight = \"80vh\";\n containerEl.style.overflowY = \"auto\";\n containerEl.style.boxShadow = \"0 10px 25px rgba(0,0,0,0.1)\";\n document.body.appendChild(containerEl);\n isAutoCreated = true;\n }\n\n let adapterInstance: any;\n\n if (mode === \"local\") {\n console.log(\"[bit-form] DevTools iniciado em modo Local.\");\n adapterInstance = setupLocalDevTools(containerEl);\n } else if (mode === \"remote\") {\n console.log(\"[bit-form] DevTools iniciado em modo Remote.\");\n adapterInstance = setupRemoteDevTools(containerEl, url);\n } else {\n throw new Error(`[bit-form] Modo DevTools inválido: ${mode}`);\n }\n\n return {\n ...adapterInstance,\n destroy: () => {\n if (adapterInstance && typeof adapterInstance.destroy === \"function\") {\n adapterInstance.destroy();\n }\n\n if (isAutoCreated && containerEl.parentNode) {\n containerEl.parentNode.removeChild(containerEl);\n } else {\n containerEl.innerHTML = \"\";\n }\n },\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- import{d as T,e as B,h as I,i as x}from"./chunk-ZWLZ4XDF.js";import{createContext as M,useContext as A}from"react";import{jsx as O}from"react/jsx-runtime";var D=M(null),st=({store:t,children:e})=>O(D.Provider,{value:t,children:e}),b=()=>{let t=A(D);if(!t)throw new Error("BitForm hooks devem ser usados dentro de um BitFormProvider");return t};import{useCallback as y,useSyncExternalStore as q,useMemo as H,useRef as L,useState as R}from"react";function lt(){let t=b(),[e,r]=R(null),[i,a]=R(null),o=L(null),g=y(()=>{let m=t.getState(),d={isValid:m.isValid,isDirty:m.isDirty,isSubmitting:m.isSubmitting};return o.current&&o.current.isValid===d.isValid&&o.current.isDirty===d.isDirty&&o.current.isSubmitting===d.isSubmitting?o.current:(o.current=d,d)},[t]),l=q(t.subscribe.bind(t),g,g),s=y(m=>d=>(d?.preventDefault?.(),t.submit(m)),[t]),n=y(m=>d=>(d?.preventDefault?.(),r(null),t.submit(async(j,C)=>{try{let f=await m(j,C);a(f),r(null)}catch(f){I(f)?t.setServerErrors(x(f)):r(f instanceof Error?f:new Error(String(f)))}})),[t]),S=y(()=>{t.reset(),r(null),a(null)},[t]),u=y(()=>t.getState().values,[t]),p=y(()=>t.getState().errors,[t]),h=y(()=>t.getState().touched,[t]),v=y(()=>t.getDirtyValues(),[t]);return{meta:H(()=>({...l,submitError:e,lastResponse:i}),[l,e,i]),getValues:u,getErrors:p,getTouched:h,getDirtyValues:v,submit:s,onSubmit:n,reset:S,setField:t.setField.bind(t),blurField:t.blurField.bind(t),setValues:t.setValues.bind(t),setError:t.setError.bind(t),setErrors:t.setErrors.bind(t),setServerErrors:t.setServerErrors.bind(t),validate:t.validate.bind(t),mutations:{pushItem:t.pushItem.bind(t),removeItem:t.removeItem.bind(t),prependItem:t.prependItem.bind(t),insertItem:t.insertItem.bind(t),moveItem:t.moveItem.bind(t),swapItems:t.swapItems.bind(t)}}}import{useCallback as U,useSyncExternalStore as W,useState as _,useMemo as w,useEffect as $}from"react";var P=()=>Math.random().toString(36).substring(2,9);function ft(t){let e=b(),r=U(()=>{let s=e.getState(),n=B(s.values,t);return Array.isArray(n)?n:[]},[e,t]),i=W(e.subscribe.bind(e),r,r),[a,o]=_(()=>i.map(P));$(()=>{i.length!==a.length&&o(s=>{if(i.length>s.length){let n=i.length-s.length;return[...s,...Array(n).fill(null).map(P)]}return s.slice(0,i.length)})},[i.length]);let g=w(()=>({append:s=>{o(n=>[...n,P()]),e.pushItem(t,s)},prepend:s=>{o(n=>[P(),...n]),e.prependItem(t,s)},insert:(s,n)=>{o(S=>{let u=[...S];return u.splice(s,0,P()),u}),e.insertItem(t,s,n)},remove:s=>{o(n=>n.filter((S,u)=>u!==s)),e.removeItem(t,s)},move:(s,n)=>{o(S=>{let u=[...S],[p]=u.splice(s,1);return u.splice(n,0,p),u}),e.moveItem(t,s,n)},swap:(s,n)=>{o(S=>{let u=[...S];return[u[s],u[n]]=[u[n],u[s]],u}),e.swapItems(t,s,n)},replace:s=>{o(s.map(P)),e.setField(t,s)},clear:()=>{o([]),e.setField(t,[])}}),[e,t]);return{fields:w(()=>i.map((s,n)=>({key:a[n]||`temp-${n}`,value:s,index:n})),[i,a]),length:i.length,...g}}import{useCallback as E,useSyncExternalStore as z,useRef as G}from"react";function Pt(t){let e=b(),r=G(null),i=E(()=>{let l=e.getStepStatus(t);return r.current&&r.current.hasErrors===l.hasErrors&&r.current.isDirty===l.isDirty&&Object.keys(r.current.errors).length===Object.keys(l.errors).length&&Object.entries(l.errors).every(([s,n])=>r.current.errors[s]===n)?r.current:(r.current=l,l)},[e,t]),a=z(e.subscribe.bind(e),i,i),o=E(async()=>{let l=await e.validate({scope:t}),s=e.getStepErrors(t);return{valid:l,errors:s}},[e,t]),g=E(()=>e.getStepErrors(t),[e,t]);return{scopeName:t,status:a,errors:a.errors,validate:o,getErrors:g,isValid:!a.hasErrors,isDirty:a.isDirty}}import{useCallback as F,useSyncExternalStore as J,useRef as K,useState as Q}from"react";function Tt(t){let e=b(),[r,i]=Q(0),a=t[r]??"",o=K(null),g=F(()=>{let c=e.getStepStatus(a);return o.current&&o.current.hasErrors===c.hasErrors&&o.current.isDirty===c.isDirty&&Object.keys(o.current.errors).length===Object.keys(c.errors).length&&Object.entries(c.errors).every(([m,d])=>o.current.errors[m]===d)?o.current:(o.current=c,c)},[e,a]),l=J(e.subscribe.bind(e),g,g),s=F(async()=>{let c=await e.validate({scope:a}),m=e.getStepErrors(a);return{valid:c,errors:m}},[e,a]),n=F(()=>e.getStepErrors(a),[e,a]),S=F(async()=>{let c=await e.validate({scope:a});if(c)i(m=>Math.min(m+1,t.length-1));else{let m=e.getStepErrors(a),d=Object.keys(m);d.length>0&&e.markFieldsTouched(d)}return c},[e,a,t.length]),u=F(()=>{i(c=>Math.max(c-1,0))},[]),p=F(c=>{i(Math.max(0,Math.min(c-1,t.length-1)))},[t.length]),h=r===0,v=r>=t.length-1;return{step:r+1,stepIndex:r,scope:a,next:S,prev:u,goTo:p,isFirst:h,isLast:v,status:l,errors:l.errors,isValid:!l.hasErrors,isDirty:l.isDirty,validate:s,getErrors:n}}import{useCallback as k,useSyncExternalStore as X,useRef as Y}from"react";function jt(t){let e=b(),r=Y(null),i=k(()=>{let o=B(e.getState().values,t);return r.current!==null&&T(r.current,o)?r.current:(r.current=o,o)},[e,t]),a=k(o=>e.subscribe(o),[e]);return X(a,i,i)}import{useCallback as V,useSyncExternalStore as Z,useRef as N,useEffect as tt}from"react";function Ut(t,e){let r=b(),i=N(null);tt(()=>(e&&r.registerField(t,e),()=>{r.unregisterField&&r.unregisterField(t)}),[r,t,e]);let a=V(()=>{let n=r.getState(),S=B(n.values,t),u=n.errors[t],p=!!n.touched[t],h=r.isHidden(t),v=r.isRequired(t),c=r.isFieldDirty(t),m=r.isFieldValidating(t);if(i.current&&i.current.value===S&&i.current.error===u&&i.current.touched===p&&i.current.isHidden===h&&i.current.isRequired===v&&i.current.isDirty===c&&i.current.isValidating===m)return i.current;let d={value:S,error:u,touched:p,isHidden:h,isRequired:v,isDirty:c,isValidating:m};return i.current=d,d},[r,t]),o=V(n=>r.subscribe(n),[r]),g=Z(o,a,a),l=V(n=>r.setField(t,n),[r,t]),s=V(()=>r.blurField(t),[r,t]);return{fieldState:g,setValue:l,setBlur:s,store:r}}export{st as a,b,lt as c,Ut as d,ft as e,Pt as f,Tt as g,jt as h};
2
- //# sourceMappingURL=chunk-OZOSKSJA.js.map