@rilaykit/core 2.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -5,135 +5,88 @@ import { z } from 'zod';
5
5
  * Main configuration class for Rilay form components and workflows
6
6
  * Manages component registration, retrieval, and configuration
7
7
  */
8
- declare class ril {
8
+ declare class ril<C> {
9
9
  private components;
10
10
  private formRenderConfig;
11
11
  private workflowRenderConfig;
12
- static create(): ril;
12
+ static create<CT>(): ril<CT>;
13
13
  /**
14
14
  * Add a component to the configuration
15
15
  * @param type - The component type (e.g., 'text', 'email', 'heading'), used as a unique identifier.
16
16
  * @param config - Component configuration without id and type
17
17
  * @returns The ril instance for chaining
18
18
  */
19
- addComponent<TProps = any>(type: string, config: Omit<ComponentConfig<TProps>, 'id' | 'type'>): this;
20
- /**
21
- * Generic method to set any renderer type easily
22
- * @param rendererType - The type of renderer to set
23
- * @param renderer - The renderer function
24
- * @returns The ril instance for chaining
25
- */
26
- setRenderer<T extends keyof (FormRenderConfig & WorkflowRenderConfig)>(rendererType: T, renderer: (FormRenderConfig & WorkflowRenderConfig)[T]): this;
27
- /**
28
- * Set multiple renderers at once
29
- * @param renderers - Object with renderer configurations
30
- * @returns The ril instance for chaining
31
- */
32
- setRenderers(renderers: Partial<FormRenderConfig & WorkflowRenderConfig>): this;
33
- /**
34
- * Set custom row renderer
35
- * @param renderer - Custom row renderer function
36
- * @returns The ril instance for chaining
37
- */
38
- setRowRenderer(renderer: FormRowRenderer): this;
39
- /**
40
- * Set custom body renderer
41
- * @param renderer - Custom body renderer function
42
- * @returns The ril instance for chaining
43
- */
44
- setBodyRenderer(renderer: FormBodyRenderer): this;
45
- /**
46
- * Set custom submit button renderer
47
- * @param renderer - Custom submit button renderer function
48
- * @returns The ril instance for chaining
49
- */
50
- setSubmitButtonRenderer(renderer: FormSubmitButtonRenderer): this;
51
- /**
52
- * Set custom field renderer
53
- * @param renderer - Custom field renderer function
54
- * @returns The ril instance for chaining
55
- */
56
- setFieldRenderer(renderer: FieldRenderer): this;
57
- /**
58
- * Set complete form render configuration
59
- * @param config - Form render configuration
60
- * @returns The ril instance for chaining
61
- */
62
- setFormRenderConfig(config: FormRenderConfig): this;
63
- /**
64
- * Get current form render configuration
65
- * @returns Current form render configuration
19
+ addComponent<NewType extends string, TProps = any>(type: NewType, config: Omit<ComponentConfig<TProps>, 'id' | 'type'>): ril<C & {
20
+ [K in NewType]: TProps;
21
+ }>;
22
+ /**
23
+ * Universal configuration method for all renderer types
24
+ *
25
+ * This method provides a unified API to configure both form and workflow renderers
26
+ * in a single call, automatically categorizing and applying the appropriate configurations.
27
+ *
28
+ * @param config - Configuration object containing renderer settings
29
+ * @param config.rowRenderer - Custom renderer for form rows (form-specific)
30
+ * @param config.bodyRenderer - Custom renderer for form body container (form-specific)
31
+ * @param config.submitButtonRenderer - Custom renderer for form submit buttons (form-specific)
32
+ * @param config.fieldRenderer - Custom renderer for individual form fields (form-specific)
33
+ * @param config.stepperRenderer - Custom renderer for workflow step navigation (workflow-specific)
34
+ * @param config.nextButtonRenderer - Custom renderer for workflow next buttons (workflow-specific)
35
+ * @param config.previousButtonRenderer - Custom renderer for workflow previous buttons (workflow-specific)
36
+ * @param config.skipButtonRenderer - Custom renderer for workflow skip buttons (workflow-specific)
37
+ *
38
+ * @returns The ril instance for method chaining
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Configure form renderers only
43
+ * const config = ril.create()
44
+ * .configure({
45
+ * rowRenderer: CustomRowRenderer,
46
+ * submitButtonRenderer: CustomSubmitButton
47
+ * });
48
+ *
49
+ * // Configure workflow renderers only
50
+ * const config = ril.create()
51
+ * .configure({
52
+ * stepperRenderer: CustomStepper,
53
+ * nextButtonRenderer: CustomNextButton
54
+ * });
55
+ *
56
+ * // Configure both form and workflow renderers
57
+ * const config = ril.create()
58
+ * .configure({
59
+ * // Form renderers
60
+ * rowRenderer: CustomRowRenderer,
61
+ * fieldRenderer: CustomFieldRenderer,
62
+ * // Workflow renderers
63
+ * stepperRenderer: CustomStepper,
64
+ * nextButtonRenderer: CustomNextButton
65
+ * });
66
+ * ```
67
+ *
68
+ * @remarks
69
+ * - Renderers are automatically categorized into form or workflow configurations
70
+ * - Existing configurations are merged, not replaced entirely
71
+ * - Invalid renderer keys are silently ignored
72
+ * - This method replaces individual setter methods for better DX
73
+ */
74
+ configure(config: Partial<FormRenderConfig & WorkflowRenderConfig>): this;
75
+ /**
76
+ * Configuration getters
66
77
  */
67
78
  getFormRenderConfig(): FormRenderConfig;
68
- /**
69
- * Set custom stepper renderer for workflows
70
- * @param renderer - Custom stepper renderer function
71
- * @returns The ril instance for chaining
72
- */
73
- setStepperRenderer(renderer: WorkflowStepperRenderer): this;
74
- /**
75
- * Set custom workflow next button renderer
76
- * @param renderer - Custom workflow next button renderer function
77
- * @returns The ril instance for chaining
78
- */
79
- setWorkflowNextButtonRenderer(renderer: WorkflowNextButtonRenderer): this;
80
- /**
81
- * Set custom workflow previous button renderer
82
- * @param renderer - Custom workflow previous button renderer function
83
- * @returns The ril instance for chaining
84
- */
85
- setWorkflowPreviousButtonRenderer(renderer: WorkflowPreviousButtonRenderer): this;
86
- /**
87
- * Set custom workflow skip button renderer
88
- * @param renderer - Custom workflow skip button renderer function
89
- * @returns The ril instance for chaining
90
- */
91
- setWorkflowSkipButtonRenderer(renderer: WorkflowSkipButtonRenderer): this;
92
- /**
93
- * Set complete workflow render configuration
94
- * @param config - Workflow render configuration
95
- * @returns The ril instance for chaining
96
- */
97
- setWorkflowRenderConfig(config: WorkflowRenderConfig): this;
98
- /**
99
- * Get current workflow render configuration
100
- * @returns Current workflow render configuration
101
- */
102
79
  getWorkflowRenderConfig(): WorkflowRenderConfig;
103
80
  /**
104
- * @deprecated Use setFormRenderConfig() instead
105
- */
106
- setRenderConfig(config: FormRenderConfig): this;
107
- /**
108
- * Get a component by its ID
109
- * @param id - Component ID (which is its type)
110
- * @returns Component configuration or undefined
111
- */
112
- getComponent(id: string): ComponentConfig | undefined;
113
- /**
114
- * List all registered components
115
- * @returns Array of all components
81
+ * Component management methods
116
82
  */
83
+ getComponent<T extends keyof C & string>(id: T): ComponentConfig<C[T]> | undefined;
117
84
  getAllComponents(): ComponentConfig[];
118
- /**
119
- * Check if a component exists
120
- * @param id - Component ID
121
- * @returns True if component exists
122
- */
123
85
  hasComponent(id: string): boolean;
124
- /**
125
- * Remove a component from the configuration
126
- * @param id - Component ID
127
- * @returns True if component was removed
128
- */
129
86
  removeComponent(id: string): boolean;
130
- /**
131
- * Clear all components
132
- */
133
87
  clear(): void;
134
88
  /**
135
- * Get statistics about registered components and renderers
136
- * @returns Object with comprehensive statistics
89
+ * Enhanced statistics with more detailed information
137
90
  */
138
91
  getStats(): {
139
92
  total: number;
@@ -150,8 +103,7 @@ declare class ril {
150
103
  };
151
104
  };
152
105
  /**
153
- * Validate the configuration
154
- * @returns Array of validation errors
106
+ * Enhanced validation using shared utilities
155
107
  */
156
108
  validate(): string[];
157
109
  }
@@ -418,10 +370,10 @@ interface FormRenderConfig {
418
370
  readonly submitButtonRenderer?: FormSubmitButtonRenderer;
419
371
  readonly fieldRenderer?: FieldRenderer;
420
372
  }
421
- interface FormConfiguration {
373
+ interface FormConfiguration<C extends Record<string, any> = Record<string, never>> {
422
374
  readonly id: string;
423
375
  readonly schema?: any;
424
- readonly config: ril;
376
+ readonly config: ril<C>;
425
377
  readonly rows: FormFieldRow[];
426
378
  readonly allFields: FormFieldConfig[];
427
379
  readonly renderConfig?: FormRenderConfig;
@@ -464,7 +416,61 @@ type WorkflowPreviousButtonRenderer = (props: WorkflowPreviousButtonRendererProp
464
416
  type WorkflowSkipButtonRenderer = (props: WorkflowSkipButtonRendererProps) => React.ReactElement;
465
417
 
466
418
  /**
467
- * Create a Zod-based validator
419
+ * Utility for merging partial configurations into existing objects
420
+ * Eliminates repetitive object spread operations
421
+ */
422
+ declare function mergeInto<T>(target: T, partial: Partial<T>): T;
423
+ /**
424
+ * Validates uniqueness of identifiers and throws descriptive errors
425
+ */
426
+ declare function ensureUnique(ids: string[], entityName: string): void;
427
+ /**
428
+ * Validates required fields exist in configurations
429
+ */
430
+ declare function validateRequired<T>(items: T[], requiredFields: (keyof T)[], entityName: string): void;
431
+ /**
432
+ * Auto-generates IDs when not provided
433
+ */
434
+ declare class IdGenerator {
435
+ private counters;
436
+ next(prefix: string): string;
437
+ reset(prefix?: string): void;
438
+ }
439
+ /**
440
+ * Validation error builder for consistent error handling
441
+ */
442
+ declare class ValidationErrorBuilder {
443
+ private errors;
444
+ add(code: string, message: string, path?: string[]): this;
445
+ addIf(condition: boolean, code: string, message: string, path?: string[]): this;
446
+ build(): ValidationError[];
447
+ hasErrors(): boolean;
448
+ clear(): this;
449
+ }
450
+ /**
451
+ * Common validation patterns
452
+ */
453
+ declare const ValidationPatterns: {
454
+ hasValue: (value: any) => boolean;
455
+ isArray: (value: any) => value is any[];
456
+ arrayMinLength: (value: any[], min: number) => boolean;
457
+ arrayMaxLength: (value: any[], max: number) => boolean;
458
+ };
459
+ /**
460
+ * Polymorphic helper for handling single items or arrays
461
+ */
462
+ declare function normalizeToArray<T>(input: T | T[]): T[];
463
+ /**
464
+ * Deep clone utility for configuration objects
465
+ */
466
+ declare function deepClone<T>(obj: T): T;
467
+ /**
468
+ * Generic configuration merger with type safety
469
+ */
470
+ declare function configureObject<T>(target: T, updates: Partial<T>, allowedKeys?: (keyof T)[]): T;
471
+
472
+ /**
473
+ * Create a `Zod`-based validator
468
474
  * @param schema - Zod schema to validate against
469
475
  * @returns Validator function
470
476
  */
@@ -626,4 +632,4 @@ declare const persistence: {
626
632
  */
627
633
  declare function createResilientPersistence(primary: PersistenceAdapter, fallback?: PersistenceAdapter, options?: Partial<PersistenceConfig>): PersistenceConfig;
628
634
 
629
- export { type CompletionConfig, type ComponentConfig, type ComponentRenderProps, type ComponentRenderer, CompositeAdapter, type ConditionalConfig, type CustomStepRenderer, type DynamicStepConfig, type FieldRenderer, type FieldRendererProps, type FormBodyRenderer, type FormBodyRendererProps, type FormConfiguration, type FormFieldConfig, type FormFieldRow, type FormRenderConfig, type FormRowRenderer, type FormRowRendererProps, type FormSubmitButtonRenderer, type FormSubmitButtonRendererProps, LocalStorageAdapter, MemoryAdapter, type NavigationConfig, type PersistenceAdapter, type PersistenceConfig, type RendererChildrenFunction, type RetryPolicy, type RilayLicenseConfig, SessionStorageAdapter, type StepConditionalConfig, type StepConfig, type StepLifecycleHooks, type StepPermissions, type StepValidationConfig, type ValidationConfig, type ValidationContext, type ValidationError, type ValidationResult, type ValidatorFunction, type WorkflowAnalytics, type WorkflowConfig, type WorkflowContext, type WorkflowHooks, type WorkflowNextButtonRenderer, type WorkflowNextButtonRendererProps, type WorkflowPersistenceData, type WorkflowPlugin, type WorkflowPreviousButtonRenderer, type WorkflowPreviousButtonRendererProps, type WorkflowRenderConfig, type WorkflowSkipButtonRenderer, type WorkflowSkipButtonRendererProps, type WorkflowStepperRenderer, type WorkflowStepperRendererProps, combineValidators, commonValidators, createConditionalValidator, createCustomValidator, createResilientPersistence, createValidationError, createValidationResult, createZodValidator, persistence, resolveRendererChildren, ril };
635
+ export { type CompletionConfig, type ComponentConfig, type ComponentRenderProps, type ComponentRenderer, CompositeAdapter, type ConditionalConfig, type CustomStepRenderer, type DynamicStepConfig, type FieldRenderer, type FieldRendererProps, type FormBodyRenderer, type FormBodyRendererProps, type FormConfiguration, type FormFieldConfig, type FormFieldRow, type FormRenderConfig, type FormRowRenderer, type FormRowRendererProps, type FormSubmitButtonRenderer, type FormSubmitButtonRendererProps, IdGenerator, LocalStorageAdapter, MemoryAdapter, type NavigationConfig, type PersistenceAdapter, type PersistenceConfig, type RendererChildrenFunction, type RetryPolicy, type RilayLicenseConfig, SessionStorageAdapter, type StepConditionalConfig, type StepConfig, type StepLifecycleHooks, type StepPermissions, type StepValidationConfig, type ValidationConfig, type ValidationContext, type ValidationError, ValidationErrorBuilder, ValidationPatterns, type ValidationResult, type ValidatorFunction, type WorkflowAnalytics, type WorkflowConfig, type WorkflowContext, type WorkflowHooks, type WorkflowNextButtonRenderer, type WorkflowNextButtonRendererProps, type WorkflowPersistenceData, type WorkflowPlugin, type WorkflowPreviousButtonRenderer, type WorkflowPreviousButtonRendererProps, type WorkflowRenderConfig, type WorkflowSkipButtonRenderer, type WorkflowSkipButtonRendererProps, type WorkflowStepperRenderer, type WorkflowStepperRendererProps, combineValidators, commonValidators, configureObject, createConditionalValidator, createCustomValidator, createResilientPersistence, createValidationError, createValidationResult, createZodValidator, deepClone, ensureUnique, mergeInto, normalizeToArray, persistence, resolveRendererChildren, ril, validateRequired };
package/dist/index.d.ts CHANGED
@@ -5,135 +5,88 @@ import { z } from 'zod';
5
5
  * Main configuration class for Rilay form components and workflows
6
6
  * Manages component registration, retrieval, and configuration
7
7
  */
8
- declare class ril {
8
+ declare class ril<C> {
9
9
  private components;
10
10
  private formRenderConfig;
11
11
  private workflowRenderConfig;
12
- static create(): ril;
12
+ static create<CT>(): ril<CT>;
13
13
  /**
14
14
  * Add a component to the configuration
15
15
  * @param type - The component type (e.g., 'text', 'email', 'heading'), used as a unique identifier.
16
16
  * @param config - Component configuration without id and type
17
17
  * @returns The ril instance for chaining
18
18
  */
19
- addComponent<TProps = any>(type: string, config: Omit<ComponentConfig<TProps>, 'id' | 'type'>): this;
20
- /**
21
- * Generic method to set any renderer type easily
22
- * @param rendererType - The type of renderer to set
23
- * @param renderer - The renderer function
24
- * @returns The ril instance for chaining
25
- */
26
- setRenderer<T extends keyof (FormRenderConfig & WorkflowRenderConfig)>(rendererType: T, renderer: (FormRenderConfig & WorkflowRenderConfig)[T]): this;
27
- /**
28
- * Set multiple renderers at once
29
- * @param renderers - Object with renderer configurations
30
- * @returns The ril instance for chaining
31
- */
32
- setRenderers(renderers: Partial<FormRenderConfig & WorkflowRenderConfig>): this;
33
- /**
34
- * Set custom row renderer
35
- * @param renderer - Custom row renderer function
36
- * @returns The ril instance for chaining
37
- */
38
- setRowRenderer(renderer: FormRowRenderer): this;
39
- /**
40
- * Set custom body renderer
41
- * @param renderer - Custom body renderer function
42
- * @returns The ril instance for chaining
43
- */
44
- setBodyRenderer(renderer: FormBodyRenderer): this;
45
- /**
46
- * Set custom submit button renderer
47
- * @param renderer - Custom submit button renderer function
48
- * @returns The ril instance for chaining
49
- */
50
- setSubmitButtonRenderer(renderer: FormSubmitButtonRenderer): this;
51
- /**
52
- * Set custom field renderer
53
- * @param renderer - Custom field renderer function
54
- * @returns The ril instance for chaining
55
- */
56
- setFieldRenderer(renderer: FieldRenderer): this;
57
- /**
58
- * Set complete form render configuration
59
- * @param config - Form render configuration
60
- * @returns The ril instance for chaining
61
- */
62
- setFormRenderConfig(config: FormRenderConfig): this;
63
- /**
64
- * Get current form render configuration
65
- * @returns Current form render configuration
19
+ addComponent<NewType extends string, TProps = any>(type: NewType, config: Omit<ComponentConfig<TProps>, 'id' | 'type'>): ril<C & {
20
+ [K in NewType]: TProps;
21
+ }>;
22
+ /**
23
+ * Universal configuration method for all renderer types
24
+ *
25
+ * This method provides a unified API to configure both form and workflow renderers
26
+ * in a single call, automatically categorizing and applying the appropriate configurations.
27
+ *
28
+ * @param config - Configuration object containing renderer settings
29
+ * @param config.rowRenderer - Custom renderer for form rows (form-specific)
30
+ * @param config.bodyRenderer - Custom renderer for form body container (form-specific)
31
+ * @param config.submitButtonRenderer - Custom renderer for form submit buttons (form-specific)
32
+ * @param config.fieldRenderer - Custom renderer for individual form fields (form-specific)
33
+ * @param config.stepperRenderer - Custom renderer for workflow step navigation (workflow-specific)
34
+ * @param config.nextButtonRenderer - Custom renderer for workflow next buttons (workflow-specific)
35
+ * @param config.previousButtonRenderer - Custom renderer for workflow previous buttons (workflow-specific)
36
+ * @param config.skipButtonRenderer - Custom renderer for workflow skip buttons (workflow-specific)
37
+ *
38
+ * @returns The ril instance for method chaining
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Configure form renderers only
43
+ * const config = ril.create()
44
+ * .configure({
45
+ * rowRenderer: CustomRowRenderer,
46
+ * submitButtonRenderer: CustomSubmitButton
47
+ * });
48
+ *
49
+ * // Configure workflow renderers only
50
+ * const config = ril.create()
51
+ * .configure({
52
+ * stepperRenderer: CustomStepper,
53
+ * nextButtonRenderer: CustomNextButton
54
+ * });
55
+ *
56
+ * // Configure both form and workflow renderers
57
+ * const config = ril.create()
58
+ * .configure({
59
+ * // Form renderers
60
+ * rowRenderer: CustomRowRenderer,
61
+ * fieldRenderer: CustomFieldRenderer,
62
+ * // Workflow renderers
63
+ * stepperRenderer: CustomStepper,
64
+ * nextButtonRenderer: CustomNextButton
65
+ * });
66
+ * ```
67
+ *
68
+ * @remarks
69
+ * - Renderers are automatically categorized into form or workflow configurations
70
+ * - Existing configurations are merged, not replaced entirely
71
+ * - Invalid renderer keys are silently ignored
72
+ * - This method replaces individual setter methods for better DX
73
+ */
74
+ configure(config: Partial<FormRenderConfig & WorkflowRenderConfig>): this;
75
+ /**
76
+ * Configuration getters
66
77
  */
67
78
  getFormRenderConfig(): FormRenderConfig;
68
- /**
69
- * Set custom stepper renderer for workflows
70
- * @param renderer - Custom stepper renderer function
71
- * @returns The ril instance for chaining
72
- */
73
- setStepperRenderer(renderer: WorkflowStepperRenderer): this;
74
- /**
75
- * Set custom workflow next button renderer
76
- * @param renderer - Custom workflow next button renderer function
77
- * @returns The ril instance for chaining
78
- */
79
- setWorkflowNextButtonRenderer(renderer: WorkflowNextButtonRenderer): this;
80
- /**
81
- * Set custom workflow previous button renderer
82
- * @param renderer - Custom workflow previous button renderer function
83
- * @returns The ril instance for chaining
84
- */
85
- setWorkflowPreviousButtonRenderer(renderer: WorkflowPreviousButtonRenderer): this;
86
- /**
87
- * Set custom workflow skip button renderer
88
- * @param renderer - Custom workflow skip button renderer function
89
- * @returns The ril instance for chaining
90
- */
91
- setWorkflowSkipButtonRenderer(renderer: WorkflowSkipButtonRenderer): this;
92
- /**
93
- * Set complete workflow render configuration
94
- * @param config - Workflow render configuration
95
- * @returns The ril instance for chaining
96
- */
97
- setWorkflowRenderConfig(config: WorkflowRenderConfig): this;
98
- /**
99
- * Get current workflow render configuration
100
- * @returns Current workflow render configuration
101
- */
102
79
  getWorkflowRenderConfig(): WorkflowRenderConfig;
103
80
  /**
104
- * @deprecated Use setFormRenderConfig() instead
105
- */
106
- setRenderConfig(config: FormRenderConfig): this;
107
- /**
108
- * Get a component by its ID
109
- * @param id - Component ID (which is its type)
110
- * @returns Component configuration or undefined
111
- */
112
- getComponent(id: string): ComponentConfig | undefined;
113
- /**
114
- * List all registered components
115
- * @returns Array of all components
81
+ * Component management methods
116
82
  */
83
+ getComponent<T extends keyof C & string>(id: T): ComponentConfig<C[T]> | undefined;
117
84
  getAllComponents(): ComponentConfig[];
118
- /**
119
- * Check if a component exists
120
- * @param id - Component ID
121
- * @returns True if component exists
122
- */
123
85
  hasComponent(id: string): boolean;
124
- /**
125
- * Remove a component from the configuration
126
- * @param id - Component ID
127
- * @returns True if component was removed
128
- */
129
86
  removeComponent(id: string): boolean;
130
- /**
131
- * Clear all components
132
- */
133
87
  clear(): void;
134
88
  /**
135
- * Get statistics about registered components and renderers
136
- * @returns Object with comprehensive statistics
89
+ * Enhanced statistics with more detailed information
137
90
  */
138
91
  getStats(): {
139
92
  total: number;
@@ -150,8 +103,7 @@ declare class ril {
150
103
  };
151
104
  };
152
105
  /**
153
- * Validate the configuration
154
- * @returns Array of validation errors
106
+ * Enhanced validation using shared utilities
155
107
  */
156
108
  validate(): string[];
157
109
  }
@@ -418,10 +370,10 @@ interface FormRenderConfig {
418
370
  readonly submitButtonRenderer?: FormSubmitButtonRenderer;
419
371
  readonly fieldRenderer?: FieldRenderer;
420
372
  }
421
- interface FormConfiguration {
373
+ interface FormConfiguration<C extends Record<string, any> = Record<string, never>> {
422
374
  readonly id: string;
423
375
  readonly schema?: any;
424
- readonly config: ril;
376
+ readonly config: ril<C>;
425
377
  readonly rows: FormFieldRow[];
426
378
  readonly allFields: FormFieldConfig[];
427
379
  readonly renderConfig?: FormRenderConfig;
@@ -464,7 +416,61 @@ type WorkflowPreviousButtonRenderer = (props: WorkflowPreviousButtonRendererProp
464
416
  type WorkflowSkipButtonRenderer = (props: WorkflowSkipButtonRendererProps) => React.ReactElement;
465
417
 
466
418
  /**
467
- * Create a Zod-based validator
419
+ * Utility for merging partial configurations into existing objects
420
+ * Eliminates repetitive object spread operations
421
+ */
422
+ declare function mergeInto<T>(target: T, partial: Partial<T>): T;
423
+ /**
424
+ * Validates uniqueness of identifiers and throws descriptive errors
425
+ */
426
+ declare function ensureUnique(ids: string[], entityName: string): void;
427
+ /**
428
+ * Validates required fields exist in configurations
429
+ */
430
+ declare function validateRequired<T>(items: T[], requiredFields: (keyof T)[], entityName: string): void;
431
+ /**
432
+ * Auto-generates IDs when not provided
433
+ */
434
+ declare class IdGenerator {
435
+ private counters;
436
+ next(prefix: string): string;
437
+ reset(prefix?: string): void;
438
+ }
439
+ /**
440
+ * Validation error builder for consistent error handling
441
+ */
442
+ declare class ValidationErrorBuilder {
443
+ private errors;
444
+ add(code: string, message: string, path?: string[]): this;
445
+ addIf(condition: boolean, code: string, message: string, path?: string[]): this;
446
+ build(): ValidationError[];
447
+ hasErrors(): boolean;
448
+ clear(): this;
449
+ }
450
+ /**
451
+ * Common validation patterns
452
+ */
453
+ declare const ValidationPatterns: {
454
+ hasValue: (value: any) => boolean;
455
+ isArray: (value: any) => value is any[];
456
+ arrayMinLength: (value: any[], min: number) => boolean;
457
+ arrayMaxLength: (value: any[], max: number) => boolean;
458
+ };
459
+ /**
460
+ * Polymorphic helper for handling single items or arrays
461
+ */
462
+ declare function normalizeToArray<T>(input: T | T[]): T[];
463
+ /**
464
+ * Deep clone utility for configuration objects
465
+ */
466
+ declare function deepClone<T>(obj: T): T;
467
+ /**
468
+ * Generic configuration merger with type safety
469
+ */
470
+ declare function configureObject<T>(target: T, updates: Partial<T>, allowedKeys?: (keyof T)[]): T;
471
+
472
+ /**
473
+ * Create a `Zod`-based validator
468
474
  * @param schema - Zod schema to validate against
469
475
  * @returns Validator function
470
476
  */
@@ -626,4 +632,4 @@ declare const persistence: {
626
632
  */
627
633
  declare function createResilientPersistence(primary: PersistenceAdapter, fallback?: PersistenceAdapter, options?: Partial<PersistenceConfig>): PersistenceConfig;
628
634
 
629
- export { type CompletionConfig, type ComponentConfig, type ComponentRenderProps, type ComponentRenderer, CompositeAdapter, type ConditionalConfig, type CustomStepRenderer, type DynamicStepConfig, type FieldRenderer, type FieldRendererProps, type FormBodyRenderer, type FormBodyRendererProps, type FormConfiguration, type FormFieldConfig, type FormFieldRow, type FormRenderConfig, type FormRowRenderer, type FormRowRendererProps, type FormSubmitButtonRenderer, type FormSubmitButtonRendererProps, LocalStorageAdapter, MemoryAdapter, type NavigationConfig, type PersistenceAdapter, type PersistenceConfig, type RendererChildrenFunction, type RetryPolicy, type RilayLicenseConfig, SessionStorageAdapter, type StepConditionalConfig, type StepConfig, type StepLifecycleHooks, type StepPermissions, type StepValidationConfig, type ValidationConfig, type ValidationContext, type ValidationError, type ValidationResult, type ValidatorFunction, type WorkflowAnalytics, type WorkflowConfig, type WorkflowContext, type WorkflowHooks, type WorkflowNextButtonRenderer, type WorkflowNextButtonRendererProps, type WorkflowPersistenceData, type WorkflowPlugin, type WorkflowPreviousButtonRenderer, type WorkflowPreviousButtonRendererProps, type WorkflowRenderConfig, type WorkflowSkipButtonRenderer, type WorkflowSkipButtonRendererProps, type WorkflowStepperRenderer, type WorkflowStepperRendererProps, combineValidators, commonValidators, createConditionalValidator, createCustomValidator, createResilientPersistence, createValidationError, createValidationResult, createZodValidator, persistence, resolveRendererChildren, ril };
635
+ export { type CompletionConfig, type ComponentConfig, type ComponentRenderProps, type ComponentRenderer, CompositeAdapter, type ConditionalConfig, type CustomStepRenderer, type DynamicStepConfig, type FieldRenderer, type FieldRendererProps, type FormBodyRenderer, type FormBodyRendererProps, type FormConfiguration, type FormFieldConfig, type FormFieldRow, type FormRenderConfig, type FormRowRenderer, type FormRowRendererProps, type FormSubmitButtonRenderer, type FormSubmitButtonRendererProps, IdGenerator, LocalStorageAdapter, MemoryAdapter, type NavigationConfig, type PersistenceAdapter, type PersistenceConfig, type RendererChildrenFunction, type RetryPolicy, type RilayLicenseConfig, SessionStorageAdapter, type StepConditionalConfig, type StepConfig, type StepLifecycleHooks, type StepPermissions, type StepValidationConfig, type ValidationConfig, type ValidationContext, type ValidationError, ValidationErrorBuilder, ValidationPatterns, type ValidationResult, type ValidatorFunction, type WorkflowAnalytics, type WorkflowConfig, type WorkflowContext, type WorkflowHooks, type WorkflowNextButtonRenderer, type WorkflowNextButtonRendererProps, type WorkflowPersistenceData, type WorkflowPlugin, type WorkflowPreviousButtonRenderer, type WorkflowPreviousButtonRendererProps, type WorkflowRenderConfig, type WorkflowSkipButtonRenderer, type WorkflowSkipButtonRendererProps, type WorkflowStepperRenderer, type WorkflowStepperRendererProps, combineValidators, commonValidators, configureObject, createConditionalValidator, createCustomValidator, createResilientPersistence, createValidationError, createValidationResult, createZodValidator, deepClone, ensureUnique, mergeInto, normalizeToArray, persistence, resolveRendererChildren, ril, validateRequired };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var zod=require('zod');function w(n,e){return typeof n=="function"?n(e):n}var u=class n{constructor(){this.components=new Map;this.formRenderConfig={};this.workflowRenderConfig={};}static create(){return new n}addComponent(e,r){let o={id:e,type:e,...r};return this.components.set(e,o),this}setRenderer(e,r){return e in this.formRenderConfig?this.formRenderConfig={...this.formRenderConfig,[e]:r}:e in this.workflowRenderConfig&&(this.workflowRenderConfig={...this.workflowRenderConfig,[e]:r}),this}setRenderers(e){let r={},o={};for(let[t,i]of Object.entries(e))["rowRenderer","bodyRenderer","submitButtonRenderer","fieldRenderer"].includes(t)?r[t]=i:o[t]=i;return this.formRenderConfig={...this.formRenderConfig,...r},this.workflowRenderConfig={...this.workflowRenderConfig,...o},this}setRowRenderer(e){return this.formRenderConfig={...this.formRenderConfig,rowRenderer:e},this}setBodyRenderer(e){return this.formRenderConfig={...this.formRenderConfig,bodyRenderer:e},this}setSubmitButtonRenderer(e){return this.formRenderConfig={...this.formRenderConfig,submitButtonRenderer:e},this}setFieldRenderer(e){return this.formRenderConfig={...this.formRenderConfig,fieldRenderer:e},this}setFormRenderConfig(e){return this.formRenderConfig=e,this}getFormRenderConfig(){return {...this.formRenderConfig}}setStepperRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,stepperRenderer:e},this}setWorkflowNextButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,nextButtonRenderer:e},this}setWorkflowPreviousButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,previousButtonRenderer:e},this}setWorkflowSkipButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,skipButtonRenderer:e},this}setWorkflowRenderConfig(e){return this.workflowRenderConfig=e,this}getWorkflowRenderConfig(){return {...this.workflowRenderConfig}}setRenderConfig(e){return this.setFormRenderConfig(e)}getComponent(e){return this.components.get(e)}getAllComponents(){return Array.from(this.components.values())}hasComponent(e){return this.components.has(e)}removeComponent(e){return this.components.delete(e)}clear(){this.components.clear();}getStats(){let e=Array.from(this.components.values());return {total:e.length,byType:e.reduce((r,o)=>(r[o.type]=(r[o.type]||0)+1,r),{}),hasCustomRenderers:{row:!!this.formRenderConfig.rowRenderer,body:!!this.formRenderConfig.bodyRenderer,submitButton:!!this.formRenderConfig.submitButtonRenderer,field:!!this.formRenderConfig.fieldRenderer,stepper:!!this.workflowRenderConfig.stepperRenderer,workflowNextButton:!!this.workflowRenderConfig.nextButtonRenderer,workflowPreviousButton:!!this.workflowRenderConfig.previousButtonRenderer,workflowSkipButton:!!this.workflowRenderConfig.skipButtonRenderer}}}validate(){let e=[],r=Array.from(this.components.values()),o=r.map(a=>a.id),t=o.filter((a,s)=>o.indexOf(a)!==s);t.length>0&&e.push(`Duplicate component IDs found: ${t.join(", ")}`);let i=r.filter(a=>!a.renderer);return i.length>0&&e.push(`Components without renderer: ${i.map(a=>a.id).join(", ")}`),e}};var f=n=>async e=>{try{return await n.parseAsync(e),{isValid:!0,errors:[]}}catch(r){return r&&typeof r=="object"&&"errors"in r&&Array.isArray(r.errors)?{isValid:false,errors:r.errors.map(o=>({code:o.code,message:o.message,path:o.path?o.path.map(String):[]}))}:{isValid:false,errors:[{code:"unknown",message:r instanceof Error?r.message:"Unknown validation error"}]}}},R=n=>async(e,r,o)=>{try{let t=await n(e,r);return t===!0?{isValid:!0,errors:[]}:t===!1?{isValid:!1,errors:[{code:"validation_failed",message:"Validation failed"}]}:{isValid:!1,errors:[{code:"validation_failed",message:String(t)}]}}catch(t){return {isValid:false,errors:[{code:"validation_error",message:t instanceof Error?t.message:"Validation error"}]}}},P=(n,e="all")=>async(r,o,t)=>{let i=await Promise.all(n.map(d=>d(r,o,t)));if(e==="all"){let d=i.flatMap(l=>l.errors);return {isValid:i.every(l=>l.isValid),errors:d}}return i.some(d=>d.isValid)?{isValid:true,errors:[]}:{isValid:false,errors:i.flatMap(d=>d.errors)}},x=(n,e)=>async(r,o,t)=>n(r,o)?e(r,o,t):{isValid:true,errors:[]},v={required:(n="This field is required")=>R(e=>e==null||e===""?n:!0),email:(n="Invalid email format")=>f(zod.z.string().email(n)),minLength:(n,e)=>f(zod.z.string().min(n,e||`Minimum ${n} characters required`)),maxLength:(n,e)=>f(zod.z.string().max(n,e||`Maximum ${n} characters allowed`)),pattern:(n,e="Invalid format")=>f(zod.z.string().regex(n,e)),numberRange:(n,e,r)=>{let o=zod.z.number();return n!==void 0&&(o=o.min(n,r||`Value must be at least ${n}`)),e!==void 0&&(o=o.max(e,r||`Value must be at most ${e}`)),f(o)},url:(n="Invalid URL format")=>f(zod.z.string().url(n)),phoneNumber:(n="Invalid phone number format")=>f(zod.z.string().regex(/^\+?[\d\s\-\(\)]+$/,n)),asyncValidation:(n,e=300)=>{let r=new Map;return (o,t,i)=>new Promise(a=>{let s=`${t.fieldId}-${JSON.stringify(o)}`;r.has(s)&&clearTimeout(r.get(s));let d=setTimeout(async()=>{try{let l=await n(o,t);a(l===!0?{isValid:!0,errors:[]}:{isValid:!1,errors:[{code:"async_validation_failed",message:typeof l=="string"?l:"Async validation failed"}]});}catch(l){a({isValid:false,errors:[{code:"async_validation_error",message:l instanceof Error?l.message:"Async validation error"}]});}finally{r.delete(s);}},e);r.set(s,d);})}},b=(n,e=[])=>({isValid:n,errors:e}),S=(n,e,r)=>({code:n,message:e,path:r});var m=class{constructor(){this.name="localStorage";}async save(e,r){try{localStorage.setItem(e,JSON.stringify(r));}catch(o){throw new Error(`Failed to save to localStorage: ${o}`)}}async load(e){try{let r=localStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from localStorage: ${r}`)}}async remove(e){try{localStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from localStorage: ${r}`)}}async exists(e){return localStorage.getItem(e)!==null}async list(e){let r=[];for(let o=0;o<localStorage.length;o++){let t=localStorage.key(o);t&&(!e||t.includes(e))&&r.push(t);}return r}},y=class{constructor(){this.name="sessionStorage";}async save(e,r){try{sessionStorage.setItem(e,JSON.stringify(r));}catch(o){throw new Error(`Failed to save to sessionStorage: ${o}`)}}async load(e){try{let r=sessionStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from sessionStorage: ${r}`)}}async remove(e){try{sessionStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from sessionStorage: ${r}`)}}async exists(e){return sessionStorage.getItem(e)!==null}async list(e){let r=[];for(let o=0;o<sessionStorage.length;o++){let t=sessionStorage.key(o);t&&(!e||t.includes(e))&&r.push(t);}return r}},p=class{constructor(){this.name="memory";this.storage=new Map;}async save(e,r){this.storage.set(e,{...r});}async load(e){let r=this.storage.get(e);return r?{...r}:null}async remove(e){this.storage.delete(e);}async exists(e){return this.storage.has(e)}async list(e){let r=Array.from(this.storage.keys());return e?r.filter(o=>o.includes(e)):r}clear(){this.storage.clear();}},g=class{constructor(e,r=[]){this.primary=e;this.fallbacks=r;this.name="composite";}async save(e,r){let o=[this.primary,...this.fallbacks];for(let t of o)try{await t.save(e,r);return}catch(i){console.warn(`Failed to save with ${t.name}:`,i);}throw new Error("All persistence adapters failed to save")}async load(e){let r=[this.primary,...this.fallbacks];for(let o of r)try{let t=await o.load(e);if(t)return t}catch(t){console.warn(`Failed to load with ${o.name}:`,t);}return null}async remove(e){let r=[this.primary,...this.fallbacks],o=[];for(let t of r)try{await t.remove(e);}catch(i){o.push(i);}if(o.length===r.length)throw new Error(`All adapters failed to remove: ${o.map(t=>t.message).join(", ")}`)}async exists(e){let r=[this.primary,...this.fallbacks];for(let o of r)try{if(await o.exists(e))return !0}catch(t){console.warn(`Failed to check existence with ${o.name}:`,t);}return false}async list(e){try{return await this.primary.list?.(e)||[]}catch(r){console.warn("Failed to list with primary adapter:",r);for(let o of this.fallbacks)try{return await o.list?.(e)||[]}catch(t){console.warn(`Failed to list with fallback ${o.name}:`,t);}return []}}};var B={localStorage(n={}){return {adapter:new m,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...n}},sessionStorage(n={}){return {adapter:new y,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...n}},memory(n={}){return {adapter:new p,debounceMs:0,autoSave:true,saveOnStepChange:true,...n}},custom(n,e={}){return {adapter:n,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...e}}};function E(n,e,r={}){let o=e||new p;return {adapter:{name:`resilient-${n.name}`,async save(i,a){try{await n.save(i,a);}catch(s){console.warn("Primary persistence failed, using fallback:",s),await o.save(i,a);}},async load(i){try{let a=await n.load(i);if(a)return a}catch(a){console.warn("Primary persistence load failed, trying fallback:",a);}return await o.load(i)},async remove(i){let a=[];try{await n.remove(i);}catch(s){a.push(s);}try{await o.remove(i);}catch(s){a.push(s);}if(a.length===2)throw new Error(`Both adapters failed: ${a.map(s=>s.message).join(", ")}`)},async exists(i){try{if(await n.exists(i))return !0}catch(a){console.warn("Primary persistence exists check failed:",a);}try{return await o.exists(i)}catch(a){return console.warn("Fallback persistence exists check failed:",a),false}},async list(i){try{return await n.list?.(i)||[]}catch(a){console.warn("Primary persistence list failed:",a);try{return await o.list?.(i)||[]}catch(s){return console.warn("Fallback persistence list failed:",s),[]}}}},debounceMs:1e3,autoSave:true,saveOnStepChange:true,maxRetries:3,retryDelayMs:1e3,...r}}exports.CompositeAdapter=g;exports.LocalStorageAdapter=m;exports.MemoryAdapter=p;exports.SessionStorageAdapter=y;exports.combineValidators=P;exports.commonValidators=v;exports.createConditionalValidator=x;exports.createCustomValidator=R;exports.createResilientPersistence=E;exports.createValidationError=S;exports.createValidationResult=b;exports.createZodValidator=f;exports.persistence=B;exports.resolveRendererChildren=w;exports.ril=u;
1
+ 'use strict';var zod=require('zod');function P(o,e){return typeof o=="function"?o(e):o}function b(o,e){return {...o,...e}}function h(o,e){let r=o.filter((n,t)=>o.indexOf(n)!==t);if(r.length>0)throw new Error(`Duplicate ${e} IDs: ${r.join(", ")}`)}function S(o,e,r){if(o.filter(t=>e.some(a=>!t[a])).length>0)throw new Error(`Missing required fields in ${r}: ${e.join(", ")}`)}var R=class{constructor(){this.counters=new Map;}next(e){let r=this.counters.get(e)||0;return this.counters.set(e,r+1),`${e}-${r+1}`}reset(e){e?this.counters.delete(e):this.counters.clear();}},y=class{constructor(){this.errors=[];}add(e,r,n){return this.errors.push({code:e,message:r,path:n}),this}addIf(e,r,n,t){return e&&this.add(r,n,t),this}build(){return [...this.errors]}hasErrors(){return this.errors.length>0}clear(){return this.errors=[],this}},V={hasValue:o=>o!=null&&o!=="",isArray:o=>Array.isArray(o),arrayMinLength:(o,e)=>o.length>=e,arrayMaxLength:(o,e)=>o.length<=e};function F(o){return Array.isArray(o)?o:[o]}function C(o){if(o===null||typeof o!="object")return o;if(o instanceof Date)return new Date(o.getTime());if(Array.isArray(o))return o.map(r=>C(r));let e={};for(let r in o)Object.prototype.hasOwnProperty.call(o,r)&&(e[r]=C(o[r]));return e}function g(o,e,r){let n={...o};for(let t in e)r&&!r.includes(t)||e[t]!==void 0&&(n[t]=e[t]);return n}var w=class o{constructor(){this.components=new Map;this.formRenderConfig={};this.workflowRenderConfig={};}static create(){return new o}addComponent(e,r){let n={id:e,type:e,...r};return this.components.set(e,n),this}configure(e){let r=["rowRenderer","bodyRenderer","submitButtonRenderer","fieldRenderer"],n=["stepperRenderer","nextButtonRenderer","previousButtonRenderer","skipButtonRenderer"],t={},a={};for(let[i,s]of Object.entries(e))r.includes(i)?t[i]=s:n.includes(i)&&(a[i]=s);return this.formRenderConfig=g(this.formRenderConfig,t),this.workflowRenderConfig=g(this.workflowRenderConfig,a),this}getFormRenderConfig(){return {...this.formRenderConfig}}getWorkflowRenderConfig(){return {...this.workflowRenderConfig}}getComponent(e){return this.components.get(e)}getAllComponents(){return Array.from(this.components.values())}hasComponent(e){return this.components.has(e)}removeComponent(e){return this.components.delete(e)}clear(){this.components.clear();}getStats(){let e=Array.from(this.components.values());return {total:e.length,byType:e.reduce((r,n)=>(r[n.type]=(r[n.type]||0)+1,r),{}),hasCustomRenderers:{row:!!this.formRenderConfig.rowRenderer,body:!!this.formRenderConfig.bodyRenderer,submitButton:!!this.formRenderConfig.submitButtonRenderer,field:!!this.formRenderConfig.fieldRenderer,stepper:!!this.workflowRenderConfig.stepperRenderer,workflowNextButton:!!this.workflowRenderConfig.nextButtonRenderer,workflowPreviousButton:!!this.workflowRenderConfig.previousButtonRenderer,workflowSkipButton:!!this.workflowRenderConfig.skipButtonRenderer}}}validate(){let e=new y,r=Array.from(this.components.values()),n=r.map(a=>a.id);try{h(n,"component");}catch(a){e.add("DUPLICATE_IDS",a instanceof Error?a.message:String(a));}let t=r.filter(a=>!a.renderer);return e.addIf(t.length>0,"MISSING_RENDERER",`Components without renderer: ${t.map(a=>a.id).join(", ")}`),e.build().map(a=>a.message)}};var p=o=>async e=>{try{return await o.parseAsync(e),{isValid:!0,errors:[]}}catch(r){return r&&typeof r=="object"&&"errors"in r&&Array.isArray(r.errors)?{isValid:false,errors:r.errors.map(n=>({code:n.code,message:n.message,path:n.path?n.path.map(String):[]}))}:{isValid:false,errors:[{code:"unknown",message:r instanceof Error?r.message:"Unknown validation error"}]}}},k=o=>async(e,r,n)=>{try{let t=await o(e,r);return t===!0?{isValid:!0,errors:[]}:t===!1?{isValid:!1,errors:[{code:"validation_failed",message:"Validation failed"}]}:{isValid:!1,errors:[{code:"validation_failed",message:String(t)}]}}catch(t){return {isValid:false,errors:[{code:"validation_error",message:t instanceof Error?t.message:"Validation error"}]}}},D=(o,e="all")=>async(r,n,t)=>{let a=await Promise.all(o.map(d=>d(r,n,t)));if(e==="all"){let d=a.flatMap(l=>l.errors);return {isValid:a.every(l=>l.isValid),errors:d}}return a.some(d=>d.isValid)?{isValid:true,errors:[]}:{isValid:false,errors:a.flatMap(d=>d.errors)}},N=(o,e)=>async(r,n,t)=>o(r,n)?e(r,n,t):{isValid:true,errors:[]},I={required:(o="This field is required")=>k(e=>e==null||e===""?o:!0),email:(o="Invalid email format")=>p(zod.z.string().email(o)),minLength:(o,e)=>p(zod.z.string().min(o,e||`Minimum ${o} characters required`)),maxLength:(o,e)=>p(zod.z.string().max(o,e||`Maximum ${o} characters allowed`)),pattern:(o,e="Invalid format")=>p(zod.z.string().regex(o,e)),numberRange:(o,e,r)=>{let n=zod.z.number();return o!==void 0&&(n=n.min(o,r||`Value must be at least ${o}`)),e!==void 0&&(n=n.max(e,r||`Value must be at most ${e}`)),p(n)},url:(o="Invalid URL format")=>p(zod.z.string().url(o)),phoneNumber:(o="Invalid phone number format")=>p(zod.z.string().regex(/^\+?[\d\s\-\(\)]+$/,o)),asyncValidation:(o,e=300)=>{let r=new Map;return (n,t,a)=>new Promise(i=>{let s=`${t.fieldId}-${JSON.stringify(n)}`;r.has(s)&&clearTimeout(r.get(s));let d=setTimeout(async()=>{try{let l=await o(n,t);i(l===!0?{isValid:!0,errors:[]}:{isValid:!1,errors:[{code:"async_validation_failed",message:typeof l=="string"?l:"Async validation failed"}]});}catch(l){i({isValid:false,errors:[{code:"async_validation_error",message:l instanceof Error?l.message:"Async validation error"}]});}finally{r.delete(s);}},e);r.set(s,d);})}},A=(o,e=[])=>({isValid:o,errors:e}),$=(o,e,r)=>({code:o,message:e,path:r});var m=class{constructor(){this.name="localStorage";}async save(e,r){try{localStorage.setItem(e,JSON.stringify(r));}catch(n){throw new Error(`Failed to save to localStorage: ${n}`)}}async load(e){try{let r=localStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from localStorage: ${r}`)}}async remove(e){try{localStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from localStorage: ${r}`)}}async exists(e){return localStorage.getItem(e)!==null}async list(e){let r=[];for(let n=0;n<localStorage.length;n++){let t=localStorage.key(n);t&&(!e||t.includes(e))&&r.push(t);}return r}},u=class{constructor(){this.name="sessionStorage";}async save(e,r){try{sessionStorage.setItem(e,JSON.stringify(r));}catch(n){throw new Error(`Failed to save to sessionStorage: ${n}`)}}async load(e){try{let r=sessionStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from sessionStorage: ${r}`)}}async remove(e){try{sessionStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from sessionStorage: ${r}`)}}async exists(e){return sessionStorage.getItem(e)!==null}async list(e){let r=[];for(let n=0;n<sessionStorage.length;n++){let t=sessionStorage.key(n);t&&(!e||t.includes(e))&&r.push(t);}return r}},f=class{constructor(){this.name="memory";this.storage=new Map;}async save(e,r){this.storage.set(e,{...r});}async load(e){let r=this.storage.get(e);return r?{...r}:null}async remove(e){this.storage.delete(e);}async exists(e){return this.storage.has(e)}async list(e){let r=Array.from(this.storage.keys());return e?r.filter(n=>n.includes(e)):r}clear(){this.storage.clear();}},x=class{constructor(e,r=[]){this.primary=e;this.fallbacks=r;this.name="composite";}async save(e,r){let n=[this.primary,...this.fallbacks];for(let t of n)try{await t.save(e,r);return}catch(a){console.warn(`Failed to save with ${t.name}:`,a);}throw new Error("All persistence adapters failed to save")}async load(e){let r=[this.primary,...this.fallbacks];for(let n of r)try{let t=await n.load(e);if(t)return t}catch(t){console.warn(`Failed to load with ${n.name}:`,t);}return null}async remove(e){let r=[this.primary,...this.fallbacks],n=[];for(let t of r)try{await t.remove(e);}catch(a){n.push(a);}if(n.length===r.length)throw new Error(`All adapters failed to remove: ${n.map(t=>t.message).join(", ")}`)}async exists(e){let r=[this.primary,...this.fallbacks];for(let n of r)try{if(await n.exists(e))return !0}catch(t){console.warn(`Failed to check existence with ${n.name}:`,t);}return false}async list(e){try{return await this.primary.list?.(e)||[]}catch(r){console.warn("Failed to list with primary adapter:",r);for(let n of this.fallbacks)try{return await n.list?.(e)||[]}catch(t){console.warn(`Failed to list with fallback ${n.name}:`,t);}return []}}};var q={localStorage(o={}){return {adapter:new m,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...o}},sessionStorage(o={}){return {adapter:new u,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...o}},memory(o={}){return {adapter:new f,debounceMs:0,autoSave:true,saveOnStepChange:true,...o}},custom(o,e={}){return {adapter:o,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...e}}};function _(o,e,r={}){let n=e||new f;return {adapter:{name:`resilient-${o.name}`,async save(a,i){try{await o.save(a,i);}catch(s){console.warn("Primary persistence failed, using fallback:",s),await n.save(a,i);}},async load(a){try{let i=await o.load(a);if(i)return i}catch(i){console.warn("Primary persistence load failed, trying fallback:",i);}return await n.load(a)},async remove(a){let i=[];try{await o.remove(a);}catch(s){i.push(s);}try{await n.remove(a);}catch(s){i.push(s);}if(i.length===2)throw new Error(`Both adapters failed: ${i.map(s=>s.message).join(", ")}`)},async exists(a){try{if(await o.exists(a))return !0}catch(i){console.warn("Primary persistence exists check failed:",i);}try{return await n.exists(a)}catch(i){return console.warn("Fallback persistence exists check failed:",i),false}},async list(a){try{return await o.list?.(a)||[]}catch(i){console.warn("Primary persistence list failed:",i);try{return await n.list?.(a)||[]}catch(s){return console.warn("Fallback persistence list failed:",s),[]}}}},debounceMs:1e3,autoSave:true,saveOnStepChange:true,maxRetries:3,retryDelayMs:1e3,...r}}exports.CompositeAdapter=x;exports.IdGenerator=R;exports.LocalStorageAdapter=m;exports.MemoryAdapter=f;exports.SessionStorageAdapter=u;exports.ValidationErrorBuilder=y;exports.ValidationPatterns=V;exports.combineValidators=D;exports.commonValidators=I;exports.configureObject=g;exports.createConditionalValidator=N;exports.createCustomValidator=k;exports.createResilientPersistence=_;exports.createValidationError=$;exports.createValidationResult=A;exports.createZodValidator=p;exports.deepClone=C;exports.ensureUnique=h;exports.mergeInto=b;exports.normalizeToArray=F;exports.persistence=q;exports.resolveRendererChildren=P;exports.ril=w;exports.validateRequired=S;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {z}from'zod';function w(n,e){return typeof n=="function"?n(e):n}var u=class n{constructor(){this.components=new Map;this.formRenderConfig={};this.workflowRenderConfig={};}static create(){return new n}addComponent(e,r){let o={id:e,type:e,...r};return this.components.set(e,o),this}setRenderer(e,r){return e in this.formRenderConfig?this.formRenderConfig={...this.formRenderConfig,[e]:r}:e in this.workflowRenderConfig&&(this.workflowRenderConfig={...this.workflowRenderConfig,[e]:r}),this}setRenderers(e){let r={},o={};for(let[t,i]of Object.entries(e))["rowRenderer","bodyRenderer","submitButtonRenderer","fieldRenderer"].includes(t)?r[t]=i:o[t]=i;return this.formRenderConfig={...this.formRenderConfig,...r},this.workflowRenderConfig={...this.workflowRenderConfig,...o},this}setRowRenderer(e){return this.formRenderConfig={...this.formRenderConfig,rowRenderer:e},this}setBodyRenderer(e){return this.formRenderConfig={...this.formRenderConfig,bodyRenderer:e},this}setSubmitButtonRenderer(e){return this.formRenderConfig={...this.formRenderConfig,submitButtonRenderer:e},this}setFieldRenderer(e){return this.formRenderConfig={...this.formRenderConfig,fieldRenderer:e},this}setFormRenderConfig(e){return this.formRenderConfig=e,this}getFormRenderConfig(){return {...this.formRenderConfig}}setStepperRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,stepperRenderer:e},this}setWorkflowNextButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,nextButtonRenderer:e},this}setWorkflowPreviousButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,previousButtonRenderer:e},this}setWorkflowSkipButtonRenderer(e){return this.workflowRenderConfig={...this.workflowRenderConfig,skipButtonRenderer:e},this}setWorkflowRenderConfig(e){return this.workflowRenderConfig=e,this}getWorkflowRenderConfig(){return {...this.workflowRenderConfig}}setRenderConfig(e){return this.setFormRenderConfig(e)}getComponent(e){return this.components.get(e)}getAllComponents(){return Array.from(this.components.values())}hasComponent(e){return this.components.has(e)}removeComponent(e){return this.components.delete(e)}clear(){this.components.clear();}getStats(){let e=Array.from(this.components.values());return {total:e.length,byType:e.reduce((r,o)=>(r[o.type]=(r[o.type]||0)+1,r),{}),hasCustomRenderers:{row:!!this.formRenderConfig.rowRenderer,body:!!this.formRenderConfig.bodyRenderer,submitButton:!!this.formRenderConfig.submitButtonRenderer,field:!!this.formRenderConfig.fieldRenderer,stepper:!!this.workflowRenderConfig.stepperRenderer,workflowNextButton:!!this.workflowRenderConfig.nextButtonRenderer,workflowPreviousButton:!!this.workflowRenderConfig.previousButtonRenderer,workflowSkipButton:!!this.workflowRenderConfig.skipButtonRenderer}}}validate(){let e=[],r=Array.from(this.components.values()),o=r.map(a=>a.id),t=o.filter((a,s)=>o.indexOf(a)!==s);t.length>0&&e.push(`Duplicate component IDs found: ${t.join(", ")}`);let i=r.filter(a=>!a.renderer);return i.length>0&&e.push(`Components without renderer: ${i.map(a=>a.id).join(", ")}`),e}};var f=n=>async e=>{try{return await n.parseAsync(e),{isValid:!0,errors:[]}}catch(r){return r&&typeof r=="object"&&"errors"in r&&Array.isArray(r.errors)?{isValid:false,errors:r.errors.map(o=>({code:o.code,message:o.message,path:o.path?o.path.map(String):[]}))}:{isValid:false,errors:[{code:"unknown",message:r instanceof Error?r.message:"Unknown validation error"}]}}},R=n=>async(e,r,o)=>{try{let t=await n(e,r);return t===!0?{isValid:!0,errors:[]}:t===!1?{isValid:!1,errors:[{code:"validation_failed",message:"Validation failed"}]}:{isValid:!1,errors:[{code:"validation_failed",message:String(t)}]}}catch(t){return {isValid:false,errors:[{code:"validation_error",message:t instanceof Error?t.message:"Validation error"}]}}},P=(n,e="all")=>async(r,o,t)=>{let i=await Promise.all(n.map(d=>d(r,o,t)));if(e==="all"){let d=i.flatMap(l=>l.errors);return {isValid:i.every(l=>l.isValid),errors:d}}return i.some(d=>d.isValid)?{isValid:true,errors:[]}:{isValid:false,errors:i.flatMap(d=>d.errors)}},x=(n,e)=>async(r,o,t)=>n(r,o)?e(r,o,t):{isValid:true,errors:[]},v={required:(n="This field is required")=>R(e=>e==null||e===""?n:!0),email:(n="Invalid email format")=>f(z.string().email(n)),minLength:(n,e)=>f(z.string().min(n,e||`Minimum ${n} characters required`)),maxLength:(n,e)=>f(z.string().max(n,e||`Maximum ${n} characters allowed`)),pattern:(n,e="Invalid format")=>f(z.string().regex(n,e)),numberRange:(n,e,r)=>{let o=z.number();return n!==void 0&&(o=o.min(n,r||`Value must be at least ${n}`)),e!==void 0&&(o=o.max(e,r||`Value must be at most ${e}`)),f(o)},url:(n="Invalid URL format")=>f(z.string().url(n)),phoneNumber:(n="Invalid phone number format")=>f(z.string().regex(/^\+?[\d\s\-\(\)]+$/,n)),asyncValidation:(n,e=300)=>{let r=new Map;return (o,t,i)=>new Promise(a=>{let s=`${t.fieldId}-${JSON.stringify(o)}`;r.has(s)&&clearTimeout(r.get(s));let d=setTimeout(async()=>{try{let l=await n(o,t);a(l===!0?{isValid:!0,errors:[]}:{isValid:!1,errors:[{code:"async_validation_failed",message:typeof l=="string"?l:"Async validation failed"}]});}catch(l){a({isValid:false,errors:[{code:"async_validation_error",message:l instanceof Error?l.message:"Async validation error"}]});}finally{r.delete(s);}},e);r.set(s,d);})}},b=(n,e=[])=>({isValid:n,errors:e}),S=(n,e,r)=>({code:n,message:e,path:r});var m=class{constructor(){this.name="localStorage";}async save(e,r){try{localStorage.setItem(e,JSON.stringify(r));}catch(o){throw new Error(`Failed to save to localStorage: ${o}`)}}async load(e){try{let r=localStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from localStorage: ${r}`)}}async remove(e){try{localStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from localStorage: ${r}`)}}async exists(e){return localStorage.getItem(e)!==null}async list(e){let r=[];for(let o=0;o<localStorage.length;o++){let t=localStorage.key(o);t&&(!e||t.includes(e))&&r.push(t);}return r}},y=class{constructor(){this.name="sessionStorage";}async save(e,r){try{sessionStorage.setItem(e,JSON.stringify(r));}catch(o){throw new Error(`Failed to save to sessionStorage: ${o}`)}}async load(e){try{let r=sessionStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from sessionStorage: ${r}`)}}async remove(e){try{sessionStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from sessionStorage: ${r}`)}}async exists(e){return sessionStorage.getItem(e)!==null}async list(e){let r=[];for(let o=0;o<sessionStorage.length;o++){let t=sessionStorage.key(o);t&&(!e||t.includes(e))&&r.push(t);}return r}},p=class{constructor(){this.name="memory";this.storage=new Map;}async save(e,r){this.storage.set(e,{...r});}async load(e){let r=this.storage.get(e);return r?{...r}:null}async remove(e){this.storage.delete(e);}async exists(e){return this.storage.has(e)}async list(e){let r=Array.from(this.storage.keys());return e?r.filter(o=>o.includes(e)):r}clear(){this.storage.clear();}},g=class{constructor(e,r=[]){this.primary=e;this.fallbacks=r;this.name="composite";}async save(e,r){let o=[this.primary,...this.fallbacks];for(let t of o)try{await t.save(e,r);return}catch(i){console.warn(`Failed to save with ${t.name}:`,i);}throw new Error("All persistence adapters failed to save")}async load(e){let r=[this.primary,...this.fallbacks];for(let o of r)try{let t=await o.load(e);if(t)return t}catch(t){console.warn(`Failed to load with ${o.name}:`,t);}return null}async remove(e){let r=[this.primary,...this.fallbacks],o=[];for(let t of r)try{await t.remove(e);}catch(i){o.push(i);}if(o.length===r.length)throw new Error(`All adapters failed to remove: ${o.map(t=>t.message).join(", ")}`)}async exists(e){let r=[this.primary,...this.fallbacks];for(let o of r)try{if(await o.exists(e))return !0}catch(t){console.warn(`Failed to check existence with ${o.name}:`,t);}return false}async list(e){try{return await this.primary.list?.(e)||[]}catch(r){console.warn("Failed to list with primary adapter:",r);for(let o of this.fallbacks)try{return await o.list?.(e)||[]}catch(t){console.warn(`Failed to list with fallback ${o.name}:`,t);}return []}}};var B={localStorage(n={}){return {adapter:new m,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...n}},sessionStorage(n={}){return {adapter:new y,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...n}},memory(n={}){return {adapter:new p,debounceMs:0,autoSave:true,saveOnStepChange:true,...n}},custom(n,e={}){return {adapter:n,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...e}}};function E(n,e,r={}){let o=e||new p;return {adapter:{name:`resilient-${n.name}`,async save(i,a){try{await n.save(i,a);}catch(s){console.warn("Primary persistence failed, using fallback:",s),await o.save(i,a);}},async load(i){try{let a=await n.load(i);if(a)return a}catch(a){console.warn("Primary persistence load failed, trying fallback:",a);}return await o.load(i)},async remove(i){let a=[];try{await n.remove(i);}catch(s){a.push(s);}try{await o.remove(i);}catch(s){a.push(s);}if(a.length===2)throw new Error(`Both adapters failed: ${a.map(s=>s.message).join(", ")}`)},async exists(i){try{if(await n.exists(i))return !0}catch(a){console.warn("Primary persistence exists check failed:",a);}try{return await o.exists(i)}catch(a){return console.warn("Fallback persistence exists check failed:",a),false}},async list(i){try{return await n.list?.(i)||[]}catch(a){console.warn("Primary persistence list failed:",a);try{return await o.list?.(i)||[]}catch(s){return console.warn("Fallback persistence list failed:",s),[]}}}},debounceMs:1e3,autoSave:true,saveOnStepChange:true,maxRetries:3,retryDelayMs:1e3,...r}}export{g as CompositeAdapter,m as LocalStorageAdapter,p as MemoryAdapter,y as SessionStorageAdapter,P as combineValidators,v as commonValidators,x as createConditionalValidator,R as createCustomValidator,E as createResilientPersistence,S as createValidationError,b as createValidationResult,f as createZodValidator,B as persistence,w as resolveRendererChildren,u as ril};
1
+ import {z}from'zod';function P(o,e){return typeof o=="function"?o(e):o}function b(o,e){return {...o,...e}}function h(o,e){let r=o.filter((n,t)=>o.indexOf(n)!==t);if(r.length>0)throw new Error(`Duplicate ${e} IDs: ${r.join(", ")}`)}function S(o,e,r){if(o.filter(t=>e.some(a=>!t[a])).length>0)throw new Error(`Missing required fields in ${r}: ${e.join(", ")}`)}var R=class{constructor(){this.counters=new Map;}next(e){let r=this.counters.get(e)||0;return this.counters.set(e,r+1),`${e}-${r+1}`}reset(e){e?this.counters.delete(e):this.counters.clear();}},y=class{constructor(){this.errors=[];}add(e,r,n){return this.errors.push({code:e,message:r,path:n}),this}addIf(e,r,n,t){return e&&this.add(r,n,t),this}build(){return [...this.errors]}hasErrors(){return this.errors.length>0}clear(){return this.errors=[],this}},V={hasValue:o=>o!=null&&o!=="",isArray:o=>Array.isArray(o),arrayMinLength:(o,e)=>o.length>=e,arrayMaxLength:(o,e)=>o.length<=e};function F(o){return Array.isArray(o)?o:[o]}function C(o){if(o===null||typeof o!="object")return o;if(o instanceof Date)return new Date(o.getTime());if(Array.isArray(o))return o.map(r=>C(r));let e={};for(let r in o)Object.prototype.hasOwnProperty.call(o,r)&&(e[r]=C(o[r]));return e}function g(o,e,r){let n={...o};for(let t in e)r&&!r.includes(t)||e[t]!==void 0&&(n[t]=e[t]);return n}var w=class o{constructor(){this.components=new Map;this.formRenderConfig={};this.workflowRenderConfig={};}static create(){return new o}addComponent(e,r){let n={id:e,type:e,...r};return this.components.set(e,n),this}configure(e){let r=["rowRenderer","bodyRenderer","submitButtonRenderer","fieldRenderer"],n=["stepperRenderer","nextButtonRenderer","previousButtonRenderer","skipButtonRenderer"],t={},a={};for(let[i,s]of Object.entries(e))r.includes(i)?t[i]=s:n.includes(i)&&(a[i]=s);return this.formRenderConfig=g(this.formRenderConfig,t),this.workflowRenderConfig=g(this.workflowRenderConfig,a),this}getFormRenderConfig(){return {...this.formRenderConfig}}getWorkflowRenderConfig(){return {...this.workflowRenderConfig}}getComponent(e){return this.components.get(e)}getAllComponents(){return Array.from(this.components.values())}hasComponent(e){return this.components.has(e)}removeComponent(e){return this.components.delete(e)}clear(){this.components.clear();}getStats(){let e=Array.from(this.components.values());return {total:e.length,byType:e.reduce((r,n)=>(r[n.type]=(r[n.type]||0)+1,r),{}),hasCustomRenderers:{row:!!this.formRenderConfig.rowRenderer,body:!!this.formRenderConfig.bodyRenderer,submitButton:!!this.formRenderConfig.submitButtonRenderer,field:!!this.formRenderConfig.fieldRenderer,stepper:!!this.workflowRenderConfig.stepperRenderer,workflowNextButton:!!this.workflowRenderConfig.nextButtonRenderer,workflowPreviousButton:!!this.workflowRenderConfig.previousButtonRenderer,workflowSkipButton:!!this.workflowRenderConfig.skipButtonRenderer}}}validate(){let e=new y,r=Array.from(this.components.values()),n=r.map(a=>a.id);try{h(n,"component");}catch(a){e.add("DUPLICATE_IDS",a instanceof Error?a.message:String(a));}let t=r.filter(a=>!a.renderer);return e.addIf(t.length>0,"MISSING_RENDERER",`Components without renderer: ${t.map(a=>a.id).join(", ")}`),e.build().map(a=>a.message)}};var p=o=>async e=>{try{return await o.parseAsync(e),{isValid:!0,errors:[]}}catch(r){return r&&typeof r=="object"&&"errors"in r&&Array.isArray(r.errors)?{isValid:false,errors:r.errors.map(n=>({code:n.code,message:n.message,path:n.path?n.path.map(String):[]}))}:{isValid:false,errors:[{code:"unknown",message:r instanceof Error?r.message:"Unknown validation error"}]}}},k=o=>async(e,r,n)=>{try{let t=await o(e,r);return t===!0?{isValid:!0,errors:[]}:t===!1?{isValid:!1,errors:[{code:"validation_failed",message:"Validation failed"}]}:{isValid:!1,errors:[{code:"validation_failed",message:String(t)}]}}catch(t){return {isValid:false,errors:[{code:"validation_error",message:t instanceof Error?t.message:"Validation error"}]}}},D=(o,e="all")=>async(r,n,t)=>{let a=await Promise.all(o.map(d=>d(r,n,t)));if(e==="all"){let d=a.flatMap(l=>l.errors);return {isValid:a.every(l=>l.isValid),errors:d}}return a.some(d=>d.isValid)?{isValid:true,errors:[]}:{isValid:false,errors:a.flatMap(d=>d.errors)}},N=(o,e)=>async(r,n,t)=>o(r,n)?e(r,n,t):{isValid:true,errors:[]},I={required:(o="This field is required")=>k(e=>e==null||e===""?o:!0),email:(o="Invalid email format")=>p(z.string().email(o)),minLength:(o,e)=>p(z.string().min(o,e||`Minimum ${o} characters required`)),maxLength:(o,e)=>p(z.string().max(o,e||`Maximum ${o} characters allowed`)),pattern:(o,e="Invalid format")=>p(z.string().regex(o,e)),numberRange:(o,e,r)=>{let n=z.number();return o!==void 0&&(n=n.min(o,r||`Value must be at least ${o}`)),e!==void 0&&(n=n.max(e,r||`Value must be at most ${e}`)),p(n)},url:(o="Invalid URL format")=>p(z.string().url(o)),phoneNumber:(o="Invalid phone number format")=>p(z.string().regex(/^\+?[\d\s\-\(\)]+$/,o)),asyncValidation:(o,e=300)=>{let r=new Map;return (n,t,a)=>new Promise(i=>{let s=`${t.fieldId}-${JSON.stringify(n)}`;r.has(s)&&clearTimeout(r.get(s));let d=setTimeout(async()=>{try{let l=await o(n,t);i(l===!0?{isValid:!0,errors:[]}:{isValid:!1,errors:[{code:"async_validation_failed",message:typeof l=="string"?l:"Async validation failed"}]});}catch(l){i({isValid:false,errors:[{code:"async_validation_error",message:l instanceof Error?l.message:"Async validation error"}]});}finally{r.delete(s);}},e);r.set(s,d);})}},A=(o,e=[])=>({isValid:o,errors:e}),$=(o,e,r)=>({code:o,message:e,path:r});var m=class{constructor(){this.name="localStorage";}async save(e,r){try{localStorage.setItem(e,JSON.stringify(r));}catch(n){throw new Error(`Failed to save to localStorage: ${n}`)}}async load(e){try{let r=localStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from localStorage: ${r}`)}}async remove(e){try{localStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from localStorage: ${r}`)}}async exists(e){return localStorage.getItem(e)!==null}async list(e){let r=[];for(let n=0;n<localStorage.length;n++){let t=localStorage.key(n);t&&(!e||t.includes(e))&&r.push(t);}return r}},u=class{constructor(){this.name="sessionStorage";}async save(e,r){try{sessionStorage.setItem(e,JSON.stringify(r));}catch(n){throw new Error(`Failed to save to sessionStorage: ${n}`)}}async load(e){try{let r=sessionStorage.getItem(e);return r?JSON.parse(r):null}catch(r){throw new Error(`Failed to load from sessionStorage: ${r}`)}}async remove(e){try{sessionStorage.removeItem(e);}catch(r){throw new Error(`Failed to remove from sessionStorage: ${r}`)}}async exists(e){return sessionStorage.getItem(e)!==null}async list(e){let r=[];for(let n=0;n<sessionStorage.length;n++){let t=sessionStorage.key(n);t&&(!e||t.includes(e))&&r.push(t);}return r}},f=class{constructor(){this.name="memory";this.storage=new Map;}async save(e,r){this.storage.set(e,{...r});}async load(e){let r=this.storage.get(e);return r?{...r}:null}async remove(e){this.storage.delete(e);}async exists(e){return this.storage.has(e)}async list(e){let r=Array.from(this.storage.keys());return e?r.filter(n=>n.includes(e)):r}clear(){this.storage.clear();}},x=class{constructor(e,r=[]){this.primary=e;this.fallbacks=r;this.name="composite";}async save(e,r){let n=[this.primary,...this.fallbacks];for(let t of n)try{await t.save(e,r);return}catch(a){console.warn(`Failed to save with ${t.name}:`,a);}throw new Error("All persistence adapters failed to save")}async load(e){let r=[this.primary,...this.fallbacks];for(let n of r)try{let t=await n.load(e);if(t)return t}catch(t){console.warn(`Failed to load with ${n.name}:`,t);}return null}async remove(e){let r=[this.primary,...this.fallbacks],n=[];for(let t of r)try{await t.remove(e);}catch(a){n.push(a);}if(n.length===r.length)throw new Error(`All adapters failed to remove: ${n.map(t=>t.message).join(", ")}`)}async exists(e){let r=[this.primary,...this.fallbacks];for(let n of r)try{if(await n.exists(e))return !0}catch(t){console.warn(`Failed to check existence with ${n.name}:`,t);}return false}async list(e){try{return await this.primary.list?.(e)||[]}catch(r){console.warn("Failed to list with primary adapter:",r);for(let n of this.fallbacks)try{return await n.list?.(e)||[]}catch(t){console.warn(`Failed to list with fallback ${n.name}:`,t);}return []}}};var q={localStorage(o={}){return {adapter:new m,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...o}},sessionStorage(o={}){return {adapter:new u,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...o}},memory(o={}){return {adapter:new f,debounceMs:0,autoSave:true,saveOnStepChange:true,...o}},custom(o,e={}){return {adapter:o,debounceMs:1e3,autoSave:true,saveOnStepChange:true,...e}}};function _(o,e,r={}){let n=e||new f;return {adapter:{name:`resilient-${o.name}`,async save(a,i){try{await o.save(a,i);}catch(s){console.warn("Primary persistence failed, using fallback:",s),await n.save(a,i);}},async load(a){try{let i=await o.load(a);if(i)return i}catch(i){console.warn("Primary persistence load failed, trying fallback:",i);}return await n.load(a)},async remove(a){let i=[];try{await o.remove(a);}catch(s){i.push(s);}try{await n.remove(a);}catch(s){i.push(s);}if(i.length===2)throw new Error(`Both adapters failed: ${i.map(s=>s.message).join(", ")}`)},async exists(a){try{if(await o.exists(a))return !0}catch(i){console.warn("Primary persistence exists check failed:",i);}try{return await n.exists(a)}catch(i){return console.warn("Fallback persistence exists check failed:",i),false}},async list(a){try{return await o.list?.(a)||[]}catch(i){console.warn("Primary persistence list failed:",i);try{return await n.list?.(a)||[]}catch(s){return console.warn("Fallback persistence list failed:",s),[]}}}},debounceMs:1e3,autoSave:true,saveOnStepChange:true,maxRetries:3,retryDelayMs:1e3,...r}}export{x as CompositeAdapter,R as IdGenerator,m as LocalStorageAdapter,f as MemoryAdapter,u as SessionStorageAdapter,y as ValidationErrorBuilder,V as ValidationPatterns,D as combineValidators,I as commonValidators,g as configureObject,N as createConditionalValidator,k as createCustomValidator,_ as createResilientPersistence,$ as createValidationError,A as createValidationResult,p as createZodValidator,C as deepClone,h as ensureUnique,b as mergeInto,F as normalizeToArray,q as persistence,P as resolveRendererChildren,w as ril,S as validateRequired};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rilaykit/core",
3
- "version": "2.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Core types, configurations, and utilities for the RilayKit form library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",