@rilaykit/workflow 7.2.0 → 8.1.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
@@ -3,7 +3,8 @@ export * from '@rilaykit/core';
3
3
  import { form } from '@rilaykit/forms';
4
4
  export { form } from '@rilaykit/forms';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
- import React$1 from 'react';
6
+ import * as React$1 from 'react';
7
+ import React__default from 'react';
7
8
 
8
9
  interface WorkflowState {
9
10
  currentStepIndex: number;
@@ -14,39 +15,6 @@ interface WorkflowState {
14
15
  isTransitioning: boolean;
15
16
  isInitializing: boolean;
16
17
  }
17
- type WorkflowAction = {
18
- type: 'SET_CURRENT_STEP';
19
- stepIndex: number;
20
- } | {
21
- type: 'SET_STEP_DATA';
22
- data: Record<string, any>;
23
- stepId: string;
24
- } | {
25
- type: 'SET_ALL_DATA';
26
- data: Record<string, any>;
27
- } | {
28
- type: 'SET_FIELD_VALUE';
29
- fieldId: string;
30
- value: any;
31
- stepId: string;
32
- } | {
33
- type: 'SET_SUBMITTING';
34
- isSubmitting: boolean;
35
- } | {
36
- type: 'SET_TRANSITIONING';
37
- isTransitioning: boolean;
38
- } | {
39
- type: 'MARK_STEP_VISITED';
40
- stepIndex: number;
41
- stepId: string;
42
- } | {
43
- type: 'RESET_WORKFLOW';
44
- } | {
45
- type: 'LOAD_PERSISTED_STATE';
46
- state: Partial<WorkflowState>;
47
- } | {
48
- type: 'SET_INITIALIZATION_COMPLETE';
49
- };
50
18
  interface UseWorkflowStateProps {
51
19
  defaultValues?: Record<string, any>;
52
20
  persistence?: {
@@ -251,6 +219,30 @@ interface StepDefinition {
251
219
  * Controls visibility and skippable state
252
220
  */
253
221
  conditions?: StepConditionalBehavior;
222
+ /**
223
+ * Custom metadata for this step
224
+ * Allows storing arbitrary information that can be accessed via hooks and context
225
+ *
226
+ * This is useful for:
227
+ * - UI customization (icons, colors, themes)
228
+ * - Analytics tracking (categories, priorities, custom events)
229
+ * - Business logic flags (feature flags, permissions, workflow rules)
230
+ * - Integration data (external IDs, API endpoints, configuration)
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * {
235
+ * metadata: {
236
+ * icon: 'user-circle',
237
+ * category: 'personal-info',
238
+ * analytics: { trackCompletion: true, priority: 'high' },
239
+ * ui: { theme: 'primary', showProgress: true },
240
+ * business: { requiresApproval: false, estimatedTime: 120 }
241
+ * }
242
+ * }
243
+ * ```
244
+ */
245
+ metadata?: Record<string, any>;
254
246
  /**
255
247
  * Callback function that executes after successful validation and before moving to next step
256
248
  * Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
@@ -756,22 +748,6 @@ interface ConditionEvaluationResult {
756
748
  * @returns Evaluated condition results
757
749
  */
758
750
  declare function useConditionEvaluation(conditions?: ConditionalBehavior, workflowData?: Record<string, any>, defaultState?: Partial<ConditionEvaluationResult>): ConditionEvaluationResult;
759
- /**
760
- * Hook to evaluate multiple field conditions at once
761
- *
762
- * @param fieldsWithConditions - Map of field IDs to their conditional behaviors
763
- * @param workflowData - Current workflow data to evaluate against
764
- * @returns Map of field IDs to their evaluated conditions
765
- */
766
- declare function useMultipleConditionEvaluation(fieldsWithConditions: Record<string, ConditionalBehavior | undefined>, workflowData?: Record<string, any>): Record<string, ConditionEvaluationResult>;
767
- /**
768
- * Hook to evaluate multiple step conditions at once using numeric indices
769
- *
770
- * @param stepsWithConditions - Map of step indices to their conditional behaviors
771
- * @param workflowData - Current workflow data to evaluate against
772
- * @returns Map of step indices to their evaluated conditions
773
- */
774
- declare function useMultipleStepConditionEvaluation(stepsWithConditions: Record<number, ConditionalBehavior | undefined>, workflowData?: Record<string, any>): Record<number, ConditionEvaluationResult>;
775
751
 
776
752
  /**
777
753
  * @fileoverview Persistence hook for Rilay workflows
@@ -819,6 +795,100 @@ interface UsePersistenceProps {
819
795
  */
820
796
  declare function usePersistence({ workflowId, workflowState, adapter, options, userId, }: UsePersistenceProps): UsePersistenceReturn;
821
797
 
798
+ /**
799
+ * Hook return type for step metadata access
800
+ */
801
+ interface UseStepMetadataReturn {
802
+ /**
803
+ * Metadata for the current step
804
+ */
805
+ current: Record<string, any> | undefined;
806
+ /**
807
+ * Get metadata for a specific step by ID
808
+ * @param stepId - The ID of the step to get metadata for
809
+ * @returns The metadata object or undefined if step not found
810
+ */
811
+ getByStepId: (stepId: string) => Record<string, any> | undefined;
812
+ /**
813
+ * Get metadata for a specific step by index
814
+ * @param stepIndex - The index of the step to get metadata for
815
+ * @returns The metadata object or undefined if step not found
816
+ */
817
+ getByStepIndex: (stepIndex: number) => Record<string, any> | undefined;
818
+ /**
819
+ * Check if current step has specific metadata key
820
+ * @param key - The metadata key to check for
821
+ * @returns True if the key exists in current step metadata
822
+ */
823
+ hasCurrentKey: (key: string) => boolean;
824
+ /**
825
+ * Get specific metadata value from current step
826
+ * @param key - The metadata key to retrieve
827
+ * @param defaultValue - Default value if key doesn't exist
828
+ * @returns The metadata value or default value
829
+ */
830
+ getCurrentValue: <T = any>(key: string, defaultValue?: T) => T;
831
+ /**
832
+ * Get all steps with their metadata
833
+ * @returns Array of objects containing step info and metadata
834
+ */
835
+ getAllStepsMetadata: () => Array<{
836
+ id: string;
837
+ title: string;
838
+ index: number;
839
+ metadata: Record<string, any> | undefined;
840
+ }>;
841
+ /**
842
+ * Find steps by metadata criteria
843
+ * @param predicate - Function to test each step's metadata
844
+ * @returns Array of step IDs that match the criteria
845
+ */
846
+ findStepsByMetadata: (predicate: (metadata: Record<string, any> | undefined, stepId: string, stepIndex: number) => boolean) => string[];
847
+ }
848
+ /**
849
+ * Hook to access and work with step metadata in workflows
850
+ *
851
+ * This hook provides convenient methods to access metadata for the current step
852
+ * or any other step in the workflow. It's useful for UI customization, analytics,
853
+ * business logic, and integration scenarios.
854
+ *
855
+ * @returns Object containing metadata access methods and current step metadata
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * function MyComponent() {
860
+ * const {
861
+ * current,
862
+ * getCurrentValue,
863
+ * hasCurrentKey,
864
+ * getByStepId,
865
+ * findStepsByMetadata
866
+ * } = useStepMetadata();
867
+ *
868
+ * // Access current step metadata
869
+ * const stepIcon = getCurrentValue('icon', 'default-icon');
870
+ * const hasAnalytics = hasCurrentKey('analytics');
871
+ *
872
+ * // Find steps with specific metadata
873
+ * const importantSteps = findStepsByMetadata(
874
+ * (metadata) => metadata?.priority === 'high'
875
+ * );
876
+ *
877
+ * // Get metadata from specific step
878
+ * const paymentStepMeta = getByStepId('payment-step');
879
+ *
880
+ * return (
881
+ * <div>
882
+ * <Icon name={stepIcon} />
883
+ * {hasAnalytics && <AnalyticsTracker />}
884
+ * <p>Important steps: {importantSteps.length}</p>
885
+ * </div>
886
+ * );
887
+ * }
888
+ * ```
889
+ */
890
+ declare function useStepMetadata(): UseStepMetadataReturn;
891
+
822
892
  interface UseWorkflowAnalyticsProps {
823
893
  workflowConfig: WorkflowConfig;
824
894
  workflowState: WorkflowState;
@@ -911,6 +981,7 @@ interface WorkflowContextValue {
911
981
  context: WorkflowContext;
912
982
  formConfig?: FormConfiguration;
913
983
  conditionsHelpers: UseWorkflowConditionsReturn;
984
+ currentStepMetadata?: Record<string, any>;
914
985
  goToStep: (stepIndex: number) => Promise<boolean>;
915
986
  goNext: () => Promise<boolean>;
916
987
  goPrevious: () => Promise<boolean>;
@@ -930,7 +1001,7 @@ interface WorkflowContextValue {
930
1001
  persistenceError?: Error | null;
931
1002
  }
932
1003
  interface WorkflowProviderProps {
933
- children: React$1.ReactNode;
1004
+ children: React__default.ReactNode;
934
1005
  workflowConfig: WorkflowConfig;
935
1006
  defaultValues?: Record<string, any>;
936
1007
  onStepChange?: (fromStep: number, toStep: number, context: WorkflowContext) => void;
@@ -941,7 +1012,7 @@ declare function WorkflowProvider({ children, workflowConfig, defaultValues, onS
941
1012
  declare function useWorkflowContext(): WorkflowContextValue;
942
1013
 
943
1014
  type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'> & {
944
- children: React$1.ReactNode;
1015
+ children: React__default.ReactNode;
945
1016
  workflowConfig: WorkflowConfig | flow;
946
1017
  };
947
1018
  /**
@@ -952,17 +1023,42 @@ type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'>
952
1023
  */
953
1024
  declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps): react_jsx_runtime.JSX.Element;
954
1025
 
1026
+ interface WorkflowBodyProps {
1027
+ stepId?: string;
1028
+ children?: React.ReactNode;
1029
+ }
955
1030
  /**
956
1031
  * Renders the main content of the current workflow step.
957
1032
  * Simple component that renders either the children or FormBody by default.
958
1033
  */
959
- declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
1034
+ declare function WorkflowBody({ stepId, children }: WorkflowBodyProps): string | number | boolean | Iterable<React$1.ReactNode> | react_jsx_runtime.JSX.Element | null;
960
1035
 
961
- declare function WorkflowNextButton({ className, ...props }: ComponentRendererBaseProps<WorkflowNextButtonRendererProps>): react_jsx_runtime.JSX.Element;
1036
+ interface WorkflowNextButtonProps extends ComponentRendererBaseProps<WorkflowNextButtonRendererProps> {
1037
+ /**
1038
+ * Override the isSubmitting state from workflow/form context
1039
+ * If provided, this value will be used instead of the computed isSubmitting state
1040
+ */
1041
+ isSubmitting?: boolean;
1042
+ }
1043
+ declare function WorkflowNextButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowNextButtonProps): react_jsx_runtime.JSX.Element;
962
1044
 
963
- declare function WorkflowPreviousButton({ className, ...props }: ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps>): react_jsx_runtime.JSX.Element;
1045
+ interface WorkflowPreviousButtonProps extends ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps> {
1046
+ /**
1047
+ * Override the isSubmitting state from workflow/form context
1048
+ * If provided, this value will be used instead of the computed isSubmitting state
1049
+ */
1050
+ isSubmitting?: boolean;
1051
+ }
1052
+ declare function WorkflowPreviousButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowPreviousButtonProps): react_jsx_runtime.JSX.Element;
964
1053
 
965
- declare function WorkflowSkipButton({ className, ...props }: ComponentRendererBaseProps<WorkflowSkipButtonRendererProps>): react_jsx_runtime.JSX.Element;
1054
+ interface WorkflowSkipButtonProps extends ComponentRendererBaseProps<WorkflowSkipButtonRendererProps> {
1055
+ /**
1056
+ * Override the isSubmitting state from workflow/form context
1057
+ * If provided, this value will be used instead of the computed isSubmitting state
1058
+ */
1059
+ isSubmitting?: boolean;
1060
+ }
1061
+ declare function WorkflowSkipButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowSkipButtonProps): react_jsx_runtime.JSX.Element;
966
1062
 
967
1063
  interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
968
1064
  onStepClick?: (stepIndex: number) => void;
@@ -1155,4 +1251,4 @@ declare class RilayLicenseManager {
1155
1251
  }>;
1156
1252
  }
1157
1253
 
1158
- export { type ConditionEvaluationResult, type LicensePayload, type LicensePlan, type LicenseResult, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, RilayLicenseManager, type StepConditionResult, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowAnalyticsProps, type UseWorkflowAnalyticsReturn, type UseWorkflowConditionsProps, type UseWorkflowConditionsReturn, type UseWorkflowNavigationProps, type UseWorkflowNavigationReturn, type UseWorkflowStateProps, type UseWorkflowSubmissionProps, type UseWorkflowSubmissionReturn, Workflow, type WorkflowAction, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, type WorkflowState, WorkflowStepper, createFlow, debounce, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useMultipleConditionEvaluation, useMultipleStepConditionEvaluation, usePersistence, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowNavigation, useWorkflowState, useWorkflowSubmission, validatePersistedData, workflowStateToPersisted };
1254
+ export { type LicensePayload, type LicensePlan, type LicenseResult, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, RilayLicenseManager, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, createFlow, debounce, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, usePersistence, useStepMetadata, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowNavigation, useWorkflowState, useWorkflowSubmission, validatePersistedData, workflowStateToPersisted };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,8 @@ export * from '@rilaykit/core';
3
3
  import { form } from '@rilaykit/forms';
4
4
  export { form } from '@rilaykit/forms';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
- import React$1 from 'react';
6
+ import * as React$1 from 'react';
7
+ import React__default from 'react';
7
8
 
8
9
  interface WorkflowState {
9
10
  currentStepIndex: number;
@@ -14,39 +15,6 @@ interface WorkflowState {
14
15
  isTransitioning: boolean;
15
16
  isInitializing: boolean;
16
17
  }
17
- type WorkflowAction = {
18
- type: 'SET_CURRENT_STEP';
19
- stepIndex: number;
20
- } | {
21
- type: 'SET_STEP_DATA';
22
- data: Record<string, any>;
23
- stepId: string;
24
- } | {
25
- type: 'SET_ALL_DATA';
26
- data: Record<string, any>;
27
- } | {
28
- type: 'SET_FIELD_VALUE';
29
- fieldId: string;
30
- value: any;
31
- stepId: string;
32
- } | {
33
- type: 'SET_SUBMITTING';
34
- isSubmitting: boolean;
35
- } | {
36
- type: 'SET_TRANSITIONING';
37
- isTransitioning: boolean;
38
- } | {
39
- type: 'MARK_STEP_VISITED';
40
- stepIndex: number;
41
- stepId: string;
42
- } | {
43
- type: 'RESET_WORKFLOW';
44
- } | {
45
- type: 'LOAD_PERSISTED_STATE';
46
- state: Partial<WorkflowState>;
47
- } | {
48
- type: 'SET_INITIALIZATION_COMPLETE';
49
- };
50
18
  interface UseWorkflowStateProps {
51
19
  defaultValues?: Record<string, any>;
52
20
  persistence?: {
@@ -251,6 +219,30 @@ interface StepDefinition {
251
219
  * Controls visibility and skippable state
252
220
  */
253
221
  conditions?: StepConditionalBehavior;
222
+ /**
223
+ * Custom metadata for this step
224
+ * Allows storing arbitrary information that can be accessed via hooks and context
225
+ *
226
+ * This is useful for:
227
+ * - UI customization (icons, colors, themes)
228
+ * - Analytics tracking (categories, priorities, custom events)
229
+ * - Business logic flags (feature flags, permissions, workflow rules)
230
+ * - Integration data (external IDs, API endpoints, configuration)
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * {
235
+ * metadata: {
236
+ * icon: 'user-circle',
237
+ * category: 'personal-info',
238
+ * analytics: { trackCompletion: true, priority: 'high' },
239
+ * ui: { theme: 'primary', showProgress: true },
240
+ * business: { requiresApproval: false, estimatedTime: 120 }
241
+ * }
242
+ * }
243
+ * ```
244
+ */
245
+ metadata?: Record<string, any>;
254
246
  /**
255
247
  * Callback function that executes after successful validation and before moving to next step
256
248
  * Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
@@ -756,22 +748,6 @@ interface ConditionEvaluationResult {
756
748
  * @returns Evaluated condition results
757
749
  */
758
750
  declare function useConditionEvaluation(conditions?: ConditionalBehavior, workflowData?: Record<string, any>, defaultState?: Partial<ConditionEvaluationResult>): ConditionEvaluationResult;
759
- /**
760
- * Hook to evaluate multiple field conditions at once
761
- *
762
- * @param fieldsWithConditions - Map of field IDs to their conditional behaviors
763
- * @param workflowData - Current workflow data to evaluate against
764
- * @returns Map of field IDs to their evaluated conditions
765
- */
766
- declare function useMultipleConditionEvaluation(fieldsWithConditions: Record<string, ConditionalBehavior | undefined>, workflowData?: Record<string, any>): Record<string, ConditionEvaluationResult>;
767
- /**
768
- * Hook to evaluate multiple step conditions at once using numeric indices
769
- *
770
- * @param stepsWithConditions - Map of step indices to their conditional behaviors
771
- * @param workflowData - Current workflow data to evaluate against
772
- * @returns Map of step indices to their evaluated conditions
773
- */
774
- declare function useMultipleStepConditionEvaluation(stepsWithConditions: Record<number, ConditionalBehavior | undefined>, workflowData?: Record<string, any>): Record<number, ConditionEvaluationResult>;
775
751
 
776
752
  /**
777
753
  * @fileoverview Persistence hook for Rilay workflows
@@ -819,6 +795,100 @@ interface UsePersistenceProps {
819
795
  */
820
796
  declare function usePersistence({ workflowId, workflowState, adapter, options, userId, }: UsePersistenceProps): UsePersistenceReturn;
821
797
 
798
+ /**
799
+ * Hook return type for step metadata access
800
+ */
801
+ interface UseStepMetadataReturn {
802
+ /**
803
+ * Metadata for the current step
804
+ */
805
+ current: Record<string, any> | undefined;
806
+ /**
807
+ * Get metadata for a specific step by ID
808
+ * @param stepId - The ID of the step to get metadata for
809
+ * @returns The metadata object or undefined if step not found
810
+ */
811
+ getByStepId: (stepId: string) => Record<string, any> | undefined;
812
+ /**
813
+ * Get metadata for a specific step by index
814
+ * @param stepIndex - The index of the step to get metadata for
815
+ * @returns The metadata object or undefined if step not found
816
+ */
817
+ getByStepIndex: (stepIndex: number) => Record<string, any> | undefined;
818
+ /**
819
+ * Check if current step has specific metadata key
820
+ * @param key - The metadata key to check for
821
+ * @returns True if the key exists in current step metadata
822
+ */
823
+ hasCurrentKey: (key: string) => boolean;
824
+ /**
825
+ * Get specific metadata value from current step
826
+ * @param key - The metadata key to retrieve
827
+ * @param defaultValue - Default value if key doesn't exist
828
+ * @returns The metadata value or default value
829
+ */
830
+ getCurrentValue: <T = any>(key: string, defaultValue?: T) => T;
831
+ /**
832
+ * Get all steps with their metadata
833
+ * @returns Array of objects containing step info and metadata
834
+ */
835
+ getAllStepsMetadata: () => Array<{
836
+ id: string;
837
+ title: string;
838
+ index: number;
839
+ metadata: Record<string, any> | undefined;
840
+ }>;
841
+ /**
842
+ * Find steps by metadata criteria
843
+ * @param predicate - Function to test each step's metadata
844
+ * @returns Array of step IDs that match the criteria
845
+ */
846
+ findStepsByMetadata: (predicate: (metadata: Record<string, any> | undefined, stepId: string, stepIndex: number) => boolean) => string[];
847
+ }
848
+ /**
849
+ * Hook to access and work with step metadata in workflows
850
+ *
851
+ * This hook provides convenient methods to access metadata for the current step
852
+ * or any other step in the workflow. It's useful for UI customization, analytics,
853
+ * business logic, and integration scenarios.
854
+ *
855
+ * @returns Object containing metadata access methods and current step metadata
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * function MyComponent() {
860
+ * const {
861
+ * current,
862
+ * getCurrentValue,
863
+ * hasCurrentKey,
864
+ * getByStepId,
865
+ * findStepsByMetadata
866
+ * } = useStepMetadata();
867
+ *
868
+ * // Access current step metadata
869
+ * const stepIcon = getCurrentValue('icon', 'default-icon');
870
+ * const hasAnalytics = hasCurrentKey('analytics');
871
+ *
872
+ * // Find steps with specific metadata
873
+ * const importantSteps = findStepsByMetadata(
874
+ * (metadata) => metadata?.priority === 'high'
875
+ * );
876
+ *
877
+ * // Get metadata from specific step
878
+ * const paymentStepMeta = getByStepId('payment-step');
879
+ *
880
+ * return (
881
+ * <div>
882
+ * <Icon name={stepIcon} />
883
+ * {hasAnalytics && <AnalyticsTracker />}
884
+ * <p>Important steps: {importantSteps.length}</p>
885
+ * </div>
886
+ * );
887
+ * }
888
+ * ```
889
+ */
890
+ declare function useStepMetadata(): UseStepMetadataReturn;
891
+
822
892
  interface UseWorkflowAnalyticsProps {
823
893
  workflowConfig: WorkflowConfig;
824
894
  workflowState: WorkflowState;
@@ -911,6 +981,7 @@ interface WorkflowContextValue {
911
981
  context: WorkflowContext;
912
982
  formConfig?: FormConfiguration;
913
983
  conditionsHelpers: UseWorkflowConditionsReturn;
984
+ currentStepMetadata?: Record<string, any>;
914
985
  goToStep: (stepIndex: number) => Promise<boolean>;
915
986
  goNext: () => Promise<boolean>;
916
987
  goPrevious: () => Promise<boolean>;
@@ -930,7 +1001,7 @@ interface WorkflowContextValue {
930
1001
  persistenceError?: Error | null;
931
1002
  }
932
1003
  interface WorkflowProviderProps {
933
- children: React$1.ReactNode;
1004
+ children: React__default.ReactNode;
934
1005
  workflowConfig: WorkflowConfig;
935
1006
  defaultValues?: Record<string, any>;
936
1007
  onStepChange?: (fromStep: number, toStep: number, context: WorkflowContext) => void;
@@ -941,7 +1012,7 @@ declare function WorkflowProvider({ children, workflowConfig, defaultValues, onS
941
1012
  declare function useWorkflowContext(): WorkflowContextValue;
942
1013
 
943
1014
  type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'> & {
944
- children: React$1.ReactNode;
1015
+ children: React__default.ReactNode;
945
1016
  workflowConfig: WorkflowConfig | flow;
946
1017
  };
947
1018
  /**
@@ -952,17 +1023,42 @@ type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'>
952
1023
  */
953
1024
  declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps): react_jsx_runtime.JSX.Element;
954
1025
 
1026
+ interface WorkflowBodyProps {
1027
+ stepId?: string;
1028
+ children?: React.ReactNode;
1029
+ }
955
1030
  /**
956
1031
  * Renders the main content of the current workflow step.
957
1032
  * Simple component that renders either the children or FormBody by default.
958
1033
  */
959
- declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
1034
+ declare function WorkflowBody({ stepId, children }: WorkflowBodyProps): string | number | boolean | Iterable<React$1.ReactNode> | react_jsx_runtime.JSX.Element | null;
960
1035
 
961
- declare function WorkflowNextButton({ className, ...props }: ComponentRendererBaseProps<WorkflowNextButtonRendererProps>): react_jsx_runtime.JSX.Element;
1036
+ interface WorkflowNextButtonProps extends ComponentRendererBaseProps<WorkflowNextButtonRendererProps> {
1037
+ /**
1038
+ * Override the isSubmitting state from workflow/form context
1039
+ * If provided, this value will be used instead of the computed isSubmitting state
1040
+ */
1041
+ isSubmitting?: boolean;
1042
+ }
1043
+ declare function WorkflowNextButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowNextButtonProps): react_jsx_runtime.JSX.Element;
962
1044
 
963
- declare function WorkflowPreviousButton({ className, ...props }: ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps>): react_jsx_runtime.JSX.Element;
1045
+ interface WorkflowPreviousButtonProps extends ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps> {
1046
+ /**
1047
+ * Override the isSubmitting state from workflow/form context
1048
+ * If provided, this value will be used instead of the computed isSubmitting state
1049
+ */
1050
+ isSubmitting?: boolean;
1051
+ }
1052
+ declare function WorkflowPreviousButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowPreviousButtonProps): react_jsx_runtime.JSX.Element;
964
1053
 
965
- declare function WorkflowSkipButton({ className, ...props }: ComponentRendererBaseProps<WorkflowSkipButtonRendererProps>): react_jsx_runtime.JSX.Element;
1054
+ interface WorkflowSkipButtonProps extends ComponentRendererBaseProps<WorkflowSkipButtonRendererProps> {
1055
+ /**
1056
+ * Override the isSubmitting state from workflow/form context
1057
+ * If provided, this value will be used instead of the computed isSubmitting state
1058
+ */
1059
+ isSubmitting?: boolean;
1060
+ }
1061
+ declare function WorkflowSkipButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowSkipButtonProps): react_jsx_runtime.JSX.Element;
966
1062
 
967
1063
  interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
968
1064
  onStepClick?: (stepIndex: number) => void;
@@ -1155,4 +1251,4 @@ declare class RilayLicenseManager {
1155
1251
  }>;
1156
1252
  }
1157
1253
 
1158
- export { type ConditionEvaluationResult, type LicensePayload, type LicensePlan, type LicenseResult, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, RilayLicenseManager, type StepConditionResult, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowAnalyticsProps, type UseWorkflowAnalyticsReturn, type UseWorkflowConditionsProps, type UseWorkflowConditionsReturn, type UseWorkflowNavigationProps, type UseWorkflowNavigationReturn, type UseWorkflowStateProps, type UseWorkflowSubmissionProps, type UseWorkflowSubmissionReturn, Workflow, type WorkflowAction, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, type WorkflowState, WorkflowStepper, createFlow, debounce, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useMultipleConditionEvaluation, useMultipleStepConditionEvaluation, usePersistence, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowNavigation, useWorkflowState, useWorkflowSubmission, validatePersistedData, workflowStateToPersisted };
1254
+ export { type LicensePayload, type LicensePlan, type LicenseResult, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, RilayLicenseManager, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, createFlow, debounce, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, usePersistence, useStepMetadata, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowNavigation, useWorkflowState, useWorkflowSubmission, validatePersistedData, workflowStateToPersisted };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),react=require('react'),pe=require('@noble/ed25519'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var pe__namespace=/*#__PURE__*/_interopNamespace(pe);var L=class r{constructor(e,t,i,o){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=t,this.workflowName=i,this.workflowDescription=o;}static create(e,t,i,o){return new r(e,t,i,o)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,onAfterValidation:e.onAfterValidation}}addStep(e){let t=core.normalizeToArray(e);for(let i of t){let o=this.createStepFromDefinition(i);this.steps.push(o);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(t){throw new Error(`Failed to install plugin "${e.name}": ${t instanceof Error?t.message:String(t)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let t=e.dependencies.filter(i=>!this.plugins.some(o=>o.name===i));if(t.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${t.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(t=>t.name!==e),this}updateStep(e,t){let i=this.steps.findIndex(o=>o.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[i]={...this.steps[i],...t},this}addStepConditions(e,t){let i=this.steps.findIndex(s=>s.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);let o={...this.steps[i].conditions,...t};return this.steps[i]={...this.steps[i],conditions:o},this}removeStep(e){return this.steps=this.steps.filter(t=>t.id!==e),this}getStep(e){return this.steps.find(t=>t.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,t){let i=new r(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return i.steps=core.deepClone(this.steps),i.analytics=this.analytics?core.deepClone(this.analytics):void 0,i.persistenceConfig=this.persistenceConfig?core.deepClone(this.persistenceConfig):void 0,i.plugins=[...this.plugins],i}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(i=>i.id);try{core.ensureUnique(t,"step");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of this.plugins)if(i.dependencies){let o=i.dependencies.filter(s=>!this.plugins.some(n=>n.name===s));o.length>0&&e.push(`Plugin "${i.name}" requires missing dependencies: ${o.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((i,o)=>i+o.formConfig.allFields.length,0),t=this.steps.map(i=>i.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:t.length>0?Math.max(...t):0,minFieldsInStep:t.length>0?Math.min(...t):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function Fe(r,e,t,i){return L.create(r,e,t,i)}core.ril.prototype.flow=function(r,e,t){return L.create(this,r,e,t)};var Oe=1751361139160,Ve="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",v=class v{static async setLicenseKey(e){v.licenseKey=e||"",v.licenseKey?v.licenseResult=await v.validateLicense():v.licenseResult={valid:false,error:"MISSING"},v.isInitialized=true;}static async validateLicense(){if(!v.licenseKey)return {valid:false,error:"MISSING"};try{if(!v.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=v.licenseKey.slice(4),i=v.base64ToString(e).split(".");if(i.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[o,s,n]=i,l=`${o}.${s}`,m=new TextEncoder().encode(l),a=n.match(/.{2}/g);if(!a)return {valid:!1,error:"INVALID"};let S=new Uint8Array(a.map(W=>Number.parseInt(W,16))),y=v.hexToBytes(Ve);if(!await pe__namespace.verify(S,m,y))return {valid:!1,error:"SIGNATURE_INVALID"};let b=v.base64ToString(s.replace(/-/g,"+").replace(/_/g,"/")),f=JSON.parse(b),c=Math.floor(Date.now()/1e3);return f.e<c?{valid:!1,error:"EXPIRED",data:v.decompressPayload(f)}:Oe>f.e*1e3?{valid:!1,error:"EXPIRED",data:v.decompressPayload(f)}:f.p===void 0||!f.c||!f.i||!f.e||!f.t?{valid:!1,error:"INVALID"}:{valid:!0,data:v.decompressPayload(f)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let t=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)t[i/2]=Number.parseInt(e.substring(i,i+2),16);return t}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",o=0,s=e.replace(/[^A-Za-z0-9+/]/g,"");for(;o<s.length;){let n=t.indexOf(s.charAt(o++)),l=t.indexOf(s.charAt(o++)),m=t.indexOf(s.charAt(o++)),a=t.indexOf(s.charAt(o++)),S=n<<18|l<<12|m<<6|a;i+=String.fromCharCode(S>>16&255),m!==64&&(i+=String.fromCharCode(S>>8&255)),a!==64&&(i+=String.fromCharCode(S&255));}return i}static getLicenseResult(){return v.isInitialized?v.licenseResult?v.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!v.getLicenseResult().valid}static getWatermarkMessage(){let e=v.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=v.getLicenseResult();if(e.valid)return;let i={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${i}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=v.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};v.licenseKey="",v.licenseResult=null,v.isInitialized=false;var F=v;function ce(r,e={},t={}){return react.useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=o=>{try{let s;return o&&typeof o=="object"&&"build"in o?s=o.build():s=o,core.evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:r.visible?i(r.visible):true,disabled:r.disabled?i(r.disabled):false,required:r.required?i(r.required):false,readonly:r.readonly?i(r.readonly):false}},[r,e,t])}function de(r,e={}){return react.useMemo(()=>{let t={};for(let[i,o]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},o){let s=n=>{try{return n&&typeof n=="object"&&"build"in n?core.evaluateCondition(n.build(),e):core.evaluateCondition(n,e)}catch(l){return console.warn(`Error evaluating condition for field ${i}:`,l),false}};t[i]={visible:o.visible?s(o.visible):true,disabled:o.disabled?s(o.disabled):false,required:o.required?s(o.required):false,readonly:o.readonly?s(o.readonly):false};}return t},[r,e])}function ue(r,e={}){return react.useMemo(()=>{let t={};for(let[i,o]of Object.entries(r)){let s=Number.parseInt(i,10);if(t[s]={visible:true,disabled:false,required:false,readonly:false},o){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?core.evaluateCondition(l.build(),e):core.evaluateCondition(l,e)}catch(m){return console.warn(`Error evaluating condition for step ${s}:`,m),false}};t[s]={visible:o.visible?n(o.visible):true,disabled:o.disabled?n(o.disabled):false,required:o.required?n(o.required):false,readonly:o.readonly?n(o.readonly):false};}}return t},[r,e])}var D=class extends Error{constructor(t,i,o){super(`[WorkflowPersistence] ${t} (Code: ${i})`);this.code=i;this.cause=o;this.name="WorkflowPersistenceError";}};function X(r,e,t){return {workflowId:r,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:t}}function fe(r){return {currentStepIndex:r.currentStepIndex,allData:{...r.allData},stepData:{...r.stepData},visitedSteps:new Set(r.visitedSteps),isSubmitting:false,isTransitioning:false}}function _e(r){if(!r||typeof r!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let t of e)if(!(t in r))return false;return !(typeof r.workflowId!="string"||typeof r.currentStepIndex!="number"||typeof r.allData!="object"||typeof r.stepData!="object"||!Array.isArray(r.visitedSteps)||typeof r.lastSaved!="number")}function H(r,e){return e?`${e}:${r}`:r}function Z(r,e){let t=null;return (...i)=>{t&&clearTimeout(t),t=setTimeout(()=>{r(...i);},e);}}function Be(r,e,t="persist"){let i=fe(e);switch(t){case "persist":return {...i,isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};case "current":return {...r,visitedSteps:new Set([...r.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:r.currentStepIndex,allData:{...i.allData,...r.allData},stepData:{...i.stepData,...r.stepData},visitedSteps:new Set([...i.visitedSteps,...r.visitedSteps]),isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};default:return i}}function Q({workflowId:r,workflowState:e,adapter:t,options:i={},userId:o}){let[s,n]=react.useState(false),[l,m]=react.useState(null),[a,S]=react.useState(false),y=react.useRef(t),x=react.useRef(i),b=react.useRef({hasPendingChanges:false});react.useEffect(()=>{y.current=t,x.current=i;},[t,i]);let f=H(x.current.storageKey||r,o),c=react.useCallback(()=>{m(null);},[]),P=react.useCallback((u,k)=>{let C=u instanceof D?u:new D(`${k} failed: ${u.message}`,"OPERATION_FAILED",u);m(C),console.error("[WorkflowPersistence]",C);},[]),W=react.useCallback(async u=>{c(),n(true);try{let k=X(r,u,x.current.metadata);await y.current.save(f,k),b.current.lastSavedState={...u},b.current.hasPendingChanges=!1;}catch(k){throw P(k,"Save"),k}finally{n(false);}},[r,f,c,P]),d=react.useRef(Z(async u=>{try{await W(u);}catch(k){console.debug("[WorkflowPersistence] Auto-save failed:",k);}},i.debounceMs||500)),h=react.useCallback((u,k)=>k?u.currentStepIndex!==k.currentStepIndex||JSON.stringify(u.allData)!==JSON.stringify(k.allData)||JSON.stringify(u.stepData)!==JSON.stringify(k.stepData)||u.visitedSteps.size!==k.visitedSteps.size||!Array.from(u.visitedSteps).every(C=>k.visitedSteps.has(C)):true,[]),I=react.useCallback(async()=>{c(),S(true);try{let u=await y.current.load(f);return u&&(b.current.lastSavedState={currentStepIndex:u.currentStepIndex,allData:u.allData,stepData:u.stepData,visitedSteps:new Set(u.visitedSteps),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},b.current.hasPendingChanges=!1),u}catch(u){return P(u,"Load"),null}finally{setTimeout(()=>S(false),100);}},[f,c,P]),R=react.useCallback(async()=>{c();try{await y.current.remove(f),b.current.lastSavedState=void 0,b.current.hasPendingChanges=!1;}catch(u){throw P(u,"Clear"),u}},[f,c,P]),p=react.useCallback(async()=>{try{return await y.current.exists(f)}catch(u){return P(u,"Exists check"),false}},[f,P]);react.useEffect(()=>{x.current.autoPersist&&(s||a||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,b.current.lastSavedState)&&(b.current.hasPendingChanges=true,d.current(e)));},[e,s,a,h]);let g=react.useCallback(async()=>{await W(e);},[W,e]);return {isPersisting:s,persistenceError:l,persistNow:g,loadPersistedData:I,clearPersistedData:R,hasPersistedData:p}}function ye({workflowConfig:r,workflowState:e,workflowContext:t}){let i=react.useRef(Date.now()),o=react.useRef(new Map),s=react.useRef(false),n=react.useRef(null);react.useEffect(()=>{r.analytics?.onWorkflowStart&&!s.current&&(s.current=true,r.analytics.onWorkflowStart(r.id,t));},[r.id,r.analytics,t]),react.useEffect(()=>{let a=r.steps[e.currentStepIndex];if(a&&n.current!==a.id){if(n.current&&r.analytics?.onStepComplete){let S=o.current.get(n.current);S&&r.analytics.onStepComplete(n.current,Date.now()-S,e.stepData,t);}n.current=a.id,o.current.set(a.id,Date.now()),r.analytics?.onStepStart&&r.analytics.onStepStart(a.id,Date.now(),t);}},[e.currentStepIndex,r.steps,r.analytics,t,e.stepData]);let l=react.useCallback((a,S)=>{r.analytics?.onStepSkip&&r.analytics.onStepSkip(a,S,t);},[r.analytics,t]),m=react.useCallback(a=>{r.analytics?.onError&&r.analytics.onError(a,t);},[r.analytics,t]);return {analyticsStartTime:i,trackStepSkip:l,trackError:m}}function be(r,e){return {visible:r.visible,skippable:e===true||r.required}}function he({workflowConfig:r,workflowState:e,currentStep:t}){let i=react.useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),o=react.useMemo(()=>{if(t?.conditions)return {visible:t.conditions.visible,required:t.conditions.skippable}},[t?.conditions]),s=ce(o,i,{visible:true,disabled:false,required:false,readonly:false}),n=react.useMemo(()=>be(s,t?.allowSkip),[s,t?.allowSkip]),l=react.useMemo(()=>{let d={};return r.steps.forEach((h,I)=>{h.conditions&&(d[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),d},[r.steps]),m=ue(l,i),a=react.useMemo(()=>{let d={};return r.steps.forEach((h,I)=>{let R=m[I];R?d[I]=be(R,h.allowSkip):d[I]={visible:true,skippable:h.allowSkip===true};}),d},[r.steps,m]),S=react.useMemo(()=>{if(!t?.formConfig?.allFields)return {};let d={};for(let h of t.formConfig.allFields)h.conditions&&(d[h.id]=h.conditions);return d},[t?.formConfig?.allFields]),y=de(S,i),x=react.useCallback(d=>d<0||d>=r.steps.length?false:a[d]?.visible??true,[a,r.steps.length]),b=react.useCallback(d=>d<0||d>=r.steps.length?false:a[d]?.skippable??false,[a,r.steps.length]),f=react.useCallback(d=>y[d]?.visible??true,[y]),c=react.useCallback(d=>y[d]?.disabled??false,[y]),P=react.useCallback(d=>y[d]?.required??false,[y]),W=react.useCallback(d=>y[d]?.readonly??false,[y]);return {stepConditions:n,fieldConditions:y,allStepConditions:a,isStepVisible:x,isStepSkippable:b,isFieldVisible:f,isFieldDisabled:c,isFieldRequired:P,isFieldReadonly:W}}function ve({workflowConfig:r,workflowState:e,workflowContext:t,conditionsHelpers:i,setCurrentStep:o,setTransitioning:s,markStepVisited:n,setStepData:l,onStepChange:m}){let a=react.useRef(m);a.current=m;let S=r.steps[e.currentStepIndex],y=react.useCallback(()=>({setStepData:(p,g)=>{l(g,p);},setStepFields:(p,g)=>{let k={...e.allData[p]||{},...g};l(k,p);},getStepData:p=>e.allData[p]||{},setNextStepField:(p,g)=>{let u=e.currentStepIndex+1;if(u<r.steps.length){let k=r.steps[u].id,B={...e.allData[k]||{},[p]:g};l(B,k);}},setNextStepFields:p=>{let g=e.currentStepIndex+1;if(g<r.steps.length){let u=r.steps[g].id,C={...e.allData[u]||{},...p};l(C,u);}},getAllData:()=>({...e.allData}),getSteps:()=>[...r.steps]}),[e.allData,e.currentStepIndex,r.steps,l]),x=react.useCallback(async p=>{if(p<0||p>=r.steps.length||!i.isStepVisible(p))return false;s(true);try{return a.current&&a.current(e.currentStepIndex,p,t),o(p),n(p,r.steps[p].id),!0}catch(g){return console.error("Step transition failed:",g),r.analytics?.onError&&r.analytics.onError(g,t),false}finally{s(false);}},[r.steps,r.analytics,i,e.currentStepIndex,t,s,o,n]),b=react.useCallback(p=>{for(let g=p+1;g<r.steps.length;g++)if(i.isStepVisible(g))return g;return null},[r.steps.length,i]),f=react.useCallback(p=>{for(let g=p-1;g>=0;g--)if(i.isStepVisible(g))return g;return null},[i]),c=react.useCallback(async()=>{if(S?.onAfterValidation)try{let g=y();await S.onAfterValidation(e.stepData,g,t);}catch(g){return console.error("onAfterValidation failed:",g),r.analytics?.onError&&r.analytics.onError(g,t),false}let p=b(e.currentStepIndex);return p===null?false:x(p)},[S,y,e.stepData,t,r.analytics,e.currentStepIndex,b,x]),P=react.useCallback(async()=>{let p=f(e.currentStepIndex);return p===null?false:x(p)},[e.currentStepIndex,f,x]),W=react.useCallback(async()=>!S?.allowSkip&&!i.isStepSkippable(e.currentStepIndex)?false:(r.analytics?.onStepSkip&&r.analytics.onStepSkip(S.id,"user_skip",t),c()),[S,i,e.currentStepIndex,r.analytics,t,c]),d=react.useCallback(p=>p<0||p>=r.steps.length?false:i.isStepVisible(p),[r.steps.length,i]),h=react.useCallback(()=>{let p=b(e.currentStepIndex);return p!==null&&d(p)},[e.currentStepIndex,b,d]),I=react.useCallback(()=>{let p=f(e.currentStepIndex);return p!==null&&d(p)},[e.currentStepIndex,f,d]),R=react.useCallback(()=>S?.allowSkip===true&&i.isStepSkippable(e.currentStepIndex),[S?.allowSkip,i,e.currentStepIndex]);return {goToStep:x,goNext:c,goPrevious:P,skipStep:W,canGoToStep:d,canGoNext:h,canGoPrevious:I,canSkipCurrentStep:R}}function Ke(r,e){switch(e.type){case "SET_CURRENT_STEP":return {...r,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...r,stepData:e.data,allData:{...r.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...r,allData:e.data};case "SET_FIELD_VALUE":{let t={...r.stepData,[e.fieldId]:e.value};return {...r,stepData:t,allData:{...r.allData,[e.stepId]:t}}}case "SET_SUBMITTING":return {...r,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...r,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...r,visitedSteps:new Set([...r.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...r,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...r,isInitializing:false};default:return r}}function Pe({defaultValues:r={},persistence:e}){let t={currentStepIndex:0,allData:r,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,o]=react.useReducer(Ke,t),s=e?.adapter?Q({workflowId:e.workflowId,workflowState:i,adapter:e.adapter,options:e.options,userId:e.userId}):null,n=react.useCallback(c=>{o({type:"SET_CURRENT_STEP",stepIndex:c});},[]),l=react.useCallback((c,P)=>{o({type:"SET_STEP_DATA",data:c,stepId:P});},[]),m=react.useCallback((c,P,W)=>{o({type:"SET_FIELD_VALUE",fieldId:c,value:P,stepId:W});},[]),a=react.useCallback(c=>{o({type:"SET_SUBMITTING",isSubmitting:c});},[]),S=react.useCallback(c=>{o({type:"SET_TRANSITIONING",isTransitioning:c});},[]),y=react.useCallback((c,P)=>{o({type:"MARK_STEP_VISITED",stepIndex:c,stepId:P});},[]),x=react.useCallback(()=>{o({type:"RESET_WORKFLOW"});},[]),b=react.useCallback(()=>{o({type:"SET_INITIALIZATION_COMPLETE"});},[]),f=react.useCallback(async()=>{if(!s)return b(),false;try{let c=await s.loadPersistedData();if(c){let P={currentStepIndex:c.currentStepIndex,allData:c.allData,stepData:c.stepData,visitedSteps:new Set(c.visitedSteps)};return o({type:"LOAD_PERSISTED_STATE",state:P}),b(),!0}}catch(c){console.error("Failed to load persisted state:",c);}return b(),false},[s,b]);return {workflowState:i,setCurrentStep:n,setStepData:l,setFieldValue:m,setSubmitting:a,setTransitioning:S,markStepVisited:y,resetWorkflow:x,loadPersistedState:f,persistence:s?{isPersisting:s.isPersisting,persistenceError:s.persistenceError,persistNow:s.persistNow,clearPersistedData:s.clearPersistedData,hasPersistedData:s.hasPersistedData}:null}}function xe({workflowConfig:r,workflowState:e,workflowContext:t,setSubmitting:i,onWorkflowComplete:o,analyticsStartTime:s}){let n=react.useRef(o);n.current=o;let l=react.useCallback(async()=>{i(true);try{if(n.current&&await n.current(e.allData),r.analytics?.onWorkflowComplete){let a=Date.now()-s.current;r.analytics.onWorkflowComplete(r.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),r.analytics?.onError&&r.analytics.onError(a,t),a}finally{i(false);}},[e.allData,r.analytics,r.id,t,s,i]),m=react.useCallback(()=>e.isSubmitting?false:e.currentStepIndex===r.steps.length-1,[e.isSubmitting,e.currentStepIndex,r.steps.length]);return {submitWorkflow:l,isSubmitting:e.isSubmitting,canSubmit:m()}}var De=react.createContext(null);function ee({children:r,workflowConfig:e,defaultValues:t={},onStepChange:i,onWorkflowComplete:o,className:s}){let{workflowState:n,setCurrentStep:l,setStepData:m,setFieldValue:a,setSubmitting:S,setTransitioning:y,markStepVisited:x,resetWorkflow:b,loadPersistedState:f,persistence:c}=Pe({defaultValues:t,persistence:e.persistence?{workflowId:e.id,adapter:e.persistence.adapter,options:e.persistence.options,userId:e.persistence.userId}:void 0});react.useEffect(()=>{e.persistence&&f&&f();},[]);let P=c?.isPersisting??false,W=c?.persistenceError??null,d=c?.persistNow,h=react.useMemo(()=>({workflowId:e.id,currentStepIndex:n.currentStepIndex,totalSteps:e.steps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===e.steps.length-1,visitedSteps:n.visitedSteps}),[e.id,e.steps.length,n.currentStepIndex,n.allData,n.stepData,n.visitedSteps]),I=react.useMemo(()=>e.steps[n.currentStepIndex],[e.steps,n.currentStepIndex]),R=react.useMemo(()=>I?.formConfig,[I]),{analyticsStartTime:p}=ye({workflowConfig:e,workflowState:n,workflowContext:h}),g=he({workflowConfig:e,workflowState:n,currentStep:I}),{goToStep:u,goNext:k,goPrevious:C,skipStep:B,canGoToStep:re,canGoNext:ie,canGoPrevious:oe,canSkipCurrentStep:se}=ve({workflowConfig:e,workflowState:n,workflowContext:h,conditionsHelpers:g,setCurrentStep:l,setTransitioning:y,markStepVisited:x,setStepData:m,onStepChange:i});react.useEffect(()=>{if(!g.isStepVisible(n.currentStepIndex)){for(let A=0;A<e.steps.length;A++)if(g.isStepVisible(A)){l(A),x(A,e.steps[A].id);break}}},[g,n.currentStepIndex,e.steps,l,x]);let{submitWorkflow:M,isSubmitting:ne,canSubmit:ae}=xe({workflowConfig:e,workflowState:n,workflowContext:h,setSubmitting:S,onWorkflowComplete:o,analyticsStartTime:p}),$=react.useCallback((U,A)=>{a(U,A,I?.id||"");},[a,I?.id]),le=react.useCallback(U=>{m(U,I?.id||"");},[m,I?.id]),Ee=react.useCallback(async()=>{h.isLastStep?await M():await k();},[h.isLastStep,M,k]),Re=react.useMemo(()=>({workflowState:n,workflowConfig:e,currentStep:I,context:h,formConfig:R,conditionsHelpers:g,goToStep:u,goNext:k,goPrevious:C,skipStep:B,canGoToStep:re,canGoNext:ie,canGoPrevious:oe,canSkipCurrentStep:se,setValue:$,setStepData:le,resetWorkflow:b,submitWorkflow:M,isSubmitting:ne,canSubmit:ae,persistNow:d,isPersisting:P,persistenceError:W}),[n,e,I,h,R,g,u,k,C,B,re,ie,oe,se,$,le,b,M,ne,ae,d,P,W]);return jsxRuntime.jsx(De.Provider,{value:Re,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:R,defaultValues:n?.allData[I?.id]||{},onFieldChange:$,"data-workflow-id":e.id,className:s,onSubmit:Ee,children:r},n.isInitializing.toString())})}function E(){let r=react.useContext(De);if(!r)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return r}function Ze({children:r,workflowConfig:e,...t}){let[i,o]=react.useState(),s=react.useMemo(()=>e instanceof L?e.build():e,[e]);return react.useEffect(()=>{if(typeof window<"u"&&F.shouldDisplayWatermark()){let l=F.getWatermarkMessage();o(l);}},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(ee,{...t,workflowConfig:s,children:r}),i&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function je(){let{currentStep:r}=E();if(!r)return null;let{formConfig:e,renderer:t}=r;return e?t?t(r):jsxRuntime.jsx(forms.FormBody,{}):null}function it({className:r,...e}){let{context:t,workflowState:i,workflowConfig:o,currentStep:s}=E(),{submit:n,formState:l}=forms.useFormContext(),m=!i.isTransitioning&&!i.isSubmitting,a=async y=>{y?.preventDefault(),m&&await n(y);},S={isLastStep:t.isLastStep,canGoNext:m,isSubmitting:l.isSubmitting||i.isSubmitting,onSubmit:a,className:r,currentStep:s,stepData:l.values||{},allData:t.allData,context:t};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:S,...e})}function at({className:r,...e}){let{context:t,goPrevious:i,workflowState:o,workflowConfig:s,currentStep:n}=E(),{formState:l}=forms.useFormContext(),m=t.currentStepIndex>0&&!o.isTransitioning&&!o.isSubmitting,S={canGoPrevious:m,onPrevious:async y=>{y?.preventDefault(),m&&await i();},className:r,currentStep:n,stepData:l.values||{},allData:t.allData,context:t};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:S,...e})}function dt({className:r,...e}){let{currentStep:t,skipStep:i,workflowState:o,workflowConfig:s,context:n,conditionsHelpers:l}=E(),{formState:m}=forms.useFormContext(),a=(!!t?.allowSkip||l.isStepSkippable(o.currentStepIndex))&&!o.isTransitioning&&!o.isSubmitting,y={canSkip:a,onSkip:async x=>{x?.preventDefault(),a&&await i();},className:r,currentStep:t,stepData:m.values||{},allData:n.allData,context:n};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:y,...e})}function St({onStepClick:r,className:e,...t}){let{workflowConfig:i,workflowState:o,goToStep:s,conditionsHelpers:n}=E(),{visibleSteps:l,visibleToOriginalIndexMap:m,originalToVisibleIndexMap:a}=react.useMemo(()=>{let b=[],f=new Map,c=new Map;return i.steps.forEach((P,W)=>{if(n.isStepVisible(W)){let d=b.length;b.push(P),f.set(d,W),c.set(W,d);}}),{visibleSteps:b,visibleToOriginalIndexMap:f,originalToVisibleIndexMap:c}},[i.steps,n]),S=b=>{let f=m.get(b);f!==void 0&&(r?r(f):s(f));},y=a.get(o.currentStepIndex)??-1,x={steps:l,currentStepIndex:y,visitedSteps:o.visitedSteps,onStepClick:S,className:e};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:x,...t})}var te=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,t){if(this._isAvailable)try{let i=this.getStorageKey(e),o={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(o),n=this.compress?this.compressData(s):s;localStorage.setItem(i,n);}catch(i){if(i instanceof Error)if(i.name==="QuotaExceededError"||i.message.includes("quota")){await this.clearExpiredData();try{let o=this.getStorageKey(e),s={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},n=JSON.stringify(s),l=this.compress?this.compressData(n):n;localStorage.setItem(o,l);}catch(o){throw new D("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",o)}}else throw new D(`Failed to save to localStorage: ${i.message}`,"SAVE_FAILED",i);else throw new D("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return null;let o=this.compress?this.decompressData(i):i,s=JSON.parse(o);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(t){throw t instanceof Error?new D(`Failed to load from localStorage: ${t.message}`,"LOAD_FAILED",t):new D("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let t=this.getStorageKey(e);localStorage.removeItem(t);}catch(t){throw t instanceof Error?new D(`Failed to remove from localStorage: ${t.message}`,"REMOVE_FAILED",t):new D("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return !1;let o=this.compress?this.decompressData(i):i,s=JSON.parse(o);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix)){let o=i.substring(this.keyPrefix.length);await this.exists(o)&&e.push(o);}}return e}catch(e){throw e instanceof Error?new D(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new D("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let t of e)localStorage.removeItem(t);}catch(e){throw e instanceof Error?new D(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new D("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix))try{let o=localStorage.getItem(i);if(o){let s=this.compress?this.decompressData(o):o,n=JSON.parse(s);n.expiresAt&&Date.now()>n.expiresAt&&e.push(i);}}catch{e.push(i);}}for(let t of e)localStorage.removeItem(t);}};
2
- Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});exports.LocalStorageAdapter=te;exports.RilayLicenseManager=F;exports.Workflow=Ze;exports.WorkflowBody=je;exports.WorkflowNextButton=it;exports.WorkflowPersistenceError=D;exports.WorkflowPreviousButton=at;exports.WorkflowProvider=ee;exports.WorkflowSkipButton=dt;exports.WorkflowStepper=St;exports.createFlow=Fe;exports.debounce=Z;exports.flow=L;exports.generateStorageKey=H;exports.mergePersistedState=Be;exports.persistedToWorkflowState=fe;exports.useConditionEvaluation=ce;exports.useMultipleConditionEvaluation=de;exports.useMultipleStepConditionEvaluation=ue;exports.usePersistence=Q;exports.useWorkflowAnalytics=ye;exports.useWorkflowConditions=he;exports.useWorkflowContext=E;exports.useWorkflowNavigation=ve;exports.useWorkflowState=Pe;exports.useWorkflowSubmission=xe;exports.validatePersistedData=_e;exports.workflowStateToPersisted=X;Object.keys(core).forEach(function(k){if(k!=='default'&&!Object.prototype.hasOwnProperty.call(exports,k))Object.defineProperty(exports,k,{enumerable:true,get:function(){return core[k]}})});
1
+ 'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),react=require('react'),ge=require('@noble/ed25519'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var ge__namespace=/*#__PURE__*/_interopNamespace(ge);var L=class r{constructor(e,t,i,n){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=t,this.workflowName=i,this.workflowDescription=n;}static create(e,t,i,n){return new r(e,t,i,n)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:e.onAfterValidation}}addStep(e){let t=core.normalizeToArray(e);for(let i of t){let n=this.createStepFromDefinition(i);this.steps.push(n);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(t){throw new Error(`Failed to install plugin "${e.name}": ${t instanceof Error?t.message:String(t)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let t=e.dependencies.filter(i=>!this.plugins.some(n=>n.name===i));if(t.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${t.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(t=>t.name!==e),this}updateStep(e,t){let i=this.steps.findIndex(n=>n.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[i]={...this.steps[i],...t},this}addStepConditions(e,t){let i=this.steps.findIndex(o=>o.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);let n={...this.steps[i].conditions,...t};return this.steps[i]={...this.steps[i],conditions:n},this}removeStep(e){return this.steps=this.steps.filter(t=>t.id!==e),this}getStep(e){return this.steps.find(t=>t.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,t){let i=new r(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return i.steps=core.deepClone(this.steps),i.analytics=this.analytics?core.deepClone(this.analytics):void 0,i.persistenceConfig=this.persistenceConfig?core.deepClone(this.persistenceConfig):void 0,i.plugins=[...this.plugins],i}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(i=>i.id);try{core.ensureUnique(t,"step");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of this.plugins)if(i.dependencies){let n=i.dependencies.filter(o=>!this.plugins.some(s=>s.name===o));n.length>0&&e.push(`Plugin "${i.name}" requires missing dependencies: ${n.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((i,n)=>i+n.formConfig.allFields.length,0),t=this.steps.map(i=>i.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:t.length>0?Math.max(...t):0,minFieldsInStep:t.length>0?Math.min(...t):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function Be(r,e,t,i){return L.create(r,e,t,i)}core.ril.prototype.flow=function(r,e,t){return L.create(this,r,e,t)};var Me=1751361139160,Oe="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",k=class k{static async setLicenseKey(e){k.licenseKey=e||"",k.licenseKey?k.licenseResult=await k.validateLicense():k.licenseResult={valid:false,error:"MISSING"},k.isInitialized=true;}static async validateLicense(){if(!k.licenseKey)return {valid:false,error:"MISSING"};try{if(!k.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=k.licenseKey.slice(4),i=k.base64ToString(e).split(".");if(i.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[n,o,s]=i,p=`${n}.${o}`,g=new TextEncoder().encode(p),a=s.match(/.{2}/g);if(!a)return {valid:!1,error:"INVALID"};let l=new Uint8Array(a.map(W=>Number.parseInt(W,16))),f=k.hexToBytes(Oe);if(!await ge__namespace.verify(l,g,f))return {valid:!1,error:"SIGNATURE_INVALID"};let y=k.base64ToString(o.replace(/-/g,"+").replace(/_/g,"/")),c=JSON.parse(y),d=Math.floor(Date.now()/1e3);return c.e<d?{valid:!1,error:"EXPIRED",data:k.decompressPayload(c)}:Me>c.e*1e3?{valid:!1,error:"EXPIRED",data:k.decompressPayload(c)}:c.p===void 0||!c.c||!c.i||!c.e||!c.t?{valid:!1,error:"INVALID"}:{valid:!0,data:k.decompressPayload(c)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let t=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)t[i/2]=Number.parseInt(e.substring(i,i+2),16);return t}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",n=0,o=e.replace(/[^A-Za-z0-9+/]/g,"");for(;n<o.length;){let s=t.indexOf(o.charAt(n++)),p=t.indexOf(o.charAt(n++)),g=t.indexOf(o.charAt(n++)),a=t.indexOf(o.charAt(n++)),l=s<<18|p<<12|g<<6|a;i+=String.fromCharCode(l>>16&255),g!==64&&(i+=String.fromCharCode(l>>8&255)),a!==64&&(i+=String.fromCharCode(l&255));}return i}static getLicenseResult(){return k.isInitialized?k.licenseResult?k.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!k.getLicenseResult().valid}static getWatermarkMessage(){let e=k.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=k.getLicenseResult();if(e.valid)return;let i={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${i}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=k.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};k.licenseKey="",k.licenseResult=null,k.isInitialized=false;var B=k;function Z(r,e={},t={}){return react.useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=n=>{try{let o;return n&&typeof n=="object"&&"build"in n?o=n.build():o=n,core.evaluateCondition(o,e)}catch(o){return console.warn("Error evaluating condition:",o),false}};return {visible:r.visible?i(r.visible):true,disabled:r.disabled?i(r.disabled):false,required:r.required?i(r.required):false,readonly:r.readonly?i(r.readonly):false}},[r,e,t])}function ye(r,e={}){return react.useMemo(()=>{let t={};for(let[i,n]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},n){let o=s=>{try{return s&&typeof s=="object"&&"build"in s?core.evaluateCondition(s.build(),e):core.evaluateCondition(s,e)}catch(p){return console.warn(`Error evaluating condition for field ${i}:`,p),false}};t[i]={visible:n.visible?o(n.visible):true,disabled:n.disabled?o(n.disabled):false,required:n.required?o(n.required):false,readonly:n.readonly?o(n.readonly):false};}return t},[r,e])}function be(r,e={}){return react.useMemo(()=>{let t={};for(let[i,n]of Object.entries(r)){let o=Number.parseInt(i,10);if(t[o]={visible:true,disabled:false,required:false,readonly:false},n){let s=p=>{try{return p&&typeof p=="object"&&"build"in p?core.evaluateCondition(p.build(),e):core.evaluateCondition(p,e)}catch(g){return console.warn(`Error evaluating condition for step ${o}:`,g),false}};t[o]={visible:n.visible?s(n.visible):true,disabled:n.disabled?s(n.disabled):false,required:n.required?s(n.required):false,readonly:n.readonly?s(n.readonly):false};}}return t},[r,e])}var w=class extends Error{constructor(t,i,n){super(`[WorkflowPersistence] ${t} (Code: ${i})`);this.code=i;this.cause=n;this.name="WorkflowPersistenceError";}};function Y(r,e,t){return {workflowId:r,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:t}}function he(r){return {currentStepIndex:r.currentStepIndex,allData:{...r.allData},stepData:{...r.stepData},visitedSteps:new Set(r.visitedSteps),isSubmitting:false,isTransitioning:false}}function Ve(r){if(!r||typeof r!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let t of e)if(!(t in r))return false;return !(typeof r.workflowId!="string"||typeof r.currentStepIndex!="number"||typeof r.allData!="object"||typeof r.stepData!="object"||!Array.isArray(r.visitedSteps)||typeof r.lastSaved!="number")}function Q(r,e){return e?`${e}:${r}`:r}function j(r,e){let t=null;return (...i)=>{t&&clearTimeout(t),t=setTimeout(()=>{r(...i);},e);}}function _e(r,e,t="persist"){let i=he(e);switch(t){case "persist":return {...i,isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};case "current":return {...r,visitedSteps:new Set([...r.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:r.currentStepIndex,allData:{...i.allData,...r.allData},stepData:{...i.stepData,...r.stepData},visitedSteps:new Set([...i.visitedSteps,...r.visitedSteps]),isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};default:return i}}function q({workflowId:r,workflowState:e,adapter:t,options:i={},userId:n}){let[o,s]=react.useState(false),[p,g]=react.useState(null),[a,l]=react.useState(false),f=react.useRef(t),v=react.useRef(i),y=react.useRef({hasPendingChanges:false});react.useEffect(()=>{f.current=t,v.current=i;},[t,i]);let c=Q(v.current.storageKey||r,n),d=react.useCallback(()=>{g(null);},[]),P=react.useCallback((S,x)=>{let C=S instanceof w?S:new w(`${x} failed: ${S.message}`,"OPERATION_FAILED",S);g(C),console.error("[WorkflowPersistence]",C);},[]),W=react.useCallback(async S=>{d(),s(true);try{let x=Y(r,S,v.current.metadata);await f.current.save(c,x),y.current.lastSavedState={...S},y.current.hasPendingChanges=!1;}catch(x){throw P(x,"Save"),x}finally{s(false);}},[r,c,d,P]),m=react.useRef(j(async S=>{try{await W(S);}catch(x){console.debug("[WorkflowPersistence] Auto-save failed:",x);}},i.debounceMs||500)),h=react.useCallback((S,x)=>x?S.currentStepIndex!==x.currentStepIndex||JSON.stringify(S.allData)!==JSON.stringify(x.allData)||JSON.stringify(S.stepData)!==JSON.stringify(x.stepData)||S.visitedSteps.size!==x.visitedSteps.size||!Array.from(S.visitedSteps).every(C=>x.visitedSteps.has(C)):true,[]),I=react.useCallback(async()=>{d(),l(true);try{let S=await f.current.load(c);return S&&(y.current.lastSavedState={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},y.current.hasPendingChanges=!1),S}catch(S){return P(S,"Load"),null}finally{setTimeout(()=>l(false),100);}},[c,d,P]),R=react.useCallback(async()=>{d();try{await f.current.remove(c),y.current.lastSavedState=void 0,y.current.hasPendingChanges=!1;}catch(S){throw P(S,"Clear"),S}},[c,d,P]),u=react.useCallback(async()=>{try{return await f.current.exists(c)}catch(S){return P(S,"Exists check"),false}},[c,P]);react.useEffect(()=>{v.current.autoPersist&&(o||a||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,y.current.lastSavedState)&&(y.current.hasPendingChanges=true,m.current(e)));},[e,o,a,h]);let b=react.useCallback(async()=>{await W(e);},[W,e]);return {isPersisting:o,persistenceError:p,persistNow:b,loadPersistedData:I,clearPersistedData:R,hasPersistedData:u}}function Ue(){let{workflowConfig:r,currentStep:e}=D(),t=react.useMemo(()=>e?.metadata,[e?.metadata]),i=react.useMemo(()=>a=>r.steps.find(f=>f.id===a)?.metadata,[r.steps]),n=react.useMemo(()=>a=>r.steps[a]?.metadata,[r.steps]),o=react.useMemo(()=>a=>t?a in t:false,[t]),s=react.useMemo(()=>(a,l)=>t&&a in t?t[a]:l,[t]),p=react.useMemo(()=>()=>r.steps.map((a,l)=>({id:a.id,title:a.title,index:l,metadata:a.metadata})),[r.steps]),g=react.useMemo(()=>a=>r.steps.map((l,f)=>({step:l,index:f})).filter(({step:l,index:f})=>a(l.metadata,l.id,f)).map(({step:l})=>l.id),[r.steps]);return {current:t,getByStepId:i,getByStepIndex:n,hasCurrentKey:o,getCurrentValue:s,getAllStepsMetadata:p,findStepsByMetadata:g}}function te({workflowConfig:r,workflowState:e,workflowContext:t}){let i=react.useRef(Date.now()),n=react.useRef(new Map),o=react.useRef(false),s=react.useRef(null);react.useEffect(()=>{r.analytics?.onWorkflowStart&&!o.current&&(o.current=true,r.analytics.onWorkflowStart(r.id,t));},[r.id,r.analytics,t]),react.useEffect(()=>{let a=r.steps[e.currentStepIndex];if(a&&s.current!==a.id){if(s.current&&r.analytics?.onStepComplete){let l=n.current.get(s.current);l&&r.analytics.onStepComplete(s.current,Date.now()-l,e.stepData,t);}s.current=a.id,n.current.set(a.id,Date.now()),r.analytics?.onStepStart&&r.analytics.onStepStart(a.id,Date.now(),t);}},[e.currentStepIndex,r.steps,r.analytics,t,e.stepData]);let p=react.useCallback((a,l)=>{r.analytics?.onStepSkip&&r.analytics.onStepSkip(a,l,t);},[r.analytics,t]),g=react.useCallback(a=>{r.analytics?.onError&&r.analytics.onError(a,t);},[r.analytics,t]);return {analyticsStartTime:i,trackStepSkip:p,trackError:g}}function xe(r,e){return {visible:r.visible,skippable:e===true||r.required}}function re({workflowConfig:r,workflowState:e,currentStep:t}){let i=react.useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),n=react.useMemo(()=>{if(t?.conditions)return {visible:t.conditions.visible,required:t.conditions.skippable}},[t?.conditions]),o=Z(n,i,{visible:true,disabled:false,required:false,readonly:false}),s=react.useMemo(()=>xe(o,t?.allowSkip),[o,t?.allowSkip]),p=react.useMemo(()=>{let m={};return r.steps.forEach((h,I)=>{h.conditions&&(m[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),m},[r.steps]),g=be(p,i),a=react.useMemo(()=>{let m={};return r.steps.forEach((h,I)=>{let R=g[I];R?m[I]=xe(R,h.allowSkip):m[I]={visible:true,skippable:h.allowSkip===true};}),m},[r.steps,g]),l=react.useMemo(()=>{if(!t?.formConfig?.allFields)return {};let m={};for(let h of t.formConfig.allFields)h.conditions&&(m[h.id]=h.conditions);return m},[t?.formConfig?.allFields]),f=ye(l,i),v=react.useCallback(m=>m<0||m>=r.steps.length?false:a[m]?.visible??true,[a,r.steps.length]),y=react.useCallback(m=>m<0||m>=r.steps.length?false:a[m]?.skippable??false,[a,r.steps.length]),c=react.useCallback(m=>f[m]?.visible??true,[f]),d=react.useCallback(m=>f[m]?.disabled??false,[f]),P=react.useCallback(m=>f[m]?.required??false,[f]),W=react.useCallback(m=>f[m]?.readonly??false,[f]);return {stepConditions:s,fieldConditions:f,allStepConditions:a,isStepVisible:v,isStepSkippable:y,isFieldVisible:c,isFieldDisabled:d,isFieldRequired:P,isFieldReadonly:W}}function ie({workflowConfig:r,workflowState:e,workflowContext:t,conditionsHelpers:i,setCurrentStep:n,setTransitioning:o,markStepVisited:s,setStepData:p,onStepChange:g}){let a=react.useRef(g);a.current=g;let l=r.steps[e.currentStepIndex],f=react.useCallback(()=>({setStepData:(u,b)=>{p(b,u);},setStepFields:(u,b)=>{let x={...e.allData[u]||{},...b};p(x,u);},getStepData:u=>e.allData[u]||{},setNextStepField:(u,b)=>{let S=e.currentStepIndex+1;if(S<r.steps.length){let x=r.steps[S].id,_={...e.allData[x]||{},[u]:b};p(_,x);}},setNextStepFields:u=>{let b=e.currentStepIndex+1;if(b<r.steps.length){let S=r.steps[b].id,C={...e.allData[S]||{},...u};p(C,S);}},getAllData:()=>({...e.allData}),getSteps:()=>[...r.steps]}),[e.allData,e.currentStepIndex,r.steps,p]),v=react.useCallback(async u=>{if(u<0||u>=r.steps.length||!i.isStepVisible(u))return false;o(true);try{return a.current&&a.current(e.currentStepIndex,u,t),n(u),s(u,r.steps[u].id),!0}catch(b){return console.error("Step transition failed:",b),r.analytics?.onError&&r.analytics.onError(b,t),false}finally{o(false);}},[r.steps,r.analytics,i,e.currentStepIndex,t,o,n,s]),y=react.useCallback(u=>{for(let b=u+1;b<r.steps.length;b++)if(i.isStepVisible(b))return b;return null},[r.steps.length,i]),c=react.useCallback(u=>{for(let b=u-1;b>=0;b--)if(i.isStepVisible(b))return b;return null},[i]),d=react.useCallback(async()=>{if(l?.onAfterValidation)try{let b=f();await l.onAfterValidation(e.stepData,b,t);}catch(b){return console.error("onAfterValidation failed:",b),r.analytics?.onError&&r.analytics.onError(b,t),false}let u=y(e.currentStepIndex);return u===null?false:v(u)},[l,f,e.stepData,t,r.analytics,e.currentStepIndex,y,v]),P=react.useCallback(async()=>{let u=c(e.currentStepIndex);return u===null?false:v(u)},[e.currentStepIndex,c,v]),W=react.useCallback(async()=>!l?.allowSkip&&!i.isStepSkippable(e.currentStepIndex)?false:(r.analytics?.onStepSkip&&r.analytics.onStepSkip(l.id,"user_skip",t),d()),[l,i,e.currentStepIndex,r.analytics,t,d]),m=react.useCallback(u=>u<0||u>=r.steps.length?false:i.isStepVisible(u),[r.steps.length,i]),h=react.useCallback(()=>{let u=y(e.currentStepIndex);return u!==null&&m(u)},[e.currentStepIndex,y,m]),I=react.useCallback(()=>{let u=c(e.currentStepIndex);return u!==null&&m(u)},[e.currentStepIndex,c,m]),R=react.useCallback(()=>l?.allowSkip===true&&i.isStepSkippable(e.currentStepIndex),[l?.allowSkip,i,e.currentStepIndex]);return {goToStep:v,goNext:d,goPrevious:P,skipStep:W,canGoToStep:m,canGoNext:h,canGoPrevious:I,canSkipCurrentStep:R}}function qe(r,e){switch(e.type){case "SET_CURRENT_STEP":return {...r,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...r,stepData:e.data,allData:{...r.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...r,allData:e.data};case "SET_FIELD_VALUE":{let t={...r.stepData,[e.fieldId]:e.value};return {...r,stepData:t,allData:{...r.allData,[e.stepId]:t}}}case "SET_SUBMITTING":return {...r,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...r,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...r,visitedSteps:new Set([...r.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...r,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...r,isInitializing:false};default:return r}}function ne({defaultValues:r={},persistence:e}){let t={currentStepIndex:0,allData:r,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,n]=react.useReducer(qe,t),o=e?.adapter?q({workflowId:e.workflowId,workflowState:i,adapter:e.adapter,options:e.options,userId:e.userId}):null,s=react.useCallback(d=>{n({type:"SET_CURRENT_STEP",stepIndex:d});},[]),p=react.useCallback((d,P)=>{n({type:"SET_STEP_DATA",data:d,stepId:P});},[]),g=react.useCallback((d,P,W)=>{n({type:"SET_FIELD_VALUE",fieldId:d,value:P,stepId:W});},[]),a=react.useCallback(d=>{n({type:"SET_SUBMITTING",isSubmitting:d});},[]),l=react.useCallback(d=>{n({type:"SET_TRANSITIONING",isTransitioning:d});},[]),f=react.useCallback((d,P)=>{n({type:"MARK_STEP_VISITED",stepIndex:d,stepId:P});},[]),v=react.useCallback(()=>{n({type:"RESET_WORKFLOW"});},[]),y=react.useCallback(()=>{n({type:"SET_INITIALIZATION_COMPLETE"});},[]),c=react.useCallback(async()=>{if(!o)return y(),false;try{let d=await o.loadPersistedData();if(d){let P={currentStepIndex:d.currentStepIndex,allData:d.allData,stepData:d.stepData,visitedSteps:new Set(d.visitedSteps)};return n({type:"LOAD_PERSISTED_STATE",state:P}),y(),!0}}catch(d){console.error("Failed to load persisted state:",d);}return y(),false},[o,y]);return {workflowState:i,setCurrentStep:s,setStepData:p,setFieldValue:g,setSubmitting:a,setTransitioning:l,markStepVisited:f,resetWorkflow:v,loadPersistedState:c,persistence:o?{isPersisting:o.isPersisting,persistenceError:o.persistenceError,persistNow:o.persistNow,clearPersistedData:o.clearPersistedData,hasPersistedData:o.hasPersistedData}:null}}function oe({workflowConfig:r,workflowState:e,workflowContext:t,setSubmitting:i,onWorkflowComplete:n,analyticsStartTime:o}){let s=react.useRef(n);s.current=n;let p=react.useCallback(async()=>{i(true);try{if(s.current&&await s.current(e.allData),r.analytics?.onWorkflowComplete){let a=Date.now()-o.current;r.analytics.onWorkflowComplete(r.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),r.analytics?.onError&&r.analytics.onError(a,t),a}finally{i(false);}},[e.allData,r.analytics,r.id,t,o,i]),g=react.useCallback(()=>e.isSubmitting?false:e.currentStepIndex===r.steps.length-1,[e.isSubmitting,e.currentStepIndex,r.steps.length]);return {submitWorkflow:p,isSubmitting:e.isSubmitting,canSubmit:g()}}var De=react.createContext(null);function ae({children:r,workflowConfig:e,defaultValues:t={},onStepChange:i,onWorkflowComplete:n,className:o}){let{workflowState:s,setCurrentStep:p,setStepData:g,setFieldValue:a,setSubmitting:l,setTransitioning:f,markStepVisited:v,resetWorkflow:y,loadPersistedState:c,persistence:d}=ne({defaultValues:t,persistence:e.persistence?{workflowId:e.id,adapter:e.persistence.adapter,options:e.persistence.options,userId:e.persistence.userId}:void 0});react.useEffect(()=>{e.persistence&&c&&c();},[]);let P=d?.isPersisting??false,W=d?.persistenceError??null,m=d?.persistNow,h=react.useMemo(()=>({workflowId:e.id,currentStepIndex:s.currentStepIndex,totalSteps:e.steps.length,allData:s.allData,stepData:s.stepData,isFirstStep:s.currentStepIndex===0,isLastStep:s.currentStepIndex===e.steps.length-1,visitedSteps:s.visitedSteps}),[e.id,e.steps.length,s.currentStepIndex,s.allData,s.stepData,s.visitedSteps]),I=react.useMemo(()=>e.steps[s.currentStepIndex],[e.steps,s.currentStepIndex]),R=react.useMemo(()=>I?.formConfig,[I]),{analyticsStartTime:u}=te({workflowConfig:e,workflowState:s,workflowContext:h}),b=re({workflowConfig:e,workflowState:s,currentStep:I}),{goToStep:S,goNext:x,goPrevious:C,skipStep:_,canGoToStep:pe,canGoNext:ce,canGoPrevious:de,canSkipCurrentStep:ue}=ie({workflowConfig:e,workflowState:s,workflowContext:h,conditionsHelpers:b,setCurrentStep:p,setTransitioning:f,markStepVisited:v,setStepData:g,onStepChange:i});react.useEffect(()=>{if(!b.isStepVisible(s.currentStepIndex)){for(let A=0;A<e.steps.length;A++)if(b.isStepVisible(A)){p(A),v(A,e.steps[A].id);break}}},[b,s.currentStepIndex,e.steps,p,v]);let{submitWorkflow:U,isSubmitting:fe,canSubmit:me}=oe({workflowConfig:e,workflowState:s,workflowContext:h,setSubmitting:l,onWorkflowComplete:n,analyticsStartTime:u}),J=react.useCallback((K,A)=>{a(K,A,I?.id||"");},[a,I?.id]),Se=react.useCallback(K=>{g(K,I?.id||"");},[g,I?.id]),Re=react.useCallback(async()=>{h.isLastStep?await U():await x();},[h.isLastStep,U,x]),Ce=react.useMemo(()=>({workflowState:s,workflowConfig:e,currentStep:I,context:h,formConfig:R,conditionsHelpers:b,currentStepMetadata:I?.metadata,goToStep:S,goNext:x,goPrevious:C,skipStep:_,canGoToStep:pe,canGoNext:ce,canGoPrevious:de,canSkipCurrentStep:ue,setValue:J,setStepData:Se,resetWorkflow:y,submitWorkflow:U,isSubmitting:fe,canSubmit:me,persistNow:m,isPersisting:P,persistenceError:W}),[s,e,I,h,R,b,S,x,C,_,pe,ce,de,ue,J,Se,y,U,fe,me,m,P,W]);return jsxRuntime.jsx(De.Provider,{value:Ce,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:R,defaultValues:s?.allData[I?.id]||{},onFieldChange:J,"data-workflow-id":e.id,className:o,onSubmit:Re,children:r},s.isInitializing.toString())})}function D(){let r=react.useContext(De);if(!r)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return r}function Qe({children:r,workflowConfig:e,...t}){let[i,n]=react.useState(),o=react.useMemo(()=>e instanceof L?e.build():e,[e]);return react.useEffect(()=>{if(typeof window<"u"&&B.shouldDisplayWatermark()){let p=B.getWatermarkMessage();n(p);}},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(ae,{...t,workflowConfig:o,children:r}),i&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function tt({stepId:r,children:e}){let{currentStep:t}=D();if(!t||r&&t.id!==r)return null;let{formConfig:i,renderer:n}=t;return i?n?n(t):e??jsxRuntime.jsx(forms.FormBody,{}):null}function ot({className:r,isSubmitting:e,...t}){let{context:i,workflowState:n,workflowConfig:o,currentStep:s}=D(),{submit:p,formState:g}=forms.useFormContext(),a=g.isSubmitting||n.isSubmitting,l=e??a,f=!n.isTransitioning&&!l,v=async c=>{c?.preventDefault(),f&&await p(c);},y={isLastStep:i.isLastStep,canGoNext:f,isSubmitting:l,onSubmit:v,className:r,currentStep:s,stepData:g.values||{},allData:i.allData,context:i};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:y,...t})}function pt({className:r,isSubmitting:e,...t}){let{context:i,goPrevious:n,workflowState:o,workflowConfig:s,currentStep:p}=D(),{formState:g}=forms.useFormContext(),a=g.isSubmitting||o.isSubmitting,l=e??a,f=i.currentStepIndex>0&&!o.isTransitioning&&!l,y={canGoPrevious:f,isSubmitting:l,onPrevious:async c=>{c?.preventDefault(),f&&await n();},className:r,currentStep:p,stepData:g.values||{},allData:i.allData,context:i};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:y,...t})}function ft({className:r,isSubmitting:e,...t}){let{currentStep:i,skipStep:n,workflowState:o,workflowConfig:s,context:p,conditionsHelpers:g}=D(),{formState:a}=forms.useFormContext(),l=a.isSubmitting||o.isSubmitting,f=e??l,v=(!!i?.allowSkip||g.isStepSkippable(o.currentStepIndex))&&!o.isTransitioning&&!f,c={canSkip:v,isSubmitting:f,onSkip:async d=>{d?.preventDefault(),v&&await n();},className:r,currentStep:i,stepData:a.values||{},allData:p.allData,context:p};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:c,...t})}function yt({onStepClick:r,className:e,...t}){let{workflowConfig:i,workflowState:n,goToStep:o,conditionsHelpers:s}=D(),{visibleSteps:p,visibleToOriginalIndexMap:g,originalToVisibleIndexMap:a}=react.useMemo(()=>{let y=[],c=new Map,d=new Map;return i.steps.forEach((P,W)=>{if(s.isStepVisible(W)){let m=y.length;y.push(P),c.set(m,W),d.set(W,m);}}),{visibleSteps:y,visibleToOriginalIndexMap:c,originalToVisibleIndexMap:d}},[i.steps,s]),l=y=>{let c=g.get(y);c!==void 0&&(r?r(c):o(c));},f=a.get(n.currentStepIndex)??-1,v={steps:p,currentStepIndex:f,visitedSteps:n.visitedSteps,onStepClick:l,className:e};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:v,...t})}var le=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,t){if(this._isAvailable)try{let i=this.getStorageKey(e),n={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},o=JSON.stringify(n),s=this.compress?this.compressData(o):o;localStorage.setItem(i,s);}catch(i){if(i instanceof Error)if(i.name==="QuotaExceededError"||i.message.includes("quota")){await this.clearExpiredData();try{let n=this.getStorageKey(e),o={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(o),p=this.compress?this.compressData(s):s;localStorage.setItem(n,p);}catch(n){throw new w("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",n)}}else throw new w(`Failed to save to localStorage: ${i.message}`,"SAVE_FAILED",i);else throw new w("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return null;let n=this.compress?this.decompressData(i):i,o=JSON.parse(n);return o.expiresAt&&Date.now()>o.expiresAt?(await this.remove(e),null):{...o.data,visitedSteps:Array.isArray(o.data.visitedSteps)?o.data.visitedSteps:[]}}catch(t){throw t instanceof Error?new w(`Failed to load from localStorage: ${t.message}`,"LOAD_FAILED",t):new w("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let t=this.getStorageKey(e);localStorage.removeItem(t);}catch(t){throw t instanceof Error?new w(`Failed to remove from localStorage: ${t.message}`,"REMOVE_FAILED",t):new w("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return !1;let n=this.compress?this.decompressData(i):i,o=JSON.parse(n);return o.expiresAt&&Date.now()>o.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix)){let n=i.substring(this.keyPrefix.length);await this.exists(n)&&e.push(n);}}return e}catch(e){throw e instanceof Error?new w(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new w("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let t of e)localStorage.removeItem(t);}catch(e){throw e instanceof Error?new w(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new w("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix))try{let n=localStorage.getItem(i);if(n){let o=this.compress?this.decompressData(n):n,s=JSON.parse(o);s.expiresAt&&Date.now()>s.expiresAt&&e.push(i);}}catch{e.push(i);}}for(let t of e)localStorage.removeItem(t);}};
2
+ Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});exports.LocalStorageAdapter=le;exports.RilayLicenseManager=B;exports.Workflow=Qe;exports.WorkflowBody=tt;exports.WorkflowNextButton=ot;exports.WorkflowPersistenceError=w;exports.WorkflowPreviousButton=pt;exports.WorkflowProvider=ae;exports.WorkflowSkipButton=ft;exports.WorkflowStepper=yt;exports.createFlow=Be;exports.debounce=j;exports.flow=L;exports.generateStorageKey=Q;exports.mergePersistedState=_e;exports.persistedToWorkflowState=he;exports.useConditionEvaluation=Z;exports.usePersistence=q;exports.useStepMetadata=Ue;exports.useWorkflowAnalytics=te;exports.useWorkflowConditions=re;exports.useWorkflowContext=D;exports.useWorkflowNavigation=ie;exports.useWorkflowState=ne;exports.useWorkflowSubmission=oe;exports.validatePersistedData=Ve;exports.workflowStateToPersisted=Y;Object.keys(core).forEach(function(k){if(k!=='default'&&!Object.prototype.hasOwnProperty.call(exports,k))Object.defineProperty(exports,k,{enumerable:true,get:function(){return core[k]}})});
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {ril,IdGenerator,normalizeToArray,deepClone,ensureUnique,ComponentRendererWrapper,evaluateCondition}from'@rilaykit/core';export*from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import {createContext,useMemo,useState,useRef,useEffect,useCallback,useReducer,useContext}from'react';import*as pe from'@noble/ed25519';import {jsx,jsxs}from'react/jsx-runtime';var L=class r{constructor(e,t,i,o){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=t,this.workflowName=i,this.workflowDescription=o;}static create(e,t,i,o){return new r(e,t,i,o)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,onAfterValidation:e.onAfterValidation}}addStep(e){let t=normalizeToArray(e);for(let i of t){let o=this.createStepFromDefinition(i);this.steps.push(o);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(t){throw new Error(`Failed to install plugin "${e.name}": ${t instanceof Error?t.message:String(t)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let t=e.dependencies.filter(i=>!this.plugins.some(o=>o.name===i));if(t.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${t.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(t=>t.name!==e),this}updateStep(e,t){let i=this.steps.findIndex(o=>o.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[i]={...this.steps[i],...t},this}addStepConditions(e,t){let i=this.steps.findIndex(s=>s.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);let o={...this.steps[i].conditions,...t};return this.steps[i]={...this.steps[i],conditions:o},this}removeStep(e){return this.steps=this.steps.filter(t=>t.id!==e),this}getStep(e){return this.steps.find(t=>t.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,t){let i=new r(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return i.steps=deepClone(this.steps),i.analytics=this.analytics?deepClone(this.analytics):void 0,i.persistenceConfig=this.persistenceConfig?deepClone(this.persistenceConfig):void 0,i.plugins=[...this.plugins],i}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(i=>i.id);try{ensureUnique(t,"step");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of this.plugins)if(i.dependencies){let o=i.dependencies.filter(s=>!this.plugins.some(n=>n.name===s));o.length>0&&e.push(`Plugin "${i.name}" requires missing dependencies: ${o.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((i,o)=>i+o.formConfig.allFields.length,0),t=this.steps.map(i=>i.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:t.length>0?Math.max(...t):0,minFieldsInStep:t.length>0?Math.min(...t):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function Fe(r,e,t,i){return L.create(r,e,t,i)}ril.prototype.flow=function(r,e,t){return L.create(this,r,e,t)};var Oe=1751361139160,Ve="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",v=class v{static async setLicenseKey(e){v.licenseKey=e||"",v.licenseKey?v.licenseResult=await v.validateLicense():v.licenseResult={valid:false,error:"MISSING"},v.isInitialized=true;}static async validateLicense(){if(!v.licenseKey)return {valid:false,error:"MISSING"};try{if(!v.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=v.licenseKey.slice(4),i=v.base64ToString(e).split(".");if(i.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[o,s,n]=i,l=`${o}.${s}`,m=new TextEncoder().encode(l),a=n.match(/.{2}/g);if(!a)return {valid:!1,error:"INVALID"};let S=new Uint8Array(a.map(W=>Number.parseInt(W,16))),y=v.hexToBytes(Ve);if(!await pe.verify(S,m,y))return {valid:!1,error:"SIGNATURE_INVALID"};let b=v.base64ToString(s.replace(/-/g,"+").replace(/_/g,"/")),f=JSON.parse(b),c=Math.floor(Date.now()/1e3);return f.e<c?{valid:!1,error:"EXPIRED",data:v.decompressPayload(f)}:Oe>f.e*1e3?{valid:!1,error:"EXPIRED",data:v.decompressPayload(f)}:f.p===void 0||!f.c||!f.i||!f.e||!f.t?{valid:!1,error:"INVALID"}:{valid:!0,data:v.decompressPayload(f)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let t=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)t[i/2]=Number.parseInt(e.substring(i,i+2),16);return t}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",o=0,s=e.replace(/[^A-Za-z0-9+/]/g,"");for(;o<s.length;){let n=t.indexOf(s.charAt(o++)),l=t.indexOf(s.charAt(o++)),m=t.indexOf(s.charAt(o++)),a=t.indexOf(s.charAt(o++)),S=n<<18|l<<12|m<<6|a;i+=String.fromCharCode(S>>16&255),m!==64&&(i+=String.fromCharCode(S>>8&255)),a!==64&&(i+=String.fromCharCode(S&255));}return i}static getLicenseResult(){return v.isInitialized?v.licenseResult?v.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!v.getLicenseResult().valid}static getWatermarkMessage(){let e=v.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=v.getLicenseResult();if(e.valid)return;let i={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${i}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=v.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};v.licenseKey="",v.licenseResult=null,v.isInitialized=false;var F=v;function ce(r,e={},t={}){return useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=o=>{try{let s;return o&&typeof o=="object"&&"build"in o?s=o.build():s=o,evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:r.visible?i(r.visible):true,disabled:r.disabled?i(r.disabled):false,required:r.required?i(r.required):false,readonly:r.readonly?i(r.readonly):false}},[r,e,t])}function de(r,e={}){return useMemo(()=>{let t={};for(let[i,o]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},o){let s=n=>{try{return n&&typeof n=="object"&&"build"in n?evaluateCondition(n.build(),e):evaluateCondition(n,e)}catch(l){return console.warn(`Error evaluating condition for field ${i}:`,l),false}};t[i]={visible:o.visible?s(o.visible):true,disabled:o.disabled?s(o.disabled):false,required:o.required?s(o.required):false,readonly:o.readonly?s(o.readonly):false};}return t},[r,e])}function ue(r,e={}){return useMemo(()=>{let t={};for(let[i,o]of Object.entries(r)){let s=Number.parseInt(i,10);if(t[s]={visible:true,disabled:false,required:false,readonly:false},o){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?evaluateCondition(l.build(),e):evaluateCondition(l,e)}catch(m){return console.warn(`Error evaluating condition for step ${s}:`,m),false}};t[s]={visible:o.visible?n(o.visible):true,disabled:o.disabled?n(o.disabled):false,required:o.required?n(o.required):false,readonly:o.readonly?n(o.readonly):false};}}return t},[r,e])}var D=class extends Error{constructor(t,i,o){super(`[WorkflowPersistence] ${t} (Code: ${i})`);this.code=i;this.cause=o;this.name="WorkflowPersistenceError";}};function X(r,e,t){return {workflowId:r,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:t}}function fe(r){return {currentStepIndex:r.currentStepIndex,allData:{...r.allData},stepData:{...r.stepData},visitedSteps:new Set(r.visitedSteps),isSubmitting:false,isTransitioning:false}}function _e(r){if(!r||typeof r!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let t of e)if(!(t in r))return false;return !(typeof r.workflowId!="string"||typeof r.currentStepIndex!="number"||typeof r.allData!="object"||typeof r.stepData!="object"||!Array.isArray(r.visitedSteps)||typeof r.lastSaved!="number")}function H(r,e){return e?`${e}:${r}`:r}function Z(r,e){let t=null;return (...i)=>{t&&clearTimeout(t),t=setTimeout(()=>{r(...i);},e);}}function Be(r,e,t="persist"){let i=fe(e);switch(t){case "persist":return {...i,isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};case "current":return {...r,visitedSteps:new Set([...r.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:r.currentStepIndex,allData:{...i.allData,...r.allData},stepData:{...i.stepData,...r.stepData},visitedSteps:new Set([...i.visitedSteps,...r.visitedSteps]),isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};default:return i}}function Q({workflowId:r,workflowState:e,adapter:t,options:i={},userId:o}){let[s,n]=useState(false),[l,m]=useState(null),[a,S]=useState(false),y=useRef(t),x=useRef(i),b=useRef({hasPendingChanges:false});useEffect(()=>{y.current=t,x.current=i;},[t,i]);let f=H(x.current.storageKey||r,o),c=useCallback(()=>{m(null);},[]),P=useCallback((u,k)=>{let C=u instanceof D?u:new D(`${k} failed: ${u.message}`,"OPERATION_FAILED",u);m(C),console.error("[WorkflowPersistence]",C);},[]),W=useCallback(async u=>{c(),n(true);try{let k=X(r,u,x.current.metadata);await y.current.save(f,k),b.current.lastSavedState={...u},b.current.hasPendingChanges=!1;}catch(k){throw P(k,"Save"),k}finally{n(false);}},[r,f,c,P]),d=useRef(Z(async u=>{try{await W(u);}catch(k){console.debug("[WorkflowPersistence] Auto-save failed:",k);}},i.debounceMs||500)),h=useCallback((u,k)=>k?u.currentStepIndex!==k.currentStepIndex||JSON.stringify(u.allData)!==JSON.stringify(k.allData)||JSON.stringify(u.stepData)!==JSON.stringify(k.stepData)||u.visitedSteps.size!==k.visitedSteps.size||!Array.from(u.visitedSteps).every(C=>k.visitedSteps.has(C)):true,[]),I=useCallback(async()=>{c(),S(true);try{let u=await y.current.load(f);return u&&(b.current.lastSavedState={currentStepIndex:u.currentStepIndex,allData:u.allData,stepData:u.stepData,visitedSteps:new Set(u.visitedSteps),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},b.current.hasPendingChanges=!1),u}catch(u){return P(u,"Load"),null}finally{setTimeout(()=>S(false),100);}},[f,c,P]),R=useCallback(async()=>{c();try{await y.current.remove(f),b.current.lastSavedState=void 0,b.current.hasPendingChanges=!1;}catch(u){throw P(u,"Clear"),u}},[f,c,P]),p=useCallback(async()=>{try{return await y.current.exists(f)}catch(u){return P(u,"Exists check"),false}},[f,P]);useEffect(()=>{x.current.autoPersist&&(s||a||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,b.current.lastSavedState)&&(b.current.hasPendingChanges=true,d.current(e)));},[e,s,a,h]);let g=useCallback(async()=>{await W(e);},[W,e]);return {isPersisting:s,persistenceError:l,persistNow:g,loadPersistedData:I,clearPersistedData:R,hasPersistedData:p}}function ye({workflowConfig:r,workflowState:e,workflowContext:t}){let i=useRef(Date.now()),o=useRef(new Map),s=useRef(false),n=useRef(null);useEffect(()=>{r.analytics?.onWorkflowStart&&!s.current&&(s.current=true,r.analytics.onWorkflowStart(r.id,t));},[r.id,r.analytics,t]),useEffect(()=>{let a=r.steps[e.currentStepIndex];if(a&&n.current!==a.id){if(n.current&&r.analytics?.onStepComplete){let S=o.current.get(n.current);S&&r.analytics.onStepComplete(n.current,Date.now()-S,e.stepData,t);}n.current=a.id,o.current.set(a.id,Date.now()),r.analytics?.onStepStart&&r.analytics.onStepStart(a.id,Date.now(),t);}},[e.currentStepIndex,r.steps,r.analytics,t,e.stepData]);let l=useCallback((a,S)=>{r.analytics?.onStepSkip&&r.analytics.onStepSkip(a,S,t);},[r.analytics,t]),m=useCallback(a=>{r.analytics?.onError&&r.analytics.onError(a,t);},[r.analytics,t]);return {analyticsStartTime:i,trackStepSkip:l,trackError:m}}function be(r,e){return {visible:r.visible,skippable:e===true||r.required}}function he({workflowConfig:r,workflowState:e,currentStep:t}){let i=useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),o=useMemo(()=>{if(t?.conditions)return {visible:t.conditions.visible,required:t.conditions.skippable}},[t?.conditions]),s=ce(o,i,{visible:true,disabled:false,required:false,readonly:false}),n=useMemo(()=>be(s,t?.allowSkip),[s,t?.allowSkip]),l=useMemo(()=>{let d={};return r.steps.forEach((h,I)=>{h.conditions&&(d[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),d},[r.steps]),m=ue(l,i),a=useMemo(()=>{let d={};return r.steps.forEach((h,I)=>{let R=m[I];R?d[I]=be(R,h.allowSkip):d[I]={visible:true,skippable:h.allowSkip===true};}),d},[r.steps,m]),S=useMemo(()=>{if(!t?.formConfig?.allFields)return {};let d={};for(let h of t.formConfig.allFields)h.conditions&&(d[h.id]=h.conditions);return d},[t?.formConfig?.allFields]),y=de(S,i),x=useCallback(d=>d<0||d>=r.steps.length?false:a[d]?.visible??true,[a,r.steps.length]),b=useCallback(d=>d<0||d>=r.steps.length?false:a[d]?.skippable??false,[a,r.steps.length]),f=useCallback(d=>y[d]?.visible??true,[y]),c=useCallback(d=>y[d]?.disabled??false,[y]),P=useCallback(d=>y[d]?.required??false,[y]),W=useCallback(d=>y[d]?.readonly??false,[y]);return {stepConditions:n,fieldConditions:y,allStepConditions:a,isStepVisible:x,isStepSkippable:b,isFieldVisible:f,isFieldDisabled:c,isFieldRequired:P,isFieldReadonly:W}}function ve({workflowConfig:r,workflowState:e,workflowContext:t,conditionsHelpers:i,setCurrentStep:o,setTransitioning:s,markStepVisited:n,setStepData:l,onStepChange:m}){let a=useRef(m);a.current=m;let S=r.steps[e.currentStepIndex],y=useCallback(()=>({setStepData:(p,g)=>{l(g,p);},setStepFields:(p,g)=>{let k={...e.allData[p]||{},...g};l(k,p);},getStepData:p=>e.allData[p]||{},setNextStepField:(p,g)=>{let u=e.currentStepIndex+1;if(u<r.steps.length){let k=r.steps[u].id,B={...e.allData[k]||{},[p]:g};l(B,k);}},setNextStepFields:p=>{let g=e.currentStepIndex+1;if(g<r.steps.length){let u=r.steps[g].id,C={...e.allData[u]||{},...p};l(C,u);}},getAllData:()=>({...e.allData}),getSteps:()=>[...r.steps]}),[e.allData,e.currentStepIndex,r.steps,l]),x=useCallback(async p=>{if(p<0||p>=r.steps.length||!i.isStepVisible(p))return false;s(true);try{return a.current&&a.current(e.currentStepIndex,p,t),o(p),n(p,r.steps[p].id),!0}catch(g){return console.error("Step transition failed:",g),r.analytics?.onError&&r.analytics.onError(g,t),false}finally{s(false);}},[r.steps,r.analytics,i,e.currentStepIndex,t,s,o,n]),b=useCallback(p=>{for(let g=p+1;g<r.steps.length;g++)if(i.isStepVisible(g))return g;return null},[r.steps.length,i]),f=useCallback(p=>{for(let g=p-1;g>=0;g--)if(i.isStepVisible(g))return g;return null},[i]),c=useCallback(async()=>{if(S?.onAfterValidation)try{let g=y();await S.onAfterValidation(e.stepData,g,t);}catch(g){return console.error("onAfterValidation failed:",g),r.analytics?.onError&&r.analytics.onError(g,t),false}let p=b(e.currentStepIndex);return p===null?false:x(p)},[S,y,e.stepData,t,r.analytics,e.currentStepIndex,b,x]),P=useCallback(async()=>{let p=f(e.currentStepIndex);return p===null?false:x(p)},[e.currentStepIndex,f,x]),W=useCallback(async()=>!S?.allowSkip&&!i.isStepSkippable(e.currentStepIndex)?false:(r.analytics?.onStepSkip&&r.analytics.onStepSkip(S.id,"user_skip",t),c()),[S,i,e.currentStepIndex,r.analytics,t,c]),d=useCallback(p=>p<0||p>=r.steps.length?false:i.isStepVisible(p),[r.steps.length,i]),h=useCallback(()=>{let p=b(e.currentStepIndex);return p!==null&&d(p)},[e.currentStepIndex,b,d]),I=useCallback(()=>{let p=f(e.currentStepIndex);return p!==null&&d(p)},[e.currentStepIndex,f,d]),R=useCallback(()=>S?.allowSkip===true&&i.isStepSkippable(e.currentStepIndex),[S?.allowSkip,i,e.currentStepIndex]);return {goToStep:x,goNext:c,goPrevious:P,skipStep:W,canGoToStep:d,canGoNext:h,canGoPrevious:I,canSkipCurrentStep:R}}function Ke(r,e){switch(e.type){case "SET_CURRENT_STEP":return {...r,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...r,stepData:e.data,allData:{...r.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...r,allData:e.data};case "SET_FIELD_VALUE":{let t={...r.stepData,[e.fieldId]:e.value};return {...r,stepData:t,allData:{...r.allData,[e.stepId]:t}}}case "SET_SUBMITTING":return {...r,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...r,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...r,visitedSteps:new Set([...r.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...r,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...r,isInitializing:false};default:return r}}function Pe({defaultValues:r={},persistence:e}){let t={currentStepIndex:0,allData:r,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,o]=useReducer(Ke,t),s=e?.adapter?Q({workflowId:e.workflowId,workflowState:i,adapter:e.adapter,options:e.options,userId:e.userId}):null,n=useCallback(c=>{o({type:"SET_CURRENT_STEP",stepIndex:c});},[]),l=useCallback((c,P)=>{o({type:"SET_STEP_DATA",data:c,stepId:P});},[]),m=useCallback((c,P,W)=>{o({type:"SET_FIELD_VALUE",fieldId:c,value:P,stepId:W});},[]),a=useCallback(c=>{o({type:"SET_SUBMITTING",isSubmitting:c});},[]),S=useCallback(c=>{o({type:"SET_TRANSITIONING",isTransitioning:c});},[]),y=useCallback((c,P)=>{o({type:"MARK_STEP_VISITED",stepIndex:c,stepId:P});},[]),x=useCallback(()=>{o({type:"RESET_WORKFLOW"});},[]),b=useCallback(()=>{o({type:"SET_INITIALIZATION_COMPLETE"});},[]),f=useCallback(async()=>{if(!s)return b(),false;try{let c=await s.loadPersistedData();if(c){let P={currentStepIndex:c.currentStepIndex,allData:c.allData,stepData:c.stepData,visitedSteps:new Set(c.visitedSteps)};return o({type:"LOAD_PERSISTED_STATE",state:P}),b(),!0}}catch(c){console.error("Failed to load persisted state:",c);}return b(),false},[s,b]);return {workflowState:i,setCurrentStep:n,setStepData:l,setFieldValue:m,setSubmitting:a,setTransitioning:S,markStepVisited:y,resetWorkflow:x,loadPersistedState:f,persistence:s?{isPersisting:s.isPersisting,persistenceError:s.persistenceError,persistNow:s.persistNow,clearPersistedData:s.clearPersistedData,hasPersistedData:s.hasPersistedData}:null}}function xe({workflowConfig:r,workflowState:e,workflowContext:t,setSubmitting:i,onWorkflowComplete:o,analyticsStartTime:s}){let n=useRef(o);n.current=o;let l=useCallback(async()=>{i(true);try{if(n.current&&await n.current(e.allData),r.analytics?.onWorkflowComplete){let a=Date.now()-s.current;r.analytics.onWorkflowComplete(r.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),r.analytics?.onError&&r.analytics.onError(a,t),a}finally{i(false);}},[e.allData,r.analytics,r.id,t,s,i]),m=useCallback(()=>e.isSubmitting?false:e.currentStepIndex===r.steps.length-1,[e.isSubmitting,e.currentStepIndex,r.steps.length]);return {submitWorkflow:l,isSubmitting:e.isSubmitting,canSubmit:m()}}var De=createContext(null);function ee({children:r,workflowConfig:e,defaultValues:t={},onStepChange:i,onWorkflowComplete:o,className:s}){let{workflowState:n,setCurrentStep:l,setStepData:m,setFieldValue:a,setSubmitting:S,setTransitioning:y,markStepVisited:x,resetWorkflow:b,loadPersistedState:f,persistence:c}=Pe({defaultValues:t,persistence:e.persistence?{workflowId:e.id,adapter:e.persistence.adapter,options:e.persistence.options,userId:e.persistence.userId}:void 0});useEffect(()=>{e.persistence&&f&&f();},[]);let P=c?.isPersisting??false,W=c?.persistenceError??null,d=c?.persistNow,h=useMemo(()=>({workflowId:e.id,currentStepIndex:n.currentStepIndex,totalSteps:e.steps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===e.steps.length-1,visitedSteps:n.visitedSteps}),[e.id,e.steps.length,n.currentStepIndex,n.allData,n.stepData,n.visitedSteps]),I=useMemo(()=>e.steps[n.currentStepIndex],[e.steps,n.currentStepIndex]),R=useMemo(()=>I?.formConfig,[I]),{analyticsStartTime:p}=ye({workflowConfig:e,workflowState:n,workflowContext:h}),g=he({workflowConfig:e,workflowState:n,currentStep:I}),{goToStep:u,goNext:k,goPrevious:C,skipStep:B,canGoToStep:re,canGoNext:ie,canGoPrevious:oe,canSkipCurrentStep:se}=ve({workflowConfig:e,workflowState:n,workflowContext:h,conditionsHelpers:g,setCurrentStep:l,setTransitioning:y,markStepVisited:x,setStepData:m,onStepChange:i});useEffect(()=>{if(!g.isStepVisible(n.currentStepIndex)){for(let A=0;A<e.steps.length;A++)if(g.isStepVisible(A)){l(A),x(A,e.steps[A].id);break}}},[g,n.currentStepIndex,e.steps,l,x]);let{submitWorkflow:M,isSubmitting:ne,canSubmit:ae}=xe({workflowConfig:e,workflowState:n,workflowContext:h,setSubmitting:S,onWorkflowComplete:o,analyticsStartTime:p}),$=useCallback((U,A)=>{a(U,A,I?.id||"");},[a,I?.id]),le=useCallback(U=>{m(U,I?.id||"");},[m,I?.id]),Ee=useCallback(async()=>{h.isLastStep?await M():await k();},[h.isLastStep,M,k]),Re=useMemo(()=>({workflowState:n,workflowConfig:e,currentStep:I,context:h,formConfig:R,conditionsHelpers:g,goToStep:u,goNext:k,goPrevious:C,skipStep:B,canGoToStep:re,canGoNext:ie,canGoPrevious:oe,canSkipCurrentStep:se,setValue:$,setStepData:le,resetWorkflow:b,submitWorkflow:M,isSubmitting:ne,canSubmit:ae,persistNow:d,isPersisting:P,persistenceError:W}),[n,e,I,h,R,g,u,k,C,B,re,ie,oe,se,$,le,b,M,ne,ae,d,P,W]);return jsx(De.Provider,{value:Re,children:jsx(FormProvider,{formConfig:R,defaultValues:n?.allData[I?.id]||{},onFieldChange:$,"data-workflow-id":e.id,className:s,onSubmit:Ee,children:r},n.isInitializing.toString())})}function E(){let r=useContext(De);if(!r)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return r}function Ze({children:r,workflowConfig:e,...t}){let[i,o]=useState(),s=useMemo(()=>e instanceof L?e.build():e,[e]);return useEffect(()=>{if(typeof window<"u"&&F.shouldDisplayWatermark()){let l=F.getWatermarkMessage();o(l);}},[]),jsxs("div",{style:{position:"relative"},children:[jsx(ee,{...t,workflowConfig:s,children:r}),i&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function je(){let{currentStep:r}=E();if(!r)return null;let{formConfig:e,renderer:t}=r;return e?t?t(r):jsx(FormBody,{}):null}function it({className:r,...e}){let{context:t,workflowState:i,workflowConfig:o,currentStep:s}=E(),{submit:n,formState:l}=useFormContext(),m=!i.isTransitioning&&!i.isSubmitting,a=async y=>{y?.preventDefault(),m&&await n(y);},S={isLastStep:t.isLastStep,canGoNext:m,isSubmitting:l.isSubmitting||i.isSubmitting,onSubmit:a,className:r,currentStep:s,stepData:l.values||{},allData:t.allData,context:t};return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:S,...e})}function at({className:r,...e}){let{context:t,goPrevious:i,workflowState:o,workflowConfig:s,currentStep:n}=E(),{formState:l}=useFormContext(),m=t.currentStepIndex>0&&!o.isTransitioning&&!o.isSubmitting,S={canGoPrevious:m,onPrevious:async y=>{y?.preventDefault(),m&&await i();},className:r,currentStep:n,stepData:l.values||{},allData:t.allData,context:t};return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:S,...e})}function dt({className:r,...e}){let{currentStep:t,skipStep:i,workflowState:o,workflowConfig:s,context:n,conditionsHelpers:l}=E(),{formState:m}=useFormContext(),a=(!!t?.allowSkip||l.isStepSkippable(o.currentStepIndex))&&!o.isTransitioning&&!o.isSubmitting,y={canSkip:a,onSkip:async x=>{x?.preventDefault(),a&&await i();},className:r,currentStep:t,stepData:m.values||{},allData:n.allData,context:n};return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:y,...e})}function St({onStepClick:r,className:e,...t}){let{workflowConfig:i,workflowState:o,goToStep:s,conditionsHelpers:n}=E(),{visibleSteps:l,visibleToOriginalIndexMap:m,originalToVisibleIndexMap:a}=useMemo(()=>{let b=[],f=new Map,c=new Map;return i.steps.forEach((P,W)=>{if(n.isStepVisible(W)){let d=b.length;b.push(P),f.set(d,W),c.set(W,d);}}),{visibleSteps:b,visibleToOriginalIndexMap:f,originalToVisibleIndexMap:c}},[i.steps,n]),S=b=>{let f=m.get(b);f!==void 0&&(r?r(f):s(f));},y=a.get(o.currentStepIndex)??-1,x={steps:l,currentStepIndex:y,visitedSteps:o.visitedSteps,onStepClick:S,className:e};return jsx(ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:x,...t})}var te=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,t){if(this._isAvailable)try{let i=this.getStorageKey(e),o={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(o),n=this.compress?this.compressData(s):s;localStorage.setItem(i,n);}catch(i){if(i instanceof Error)if(i.name==="QuotaExceededError"||i.message.includes("quota")){await this.clearExpiredData();try{let o=this.getStorageKey(e),s={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},n=JSON.stringify(s),l=this.compress?this.compressData(n):n;localStorage.setItem(o,l);}catch(o){throw new D("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",o)}}else throw new D(`Failed to save to localStorage: ${i.message}`,"SAVE_FAILED",i);else throw new D("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return null;let o=this.compress?this.decompressData(i):i,s=JSON.parse(o);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(t){throw t instanceof Error?new D(`Failed to load from localStorage: ${t.message}`,"LOAD_FAILED",t):new D("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let t=this.getStorageKey(e);localStorage.removeItem(t);}catch(t){throw t instanceof Error?new D(`Failed to remove from localStorage: ${t.message}`,"REMOVE_FAILED",t):new D("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return !1;let o=this.compress?this.decompressData(i):i,s=JSON.parse(o);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix)){let o=i.substring(this.keyPrefix.length);await this.exists(o)&&e.push(o);}}return e}catch(e){throw e instanceof Error?new D(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new D("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let t of e)localStorage.removeItem(t);}catch(e){throw e instanceof Error?new D(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new D("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix))try{let o=localStorage.getItem(i);if(o){let s=this.compress?this.decompressData(o):o,n=JSON.parse(s);n.expiresAt&&Date.now()>n.expiresAt&&e.push(i);}}catch{e.push(i);}}for(let t of e)localStorage.removeItem(t);}};
2
- export{te as LocalStorageAdapter,F as RilayLicenseManager,Ze as Workflow,je as WorkflowBody,it as WorkflowNextButton,D as WorkflowPersistenceError,at as WorkflowPreviousButton,ee as WorkflowProvider,dt as WorkflowSkipButton,St as WorkflowStepper,Fe as createFlow,Z as debounce,L as flow,H as generateStorageKey,Be as mergePersistedState,fe as persistedToWorkflowState,ce as useConditionEvaluation,de as useMultipleConditionEvaluation,ue as useMultipleStepConditionEvaluation,Q as usePersistence,ye as useWorkflowAnalytics,he as useWorkflowConditions,E as useWorkflowContext,ve as useWorkflowNavigation,Pe as useWorkflowState,xe as useWorkflowSubmission,_e as validatePersistedData,X as workflowStateToPersisted};
1
+ import {ril,IdGenerator,normalizeToArray,deepClone,ensureUnique,ComponentRendererWrapper,evaluateCondition}from'@rilaykit/core';export*from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import {createContext,useMemo,useState,useRef,useEffect,useCallback,useReducer,useContext}from'react';import*as ge from'@noble/ed25519';import {jsx,jsxs}from'react/jsx-runtime';var L=class r{constructor(e,t,i,n){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=t,this.workflowName=i,this.workflowDescription=n;}static create(e,t,i,n){return new r(e,t,i,n)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:e.onAfterValidation}}addStep(e){let t=normalizeToArray(e);for(let i of t){let n=this.createStepFromDefinition(i);this.steps.push(n);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(t){throw new Error(`Failed to install plugin "${e.name}": ${t instanceof Error?t.message:String(t)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let t=e.dependencies.filter(i=>!this.plugins.some(n=>n.name===i));if(t.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${t.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(t=>t.name!==e),this}updateStep(e,t){let i=this.steps.findIndex(n=>n.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[i]={...this.steps[i],...t},this}addStepConditions(e,t){let i=this.steps.findIndex(o=>o.id===e);if(i===-1)throw new Error(`Step with ID "${e}" not found`);let n={...this.steps[i].conditions,...t};return this.steps[i]={...this.steps[i],conditions:n},this}removeStep(e){return this.steps=this.steps.filter(t=>t.id!==e),this}getStep(e){return this.steps.find(t=>t.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,t){let i=new r(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return i.steps=deepClone(this.steps),i.analytics=this.analytics?deepClone(this.analytics):void 0,i.persistenceConfig=this.persistenceConfig?deepClone(this.persistenceConfig):void 0,i.plugins=[...this.plugins],i}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(i=>i.id);try{ensureUnique(t,"step");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of this.plugins)if(i.dependencies){let n=i.dependencies.filter(o=>!this.plugins.some(s=>s.name===o));n.length>0&&e.push(`Plugin "${i.name}" requires missing dependencies: ${n.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((i,n)=>i+n.formConfig.allFields.length,0),t=this.steps.map(i=>i.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:t.length>0?Math.max(...t):0,minFieldsInStep:t.length>0?Math.min(...t):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function Be(r,e,t,i){return L.create(r,e,t,i)}ril.prototype.flow=function(r,e,t){return L.create(this,r,e,t)};var Me=1751361139160,Oe="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",k=class k{static async setLicenseKey(e){k.licenseKey=e||"",k.licenseKey?k.licenseResult=await k.validateLicense():k.licenseResult={valid:false,error:"MISSING"},k.isInitialized=true;}static async validateLicense(){if(!k.licenseKey)return {valid:false,error:"MISSING"};try{if(!k.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=k.licenseKey.slice(4),i=k.base64ToString(e).split(".");if(i.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[n,o,s]=i,p=`${n}.${o}`,g=new TextEncoder().encode(p),a=s.match(/.{2}/g);if(!a)return {valid:!1,error:"INVALID"};let l=new Uint8Array(a.map(W=>Number.parseInt(W,16))),f=k.hexToBytes(Oe);if(!await ge.verify(l,g,f))return {valid:!1,error:"SIGNATURE_INVALID"};let y=k.base64ToString(o.replace(/-/g,"+").replace(/_/g,"/")),c=JSON.parse(y),d=Math.floor(Date.now()/1e3);return c.e<d?{valid:!1,error:"EXPIRED",data:k.decompressPayload(c)}:Me>c.e*1e3?{valid:!1,error:"EXPIRED",data:k.decompressPayload(c)}:c.p===void 0||!c.c||!c.i||!c.e||!c.t?{valid:!1,error:"INVALID"}:{valid:!0,data:k.decompressPayload(c)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let t=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)t[i/2]=Number.parseInt(e.substring(i,i+2),16);return t}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",n=0,o=e.replace(/[^A-Za-z0-9+/]/g,"");for(;n<o.length;){let s=t.indexOf(o.charAt(n++)),p=t.indexOf(o.charAt(n++)),g=t.indexOf(o.charAt(n++)),a=t.indexOf(o.charAt(n++)),l=s<<18|p<<12|g<<6|a;i+=String.fromCharCode(l>>16&255),g!==64&&(i+=String.fromCharCode(l>>8&255)),a!==64&&(i+=String.fromCharCode(l&255));}return i}static getLicenseResult(){return k.isInitialized?k.licenseResult?k.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!k.getLicenseResult().valid}static getWatermarkMessage(){let e=k.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=k.getLicenseResult();if(e.valid)return;let i={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${i}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=k.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};k.licenseKey="",k.licenseResult=null,k.isInitialized=false;var B=k;function Z(r,e={},t={}){return useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=n=>{try{let o;return n&&typeof n=="object"&&"build"in n?o=n.build():o=n,evaluateCondition(o,e)}catch(o){return console.warn("Error evaluating condition:",o),false}};return {visible:r.visible?i(r.visible):true,disabled:r.disabled?i(r.disabled):false,required:r.required?i(r.required):false,readonly:r.readonly?i(r.readonly):false}},[r,e,t])}function ye(r,e={}){return useMemo(()=>{let t={};for(let[i,n]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},n){let o=s=>{try{return s&&typeof s=="object"&&"build"in s?evaluateCondition(s.build(),e):evaluateCondition(s,e)}catch(p){return console.warn(`Error evaluating condition for field ${i}:`,p),false}};t[i]={visible:n.visible?o(n.visible):true,disabled:n.disabled?o(n.disabled):false,required:n.required?o(n.required):false,readonly:n.readonly?o(n.readonly):false};}return t},[r,e])}function be(r,e={}){return useMemo(()=>{let t={};for(let[i,n]of Object.entries(r)){let o=Number.parseInt(i,10);if(t[o]={visible:true,disabled:false,required:false,readonly:false},n){let s=p=>{try{return p&&typeof p=="object"&&"build"in p?evaluateCondition(p.build(),e):evaluateCondition(p,e)}catch(g){return console.warn(`Error evaluating condition for step ${o}:`,g),false}};t[o]={visible:n.visible?s(n.visible):true,disabled:n.disabled?s(n.disabled):false,required:n.required?s(n.required):false,readonly:n.readonly?s(n.readonly):false};}}return t},[r,e])}var w=class extends Error{constructor(t,i,n){super(`[WorkflowPersistence] ${t} (Code: ${i})`);this.code=i;this.cause=n;this.name="WorkflowPersistenceError";}};function Y(r,e,t){return {workflowId:r,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:t}}function he(r){return {currentStepIndex:r.currentStepIndex,allData:{...r.allData},stepData:{...r.stepData},visitedSteps:new Set(r.visitedSteps),isSubmitting:false,isTransitioning:false}}function Ve(r){if(!r||typeof r!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let t of e)if(!(t in r))return false;return !(typeof r.workflowId!="string"||typeof r.currentStepIndex!="number"||typeof r.allData!="object"||typeof r.stepData!="object"||!Array.isArray(r.visitedSteps)||typeof r.lastSaved!="number")}function Q(r,e){return e?`${e}:${r}`:r}function j(r,e){let t=null;return (...i)=>{t&&clearTimeout(t),t=setTimeout(()=>{r(...i);},e);}}function _e(r,e,t="persist"){let i=he(e);switch(t){case "persist":return {...i,isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};case "current":return {...r,visitedSteps:new Set([...r.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:r.currentStepIndex,allData:{...i.allData,...r.allData},stepData:{...i.stepData,...r.stepData},visitedSteps:new Set([...i.visitedSteps,...r.visitedSteps]),isSubmitting:r.isSubmitting,isTransitioning:r.isTransitioning};default:return i}}function q({workflowId:r,workflowState:e,adapter:t,options:i={},userId:n}){let[o,s]=useState(false),[p,g]=useState(null),[a,l]=useState(false),f=useRef(t),v=useRef(i),y=useRef({hasPendingChanges:false});useEffect(()=>{f.current=t,v.current=i;},[t,i]);let c=Q(v.current.storageKey||r,n),d=useCallback(()=>{g(null);},[]),P=useCallback((S,x)=>{let C=S instanceof w?S:new w(`${x} failed: ${S.message}`,"OPERATION_FAILED",S);g(C),console.error("[WorkflowPersistence]",C);},[]),W=useCallback(async S=>{d(),s(true);try{let x=Y(r,S,v.current.metadata);await f.current.save(c,x),y.current.lastSavedState={...S},y.current.hasPendingChanges=!1;}catch(x){throw P(x,"Save"),x}finally{s(false);}},[r,c,d,P]),m=useRef(j(async S=>{try{await W(S);}catch(x){console.debug("[WorkflowPersistence] Auto-save failed:",x);}},i.debounceMs||500)),h=useCallback((S,x)=>x?S.currentStepIndex!==x.currentStepIndex||JSON.stringify(S.allData)!==JSON.stringify(x.allData)||JSON.stringify(S.stepData)!==JSON.stringify(x.stepData)||S.visitedSteps.size!==x.visitedSteps.size||!Array.from(S.visitedSteps).every(C=>x.visitedSteps.has(C)):true,[]),I=useCallback(async()=>{d(),l(true);try{let S=await f.current.load(c);return S&&(y.current.lastSavedState={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},y.current.hasPendingChanges=!1),S}catch(S){return P(S,"Load"),null}finally{setTimeout(()=>l(false),100);}},[c,d,P]),R=useCallback(async()=>{d();try{await f.current.remove(c),y.current.lastSavedState=void 0,y.current.hasPendingChanges=!1;}catch(S){throw P(S,"Clear"),S}},[c,d,P]),u=useCallback(async()=>{try{return await f.current.exists(c)}catch(S){return P(S,"Exists check"),false}},[c,P]);useEffect(()=>{v.current.autoPersist&&(o||a||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,y.current.lastSavedState)&&(y.current.hasPendingChanges=true,m.current(e)));},[e,o,a,h]);let b=useCallback(async()=>{await W(e);},[W,e]);return {isPersisting:o,persistenceError:p,persistNow:b,loadPersistedData:I,clearPersistedData:R,hasPersistedData:u}}function Ue(){let{workflowConfig:r,currentStep:e}=D(),t=useMemo(()=>e?.metadata,[e?.metadata]),i=useMemo(()=>a=>r.steps.find(f=>f.id===a)?.metadata,[r.steps]),n=useMemo(()=>a=>r.steps[a]?.metadata,[r.steps]),o=useMemo(()=>a=>t?a in t:false,[t]),s=useMemo(()=>(a,l)=>t&&a in t?t[a]:l,[t]),p=useMemo(()=>()=>r.steps.map((a,l)=>({id:a.id,title:a.title,index:l,metadata:a.metadata})),[r.steps]),g=useMemo(()=>a=>r.steps.map((l,f)=>({step:l,index:f})).filter(({step:l,index:f})=>a(l.metadata,l.id,f)).map(({step:l})=>l.id),[r.steps]);return {current:t,getByStepId:i,getByStepIndex:n,hasCurrentKey:o,getCurrentValue:s,getAllStepsMetadata:p,findStepsByMetadata:g}}function te({workflowConfig:r,workflowState:e,workflowContext:t}){let i=useRef(Date.now()),n=useRef(new Map),o=useRef(false),s=useRef(null);useEffect(()=>{r.analytics?.onWorkflowStart&&!o.current&&(o.current=true,r.analytics.onWorkflowStart(r.id,t));},[r.id,r.analytics,t]),useEffect(()=>{let a=r.steps[e.currentStepIndex];if(a&&s.current!==a.id){if(s.current&&r.analytics?.onStepComplete){let l=n.current.get(s.current);l&&r.analytics.onStepComplete(s.current,Date.now()-l,e.stepData,t);}s.current=a.id,n.current.set(a.id,Date.now()),r.analytics?.onStepStart&&r.analytics.onStepStart(a.id,Date.now(),t);}},[e.currentStepIndex,r.steps,r.analytics,t,e.stepData]);let p=useCallback((a,l)=>{r.analytics?.onStepSkip&&r.analytics.onStepSkip(a,l,t);},[r.analytics,t]),g=useCallback(a=>{r.analytics?.onError&&r.analytics.onError(a,t);},[r.analytics,t]);return {analyticsStartTime:i,trackStepSkip:p,trackError:g}}function xe(r,e){return {visible:r.visible,skippable:e===true||r.required}}function re({workflowConfig:r,workflowState:e,currentStep:t}){let i=useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),n=useMemo(()=>{if(t?.conditions)return {visible:t.conditions.visible,required:t.conditions.skippable}},[t?.conditions]),o=Z(n,i,{visible:true,disabled:false,required:false,readonly:false}),s=useMemo(()=>xe(o,t?.allowSkip),[o,t?.allowSkip]),p=useMemo(()=>{let m={};return r.steps.forEach((h,I)=>{h.conditions&&(m[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),m},[r.steps]),g=be(p,i),a=useMemo(()=>{let m={};return r.steps.forEach((h,I)=>{let R=g[I];R?m[I]=xe(R,h.allowSkip):m[I]={visible:true,skippable:h.allowSkip===true};}),m},[r.steps,g]),l=useMemo(()=>{if(!t?.formConfig?.allFields)return {};let m={};for(let h of t.formConfig.allFields)h.conditions&&(m[h.id]=h.conditions);return m},[t?.formConfig?.allFields]),f=ye(l,i),v=useCallback(m=>m<0||m>=r.steps.length?false:a[m]?.visible??true,[a,r.steps.length]),y=useCallback(m=>m<0||m>=r.steps.length?false:a[m]?.skippable??false,[a,r.steps.length]),c=useCallback(m=>f[m]?.visible??true,[f]),d=useCallback(m=>f[m]?.disabled??false,[f]),P=useCallback(m=>f[m]?.required??false,[f]),W=useCallback(m=>f[m]?.readonly??false,[f]);return {stepConditions:s,fieldConditions:f,allStepConditions:a,isStepVisible:v,isStepSkippable:y,isFieldVisible:c,isFieldDisabled:d,isFieldRequired:P,isFieldReadonly:W}}function ie({workflowConfig:r,workflowState:e,workflowContext:t,conditionsHelpers:i,setCurrentStep:n,setTransitioning:o,markStepVisited:s,setStepData:p,onStepChange:g}){let a=useRef(g);a.current=g;let l=r.steps[e.currentStepIndex],f=useCallback(()=>({setStepData:(u,b)=>{p(b,u);},setStepFields:(u,b)=>{let x={...e.allData[u]||{},...b};p(x,u);},getStepData:u=>e.allData[u]||{},setNextStepField:(u,b)=>{let S=e.currentStepIndex+1;if(S<r.steps.length){let x=r.steps[S].id,_={...e.allData[x]||{},[u]:b};p(_,x);}},setNextStepFields:u=>{let b=e.currentStepIndex+1;if(b<r.steps.length){let S=r.steps[b].id,C={...e.allData[S]||{},...u};p(C,S);}},getAllData:()=>({...e.allData}),getSteps:()=>[...r.steps]}),[e.allData,e.currentStepIndex,r.steps,p]),v=useCallback(async u=>{if(u<0||u>=r.steps.length||!i.isStepVisible(u))return false;o(true);try{return a.current&&a.current(e.currentStepIndex,u,t),n(u),s(u,r.steps[u].id),!0}catch(b){return console.error("Step transition failed:",b),r.analytics?.onError&&r.analytics.onError(b,t),false}finally{o(false);}},[r.steps,r.analytics,i,e.currentStepIndex,t,o,n,s]),y=useCallback(u=>{for(let b=u+1;b<r.steps.length;b++)if(i.isStepVisible(b))return b;return null},[r.steps.length,i]),c=useCallback(u=>{for(let b=u-1;b>=0;b--)if(i.isStepVisible(b))return b;return null},[i]),d=useCallback(async()=>{if(l?.onAfterValidation)try{let b=f();await l.onAfterValidation(e.stepData,b,t);}catch(b){return console.error("onAfterValidation failed:",b),r.analytics?.onError&&r.analytics.onError(b,t),false}let u=y(e.currentStepIndex);return u===null?false:v(u)},[l,f,e.stepData,t,r.analytics,e.currentStepIndex,y,v]),P=useCallback(async()=>{let u=c(e.currentStepIndex);return u===null?false:v(u)},[e.currentStepIndex,c,v]),W=useCallback(async()=>!l?.allowSkip&&!i.isStepSkippable(e.currentStepIndex)?false:(r.analytics?.onStepSkip&&r.analytics.onStepSkip(l.id,"user_skip",t),d()),[l,i,e.currentStepIndex,r.analytics,t,d]),m=useCallback(u=>u<0||u>=r.steps.length?false:i.isStepVisible(u),[r.steps.length,i]),h=useCallback(()=>{let u=y(e.currentStepIndex);return u!==null&&m(u)},[e.currentStepIndex,y,m]),I=useCallback(()=>{let u=c(e.currentStepIndex);return u!==null&&m(u)},[e.currentStepIndex,c,m]),R=useCallback(()=>l?.allowSkip===true&&i.isStepSkippable(e.currentStepIndex),[l?.allowSkip,i,e.currentStepIndex]);return {goToStep:v,goNext:d,goPrevious:P,skipStep:W,canGoToStep:m,canGoNext:h,canGoPrevious:I,canSkipCurrentStep:R}}function qe(r,e){switch(e.type){case "SET_CURRENT_STEP":return {...r,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...r,stepData:e.data,allData:{...r.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...r,allData:e.data};case "SET_FIELD_VALUE":{let t={...r.stepData,[e.fieldId]:e.value};return {...r,stepData:t,allData:{...r.allData,[e.stepId]:t}}}case "SET_SUBMITTING":return {...r,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...r,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...r,visitedSteps:new Set([...r.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...r,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...r,isInitializing:false};default:return r}}function ne({defaultValues:r={},persistence:e}){let t={currentStepIndex:0,allData:r,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,n]=useReducer(qe,t),o=e?.adapter?q({workflowId:e.workflowId,workflowState:i,adapter:e.adapter,options:e.options,userId:e.userId}):null,s=useCallback(d=>{n({type:"SET_CURRENT_STEP",stepIndex:d});},[]),p=useCallback((d,P)=>{n({type:"SET_STEP_DATA",data:d,stepId:P});},[]),g=useCallback((d,P,W)=>{n({type:"SET_FIELD_VALUE",fieldId:d,value:P,stepId:W});},[]),a=useCallback(d=>{n({type:"SET_SUBMITTING",isSubmitting:d});},[]),l=useCallback(d=>{n({type:"SET_TRANSITIONING",isTransitioning:d});},[]),f=useCallback((d,P)=>{n({type:"MARK_STEP_VISITED",stepIndex:d,stepId:P});},[]),v=useCallback(()=>{n({type:"RESET_WORKFLOW"});},[]),y=useCallback(()=>{n({type:"SET_INITIALIZATION_COMPLETE"});},[]),c=useCallback(async()=>{if(!o)return y(),false;try{let d=await o.loadPersistedData();if(d){let P={currentStepIndex:d.currentStepIndex,allData:d.allData,stepData:d.stepData,visitedSteps:new Set(d.visitedSteps)};return n({type:"LOAD_PERSISTED_STATE",state:P}),y(),!0}}catch(d){console.error("Failed to load persisted state:",d);}return y(),false},[o,y]);return {workflowState:i,setCurrentStep:s,setStepData:p,setFieldValue:g,setSubmitting:a,setTransitioning:l,markStepVisited:f,resetWorkflow:v,loadPersistedState:c,persistence:o?{isPersisting:o.isPersisting,persistenceError:o.persistenceError,persistNow:o.persistNow,clearPersistedData:o.clearPersistedData,hasPersistedData:o.hasPersistedData}:null}}function oe({workflowConfig:r,workflowState:e,workflowContext:t,setSubmitting:i,onWorkflowComplete:n,analyticsStartTime:o}){let s=useRef(n);s.current=n;let p=useCallback(async()=>{i(true);try{if(s.current&&await s.current(e.allData),r.analytics?.onWorkflowComplete){let a=Date.now()-o.current;r.analytics.onWorkflowComplete(r.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),r.analytics?.onError&&r.analytics.onError(a,t),a}finally{i(false);}},[e.allData,r.analytics,r.id,t,o,i]),g=useCallback(()=>e.isSubmitting?false:e.currentStepIndex===r.steps.length-1,[e.isSubmitting,e.currentStepIndex,r.steps.length]);return {submitWorkflow:p,isSubmitting:e.isSubmitting,canSubmit:g()}}var De=createContext(null);function ae({children:r,workflowConfig:e,defaultValues:t={},onStepChange:i,onWorkflowComplete:n,className:o}){let{workflowState:s,setCurrentStep:p,setStepData:g,setFieldValue:a,setSubmitting:l,setTransitioning:f,markStepVisited:v,resetWorkflow:y,loadPersistedState:c,persistence:d}=ne({defaultValues:t,persistence:e.persistence?{workflowId:e.id,adapter:e.persistence.adapter,options:e.persistence.options,userId:e.persistence.userId}:void 0});useEffect(()=>{e.persistence&&c&&c();},[]);let P=d?.isPersisting??false,W=d?.persistenceError??null,m=d?.persistNow,h=useMemo(()=>({workflowId:e.id,currentStepIndex:s.currentStepIndex,totalSteps:e.steps.length,allData:s.allData,stepData:s.stepData,isFirstStep:s.currentStepIndex===0,isLastStep:s.currentStepIndex===e.steps.length-1,visitedSteps:s.visitedSteps}),[e.id,e.steps.length,s.currentStepIndex,s.allData,s.stepData,s.visitedSteps]),I=useMemo(()=>e.steps[s.currentStepIndex],[e.steps,s.currentStepIndex]),R=useMemo(()=>I?.formConfig,[I]),{analyticsStartTime:u}=te({workflowConfig:e,workflowState:s,workflowContext:h}),b=re({workflowConfig:e,workflowState:s,currentStep:I}),{goToStep:S,goNext:x,goPrevious:C,skipStep:_,canGoToStep:pe,canGoNext:ce,canGoPrevious:de,canSkipCurrentStep:ue}=ie({workflowConfig:e,workflowState:s,workflowContext:h,conditionsHelpers:b,setCurrentStep:p,setTransitioning:f,markStepVisited:v,setStepData:g,onStepChange:i});useEffect(()=>{if(!b.isStepVisible(s.currentStepIndex)){for(let A=0;A<e.steps.length;A++)if(b.isStepVisible(A)){p(A),v(A,e.steps[A].id);break}}},[b,s.currentStepIndex,e.steps,p,v]);let{submitWorkflow:U,isSubmitting:fe,canSubmit:me}=oe({workflowConfig:e,workflowState:s,workflowContext:h,setSubmitting:l,onWorkflowComplete:n,analyticsStartTime:u}),J=useCallback((K,A)=>{a(K,A,I?.id||"");},[a,I?.id]),Se=useCallback(K=>{g(K,I?.id||"");},[g,I?.id]),Re=useCallback(async()=>{h.isLastStep?await U():await x();},[h.isLastStep,U,x]),Ce=useMemo(()=>({workflowState:s,workflowConfig:e,currentStep:I,context:h,formConfig:R,conditionsHelpers:b,currentStepMetadata:I?.metadata,goToStep:S,goNext:x,goPrevious:C,skipStep:_,canGoToStep:pe,canGoNext:ce,canGoPrevious:de,canSkipCurrentStep:ue,setValue:J,setStepData:Se,resetWorkflow:y,submitWorkflow:U,isSubmitting:fe,canSubmit:me,persistNow:m,isPersisting:P,persistenceError:W}),[s,e,I,h,R,b,S,x,C,_,pe,ce,de,ue,J,Se,y,U,fe,me,m,P,W]);return jsx(De.Provider,{value:Ce,children:jsx(FormProvider,{formConfig:R,defaultValues:s?.allData[I?.id]||{},onFieldChange:J,"data-workflow-id":e.id,className:o,onSubmit:Re,children:r},s.isInitializing.toString())})}function D(){let r=useContext(De);if(!r)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return r}function Qe({children:r,workflowConfig:e,...t}){let[i,n]=useState(),o=useMemo(()=>e instanceof L?e.build():e,[e]);return useEffect(()=>{if(typeof window<"u"&&B.shouldDisplayWatermark()){let p=B.getWatermarkMessage();n(p);}},[]),jsxs("div",{style:{position:"relative"},children:[jsx(ae,{...t,workflowConfig:o,children:r}),i&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function tt({stepId:r,children:e}){let{currentStep:t}=D();if(!t||r&&t.id!==r)return null;let{formConfig:i,renderer:n}=t;return i?n?n(t):e??jsx(FormBody,{}):null}function ot({className:r,isSubmitting:e,...t}){let{context:i,workflowState:n,workflowConfig:o,currentStep:s}=D(),{submit:p,formState:g}=useFormContext(),a=g.isSubmitting||n.isSubmitting,l=e??a,f=!n.isTransitioning&&!l,v=async c=>{c?.preventDefault(),f&&await p(c);},y={isLastStep:i.isLastStep,canGoNext:f,isSubmitting:l,onSubmit:v,className:r,currentStep:s,stepData:g.values||{},allData:i.allData,context:i};return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:y,...t})}function pt({className:r,isSubmitting:e,...t}){let{context:i,goPrevious:n,workflowState:o,workflowConfig:s,currentStep:p}=D(),{formState:g}=useFormContext(),a=g.isSubmitting||o.isSubmitting,l=e??a,f=i.currentStepIndex>0&&!o.isTransitioning&&!l,y={canGoPrevious:f,isSubmitting:l,onPrevious:async c=>{c?.preventDefault(),f&&await n();},className:r,currentStep:p,stepData:g.values||{},allData:i.allData,context:i};return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:y,...t})}function ft({className:r,isSubmitting:e,...t}){let{currentStep:i,skipStep:n,workflowState:o,workflowConfig:s,context:p,conditionsHelpers:g}=D(),{formState:a}=useFormContext(),l=a.isSubmitting||o.isSubmitting,f=e??l,v=(!!i?.allowSkip||g.isStepSkippable(o.currentStepIndex))&&!o.isTransitioning&&!f,c={canSkip:v,isSubmitting:f,onSkip:async d=>{d?.preventDefault(),v&&await n();},className:r,currentStep:i,stepData:a.values||{},allData:p.allData,context:p};return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:c,...t})}function yt({onStepClick:r,className:e,...t}){let{workflowConfig:i,workflowState:n,goToStep:o,conditionsHelpers:s}=D(),{visibleSteps:p,visibleToOriginalIndexMap:g,originalToVisibleIndexMap:a}=useMemo(()=>{let y=[],c=new Map,d=new Map;return i.steps.forEach((P,W)=>{if(s.isStepVisible(W)){let m=y.length;y.push(P),c.set(m,W),d.set(W,m);}}),{visibleSteps:y,visibleToOriginalIndexMap:c,originalToVisibleIndexMap:d}},[i.steps,s]),l=y=>{let c=g.get(y);c!==void 0&&(r?r(c):o(c));},f=a.get(n.currentStepIndex)??-1,v={steps:p,currentStepIndex:f,visitedSteps:n.visitedSteps,onStepClick:l,className:e};return jsx(ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:v,...t})}var le=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,t){if(this._isAvailable)try{let i=this.getStorageKey(e),n={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},o=JSON.stringify(n),s=this.compress?this.compressData(o):o;localStorage.setItem(i,s);}catch(i){if(i instanceof Error)if(i.name==="QuotaExceededError"||i.message.includes("quota")){await this.clearExpiredData();try{let n=this.getStorageKey(e),o={data:{...t,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(o),p=this.compress?this.compressData(s):s;localStorage.setItem(n,p);}catch(n){throw new w("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",n)}}else throw new w(`Failed to save to localStorage: ${i.message}`,"SAVE_FAILED",i);else throw new w("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return null;let n=this.compress?this.decompressData(i):i,o=JSON.parse(n);return o.expiresAt&&Date.now()>o.expiresAt?(await this.remove(e),null):{...o.data,visitedSteps:Array.isArray(o.data.visitedSteps)?o.data.visitedSteps:[]}}catch(t){throw t instanceof Error?new w(`Failed to load from localStorage: ${t.message}`,"LOAD_FAILED",t):new w("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let t=this.getStorageKey(e);localStorage.removeItem(t);}catch(t){throw t instanceof Error?new w(`Failed to remove from localStorage: ${t.message}`,"REMOVE_FAILED",t):new w("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let t=this.getStorageKey(e),i=localStorage.getItem(t);if(!i)return !1;let n=this.compress?this.decompressData(i):i,o=JSON.parse(n);return o.expiresAt&&Date.now()>o.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix)){let n=i.substring(this.keyPrefix.length);await this.exists(n)&&e.push(n);}}return e}catch(e){throw e instanceof Error?new w(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new w("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let t of e)localStorage.removeItem(t);}catch(e){throw e instanceof Error?new w(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new w("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);if(i?.startsWith(this.keyPrefix))try{let n=localStorage.getItem(i);if(n){let o=this.compress?this.decompressData(n):n,s=JSON.parse(o);s.expiresAt&&Date.now()>s.expiresAt&&e.push(i);}}catch{e.push(i);}}for(let t of e)localStorage.removeItem(t);}};
2
+ export{le as LocalStorageAdapter,B as RilayLicenseManager,Qe as Workflow,tt as WorkflowBody,ot as WorkflowNextButton,w as WorkflowPersistenceError,pt as WorkflowPreviousButton,ae as WorkflowProvider,ft as WorkflowSkipButton,yt as WorkflowStepper,Be as createFlow,j as debounce,L as flow,Q as generateStorageKey,_e as mergePersistedState,he as persistedToWorkflowState,Z as useConditionEvaluation,q as usePersistence,Ue as useStepMetadata,te as useWorkflowAnalytics,re as useWorkflowConditions,D as useWorkflowContext,ie as useWorkflowNavigation,ne as useWorkflowState,oe as useWorkflowSubmission,Ve as validatePersistedData,Y as workflowStateToPersisted};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rilaykit/workflow",
3
- "version": "7.2.0",
3
+ "version": "8.1.0",
4
4
  "description": "Commercial workflow and multi-step form utilities for RilayKit - License required for all use",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,8 +26,8 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@noble/ed25519": "^1.7.1",
29
- "@rilaykit/core": "7.0.0",
30
- "@rilaykit/forms": "7.0.0"
29
+ "@rilaykit/core": "8.0.0",
30
+ "@rilaykit/forms": "8.0.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "react": ">=18.0.0",