@rilaykit/workflow 4.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +44 -101
- package/dist/index.d.ts +44 -101
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { ril, FormConfiguration,
|
|
1
|
+
import { ril, FormConfiguration, CustomStepRenderer, StepDataHelper, WorkflowContext, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
|
|
2
2
|
export * from '@rilaykit/core';
|
|
3
|
-
export { createZodValidator, ril } from '@rilaykit/core';
|
|
4
3
|
import { form } from '@rilaykit/forms';
|
|
5
4
|
export { form } from '@rilaykit/forms';
|
|
6
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
|
-
import
|
|
8
|
-
import react__default from 'react';
|
|
6
|
+
import React from 'react';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Enhanced step configuration interface for better type safety and simplicity
|
|
@@ -47,26 +45,41 @@ interface StepDefinition {
|
|
|
47
45
|
* @default true
|
|
48
46
|
*/
|
|
49
47
|
requiredToComplete?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Lifecycle hooks for step events
|
|
52
|
-
* Allows custom logic at different points in the step lifecycle
|
|
53
|
-
*/
|
|
54
|
-
hooks?: StepLifecycleHooks;
|
|
55
|
-
/**
|
|
56
|
-
* Permission configuration for step access control
|
|
57
|
-
* Defines who can view, edit, or complete this step
|
|
58
|
-
*/
|
|
59
|
-
permissions?: StepPermissions;
|
|
60
48
|
/**
|
|
61
49
|
* Custom renderer for the step
|
|
62
50
|
* Allows complete customization of step presentation
|
|
63
51
|
*/
|
|
64
52
|
renderer?: CustomStepRenderer;
|
|
65
53
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
54
|
+
* Callback function that executes after successful validation and before moving to next step
|
|
55
|
+
* Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
|
|
56
|
+
*
|
|
57
|
+
* @param stepData - The validated data from the current step
|
|
58
|
+
* @param helper - Helper object with methods to modify workflow data cleanly
|
|
59
|
+
* @param context - Full workflow context for reference
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* onAfterValidation: async (stepData, helper, context) => {
|
|
64
|
+
* // API call based on current step data
|
|
65
|
+
* const companyInfo = await fetchCompanyBySiren(stepData.siren);
|
|
66
|
+
*
|
|
67
|
+
* // Pre-fill next step with clean helper methods
|
|
68
|
+
* helper.setNextStepFields({
|
|
69
|
+
* companyName: companyInfo.name,
|
|
70
|
+
* address: companyInfo.address,
|
|
71
|
+
* industry: companyInfo.sector
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* // Or set data for a specific step
|
|
75
|
+
* helper.setStepFields('company-details', {
|
|
76
|
+
* legalForm: companyInfo.legalForm,
|
|
77
|
+
* foundedYear: companyInfo.creation_date
|
|
78
|
+
* });
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
68
81
|
*/
|
|
69
|
-
|
|
82
|
+
onAfterValidation?: (stepData: Record<string, any>, helper: StepDataHelper, context: WorkflowContext) => void | Promise<void>;
|
|
70
83
|
}
|
|
71
84
|
/**
|
|
72
85
|
* Configuration options for workflow behavior and features
|
|
@@ -77,12 +90,6 @@ interface StepDefinition {
|
|
|
77
90
|
* @interface WorkflowOptions
|
|
78
91
|
*/
|
|
79
92
|
interface WorkflowOptions {
|
|
80
|
-
/** Navigation behavior configuration */
|
|
81
|
-
navigation?: NavigationConfig;
|
|
82
|
-
/** Data persistence settings */
|
|
83
|
-
persistence?: PersistenceConfig;
|
|
84
|
-
/** Workflow completion handling */
|
|
85
|
-
completion?: CompletionConfig;
|
|
86
93
|
/** Analytics and tracking configuration */
|
|
87
94
|
analytics?: WorkflowAnalytics;
|
|
88
95
|
}
|
|
@@ -128,9 +135,6 @@ declare class flow {
|
|
|
128
135
|
private workflowName;
|
|
129
136
|
private workflowDescription?;
|
|
130
137
|
private steps;
|
|
131
|
-
private navigation;
|
|
132
|
-
private persistence?;
|
|
133
|
-
private completion?;
|
|
134
138
|
private analytics?;
|
|
135
139
|
private plugins;
|
|
136
140
|
private idGenerator;
|
|
@@ -166,7 +170,7 @@ declare class flow {
|
|
|
166
170
|
*
|
|
167
171
|
* This internal method handles the conversion from the user-friendly
|
|
168
172
|
* StepDefinition interface to the internal StepConfig structure,
|
|
169
|
-
* including ID generation
|
|
173
|
+
* including ID generation, form configuration processing, and validation setup.
|
|
170
174
|
*
|
|
171
175
|
* @private
|
|
172
176
|
* @param stepDef - The step definition to convert
|
|
@@ -209,31 +213,6 @@ declare class flow {
|
|
|
209
213
|
* ```
|
|
210
214
|
*/
|
|
211
215
|
addStep(stepDefinitions: StepDefinition[]): this;
|
|
212
|
-
/**
|
|
213
|
-
* Add a dynamic step using StepDefinition with dynamicConfig
|
|
214
|
-
*
|
|
215
|
-
* Dynamic steps can change their behavior, visibility, or configuration
|
|
216
|
-
* based on data from previous steps. This method is a convenience wrapper
|
|
217
|
-
* around addStep() with enhanced type safety for dynamic configurations.
|
|
218
|
-
*
|
|
219
|
-
* @param stepDefinition - Step definition with required dynamicConfig
|
|
220
|
-
* @returns The flow instance for method chaining
|
|
221
|
-
*
|
|
222
|
-
* @example
|
|
223
|
-
* ```typescript
|
|
224
|
-
* workflow.addDynamicStep({
|
|
225
|
-
* title: 'Conditional Step',
|
|
226
|
-
* formConfig: conditionalForm,
|
|
227
|
-
* dynamicConfig: {
|
|
228
|
-
* condition: (data) => data.userType === 'premium',
|
|
229
|
-
* generator: (data) => generatePremiumForm(data)
|
|
230
|
-
* }
|
|
231
|
-
* });
|
|
232
|
-
* ```
|
|
233
|
-
*/
|
|
234
|
-
addDynamicStep(stepDefinition: StepDefinition & {
|
|
235
|
-
dynamicConfig: DynamicStepConfig;
|
|
236
|
-
}): this;
|
|
237
216
|
/**
|
|
238
217
|
* Universal configuration method for all workflow options
|
|
239
218
|
*
|
|
@@ -429,20 +408,12 @@ declare class flow {
|
|
|
429
408
|
* ```
|
|
430
409
|
*/
|
|
431
410
|
getStats(): {
|
|
432
|
-
/** Total number of steps in the workflow */
|
|
433
411
|
totalSteps: number;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
/** Estimated total number of form fields across all steps */
|
|
439
|
-
estimatedFields: number;
|
|
440
|
-
/** Whether persistence is configured */
|
|
441
|
-
hasPersistence: boolean;
|
|
442
|
-
/** Whether analytics is configured */
|
|
412
|
+
totalFields: number;
|
|
413
|
+
averageFieldsPerStep: number;
|
|
414
|
+
maxFieldsInStep: number;
|
|
415
|
+
minFieldsInStep: number;
|
|
443
416
|
hasAnalytics: boolean;
|
|
444
|
-
/** Whether back navigation is allowed */
|
|
445
|
-
allowBackNavigation: boolean;
|
|
446
417
|
};
|
|
447
418
|
/**
|
|
448
419
|
* Build the final workflow configuration
|
|
@@ -549,14 +520,9 @@ interface WorkflowState {
|
|
|
549
520
|
currentStepIndex: number;
|
|
550
521
|
allData: Record<string, any>;
|
|
551
522
|
stepData: Record<string, any>;
|
|
552
|
-
errors: Record<string, ValidationError[]>;
|
|
553
|
-
touched: Set<string>;
|
|
554
|
-
isValidating: Set<string>;
|
|
555
523
|
visitedSteps: Set<string>;
|
|
556
524
|
isSubmitting: boolean;
|
|
557
525
|
isTransitioning: boolean;
|
|
558
|
-
persistedData?: any;
|
|
559
|
-
resolvedSteps: StepConfig[];
|
|
560
526
|
}
|
|
561
527
|
interface WorkflowContextValue {
|
|
562
528
|
workflowState: WorkflowState;
|
|
@@ -570,27 +536,22 @@ interface WorkflowContextValue {
|
|
|
570
536
|
skipStep: () => Promise<boolean>;
|
|
571
537
|
setValue: (fieldId: string, value: any) => void;
|
|
572
538
|
setStepData: (data: Record<string, any>) => void;
|
|
573
|
-
validateCurrentStep: () => Promise<ValidationResult>;
|
|
574
539
|
submitWorkflow: () => Promise<void>;
|
|
575
540
|
resetWorkflow: () => void;
|
|
576
|
-
saveDraft: () => Promise<void>;
|
|
577
|
-
loadDraft: () => Promise<void>;
|
|
578
|
-
clearDraft: () => Promise<void>;
|
|
579
541
|
}
|
|
580
542
|
interface WorkflowProviderProps {
|
|
581
|
-
children:
|
|
543
|
+
children: React.ReactNode;
|
|
582
544
|
workflowConfig: WorkflowConfig;
|
|
583
545
|
defaultValues?: Record<string, any>;
|
|
584
546
|
onStepChange?: (fromStep: number, toStep: number, context: WorkflowContext) => void;
|
|
585
547
|
onWorkflowComplete?: (data: Record<string, any>) => void | Promise<void>;
|
|
586
548
|
className?: string;
|
|
587
|
-
user?: any;
|
|
588
549
|
}
|
|
589
|
-
declare function WorkflowProvider({ children, workflowConfig, defaultValues, onStepChange, onWorkflowComplete, className,
|
|
550
|
+
declare function WorkflowProvider({ children, workflowConfig, defaultValues, onStepChange, onWorkflowComplete, className, }: WorkflowProviderProps): react_jsx_runtime.JSX.Element;
|
|
590
551
|
declare function useWorkflowContext(): WorkflowContextValue;
|
|
591
552
|
|
|
592
553
|
type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'> & {
|
|
593
|
-
children:
|
|
554
|
+
children: React.ReactNode;
|
|
594
555
|
workflowConfig: WorkflowConfig | flow;
|
|
595
556
|
};
|
|
596
557
|
/**
|
|
@@ -607,34 +568,16 @@ declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps)
|
|
|
607
568
|
*/
|
|
608
569
|
declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
|
|
609
570
|
|
|
610
|
-
|
|
611
|
-
className?: string;
|
|
612
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowNextButtonRendererProps>;
|
|
613
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
614
|
-
}
|
|
615
|
-
declare function WorkflowNextButton({ className, children, renderAs }: WorkflowNextButtonProps): react.ReactNode;
|
|
571
|
+
declare function WorkflowNextButton({ className, ...props }: ComponentRendererBaseProps<WorkflowNextButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
616
572
|
|
|
617
|
-
|
|
618
|
-
className?: string;
|
|
619
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowPreviousButtonRendererProps>;
|
|
620
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
621
|
-
}
|
|
622
|
-
declare function WorkflowPreviousButton({ className, children, renderAs, }: WorkflowPreviousButtonProps): react.ReactNode;
|
|
573
|
+
declare function WorkflowPreviousButton({ className, ...props }: ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
623
574
|
|
|
624
|
-
|
|
625
|
-
className?: string;
|
|
626
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowSkipButtonRendererProps>;
|
|
627
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
628
|
-
}
|
|
629
|
-
declare function WorkflowSkipButton({ className, children, renderAs }: WorkflowSkipButtonProps): react.ReactNode;
|
|
575
|
+
declare function WorkflowSkipButton({ className, ...props }: ComponentRendererBaseProps<WorkflowSkipButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
630
576
|
|
|
631
|
-
interface WorkflowStepperProps {
|
|
577
|
+
interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
|
|
632
578
|
onStepClick?: (stepIndex: number) => void;
|
|
633
|
-
className?: string;
|
|
634
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowStepperRendererProps>;
|
|
635
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
636
579
|
}
|
|
637
|
-
declare function WorkflowStepper({ onStepClick, className,
|
|
580
|
+
declare function WorkflowStepper({ onStepClick, className, ...props }: WorkflowStepperProps): react_jsx_runtime.JSX.Element;
|
|
638
581
|
|
|
639
582
|
interface LicensePayload {
|
|
640
583
|
plan: 'ARCHITECT' | 'FOUNDRY';
|
|
@@ -704,4 +647,4 @@ declare class RilayLicenseManager {
|
|
|
704
647
|
}>;
|
|
705
648
|
}
|
|
706
649
|
|
|
707
|
-
export { type LicensePayload, type LicensePlan, type LicenseResult, RilayLicenseManager, type StepDefinition, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton,
|
|
650
|
+
export { type LicensePayload, type LicensePlan, type LicenseResult, RilayLicenseManager, type StepDefinition, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, createFlow, flow, useWorkflowContext };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { ril, FormConfiguration,
|
|
1
|
+
import { ril, FormConfiguration, CustomStepRenderer, StepDataHelper, WorkflowContext, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
|
|
2
2
|
export * from '@rilaykit/core';
|
|
3
|
-
export { createZodValidator, ril } from '@rilaykit/core';
|
|
4
3
|
import { form } from '@rilaykit/forms';
|
|
5
4
|
export { form } from '@rilaykit/forms';
|
|
6
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
|
-
import
|
|
8
|
-
import react__default from 'react';
|
|
6
|
+
import React from 'react';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Enhanced step configuration interface for better type safety and simplicity
|
|
@@ -47,26 +45,41 @@ interface StepDefinition {
|
|
|
47
45
|
* @default true
|
|
48
46
|
*/
|
|
49
47
|
requiredToComplete?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Lifecycle hooks for step events
|
|
52
|
-
* Allows custom logic at different points in the step lifecycle
|
|
53
|
-
*/
|
|
54
|
-
hooks?: StepLifecycleHooks;
|
|
55
|
-
/**
|
|
56
|
-
* Permission configuration for step access control
|
|
57
|
-
* Defines who can view, edit, or complete this step
|
|
58
|
-
*/
|
|
59
|
-
permissions?: StepPermissions;
|
|
60
48
|
/**
|
|
61
49
|
* Custom renderer for the step
|
|
62
50
|
* Allows complete customization of step presentation
|
|
63
51
|
*/
|
|
64
52
|
renderer?: CustomStepRenderer;
|
|
65
53
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
54
|
+
* Callback function that executes after successful validation and before moving to next step
|
|
55
|
+
* Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
|
|
56
|
+
*
|
|
57
|
+
* @param stepData - The validated data from the current step
|
|
58
|
+
* @param helper - Helper object with methods to modify workflow data cleanly
|
|
59
|
+
* @param context - Full workflow context for reference
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* onAfterValidation: async (stepData, helper, context) => {
|
|
64
|
+
* // API call based on current step data
|
|
65
|
+
* const companyInfo = await fetchCompanyBySiren(stepData.siren);
|
|
66
|
+
*
|
|
67
|
+
* // Pre-fill next step with clean helper methods
|
|
68
|
+
* helper.setNextStepFields({
|
|
69
|
+
* companyName: companyInfo.name,
|
|
70
|
+
* address: companyInfo.address,
|
|
71
|
+
* industry: companyInfo.sector
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* // Or set data for a specific step
|
|
75
|
+
* helper.setStepFields('company-details', {
|
|
76
|
+
* legalForm: companyInfo.legalForm,
|
|
77
|
+
* foundedYear: companyInfo.creation_date
|
|
78
|
+
* });
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
68
81
|
*/
|
|
69
|
-
|
|
82
|
+
onAfterValidation?: (stepData: Record<string, any>, helper: StepDataHelper, context: WorkflowContext) => void | Promise<void>;
|
|
70
83
|
}
|
|
71
84
|
/**
|
|
72
85
|
* Configuration options for workflow behavior and features
|
|
@@ -77,12 +90,6 @@ interface StepDefinition {
|
|
|
77
90
|
* @interface WorkflowOptions
|
|
78
91
|
*/
|
|
79
92
|
interface WorkflowOptions {
|
|
80
|
-
/** Navigation behavior configuration */
|
|
81
|
-
navigation?: NavigationConfig;
|
|
82
|
-
/** Data persistence settings */
|
|
83
|
-
persistence?: PersistenceConfig;
|
|
84
|
-
/** Workflow completion handling */
|
|
85
|
-
completion?: CompletionConfig;
|
|
86
93
|
/** Analytics and tracking configuration */
|
|
87
94
|
analytics?: WorkflowAnalytics;
|
|
88
95
|
}
|
|
@@ -128,9 +135,6 @@ declare class flow {
|
|
|
128
135
|
private workflowName;
|
|
129
136
|
private workflowDescription?;
|
|
130
137
|
private steps;
|
|
131
|
-
private navigation;
|
|
132
|
-
private persistence?;
|
|
133
|
-
private completion?;
|
|
134
138
|
private analytics?;
|
|
135
139
|
private plugins;
|
|
136
140
|
private idGenerator;
|
|
@@ -166,7 +170,7 @@ declare class flow {
|
|
|
166
170
|
*
|
|
167
171
|
* This internal method handles the conversion from the user-friendly
|
|
168
172
|
* StepDefinition interface to the internal StepConfig structure,
|
|
169
|
-
* including ID generation
|
|
173
|
+
* including ID generation, form configuration processing, and validation setup.
|
|
170
174
|
*
|
|
171
175
|
* @private
|
|
172
176
|
* @param stepDef - The step definition to convert
|
|
@@ -209,31 +213,6 @@ declare class flow {
|
|
|
209
213
|
* ```
|
|
210
214
|
*/
|
|
211
215
|
addStep(stepDefinitions: StepDefinition[]): this;
|
|
212
|
-
/**
|
|
213
|
-
* Add a dynamic step using StepDefinition with dynamicConfig
|
|
214
|
-
*
|
|
215
|
-
* Dynamic steps can change their behavior, visibility, or configuration
|
|
216
|
-
* based on data from previous steps. This method is a convenience wrapper
|
|
217
|
-
* around addStep() with enhanced type safety for dynamic configurations.
|
|
218
|
-
*
|
|
219
|
-
* @param stepDefinition - Step definition with required dynamicConfig
|
|
220
|
-
* @returns The flow instance for method chaining
|
|
221
|
-
*
|
|
222
|
-
* @example
|
|
223
|
-
* ```typescript
|
|
224
|
-
* workflow.addDynamicStep({
|
|
225
|
-
* title: 'Conditional Step',
|
|
226
|
-
* formConfig: conditionalForm,
|
|
227
|
-
* dynamicConfig: {
|
|
228
|
-
* condition: (data) => data.userType === 'premium',
|
|
229
|
-
* generator: (data) => generatePremiumForm(data)
|
|
230
|
-
* }
|
|
231
|
-
* });
|
|
232
|
-
* ```
|
|
233
|
-
*/
|
|
234
|
-
addDynamicStep(stepDefinition: StepDefinition & {
|
|
235
|
-
dynamicConfig: DynamicStepConfig;
|
|
236
|
-
}): this;
|
|
237
216
|
/**
|
|
238
217
|
* Universal configuration method for all workflow options
|
|
239
218
|
*
|
|
@@ -429,20 +408,12 @@ declare class flow {
|
|
|
429
408
|
* ```
|
|
430
409
|
*/
|
|
431
410
|
getStats(): {
|
|
432
|
-
/** Total number of steps in the workflow */
|
|
433
411
|
totalSteps: number;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
/** Estimated total number of form fields across all steps */
|
|
439
|
-
estimatedFields: number;
|
|
440
|
-
/** Whether persistence is configured */
|
|
441
|
-
hasPersistence: boolean;
|
|
442
|
-
/** Whether analytics is configured */
|
|
412
|
+
totalFields: number;
|
|
413
|
+
averageFieldsPerStep: number;
|
|
414
|
+
maxFieldsInStep: number;
|
|
415
|
+
minFieldsInStep: number;
|
|
443
416
|
hasAnalytics: boolean;
|
|
444
|
-
/** Whether back navigation is allowed */
|
|
445
|
-
allowBackNavigation: boolean;
|
|
446
417
|
};
|
|
447
418
|
/**
|
|
448
419
|
* Build the final workflow configuration
|
|
@@ -549,14 +520,9 @@ interface WorkflowState {
|
|
|
549
520
|
currentStepIndex: number;
|
|
550
521
|
allData: Record<string, any>;
|
|
551
522
|
stepData: Record<string, any>;
|
|
552
|
-
errors: Record<string, ValidationError[]>;
|
|
553
|
-
touched: Set<string>;
|
|
554
|
-
isValidating: Set<string>;
|
|
555
523
|
visitedSteps: Set<string>;
|
|
556
524
|
isSubmitting: boolean;
|
|
557
525
|
isTransitioning: boolean;
|
|
558
|
-
persistedData?: any;
|
|
559
|
-
resolvedSteps: StepConfig[];
|
|
560
526
|
}
|
|
561
527
|
interface WorkflowContextValue {
|
|
562
528
|
workflowState: WorkflowState;
|
|
@@ -570,27 +536,22 @@ interface WorkflowContextValue {
|
|
|
570
536
|
skipStep: () => Promise<boolean>;
|
|
571
537
|
setValue: (fieldId: string, value: any) => void;
|
|
572
538
|
setStepData: (data: Record<string, any>) => void;
|
|
573
|
-
validateCurrentStep: () => Promise<ValidationResult>;
|
|
574
539
|
submitWorkflow: () => Promise<void>;
|
|
575
540
|
resetWorkflow: () => void;
|
|
576
|
-
saveDraft: () => Promise<void>;
|
|
577
|
-
loadDraft: () => Promise<void>;
|
|
578
|
-
clearDraft: () => Promise<void>;
|
|
579
541
|
}
|
|
580
542
|
interface WorkflowProviderProps {
|
|
581
|
-
children:
|
|
543
|
+
children: React.ReactNode;
|
|
582
544
|
workflowConfig: WorkflowConfig;
|
|
583
545
|
defaultValues?: Record<string, any>;
|
|
584
546
|
onStepChange?: (fromStep: number, toStep: number, context: WorkflowContext) => void;
|
|
585
547
|
onWorkflowComplete?: (data: Record<string, any>) => void | Promise<void>;
|
|
586
548
|
className?: string;
|
|
587
|
-
user?: any;
|
|
588
549
|
}
|
|
589
|
-
declare function WorkflowProvider({ children, workflowConfig, defaultValues, onStepChange, onWorkflowComplete, className,
|
|
550
|
+
declare function WorkflowProvider({ children, workflowConfig, defaultValues, onStepChange, onWorkflowComplete, className, }: WorkflowProviderProps): react_jsx_runtime.JSX.Element;
|
|
590
551
|
declare function useWorkflowContext(): WorkflowContextValue;
|
|
591
552
|
|
|
592
553
|
type WorkflowProps = Omit<WorkflowProviderProps, 'children' | 'workflowConfig'> & {
|
|
593
|
-
children:
|
|
554
|
+
children: React.ReactNode;
|
|
594
555
|
workflowConfig: WorkflowConfig | flow;
|
|
595
556
|
};
|
|
596
557
|
/**
|
|
@@ -607,34 +568,16 @@ declare function Workflow({ children, workflowConfig, ...props }: WorkflowProps)
|
|
|
607
568
|
*/
|
|
608
569
|
declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
|
|
609
570
|
|
|
610
|
-
|
|
611
|
-
className?: string;
|
|
612
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowNextButtonRendererProps>;
|
|
613
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
614
|
-
}
|
|
615
|
-
declare function WorkflowNextButton({ className, children, renderAs }: WorkflowNextButtonProps): react.ReactNode;
|
|
571
|
+
declare function WorkflowNextButton({ className, ...props }: ComponentRendererBaseProps<WorkflowNextButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
616
572
|
|
|
617
|
-
|
|
618
|
-
className?: string;
|
|
619
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowPreviousButtonRendererProps>;
|
|
620
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
621
|
-
}
|
|
622
|
-
declare function WorkflowPreviousButton({ className, children, renderAs, }: WorkflowPreviousButtonProps): react.ReactNode;
|
|
573
|
+
declare function WorkflowPreviousButton({ className, ...props }: ComponentRendererBaseProps<WorkflowPreviousButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
623
574
|
|
|
624
|
-
|
|
625
|
-
className?: string;
|
|
626
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowSkipButtonRendererProps>;
|
|
627
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
628
|
-
}
|
|
629
|
-
declare function WorkflowSkipButton({ className, children, renderAs }: WorkflowSkipButtonProps): react.ReactNode;
|
|
575
|
+
declare function WorkflowSkipButton({ className, ...props }: ComponentRendererBaseProps<WorkflowSkipButtonRendererProps>): react_jsx_runtime.JSX.Element;
|
|
630
576
|
|
|
631
|
-
interface WorkflowStepperProps {
|
|
577
|
+
interface WorkflowStepperProps extends ComponentRendererBaseProps<WorkflowStepperRendererProps> {
|
|
632
578
|
onStepClick?: (stepIndex: number) => void;
|
|
633
|
-
className?: string;
|
|
634
|
-
children?: React.ReactNode | RendererChildrenFunction<WorkflowStepperRendererProps>;
|
|
635
|
-
renderAs?: 'default' | 'children' | boolean;
|
|
636
579
|
}
|
|
637
|
-
declare function WorkflowStepper({ onStepClick, className,
|
|
580
|
+
declare function WorkflowStepper({ onStepClick, className, ...props }: WorkflowStepperProps): react_jsx_runtime.JSX.Element;
|
|
638
581
|
|
|
639
582
|
interface LicensePayload {
|
|
640
583
|
plan: 'ARCHITECT' | 'FOUNDRY';
|
|
@@ -704,4 +647,4 @@ declare class RilayLicenseManager {
|
|
|
704
647
|
}>;
|
|
705
648
|
}
|
|
706
649
|
|
|
707
|
-
export { type LicensePayload, type LicensePlan, type LicenseResult, RilayLicenseManager, type StepDefinition, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton,
|
|
650
|
+
export { type LicensePayload, type LicensePlan, type LicenseResult, RilayLicenseManager, type StepDefinition, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, createFlow, flow, useWorkflowContext };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),H=require('@noble/ed25519'),react=require('react'),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 H__namespace=/*#__PURE__*/_interopNamespace(H);var Q=1751361139160,j="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),o=f.base64ToString(e).split(".");if(o.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[a,d,p]=o,n=`${a}.${d}`,c=new TextEncoder().encode(n),w=p.match(/.{2}/g);if(!w)return {valid:!1,error:"INVALID"};let k=new Uint8Array(w.map(u=>Number.parseInt(u,16))),h=f.hexToBytes(j);if(!await H__namespace.verify(k,c,h))return {valid:!1,error:"SIGNATURE_INVALID"};let g=f.base64ToString(d.replace(/-/g,"+").replace(/_/g,"/")),m=JSON.parse(g),y=Math.floor(Date.now()/1e3);return m.e<y?{valid:!1,error:"EXPIRED",data:f.decompressPayload(m)}:Q>m.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(m)}:m.p===void 0||!m.c||!m.i||!m.e||!m.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(m)}}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 o=0;o<e.length;o+=2)r[o/2]=Number.parseInt(e.substring(o,o+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+/",o="",a=0,d=e.replace(/[^A-Za-z0-9+/]/g,"");for(;a<d.length;){let p=r.indexOf(d.charAt(a++)),n=r.indexOf(d.charAt(a++)),c=r.indexOf(d.charAt(a++)),w=r.indexOf(d.charAt(a++)),k=p<<18|n<<12|c<<6|w;o+=String.fromCharCode(k>>16&255),c!==64&&(o+=String.fromCharCode(k>>8&255)),w!==64&&(o+=String.fromCharCode(k&255));}return o}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.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=f.getLicenseResult();if(e.valid)return;let o={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${o}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var D=f;var x=class i{constructor(e,r,o,a){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=r,this.workflowName=o,this.workflowDescription=a,D.logLicenseStatus();}static create(e,r,o,a){return new i(e,r,o,a)}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,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let r=core.normalizeToArray(e);for(let o of r){let a=this.createStepFromDefinition(o);this.steps.push(a);}return this}addDynamicStep(e){return this.addStep(e)}configure(e){return e.navigation&&(this.navigation=core.configureObject(this.navigation,e.navigation)),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),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(o=>!this.plugins.some(a=>a.name===o));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 o=this.steps.findIndex(a=>a.id===e);if(o===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[o]={...this.steps[o],...r},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 o=new i(this.config,e||`${this.workflowId}-clone`,r||`${this.workflowName} (Copy)`,this.workflowDescription);return o.steps=core.deepClone(this.steps),o.navigation=core.deepClone(this.navigation),o.persistence=this.persistence?core.deepClone(this.persistence):void 0,o.completion=this.completion?core.deepClone(this.completion):void 0,o.analytics=this.analytics?core.deepClone(this.analytics):void 0,o.plugins=[...this.plugins],o}validate(){let e=new core.ValidationErrorBuilder;e.addIf(this.steps.length===0,"NO_STEPS","Workflow must have at least one step");let r=this.steps.map(o=>o.id);try{core.ensureUnique(r,"step");}catch(o){e.add("DUPLICATE_STEP_IDS",o instanceof Error?o.message:String(o));}for(let o of this.plugins)if(o.dependencies){let a=o.dependencies.filter(d=>!this.plugins.some(p=>p.name===d));e.addIf(a.length>0,"MISSING_PLUGIN_DEPENDENCIES",`Plugin "${o.name}" requires missing dependencies: ${a.join(", ")}`);}return e.build().map(o=>o.message)}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,r)=>e+r.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}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],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function ae(i,e,r,o){return x.create(i,e,r,o)}core.ril.prototype.flow=function(i,e,r){return x.create(this,i,e,r)};function fe(i,e){switch(e.type){case "SET_CURRENT_STEP":return {...i,currentStepIndex:e.stepIndex,stepData:i.allData[i.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let r=i.resolvedSteps[i.currentStepIndex]?.id;return {...i,stepData:e.data,allData:{...i.allData,[r]:e.data}}}case "SET_ALL_DATA":return {...i,allData:e.data};case "SET_FIELD_VALUE":{let r=i.resolvedSteps[i.currentStepIndex]?.id,o={...i.stepData,[e.fieldId]:e.value};return {...i,stepData:o,allData:{...i.allData,[r]:o}}}case "SET_ERROR":return {...i,errors:{...i.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let r={...i.errors};return delete r[e.fieldId],{...i,errors:r}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,e.fieldId])};case "SET_VALIDATING":{let r=new Set(i.isValidating);return e.isValidating?r.add(e.fieldId):r.delete(e.fieldId),{...i,isValidating:r}}case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...i,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...i,visitedSteps:new Set([...i.visitedSteps,i.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...i,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...i,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:i.resolvedSteps};default:return i}}var J=react.createContext(null);function F({children:i,workflowConfig:e,defaultValues:r={},onStepChange:o,onWorkflowComplete:a,className:d,user:p}){let[n,c]=react.useReducer(fe,{currentStepIndex:0,allData:r,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),w=react.useRef(null),k=react.useRef(Date.now()),h=react.useRef(new Map),E=react.useRef(false),g=react.useRef(null),m=react.useRef(o),y=react.useRef(a);m.current=o,y.current=a;let t=react.useMemo(()=>e,[e]),u=react.useMemo(()=>({workflowId:t.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:p}),[t.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,p]);react.useEffect(()=>{(async()=>{let l=[];for(let S of t.steps)if(S.isDynamic&&S.dynamicConfig)try{let _=await S.dynamicConfig.resolver(n.allData,u);l.push(..._);}catch(_){console.error(`Failed to resolve dynamic step "${S.id}":`,_),l.push({...S,isDynamic:false});}else l.push(S);c({type:"SET_RESOLVED_STEPS",steps:l});})();},[t.steps,n.allData,u]),react.useEffect(()=>{t.analytics?.onWorkflowStart&&!E.current&&(E.current=true,t.analytics.onWorkflowStart(t.id,u));},[t.id,t.analytics,u]),react.useEffect(()=>{let s=n.resolvedSteps[n.currentStepIndex];if(s&&g.current!==s.id){if(g.current&&t.analytics?.onStepComplete){let l=h.current.get(g.current);l&&t.analytics.onStepComplete(g.current,Date.now()-l,n.stepData,u);}g.current=s.id,h.current.set(s.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(s.id,Date.now(),u);}},[n.currentStepIndex,n.resolvedSteps,t.analytics,u]);let C=react.useCallback(async()=>{if(t.persistence)try{let s={workflowId:t.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:p?.id,sessionId:crypto.randomUUID()}},l=t.persistence.key||`workflow-${t.id}`;await t.persistence.adapter.save(l,s),t.persistence.onSave&&await t.persistence.onSave(s);}catch(s){console.error("Failed to save workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"save");}},[t,n.currentStepIndex,n.allData,p]),V=react.useCallback(async()=>{if(t.persistence)try{let s=t.persistence.key||`workflow-${t.id}`,l=await t.persistence.adapter.load(s);l&&l.workflowId===t.id&&(c({type:"SET_ALL_DATA",data:l.allData}),c({type:"SET_CURRENT_STEP",stepIndex:l.currentStepIndex}),c({type:"SET_PERSISTED_DATA",data:l}),t.persistence.onLoad&&await t.persistence.onLoad(l));}catch(s){console.error("Failed to load workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"load");}},[t]),A=react.useCallback(async()=>{if(t.persistence)try{let s=t.persistence.key||`workflow-${t.id}`;await t.persistence.adapter.remove(s);}catch(s){console.error("Failed to clear workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"remove");}},[t]);react.useEffect(()=>{t.persistence&&(async()=>{try{let l=t.persistence.key||`workflow-${t.id}`,S=await t.persistence.adapter.load(l);S&&S.workflowId===t.id&&(c({type:"SET_ALL_DATA",data:S.allData}),c({type:"SET_CURRENT_STEP",stepIndex:S.currentStepIndex}),c({type:"SET_PERSISTED_DATA",data:S}),t.persistence.onLoad&&await t.persistence.onLoad(S),console.log("Workflow data loaded from persistence:",S));}catch(l){console.error("Failed to load workflow draft on mount:",l),t.persistence.onError&&await t.persistence.onError(l,"load");}})();},[t.id]),react.useEffect(()=>{if(t.persistence?.saveOnStepChange)return w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{C();},t.persistence.debounceMs||1e3),()=>{w.current&&clearTimeout(w.current);}},[n.allData,C,t.persistence]);let R=react.useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),O=react.useMemo(()=>R?.formConfig,[R]),P=react.useCallback(async s=>{if(s<0||s>=n.resolvedSteps.length)return false;let l=n.resolvedSteps[s];if(l.permissions)try{if(!(l.permissions.customGuard?await l.permissions.customGuard(p,u):!0))return console.warn(`Access denied to step "${l.id}"`),!1}catch(S){return console.error(`Permission check failed for step "${l.id}":`,S),false}if(l.hooks?.onBeforeEnter)try{await l.hooks.onBeforeEnter(n.stepData,n.allData,u);}catch(S){return console.error(`onBeforeEnter hook failed for step "${l.id}":`,S),t.analytics?.onError&&t.analytics.onError(S,u),false}c({type:"SET_TRANSITIONING",isTransitioning:true});try{return m.current&&m.current(n.currentStepIndex,s,u),c({type:"SET_CURRENT_STEP",stepIndex:s}),c({type:"MARK_STEP_VISITED",stepIndex:s}),!0}catch(S){return console.error("Step transition failed:",S),t.analytics?.onError&&t.analytics.onError(S,u),false}finally{c({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,p,u,t.analytics]),B=react.useCallback((s,l)=>{c({type:"SET_FIELD_VALUE",fieldId:s,value:l});},[]),U=react.useCallback(s=>{c({type:"SET_STEP_DATA",data:s});},[]),M=react.useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),L=react.useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=react.useCallback(async()=>t.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[t.navigation,n.currentStepIndex,P]),$=react.useCallback(async()=>!R?.allowSkip||!t.navigation?.allowStepSkipping?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(R.id,"user_skip",u),P(n.currentStepIndex+1)),[R,t.navigation,t.analytics,u,P,n.currentStepIndex]),K=react.useCallback(async()=>{c({type:"SET_SUBMITTING",isSubmitting:true});try{if(y.current&&await y.current(n.allData),await A(),t.analytics?.onWorkflowComplete){let s=Date.now()-k.current;t.analytics.onWorkflowComplete(t.id,s,n.allData);}}catch(s){throw console.error("Workflow submission failed:",s),t.analytics?.onError&&t.analytics.onError(s,u),s}finally{c({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,y,A,t.analytics,u]),z=react.useCallback(()=>{c({type:"RESET_WORKFLOW"});},[]),Y=react.useMemo(()=>({workflowState:n,workflowConfig:t,currentStep:R,context:u,formConfig:O,goToStep:P,goNext:L,goPrevious:G,skipStep:$,setValue:B,setStepData:U,validateCurrentStep:M,submitWorkflow:K,resetWorkflow:z,saveDraft:C,loadDraft:V,clearDraft:A}),[n,t,R,u,O,P,L,G,$,B,U,M,K,z,C,V,A]),Z=react.useCallback(async()=>{await L();},[L]);return jsxRuntime.jsx(J.Provider,{value:Y,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:B,"data-workflow-id":t.id,className:d,onSubmit:Z,children:i})})}function I(){let i=react.useContext(J);if(!i)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return i}function we({children:i,workflowConfig:e,...r}){let[o,a]=react.useState(false),d=D.shouldDisplayWatermark(),p=D.getWatermarkMessage(),n=e instanceof x?e.build():e;return react.useEffect(()=>{a(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(F,{...r,workflowConfig:n,children:i}),o&&d&&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:p})]})}function ke(){let{currentStep:i}=I();if(!i)return null;let{formConfig:e,renderer:r}=i;return e?r?r(i):jsxRuntime.jsx(forms.FormBody,{}):null}function Re({className:i,children:e,renderAs:r}){let{context:o,submitWorkflow:a,workflowState:d,workflowConfig:p,currentStep:n}=I(),{submit:c,formState:w}=forms.useFormContext(),k=!d.isTransitioning&&!d.isSubmitting,h=async C=>{C?.preventDefault(),k&&await c(C);},E=async C=>{C?.preventDefault(),k&&await a();},g={isLastStep:o.isLastStep,canGoNext:k,isSubmitting:d.isSubmitting,onNext:h,onSubmit:E,className:i,currentStep:n,stepData:w.values||{},allData:o.allData,context:o};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(g)}let y=p.renderConfig?.nextButtonRenderer;if(!y)throw new Error(`No nextButtonRenderer configured for workflow "${p.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let t=core.resolveRendererChildren(e,g),u={...g,children:t};return y(u)}function Ce({className:i,children:e,renderAs:r}){let{context:o,goPrevious:a,workflowState:d,workflowConfig:p,currentStep:n}=I(),{formState:c}=forms.useFormContext(),w=o.currentStepIndex>0&&p.navigation?.allowBackNavigation!==false&&!d.isTransitioning&&!d.isSubmitting;if(p.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${p.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let h={canGoPrevious:w,onPrevious:async t=>{t?.preventDefault(),w&&await a();},className:i,currentStep:n,stepData:c.values||{},allData:o.allData,context:o};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(h)}let g=p.renderConfig?.previousButtonRenderer;if(!g)throw new Error(`No previousButtonRenderer configured for workflow "${p.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let m=core.resolveRendererChildren(e,h),y={...h,children:m};return g(y)}function xe({className:i,children:e,renderAs:r}){let{currentStep:o,skipStep:a,workflowState:d,workflowConfig:p,context:n}=I(),{formState:c}=forms.useFormContext(),w=!!o?.allowSkip&&p.navigation?.allowStepSkipping!==false&&!d.isTransitioning&&!d.isSubmitting,h={canSkip:w,onSkip:async t=>{t?.preventDefault(),w&&await a();},className:i,currentStep:o,stepData:c.values||{},allData:n.allData,context:n};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(h)}let g=p.renderConfig?.skipButtonRenderer;if(!g)throw new Error(`No skipButtonRenderer configured for workflow "${p.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let m=core.resolveRendererChildren(e,h),y={...h,children:m};return g(y)}function We({onStepClick:i,className:e,children:r,renderAs:o}){let{workflowConfig:a,workflowState:d,goToStep:p}=I(),n=E=>{i?i(E):p(E);},c={steps:d.resolvedSteps,currentStepIndex:d.currentStepIndex,visitedSteps:d.visitedSteps,onStepClick:n,className:e};if(o==="children"||o===true){if(typeof r!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return r(c)}let k=a.renderConfig?.stepperRenderer;if(!k)throw new Error(`No stepperRenderer configured for workflow "${a.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return k(c)}
|
|
2
|
-
Object.defineProperty(exports,"
|
|
1
|
+
'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),O=require('@noble/ed25519'),react=require('react'),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 O__namespace=/*#__PURE__*/_interopNamespace(O);var X=1751361139160,Y="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",p=class p{static async setLicenseKey(e){p.licenseKey=e||"",p.licenseKey?p.licenseResult=await p.validateLicense():p.licenseResult={valid:false,error:"MISSING"},p.isInitialized=true;}static async validateLicense(){if(!p.licenseKey)return {valid:false,error:"MISSING"};try{if(!p.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=p.licenseKey.slice(4),r=p.base64ToString(e).split(".");if(r.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[s,f,n]=r,l=`${s}.${f}`,u=new TextEncoder().encode(l),w=n.match(/.{2}/g);if(!w)return {valid:!1,error:"INVALID"};let m=new Uint8Array(w.map(E=>Number.parseInt(E,16))),g=p.hexToBytes(Y);if(!await O__namespace.verify(m,u,g))return {valid:!1,error:"SIGNATURE_INVALID"};let x=p.base64ToString(f.replace(/-/g,"+").replace(/_/g,"/")),o=JSON.parse(x),d=Math.floor(Date.now()/1e3);return o.e<d?{valid:!1,error:"EXPIRED",data:p.decompressPayload(o)}:X>o.e*1e3?{valid:!1,error:"EXPIRED",data:p.decompressPayload(o)}:o.p===void 0||!o.c||!o.i||!o.e||!o.t?{valid:!1,error:"INVALID"}:{valid:!0,data:p.decompressPayload(o)}}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 r=0;r<e.length;r+=2)t[r/2]=Number.parseInt(e.substring(r,r+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+/",r="",s=0,f=e.replace(/[^A-Za-z0-9+/]/g,"");for(;s<f.length;){let n=t.indexOf(f.charAt(s++)),l=t.indexOf(f.charAt(s++)),u=t.indexOf(f.charAt(s++)),w=t.indexOf(f.charAt(s++)),m=n<<18|l<<12|u<<6|w;r+=String.fromCharCode(m>>16&255),u!==64&&(r+=String.fromCharCode(m>>8&255)),w!==64&&(r+=String.fromCharCode(m&255));}return r}static getLicenseResult(){return p.isInitialized?p.licenseResult?p.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!p.getLicenseResult().valid}static getWatermarkMessage(){let e=p.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=p.getLicenseResult();if(e.valid)return;let r={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${r}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=p.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};p.licenseKey="",p.licenseResult=null,p.isInitialized=false;var h=p;var I=class i{constructor(e,t,r,s){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=t,this.workflowName=r,this.workflowDescription=s,h.logLicenseStatus();}static create(e,t,r,s){return new i(e,t,r,s)}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,onAfterValidation:e.onAfterValidation}}addStep(e){let t=core.normalizeToArray(e);for(let r of t){let s=this.createStepFromDefinition(r);this.steps.push(s);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),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(r=>!this.plugins.some(s=>s.name===r));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 r=this.steps.findIndex(s=>s.id===e);if(r===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[r]={...this.steps[r],...t},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 r=new i(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return r.steps=core.deepClone(this.steps),r.analytics=this.analytics?core.deepClone(this.analytics):void 0,r.plugins=[...this.plugins],r}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(r=>r.id);try{core.ensureUnique(t,"step");}catch(r){e.push(r instanceof Error?r.message:String(r));}for(let r of this.plugins)if(r.dependencies){let s=r.dependencies.filter(f=>!this.plugins.some(n=>n.name===f));s.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${s.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((r,s)=>r+s.formConfig.allFields.length,0),t=this.steps.map(r=>r.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,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,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.plugins=e.plugins||[],this}};function re(i,e,t,r){return I.create(i,e,t,r)}core.ril.prototype.flow=function(i,e,t){return I.create(this,i,e,t)};function ae(i,e){switch(e.type){case "SET_CURRENT_STEP":return {...i,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":{let t=e.stepId;return {...i,stepData:e.data,allData:{...i.allData,[t]:e.data}}}case "SET_ALL_DATA":return {...i,allData:e.data};case "SET_FIELD_VALUE":{let t=e.stepId,r={...i.stepData,[e.fieldId]:e.value};return {...i,stepData:r,allData:{...i.allData,[t]:r}}}case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...i,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...i,visitedSteps:new Set([...i.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false};default:return i}}var $=react.createContext(null);function N({children:i,workflowConfig:e,defaultValues:t={},onStepChange:r,onWorkflowComplete:s,className:f}){let[n,l]=react.useReducer(ae,{currentStepIndex:0,allData:t,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false}),u=react.useRef(Date.now()),w=react.useRef(new Map),m=react.useRef(false),g=react.useRef(null),T=react.useRef(r),x=react.useRef(s);T.current=r,x.current=s;let o=react.useMemo(()=>e,[e]),d=react.useMemo(()=>({workflowId:o.id,currentStepIndex:n.currentStepIndex,totalSteps:o.steps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===o.steps.length-1,visitedSteps:n.visitedSteps}),[o.id,n.currentStepIndex,o.steps.length,n.allData,n.stepData,n.visitedSteps]);react.useEffect(()=>{o.analytics?.onWorkflowStart&&!m.current&&(m.current=true,o.analytics.onWorkflowStart(o.id,d));},[o.id,o.analytics,d]),react.useEffect(()=>{let a=o.steps[n.currentStepIndex];if(a&&g.current!==a.id){if(g.current&&o.analytics?.onStepComplete){let c=w.current.get(g.current);c&&o.analytics.onStepComplete(g.current,Date.now()-c,n.stepData,d);}g.current=a.id,w.current.set(a.id,Date.now()),o.analytics?.onStepStart&&o.analytics.onStepStart(a.id,Date.now(),d);}},[n.currentStepIndex,o.steps,o.analytics,d]);let S=react.useMemo(()=>o.steps[n.currentStepIndex],[o.steps,n.currentStepIndex]),E=react.useMemo(()=>S?.formConfig,[S]),D=react.useCallback(async a=>{if(a<0||a>=o.steps.length)return false;l({type:"SET_TRANSITIONING",isTransitioning:true});try{return T.current&&T.current(n.currentStepIndex,a,d),l({type:"SET_CURRENT_STEP",stepIndex:a}),l({type:"MARK_STEP_VISITED",stepIndex:a,stepId:o.steps[a].id}),!0}catch(c){return console.error("Step transition failed:",c),o.analytics?.onError&&o.analytics.onError(c,d),false}finally{l({type:"SET_TRANSITIONING",isTransitioning:false});}},[o.steps,n.currentStepIndex,d,o.analytics]),L=react.useCallback(()=>({setStepData:(a,c)=>{l({type:"SET_STEP_DATA",data:c,stepId:a});},setStepFields:(a,c)=>{let C={...n.allData[a]||{},...c};l({type:"SET_STEP_DATA",data:C,stepId:a});},getStepData:a=>n.allData[a]||{},setNextStepField:(a,c)=>{let v=n.currentStepIndex+1;if(v<o.steps.length){let C=o.steps[v].id,J={...n.allData[C]||{},[a]:c};l({type:"SET_STEP_DATA",data:J,stepId:C});}},setNextStepFields:a=>{let c=n.currentStepIndex+1;if(c<o.steps.length){let v=o.steps[c].id,_={...n.allData[v]||{},...a};l({type:"SET_STEP_DATA",data:_,stepId:v});}},getAllData:()=>({...n.allData}),getSteps:()=>[...o.steps]}),[n.allData,n.currentStepIndex,o.steps]),A=react.useCallback((a,c)=>{l({type:"SET_FIELD_VALUE",fieldId:a,value:c,stepId:S?.id||""});},[S?.id]),F=react.useCallback(a=>{l({type:"SET_STEP_DATA",data:a,stepId:S?.id||""});},[S?.id]),W=react.useCallback(async()=>{if(S?.onAfterValidation)try{let c=L();await S.onAfterValidation(n.stepData,c,d);}catch(c){return console.error("onAfterValidation failed:",c),o.analytics?.onError&&o.analytics.onError(c,d),false}let a=n.currentStepIndex+1;return D(a)},[S,L,n.stepData,d,o.analytics,D,n.currentStepIndex]),B=react.useCallback(async()=>D(n.currentStepIndex-1),[n.currentStepIndex,D]),b=react.useCallback(async()=>{l({type:"SET_SUBMITTING",isSubmitting:true});try{if(x.current&&await x.current(n.allData),o.analytics?.onWorkflowComplete){let a=Date.now()-u.current;o.analytics.onWorkflowComplete(o.id,a,n.allData);}}catch(a){throw console.error("Workflow submission failed:",a),o.analytics?.onError&&o.analytics.onError(a,d),a}finally{l({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,x,o.analytics,d]),V=react.useCallback(async()=>S?.allowSkip?(o.analytics?.onStepSkip&&o.analytics.onStepSkip(S.id,"user_skip",d),d.isLastStep?(await b(),true):W()):false,[S,o.analytics,d,W,b]),M=react.useCallback(()=>{l({type:"RESET_WORKFLOW"});},[]),z=react.useMemo(()=>({workflowState:n,workflowConfig:o,currentStep:S,context:d,formConfig:E,goToStep:D,goNext:W,goPrevious:B,skipStep:V,setValue:A,setStepData:F,submitWorkflow:b,resetWorkflow:M}),[n,o,S,d,E,D,W,B,V,A,F,b,M]),q=react.useCallback(async()=>{await W();},[W]);return jsxRuntime.jsx($.Provider,{value:z,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:S?.formConfig,defaultValues:n?.allData[S?.id]||{},onFieldChange:A,"data-workflow-id":o.id,className:f,onSubmit:q,children:i})})}function y(){let i=react.useContext($);if(!i)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return i}function ce({children:i,workflowConfig:e,...t}){let[r,s]=react.useState(false),f=h.shouldDisplayWatermark(),n=h.getWatermarkMessage(),l=react.useMemo(()=>e instanceof I?e.build():e,[e]);return react.useEffect(()=>{s(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(N,{...t,workflowConfig:l,children:i}),r&&f&&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:n})]})}function Se(){let{currentStep:i}=y();if(!i)return null;let{formConfig:e,renderer:t}=i;return e?t?t(i):jsxRuntime.jsx(forms.FormBody,{}):null}function ye({className:i,...e}){let{context:t,workflowState:r,workflowConfig:s,currentStep:f}=y(),{submit:n,formState:l}=forms.useFormContext(),u=!r.isTransitioning&&!r.isSubmitting,w=async g=>{g?.preventDefault(),u&&await n(g);},m={isLastStep:t.isLastStep,canGoNext:u,isSubmitting:l.isSubmitting||r.isSubmitting,onSubmit:w,className:i,currentStep:f,stepData:l.values||{},allData:t.allData,context:t};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:s.renderConfig?.nextButtonRenderer,props:m,...e})}function xe({className:i,...e}){let{context:t,goPrevious:r,workflowState:s,workflowConfig:f,currentStep:n}=y(),{formState:l}=forms.useFormContext(),u=t.currentStepIndex>0&&!s.isTransitioning&&!s.isSubmitting,m={canGoPrevious:u,onPrevious:async g=>{g?.preventDefault(),u&&await r();},className:i,currentStep:n,stepData:l.values||{},allData:t.allData,context:t};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:f.renderConfig?.previousButtonRenderer,props:m,...e})}function Re({className:i,...e}){let{currentStep:t,skipStep:r,workflowState:s,workflowConfig:f,context:n}=y(),{formState:l}=forms.useFormContext(),u=!!t?.allowSkip&&!s.isTransitioning&&!s.isSubmitting,m={canSkip:u,onSkip:async g=>{g?.preventDefault(),u&&await r();},className:i,currentStep:t,stepData:l.values||{},allData:n.allData,context:n};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:f.renderConfig?.skipButtonRenderer,props:m,...e})}function Te({onStepClick:i,className:e,...t}){let{workflowConfig:r,workflowState:s,goToStep:f}=y(),n=u=>{i?i(u):f(u);},l={steps:r.steps,currentStepIndex:s.currentStepIndex,visitedSteps:s.visitedSteps,onStepClick:n,className:e};return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowStepper",renderer:r.renderConfig?.stepperRenderer,props:l,...t})}
|
|
2
|
+
Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});exports.RilayLicenseManager=h;exports.Workflow=ce;exports.WorkflowBody=Se;exports.WorkflowNextButton=ye;exports.WorkflowPreviousButton=xe;exports.WorkflowProvider=N;exports.WorkflowSkipButton=Re;exports.WorkflowStepper=Te;exports.createFlow=re;exports.flow=I;exports.useWorkflowContext=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,configureObject,deepClone,ValidationErrorBuilder,ensureUnique,resolveRendererChildren}from'@rilaykit/core';export{createZodValidator,ril}from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import*as H from'@noble/ed25519';import {createContext,useReducer,useRef,useMemo,useEffect,useCallback,useContext,useState}from'react';import {jsx,jsxs}from'react/jsx-runtime';var Q=1751361139160,j="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),o=f.base64ToString(e).split(".");if(o.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[a,d,p]=o,n=`${a}.${d}`,c=new TextEncoder().encode(n),w=p.match(/.{2}/g);if(!w)return {valid:!1,error:"INVALID"};let k=new Uint8Array(w.map(u=>Number.parseInt(u,16))),h=f.hexToBytes(j);if(!await H.verify(k,c,h))return {valid:!1,error:"SIGNATURE_INVALID"};let g=f.base64ToString(d.replace(/-/g,"+").replace(/_/g,"/")),m=JSON.parse(g),y=Math.floor(Date.now()/1e3);return m.e<y?{valid:!1,error:"EXPIRED",data:f.decompressPayload(m)}:Q>m.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(m)}:m.p===void 0||!m.c||!m.i||!m.e||!m.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(m)}}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 o=0;o<e.length;o+=2)r[o/2]=Number.parseInt(e.substring(o,o+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+/",o="",a=0,d=e.replace(/[^A-Za-z0-9+/]/g,"");for(;a<d.length;){let p=r.indexOf(d.charAt(a++)),n=r.indexOf(d.charAt(a++)),c=r.indexOf(d.charAt(a++)),w=r.indexOf(d.charAt(a++)),k=p<<18|n<<12|c<<6|w;o+=String.fromCharCode(k>>16&255),c!==64&&(o+=String.fromCharCode(k>>8&255)),w!==64&&(o+=String.fromCharCode(k&255));}return o}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.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=f.getLicenseResult();if(e.valid)return;let o={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${o}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var D=f;var x=class i{constructor(e,r,o,a){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=r,this.workflowName=o,this.workflowDescription=a,D.logLicenseStatus();}static create(e,r,o,a){return new i(e,r,o,a)}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,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let r=normalizeToArray(e);for(let o of r){let a=this.createStepFromDefinition(o);this.steps.push(a);}return this}addDynamicStep(e){return this.addStep(e)}configure(e){return e.navigation&&(this.navigation=configureObject(this.navigation,e.navigation)),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),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(o=>!this.plugins.some(a=>a.name===o));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 o=this.steps.findIndex(a=>a.id===e);if(o===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[o]={...this.steps[o],...r},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 o=new i(this.config,e||`${this.workflowId}-clone`,r||`${this.workflowName} (Copy)`,this.workflowDescription);return o.steps=deepClone(this.steps),o.navigation=deepClone(this.navigation),o.persistence=this.persistence?deepClone(this.persistence):void 0,o.completion=this.completion?deepClone(this.completion):void 0,o.analytics=this.analytics?deepClone(this.analytics):void 0,o.plugins=[...this.plugins],o}validate(){let e=new ValidationErrorBuilder;e.addIf(this.steps.length===0,"NO_STEPS","Workflow must have at least one step");let r=this.steps.map(o=>o.id);try{ensureUnique(r,"step");}catch(o){e.add("DUPLICATE_STEP_IDS",o instanceof Error?o.message:String(o));}for(let o of this.plugins)if(o.dependencies){let a=o.dependencies.filter(d=>!this.plugins.some(p=>p.name===d));e.addIf(a.length>0,"MISSING_PLUGIN_DEPENDENCIES",`Plugin "${o.name}" requires missing dependencies: ${a.join(", ")}`);}return e.build().map(o=>o.message)}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,r)=>e+r.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}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],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function ae(i,e,r,o){return x.create(i,e,r,o)}ril.prototype.flow=function(i,e,r){return x.create(this,i,e,r)};function fe(i,e){switch(e.type){case "SET_CURRENT_STEP":return {...i,currentStepIndex:e.stepIndex,stepData:i.allData[i.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let r=i.resolvedSteps[i.currentStepIndex]?.id;return {...i,stepData:e.data,allData:{...i.allData,[r]:e.data}}}case "SET_ALL_DATA":return {...i,allData:e.data};case "SET_FIELD_VALUE":{let r=i.resolvedSteps[i.currentStepIndex]?.id,o={...i.stepData,[e.fieldId]:e.value};return {...i,stepData:o,allData:{...i.allData,[r]:o}}}case "SET_ERROR":return {...i,errors:{...i.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let r={...i.errors};return delete r[e.fieldId],{...i,errors:r}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,e.fieldId])};case "SET_VALIDATING":{let r=new Set(i.isValidating);return e.isValidating?r.add(e.fieldId):r.delete(e.fieldId),{...i,isValidating:r}}case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...i,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...i,visitedSteps:new Set([...i.visitedSteps,i.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...i,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...i,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:i.resolvedSteps};default:return i}}var J=createContext(null);function F({children:i,workflowConfig:e,defaultValues:r={},onStepChange:o,onWorkflowComplete:a,className:d,user:p}){let[n,c]=useReducer(fe,{currentStepIndex:0,allData:r,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),w=useRef(null),k=useRef(Date.now()),h=useRef(new Map),E=useRef(false),g=useRef(null),m=useRef(o),y=useRef(a);m.current=o,y.current=a;let t=useMemo(()=>e,[e]),u=useMemo(()=>({workflowId:t.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:p}),[t.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,p]);useEffect(()=>{(async()=>{let l=[];for(let S of t.steps)if(S.isDynamic&&S.dynamicConfig)try{let _=await S.dynamicConfig.resolver(n.allData,u);l.push(..._);}catch(_){console.error(`Failed to resolve dynamic step "${S.id}":`,_),l.push({...S,isDynamic:false});}else l.push(S);c({type:"SET_RESOLVED_STEPS",steps:l});})();},[t.steps,n.allData,u]),useEffect(()=>{t.analytics?.onWorkflowStart&&!E.current&&(E.current=true,t.analytics.onWorkflowStart(t.id,u));},[t.id,t.analytics,u]),useEffect(()=>{let s=n.resolvedSteps[n.currentStepIndex];if(s&&g.current!==s.id){if(g.current&&t.analytics?.onStepComplete){let l=h.current.get(g.current);l&&t.analytics.onStepComplete(g.current,Date.now()-l,n.stepData,u);}g.current=s.id,h.current.set(s.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(s.id,Date.now(),u);}},[n.currentStepIndex,n.resolvedSteps,t.analytics,u]);let C=useCallback(async()=>{if(t.persistence)try{let s={workflowId:t.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:p?.id,sessionId:crypto.randomUUID()}},l=t.persistence.key||`workflow-${t.id}`;await t.persistence.adapter.save(l,s),t.persistence.onSave&&await t.persistence.onSave(s);}catch(s){console.error("Failed to save workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"save");}},[t,n.currentStepIndex,n.allData,p]),V=useCallback(async()=>{if(t.persistence)try{let s=t.persistence.key||`workflow-${t.id}`,l=await t.persistence.adapter.load(s);l&&l.workflowId===t.id&&(c({type:"SET_ALL_DATA",data:l.allData}),c({type:"SET_CURRENT_STEP",stepIndex:l.currentStepIndex}),c({type:"SET_PERSISTED_DATA",data:l}),t.persistence.onLoad&&await t.persistence.onLoad(l));}catch(s){console.error("Failed to load workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"load");}},[t]),A=useCallback(async()=>{if(t.persistence)try{let s=t.persistence.key||`workflow-${t.id}`;await t.persistence.adapter.remove(s);}catch(s){console.error("Failed to clear workflow draft:",s),t.persistence.onError&&await t.persistence.onError(s,"remove");}},[t]);useEffect(()=>{t.persistence&&(async()=>{try{let l=t.persistence.key||`workflow-${t.id}`,S=await t.persistence.adapter.load(l);S&&S.workflowId===t.id&&(c({type:"SET_ALL_DATA",data:S.allData}),c({type:"SET_CURRENT_STEP",stepIndex:S.currentStepIndex}),c({type:"SET_PERSISTED_DATA",data:S}),t.persistence.onLoad&&await t.persistence.onLoad(S),console.log("Workflow data loaded from persistence:",S));}catch(l){console.error("Failed to load workflow draft on mount:",l),t.persistence.onError&&await t.persistence.onError(l,"load");}})();},[t.id]),useEffect(()=>{if(t.persistence?.saveOnStepChange)return w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{C();},t.persistence.debounceMs||1e3),()=>{w.current&&clearTimeout(w.current);}},[n.allData,C,t.persistence]);let R=useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),O=useMemo(()=>R?.formConfig,[R]),P=useCallback(async s=>{if(s<0||s>=n.resolvedSteps.length)return false;let l=n.resolvedSteps[s];if(l.permissions)try{if(!(l.permissions.customGuard?await l.permissions.customGuard(p,u):!0))return console.warn(`Access denied to step "${l.id}"`),!1}catch(S){return console.error(`Permission check failed for step "${l.id}":`,S),false}if(l.hooks?.onBeforeEnter)try{await l.hooks.onBeforeEnter(n.stepData,n.allData,u);}catch(S){return console.error(`onBeforeEnter hook failed for step "${l.id}":`,S),t.analytics?.onError&&t.analytics.onError(S,u),false}c({type:"SET_TRANSITIONING",isTransitioning:true});try{return m.current&&m.current(n.currentStepIndex,s,u),c({type:"SET_CURRENT_STEP",stepIndex:s}),c({type:"MARK_STEP_VISITED",stepIndex:s}),!0}catch(S){return console.error("Step transition failed:",S),t.analytics?.onError&&t.analytics.onError(S,u),false}finally{c({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,p,u,t.analytics]),B=useCallback((s,l)=>{c({type:"SET_FIELD_VALUE",fieldId:s,value:l});},[]),U=useCallback(s=>{c({type:"SET_STEP_DATA",data:s});},[]),M=useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),L=useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=useCallback(async()=>t.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[t.navigation,n.currentStepIndex,P]),$=useCallback(async()=>!R?.allowSkip||!t.navigation?.allowStepSkipping?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(R.id,"user_skip",u),P(n.currentStepIndex+1)),[R,t.navigation,t.analytics,u,P,n.currentStepIndex]),K=useCallback(async()=>{c({type:"SET_SUBMITTING",isSubmitting:true});try{if(y.current&&await y.current(n.allData),await A(),t.analytics?.onWorkflowComplete){let s=Date.now()-k.current;t.analytics.onWorkflowComplete(t.id,s,n.allData);}}catch(s){throw console.error("Workflow submission failed:",s),t.analytics?.onError&&t.analytics.onError(s,u),s}finally{c({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,y,A,t.analytics,u]),z=useCallback(()=>{c({type:"RESET_WORKFLOW"});},[]),Y=useMemo(()=>({workflowState:n,workflowConfig:t,currentStep:R,context:u,formConfig:O,goToStep:P,goNext:L,goPrevious:G,skipStep:$,setValue:B,setStepData:U,validateCurrentStep:M,submitWorkflow:K,resetWorkflow:z,saveDraft:C,loadDraft:V,clearDraft:A}),[n,t,R,u,O,P,L,G,$,B,U,M,K,z,C,V,A]),Z=useCallback(async()=>{await L();},[L]);return jsx(J.Provider,{value:Y,children:jsx(FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:B,"data-workflow-id":t.id,className:d,onSubmit:Z,children:i})})}function I(){let i=useContext(J);if(!i)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return i}function we({children:i,workflowConfig:e,...r}){let[o,a]=useState(false),d=D.shouldDisplayWatermark(),p=D.getWatermarkMessage(),n=e instanceof x?e.build():e;return useEffect(()=>{a(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(F,{...r,workflowConfig:n,children:i}),o&&d&&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:p})]})}function ke(){let{currentStep:i}=I();if(!i)return null;let{formConfig:e,renderer:r}=i;return e?r?r(i):jsx(FormBody,{}):null}function Re({className:i,children:e,renderAs:r}){let{context:o,submitWorkflow:a,workflowState:d,workflowConfig:p,currentStep:n}=I(),{submit:c,formState:w}=useFormContext(),k=!d.isTransitioning&&!d.isSubmitting,h=async C=>{C?.preventDefault(),k&&await c(C);},E=async C=>{C?.preventDefault(),k&&await a();},g={isLastStep:o.isLastStep,canGoNext:k,isSubmitting:d.isSubmitting,onNext:h,onSubmit:E,className:i,currentStep:n,stepData:w.values||{},allData:o.allData,context:o};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(g)}let y=p.renderConfig?.nextButtonRenderer;if(!y)throw new Error(`No nextButtonRenderer configured for workflow "${p.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let t=resolveRendererChildren(e,g),u={...g,children:t};return y(u)}function Ce({className:i,children:e,renderAs:r}){let{context:o,goPrevious:a,workflowState:d,workflowConfig:p,currentStep:n}=I(),{formState:c}=useFormContext(),w=o.currentStepIndex>0&&p.navigation?.allowBackNavigation!==false&&!d.isTransitioning&&!d.isSubmitting;if(p.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${p.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let h={canGoPrevious:w,onPrevious:async t=>{t?.preventDefault(),w&&await a();},className:i,currentStep:n,stepData:c.values||{},allData:o.allData,context:o};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(h)}let g=p.renderConfig?.previousButtonRenderer;if(!g)throw new Error(`No previousButtonRenderer configured for workflow "${p.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let m=resolveRendererChildren(e,h),y={...h,children:m};return g(y)}function xe({className:i,children:e,renderAs:r}){let{currentStep:o,skipStep:a,workflowState:d,workflowConfig:p,context:n}=I(),{formState:c}=useFormContext(),w=!!o?.allowSkip&&p.navigation?.allowStepSkipping!==false&&!d.isTransitioning&&!d.isSubmitting,h={canSkip:w,onSkip:async t=>{t?.preventDefault(),w&&await a();},className:i,currentStep:o,stepData:c.values||{},allData:n.allData,context:n};if(r==="children"||r===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(h)}let g=p.renderConfig?.skipButtonRenderer;if(!g)throw new Error(`No skipButtonRenderer configured for workflow "${p.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let m=resolveRendererChildren(e,h),y={...h,children:m};return g(y)}function We({onStepClick:i,className:e,children:r,renderAs:o}){let{workflowConfig:a,workflowState:d,goToStep:p}=I(),n=E=>{i?i(E):p(E);},c={steps:d.resolvedSteps,currentStepIndex:d.currentStepIndex,visitedSteps:d.visitedSteps,onStepClick:n,className:e};if(o==="children"||o===true){if(typeof r!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return r(c)}let k=a.renderConfig?.stepperRenderer;if(!k)throw new Error(`No stepperRenderer configured for workflow "${a.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return k(c)}
|
|
2
|
-
export{
|
|
1
|
+
import {ril,IdGenerator,normalizeToArray,deepClone,ensureUnique,ComponentRendererWrapper}from'@rilaykit/core';export*from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import*as O from'@noble/ed25519';import {createContext,useReducer,useRef,useMemo,useEffect,useCallback,useContext,useState}from'react';import {jsx,jsxs}from'react/jsx-runtime';var X=1751361139160,Y="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",p=class p{static async setLicenseKey(e){p.licenseKey=e||"",p.licenseKey?p.licenseResult=await p.validateLicense():p.licenseResult={valid:false,error:"MISSING"},p.isInitialized=true;}static async validateLicense(){if(!p.licenseKey)return {valid:false,error:"MISSING"};try{if(!p.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=p.licenseKey.slice(4),r=p.base64ToString(e).split(".");if(r.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[s,f,n]=r,l=`${s}.${f}`,u=new TextEncoder().encode(l),w=n.match(/.{2}/g);if(!w)return {valid:!1,error:"INVALID"};let m=new Uint8Array(w.map(E=>Number.parseInt(E,16))),g=p.hexToBytes(Y);if(!await O.verify(m,u,g))return {valid:!1,error:"SIGNATURE_INVALID"};let x=p.base64ToString(f.replace(/-/g,"+").replace(/_/g,"/")),o=JSON.parse(x),d=Math.floor(Date.now()/1e3);return o.e<d?{valid:!1,error:"EXPIRED",data:p.decompressPayload(o)}:X>o.e*1e3?{valid:!1,error:"EXPIRED",data:p.decompressPayload(o)}:o.p===void 0||!o.c||!o.i||!o.e||!o.t?{valid:!1,error:"INVALID"}:{valid:!0,data:p.decompressPayload(o)}}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 r=0;r<e.length;r+=2)t[r/2]=Number.parseInt(e.substring(r,r+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+/",r="",s=0,f=e.replace(/[^A-Za-z0-9+/]/g,"");for(;s<f.length;){let n=t.indexOf(f.charAt(s++)),l=t.indexOf(f.charAt(s++)),u=t.indexOf(f.charAt(s++)),w=t.indexOf(f.charAt(s++)),m=n<<18|l<<12|u<<6|w;r+=String.fromCharCode(m>>16&255),u!==64&&(r+=String.fromCharCode(m>>8&255)),w!==64&&(r+=String.fromCharCode(m&255));}return r}static getLicenseResult(){return p.isInitialized?p.licenseResult?p.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!p.getLicenseResult().valid}static getWatermarkMessage(){let e=p.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=p.getLicenseResult();if(e.valid)return;let r={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${r}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=p.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};p.licenseKey="",p.licenseResult=null,p.isInitialized=false;var h=p;var I=class i{constructor(e,t,r,s){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=t,this.workflowName=r,this.workflowDescription=s,h.logLicenseStatus();}static create(e,t,r,s){return new i(e,t,r,s)}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,onAfterValidation:e.onAfterValidation}}addStep(e){let t=normalizeToArray(e);for(let r of t){let s=this.createStepFromDefinition(r);this.steps.push(s);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),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(r=>!this.plugins.some(s=>s.name===r));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 r=this.steps.findIndex(s=>s.id===e);if(r===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[r]={...this.steps[r],...t},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 r=new i(this.config,e||`${this.workflowId}-clone`,t||this.workflowName);return r.steps=deepClone(this.steps),r.analytics=this.analytics?deepClone(this.analytics):void 0,r.plugins=[...this.plugins],r}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let t=this.steps.map(r=>r.id);try{ensureUnique(t,"step");}catch(r){e.push(r instanceof Error?r.message:String(r));}for(let r of this.plugins)if(r.dependencies){let s=r.dependencies.filter(f=>!this.plugins.some(n=>n.name===f));s.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${s.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((r,s)=>r+s.formConfig.allFields.length,0),t=this.steps.map(r=>r.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,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,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.plugins=e.plugins||[],this}};function re(i,e,t,r){return I.create(i,e,t,r)}ril.prototype.flow=function(i,e,t){return I.create(this,i,e,t)};function ae(i,e){switch(e.type){case "SET_CURRENT_STEP":return {...i,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":{let t=e.stepId;return {...i,stepData:e.data,allData:{...i.allData,[t]:e.data}}}case "SET_ALL_DATA":return {...i,allData:e.data};case "SET_FIELD_VALUE":{let t=e.stepId,r={...i.stepData,[e.fieldId]:e.value};return {...i,stepData:r,allData:{...i.allData,[t]:r}}}case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...i,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...i,visitedSteps:new Set([...i.visitedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false};default:return i}}var $=createContext(null);function N({children:i,workflowConfig:e,defaultValues:t={},onStepChange:r,onWorkflowComplete:s,className:f}){let[n,l]=useReducer(ae,{currentStepIndex:0,allData:t,stepData:{},visitedSteps:new Set,isSubmitting:false,isTransitioning:false}),u=useRef(Date.now()),w=useRef(new Map),m=useRef(false),g=useRef(null),T=useRef(r),x=useRef(s);T.current=r,x.current=s;let o=useMemo(()=>e,[e]),d=useMemo(()=>({workflowId:o.id,currentStepIndex:n.currentStepIndex,totalSteps:o.steps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===o.steps.length-1,visitedSteps:n.visitedSteps}),[o.id,n.currentStepIndex,o.steps.length,n.allData,n.stepData,n.visitedSteps]);useEffect(()=>{o.analytics?.onWorkflowStart&&!m.current&&(m.current=true,o.analytics.onWorkflowStart(o.id,d));},[o.id,o.analytics,d]),useEffect(()=>{let a=o.steps[n.currentStepIndex];if(a&&g.current!==a.id){if(g.current&&o.analytics?.onStepComplete){let c=w.current.get(g.current);c&&o.analytics.onStepComplete(g.current,Date.now()-c,n.stepData,d);}g.current=a.id,w.current.set(a.id,Date.now()),o.analytics?.onStepStart&&o.analytics.onStepStart(a.id,Date.now(),d);}},[n.currentStepIndex,o.steps,o.analytics,d]);let S=useMemo(()=>o.steps[n.currentStepIndex],[o.steps,n.currentStepIndex]),E=useMemo(()=>S?.formConfig,[S]),D=useCallback(async a=>{if(a<0||a>=o.steps.length)return false;l({type:"SET_TRANSITIONING",isTransitioning:true});try{return T.current&&T.current(n.currentStepIndex,a,d),l({type:"SET_CURRENT_STEP",stepIndex:a}),l({type:"MARK_STEP_VISITED",stepIndex:a,stepId:o.steps[a].id}),!0}catch(c){return console.error("Step transition failed:",c),o.analytics?.onError&&o.analytics.onError(c,d),false}finally{l({type:"SET_TRANSITIONING",isTransitioning:false});}},[o.steps,n.currentStepIndex,d,o.analytics]),L=useCallback(()=>({setStepData:(a,c)=>{l({type:"SET_STEP_DATA",data:c,stepId:a});},setStepFields:(a,c)=>{let C={...n.allData[a]||{},...c};l({type:"SET_STEP_DATA",data:C,stepId:a});},getStepData:a=>n.allData[a]||{},setNextStepField:(a,c)=>{let v=n.currentStepIndex+1;if(v<o.steps.length){let C=o.steps[v].id,J={...n.allData[C]||{},[a]:c};l({type:"SET_STEP_DATA",data:J,stepId:C});}},setNextStepFields:a=>{let c=n.currentStepIndex+1;if(c<o.steps.length){let v=o.steps[c].id,_={...n.allData[v]||{},...a};l({type:"SET_STEP_DATA",data:_,stepId:v});}},getAllData:()=>({...n.allData}),getSteps:()=>[...o.steps]}),[n.allData,n.currentStepIndex,o.steps]),A=useCallback((a,c)=>{l({type:"SET_FIELD_VALUE",fieldId:a,value:c,stepId:S?.id||""});},[S?.id]),F=useCallback(a=>{l({type:"SET_STEP_DATA",data:a,stepId:S?.id||""});},[S?.id]),W=useCallback(async()=>{if(S?.onAfterValidation)try{let c=L();await S.onAfterValidation(n.stepData,c,d);}catch(c){return console.error("onAfterValidation failed:",c),o.analytics?.onError&&o.analytics.onError(c,d),false}let a=n.currentStepIndex+1;return D(a)},[S,L,n.stepData,d,o.analytics,D,n.currentStepIndex]),B=useCallback(async()=>D(n.currentStepIndex-1),[n.currentStepIndex,D]),b=useCallback(async()=>{l({type:"SET_SUBMITTING",isSubmitting:true});try{if(x.current&&await x.current(n.allData),o.analytics?.onWorkflowComplete){let a=Date.now()-u.current;o.analytics.onWorkflowComplete(o.id,a,n.allData);}}catch(a){throw console.error("Workflow submission failed:",a),o.analytics?.onError&&o.analytics.onError(a,d),a}finally{l({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,x,o.analytics,d]),V=useCallback(async()=>S?.allowSkip?(o.analytics?.onStepSkip&&o.analytics.onStepSkip(S.id,"user_skip",d),d.isLastStep?(await b(),true):W()):false,[S,o.analytics,d,W,b]),M=useCallback(()=>{l({type:"RESET_WORKFLOW"});},[]),z=useMemo(()=>({workflowState:n,workflowConfig:o,currentStep:S,context:d,formConfig:E,goToStep:D,goNext:W,goPrevious:B,skipStep:V,setValue:A,setStepData:F,submitWorkflow:b,resetWorkflow:M}),[n,o,S,d,E,D,W,B,V,A,F,b,M]),q=useCallback(async()=>{await W();},[W]);return jsx($.Provider,{value:z,children:jsx(FormProvider,{formConfig:S?.formConfig,defaultValues:n?.allData[S?.id]||{},onFieldChange:A,"data-workflow-id":o.id,className:f,onSubmit:q,children:i})})}function y(){let i=useContext($);if(!i)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return i}function ce({children:i,workflowConfig:e,...t}){let[r,s]=useState(false),f=h.shouldDisplayWatermark(),n=h.getWatermarkMessage(),l=useMemo(()=>e instanceof I?e.build():e,[e]);return useEffect(()=>{s(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(N,{...t,workflowConfig:l,children:i}),r&&f&&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:n})]})}function Se(){let{currentStep:i}=y();if(!i)return null;let{formConfig:e,renderer:t}=i;return e?t?t(i):jsx(FormBody,{}):null}function ye({className:i,...e}){let{context:t,workflowState:r,workflowConfig:s,currentStep:f}=y(),{submit:n,formState:l}=useFormContext(),u=!r.isTransitioning&&!r.isSubmitting,w=async g=>{g?.preventDefault(),u&&await n(g);},m={isLastStep:t.isLastStep,canGoNext:u,isSubmitting:l.isSubmitting||r.isSubmitting,onSubmit:w,className:i,currentStep:f,stepData:l.values||{},allData:t.allData,context:t};return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:s.renderConfig?.nextButtonRenderer,props:m,...e})}function xe({className:i,...e}){let{context:t,goPrevious:r,workflowState:s,workflowConfig:f,currentStep:n}=y(),{formState:l}=useFormContext(),u=t.currentStepIndex>0&&!s.isTransitioning&&!s.isSubmitting,m={canGoPrevious:u,onPrevious:async g=>{g?.preventDefault(),u&&await r();},className:i,currentStep:n,stepData:l.values||{},allData:t.allData,context:t};return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:f.renderConfig?.previousButtonRenderer,props:m,...e})}function Re({className:i,...e}){let{currentStep:t,skipStep:r,workflowState:s,workflowConfig:f,context:n}=y(),{formState:l}=useFormContext(),u=!!t?.allowSkip&&!s.isTransitioning&&!s.isSubmitting,m={canSkip:u,onSkip:async g=>{g?.preventDefault(),u&&await r();},className:i,currentStep:t,stepData:l.values||{},allData:n.allData,context:n};return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:f.renderConfig?.skipButtonRenderer,props:m,...e})}function Te({onStepClick:i,className:e,...t}){let{workflowConfig:r,workflowState:s,goToStep:f}=y(),n=u=>{i?i(u):f(u);},l={steps:r.steps,currentStepIndex:s.currentStepIndex,visitedSteps:s.visitedSteps,onStepClick:n,className:e};return jsx(ComponentRendererWrapper,{name:"WorkflowStepper",renderer:r.renderConfig?.stepperRenderer,props:l,...t})}
|
|
2
|
+
export{h as RilayLicenseManager,ce as Workflow,Se as WorkflowBody,ye as WorkflowNextButton,xe as WorkflowPreviousButton,N as WorkflowProvider,Re as WorkflowSkipButton,Te as WorkflowStepper,re as createFlow,I as flow,y as useWorkflowContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rilaykit/workflow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Commercial workflow and multi-step form utilities for RilayKit - License required for all use",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@noble/ed25519": "^1.7.1",
|
|
29
|
-
"@rilaykit/core": "
|
|
30
|
-
"@rilaykit/forms": "
|
|
29
|
+
"@rilaykit/core": "5.1.0",
|
|
30
|
+
"@rilaykit/forms": "5.1.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=18.0.0",
|