@rilaykit/workflow 7.2.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +148 -54
- package/dist/index.d.ts +148 -54
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -14,39 +14,6 @@ interface WorkflowState {
|
|
|
14
14
|
isTransitioning: boolean;
|
|
15
15
|
isInitializing: boolean;
|
|
16
16
|
}
|
|
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
17
|
interface UseWorkflowStateProps {
|
|
51
18
|
defaultValues?: Record<string, any>;
|
|
52
19
|
persistence?: {
|
|
@@ -251,6 +218,30 @@ interface StepDefinition {
|
|
|
251
218
|
* Controls visibility and skippable state
|
|
252
219
|
*/
|
|
253
220
|
conditions?: StepConditionalBehavior;
|
|
221
|
+
/**
|
|
222
|
+
* Custom metadata for this step
|
|
223
|
+
* Allows storing arbitrary information that can be accessed via hooks and context
|
|
224
|
+
*
|
|
225
|
+
* This is useful for:
|
|
226
|
+
* - UI customization (icons, colors, themes)
|
|
227
|
+
* - Analytics tracking (categories, priorities, custom events)
|
|
228
|
+
* - Business logic flags (feature flags, permissions, workflow rules)
|
|
229
|
+
* - Integration data (external IDs, API endpoints, configuration)
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* {
|
|
234
|
+
* metadata: {
|
|
235
|
+
* icon: 'user-circle',
|
|
236
|
+
* category: 'personal-info',
|
|
237
|
+
* analytics: { trackCompletion: true, priority: 'high' },
|
|
238
|
+
* ui: { theme: 'primary', showProgress: true },
|
|
239
|
+
* business: { requiresApproval: false, estimatedTime: 120 }
|
|
240
|
+
* }
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
metadata?: Record<string, any>;
|
|
254
245
|
/**
|
|
255
246
|
* Callback function that executes after successful validation and before moving to next step
|
|
256
247
|
* Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
|
|
@@ -756,22 +747,6 @@ interface ConditionEvaluationResult {
|
|
|
756
747
|
* @returns Evaluated condition results
|
|
757
748
|
*/
|
|
758
749
|
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
750
|
|
|
776
751
|
/**
|
|
777
752
|
* @fileoverview Persistence hook for Rilay workflows
|
|
@@ -819,6 +794,100 @@ interface UsePersistenceProps {
|
|
|
819
794
|
*/
|
|
820
795
|
declare function usePersistence({ workflowId, workflowState, adapter, options, userId, }: UsePersistenceProps): UsePersistenceReturn;
|
|
821
796
|
|
|
797
|
+
/**
|
|
798
|
+
* Hook return type for step metadata access
|
|
799
|
+
*/
|
|
800
|
+
interface UseStepMetadataReturn {
|
|
801
|
+
/**
|
|
802
|
+
* Metadata for the current step
|
|
803
|
+
*/
|
|
804
|
+
current: Record<string, any> | undefined;
|
|
805
|
+
/**
|
|
806
|
+
* Get metadata for a specific step by ID
|
|
807
|
+
* @param stepId - The ID of the step to get metadata for
|
|
808
|
+
* @returns The metadata object or undefined if step not found
|
|
809
|
+
*/
|
|
810
|
+
getByStepId: (stepId: string) => Record<string, any> | undefined;
|
|
811
|
+
/**
|
|
812
|
+
* Get metadata for a specific step by index
|
|
813
|
+
* @param stepIndex - The index of the step to get metadata for
|
|
814
|
+
* @returns The metadata object or undefined if step not found
|
|
815
|
+
*/
|
|
816
|
+
getByStepIndex: (stepIndex: number) => Record<string, any> | undefined;
|
|
817
|
+
/**
|
|
818
|
+
* Check if current step has specific metadata key
|
|
819
|
+
* @param key - The metadata key to check for
|
|
820
|
+
* @returns True if the key exists in current step metadata
|
|
821
|
+
*/
|
|
822
|
+
hasCurrentKey: (key: string) => boolean;
|
|
823
|
+
/**
|
|
824
|
+
* Get specific metadata value from current step
|
|
825
|
+
* @param key - The metadata key to retrieve
|
|
826
|
+
* @param defaultValue - Default value if key doesn't exist
|
|
827
|
+
* @returns The metadata value or default value
|
|
828
|
+
*/
|
|
829
|
+
getCurrentValue: <T = any>(key: string, defaultValue?: T) => T;
|
|
830
|
+
/**
|
|
831
|
+
* Get all steps with their metadata
|
|
832
|
+
* @returns Array of objects containing step info and metadata
|
|
833
|
+
*/
|
|
834
|
+
getAllStepsMetadata: () => Array<{
|
|
835
|
+
id: string;
|
|
836
|
+
title: string;
|
|
837
|
+
index: number;
|
|
838
|
+
metadata: Record<string, any> | undefined;
|
|
839
|
+
}>;
|
|
840
|
+
/**
|
|
841
|
+
* Find steps by metadata criteria
|
|
842
|
+
* @param predicate - Function to test each step's metadata
|
|
843
|
+
* @returns Array of step IDs that match the criteria
|
|
844
|
+
*/
|
|
845
|
+
findStepsByMetadata: (predicate: (metadata: Record<string, any> | undefined, stepId: string, stepIndex: number) => boolean) => string[];
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Hook to access and work with step metadata in workflows
|
|
849
|
+
*
|
|
850
|
+
* This hook provides convenient methods to access metadata for the current step
|
|
851
|
+
* or any other step in the workflow. It's useful for UI customization, analytics,
|
|
852
|
+
* business logic, and integration scenarios.
|
|
853
|
+
*
|
|
854
|
+
* @returns Object containing metadata access methods and current step metadata
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* ```typescript
|
|
858
|
+
* function MyComponent() {
|
|
859
|
+
* const {
|
|
860
|
+
* current,
|
|
861
|
+
* getCurrentValue,
|
|
862
|
+
* hasCurrentKey,
|
|
863
|
+
* getByStepId,
|
|
864
|
+
* findStepsByMetadata
|
|
865
|
+
* } = useStepMetadata();
|
|
866
|
+
*
|
|
867
|
+
* // Access current step metadata
|
|
868
|
+
* const stepIcon = getCurrentValue('icon', 'default-icon');
|
|
869
|
+
* const hasAnalytics = hasCurrentKey('analytics');
|
|
870
|
+
*
|
|
871
|
+
* // Find steps with specific metadata
|
|
872
|
+
* const importantSteps = findStepsByMetadata(
|
|
873
|
+
* (metadata) => metadata?.priority === 'high'
|
|
874
|
+
* );
|
|
875
|
+
*
|
|
876
|
+
* // Get metadata from specific step
|
|
877
|
+
* const paymentStepMeta = getByStepId('payment-step');
|
|
878
|
+
*
|
|
879
|
+
* return (
|
|
880
|
+
* <div>
|
|
881
|
+
* <Icon name={stepIcon} />
|
|
882
|
+
* {hasAnalytics && <AnalyticsTracker />}
|
|
883
|
+
* <p>Important steps: {importantSteps.length}</p>
|
|
884
|
+
* </div>
|
|
885
|
+
* );
|
|
886
|
+
* }
|
|
887
|
+
* ```
|
|
888
|
+
*/
|
|
889
|
+
declare function useStepMetadata(): UseStepMetadataReturn;
|
|
890
|
+
|
|
822
891
|
interface UseWorkflowAnalyticsProps {
|
|
823
892
|
workflowConfig: WorkflowConfig;
|
|
824
893
|
workflowState: WorkflowState;
|
|
@@ -911,6 +980,7 @@ interface WorkflowContextValue {
|
|
|
911
980
|
context: WorkflowContext;
|
|
912
981
|
formConfig?: FormConfiguration;
|
|
913
982
|
conditionsHelpers: UseWorkflowConditionsReturn;
|
|
983
|
+
currentStepMetadata?: Record<string, any>;
|
|
914
984
|
goToStep: (stepIndex: number) => Promise<boolean>;
|
|
915
985
|
goNext: () => Promise<boolean>;
|
|
916
986
|
goPrevious: () => Promise<boolean>;
|
|
@@ -952,17 +1022,41 @@ type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'>
|
|
|
952
1022
|
*/
|
|
953
1023
|
declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps): react_jsx_runtime.JSX.Element;
|
|
954
1024
|
|
|
1025
|
+
interface WorkflowBodyProps {
|
|
1026
|
+
stepId?: string;
|
|
1027
|
+
}
|
|
955
1028
|
/**
|
|
956
1029
|
* Renders the main content of the current workflow step.
|
|
957
1030
|
* Simple component that renders either the children or FormBody by default.
|
|
958
1031
|
*/
|
|
959
|
-
declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
|
|
1032
|
+
declare function WorkflowBody({ stepId }: WorkflowBodyProps): react_jsx_runtime.JSX.Element | null;
|
|
960
1033
|
|
|
961
|
-
|
|
1034
|
+
interface WorkflowNextButtonProps extends ComponentRendererBaseProps<WorkflowNextButtonRendererProps> {
|
|
1035
|
+
/**
|
|
1036
|
+
* Override the isSubmitting state from workflow/form context
|
|
1037
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1038
|
+
*/
|
|
1039
|
+
isSubmitting?: boolean;
|
|
1040
|
+
}
|
|
1041
|
+
declare function WorkflowNextButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowNextButtonProps): react_jsx_runtime.JSX.Element;
|
|
962
1042
|
|
|
963
|
-
|
|
1043
|
+
interface WorkflowPreviousButtonProps extends ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps> {
|
|
1044
|
+
/**
|
|
1045
|
+
* Override the isSubmitting state from workflow/form context
|
|
1046
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1047
|
+
*/
|
|
1048
|
+
isSubmitting?: boolean;
|
|
1049
|
+
}
|
|
1050
|
+
declare function WorkflowPreviousButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowPreviousButtonProps): react_jsx_runtime.JSX.Element;
|
|
964
1051
|
|
|
965
|
-
|
|
1052
|
+
interface WorkflowSkipButtonProps extends ComponentRendererBaseProps<WorkflowSkipButtonRendererProps> {
|
|
1053
|
+
/**
|
|
1054
|
+
* Override the isSubmitting state from workflow/form context
|
|
1055
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1056
|
+
*/
|
|
1057
|
+
isSubmitting?: boolean;
|
|
1058
|
+
}
|
|
1059
|
+
declare function WorkflowSkipButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowSkipButtonProps): react_jsx_runtime.JSX.Element;
|
|
966
1060
|
|
|
967
1061
|
interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
|
|
968
1062
|
onStepClick?: (stepIndex: number) => void;
|
|
@@ -1155,4 +1249,4 @@ declare class RilayLicenseManager {
|
|
|
1155
1249
|
}>;
|
|
1156
1250
|
}
|
|
1157
1251
|
|
|
1158
|
-
export { type
|
|
1252
|
+
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
|
@@ -14,39 +14,6 @@ interface WorkflowState {
|
|
|
14
14
|
isTransitioning: boolean;
|
|
15
15
|
isInitializing: boolean;
|
|
16
16
|
}
|
|
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
17
|
interface UseWorkflowStateProps {
|
|
51
18
|
defaultValues?: Record<string, any>;
|
|
52
19
|
persistence?: {
|
|
@@ -251,6 +218,30 @@ interface StepDefinition {
|
|
|
251
218
|
* Controls visibility and skippable state
|
|
252
219
|
*/
|
|
253
220
|
conditions?: StepConditionalBehavior;
|
|
221
|
+
/**
|
|
222
|
+
* Custom metadata for this step
|
|
223
|
+
* Allows storing arbitrary information that can be accessed via hooks and context
|
|
224
|
+
*
|
|
225
|
+
* This is useful for:
|
|
226
|
+
* - UI customization (icons, colors, themes)
|
|
227
|
+
* - Analytics tracking (categories, priorities, custom events)
|
|
228
|
+
* - Business logic flags (feature flags, permissions, workflow rules)
|
|
229
|
+
* - Integration data (external IDs, API endpoints, configuration)
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* {
|
|
234
|
+
* metadata: {
|
|
235
|
+
* icon: 'user-circle',
|
|
236
|
+
* category: 'personal-info',
|
|
237
|
+
* analytics: { trackCompletion: true, priority: 'high' },
|
|
238
|
+
* ui: { theme: 'primary', showProgress: true },
|
|
239
|
+
* business: { requiresApproval: false, estimatedTime: 120 }
|
|
240
|
+
* }
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
metadata?: Record<string, any>;
|
|
254
245
|
/**
|
|
255
246
|
* Callback function that executes after successful validation and before moving to next step
|
|
256
247
|
* Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
|
|
@@ -756,22 +747,6 @@ interface ConditionEvaluationResult {
|
|
|
756
747
|
* @returns Evaluated condition results
|
|
757
748
|
*/
|
|
758
749
|
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
750
|
|
|
776
751
|
/**
|
|
777
752
|
* @fileoverview Persistence hook for Rilay workflows
|
|
@@ -819,6 +794,100 @@ interface UsePersistenceProps {
|
|
|
819
794
|
*/
|
|
820
795
|
declare function usePersistence({ workflowId, workflowState, adapter, options, userId, }: UsePersistenceProps): UsePersistenceReturn;
|
|
821
796
|
|
|
797
|
+
/**
|
|
798
|
+
* Hook return type for step metadata access
|
|
799
|
+
*/
|
|
800
|
+
interface UseStepMetadataReturn {
|
|
801
|
+
/**
|
|
802
|
+
* Metadata for the current step
|
|
803
|
+
*/
|
|
804
|
+
current: Record<string, any> | undefined;
|
|
805
|
+
/**
|
|
806
|
+
* Get metadata for a specific step by ID
|
|
807
|
+
* @param stepId - The ID of the step to get metadata for
|
|
808
|
+
* @returns The metadata object or undefined if step not found
|
|
809
|
+
*/
|
|
810
|
+
getByStepId: (stepId: string) => Record<string, any> | undefined;
|
|
811
|
+
/**
|
|
812
|
+
* Get metadata for a specific step by index
|
|
813
|
+
* @param stepIndex - The index of the step to get metadata for
|
|
814
|
+
* @returns The metadata object or undefined if step not found
|
|
815
|
+
*/
|
|
816
|
+
getByStepIndex: (stepIndex: number) => Record<string, any> | undefined;
|
|
817
|
+
/**
|
|
818
|
+
* Check if current step has specific metadata key
|
|
819
|
+
* @param key - The metadata key to check for
|
|
820
|
+
* @returns True if the key exists in current step metadata
|
|
821
|
+
*/
|
|
822
|
+
hasCurrentKey: (key: string) => boolean;
|
|
823
|
+
/**
|
|
824
|
+
* Get specific metadata value from current step
|
|
825
|
+
* @param key - The metadata key to retrieve
|
|
826
|
+
* @param defaultValue - Default value if key doesn't exist
|
|
827
|
+
* @returns The metadata value or default value
|
|
828
|
+
*/
|
|
829
|
+
getCurrentValue: <T = any>(key: string, defaultValue?: T) => T;
|
|
830
|
+
/**
|
|
831
|
+
* Get all steps with their metadata
|
|
832
|
+
* @returns Array of objects containing step info and metadata
|
|
833
|
+
*/
|
|
834
|
+
getAllStepsMetadata: () => Array<{
|
|
835
|
+
id: string;
|
|
836
|
+
title: string;
|
|
837
|
+
index: number;
|
|
838
|
+
metadata: Record<string, any> | undefined;
|
|
839
|
+
}>;
|
|
840
|
+
/**
|
|
841
|
+
* Find steps by metadata criteria
|
|
842
|
+
* @param predicate - Function to test each step's metadata
|
|
843
|
+
* @returns Array of step IDs that match the criteria
|
|
844
|
+
*/
|
|
845
|
+
findStepsByMetadata: (predicate: (metadata: Record<string, any> | undefined, stepId: string, stepIndex: number) => boolean) => string[];
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Hook to access and work with step metadata in workflows
|
|
849
|
+
*
|
|
850
|
+
* This hook provides convenient methods to access metadata for the current step
|
|
851
|
+
* or any other step in the workflow. It's useful for UI customization, analytics,
|
|
852
|
+
* business logic, and integration scenarios.
|
|
853
|
+
*
|
|
854
|
+
* @returns Object containing metadata access methods and current step metadata
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* ```typescript
|
|
858
|
+
* function MyComponent() {
|
|
859
|
+
* const {
|
|
860
|
+
* current,
|
|
861
|
+
* getCurrentValue,
|
|
862
|
+
* hasCurrentKey,
|
|
863
|
+
* getByStepId,
|
|
864
|
+
* findStepsByMetadata
|
|
865
|
+
* } = useStepMetadata();
|
|
866
|
+
*
|
|
867
|
+
* // Access current step metadata
|
|
868
|
+
* const stepIcon = getCurrentValue('icon', 'default-icon');
|
|
869
|
+
* const hasAnalytics = hasCurrentKey('analytics');
|
|
870
|
+
*
|
|
871
|
+
* // Find steps with specific metadata
|
|
872
|
+
* const importantSteps = findStepsByMetadata(
|
|
873
|
+
* (metadata) => metadata?.priority === 'high'
|
|
874
|
+
* );
|
|
875
|
+
*
|
|
876
|
+
* // Get metadata from specific step
|
|
877
|
+
* const paymentStepMeta = getByStepId('payment-step');
|
|
878
|
+
*
|
|
879
|
+
* return (
|
|
880
|
+
* <div>
|
|
881
|
+
* <Icon name={stepIcon} />
|
|
882
|
+
* {hasAnalytics && <AnalyticsTracker />}
|
|
883
|
+
* <p>Important steps: {importantSteps.length}</p>
|
|
884
|
+
* </div>
|
|
885
|
+
* );
|
|
886
|
+
* }
|
|
887
|
+
* ```
|
|
888
|
+
*/
|
|
889
|
+
declare function useStepMetadata(): UseStepMetadataReturn;
|
|
890
|
+
|
|
822
891
|
interface UseWorkflowAnalyticsProps {
|
|
823
892
|
workflowConfig: WorkflowConfig;
|
|
824
893
|
workflowState: WorkflowState;
|
|
@@ -911,6 +980,7 @@ interface WorkflowContextValue {
|
|
|
911
980
|
context: WorkflowContext;
|
|
912
981
|
formConfig?: FormConfiguration;
|
|
913
982
|
conditionsHelpers: UseWorkflowConditionsReturn;
|
|
983
|
+
currentStepMetadata?: Record<string, any>;
|
|
914
984
|
goToStep: (stepIndex: number) => Promise<boolean>;
|
|
915
985
|
goNext: () => Promise<boolean>;
|
|
916
986
|
goPrevious: () => Promise<boolean>;
|
|
@@ -952,17 +1022,41 @@ type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'>
|
|
|
952
1022
|
*/
|
|
953
1023
|
declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps): react_jsx_runtime.JSX.Element;
|
|
954
1024
|
|
|
1025
|
+
interface WorkflowBodyProps {
|
|
1026
|
+
stepId?: string;
|
|
1027
|
+
}
|
|
955
1028
|
/**
|
|
956
1029
|
* Renders the main content of the current workflow step.
|
|
957
1030
|
* Simple component that renders either the children or FormBody by default.
|
|
958
1031
|
*/
|
|
959
|
-
declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
|
|
1032
|
+
declare function WorkflowBody({ stepId }: WorkflowBodyProps): react_jsx_runtime.JSX.Element | null;
|
|
960
1033
|
|
|
961
|
-
|
|
1034
|
+
interface WorkflowNextButtonProps extends ComponentRendererBaseProps<WorkflowNextButtonRendererProps> {
|
|
1035
|
+
/**
|
|
1036
|
+
* Override the isSubmitting state from workflow/form context
|
|
1037
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1038
|
+
*/
|
|
1039
|
+
isSubmitting?: boolean;
|
|
1040
|
+
}
|
|
1041
|
+
declare function WorkflowNextButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowNextButtonProps): react_jsx_runtime.JSX.Element;
|
|
962
1042
|
|
|
963
|
-
|
|
1043
|
+
interface WorkflowPreviousButtonProps extends ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps> {
|
|
1044
|
+
/**
|
|
1045
|
+
* Override the isSubmitting state from workflow/form context
|
|
1046
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1047
|
+
*/
|
|
1048
|
+
isSubmitting?: boolean;
|
|
1049
|
+
}
|
|
1050
|
+
declare function WorkflowPreviousButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowPreviousButtonProps): react_jsx_runtime.JSX.Element;
|
|
964
1051
|
|
|
965
|
-
|
|
1052
|
+
interface WorkflowSkipButtonProps extends ComponentRendererBaseProps<WorkflowSkipButtonRendererProps> {
|
|
1053
|
+
/**
|
|
1054
|
+
* Override the isSubmitting state from workflow/form context
|
|
1055
|
+
* If provided, this value will be used instead of the computed isSubmitting state
|
|
1056
|
+
*/
|
|
1057
|
+
isSubmitting?: boolean;
|
|
1058
|
+
}
|
|
1059
|
+
declare function WorkflowSkipButton({ className, isSubmitting: overrideIsSubmitting, ...props }: WorkflowSkipButtonProps): react_jsx_runtime.JSX.Element;
|
|
966
1060
|
|
|
967
1061
|
interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
|
|
968
1062
|
onStepClick?: (stepIndex: number) => void;
|
|
@@ -1155,4 +1249,4 @@ declare class RilayLicenseManager {
|
|
|
1155
1249
|
}>;
|
|
1156
1250
|
}
|
|
1157
1251
|
|
|
1158
|
-
export { type
|
|
1252
|
+
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=
|
|
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 t{constructor(e,r,i,n){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=r,this.workflowName=i,this.workflowDescription=n;}static create(e,r,i,n){return new t(e,r,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 r=core.normalizeToArray(e);for(let i of r){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(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(i=>!this.plugins.some(n=>n.name===i));if(r.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${r.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(r=>r.name!==e),this}updateStep(e,r){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],...r},this}addStepConditions(e,r){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,...r};return this.steps[i]={...this.steps[i],conditions:n},this}removeStep(e){return this.steps=this.steps.filter(r=>r.id!==e),this}getStep(e){return this.steps.find(r=>r.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,r){let i=new t(this.config,e||`${this.workflowId}-clone`,r||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 r=this.steps.map(i=>i.id);try{core.ensureUnique(r,"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),r=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:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):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(t,e,r,i){return L.create(t,e,r,i)}core.ril.prototype.flow=function(t,e,r){return L.create(this,t,e,r)};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 r=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)r[i/2]=Number.parseInt(e.substring(i,i+2),16);return r}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",n=0,o=e.replace(/[^A-Za-z0-9+/]/g,"");for(;n<o.length;){let s=r.indexOf(o.charAt(n++)),p=r.indexOf(o.charAt(n++)),g=r.indexOf(o.charAt(n++)),a=r.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(t,e={},r={}){return react.useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.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:t.visible?i(t.visible):true,disabled:t.disabled?i(t.disabled):false,required:t.required?i(t.required):false,readonly:t.readonly?i(t.readonly):false}},[t,e,r])}function ye(t,e={}){return react.useMemo(()=>{let r={};for(let[i,n]of Object.entries(t))if(r[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}};r[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 r},[t,e])}function be(t,e={}){return react.useMemo(()=>{let r={};for(let[i,n]of Object.entries(t)){let o=Number.parseInt(i,10);if(r[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}};r[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 r},[t,e])}var w=class extends Error{constructor(r,i,n){super(`[WorkflowPersistence] ${r} (Code: ${i})`);this.code=i;this.cause=n;this.name="WorkflowPersistenceError";}};function Y(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:r}}function he(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),isSubmitting:false,isTransitioning:false}}function Ve(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function Q(t,e){return e?`${e}:${t}`:t}function j(t,e){let r=null;return (...i)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...i);},e);}}function _e(t,e,r="persist"){let i=he(e);switch(r){case "persist":return {...i,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...i.allData,...t.allData},stepData:{...i.stepData,...t.stepData},visitedSteps:new Set([...i.visitedSteps,...t.visitedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return i}}function q({workflowId:t,workflowState:e,adapter:r,options:i={},userId:n}){let[o,s]=react.useState(false),[p,g]=react.useState(null),[a,l]=react.useState(false),f=react.useRef(r),v=react.useRef(i),y=react.useRef({hasPendingChanges:false});react.useEffect(()=>{f.current=r,v.current=i;},[r,i]);let c=Q(v.current.storageKey||t,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(t,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);}},[t,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:t,currentStep:e}=D(),r=react.useMemo(()=>e?.metadata,[e?.metadata]),i=react.useMemo(()=>a=>t.steps.find(f=>f.id===a)?.metadata,[t.steps]),n=react.useMemo(()=>a=>t.steps[a]?.metadata,[t.steps]),o=react.useMemo(()=>a=>r?a in r:false,[r]),s=react.useMemo(()=>(a,l)=>r&&a in r?r[a]:l,[r]),p=react.useMemo(()=>()=>t.steps.map((a,l)=>({id:a.id,title:a.title,index:l,metadata:a.metadata})),[t.steps]),g=react.useMemo(()=>a=>t.steps.map((l,f)=>({step:l,index:f})).filter(({step:l,index:f})=>a(l.metadata,l.id,f)).map(({step:l})=>l.id),[t.steps]);return {current:r,getByStepId:i,getByStepIndex:n,hasCurrentKey:o,getCurrentValue:s,getAllStepsMetadata:p,findStepsByMetadata:g}}function te({workflowConfig:t,workflowState:e,workflowContext:r}){let i=react.useRef(Date.now()),n=react.useRef(new Map),o=react.useRef(false),s=react.useRef(null);react.useEffect(()=>{t.analytics?.onWorkflowStart&&!o.current&&(o.current=true,t.analytics.onWorkflowStart(t.id,r));},[t.id,t.analytics,r]),react.useEffect(()=>{let a=t.steps[e.currentStepIndex];if(a&&s.current!==a.id){if(s.current&&t.analytics?.onStepComplete){let l=n.current.get(s.current);l&&t.analytics.onStepComplete(s.current,Date.now()-l,e.stepData,r);}s.current=a.id,n.current.set(a.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(a.id,Date.now(),r);}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData]);let p=react.useCallback((a,l)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(a,l,r);},[t.analytics,r]),g=react.useCallback(a=>{t.analytics?.onError&&t.analytics.onError(a,r);},[t.analytics,r]);return {analyticsStartTime:i,trackStepSkip:p,trackError:g}}function xe(t,e){return {visible:t.visible,skippable:e===true||t.required}}function re({workflowConfig:t,workflowState:e,currentStep:r}){let i=react.useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),n=react.useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),o=Z(n,i,{visible:true,disabled:false,required:false,readonly:false}),s=react.useMemo(()=>xe(o,r?.allowSkip),[o,r?.allowSkip]),p=react.useMemo(()=>{let m={};return t.steps.forEach((h,I)=>{h.conditions&&(m[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),m},[t.steps]),g=be(p,i),a=react.useMemo(()=>{let m={};return t.steps.forEach((h,I)=>{let R=g[I];R?m[I]=xe(R,h.allowSkip):m[I]={visible:true,skippable:h.allowSkip===true};}),m},[t.steps,g]),l=react.useMemo(()=>{if(!r?.formConfig?.allFields)return {};let m={};for(let h of r.formConfig.allFields)h.conditions&&(m[h.id]=h.conditions);return m},[r?.formConfig?.allFields]),f=ye(l,i),v=react.useCallback(m=>m<0||m>=t.steps.length?false:a[m]?.visible??true,[a,t.steps.length]),y=react.useCallback(m=>m<0||m>=t.steps.length?false:a[m]?.skippable??false,[a,t.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:t,workflowState:e,workflowContext:r,conditionsHelpers:i,setCurrentStep:n,setTransitioning:o,markStepVisited:s,setStepData:p,onStepChange:g}){let a=react.useRef(g);a.current=g;let l=t.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<t.steps.length){let x=t.steps[S].id,_={...e.allData[x]||{},[u]:b};p(_,x);}},setNextStepFields:u=>{let b=e.currentStepIndex+1;if(b<t.steps.length){let S=t.steps[b].id,C={...e.allData[S]||{},...u};p(C,S);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,p]),v=react.useCallback(async u=>{if(u<0||u>=t.steps.length||!i.isStepVisible(u))return false;o(true);try{return a.current&&a.current(e.currentStepIndex,u,r),n(u),s(u,t.steps[u].id),!0}catch(b){return console.error("Step transition failed:",b),t.analytics?.onError&&t.analytics.onError(b,r),false}finally{o(false);}},[t.steps,t.analytics,i,e.currentStepIndex,r,o,n,s]),y=react.useCallback(u=>{for(let b=u+1;b<t.steps.length;b++)if(i.isStepVisible(b))return b;return null},[t.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,r);}catch(b){return console.error("onAfterValidation failed:",b),t.analytics?.onError&&t.analytics.onError(b,r),false}let u=y(e.currentStepIndex);return u===null?false:v(u)},[l,f,e.stepData,r,t.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:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(l.id,"user_skip",r),d()),[l,i,e.currentStepIndex,t.analytics,r,d]),m=react.useCallback(u=>u<0||u>=t.steps.length?false:i.isStepVisible(u),[t.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(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.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 {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function ne({defaultValues:t={},persistence:e}){let r={currentStepIndex:0,allData:t,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,n]=react.useReducer(qe,r),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:t,workflowState:e,workflowContext:r,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),t.analytics?.onWorkflowComplete){let a=Date.now()-o.current;t.analytics.onWorkflowComplete(t.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),t.analytics?.onError&&t.analytics.onError(a,r),a}finally{i(false);}},[e.allData,t.analytics,t.id,r,o,i]),g=react.useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:p,isSubmitting:e.isSubmitting,canSubmit:g()}}var De=react.createContext(null);function ae({children:t,workflowConfig:e,defaultValues:r={},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:r,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:t},s.isInitializing.toString())})}function D(){let t=react.useContext(De);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function Qe({children:t,workflowConfig:e,...r}){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,{...r,workflowConfig:o,children:t}),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:t}){let{currentStep:e}=D();if(!e||t&&e.id!==t)return null;let{formConfig:r,renderer:i}=e;return r?i?i(e):jsxRuntime.jsx(forms.FormBody,{}):null}function ot({className:t,isSubmitting:e,...r}){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:t,currentStep:s,stepData:g.values||{},allData:i.allData,context:i};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:y,...r})}function pt({className:t,isSubmitting:e,...r}){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:t,currentStep:p,stepData:g.values||{},allData:i.allData,context:i};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:y,...r})}function ft({className:t,isSubmitting:e,...r}){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:t,currentStep:i,stepData:a.values||{},allData:p.allData,context:p};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:c,...r})}function yt({onStepClick:t,className:e,...r}){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&&(t?t(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,...r})}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,r){if(this._isAvailable)try{let i=this.getStorageKey(e),n={data:{...r,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:{...r,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 r=this.getStorageKey(e),i=localStorage.getItem(r);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(r){throw r instanceof Error?new w(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new w("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new w(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new w("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),i=localStorage.getItem(r);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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let r of e)localStorage.removeItem(r);}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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);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 r of e)localStorage.removeItem(r);}};
|
|
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{
|
|
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 t{constructor(e,r,i,n){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=r,this.workflowName=i,this.workflowDescription=n;}static create(e,r,i,n){return new t(e,r,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 r=normalizeToArray(e);for(let i of r){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(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(i=>!this.plugins.some(n=>n.name===i));if(r.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${r.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(r=>r.name!==e),this}updateStep(e,r){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],...r},this}addStepConditions(e,r){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,...r};return this.steps[i]={...this.steps[i],conditions:n},this}removeStep(e){return this.steps=this.steps.filter(r=>r.id!==e),this}getStep(e){return this.steps.find(r=>r.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this.idGenerator.reset(),this}clone(e,r){let i=new t(this.config,e||`${this.workflowId}-clone`,r||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 r=this.steps.map(i=>i.id);try{ensureUnique(r,"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),r=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:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):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(t,e,r,i){return L.create(t,e,r,i)}ril.prototype.flow=function(t,e,r){return L.create(this,t,e,r)};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 r=new Uint8Array(e.length/2);for(let i=0;i<e.length;i+=2)r[i/2]=Number.parseInt(e.substring(i,i+2),16);return r}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i="",n=0,o=e.replace(/[^A-Za-z0-9+/]/g,"");for(;n<o.length;){let s=r.indexOf(o.charAt(n++)),p=r.indexOf(o.charAt(n++)),g=r.indexOf(o.charAt(n++)),a=r.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(t,e={},r={}){return useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.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:t.visible?i(t.visible):true,disabled:t.disabled?i(t.disabled):false,required:t.required?i(t.required):false,readonly:t.readonly?i(t.readonly):false}},[t,e,r])}function ye(t,e={}){return useMemo(()=>{let r={};for(let[i,n]of Object.entries(t))if(r[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}};r[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 r},[t,e])}function be(t,e={}){return useMemo(()=>{let r={};for(let[i,n]of Object.entries(t)){let o=Number.parseInt(i,10);if(r[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}};r[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 r},[t,e])}var w=class extends Error{constructor(r,i,n){super(`[WorkflowPersistence] ${r} (Code: ${i})`);this.code=i;this.cause=n;this.name="WorkflowPersistenceError";}};function Y(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),lastSaved:Date.now(),metadata:r}}function he(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),isSubmitting:false,isTransitioning:false}}function Ve(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function Q(t,e){return e?`${e}:${t}`:t}function j(t,e){let r=null;return (...i)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...i);},e);}}function _e(t,e,r="persist"){let i=he(e);switch(r){case "persist":return {...i,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...i.visitedSteps])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...i.allData,...t.allData},stepData:{...i.stepData,...t.stepData},visitedSteps:new Set([...i.visitedSteps,...t.visitedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return i}}function q({workflowId:t,workflowState:e,adapter:r,options:i={},userId:n}){let[o,s]=useState(false),[p,g]=useState(null),[a,l]=useState(false),f=useRef(r),v=useRef(i),y=useRef({hasPendingChanges:false});useEffect(()=>{f.current=r,v.current=i;},[r,i]);let c=Q(v.current.storageKey||t,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(t,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);}},[t,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:t,currentStep:e}=D(),r=useMemo(()=>e?.metadata,[e?.metadata]),i=useMemo(()=>a=>t.steps.find(f=>f.id===a)?.metadata,[t.steps]),n=useMemo(()=>a=>t.steps[a]?.metadata,[t.steps]),o=useMemo(()=>a=>r?a in r:false,[r]),s=useMemo(()=>(a,l)=>r&&a in r?r[a]:l,[r]),p=useMemo(()=>()=>t.steps.map((a,l)=>({id:a.id,title:a.title,index:l,metadata:a.metadata})),[t.steps]),g=useMemo(()=>a=>t.steps.map((l,f)=>({step:l,index:f})).filter(({step:l,index:f})=>a(l.metadata,l.id,f)).map(({step:l})=>l.id),[t.steps]);return {current:r,getByStepId:i,getByStepIndex:n,hasCurrentKey:o,getCurrentValue:s,getAllStepsMetadata:p,findStepsByMetadata:g}}function te({workflowConfig:t,workflowState:e,workflowContext:r}){let i=useRef(Date.now()),n=useRef(new Map),o=useRef(false),s=useRef(null);useEffect(()=>{t.analytics?.onWorkflowStart&&!o.current&&(o.current=true,t.analytics.onWorkflowStart(t.id,r));},[t.id,t.analytics,r]),useEffect(()=>{let a=t.steps[e.currentStepIndex];if(a&&s.current!==a.id){if(s.current&&t.analytics?.onStepComplete){let l=n.current.get(s.current);l&&t.analytics.onStepComplete(s.current,Date.now()-l,e.stepData,r);}s.current=a.id,n.current.set(a.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(a.id,Date.now(),r);}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData]);let p=useCallback((a,l)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(a,l,r);},[t.analytics,r]),g=useCallback(a=>{t.analytics?.onError&&t.analytics.onError(a,r);},[t.analytics,r]);return {analyticsStartTime:i,trackStepSkip:p,trackError:g}}function xe(t,e){return {visible:t.visible,skippable:e===true||t.required}}function re({workflowConfig:t,workflowState:e,currentStep:r}){let i=useMemo(()=>({...e.allData,...e.stepData}),[e.allData,e.stepData]),n=useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),o=Z(n,i,{visible:true,disabled:false,required:false,readonly:false}),s=useMemo(()=>xe(o,r?.allowSkip),[o,r?.allowSkip]),p=useMemo(()=>{let m={};return t.steps.forEach((h,I)=>{h.conditions&&(m[I]={visible:h.conditions.visible,required:h.conditions.skippable});}),m},[t.steps]),g=be(p,i),a=useMemo(()=>{let m={};return t.steps.forEach((h,I)=>{let R=g[I];R?m[I]=xe(R,h.allowSkip):m[I]={visible:true,skippable:h.allowSkip===true};}),m},[t.steps,g]),l=useMemo(()=>{if(!r?.formConfig?.allFields)return {};let m={};for(let h of r.formConfig.allFields)h.conditions&&(m[h.id]=h.conditions);return m},[r?.formConfig?.allFields]),f=ye(l,i),v=useCallback(m=>m<0||m>=t.steps.length?false:a[m]?.visible??true,[a,t.steps.length]),y=useCallback(m=>m<0||m>=t.steps.length?false:a[m]?.skippable??false,[a,t.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:t,workflowState:e,workflowContext:r,conditionsHelpers:i,setCurrentStep:n,setTransitioning:o,markStepVisited:s,setStepData:p,onStepChange:g}){let a=useRef(g);a.current=g;let l=t.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<t.steps.length){let x=t.steps[S].id,_={...e.allData[x]||{},[u]:b};p(_,x);}},setNextStepFields:u=>{let b=e.currentStepIndex+1;if(b<t.steps.length){let S=t.steps[b].id,C={...e.allData[S]||{},...u};p(C,S);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,p]),v=useCallback(async u=>{if(u<0||u>=t.steps.length||!i.isStepVisible(u))return false;o(true);try{return a.current&&a.current(e.currentStepIndex,u,r),n(u),s(u,t.steps[u].id),!0}catch(b){return console.error("Step transition failed:",b),t.analytics?.onError&&t.analytics.onError(b,r),false}finally{o(false);}},[t.steps,t.analytics,i,e.currentStepIndex,r,o,n,s]),y=useCallback(u=>{for(let b=u+1;b<t.steps.length;b++)if(i.isStepVisible(b))return b;return null},[t.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,r);}catch(b){return console.error("onAfterValidation failed:",b),t.analytics?.onError&&t.analytics.onError(b,r),false}let u=y(e.currentStepIndex);return u===null?false:v(u)},[l,f,e.stepData,r,t.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:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(l.id,"user_skip",r),d()),[l,i,e.currentStepIndex,t.analytics,r,d]),m=useCallback(u=>u<0||u>=t.steps.length?false:i.isStepVisible(u),[t.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(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.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 {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function ne({defaultValues:t={},persistence:e}){let r={currentStepIndex:0,allData:t,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:true},[i,n]=useReducer(qe,r),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:t,workflowState:e,workflowContext:r,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),t.analytics?.onWorkflowComplete){let a=Date.now()-o.current;t.analytics.onWorkflowComplete(t.id,a,e.allData);}}catch(a){throw console.error("Workflow submission failed:",a),t.analytics?.onError&&t.analytics.onError(a,r),a}finally{i(false);}},[e.allData,t.analytics,t.id,r,o,i]),g=useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:p,isSubmitting:e.isSubmitting,canSubmit:g()}}var De=createContext(null);function ae({children:t,workflowConfig:e,defaultValues:r={},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:r,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:t},s.isInitializing.toString())})}function D(){let t=useContext(De);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function Qe({children:t,workflowConfig:e,...r}){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,{...r,workflowConfig:o,children:t}),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:t}){let{currentStep:e}=D();if(!e||t&&e.id!==t)return null;let{formConfig:r,renderer:i}=e;return r?i?i(e):jsx(FormBody,{}):null}function ot({className:t,isSubmitting:e,...r}){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:t,currentStep:s,stepData:g.values||{},allData:i.allData,context:i};return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:o.renderConfig?.nextButtonRenderer,props:y,...r})}function pt({className:t,isSubmitting:e,...r}){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:t,currentStep:p,stepData:g.values||{},allData:i.allData,context:i};return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:s.renderConfig?.previousButtonRenderer,props:y,...r})}function ft({className:t,isSubmitting:e,...r}){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:t,currentStep:i,stepData:a.values||{},allData:p.allData,context:p};return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:s.renderConfig?.skipButtonRenderer,props:c,...r})}function yt({onStepClick:t,className:e,...r}){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&&(t?t(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,...r})}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,r){if(this._isAvailable)try{let i=this.getStorageKey(e),n={data:{...r,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:{...r,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 r=this.getStorageKey(e),i=localStorage.getItem(r);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(r){throw r instanceof Error?new w(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new w("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new w(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new w("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),i=localStorage.getItem(r);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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);i?.startsWith(this.keyPrefix)&&e.push(i);}for(let r of e)localStorage.removeItem(r);}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 r=0;r<localStorage.length;r++){let i=localStorage.key(r);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 r of e)localStorage.removeItem(r);}};
|
|
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": "
|
|
3
|
+
"version": "8.0.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": "
|
|
30
|
-
"@rilaykit/forms": "
|
|
29
|
+
"@rilaykit/core": "8.0.0",
|
|
30
|
+
"@rilaykit/forms": "8.0.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=18.0.0",
|