@rilaykit/workflow 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -34,7 +34,7 @@ bun add @rilaykit/core @rilaykit/forms @rilaykit/workflow
34
34
  ```tsx
35
35
  import { required, email, minLength } from '@rilaykit/core';
36
36
 
37
- const accountForm = rilay.form('account')
37
+ const accountForm = form.create(rilay, 'account')
38
38
  .add({
39
39
  id: 'email',
40
40
  type: 'input',
@@ -48,7 +48,7 @@ const accountForm = rilay.form('account')
48
48
  validation: { validate: [required(), minLength(8)] },
49
49
  });
50
50
 
51
- const profileForm = rilay.form('profile')
51
+ const profileForm = form.create(rilay, 'profile')
52
52
  .add(
53
53
  { id: 'firstName', type: 'input', props: { label: 'First Name' } },
54
54
  { id: 'lastName', type: 'input', props: { label: 'Last Name' } },
@@ -58,16 +58,18 @@ const profileForm = rilay.form('profile')
58
58
  ### 2. Build the Workflow
59
59
 
60
60
  ```tsx
61
+ import { flow } from '@rilaykit/workflow';
61
62
  import { LocalStorageAdapter } from '@rilaykit/workflow';
62
63
 
63
- const onboarding = rilay
64
- .flow('onboarding', 'User Onboarding')
65
- .addStep({
64
+ // Option 1: With explicit ID and name
65
+ const onboarding = flow
66
+ .create(rilay, 'onboarding', 'User Onboarding')
67
+ .step({
66
68
  id: 'account',
67
69
  title: 'Create Account',
68
70
  formConfig: accountForm,
69
71
  })
70
- .addStep({
72
+ .step({
71
73
  id: 'profile',
72
74
  title: 'Your Profile',
73
75
  formConfig: profileForm,
@@ -86,7 +88,14 @@ const onboarding = rilay
86
88
  trackEvent('workflow_complete', { id, totalTime });
87
89
  },
88
90
  },
89
- });
91
+ })
92
+ .build();
93
+
94
+ // Option 2: Auto-generated ID and default name
95
+ const quickWorkflow = flow
96
+ .create(rilay) // ID and name are optional
97
+ .step({ title: 'Step 1', formConfig: accountForm })
98
+ .build();
90
99
  ```
91
100
 
92
101
  ### 3. Render It
@@ -125,13 +134,16 @@ function OnboardingFlow() {
125
134
  Chainable API for defining multi-step flows with step-level configuration.
126
135
 
127
136
  ```tsx
128
- const flow = rilay
129
- .flow('checkout', 'Checkout Flow')
130
- .addStep({ id: 'cart', title: 'Review Cart', formConfig: cartForm })
131
- .addStep({ id: 'shipping', title: 'Shipping', formConfig: shippingForm })
132
- .addStep({ id: 'payment', title: 'Payment', formConfig: paymentForm })
137
+ import { flow } from '@rilaykit/workflow';
138
+
139
+ const checkoutFlow = flow
140
+ .create(rilay, 'checkout', 'Checkout Flow')
141
+ .step({ id: 'cart', title: 'Review Cart', formConfig: cartForm })
142
+ .step({ id: 'shipping', title: 'Shipping', formConfig: shippingForm })
143
+ .step({ id: 'payment', title: 'Payment', formConfig: paymentForm })
133
144
  .configure({ persistence: { ... }, analytics: { ... } })
134
- .use(myPlugin);
145
+ .use(myPlugin)
146
+ .build();
135
147
  ```
136
148
 
137
149
  ### Step Navigation
@@ -139,7 +151,7 @@ const flow = rilay
139
151
  Navigation with validation guards — users can't advance until the current step validates. Steps can be optional with `allowSkip: true`.
140
152
 
141
153
  ```tsx
142
- .addStep({
154
+ .step({
143
155
  id: 'profile',
144
156
  title: 'Your Profile',
145
157
  formConfig: profileForm,
@@ -154,7 +166,7 @@ Use `when('stepId.fieldId')` to reference fields from other steps. Steps can be
154
166
  ```tsx
155
167
  import { when } from '@rilaykit/core';
156
168
 
157
- .addStep({
169
+ .step({
158
170
  id: 'business-details',
159
171
  title: 'Business Details',
160
172
  formConfig: businessForm,
@@ -169,7 +181,7 @@ import { when } from '@rilaykit/core';
169
181
  Use `onAfterValidation` to pre-populate fields in upcoming steps based on current step data.
170
182
 
171
183
  ```tsx
172
- .addStep({
184
+ .step({
173
185
  id: 'account',
174
186
  title: 'Account',
175
187
  formConfig: accountForm,
package/dist/index.d.mts CHANGED
@@ -1,10 +1,68 @@
1
- import { FormConfiguration, CustomStepRenderer, StepConditionalBehavior, StepDataHelper, WorkflowContext, ril, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ConditionalBehavior, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
1
+ import { StepDataHelper, WorkflowContext, FormConfiguration, CustomStepRenderer, StepConditionalBehavior, ril, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ConditionalBehavior, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
2
2
  import { form } from '@rilaykit/forms';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React$1 from 'react';
5
5
  import React__default from 'react';
6
6
  import * as zustand from 'zustand';
7
7
 
8
+ /**
9
+ * Structured metadata for workflow steps
10
+ */
11
+ interface StepMetadata {
12
+ /** Icon identifier (e.g., 'user', 'payment', 'check') */
13
+ icon?: string;
14
+ /** Category for grouping steps */
15
+ category?: string;
16
+ /** Tags for filtering or organization */
17
+ tags?: string[];
18
+ /** Extensible - add any custom metadata */
19
+ [key: string]: any;
20
+ }
21
+ /**
22
+ * Simplified context for step callbacks
23
+ *
24
+ * Replaces the verbose (stepData, helper, context) signature with a single
25
+ * structured object containing everything needed for step logic.
26
+ */
27
+ interface StepContext {
28
+ /** Current step's validated data */
29
+ readonly data: Record<string, any>;
30
+ /** Controls for the next step */
31
+ readonly next: {
32
+ /** Pre-fill fields in the next step */
33
+ prefill(fields: Record<string, any>): void;
34
+ /** Skip the next step */
35
+ skip(): void;
36
+ };
37
+ /** Access to workflow-level data and navigation */
38
+ readonly workflow: {
39
+ /** Get data from a specific step by ID */
40
+ get<T = any>(stepId: string): T;
41
+ /** Get all workflow data across all steps */
42
+ all<T = any>(): T;
43
+ /** Navigate to a specific step by ID */
44
+ goto(stepId: string): void;
45
+ };
46
+ /** Step metadata */
47
+ readonly meta: StepMetadata;
48
+ /** Context flags */
49
+ readonly isFirst: boolean;
50
+ readonly isLast: boolean;
51
+ }
52
+ /**
53
+ * Creates a StepContext from the legacy helper/context system
54
+ *
55
+ * This factory wraps the old (stepData, helper, context) pattern into
56
+ * the new simplified StepContext API.
57
+ *
58
+ * @param stepData - Validated data from the current step
59
+ * @param helper - Legacy StepDataHelper with mutation methods
60
+ * @param workflowContext - Legacy WorkflowContext with workflow state
61
+ * @param metadata - Step metadata
62
+ * @returns Structured StepContext for use in after() callbacks
63
+ */
64
+ declare function createStepContext(stepData: Record<string, any>, helper: StepDataHelper, workflowContext: WorkflowContext, metadata?: StepMetadata): StepContext;
65
+
8
66
  interface WorkflowState {
9
67
  currentStepIndex: number;
10
68
  allData: Record<string, any>;
@@ -211,11 +269,6 @@ interface StepDefinition {
211
269
  * @default false
212
270
  */
213
271
  allowSkip?: boolean;
214
- /**
215
- * Whether this step is required to complete the workflow
216
- * @default true
217
- */
218
- requiredToComplete?: boolean;
219
272
  /**
220
273
  * Custom renderer for the step
221
274
  * Allows complete customization of step presentation
@@ -242,43 +295,54 @@ interface StepDefinition {
242
295
  * metadata: {
243
296
  * icon: 'user-circle',
244
297
  * category: 'personal-info',
245
- * analytics: { trackCompletion: true, priority: 'high' },
246
- * ui: { theme: 'primary', showProgress: true },
247
- * business: { requiresApproval: false, estimatedTime: 120 }
298
+ * tags: ['onboarding', 'required']
248
299
  * }
249
300
  * }
250
301
  * ```
251
302
  */
252
- metadata?: Record<string, any>;
303
+ metadata?: StepMetadata;
253
304
  /**
254
305
  * Callback function that executes after successful validation and before moving to next step
255
- * Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
256
306
  *
257
- * @param stepData - The validated data from the current step
258
- * @param helper - Helper object with methods to modify workflow data cleanly
259
- * @param context - Full workflow context for reference
307
+ * Simplified signature with a single StepContext parameter containing all necessary data and methods.
308
+ *
309
+ * @param step - Structured context with data, next-step controls, and workflow access
260
310
  *
261
311
  * @example
262
312
  * ```typescript
263
- * onAfterValidation: async (stepData, helper, context) => {
264
- * // API call based on current step data
265
- * const companyInfo = await fetchCompanyBySiren(stepData.siren);
266
- *
267
- * // Pre-fill next step with clean helper methods
268
- * helper.setNextStepFields({
269
- * companyName: companyInfo.name,
270
- * address: companyInfo.address,
271
- * industry: companyInfo.sector
272
- * });
273
- *
274
- * // Or set data for a specific step
275
- * helper.setStepFields('company-details', {
276
- * legalForm: companyInfo.legalForm,
277
- * foundedYear: companyInfo.creation_date
278
- * });
313
+ * after: async (step) => {
314
+ * // Access current step data
315
+ * if (step.data.userType === 'business') {
316
+ * // Pre-fill next step
317
+ * step.next.prefill({
318
+ * companyName: '',
319
+ * taxId: ''
320
+ * });
321
+ * }
322
+ *
323
+ * // Access other steps
324
+ * const basics = step.workflow.get('basics');
325
+ *
326
+ * // Navigation
327
+ * if (step.data.skipPayment) {
328
+ * step.next.skip();
329
+ * }
279
330
  * }
280
331
  * ```
281
332
  */
333
+ after?: (step: StepContext) => void | Promise<void>;
334
+ /**
335
+ * Legacy callback function with verbose 3-parameter signature
336
+ *
337
+ * @deprecated Use `after` instead for a simpler, more intuitive API.
338
+ *
339
+ * This callback is called after successful validation and before moving to the next step.
340
+ * The new `after` callback provides the same functionality with a cleaner, single-parameter API.
341
+ *
342
+ * @param stepData - The validated data from the current step
343
+ * @param helper - Helper object with methods to interact with workflow data
344
+ * @param context - Workflow context with navigation state
345
+ */
282
346
  onAfterValidation?: (stepData: Record<string, any>, helper: StepDataHelper, context: WorkflowContext) => void | Promise<void>;
283
347
  }
284
348
  /**
@@ -321,6 +385,7 @@ interface WorkflowOptions {
321
385
  *
322
386
  * @example
323
387
  * ```typescript
388
+ * // With explicit ID and name
324
389
  * const workflow = flow.create(rilConfig, 'user-onboarding', 'User Onboarding')
325
390
  * .addStep({
326
391
  * title: 'Personal Information',
@@ -332,10 +397,14 @@ interface WorkflowOptions {
332
397
  * allowSkip: true
333
398
  * })
334
399
  * .configure({
335
- * navigation: { allowBackNavigation: true },
336
- * persistence: { saveOnStepComplete: true }
400
+ * analytics: { trackStepCompletion: true }
337
401
  * })
338
402
  * .build();
403
+ *
404
+ * // With auto-generated ID and default name
405
+ * const workflow = flow.create(rilConfig)
406
+ * .addStep({ title: 'Step 1', formConfig: step1Form })
407
+ * .build();
339
408
  * ```
340
409
  *
341
410
  * @class flow
@@ -354,11 +423,11 @@ declare class flow {
354
423
  * Creates a new workflow builder instance
355
424
  *
356
425
  * @param config - The ril configuration instance
357
- * @param workflowId - Unique identifier for the workflow
358
- * @param workflowName - Display name for the workflow
426
+ * @param workflowId - Optional unique identifier for the workflow. Auto-generated if not provided
427
+ * @param workflowName - Optional display name for the workflow. Defaults to "Workflow" if not provided
359
428
  * @param description - Optional description of the workflow purpose
360
429
  */
361
- constructor(config: ril<any>, workflowId: string, workflowName: string, description?: string);
430
+ constructor(config: ril<any>, workflowId?: string, workflowName?: string, description?: string);
362
431
  /**
363
432
  * Static factory method to create a new workflow builder
364
433
  *
@@ -368,17 +437,21 @@ declare class flow {
368
437
  * DX Note: Prefer using this factory over `new flow(...)` for clarity and consistency.
369
438
  *
370
439
  * @param config - The ril configuration instance
371
- * @param workflowId - Unique identifier for the workflow
372
- * @param workflowName - Display name for the workflow
440
+ * @param workflowId - Optional unique identifier for the workflow. Auto-generated if not provided
441
+ * @param workflowName - Optional display name for the workflow. Defaults to "Workflow" if not provided
373
442
  * @param description - Optional description of the workflow purpose
374
443
  * @returns A new flow builder instance
375
444
  *
376
445
  * @example
377
446
  * ```typescript
447
+ * // With explicit ID and name
378
448
  * const workflow = flow.create(rilConfig, 'checkout', 'Checkout Process');
449
+ *
450
+ * // With auto-generated ID and default name
451
+ * const workflow = flow.create(rilConfig);
379
452
  * ```
380
453
  */
381
- static create(config: ril<any>, workflowId: string, workflowName: string, description?: string): flow;
454
+ static create(config: ril<any>, workflowId?: string, workflowName?: string, description?: string): flow;
382
455
  /**
383
456
  * Helper method to create a step configuration from StepDefinition
384
457
  *
@@ -391,6 +464,11 @@ declare class flow {
391
464
  * @returns A complete StepConfig object
392
465
  */
393
466
  private createStepFromDefinition;
467
+ /**
468
+ * Internal method to add steps - shared implementation for addStep() and step()
469
+ * @private
470
+ */
471
+ private _addStepsInternal;
394
472
  /**
395
473
  * Universal add method - handles single steps or multiple steps
396
474
  *
@@ -398,6 +476,8 @@ declare class flow {
398
476
  * It can handle both single step definitions and arrays of step definitions,
399
477
  * making it easy to build workflows programmatically.
400
478
  *
479
+ * **Note:** A shorter alias `.step()` is available for the same functionality.
480
+ *
401
481
  * @param stepDefinition - Single step definition
402
482
  * @returns The flow instance for method chaining
403
483
  *
@@ -406,6 +486,16 @@ declare class flow {
406
486
  * // Add a single step
407
487
  * workflow.addStep({
408
488
  * title: 'User Details',
489
+ * formConfig: userForm,
490
+ * after: async (step) => {
491
+ * // New simplified callback signature
492
+ * step.next.prefill({ field: 'value' });
493
+ * }
494
+ * });
495
+ *
496
+ * // Or use the shorter .step() alias
497
+ * workflow.step({
498
+ * title: 'User Details',
409
499
  * formConfig: userForm
410
500
  * });
411
501
  * ```
@@ -414,6 +504,8 @@ declare class flow {
414
504
  /**
415
505
  * Universal add method - handles single steps or multiple steps
416
506
  *
507
+ * **Note:** A shorter alias `.step()` is available for the same functionality.
508
+ *
417
509
  * @param stepDefinitions - Array of step definitions
418
510
  * @returns The flow instance for method chaining
419
511
  *
@@ -427,6 +519,34 @@ declare class flow {
427
519
  * ```
428
520
  */
429
521
  addStep(stepDefinitions: StepDefinition[]): this;
522
+ /**
523
+ * Alias for addStep() - provides a shorter, more concise API
524
+ *
525
+ * This method is functionally identical to addStep() and exists purely
526
+ * for developer experience. Use whichever you prefer - both are fully supported.
527
+ *
528
+ * @param input - Single step definition or array of step definitions
529
+ * @returns The flow instance for method chaining
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * // Using the concise .step() alias
534
+ * workflow.step({
535
+ * title: 'User Details',
536
+ * formConfig: userForm,
537
+ * after: async (step) => {
538
+ * step.next.prefill({ companyName: '' });
539
+ * }
540
+ * });
541
+ *
542
+ * // Also supports arrays (same as addStep)
543
+ * workflow.step([
544
+ * { title: 'Step 1', formConfig: form1 },
545
+ * { title: 'Step 2', formConfig: form2 }
546
+ * ]);
547
+ * ```
548
+ */
549
+ step(input: StepDefinition | StepDefinition[]): this;
430
550
  /**
431
551
  * Universal configuration method for all workflow options
432
552
  *
@@ -1336,4 +1456,4 @@ declare function flattenObject(obj: Record<string, any>, prefix?: string): Recor
1336
1456
  */
1337
1457
  declare function combineWorkflowDataForConditions(allData: Record<string, any>, stepData: Record<string, any>): Record<string, any>;
1338
1458
 
1339
- export { type CreateWorkflowStoreOptions, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowActionsResult, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, type WorkflowStore, WorkflowStoreContext, type WorkflowStoreState, combineWorkflowDataForConditions, createWorkflowStore, debounce, flattenObject, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useCurrentStepIndex, useIsStepPassed, useIsStepVisited, usePassedSteps, usePersistence, useStepDataById, useStepMetadata, useVisitedSteps, useWorkflowActions, useWorkflowAllData, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowInitializing, useWorkflowNavigation, useWorkflowNavigationState, useWorkflowState, useWorkflowStepData, useWorkflowStore, useWorkflowStoreApi, useWorkflowSubmission, useWorkflowSubmitState, useWorkflowSubmitting, useWorkflowTransitioning, validatePersistedData, workflowStateToPersisted };
1459
+ export { type CreateWorkflowStoreOptions, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, type StepContext, type StepDefinition, type StepMetadata, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowActionsResult, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, type WorkflowStore, WorkflowStoreContext, type WorkflowStoreState, combineWorkflowDataForConditions, createStepContext, createWorkflowStore, debounce, flattenObject, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useCurrentStepIndex, useIsStepPassed, useIsStepVisited, usePassedSteps, usePersistence, useStepDataById, useStepMetadata, useVisitedSteps, useWorkflowActions, useWorkflowAllData, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowInitializing, useWorkflowNavigation, useWorkflowNavigationState, useWorkflowState, useWorkflowStepData, useWorkflowStore, useWorkflowStoreApi, useWorkflowSubmission, useWorkflowSubmitState, useWorkflowSubmitting, useWorkflowTransitioning, validatePersistedData, workflowStateToPersisted };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,68 @@
1
- import { FormConfiguration, CustomStepRenderer, StepConditionalBehavior, StepDataHelper, WorkflowContext, ril, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ConditionalBehavior, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
1
+ import { StepDataHelper, WorkflowContext, FormConfiguration, CustomStepRenderer, StepConditionalBehavior, ril, WorkflowAnalytics, WorkflowPlugin, StepConfig, WorkflowConfig, ConditionalBehavior, ComponentRendererBaseProps, WorkflowNextButtonRendererProps, WorkflowPreviousButtonRendererProps, WorkflowSkipButtonRendererProps, WorkflowStepperRendererProps } from '@rilaykit/core';
2
2
  import { form } from '@rilaykit/forms';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React$1 from 'react';
5
5
  import React__default from 'react';
6
6
  import * as zustand from 'zustand';
7
7
 
8
+ /**
9
+ * Structured metadata for workflow steps
10
+ */
11
+ interface StepMetadata {
12
+ /** Icon identifier (e.g., 'user', 'payment', 'check') */
13
+ icon?: string;
14
+ /** Category for grouping steps */
15
+ category?: string;
16
+ /** Tags for filtering or organization */
17
+ tags?: string[];
18
+ /** Extensible - add any custom metadata */
19
+ [key: string]: any;
20
+ }
21
+ /**
22
+ * Simplified context for step callbacks
23
+ *
24
+ * Replaces the verbose (stepData, helper, context) signature with a single
25
+ * structured object containing everything needed for step logic.
26
+ */
27
+ interface StepContext {
28
+ /** Current step's validated data */
29
+ readonly data: Record<string, any>;
30
+ /** Controls for the next step */
31
+ readonly next: {
32
+ /** Pre-fill fields in the next step */
33
+ prefill(fields: Record<string, any>): void;
34
+ /** Skip the next step */
35
+ skip(): void;
36
+ };
37
+ /** Access to workflow-level data and navigation */
38
+ readonly workflow: {
39
+ /** Get data from a specific step by ID */
40
+ get<T = any>(stepId: string): T;
41
+ /** Get all workflow data across all steps */
42
+ all<T = any>(): T;
43
+ /** Navigate to a specific step by ID */
44
+ goto(stepId: string): void;
45
+ };
46
+ /** Step metadata */
47
+ readonly meta: StepMetadata;
48
+ /** Context flags */
49
+ readonly isFirst: boolean;
50
+ readonly isLast: boolean;
51
+ }
52
+ /**
53
+ * Creates a StepContext from the legacy helper/context system
54
+ *
55
+ * This factory wraps the old (stepData, helper, context) pattern into
56
+ * the new simplified StepContext API.
57
+ *
58
+ * @param stepData - Validated data from the current step
59
+ * @param helper - Legacy StepDataHelper with mutation methods
60
+ * @param workflowContext - Legacy WorkflowContext with workflow state
61
+ * @param metadata - Step metadata
62
+ * @returns Structured StepContext for use in after() callbacks
63
+ */
64
+ declare function createStepContext(stepData: Record<string, any>, helper: StepDataHelper, workflowContext: WorkflowContext, metadata?: StepMetadata): StepContext;
65
+
8
66
  interface WorkflowState {
9
67
  currentStepIndex: number;
10
68
  allData: Record<string, any>;
@@ -211,11 +269,6 @@ interface StepDefinition {
211
269
  * @default false
212
270
  */
213
271
  allowSkip?: boolean;
214
- /**
215
- * Whether this step is required to complete the workflow
216
- * @default true
217
- */
218
- requiredToComplete?: boolean;
219
272
  /**
220
273
  * Custom renderer for the step
221
274
  * Allows complete customization of step presentation
@@ -242,43 +295,54 @@ interface StepDefinition {
242
295
  * metadata: {
243
296
  * icon: 'user-circle',
244
297
  * category: 'personal-info',
245
- * analytics: { trackCompletion: true, priority: 'high' },
246
- * ui: { theme: 'primary', showProgress: true },
247
- * business: { requiresApproval: false, estimatedTime: 120 }
298
+ * tags: ['onboarding', 'required']
248
299
  * }
249
300
  * }
250
301
  * ```
251
302
  */
252
- metadata?: Record<string, any>;
303
+ metadata?: StepMetadata;
253
304
  /**
254
305
  * Callback function that executes after successful validation and before moving to next step
255
- * Provides clean helper methods for modifying workflow data and pre-filling subsequent steps
256
306
  *
257
- * @param stepData - The validated data from the current step
258
- * @param helper - Helper object with methods to modify workflow data cleanly
259
- * @param context - Full workflow context for reference
307
+ * Simplified signature with a single StepContext parameter containing all necessary data and methods.
308
+ *
309
+ * @param step - Structured context with data, next-step controls, and workflow access
260
310
  *
261
311
  * @example
262
312
  * ```typescript
263
- * onAfterValidation: async (stepData, helper, context) => {
264
- * // API call based on current step data
265
- * const companyInfo = await fetchCompanyBySiren(stepData.siren);
266
- *
267
- * // Pre-fill next step with clean helper methods
268
- * helper.setNextStepFields({
269
- * companyName: companyInfo.name,
270
- * address: companyInfo.address,
271
- * industry: companyInfo.sector
272
- * });
273
- *
274
- * // Or set data for a specific step
275
- * helper.setStepFields('company-details', {
276
- * legalForm: companyInfo.legalForm,
277
- * foundedYear: companyInfo.creation_date
278
- * });
313
+ * after: async (step) => {
314
+ * // Access current step data
315
+ * if (step.data.userType === 'business') {
316
+ * // Pre-fill next step
317
+ * step.next.prefill({
318
+ * companyName: '',
319
+ * taxId: ''
320
+ * });
321
+ * }
322
+ *
323
+ * // Access other steps
324
+ * const basics = step.workflow.get('basics');
325
+ *
326
+ * // Navigation
327
+ * if (step.data.skipPayment) {
328
+ * step.next.skip();
329
+ * }
279
330
  * }
280
331
  * ```
281
332
  */
333
+ after?: (step: StepContext) => void | Promise<void>;
334
+ /**
335
+ * Legacy callback function with verbose 3-parameter signature
336
+ *
337
+ * @deprecated Use `after` instead for a simpler, more intuitive API.
338
+ *
339
+ * This callback is called after successful validation and before moving to the next step.
340
+ * The new `after` callback provides the same functionality with a cleaner, single-parameter API.
341
+ *
342
+ * @param stepData - The validated data from the current step
343
+ * @param helper - Helper object with methods to interact with workflow data
344
+ * @param context - Workflow context with navigation state
345
+ */
282
346
  onAfterValidation?: (stepData: Record<string, any>, helper: StepDataHelper, context: WorkflowContext) => void | Promise<void>;
283
347
  }
284
348
  /**
@@ -321,6 +385,7 @@ interface WorkflowOptions {
321
385
  *
322
386
  * @example
323
387
  * ```typescript
388
+ * // With explicit ID and name
324
389
  * const workflow = flow.create(rilConfig, 'user-onboarding', 'User Onboarding')
325
390
  * .addStep({
326
391
  * title: 'Personal Information',
@@ -332,10 +397,14 @@ interface WorkflowOptions {
332
397
  * allowSkip: true
333
398
  * })
334
399
  * .configure({
335
- * navigation: { allowBackNavigation: true },
336
- * persistence: { saveOnStepComplete: true }
400
+ * analytics: { trackStepCompletion: true }
337
401
  * })
338
402
  * .build();
403
+ *
404
+ * // With auto-generated ID and default name
405
+ * const workflow = flow.create(rilConfig)
406
+ * .addStep({ title: 'Step 1', formConfig: step1Form })
407
+ * .build();
339
408
  * ```
340
409
  *
341
410
  * @class flow
@@ -354,11 +423,11 @@ declare class flow {
354
423
  * Creates a new workflow builder instance
355
424
  *
356
425
  * @param config - The ril configuration instance
357
- * @param workflowId - Unique identifier for the workflow
358
- * @param workflowName - Display name for the workflow
426
+ * @param workflowId - Optional unique identifier for the workflow. Auto-generated if not provided
427
+ * @param workflowName - Optional display name for the workflow. Defaults to "Workflow" if not provided
359
428
  * @param description - Optional description of the workflow purpose
360
429
  */
361
- constructor(config: ril<any>, workflowId: string, workflowName: string, description?: string);
430
+ constructor(config: ril<any>, workflowId?: string, workflowName?: string, description?: string);
362
431
  /**
363
432
  * Static factory method to create a new workflow builder
364
433
  *
@@ -368,17 +437,21 @@ declare class flow {
368
437
  * DX Note: Prefer using this factory over `new flow(...)` for clarity and consistency.
369
438
  *
370
439
  * @param config - The ril configuration instance
371
- * @param workflowId - Unique identifier for the workflow
372
- * @param workflowName - Display name for the workflow
440
+ * @param workflowId - Optional unique identifier for the workflow. Auto-generated if not provided
441
+ * @param workflowName - Optional display name for the workflow. Defaults to "Workflow" if not provided
373
442
  * @param description - Optional description of the workflow purpose
374
443
  * @returns A new flow builder instance
375
444
  *
376
445
  * @example
377
446
  * ```typescript
447
+ * // With explicit ID and name
378
448
  * const workflow = flow.create(rilConfig, 'checkout', 'Checkout Process');
449
+ *
450
+ * // With auto-generated ID and default name
451
+ * const workflow = flow.create(rilConfig);
379
452
  * ```
380
453
  */
381
- static create(config: ril<any>, workflowId: string, workflowName: string, description?: string): flow;
454
+ static create(config: ril<any>, workflowId?: string, workflowName?: string, description?: string): flow;
382
455
  /**
383
456
  * Helper method to create a step configuration from StepDefinition
384
457
  *
@@ -391,6 +464,11 @@ declare class flow {
391
464
  * @returns A complete StepConfig object
392
465
  */
393
466
  private createStepFromDefinition;
467
+ /**
468
+ * Internal method to add steps - shared implementation for addStep() and step()
469
+ * @private
470
+ */
471
+ private _addStepsInternal;
394
472
  /**
395
473
  * Universal add method - handles single steps or multiple steps
396
474
  *
@@ -398,6 +476,8 @@ declare class flow {
398
476
  * It can handle both single step definitions and arrays of step definitions,
399
477
  * making it easy to build workflows programmatically.
400
478
  *
479
+ * **Note:** A shorter alias `.step()` is available for the same functionality.
480
+ *
401
481
  * @param stepDefinition - Single step definition
402
482
  * @returns The flow instance for method chaining
403
483
  *
@@ -406,6 +486,16 @@ declare class flow {
406
486
  * // Add a single step
407
487
  * workflow.addStep({
408
488
  * title: 'User Details',
489
+ * formConfig: userForm,
490
+ * after: async (step) => {
491
+ * // New simplified callback signature
492
+ * step.next.prefill({ field: 'value' });
493
+ * }
494
+ * });
495
+ *
496
+ * // Or use the shorter .step() alias
497
+ * workflow.step({
498
+ * title: 'User Details',
409
499
  * formConfig: userForm
410
500
  * });
411
501
  * ```
@@ -414,6 +504,8 @@ declare class flow {
414
504
  /**
415
505
  * Universal add method - handles single steps or multiple steps
416
506
  *
507
+ * **Note:** A shorter alias `.step()` is available for the same functionality.
508
+ *
417
509
  * @param stepDefinitions - Array of step definitions
418
510
  * @returns The flow instance for method chaining
419
511
  *
@@ -427,6 +519,34 @@ declare class flow {
427
519
  * ```
428
520
  */
429
521
  addStep(stepDefinitions: StepDefinition[]): this;
522
+ /**
523
+ * Alias for addStep() - provides a shorter, more concise API
524
+ *
525
+ * This method is functionally identical to addStep() and exists purely
526
+ * for developer experience. Use whichever you prefer - both are fully supported.
527
+ *
528
+ * @param input - Single step definition or array of step definitions
529
+ * @returns The flow instance for method chaining
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * // Using the concise .step() alias
534
+ * workflow.step({
535
+ * title: 'User Details',
536
+ * formConfig: userForm,
537
+ * after: async (step) => {
538
+ * step.next.prefill({ companyName: '' });
539
+ * }
540
+ * });
541
+ *
542
+ * // Also supports arrays (same as addStep)
543
+ * workflow.step([
544
+ * { title: 'Step 1', formConfig: form1 },
545
+ * { title: 'Step 2', formConfig: form2 }
546
+ * ]);
547
+ * ```
548
+ */
549
+ step(input: StepDefinition | StepDefinition[]): this;
430
550
  /**
431
551
  * Universal configuration method for all workflow options
432
552
  *
@@ -1336,4 +1456,4 @@ declare function flattenObject(obj: Record<string, any>, prefix?: string): Recor
1336
1456
  */
1337
1457
  declare function combineWorkflowDataForConditions(allData: Record<string, any>, stepData: Record<string, any>): Record<string, any>;
1338
1458
 
1339
- export { type CreateWorkflowStoreOptions, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, type StepDefinition, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowActionsResult, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, type WorkflowStore, WorkflowStoreContext, type WorkflowStoreState, combineWorkflowDataForConditions, createWorkflowStore, debounce, flattenObject, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useCurrentStepIndex, useIsStepPassed, useIsStepVisited, usePassedSteps, usePersistence, useStepDataById, useStepMetadata, useVisitedSteps, useWorkflowActions, useWorkflowAllData, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowInitializing, useWorkflowNavigation, useWorkflowNavigationState, useWorkflowState, useWorkflowStepData, useWorkflowStore, useWorkflowStoreApi, useWorkflowSubmission, useWorkflowSubmitState, useWorkflowSubmitting, useWorkflowTransitioning, validatePersistedData, workflowStateToPersisted };
1459
+ export { type CreateWorkflowStoreOptions, LocalStorageAdapter, type LocalStorageAdapterConfig, type PersistedWorkflowData, type PersistenceOptions, type StepContext, type StepDefinition, type StepMetadata, type UsePersistenceProps, type UsePersistenceReturn, type UseWorkflowActionsResult, Workflow, WorkflowBody, type WorkflowContextValue, WorkflowNextButton, type WorkflowPersistenceAdapter, WorkflowPersistenceError, WorkflowPreviousButton, WorkflowProvider, WorkflowSkipButton, WorkflowStepper, type WorkflowStore, WorkflowStoreContext, type WorkflowStoreState, combineWorkflowDataForConditions, createStepContext, createWorkflowStore, debounce, flattenObject, flow, generateStorageKey, mergePersistedState, persistedToWorkflowState, useConditionEvaluation, useCurrentStepIndex, useIsStepPassed, useIsStepVisited, usePassedSteps, usePersistence, useStepDataById, useStepMetadata, useVisitedSteps, useWorkflowActions, useWorkflowAllData, useWorkflowAnalytics, useWorkflowConditions, useWorkflowContext, useWorkflowInitializing, useWorkflowNavigation, useWorkflowNavigationState, useWorkflowState, useWorkflowStepData, useWorkflowStore, useWorkflowStoreApi, useWorkflowSubmission, useWorkflowSubmitState, useWorkflowSubmitting, useWorkflowTransitioning, validatePersistedData, workflowStateToPersisted };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),Tt=require('react'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Tt__default=/*#__PURE__*/_interopDefault(Tt);var H=class t{constructor(e,r,n,i){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=r,this.workflowName=n,this.workflowDescription=i;}static create(e,r,n,i){return new t(e,r,n,i)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:e.onAfterValidation}}addStep(e){let r=core.normalizeToArray(e);for(let n of r){let i=this.createStepFromDefinition(n);this.steps.push(i);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(n=>!this.plugins.some(i=>i.name===n));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 n=this.steps.findIndex(i=>i.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[n]={...this.steps[n],...r},this}addStepConditions(e,r){let n=this.steps.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);let i={...this.steps[n].conditions,...r};return this.steps[n]={...this.steps[n],conditions:i},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 n=new t(this.config,e||`${this.workflowId}-clone`,r||this.workflowName);return n.steps=core.deepClone(this.steps),n.analytics=this.analytics?core.deepClone(this.analytics):void 0,n.persistenceConfig=this.persistenceConfig?core.deepClone(this.persistenceConfig):void 0,n.plugins=[...this.plugins],n}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let r=this.steps.map(n=>n.id);try{core.ensureUnique(r,"step");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of this.plugins)if(n.dependencies){let i=n.dependencies.filter(s=>!this.plugins.some(d=>d.name===s));i.length>0&&e.push(`Plugin "${n.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((n,i)=>n+i.formConfig.allFields.length,0),r=this.steps.map(n=>n.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function ue(t,e={},r={}){return Tt.useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let n=i=>{try{let s;return i&&typeof i=="object"&&"build"in i?s=i.build():s=i,core.evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:t.visible?n(t.visible):true,disabled:t.disabled?n(t.disabled):false,required:t.required?n(t.required):false,readonly:t.readonly?n(t.readonly):false}},[t,e,r])}function Oe(t,e={}){return Tt.useMemo(()=>{let r={};for(let[n,i]of Object.entries(t))if(r[n]={visible:true,disabled:false,required:false,readonly:false},i){let s=d=>{try{return d&&typeof d=="object"&&"build"in d?core.evaluateCondition(d.build(),e):core.evaluateCondition(d,e)}catch(o){return console.warn(`Error evaluating condition for field ${n}:`,o),false}};r[n]={visible:i.visible?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[t,e])}function Le(t,e={}){return Tt.useMemo(()=>{let r={};for(let[n,i]of Object.entries(t)){let s=Number.parseInt(n,10);if(r[s]={visible:true,disabled:false,required:false,readonly:false},i){let d=o=>{try{return o&&typeof o=="object"&&"build"in o?core.evaluateCondition(o.build(),e):core.evaluateCondition(o,e)}catch(f){return console.warn(`Error evaluating condition for step ${s}:`,f),false}};r[s]={visible:i.visible?d(i.visible):true,disabled:i.disabled?d(i.disabled):false,required:i.required?d(i.required):false,readonly:i.readonly?d(i.readonly):false};}}return r},[t,e])}var R=class extends Error{constructor(r,n,i){super(`[WorkflowPersistence] ${r} (Code: ${n})`);this.code=n;this.cause=i;this.name="WorkflowPersistenceError";}};function ce(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),passedSteps:Array.from(e.passedSteps),lastSaved:Date.now(),metadata:r}}function Ue(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),passedSteps:new Set(t.passedSteps||[]),isSubmitting:false,isTransitioning:false}}function at(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function fe(t,e){return e?`${e}:${t}`:t}function Se(t,e){let r=null;return (...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...n);},e);}}function lt(t,e,r="persist"){let n=Ue(e);switch(r){case "persist":return {...n,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...n.visitedSteps]),passedSteps:new Set([...t.passedSteps,...n.passedSteps||[]])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...n.allData,...t.allData},stepData:{...n.stepData,...t.stepData},visitedSteps:new Set([...n.visitedSteps,...t.visitedSteps]),passedSteps:new Set([...n.passedSteps||[],...t.passedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return n}}function q({workflowId:t,workflowState:e,adapter:r,options:n={},userId:i}){let[s,d]=Tt.useState(false),[o,f]=Tt.useState(null),[u,b]=Tt.useState(false),c=Tt.useRef(r),l=Tt.useRef(n),a=Tt.useRef({hasPendingChanges:false});Tt.useEffect(()=>{c.current=r,l.current=n;},[r,n]);let y=fe(l.current.storageKey||t,i),k=Tt.useCallback(()=>{f(null);},[]),P=Tt.useCallback((p,W)=>{let V=p instanceof R?p:new R(`${W} failed: ${p.message}`,"OPERATION_FAILED",p);f(V),console.error("[WorkflowPersistence]",V);},[]),D=Tt.useCallback(async p=>{k(),d(true);try{let W=ce(t,p,l.current.metadata);await c.current.save(y,W),a.current.lastSavedState={...p},a.current.hasPendingChanges=!1;}catch(W){throw P(W,"Save"),W}finally{d(false);}},[t,y,k,P]),x=Tt.useRef(Se(async p=>{try{await D(p);}catch(W){console.debug("[WorkflowPersistence] Auto-save failed:",W);}},n.debounceMs||500)),h=Tt.useCallback((p,W)=>W?p.currentStepIndex!==W.currentStepIndex||JSON.stringify(p.allData)!==JSON.stringify(W.allData)||JSON.stringify(p.stepData)!==JSON.stringify(W.stepData)||p.visitedSteps.size!==W.visitedSteps.size||!Array.from(p.visitedSteps).every(V=>W.visitedSteps.has(V)):true,[]),S=Tt.useCallback(async()=>{k(),b(true);try{let p=await c.current.load(y);return p&&(a.current.lastSavedState={currentStepIndex:p.currentStepIndex,allData:p.allData,stepData:p.stepData,visitedSteps:new Set(p.visitedSteps),passedSteps:new Set(p.passedSteps||[]),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},a.current.hasPendingChanges=!1),p}catch(p){return P(p,"Load"),null}finally{setTimeout(()=>b(false),100);}},[y,k,P]),I=Tt.useCallback(async()=>{k();try{await c.current.remove(y),a.current.lastSavedState=void 0,a.current.hasPendingChanges=!1;}catch(p){throw P(p,"Clear"),p}},[y,k,P]),L=Tt.useCallback(async()=>{try{return await c.current.exists(y)}catch(p){return P(p,"Exists check"),false}},[y,P]);Tt.useEffect(()=>{l.current.autoPersist&&(s||u||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,a.current.lastSavedState)&&(a.current.hasPendingChanges=true,x.current(e)));},[e,s,u,h]);let m=Tt.useCallback(async()=>{await D(e);},[D,e]);return {isPersisting:s,persistenceError:o,persistNow:m,loadPersistedData:S,clearPersistedData:I,hasPersistedData:L}}function pt(){let{workflowConfig:t,currentStep:e}=N(),r=Tt.useMemo(()=>e?.metadata,[e?.metadata]),n=Tt.useMemo(()=>u=>t.steps.find(c=>c.id===u)?.metadata,[t.steps]),i=Tt.useMemo(()=>u=>t.steps[u]?.metadata,[t.steps]),s=Tt.useMemo(()=>u=>r?u in r:false,[r]),d=Tt.useMemo(()=>(u,b)=>r&&u in r?r[u]:b,[r]),o=Tt.useMemo(()=>()=>t.steps.map((u,b)=>({id:u.id,title:u.title,index:b,metadata:u.metadata})),[t.steps]),f=Tt.useMemo(()=>u=>t.steps.map((b,c)=>({step:b,index:c})).filter(({step:b,index:c})=>u(b.metadata,b.id,c)).map(({step:b})=>b.id),[t.steps]);return {current:r,getByStepId:n,getByStepIndex:i,hasCurrentKey:s,getCurrentValue:d,getAllStepsMetadata:o,findStepsByMetadata:f}}function ge({workflowConfig:t,workflowState:e,workflowContext:r}){let n=Tt.useRef(Date.now()),i=Tt.useRef(new Map),s=Tt.useRef(false),d=Tt.useRef(null),o=core.getGlobalMonitor();Tt.useEffect(()=>{t.analytics?.onWorkflowStart&&!s.current&&(s.current=true,t.analytics.onWorkflowStart(t.id,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"start",totalSteps:t.steps.length},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:0,navigationDuration:0,conditionEvaluationDuration:0},"low"));},[t.id,t.analytics,r,o,t.steps.length]),Tt.useEffect(()=>{let l=t.steps[e.currentStepIndex];if(l&&d.current!==l.id){if(d.current&&t.analytics?.onStepComplete){let a=i.current.get(d.current);if(a){let y=Date.now()-a;t.analytics.onStepComplete(d.current,y,e.stepData,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_complete",stepId:d.current,duration:y},{timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:y,conditionEvaluationDuration:0},"low");}}d.current=l.id,i.current.set(l.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(l.id,Date.now(),r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_start",stepId:l.id,stepIndex:e.currentStepIndex},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:0},"low");}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData,o,t.id]);let f=Tt.useCallback((l,a)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(l,a,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_skip",stepId:l,reason:a},void 0,"medium");},[t.analytics,r,o,t.id]),u=Tt.useCallback(l=>{t.analytics?.onError&&t.analytics.onError(l,r),o&&o.trackError(l,`workflow_${t.id}`,{workflowId:t.id,currentStepIndex:e.currentStepIndex,currentStepId:t.steps[e.currentStepIndex]?.id,workflowContext:r});},[t.analytics,r,o,t.id,e.currentStepIndex,t.steps]),b=Tt.useCallback((l,a,y)=>{if(!o)return;let k={timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:a,navigationDuration:y,conditionEvaluationDuration:0};o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"navigation",fromStep:l,toStep:a,direction:a>l?"forward":"backward"},k,y>1e3?"medium":"low");},[o,t.id,t.steps.length]),c=Tt.useCallback((l,a)=>{if(!o)return;let y={timestamp:Date.now(),duration:l,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:l};o.track("condition_evaluation",`workflow_${t.id}`,{workflowId:t.id,conditionsCount:a,currentStepIndex:e.currentStepIndex},y,l>100?"medium":"low");},[o,t.id,t.steps.length,e.currentStepIndex]);return {analyticsStartTime:n,trackStepSkip:f,trackError:u,trackNavigation:b,trackConditionEvaluation:c}}function se(t,e=""){let r={};for(let n in t)if(n in t){let i=t[n],s=e?`${e}.${n}`:n;i!==null&&typeof i=="object"&&!Array.isArray(i)&&!(i instanceof Date)?Object.assign(r,se(i,s)):r[s]=i;}return r}function be(t,e){let r=se(t),n=se(e);return {...{...t,...e},...r,...n}}function $e(t,e){return {visible:t.visible,skippable:e===true||t.required}}function ye({workflowConfig:t,workflowState:e,currentStep:r}){let n=Tt.useMemo(()=>be(e.allData,e.stepData),[e.allData,e.stepData]),i=Tt.useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),s=ue(i,n,{visible:true,disabled:false,required:false,readonly:false}),d=Tt.useMemo(()=>$e(s,r?.allowSkip),[s,r?.allowSkip]),o=Tt.useMemo(()=>{let x={};return t.steps.forEach((h,S)=>{h.conditions&&(x[S]={visible:h.conditions.visible,required:h.conditions.skippable});}),x},[t.steps]),f=Le(o,n),u=Tt.useMemo(()=>{let x={};return t.steps.forEach((h,S)=>{let I=f[S];I?x[S]=$e(I,h.allowSkip):x[S]={visible:true,skippable:h.allowSkip===true};}),x},[t.steps,f]),b=Tt.useMemo(()=>{if(!r?.formConfig?.allFields)return {};let x={};for(let h of r.formConfig.allFields)h.conditions&&(x[h.id]=h.conditions);return x},[r?.formConfig?.allFields]),c=Oe(b,n),l=Tt.useCallback(x=>x<0||x>=t.steps.length?false:u[x]?.visible??true,[u,t.steps.length]),a=Tt.useCallback(x=>x<0||x>=t.steps.length?false:u[x]?.skippable??false,[u,t.steps.length]),y=Tt.useCallback(x=>c[x]?.visible??true,[c]),k=Tt.useCallback(x=>c[x]?.disabled??false,[c]),P=Tt.useCallback(x=>c[x]?.required??false,[c]),D=Tt.useCallback(x=>c[x]?.readonly??false,[c]);return {stepConditions:d,fieldConditions:c,allStepConditions:u,isStepVisible:l,isStepSkippable:a,isFieldVisible:y,isFieldDisabled:k,isFieldRequired:P,isFieldReadonly:D}}function ve({workflowConfig:t,workflowState:e,workflowContext:r,conditionsHelpers:n,setCurrentStep:i,setTransitioning:s,markStepVisited:d,markStepPassed:o,setStepData:f,onStepChange:u}){let b=Tt.useRef(u);b.current=u;let c=t.steps[e.currentStepIndex],l=Tt.useCallback(()=>({setStepData:(m,p)=>{f(p,m);},setStepFields:(m,p)=>{let V={...e.allData[m]||{},...p};f(V,m);},getStepData:m=>e.allData[m]||{},setNextStepField:(m,p)=>{let W=e.currentStepIndex+1;if(W<t.steps.length){let V=t.steps[W].id,X={...e.allData[V]||{},[m]:p};f(X,V);}},setNextStepFields:m=>{let p=e.currentStepIndex+1;if(p<t.steps.length){let W=t.steps[p].id,z={...e.allData[W]||{},...m};f(z,W);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,f]),a=Tt.useCallback(async m=>{if(m<0||m>=t.steps.length||!n.isStepVisible(m))return false;s(true);try{return b.current&&b.current(e.currentStepIndex,m,r),i(m),d(m,t.steps[m].id),!0}catch(p){return console.error("Step transition failed:",p),t.analytics?.onError&&t.analytics.onError(p,r),false}finally{s(false);}},[t.steps,t.analytics,n,e.currentStepIndex,r,s,i,d]),y=Tt.useCallback(m=>{for(let p=m+1;p<t.steps.length;p++)if(n.isStepVisible(p))return p;return null},[t.steps.length,n]),k=Tt.useCallback(m=>{for(let p=m-1;p>=0;p--)if(n.isStepVisible(p))return p;return null},[n]),P=Tt.useCallback(async()=>{if(c?.onAfterValidation)try{let p=l();await c.onAfterValidation(e.stepData,p,r);}catch(p){return console.error("onAfterValidation failed:",p),t.analytics?.onError&&t.analytics.onError(p,r),false}o(c.id);let m=y(e.currentStepIndex);return m===null?false:a(m)},[c,l,e.stepData,r,t.analytics,e.currentStepIndex,y,a,o]),D=Tt.useCallback(async()=>{let m=k(e.currentStepIndex);return m===null?false:a(m)},[e.currentStepIndex,k,a]),x=Tt.useCallback(async()=>!c?.allowSkip&&!n.isStepSkippable(e.currentStepIndex)?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(c.id,"user_skip",r),P()),[c,n,e.currentStepIndex,t.analytics,r,P]),h=Tt.useCallback(m=>m<0||m>=t.steps.length?false:n.isStepVisible(m),[t.steps.length,n]),S=Tt.useCallback(()=>{let m=y(e.currentStepIndex);return m!==null&&h(m)},[e.currentStepIndex,y,h]),I=Tt.useCallback(()=>{let m=k(e.currentStepIndex);return m!==null&&h(m)},[e.currentStepIndex,k,h]),L=Tt.useCallback(()=>c?.allowSkip===true&&n.isStepSkippable(e.currentStepIndex),[c?.allowSkip,n,e.currentStepIndex]);return {goToStep:a,goNext:P,goPrevious:D,skipStep:x,canGoToStep:h,canGoNext:S,canGoPrevious:I,canSkipCurrentStep:L}}function ft(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.visitedSteps,e.stepId])};case "MARK_STEP_PASSED":return {...t,passedSteps:new Set([...t.passedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function St({defaultValues:t={},defaultStepIndex:e,workflowSteps:r,persistence:n}){let i=Tt.useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let I=0;I<e;I++)r[I]&&S.add(r[I].id);return S},[e,r]),s=Tt.useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let I=0;I<e;I++)r[I]&&S.add(r[I].id);return S},[e,r]),d={currentStepIndex:e??0,allData:t,stepData:{},visitedSteps:i,passedSteps:s,isSubmitting:false,isTransitioning:false,isInitializing:true},[o,f]=Tt.useReducer(ft,d),u=n?.adapter?q({workflowId:n.workflowId,workflowState:o,adapter:n.adapter,options:n.options,userId:n.userId}):null,b=Tt.useCallback(S=>{f({type:"SET_CURRENT_STEP",stepIndex:S});},[]),c=Tt.useCallback((S,I)=>{f({type:"SET_STEP_DATA",data:S,stepId:I});},[]),l=Tt.useCallback((S,I,L)=>{f({type:"SET_FIELD_VALUE",fieldId:S,value:I,stepId:L});},[]),a=Tt.useCallback(S=>{f({type:"SET_SUBMITTING",isSubmitting:S});},[]),y=Tt.useCallback(S=>{f({type:"SET_TRANSITIONING",isTransitioning:S});},[]),k=Tt.useCallback((S,I)=>{f({type:"MARK_STEP_VISITED",stepIndex:S,stepId:I});},[]),P=Tt.useCallback(S=>{f({type:"MARK_STEP_PASSED",stepId:S});},[]),D=Tt.useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),x=Tt.useCallback(()=>{f({type:"SET_INITIALIZATION_COMPLETE"});},[]),h=Tt.useCallback(async()=>{if(!u)return x(),false;try{let S=await u.loadPersistedData();if(S){let I={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),passedSteps:new Set(S.passedSteps||[])};return f({type:"LOAD_PERSISTED_STATE",state:I}),x(),!0}}catch(S){console.error("Failed to load persisted state:",S);}return x(),false},[u,x]);return {workflowState:o,setCurrentStep:b,setStepData:c,setFieldValue:l,setSubmitting:a,setTransitioning:y,markStepVisited:k,markStepPassed:P,resetWorkflow:D,loadPersistedState:h,persistence:u?{isPersisting:u.isPersisting,persistenceError:u.persistenceError,persistNow:u.persistNow,clearPersistedData:u.clearPersistedData,hasPersistedData:u.hasPersistedData}:null}}function ke({workflowConfig:t,workflowState:e,workflowContext:r,setSubmitting:n,onWorkflowComplete:i,analyticsStartTime:s}){let d=Tt.useRef(i);d.current=i;let o=Tt.useCallback(async()=>{n(true);try{if(d.current&&await d.current(e.allData),t.analytics?.onWorkflowComplete){let u=Date.now()-s.current;t.analytics.onWorkflowComplete(t.id,u,e.allData);}}catch(u){throw console.error("Workflow submission failed:",u),t.analytics?.onError&&t.analytics.onError(u,r),u}finally{n(false);}},[e.allData,t.analytics,t.id,r,s,n]),f=Tt.useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:o,isSubmitting:e.isSubmitting,canSubmit:f()}}function Je(t={}){let{defaultValues:e={},defaultStepIndex:r=0,initialVisitedSteps:n=new Set,initialPassedSteps:i=new Set}=t;return zustand.createStore()(middleware.subscribeWithSelector((s,d)=>({currentStepIndex:r,isTransitioning:false,isInitializing:true,allData:{...e},stepData:{},visitedSteps:new Set(n),passedSteps:new Set(i),isSubmitting:false,_defaultValues:{...e},_defaultStepIndex:r,_setCurrentStep:o=>{s({currentStepIndex:o});},_setStepData:(o,f)=>{s(u=>({stepData:o,allData:{...u.allData,[f]:o}}));},_setAllData:o=>{s({allData:o});},_setFieldValue:(o,f,u)=>{s(b=>{let c={...b.stepData,[o]:f};return {stepData:c,allData:{...b.allData,[u]:c}}});},_setSubmitting:o=>{s({isSubmitting:o});},_setTransitioning:o=>{s({isTransitioning:o});},_setInitializing:o=>{s({isInitializing:o});},_markStepVisited:o=>{s(f=>({visitedSteps:new Set([...f.visitedSteps,o])}));},_markStepPassed:o=>{s(f=>({passedSteps:new Set([...f.passedSteps,o])}));},_reset:()=>{let o=d();s({currentStepIndex:o._defaultStepIndex,allData:{...o._defaultValues},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false});},_loadPersistedState:o=>{s(f=>({...f,...o,isInitializing:false}));}})))}var xe=Tt.createContext(null);function A(){let t=Tt.useContext(xe);if(!t)throw new Error("useWorkflowStore must be used within a WorkflowProvider");return t}function jr(){let t=A();return zustand.useStore(t,e=>e.currentStepIndex)}function Zr(){let t=A();return zustand.useStore(t,e=>e.isTransitioning)}function Hr(){let t=A();return zustand.useStore(t,e=>e.isInitializing)}function Qr(){let t=A();return zustand.useStore(t,e=>e.isSubmitting)}function Xr(){let t=A();return zustand.useStore(t,e=>e.allData)}function Yr(){let t=A();return zustand.useStore(t,e=>e.stepData)}function en(t){let e=A();return zustand.useStore(e,r=>r.allData[t])}function tn(){let t=A();return zustand.useStore(t,e=>e.visitedSteps)}function rn(){let t=A();return zustand.useStore(t,e=>e.passedSteps)}function nn(t){let e=A();return zustand.useStore(e,r=>r.visitedSteps.has(t))}function sn(t){let e=A();return zustand.useStore(e,r=>r.passedSteps.has(t))}function on(){let t=A(),e=zustand.useStore(t,i=>i.currentStepIndex),r=zustand.useStore(t,i=>i.isTransitioning),n=zustand.useStore(t,i=>i.isSubmitting);return {currentStepIndex:e,isTransitioning:r,isSubmitting:n}}function an(){let t=A(),e=zustand.useStore(t,i=>i.isSubmitting),r=zustand.useStore(t,i=>i.isTransitioning),n=zustand.useStore(t,i=>i.isInitializing);return {isSubmitting:e,isTransitioning:r,isInitializing:n}}function ln(){let t=A();return {setCurrentStep:e=>t.getState()._setCurrentStep(e),setStepData:(e,r)=>t.getState()._setStepData(e,r),setAllData:e=>t.getState()._setAllData(e),setFieldValue:(e,r,n)=>t.getState()._setFieldValue(e,r,n),setSubmitting:e=>t.getState()._setSubmitting(e),setTransitioning:e=>t.getState()._setTransitioning(e),setInitializing:e=>t.getState()._setInitializing(e),markStepVisited:e=>t.getState()._markStepVisited(e),markStepPassed:e=>t.getState()._markStepPassed(e),reset:()=>t.getState()._reset(),loadPersistedState:e=>t.getState()._loadPersistedState(e)}}function pn(){return A()}var It={save:async()=>{},load:async()=>null,remove:async()=>{},exists:async()=>false},je=Tt.createContext(null);function Wt(t,e){let r=new Set,n=new Set;if(t>0)for(let i=0;i<t;i++)e[i]&&(r.add(e[i].id),n.add(e[i].id));return {visitedSteps:r,passedSteps:n}}function he({children:t,workflowConfig:e,defaultValues:r={},defaultStep:n,onStepChange:i,onWorkflowComplete:s,className:d}){let o=Tt.useRef(i),f=Tt.useRef(s);o.current=i,f.current=s;let u=Tt.useMemo(()=>{if(!n)return 0;let v=e.steps.findIndex(g=>g.id===n);return v===-1?(console.warn(`Default step with ID "${n}" not found. Starting at step 0.`),0):v},[n,e.steps]),b=Tt.useMemo(()=>Wt(u,e.steps),[u,e.steps]),c=Tt.useRef(null);c.current||(c.current=Je({defaultValues:r,defaultStepIndex:u,initialVisitedSteps:b.visitedSteps,initialPassedSteps:b.passedSteps}));let l=c.current,[a,y]=Tt.useState(()=>{let v=l.getState();return {currentStepIndex:v.currentStepIndex,allData:v.allData,stepData:v.stepData,visitedSteps:v.visitedSteps,passedSteps:v.passedSteps,isSubmitting:v.isSubmitting,isTransitioning:v.isTransitioning,isInitializing:v.isInitializing}});Tt.useEffect(()=>l.subscribe(g=>{y({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:g.visitedSteps,passedSteps:g.passedSteps,isSubmitting:g.isSubmitting,isTransitioning:g.isTransitioning,isInitializing:g.isInitializing});}),[l]);let k=Tt.useCallback(v=>l.getState()._setCurrentStep(v),[l]),P=Tt.useCallback((v,g)=>l.getState()._setStepData(v,g),[l]),D=Tt.useCallback((v,g,E)=>l.getState()._setFieldValue(v,g,E),[l]),x=Tt.useCallback(v=>l.getState()._setSubmitting(v),[l]),h=Tt.useCallback(v=>l.getState()._setTransitioning(v),[l]),S=Tt.useCallback((v,g)=>l.getState()._markStepVisited(g),[l]),I=Tt.useCallback(v=>l.getState()._markStepPassed(v),[l]),L=Tt.useCallback(()=>l.getState()._reset(),[l]),m=!!e.persistence?.adapter,p=q({workflowId:e.id,workflowState:a,adapter:e.persistence?.adapter??It,options:e.persistence?.options,userId:e.persistence?.userId}),W=Tt.useRef(p);W.current=p;let V=Tt.useRef(false);Tt.useEffect(()=>{if(V.current)return;V.current=true,(async()=>{if(m)try{let g=await W.current.loadPersistedData();if(g){l.getState()._loadPersistedState({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:new Set(g.visitedSteps),passedSteps:new Set(g.passedSteps||[])});return}}catch(g){console.error("Failed to load persisted state:",g);}l.getState()._setInitializing(false);})();},[l,m]);let z=Tt.useMemo(()=>({isPersisting:m?p.isPersisting:false,persistenceError:m?p.persistenceError:null,persistNow:m?p.persistNow:void 0}),[m,p.isPersisting,p.persistenceError,p.persistNow]),X=Tt.useMemo(()=>({workflowId:e.id,currentStepIndex:a.currentStepIndex,totalSteps:e.steps.length,allData:a.allData,stepData:a.stepData,visitedSteps:a.visitedSteps}),[e.id,e.steps.length,a.currentStepIndex,a.allData,a.stepData,a.visitedSteps]),C=Tt.useMemo(()=>e.steps[a.currentStepIndex],[e.steps,a.currentStepIndex]),K=Tt.useMemo(()=>C?.formConfig,[C?.formConfig]),_=ye({workflowConfig:e,workflowState:a,currentStep:C}),G=Tt.useMemo(()=>{let v=-1;for(let w=0;w<e.steps.length;w++)if(_.isStepVisible(w)){v=w;break}let g=-1;for(let w=e.steps.length-1;w>=0;w--)if(_.isStepVisible(w)){g=w;break}let E=new Set;for(let w=0;w<e.steps.length;w++){let te=e.steps[w];_.isStepVisible(w)&&a.visitedSteps.has(te.id)&&E.add(te.id);}return {...X,isFirstStep:a.currentStepIndex===v,isLastStep:a.currentStepIndex===g,visibleVisitedSteps:E,passedSteps:a.passedSteps}},[X,a.currentStepIndex,a.visitedSteps,a.passedSteps,_,e.steps]),{analyticsStartTime:Xe}=ge({workflowConfig:e,workflowState:a,workflowContext:G}),{goToStep:De,goNext:Y,goPrevious:we,skipStep:Re,canGoToStep:Ee,canGoNext:Te,canGoPrevious:Ce,canSkipCurrentStep:Ae}=ve({workflowConfig:e,workflowState:a,workflowContext:G,conditionsHelpers:_,setCurrentStep:k,setTransitioning:h,markStepVisited:S,markStepPassed:I,setStepData:P,onStepChange:o.current}),ae=Tt.useRef(false);Tt.useEffect(()=>{if(ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){for(let g=0;g<e.steps.length;g++)if(_.isStepVisible(g)){k(g),S(g,e.steps[g].id);break}}ae.current=true;},[a.currentStepIndex,e.steps,k,S,_]),Tt.useEffect(()=>{if(!ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){let g=null;for(let E=a.currentStepIndex+1;E<e.steps.length;E++)if(_.isStepVisible(E)){g=E;break}if(g===null){for(let E=a.currentStepIndex-1;E>=0;E--)if(_.isStepVisible(E)){g=E;break}}g!==null&&(k(g),S(g,e.steps[g].id));}},[_,a.currentStepIndex,e.steps,k,S]);let{submitWorkflow:ee,isSubmitting:_e,canSubmit:Ve}=ke({workflowConfig:e,workflowState:a,workflowContext:G,setSubmitting:x,onWorkflowComplete:f.current,analyticsStartTime:Xe}),le=Tt.useCallback((v,g)=>{D(v,g,C?.id||"");},[D,C?.id]),Ne=Tt.useCallback(v=>{P(v,C?.id||"");},[P,C?.id]),Ye=Tt.useCallback(async v=>{C?.id&&v&&P(v,C.id),G.isLastStep?await ee():await Y();},[G.isLastStep,ee,Y,C?.id,P]),Fe=Tt.useMemo(()=>({goToStep:De,goNext:Y,goPrevious:we,skipStep:Re,canGoToStep:Ee,canGoNext:Te,canGoPrevious:Ce,canSkipCurrentStep:Ae}),[De,Y,we,Re,Ee,Te,Ce,Ae]),Be=Tt.useMemo(()=>({setValue:le,setStepData:Ne,resetWorkflow:L}),[le,Ne,L]),Me=Tt.useMemo(()=>({submitWorkflow:ee,isSubmitting:_e,canSubmit:Ve}),[ee,_e,Ve]),et=Tt.useMemo(()=>({workflowState:a,workflowConfig:e,currentStep:C,context:G,formConfig:K,conditionsHelpers:_,currentStepMetadata:C?.metadata,...Fe,...Be,...Me,persistNow:z.persistNow,isPersisting:z.isPersisting,persistenceError:z.persistenceError}),[a,e,C,G,K,_,Fe,Be,Me,z]),tt=Tt.useMemo(()=>{if(!C?.id)return {};let v=a?.allData[C.id]||{};if(!K?.allFields)return v;let g=new Set(K.allFields.map(w=>w.id)),E={};for(let[w,te]of Object.entries(v))g.has(w)&&(E[w]=te);return E},[a?.allData,C?.id,K?.allFields]),rt=Tt.useMemo(()=>a.isInitializing.toString(),[a.isInitializing]);return jsxRuntime.jsx(xe.Provider,{value:l,children:jsxRuntime.jsx(je.Provider,{value:et,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:K,defaultValues:tt,onFieldChange:le,"data-workflow-id":e.id,className:d,onSubmit:Ye,children:t},rt)})})}function N(){let t=Tt.useContext(je);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function wt({children:t,workflowConfig:e,...r}){let n=Tt.useMemo(()=>e instanceof H?e.build():e,[e]);return jsxRuntime.jsx(he,{...r,workflowConfig:n,children:t})}var Ct=Tt__default.default.memo(function({stepId:e,children:r}){let{currentStep:n}=N();if(!n||e&&n.id!==e)return null;let{formConfig:i,renderer:s}=n;return i?s?s(n):r??jsxRuntime.jsx(forms.FormBody,{}):null});var Ot=Tt__default.default.memo(function({className:e,isSubmitting:r,...n}){let{context:i,workflowState:s,workflowConfig:d,currentStep:o}=N(),{submit:f}=forms.useFormConfigContext(),u=forms.useFormSubmitting(),b=forms.useFormValues(),c=Tt.useMemo(()=>{let y=u||s.isSubmitting,k=r??y,P=!s.isTransitioning&&!k;return {finalIsSubmitting:k,canGoNext:P}},[u,s.isSubmitting,s.isTransitioning,r]),l=Tt.useCallback(async y=>{y?.preventDefault(),c.canGoNext&&await f(y);},[c.canGoNext,f]),a=Tt.useMemo(()=>({isLastStep:i.isLastStep,canGoNext:c.canGoNext,isSubmitting:c.finalIsSubmitting,onSubmit:l,className:e,currentStep:o,stepData:b,allData:i.allData,context:i}),[i.isLastStep,c.canGoNext,c.finalIsSubmitting,l,e,o,b,i.allData,i]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:d.renderConfig?.nextButtonRenderer,props:a,...n})});var qt=Tt__default.default.memo(function({className:e,isSubmitting:r,...n}){let{context:i,goPrevious:s,workflowState:d,workflowConfig:o,currentStep:f,canGoPrevious:u}=N(),b=forms.useFormSubmitting(),c=forms.useFormValues(),l=Tt.useMemo(()=>{let k=b||d.isSubmitting,P=r??k,D=u()&&!d.isTransitioning&&!P;return {finalIsSubmitting:P,canGoPrevious:D}},[b,d.isSubmitting,d.isTransitioning,u,r]),a=Tt.useCallback(async k=>{k?.preventDefault(),l.canGoPrevious&&await s();},[l.canGoPrevious,s]),y=Tt.useMemo(()=>({canGoPrevious:l.canGoPrevious,isSubmitting:l.finalIsSubmitting,onPrevious:a,className:e,currentStep:f,stepData:c,allData:i.allData,context:i}),[l.canGoPrevious,l.finalIsSubmitting,a,e,f,c,i.allData,i]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:o.renderConfig?.previousButtonRenderer,props:y,...n})});var Yt=Tt__default.default.memo(function({className:e,isSubmitting:r,...n}){let{currentStep:i,skipStep:s,workflowState:d,workflowConfig:o,context:f,conditionsHelpers:u}=N(),b=forms.useFormSubmitting(),c=forms.useFormValues(),l=Tt.useMemo(()=>{let k=b||d.isSubmitting,P=r??k,D=(!!i?.allowSkip||u.isStepSkippable(d.currentStepIndex))&&!d.isTransitioning&&!P;return {finalIsSubmitting:P,canSkip:D}},[b,d.isSubmitting,d.isTransitioning,d.currentStepIndex,i?.allowSkip,u.isStepSkippable,r]),a=Tt.useCallback(async k=>{k?.preventDefault(),l.canSkip&&await s();},[l.canSkip,s]),y=Tt.useMemo(()=>({canSkip:l.canSkip,isSubmitting:l.finalIsSubmitting,onSkip:a,className:e,currentStep:i,stepData:c,allData:f.allData,context:f}),[l.canSkip,l.finalIsSubmitting,a,e,i,c,f.allData,f]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:o.renderConfig?.skipButtonRenderer,props:y,...n})});var ir=Tt__default.default.memo(function({onStepClick:e,className:r,...n}){let{workflowConfig:i,workflowState:s,context:d,goToStep:o,conditionsHelpers:f}=N(),{visibleSteps:u,visibleToOriginalIndexMap:b,originalToVisibleIndexMap:c}=Tt.useMemo(()=>{let k=[],P=new Map,D=new Map;return i.steps.forEach((x,h)=>{if(f.isStepVisible(h)){let S=k.length;k.push(x),P.set(S,h),D.set(h,S);}}),{visibleSteps:k,visibleToOriginalIndexMap:P,originalToVisibleIndexMap:D}},[i.steps,f]),l=Tt.useCallback(k=>{let P=b.get(k);P!==void 0&&(e?e(P):o(P));},[b,e,o]),a=Tt.useMemo(()=>c.get(s.currentStepIndex)??-1,[c,s.currentStepIndex]),y=Tt.useMemo(()=>({steps:u,currentStepIndex:a,visitedSteps:d.visibleVisitedSteps,onStepClick:l,className:r}),[u,a,d.visibleVisitedSteps,l,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:y,...n})});var We=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,r){if(this._isAvailable)try{let n=this.getStorageKey(e),i={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(i),d=this.compress?this.compressData(s):s;localStorage.setItem(n,d);}catch(n){if(n instanceof Error)if(n.name==="QuotaExceededError"||n.message.includes("quota")){await this.clearExpiredData();try{let i=this.getStorageKey(e),s={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},d=JSON.stringify(s),o=this.compress?this.compressData(d):d;localStorage.setItem(i,o);}catch(i){throw new R("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",i)}}else throw new R(`Failed to save to localStorage: ${n.message}`,"SAVE_FAILED",n);else throw new R("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return null;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(r){throw r instanceof Error?new R(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new R("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new R(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new R("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return !1;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix)){let i=n.substring(this.keyPrefix.length);await this.exists(i)&&e.push(i);}}return e}catch(e){throw e instanceof Error?new R(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new R("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);n?.startsWith(this.keyPrefix)&&e.push(n);}for(let r of e)localStorage.removeItem(r);}catch(e){throw e instanceof Error?new R(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new R("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix))try{let i=localStorage.getItem(n);if(i){let s=this.compress?this.decompressData(i):i,d=JSON.parse(s);d.expiresAt&&Date.now()>d.expiresAt&&e.push(n);}}catch{e.push(n);}}for(let r of e)localStorage.removeItem(r);}};exports.LocalStorageAdapter=We;exports.Workflow=wt;exports.WorkflowBody=Ct;exports.WorkflowNextButton=Ot;exports.WorkflowPersistenceError=R;exports.WorkflowPreviousButton=qt;exports.WorkflowProvider=he;exports.WorkflowSkipButton=Yt;exports.WorkflowStepper=ir;exports.WorkflowStoreContext=xe;exports.combineWorkflowDataForConditions=be;exports.createWorkflowStore=Je;exports.debounce=Se;exports.flattenObject=se;exports.flow=H;exports.generateStorageKey=fe;exports.mergePersistedState=lt;exports.persistedToWorkflowState=Ue;exports.useConditionEvaluation=ue;exports.useCurrentStepIndex=jr;exports.useIsStepPassed=sn;exports.useIsStepVisited=nn;exports.usePassedSteps=rn;exports.usePersistence=q;exports.useStepDataById=en;exports.useStepMetadata=pt;exports.useVisitedSteps=tn;exports.useWorkflowActions=ln;exports.useWorkflowAllData=Xr;exports.useWorkflowAnalytics=ge;exports.useWorkflowConditions=ye;exports.useWorkflowContext=N;exports.useWorkflowInitializing=Hr;exports.useWorkflowNavigation=ve;exports.useWorkflowNavigationState=on;exports.useWorkflowState=St;exports.useWorkflowStepData=Yr;exports.useWorkflowStore=A;exports.useWorkflowStoreApi=pn;exports.useWorkflowSubmission=ke;exports.useWorkflowSubmitState=an;exports.useWorkflowSubmitting=Qr;exports.useWorkflowTransitioning=Zr;exports.validatePersistedData=at;exports.workflowStateToPersisted=ce;
1
+ 'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),Ct=require('react'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Ct__default=/*#__PURE__*/_interopDefault(Ct);function pe(t,e,r,n){return {data:t,next:{prefill:i=>{e.setNextStepFields(i);},skip:()=>{console.warn("step.next.skip() not yet implemented");}},workflow:{get:i=>e.getStepData(i),all:()=>e.getAllData(),goto:i=>{console.warn("step.workflow.goto() not yet implemented");}},meta:n||{},isFirst:r.isFirstStep,isLast:r.isLastStep}}var Z=class t{constructor(e,r,n,i){this.steps=[];this.plugins=[];this.idGenerator=new core.IdGenerator;this.config=e,this.workflowId=r||`workflow-${Math.random().toString(36).substring(2,15)}`,this.workflowName=n||"Workflow",this.workflowDescription=i;}static create(e,r,n,i){return new t(e,r,n,i)}createStepFromDefinition(e){let r=e.after?(n,i,s)=>{let p=pe(n,i,s,e.metadata);return e.after(p)}:e.onAfterValidation;return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:r}}_addStepsInternal(e){let r=core.normalizeToArray(e);for(let n of r){let i=this.createStepFromDefinition(n);this.steps.push(i);}return this}addStep(e){return this._addStepsInternal(e)}step(e){return this._addStepsInternal(e)}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(n=>!this.plugins.some(i=>i.name===n));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 n=this.steps.findIndex(i=>i.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[n]={...this.steps[n],...r},this}addStepConditions(e,r){let n=this.steps.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);let i={...this.steps[n].conditions,...r};return this.steps[n]={...this.steps[n],conditions:i},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 n=new t(this.config,e||`${this.workflowId}-clone`,r||this.workflowName);return n.steps=core.deepClone(this.steps),n.analytics=this.analytics?core.deepClone(this.analytics):void 0,n.persistenceConfig=this.persistenceConfig?core.deepClone(this.persistenceConfig):void 0,n.plugins=[...this.plugins],n}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let r=this.steps.map(n=>n.id);try{core.ensureUnique(r,"step");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of this.plugins)if(n.dependencies){let i=n.dependencies.filter(s=>!this.plugins.some(p=>p.name===s));i.length>0&&e.push(`Plugin "${n.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((n,i)=>n+i.formConfig.allFields.length,0),r=this.steps.map(n=>n.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function ce(t,e={},r={}){return Ct.useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let n=i=>{try{let s;return i&&typeof i=="object"&&"build"in i?s=i.build():s=i,core.evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:t.visible?n(t.visible):true,disabled:t.disabled?n(t.disabled):false,required:t.required?n(t.required):false,readonly:t.readonly?n(t.readonly):false}},[t,e,r])}function Le(t,e={}){return Ct.useMemo(()=>{let r={};for(let[n,i]of Object.entries(t))if(r[n]={visible:true,disabled:false,required:false,readonly:false},i){let s=p=>{try{return p&&typeof p=="object"&&"build"in p?core.evaluateCondition(p.build(),e):core.evaluateCondition(p,e)}catch(o){return console.warn(`Error evaluating condition for field ${n}:`,o),false}};r[n]={visible:i.visible?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[t,e])}function Ue(t,e={}){return Ct.useMemo(()=>{let r={};for(let[n,i]of Object.entries(t)){let s=Number.parseInt(n,10);if(r[s]={visible:true,disabled:false,required:false,readonly:false},i){let p=o=>{try{return o&&typeof o=="object"&&"build"in o?core.evaluateCondition(o.build(),e):core.evaluateCondition(o,e)}catch(f){return console.warn(`Error evaluating condition for step ${s}:`,f),false}};r[s]={visible:i.visible?p(i.visible):true,disabled:i.disabled?p(i.disabled):false,required:i.required?p(i.required):false,readonly:i.readonly?p(i.readonly):false};}}return r},[t,e])}var R=class extends Error{constructor(r,n,i){super(`[WorkflowPersistence] ${r} (Code: ${n})`);this.code=n;this.cause=i;this.name="WorkflowPersistenceError";}};function fe(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),passedSteps:Array.from(e.passedSteps),lastSaved:Date.now(),metadata:r}}function ze(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),passedSteps:new Set(t.passedSteps||[]),isSubmitting:false,isTransitioning:false}}function lt(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function Se(t,e){return e?`${e}:${t}`:t}function me(t,e){let r=null;return (...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...n);},e);}}function pt(t,e,r="persist"){let n=ze(e);switch(r){case "persist":return {...n,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...n.visitedSteps]),passedSteps:new Set([...t.passedSteps,...n.passedSteps||[]])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...n.allData,...t.allData},stepData:{...n.stepData,...t.stepData},visitedSteps:new Set([...n.visitedSteps,...t.visitedSteps]),passedSteps:new Set([...n.passedSteps||[],...t.passedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return n}}function q({workflowId:t,workflowState:e,adapter:r,options:n={},userId:i}){let[s,p]=Ct.useState(false),[o,f]=Ct.useState(null),[u,b]=Ct.useState(false),c=Ct.useRef(r),l=Ct.useRef(n),a=Ct.useRef({hasPendingChanges:false});Ct.useEffect(()=>{c.current=r,l.current=n;},[r,n]);let y=Se(l.current.storageKey||t,i),k=Ct.useCallback(()=>{f(null);},[]),P=Ct.useCallback((d,W)=>{let V=d instanceof R?d:new R(`${W} failed: ${d.message}`,"OPERATION_FAILED",d);f(V),console.error("[WorkflowPersistence]",V);},[]),D=Ct.useCallback(async d=>{k(),p(true);try{let W=fe(t,d,l.current.metadata);await c.current.save(y,W),a.current.lastSavedState={...d},a.current.hasPendingChanges=!1;}catch(W){throw P(W,"Save"),W}finally{p(false);}},[t,y,k,P]),v=Ct.useRef(me(async d=>{try{await D(d);}catch(W){console.debug("[WorkflowPersistence] Auto-save failed:",W);}},n.debounceMs||500)),I=Ct.useCallback((d,W)=>W?d.currentStepIndex!==W.currentStepIndex||JSON.stringify(d.allData)!==JSON.stringify(W.allData)||JSON.stringify(d.stepData)!==JSON.stringify(W.stepData)||d.visitedSteps.size!==W.visitedSteps.size||!Array.from(d.visitedSteps).every(V=>W.visitedSteps.has(V)):true,[]),S=Ct.useCallback(async()=>{k(),b(true);try{let d=await c.current.load(y);return d&&(a.current.lastSavedState={currentStepIndex:d.currentStepIndex,allData:d.allData,stepData:d.stepData,visitedSteps:new Set(d.visitedSteps),passedSteps:new Set(d.passedSteps||[]),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},a.current.hasPendingChanges=!1),d}catch(d){return P(d,"Load"),null}finally{setTimeout(()=>b(false),100);}},[y,k,P]),h=Ct.useCallback(async()=>{k();try{await c.current.remove(y),a.current.lastSavedState=void 0,a.current.hasPendingChanges=!1;}catch(d){throw P(d,"Clear"),d}},[y,k,P]),L=Ct.useCallback(async()=>{try{return await c.current.exists(y)}catch(d){return P(d,"Exists check"),false}},[y,P]);Ct.useEffect(()=>{l.current.autoPersist&&(s||u||e.isInitializing||e.isSubmitting||e.isTransitioning||I(e,a.current.lastSavedState)&&(a.current.hasPendingChanges=true,v.current(e)));},[e,s,u,I]);let m=Ct.useCallback(async()=>{await D(e);},[D,e]);return {isPersisting:s,persistenceError:o,persistNow:m,loadPersistedData:S,clearPersistedData:h,hasPersistedData:L}}function dt(){let{workflowConfig:t,currentStep:e}=N(),r=Ct.useMemo(()=>e?.metadata,[e?.metadata]),n=Ct.useMemo(()=>u=>t.steps.find(c=>c.id===u)?.metadata,[t.steps]),i=Ct.useMemo(()=>u=>t.steps[u]?.metadata,[t.steps]),s=Ct.useMemo(()=>u=>r?u in r:false,[r]),p=Ct.useMemo(()=>(u,b)=>r&&u in r?r[u]:b,[r]),o=Ct.useMemo(()=>()=>t.steps.map((u,b)=>({id:u.id,title:u.title,index:b,metadata:u.metadata})),[t.steps]),f=Ct.useMemo(()=>u=>t.steps.map((b,c)=>({step:b,index:c})).filter(({step:b,index:c})=>u(b.metadata,b.id,c)).map(({step:b})=>b.id),[t.steps]);return {current:r,getByStepId:n,getByStepIndex:i,hasCurrentKey:s,getCurrentValue:p,getAllStepsMetadata:o,findStepsByMetadata:f}}function be({workflowConfig:t,workflowState:e,workflowContext:r}){let n=Ct.useRef(Date.now()),i=Ct.useRef(new Map),s=Ct.useRef(false),p=Ct.useRef(null),o=core.getGlobalMonitor();Ct.useEffect(()=>{t.analytics?.onWorkflowStart&&!s.current&&(s.current=true,t.analytics.onWorkflowStart(t.id,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"start",totalSteps:t.steps.length},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:0,navigationDuration:0,conditionEvaluationDuration:0},"low"));},[t.id,t.analytics,r,o,t.steps.length]),Ct.useEffect(()=>{let l=t.steps[e.currentStepIndex];if(l&&p.current!==l.id){if(p.current&&t.analytics?.onStepComplete){let a=i.current.get(p.current);if(a){let y=Date.now()-a;t.analytics.onStepComplete(p.current,y,e.stepData,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_complete",stepId:p.current,duration:y},{timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:y,conditionEvaluationDuration:0},"low");}}p.current=l.id,i.current.set(l.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(l.id,Date.now(),r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_start",stepId:l.id,stepIndex:e.currentStepIndex},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:0},"low");}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData,o,t.id]);let f=Ct.useCallback((l,a)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(l,a,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_skip",stepId:l,reason:a},void 0,"medium");},[t.analytics,r,o,t.id]),u=Ct.useCallback(l=>{t.analytics?.onError&&t.analytics.onError(l,r),o&&o.trackError(l,`workflow_${t.id}`,{workflowId:t.id,currentStepIndex:e.currentStepIndex,currentStepId:t.steps[e.currentStepIndex]?.id,workflowContext:r});},[t.analytics,r,o,t.id,e.currentStepIndex,t.steps]),b=Ct.useCallback((l,a,y)=>{if(!o)return;let k={timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:a,navigationDuration:y,conditionEvaluationDuration:0};o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"navigation",fromStep:l,toStep:a,direction:a>l?"forward":"backward"},k,y>1e3?"medium":"low");},[o,t.id,t.steps.length]),c=Ct.useCallback((l,a)=>{if(!o)return;let y={timestamp:Date.now(),duration:l,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:l};o.track("condition_evaluation",`workflow_${t.id}`,{workflowId:t.id,conditionsCount:a,currentStepIndex:e.currentStepIndex},y,l>100?"medium":"low");},[o,t.id,t.steps.length,e.currentStepIndex]);return {analyticsStartTime:n,trackStepSkip:f,trackError:u,trackNavigation:b,trackConditionEvaluation:c}}function se(t,e=""){let r={};for(let n in t)if(n in t){let i=t[n],s=e?`${e}.${n}`:n;i!==null&&typeof i=="object"&&!Array.isArray(i)&&!(i instanceof Date)?Object.assign(r,se(i,s)):r[s]=i;}return r}function ye(t,e){let r=se(t),n=se(e);return {...{...t,...e},...r,...n}}function Ke(t,e){return {visible:t.visible,skippable:e===true||t.required}}function xe({workflowConfig:t,workflowState:e,currentStep:r}){let n=Ct.useMemo(()=>ye(e.allData,e.stepData),[e.allData,e.stepData]),i=Ct.useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),s=ce(i,n,{visible:true,disabled:false,required:false,readonly:false}),p=Ct.useMemo(()=>Ke(s,r?.allowSkip),[s,r?.allowSkip]),o=Ct.useMemo(()=>{let v={};return t.steps.forEach((I,S)=>{I.conditions&&(v[S]={visible:I.conditions.visible,required:I.conditions.skippable});}),v},[t.steps]),f=Ue(o,n),u=Ct.useMemo(()=>{let v={};return t.steps.forEach((I,S)=>{let h=f[S];h?v[S]=Ke(h,I.allowSkip):v[S]={visible:true,skippable:I.allowSkip===true};}),v},[t.steps,f]),b=Ct.useMemo(()=>{if(!r?.formConfig?.allFields)return {};let v={};for(let I of r.formConfig.allFields)I.conditions&&(v[I.id]=I.conditions);return v},[r?.formConfig?.allFields]),c=Le(b,n),l=Ct.useCallback(v=>v<0||v>=t.steps.length?false:u[v]?.visible??true,[u,t.steps.length]),a=Ct.useCallback(v=>v<0||v>=t.steps.length?false:u[v]?.skippable??false,[u,t.steps.length]),y=Ct.useCallback(v=>c[v]?.visible??true,[c]),k=Ct.useCallback(v=>c[v]?.disabled??false,[c]),P=Ct.useCallback(v=>c[v]?.required??false,[c]),D=Ct.useCallback(v=>c[v]?.readonly??false,[c]);return {stepConditions:p,fieldConditions:c,allStepConditions:u,isStepVisible:l,isStepSkippable:a,isFieldVisible:y,isFieldDisabled:k,isFieldRequired:P,isFieldReadonly:D}}function ke({workflowConfig:t,workflowState:e,workflowContext:r,conditionsHelpers:n,setCurrentStep:i,setTransitioning:s,markStepVisited:p,markStepPassed:o,setStepData:f,onStepChange:u}){let b=Ct.useRef(u);b.current=u;let c=t.steps[e.currentStepIndex],l=Ct.useCallback(()=>({setStepData:(m,d)=>{f(d,m);},setStepFields:(m,d)=>{let V={...e.allData[m]||{},...d};f(V,m);},getStepData:m=>e.allData[m]||{},setNextStepField:(m,d)=>{let W=e.currentStepIndex+1;if(W<t.steps.length){let V=t.steps[W].id,X={...e.allData[V]||{},[m]:d};f(X,V);}},setNextStepFields:m=>{let d=e.currentStepIndex+1;if(d<t.steps.length){let W=t.steps[d].id,z={...e.allData[W]||{},...m};f(z,W);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,f]),a=Ct.useCallback(async m=>{if(m<0||m>=t.steps.length||!n.isStepVisible(m))return false;s(true);try{return b.current&&b.current(e.currentStepIndex,m,r),i(m),p(m,t.steps[m].id),!0}catch(d){return console.error("Step transition failed:",d),t.analytics?.onError&&t.analytics.onError(d,r),false}finally{s(false);}},[t.steps,t.analytics,n,e.currentStepIndex,r,s,i,p]),y=Ct.useCallback(m=>{for(let d=m+1;d<t.steps.length;d++)if(n.isStepVisible(d))return d;return null},[t.steps.length,n]),k=Ct.useCallback(m=>{for(let d=m-1;d>=0;d--)if(n.isStepVisible(d))return d;return null},[n]),P=Ct.useCallback(async()=>{if(c?.onAfterValidation)try{let d=l();await c.onAfterValidation(e.stepData,d,r);}catch(d){return console.error("onAfterValidation failed:",d),t.analytics?.onError&&t.analytics.onError(d,r),false}o(c.id);let m=y(e.currentStepIndex);return m===null?false:a(m)},[c,l,e.stepData,r,t.analytics,e.currentStepIndex,y,a,o]),D=Ct.useCallback(async()=>{let m=k(e.currentStepIndex);return m===null?false:a(m)},[e.currentStepIndex,k,a]),v=Ct.useCallback(async()=>!c?.allowSkip&&!n.isStepSkippable(e.currentStepIndex)?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(c.id,"user_skip",r),P()),[c,n,e.currentStepIndex,t.analytics,r,P]),I=Ct.useCallback(m=>m<0||m>=t.steps.length?false:n.isStepVisible(m),[t.steps.length,n]),S=Ct.useCallback(()=>{let m=y(e.currentStepIndex);return m!==null&&I(m)},[e.currentStepIndex,y,I]),h=Ct.useCallback(()=>{let m=k(e.currentStepIndex);return m!==null&&I(m)},[e.currentStepIndex,k,I]),L=Ct.useCallback(()=>c?.allowSkip===true&&n.isStepSkippable(e.currentStepIndex),[c?.allowSkip,n,e.currentStepIndex]);return {goToStep:a,goNext:P,goPrevious:D,skipStep:v,canGoToStep:I,canGoNext:S,canGoPrevious:h,canSkipCurrentStep:L}}function St(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.visitedSteps,e.stepId])};case "MARK_STEP_PASSED":return {...t,passedSteps:new Set([...t.passedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function mt({defaultValues:t={},defaultStepIndex:e,workflowSteps:r,persistence:n}){let i=Ct.useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let h=0;h<e;h++)r[h]&&S.add(r[h].id);return S},[e,r]),s=Ct.useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let h=0;h<e;h++)r[h]&&S.add(r[h].id);return S},[e,r]),p={currentStepIndex:e??0,allData:t,stepData:{},visitedSteps:i,passedSteps:s,isSubmitting:false,isTransitioning:false,isInitializing:true},[o,f]=Ct.useReducer(St,p),u=n?.adapter?q({workflowId:n.workflowId,workflowState:o,adapter:n.adapter,options:n.options,userId:n.userId}):null,b=Ct.useCallback(S=>{f({type:"SET_CURRENT_STEP",stepIndex:S});},[]),c=Ct.useCallback((S,h)=>{f({type:"SET_STEP_DATA",data:S,stepId:h});},[]),l=Ct.useCallback((S,h,L)=>{f({type:"SET_FIELD_VALUE",fieldId:S,value:h,stepId:L});},[]),a=Ct.useCallback(S=>{f({type:"SET_SUBMITTING",isSubmitting:S});},[]),y=Ct.useCallback(S=>{f({type:"SET_TRANSITIONING",isTransitioning:S});},[]),k=Ct.useCallback((S,h)=>{f({type:"MARK_STEP_VISITED",stepIndex:S,stepId:h});},[]),P=Ct.useCallback(S=>{f({type:"MARK_STEP_PASSED",stepId:S});},[]),D=Ct.useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),v=Ct.useCallback(()=>{f({type:"SET_INITIALIZATION_COMPLETE"});},[]),I=Ct.useCallback(async()=>{if(!u)return v(),false;try{let S=await u.loadPersistedData();if(S){let h={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),passedSteps:new Set(S.passedSteps||[])};return f({type:"LOAD_PERSISTED_STATE",state:h}),v(),!0}}catch(S){console.error("Failed to load persisted state:",S);}return v(),false},[u,v]);return {workflowState:o,setCurrentStep:b,setStepData:c,setFieldValue:l,setSubmitting:a,setTransitioning:y,markStepVisited:k,markStepPassed:P,resetWorkflow:D,loadPersistedState:I,persistence:u?{isPersisting:u.isPersisting,persistenceError:u.persistenceError,persistNow:u.persistNow,clearPersistedData:u.clearPersistedData,hasPersistedData:u.hasPersistedData}:null}}function ve({workflowConfig:t,workflowState:e,workflowContext:r,setSubmitting:n,onWorkflowComplete:i,analyticsStartTime:s}){let p=Ct.useRef(i);p.current=i;let o=Ct.useCallback(async()=>{n(true);try{if(p.current&&await p.current(e.allData),t.analytics?.onWorkflowComplete){let u=Date.now()-s.current;t.analytics.onWorkflowComplete(t.id,u,e.allData);}}catch(u){throw console.error("Workflow submission failed:",u),t.analytics?.onError&&t.analytics.onError(u,r),u}finally{n(false);}},[e.allData,t.analytics,t.id,r,s,n]),f=Ct.useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:o,isSubmitting:e.isSubmitting,canSubmit:f()}}function He(t={}){let{defaultValues:e={},defaultStepIndex:r=0,initialVisitedSteps:n=new Set,initialPassedSteps:i=new Set}=t;return zustand.createStore()(middleware.subscribeWithSelector((s,p)=>({currentStepIndex:r,isTransitioning:false,isInitializing:true,allData:{...e},stepData:{},visitedSteps:new Set(n),passedSteps:new Set(i),isSubmitting:false,_defaultValues:{...e},_defaultStepIndex:r,_setCurrentStep:o=>{s({currentStepIndex:o});},_setStepData:(o,f)=>{s(u=>({stepData:o,allData:{...u.allData,[f]:o}}));},_setAllData:o=>{s({allData:o});},_setFieldValue:(o,f,u)=>{s(b=>{let c={...b.stepData,[o]:f};return {stepData:c,allData:{...b.allData,[u]:c}}});},_setSubmitting:o=>{s({isSubmitting:o});},_setTransitioning:o=>{s({isTransitioning:o});},_setInitializing:o=>{s({isInitializing:o});},_markStepVisited:o=>{s(f=>({visitedSteps:new Set([...f.visitedSteps,o])}));},_markStepPassed:o=>{s(f=>({passedSteps:new Set([...f.passedSteps,o])}));},_reset:()=>{let o=p();s({currentStepIndex:o._defaultStepIndex,allData:{...o._defaultValues},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false});},_loadPersistedState:o=>{s(f=>({...f,...o,isInitializing:false}));}})))}var Pe=Ct.createContext(null);function A(){let t=Ct.useContext(Pe);if(!t)throw new Error("useWorkflowStore must be used within a WorkflowProvider");return t}function Qr(){let t=A();return zustand.useStore(t,e=>e.currentStepIndex)}function Xr(){let t=A();return zustand.useStore(t,e=>e.isTransitioning)}function Yr(){let t=A();return zustand.useStore(t,e=>e.isInitializing)}function en(){let t=A();return zustand.useStore(t,e=>e.isSubmitting)}function tn(){let t=A();return zustand.useStore(t,e=>e.allData)}function rn(){let t=A();return zustand.useStore(t,e=>e.stepData)}function nn(t){let e=A();return zustand.useStore(e,r=>r.allData[t])}function sn(){let t=A();return zustand.useStore(t,e=>e.visitedSteps)}function on(){let t=A();return zustand.useStore(t,e=>e.passedSteps)}function an(t){let e=A();return zustand.useStore(e,r=>r.visitedSteps.has(t))}function ln(t){let e=A();return zustand.useStore(e,r=>r.passedSteps.has(t))}function pn(){let t=A(),e=zustand.useStore(t,i=>i.currentStepIndex),r=zustand.useStore(t,i=>i.isTransitioning),n=zustand.useStore(t,i=>i.isSubmitting);return {currentStepIndex:e,isTransitioning:r,isSubmitting:n}}function dn(){let t=A(),e=zustand.useStore(t,i=>i.isSubmitting),r=zustand.useStore(t,i=>i.isTransitioning),n=zustand.useStore(t,i=>i.isInitializing);return {isSubmitting:e,isTransitioning:r,isInitializing:n}}function un(){let t=A();return {setCurrentStep:e=>t.getState()._setCurrentStep(e),setStepData:(e,r)=>t.getState()._setStepData(e,r),setAllData:e=>t.getState()._setAllData(e),setFieldValue:(e,r,n)=>t.getState()._setFieldValue(e,r,n),setSubmitting:e=>t.getState()._setSubmitting(e),setTransitioning:e=>t.getState()._setTransitioning(e),setInitializing:e=>t.getState()._setInitializing(e),markStepVisited:e=>t.getState()._markStepVisited(e),markStepPassed:e=>t.getState()._markStepPassed(e),reset:()=>t.getState()._reset(),loadPersistedState:e=>t.getState()._loadPersistedState(e)}}function cn(){return A()}var Wt={save:async()=>{},load:async()=>null,remove:async()=>{},exists:async()=>false},je=Ct.createContext(null);function Dt(t,e){let r=new Set,n=new Set;if(t>0)for(let i=0;i<t;i++)e[i]&&(r.add(e[i].id),n.add(e[i].id));return {visitedSteps:r,passedSteps:n}}function he({children:t,workflowConfig:e,defaultValues:r={},defaultStep:n,onStepChange:i,onWorkflowComplete:s,className:p}){let o=Ct.useRef(i),f=Ct.useRef(s);o.current=i,f.current=s;let u=Ct.useMemo(()=>{if(!n)return 0;let x=e.steps.findIndex(g=>g.id===n);return x===-1?(console.warn(`Default step with ID "${n}" not found. Starting at step 0.`),0):x},[n,e.steps]),b=Ct.useMemo(()=>Dt(u,e.steps),[u,e.steps]),c=Ct.useRef(null);c.current||(c.current=He({defaultValues:r,defaultStepIndex:u,initialVisitedSteps:b.visitedSteps,initialPassedSteps:b.passedSteps}));let l=c.current,[a,y]=Ct.useState(()=>{let x=l.getState();return {currentStepIndex:x.currentStepIndex,allData:x.allData,stepData:x.stepData,visitedSteps:x.visitedSteps,passedSteps:x.passedSteps,isSubmitting:x.isSubmitting,isTransitioning:x.isTransitioning,isInitializing:x.isInitializing}});Ct.useEffect(()=>l.subscribe(g=>{y({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:g.visitedSteps,passedSteps:g.passedSteps,isSubmitting:g.isSubmitting,isTransitioning:g.isTransitioning,isInitializing:g.isInitializing});}),[l]);let k=Ct.useCallback(x=>l.getState()._setCurrentStep(x),[l]),P=Ct.useCallback((x,g)=>l.getState()._setStepData(x,g),[l]),D=Ct.useCallback((x,g,E)=>l.getState()._setFieldValue(x,g,E),[l]),v=Ct.useCallback(x=>l.getState()._setSubmitting(x),[l]),I=Ct.useCallback(x=>l.getState()._setTransitioning(x),[l]),S=Ct.useCallback((x,g)=>l.getState()._markStepVisited(g),[l]),h=Ct.useCallback(x=>l.getState()._markStepPassed(x),[l]),L=Ct.useCallback(()=>l.getState()._reset(),[l]),m=!!e.persistence?.adapter,d=q({workflowId:e.id,workflowState:a,adapter:e.persistence?.adapter??Wt,options:e.persistence?.options,userId:e.persistence?.userId}),W=Ct.useRef(d);W.current=d;let V=Ct.useRef(false);Ct.useEffect(()=>{if(V.current)return;V.current=true,(async()=>{if(m)try{let g=await W.current.loadPersistedData();if(g){l.getState()._loadPersistedState({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:new Set(g.visitedSteps),passedSteps:new Set(g.passedSteps||[])});return}}catch(g){console.error("Failed to load persisted state:",g);}l.getState()._setInitializing(false);})();},[l,m]);let z=Ct.useMemo(()=>({isPersisting:m?d.isPersisting:false,persistenceError:m?d.persistenceError:null,persistNow:m?d.persistNow:void 0}),[m,d.isPersisting,d.persistenceError,d.persistNow]),X=Ct.useMemo(()=>({workflowId:e.id,currentStepIndex:a.currentStepIndex,totalSteps:e.steps.length,allData:a.allData,stepData:a.stepData,visitedSteps:a.visitedSteps}),[e.id,e.steps.length,a.currentStepIndex,a.allData,a.stepData,a.visitedSteps]),C=Ct.useMemo(()=>e.steps[a.currentStepIndex],[e.steps,a.currentStepIndex]),K=Ct.useMemo(()=>C?.formConfig,[C?.formConfig]),_=xe({workflowConfig:e,workflowState:a,currentStep:C}),G=Ct.useMemo(()=>{let x=-1;for(let w=0;w<e.steps.length;w++)if(_.isStepVisible(w)){x=w;break}let g=-1;for(let w=e.steps.length-1;w>=0;w--)if(_.isStepVisible(w)){g=w;break}let E=new Set;for(let w=0;w<e.steps.length;w++){let te=e.steps[w];_.isStepVisible(w)&&a.visitedSteps.has(te.id)&&E.add(te.id);}return {...X,isFirstStep:a.currentStepIndex===x,isLastStep:a.currentStepIndex===g,visibleVisitedSteps:E,passedSteps:a.passedSteps}},[X,a.currentStepIndex,a.visitedSteps,a.passedSteps,_,e.steps]),{analyticsStartTime:Ye}=be({workflowConfig:e,workflowState:a,workflowContext:G}),{goToStep:we,goNext:Y,goPrevious:Re,skipStep:Ee,canGoToStep:Te,canGoNext:Ce,canGoPrevious:Ae,canSkipCurrentStep:_e}=ke({workflowConfig:e,workflowState:a,workflowContext:G,conditionsHelpers:_,setCurrentStep:k,setTransitioning:I,markStepVisited:S,markStepPassed:h,setStepData:P,onStepChange:o.current}),ae=Ct.useRef(false);Ct.useEffect(()=>{if(ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){for(let g=0;g<e.steps.length;g++)if(_.isStepVisible(g)){k(g),S(g,e.steps[g].id);break}}ae.current=true;},[a.currentStepIndex,e.steps,k,S,_]),Ct.useEffect(()=>{if(!ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){let g=null;for(let E=a.currentStepIndex+1;E<e.steps.length;E++)if(_.isStepVisible(E)){g=E;break}if(g===null){for(let E=a.currentStepIndex-1;E>=0;E--)if(_.isStepVisible(E)){g=E;break}}g!==null&&(k(g),S(g,e.steps[g].id));}},[_,a.currentStepIndex,e.steps,k,S]);let{submitWorkflow:ee,isSubmitting:Ve,canSubmit:Ne}=ve({workflowConfig:e,workflowState:a,workflowContext:G,setSubmitting:v,onWorkflowComplete:f.current,analyticsStartTime:Ye}),le=Ct.useCallback((x,g)=>{D(x,g,C?.id||"");},[D,C?.id]),Fe=Ct.useCallback(x=>{P(x,C?.id||"");},[P,C?.id]),et=Ct.useCallback(async x=>{C?.id&&x&&P(x,C.id),G.isLastStep?await ee():await Y();},[G.isLastStep,ee,Y,C?.id,P]),Me=Ct.useMemo(()=>({goToStep:we,goNext:Y,goPrevious:Re,skipStep:Ee,canGoToStep:Te,canGoNext:Ce,canGoPrevious:Ae,canSkipCurrentStep:_e}),[we,Y,Re,Ee,Te,Ce,Ae,_e]),Be=Ct.useMemo(()=>({setValue:le,setStepData:Fe,resetWorkflow:L}),[le,Fe,L]),Oe=Ct.useMemo(()=>({submitWorkflow:ee,isSubmitting:Ve,canSubmit:Ne}),[ee,Ve,Ne]),tt=Ct.useMemo(()=>({workflowState:a,workflowConfig:e,currentStep:C,context:G,formConfig:K,conditionsHelpers:_,currentStepMetadata:C?.metadata,...Me,...Be,...Oe,persistNow:z.persistNow,isPersisting:z.isPersisting,persistenceError:z.persistenceError}),[a,e,C,G,K,_,Me,Be,Oe,z]),rt=Ct.useMemo(()=>{if(!C?.id)return {};let x=a?.allData[C.id]||{};if(!K?.allFields)return x;let g=new Set(K.allFields.map(w=>w.id)),E={};for(let[w,te]of Object.entries(x))g.has(w)&&(E[w]=te);return E},[a?.allData,C?.id,K?.allFields]),nt=Ct.useMemo(()=>a.isInitializing.toString(),[a.isInitializing]);return jsxRuntime.jsx(Pe.Provider,{value:l,children:jsxRuntime.jsx(je.Provider,{value:tt,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:K,defaultValues:rt,onFieldChange:le,"data-workflow-id":e.id,className:p,onSubmit:et,children:t},nt)})})}function N(){let t=Ct.useContext(je);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function Rt({children:t,workflowConfig:e,...r}){let n=Ct.useMemo(()=>e instanceof Z?e.build():e,[e]);return jsxRuntime.jsx(he,{...r,workflowConfig:n,children:t})}var At=Ct__default.default.memo(function({stepId:e,children:r}){let{currentStep:n}=N();if(!n||e&&n.id!==e)return null;let{formConfig:i,renderer:s}=n;return i?s?s(n):r??jsxRuntime.jsx(forms.FormBody,{}):null});var Lt=Ct__default.default.memo(function({className:e,isSubmitting:r,...n}){let{context:i,workflowState:s,workflowConfig:p,currentStep:o}=N(),{submit:f}=forms.useFormConfigContext(),u=forms.useFormSubmitting(),b=forms.useFormValues(),c=Ct.useMemo(()=>{let y=u||s.isSubmitting,k=r??y,P=!s.isTransitioning&&!k;return {finalIsSubmitting:k,canGoNext:P}},[u,s.isSubmitting,s.isTransitioning,r]),l=Ct.useCallback(async y=>{y?.preventDefault(),c.canGoNext&&await f(y);},[c.canGoNext,f]),a=Ct.useMemo(()=>({isLastStep:i.isLastStep,canGoNext:c.canGoNext,isSubmitting:c.finalIsSubmitting,onSubmit:l,className:e,currentStep:o,stepData:b,allData:i.allData,context:i}),[i.isLastStep,c.canGoNext,c.finalIsSubmitting,l,e,o,b,i.allData,i]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:p.renderConfig?.nextButtonRenderer,props:a,...n})});var Jt=Ct__default.default.memo(function({className:e,isSubmitting:r,...n}){let{context:i,goPrevious:s,workflowState:p,workflowConfig:o,currentStep:f,canGoPrevious:u}=N(),b=forms.useFormSubmitting(),c=forms.useFormValues(),l=Ct.useMemo(()=>{let k=b||p.isSubmitting,P=r??k,D=u()&&!p.isTransitioning&&!P;return {finalIsSubmitting:P,canGoPrevious:D}},[b,p.isSubmitting,p.isTransitioning,u,r]),a=Ct.useCallback(async k=>{k?.preventDefault(),l.canGoPrevious&&await s();},[l.canGoPrevious,s]),y=Ct.useMemo(()=>({canGoPrevious:l.canGoPrevious,isSubmitting:l.finalIsSubmitting,onPrevious:a,className:e,currentStep:f,stepData:c,allData:i.allData,context:i}),[l.canGoPrevious,l.finalIsSubmitting,a,e,f,c,i.allData,i]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:o.renderConfig?.previousButtonRenderer,props:y,...n})});var er=Ct__default.default.memo(function({className:e,isSubmitting:r,...n}){let{currentStep:i,skipStep:s,workflowState:p,workflowConfig:o,context:f,conditionsHelpers:u}=N(),b=forms.useFormSubmitting(),c=forms.useFormValues(),l=Ct.useMemo(()=>{let k=b||p.isSubmitting,P=r??k,D=(!!i?.allowSkip||u.isStepSkippable(p.currentStepIndex))&&!p.isTransitioning&&!P;return {finalIsSubmitting:P,canSkip:D}},[b,p.isSubmitting,p.isTransitioning,p.currentStepIndex,i?.allowSkip,u.isStepSkippable,r]),a=Ct.useCallback(async k=>{k?.preventDefault(),l.canSkip&&await s();},[l.canSkip,s]),y=Ct.useMemo(()=>({canSkip:l.canSkip,isSubmitting:l.finalIsSubmitting,onSkip:a,className:e,currentStep:i,stepData:c,allData:f.allData,context:f}),[l.canSkip,l.finalIsSubmitting,a,e,i,c,f.allData,f]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:o.renderConfig?.skipButtonRenderer,props:y,...n})});var sr=Ct__default.default.memo(function({onStepClick:e,className:r,...n}){let{workflowConfig:i,workflowState:s,context:p,goToStep:o,conditionsHelpers:f}=N(),{visibleSteps:u,visibleToOriginalIndexMap:b,originalToVisibleIndexMap:c}=Ct.useMemo(()=>{let k=[],P=new Map,D=new Map;return i.steps.forEach((v,I)=>{if(f.isStepVisible(I)){let S=k.length;k.push(v),P.set(S,I),D.set(I,S);}}),{visibleSteps:k,visibleToOriginalIndexMap:P,originalToVisibleIndexMap:D}},[i.steps,f]),l=Ct.useCallback(k=>{let P=b.get(k);P!==void 0&&(e?e(P):o(P));},[b,e,o]),a=Ct.useMemo(()=>c.get(s.currentStepIndex)??-1,[c,s.currentStepIndex]),y=Ct.useMemo(()=>({steps:u,currentStepIndex:a,visitedSteps:p.visibleVisitedSteps,onStepClick:l,className:r}),[u,a,p.visibleVisitedSteps,l,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:y,...n})});var De=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,r){if(this._isAvailable)try{let n=this.getStorageKey(e),i={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(i),p=this.compress?this.compressData(s):s;localStorage.setItem(n,p);}catch(n){if(n instanceof Error)if(n.name==="QuotaExceededError"||n.message.includes("quota")){await this.clearExpiredData();try{let i=this.getStorageKey(e),s={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},p=JSON.stringify(s),o=this.compress?this.compressData(p):p;localStorage.setItem(i,o);}catch(i){throw new R("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",i)}}else throw new R(`Failed to save to localStorage: ${n.message}`,"SAVE_FAILED",n);else throw new R("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return null;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(r){throw r instanceof Error?new R(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new R("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new R(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new R("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return !1;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix)){let i=n.substring(this.keyPrefix.length);await this.exists(i)&&e.push(i);}}return e}catch(e){throw e instanceof Error?new R(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new R("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);n?.startsWith(this.keyPrefix)&&e.push(n);}for(let r of e)localStorage.removeItem(r);}catch(e){throw e instanceof Error?new R(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new R("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix))try{let i=localStorage.getItem(n);if(i){let s=this.compress?this.decompressData(i):i,p=JSON.parse(s);p.expiresAt&&Date.now()>p.expiresAt&&e.push(n);}}catch{e.push(n);}}for(let r of e)localStorage.removeItem(r);}};exports.LocalStorageAdapter=De;exports.Workflow=Rt;exports.WorkflowBody=At;exports.WorkflowNextButton=Lt;exports.WorkflowPersistenceError=R;exports.WorkflowPreviousButton=Jt;exports.WorkflowProvider=he;exports.WorkflowSkipButton=er;exports.WorkflowStepper=sr;exports.WorkflowStoreContext=Pe;exports.combineWorkflowDataForConditions=ye;exports.createStepContext=pe;exports.createWorkflowStore=He;exports.debounce=me;exports.flattenObject=se;exports.flow=Z;exports.generateStorageKey=Se;exports.mergePersistedState=pt;exports.persistedToWorkflowState=ze;exports.useConditionEvaluation=ce;exports.useCurrentStepIndex=Qr;exports.useIsStepPassed=ln;exports.useIsStepVisited=an;exports.usePassedSteps=on;exports.usePersistence=q;exports.useStepDataById=nn;exports.useStepMetadata=dt;exports.useVisitedSteps=sn;exports.useWorkflowActions=un;exports.useWorkflowAllData=tn;exports.useWorkflowAnalytics=be;exports.useWorkflowConditions=xe;exports.useWorkflowContext=N;exports.useWorkflowInitializing=Yr;exports.useWorkflowNavigation=ke;exports.useWorkflowNavigationState=pn;exports.useWorkflowState=mt;exports.useWorkflowStepData=rn;exports.useWorkflowStore=A;exports.useWorkflowStoreApi=cn;exports.useWorkflowSubmission=ve;exports.useWorkflowSubmitState=dn;exports.useWorkflowSubmitting=en;exports.useWorkflowTransitioning=Xr;exports.validatePersistedData=lt;exports.workflowStateToPersisted=fe;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {ComponentRendererWrapper,IdGenerator,normalizeToArray,deepClone,ensureUnique,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {FormBody,useFormConfigContext,useFormSubmitting,useFormValues,form,FormProvider}from'@rilaykit/forms';import Tt,{createContext,useMemo,useCallback,useContext,useState,useRef,useEffect,useReducer}from'react';import {createStore,useStore}from'zustand';import {subscribeWithSelector}from'zustand/middleware';import {jsx}from'react/jsx-runtime';var H=class t{constructor(e,r,n,i){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=r,this.workflowName=n,this.workflowDescription=i;}static create(e,r,n,i){return new t(e,r,n,i)}createStepFromDefinition(e){return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:e.onAfterValidation}}addStep(e){let r=normalizeToArray(e);for(let n of r){let i=this.createStepFromDefinition(n);this.steps.push(i);}return this}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(n=>!this.plugins.some(i=>i.name===n));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 n=this.steps.findIndex(i=>i.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[n]={...this.steps[n],...r},this}addStepConditions(e,r){let n=this.steps.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);let i={...this.steps[n].conditions,...r};return this.steps[n]={...this.steps[n],conditions:i},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 n=new t(this.config,e||`${this.workflowId}-clone`,r||this.workflowName);return n.steps=deepClone(this.steps),n.analytics=this.analytics?deepClone(this.analytics):void 0,n.persistenceConfig=this.persistenceConfig?deepClone(this.persistenceConfig):void 0,n.plugins=[...this.plugins],n}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let r=this.steps.map(n=>n.id);try{ensureUnique(r,"step");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of this.plugins)if(n.dependencies){let i=n.dependencies.filter(s=>!this.plugins.some(d=>d.name===s));i.length>0&&e.push(`Plugin "${n.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((n,i)=>n+i.formConfig.allFields.length,0),r=this.steps.map(n=>n.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function ue(t,e={},r={}){return useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let n=i=>{try{let s;return i&&typeof i=="object"&&"build"in i?s=i.build():s=i,evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:t.visible?n(t.visible):true,disabled:t.disabled?n(t.disabled):false,required:t.required?n(t.required):false,readonly:t.readonly?n(t.readonly):false}},[t,e,r])}function Oe(t,e={}){return useMemo(()=>{let r={};for(let[n,i]of Object.entries(t))if(r[n]={visible:true,disabled:false,required:false,readonly:false},i){let s=d=>{try{return d&&typeof d=="object"&&"build"in d?evaluateCondition(d.build(),e):evaluateCondition(d,e)}catch(o){return console.warn(`Error evaluating condition for field ${n}:`,o),false}};r[n]={visible:i.visible?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[t,e])}function Le(t,e={}){return useMemo(()=>{let r={};for(let[n,i]of Object.entries(t)){let s=Number.parseInt(n,10);if(r[s]={visible:true,disabled:false,required:false,readonly:false},i){let d=o=>{try{return o&&typeof o=="object"&&"build"in o?evaluateCondition(o.build(),e):evaluateCondition(o,e)}catch(f){return console.warn(`Error evaluating condition for step ${s}:`,f),false}};r[s]={visible:i.visible?d(i.visible):true,disabled:i.disabled?d(i.disabled):false,required:i.required?d(i.required):false,readonly:i.readonly?d(i.readonly):false};}}return r},[t,e])}var R=class extends Error{constructor(r,n,i){super(`[WorkflowPersistence] ${r} (Code: ${n})`);this.code=n;this.cause=i;this.name="WorkflowPersistenceError";}};function ce(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),passedSteps:Array.from(e.passedSteps),lastSaved:Date.now(),metadata:r}}function Ue(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),passedSteps:new Set(t.passedSteps||[]),isSubmitting:false,isTransitioning:false}}function at(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function fe(t,e){return e?`${e}:${t}`:t}function Se(t,e){let r=null;return (...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...n);},e);}}function lt(t,e,r="persist"){let n=Ue(e);switch(r){case "persist":return {...n,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...n.visitedSteps]),passedSteps:new Set([...t.passedSteps,...n.passedSteps||[]])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...n.allData,...t.allData},stepData:{...n.stepData,...t.stepData},visitedSteps:new Set([...n.visitedSteps,...t.visitedSteps]),passedSteps:new Set([...n.passedSteps||[],...t.passedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return n}}function q({workflowId:t,workflowState:e,adapter:r,options:n={},userId:i}){let[s,d]=useState(false),[o,f]=useState(null),[u,b]=useState(false),c=useRef(r),l=useRef(n),a=useRef({hasPendingChanges:false});useEffect(()=>{c.current=r,l.current=n;},[r,n]);let y=fe(l.current.storageKey||t,i),k=useCallback(()=>{f(null);},[]),P=useCallback((p,W)=>{let V=p instanceof R?p:new R(`${W} failed: ${p.message}`,"OPERATION_FAILED",p);f(V),console.error("[WorkflowPersistence]",V);},[]),D=useCallback(async p=>{k(),d(true);try{let W=ce(t,p,l.current.metadata);await c.current.save(y,W),a.current.lastSavedState={...p},a.current.hasPendingChanges=!1;}catch(W){throw P(W,"Save"),W}finally{d(false);}},[t,y,k,P]),x=useRef(Se(async p=>{try{await D(p);}catch(W){console.debug("[WorkflowPersistence] Auto-save failed:",W);}},n.debounceMs||500)),h=useCallback((p,W)=>W?p.currentStepIndex!==W.currentStepIndex||JSON.stringify(p.allData)!==JSON.stringify(W.allData)||JSON.stringify(p.stepData)!==JSON.stringify(W.stepData)||p.visitedSteps.size!==W.visitedSteps.size||!Array.from(p.visitedSteps).every(V=>W.visitedSteps.has(V)):true,[]),S=useCallback(async()=>{k(),b(true);try{let p=await c.current.load(y);return p&&(a.current.lastSavedState={currentStepIndex:p.currentStepIndex,allData:p.allData,stepData:p.stepData,visitedSteps:new Set(p.visitedSteps),passedSteps:new Set(p.passedSteps||[]),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},a.current.hasPendingChanges=!1),p}catch(p){return P(p,"Load"),null}finally{setTimeout(()=>b(false),100);}},[y,k,P]),I=useCallback(async()=>{k();try{await c.current.remove(y),a.current.lastSavedState=void 0,a.current.hasPendingChanges=!1;}catch(p){throw P(p,"Clear"),p}},[y,k,P]),L=useCallback(async()=>{try{return await c.current.exists(y)}catch(p){return P(p,"Exists check"),false}},[y,P]);useEffect(()=>{l.current.autoPersist&&(s||u||e.isInitializing||e.isSubmitting||e.isTransitioning||h(e,a.current.lastSavedState)&&(a.current.hasPendingChanges=true,x.current(e)));},[e,s,u,h]);let m=useCallback(async()=>{await D(e);},[D,e]);return {isPersisting:s,persistenceError:o,persistNow:m,loadPersistedData:S,clearPersistedData:I,hasPersistedData:L}}function pt(){let{workflowConfig:t,currentStep:e}=N(),r=useMemo(()=>e?.metadata,[e?.metadata]),n=useMemo(()=>u=>t.steps.find(c=>c.id===u)?.metadata,[t.steps]),i=useMemo(()=>u=>t.steps[u]?.metadata,[t.steps]),s=useMemo(()=>u=>r?u in r:false,[r]),d=useMemo(()=>(u,b)=>r&&u in r?r[u]:b,[r]),o=useMemo(()=>()=>t.steps.map((u,b)=>({id:u.id,title:u.title,index:b,metadata:u.metadata})),[t.steps]),f=useMemo(()=>u=>t.steps.map((b,c)=>({step:b,index:c})).filter(({step:b,index:c})=>u(b.metadata,b.id,c)).map(({step:b})=>b.id),[t.steps]);return {current:r,getByStepId:n,getByStepIndex:i,hasCurrentKey:s,getCurrentValue:d,getAllStepsMetadata:o,findStepsByMetadata:f}}function ge({workflowConfig:t,workflowState:e,workflowContext:r}){let n=useRef(Date.now()),i=useRef(new Map),s=useRef(false),d=useRef(null),o=getGlobalMonitor();useEffect(()=>{t.analytics?.onWorkflowStart&&!s.current&&(s.current=true,t.analytics.onWorkflowStart(t.id,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"start",totalSteps:t.steps.length},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:0,navigationDuration:0,conditionEvaluationDuration:0},"low"));},[t.id,t.analytics,r,o,t.steps.length]),useEffect(()=>{let l=t.steps[e.currentStepIndex];if(l&&d.current!==l.id){if(d.current&&t.analytics?.onStepComplete){let a=i.current.get(d.current);if(a){let y=Date.now()-a;t.analytics.onStepComplete(d.current,y,e.stepData,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_complete",stepId:d.current,duration:y},{timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:y,conditionEvaluationDuration:0},"low");}}d.current=l.id,i.current.set(l.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(l.id,Date.now(),r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_start",stepId:l.id,stepIndex:e.currentStepIndex},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:0},"low");}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData,o,t.id]);let f=useCallback((l,a)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(l,a,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_skip",stepId:l,reason:a},void 0,"medium");},[t.analytics,r,o,t.id]),u=useCallback(l=>{t.analytics?.onError&&t.analytics.onError(l,r),o&&o.trackError(l,`workflow_${t.id}`,{workflowId:t.id,currentStepIndex:e.currentStepIndex,currentStepId:t.steps[e.currentStepIndex]?.id,workflowContext:r});},[t.analytics,r,o,t.id,e.currentStepIndex,t.steps]),b=useCallback((l,a,y)=>{if(!o)return;let k={timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:a,navigationDuration:y,conditionEvaluationDuration:0};o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"navigation",fromStep:l,toStep:a,direction:a>l?"forward":"backward"},k,y>1e3?"medium":"low");},[o,t.id,t.steps.length]),c=useCallback((l,a)=>{if(!o)return;let y={timestamp:Date.now(),duration:l,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:l};o.track("condition_evaluation",`workflow_${t.id}`,{workflowId:t.id,conditionsCount:a,currentStepIndex:e.currentStepIndex},y,l>100?"medium":"low");},[o,t.id,t.steps.length,e.currentStepIndex]);return {analyticsStartTime:n,trackStepSkip:f,trackError:u,trackNavigation:b,trackConditionEvaluation:c}}function se(t,e=""){let r={};for(let n in t)if(n in t){let i=t[n],s=e?`${e}.${n}`:n;i!==null&&typeof i=="object"&&!Array.isArray(i)&&!(i instanceof Date)?Object.assign(r,se(i,s)):r[s]=i;}return r}function be(t,e){let r=se(t),n=se(e);return {...{...t,...e},...r,...n}}function $e(t,e){return {visible:t.visible,skippable:e===true||t.required}}function ye({workflowConfig:t,workflowState:e,currentStep:r}){let n=useMemo(()=>be(e.allData,e.stepData),[e.allData,e.stepData]),i=useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),s=ue(i,n,{visible:true,disabled:false,required:false,readonly:false}),d=useMemo(()=>$e(s,r?.allowSkip),[s,r?.allowSkip]),o=useMemo(()=>{let x={};return t.steps.forEach((h,S)=>{h.conditions&&(x[S]={visible:h.conditions.visible,required:h.conditions.skippable});}),x},[t.steps]),f=Le(o,n),u=useMemo(()=>{let x={};return t.steps.forEach((h,S)=>{let I=f[S];I?x[S]=$e(I,h.allowSkip):x[S]={visible:true,skippable:h.allowSkip===true};}),x},[t.steps,f]),b=useMemo(()=>{if(!r?.formConfig?.allFields)return {};let x={};for(let h of r.formConfig.allFields)h.conditions&&(x[h.id]=h.conditions);return x},[r?.formConfig?.allFields]),c=Oe(b,n),l=useCallback(x=>x<0||x>=t.steps.length?false:u[x]?.visible??true,[u,t.steps.length]),a=useCallback(x=>x<0||x>=t.steps.length?false:u[x]?.skippable??false,[u,t.steps.length]),y=useCallback(x=>c[x]?.visible??true,[c]),k=useCallback(x=>c[x]?.disabled??false,[c]),P=useCallback(x=>c[x]?.required??false,[c]),D=useCallback(x=>c[x]?.readonly??false,[c]);return {stepConditions:d,fieldConditions:c,allStepConditions:u,isStepVisible:l,isStepSkippable:a,isFieldVisible:y,isFieldDisabled:k,isFieldRequired:P,isFieldReadonly:D}}function ve({workflowConfig:t,workflowState:e,workflowContext:r,conditionsHelpers:n,setCurrentStep:i,setTransitioning:s,markStepVisited:d,markStepPassed:o,setStepData:f,onStepChange:u}){let b=useRef(u);b.current=u;let c=t.steps[e.currentStepIndex],l=useCallback(()=>({setStepData:(m,p)=>{f(p,m);},setStepFields:(m,p)=>{let V={...e.allData[m]||{},...p};f(V,m);},getStepData:m=>e.allData[m]||{},setNextStepField:(m,p)=>{let W=e.currentStepIndex+1;if(W<t.steps.length){let V=t.steps[W].id,X={...e.allData[V]||{},[m]:p};f(X,V);}},setNextStepFields:m=>{let p=e.currentStepIndex+1;if(p<t.steps.length){let W=t.steps[p].id,z={...e.allData[W]||{},...m};f(z,W);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,f]),a=useCallback(async m=>{if(m<0||m>=t.steps.length||!n.isStepVisible(m))return false;s(true);try{return b.current&&b.current(e.currentStepIndex,m,r),i(m),d(m,t.steps[m].id),!0}catch(p){return console.error("Step transition failed:",p),t.analytics?.onError&&t.analytics.onError(p,r),false}finally{s(false);}},[t.steps,t.analytics,n,e.currentStepIndex,r,s,i,d]),y=useCallback(m=>{for(let p=m+1;p<t.steps.length;p++)if(n.isStepVisible(p))return p;return null},[t.steps.length,n]),k=useCallback(m=>{for(let p=m-1;p>=0;p--)if(n.isStepVisible(p))return p;return null},[n]),P=useCallback(async()=>{if(c?.onAfterValidation)try{let p=l();await c.onAfterValidation(e.stepData,p,r);}catch(p){return console.error("onAfterValidation failed:",p),t.analytics?.onError&&t.analytics.onError(p,r),false}o(c.id);let m=y(e.currentStepIndex);return m===null?false:a(m)},[c,l,e.stepData,r,t.analytics,e.currentStepIndex,y,a,o]),D=useCallback(async()=>{let m=k(e.currentStepIndex);return m===null?false:a(m)},[e.currentStepIndex,k,a]),x=useCallback(async()=>!c?.allowSkip&&!n.isStepSkippable(e.currentStepIndex)?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(c.id,"user_skip",r),P()),[c,n,e.currentStepIndex,t.analytics,r,P]),h=useCallback(m=>m<0||m>=t.steps.length?false:n.isStepVisible(m),[t.steps.length,n]),S=useCallback(()=>{let m=y(e.currentStepIndex);return m!==null&&h(m)},[e.currentStepIndex,y,h]),I=useCallback(()=>{let m=k(e.currentStepIndex);return m!==null&&h(m)},[e.currentStepIndex,k,h]),L=useCallback(()=>c?.allowSkip===true&&n.isStepSkippable(e.currentStepIndex),[c?.allowSkip,n,e.currentStepIndex]);return {goToStep:a,goNext:P,goPrevious:D,skipStep:x,canGoToStep:h,canGoNext:S,canGoPrevious:I,canSkipCurrentStep:L}}function ft(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.visitedSteps,e.stepId])};case "MARK_STEP_PASSED":return {...t,passedSteps:new Set([...t.passedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function St({defaultValues:t={},defaultStepIndex:e,workflowSteps:r,persistence:n}){let i=useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let I=0;I<e;I++)r[I]&&S.add(r[I].id);return S},[e,r]),s=useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let I=0;I<e;I++)r[I]&&S.add(r[I].id);return S},[e,r]),d={currentStepIndex:e??0,allData:t,stepData:{},visitedSteps:i,passedSteps:s,isSubmitting:false,isTransitioning:false,isInitializing:true},[o,f]=useReducer(ft,d),u=n?.adapter?q({workflowId:n.workflowId,workflowState:o,adapter:n.adapter,options:n.options,userId:n.userId}):null,b=useCallback(S=>{f({type:"SET_CURRENT_STEP",stepIndex:S});},[]),c=useCallback((S,I)=>{f({type:"SET_STEP_DATA",data:S,stepId:I});},[]),l=useCallback((S,I,L)=>{f({type:"SET_FIELD_VALUE",fieldId:S,value:I,stepId:L});},[]),a=useCallback(S=>{f({type:"SET_SUBMITTING",isSubmitting:S});},[]),y=useCallback(S=>{f({type:"SET_TRANSITIONING",isTransitioning:S});},[]),k=useCallback((S,I)=>{f({type:"MARK_STEP_VISITED",stepIndex:S,stepId:I});},[]),P=useCallback(S=>{f({type:"MARK_STEP_PASSED",stepId:S});},[]),D=useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),x=useCallback(()=>{f({type:"SET_INITIALIZATION_COMPLETE"});},[]),h=useCallback(async()=>{if(!u)return x(),false;try{let S=await u.loadPersistedData();if(S){let I={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),passedSteps:new Set(S.passedSteps||[])};return f({type:"LOAD_PERSISTED_STATE",state:I}),x(),!0}}catch(S){console.error("Failed to load persisted state:",S);}return x(),false},[u,x]);return {workflowState:o,setCurrentStep:b,setStepData:c,setFieldValue:l,setSubmitting:a,setTransitioning:y,markStepVisited:k,markStepPassed:P,resetWorkflow:D,loadPersistedState:h,persistence:u?{isPersisting:u.isPersisting,persistenceError:u.persistenceError,persistNow:u.persistNow,clearPersistedData:u.clearPersistedData,hasPersistedData:u.hasPersistedData}:null}}function ke({workflowConfig:t,workflowState:e,workflowContext:r,setSubmitting:n,onWorkflowComplete:i,analyticsStartTime:s}){let d=useRef(i);d.current=i;let o=useCallback(async()=>{n(true);try{if(d.current&&await d.current(e.allData),t.analytics?.onWorkflowComplete){let u=Date.now()-s.current;t.analytics.onWorkflowComplete(t.id,u,e.allData);}}catch(u){throw console.error("Workflow submission failed:",u),t.analytics?.onError&&t.analytics.onError(u,r),u}finally{n(false);}},[e.allData,t.analytics,t.id,r,s,n]),f=useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:o,isSubmitting:e.isSubmitting,canSubmit:f()}}function Je(t={}){let{defaultValues:e={},defaultStepIndex:r=0,initialVisitedSteps:n=new Set,initialPassedSteps:i=new Set}=t;return createStore()(subscribeWithSelector((s,d)=>({currentStepIndex:r,isTransitioning:false,isInitializing:true,allData:{...e},stepData:{},visitedSteps:new Set(n),passedSteps:new Set(i),isSubmitting:false,_defaultValues:{...e},_defaultStepIndex:r,_setCurrentStep:o=>{s({currentStepIndex:o});},_setStepData:(o,f)=>{s(u=>({stepData:o,allData:{...u.allData,[f]:o}}));},_setAllData:o=>{s({allData:o});},_setFieldValue:(o,f,u)=>{s(b=>{let c={...b.stepData,[o]:f};return {stepData:c,allData:{...b.allData,[u]:c}}});},_setSubmitting:o=>{s({isSubmitting:o});},_setTransitioning:o=>{s({isTransitioning:o});},_setInitializing:o=>{s({isInitializing:o});},_markStepVisited:o=>{s(f=>({visitedSteps:new Set([...f.visitedSteps,o])}));},_markStepPassed:o=>{s(f=>({passedSteps:new Set([...f.passedSteps,o])}));},_reset:()=>{let o=d();s({currentStepIndex:o._defaultStepIndex,allData:{...o._defaultValues},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false});},_loadPersistedState:o=>{s(f=>({...f,...o,isInitializing:false}));}})))}var xe=createContext(null);function A(){let t=useContext(xe);if(!t)throw new Error("useWorkflowStore must be used within a WorkflowProvider");return t}function jr(){let t=A();return useStore(t,e=>e.currentStepIndex)}function Zr(){let t=A();return useStore(t,e=>e.isTransitioning)}function Hr(){let t=A();return useStore(t,e=>e.isInitializing)}function Qr(){let t=A();return useStore(t,e=>e.isSubmitting)}function Xr(){let t=A();return useStore(t,e=>e.allData)}function Yr(){let t=A();return useStore(t,e=>e.stepData)}function en(t){let e=A();return useStore(e,r=>r.allData[t])}function tn(){let t=A();return useStore(t,e=>e.visitedSteps)}function rn(){let t=A();return useStore(t,e=>e.passedSteps)}function nn(t){let e=A();return useStore(e,r=>r.visitedSteps.has(t))}function sn(t){let e=A();return useStore(e,r=>r.passedSteps.has(t))}function on(){let t=A(),e=useStore(t,i=>i.currentStepIndex),r=useStore(t,i=>i.isTransitioning),n=useStore(t,i=>i.isSubmitting);return {currentStepIndex:e,isTransitioning:r,isSubmitting:n}}function an(){let t=A(),e=useStore(t,i=>i.isSubmitting),r=useStore(t,i=>i.isTransitioning),n=useStore(t,i=>i.isInitializing);return {isSubmitting:e,isTransitioning:r,isInitializing:n}}function ln(){let t=A();return {setCurrentStep:e=>t.getState()._setCurrentStep(e),setStepData:(e,r)=>t.getState()._setStepData(e,r),setAllData:e=>t.getState()._setAllData(e),setFieldValue:(e,r,n)=>t.getState()._setFieldValue(e,r,n),setSubmitting:e=>t.getState()._setSubmitting(e),setTransitioning:e=>t.getState()._setTransitioning(e),setInitializing:e=>t.getState()._setInitializing(e),markStepVisited:e=>t.getState()._markStepVisited(e),markStepPassed:e=>t.getState()._markStepPassed(e),reset:()=>t.getState()._reset(),loadPersistedState:e=>t.getState()._loadPersistedState(e)}}function pn(){return A()}var It={save:async()=>{},load:async()=>null,remove:async()=>{},exists:async()=>false},je=createContext(null);function Wt(t,e){let r=new Set,n=new Set;if(t>0)for(let i=0;i<t;i++)e[i]&&(r.add(e[i].id),n.add(e[i].id));return {visitedSteps:r,passedSteps:n}}function he({children:t,workflowConfig:e,defaultValues:r={},defaultStep:n,onStepChange:i,onWorkflowComplete:s,className:d}){let o=useRef(i),f=useRef(s);o.current=i,f.current=s;let u=useMemo(()=>{if(!n)return 0;let v=e.steps.findIndex(g=>g.id===n);return v===-1?(console.warn(`Default step with ID "${n}" not found. Starting at step 0.`),0):v},[n,e.steps]),b=useMemo(()=>Wt(u,e.steps),[u,e.steps]),c=useRef(null);c.current||(c.current=Je({defaultValues:r,defaultStepIndex:u,initialVisitedSteps:b.visitedSteps,initialPassedSteps:b.passedSteps}));let l=c.current,[a,y]=useState(()=>{let v=l.getState();return {currentStepIndex:v.currentStepIndex,allData:v.allData,stepData:v.stepData,visitedSteps:v.visitedSteps,passedSteps:v.passedSteps,isSubmitting:v.isSubmitting,isTransitioning:v.isTransitioning,isInitializing:v.isInitializing}});useEffect(()=>l.subscribe(g=>{y({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:g.visitedSteps,passedSteps:g.passedSteps,isSubmitting:g.isSubmitting,isTransitioning:g.isTransitioning,isInitializing:g.isInitializing});}),[l]);let k=useCallback(v=>l.getState()._setCurrentStep(v),[l]),P=useCallback((v,g)=>l.getState()._setStepData(v,g),[l]),D=useCallback((v,g,E)=>l.getState()._setFieldValue(v,g,E),[l]),x=useCallback(v=>l.getState()._setSubmitting(v),[l]),h=useCallback(v=>l.getState()._setTransitioning(v),[l]),S=useCallback((v,g)=>l.getState()._markStepVisited(g),[l]),I=useCallback(v=>l.getState()._markStepPassed(v),[l]),L=useCallback(()=>l.getState()._reset(),[l]),m=!!e.persistence?.adapter,p=q({workflowId:e.id,workflowState:a,adapter:e.persistence?.adapter??It,options:e.persistence?.options,userId:e.persistence?.userId}),W=useRef(p);W.current=p;let V=useRef(false);useEffect(()=>{if(V.current)return;V.current=true,(async()=>{if(m)try{let g=await W.current.loadPersistedData();if(g){l.getState()._loadPersistedState({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:new Set(g.visitedSteps),passedSteps:new Set(g.passedSteps||[])});return}}catch(g){console.error("Failed to load persisted state:",g);}l.getState()._setInitializing(false);})();},[l,m]);let z=useMemo(()=>({isPersisting:m?p.isPersisting:false,persistenceError:m?p.persistenceError:null,persistNow:m?p.persistNow:void 0}),[m,p.isPersisting,p.persistenceError,p.persistNow]),X=useMemo(()=>({workflowId:e.id,currentStepIndex:a.currentStepIndex,totalSteps:e.steps.length,allData:a.allData,stepData:a.stepData,visitedSteps:a.visitedSteps}),[e.id,e.steps.length,a.currentStepIndex,a.allData,a.stepData,a.visitedSteps]),C=useMemo(()=>e.steps[a.currentStepIndex],[e.steps,a.currentStepIndex]),K=useMemo(()=>C?.formConfig,[C?.formConfig]),_=ye({workflowConfig:e,workflowState:a,currentStep:C}),G=useMemo(()=>{let v=-1;for(let w=0;w<e.steps.length;w++)if(_.isStepVisible(w)){v=w;break}let g=-1;for(let w=e.steps.length-1;w>=0;w--)if(_.isStepVisible(w)){g=w;break}let E=new Set;for(let w=0;w<e.steps.length;w++){let te=e.steps[w];_.isStepVisible(w)&&a.visitedSteps.has(te.id)&&E.add(te.id);}return {...X,isFirstStep:a.currentStepIndex===v,isLastStep:a.currentStepIndex===g,visibleVisitedSteps:E,passedSteps:a.passedSteps}},[X,a.currentStepIndex,a.visitedSteps,a.passedSteps,_,e.steps]),{analyticsStartTime:Xe}=ge({workflowConfig:e,workflowState:a,workflowContext:G}),{goToStep:De,goNext:Y,goPrevious:we,skipStep:Re,canGoToStep:Ee,canGoNext:Te,canGoPrevious:Ce,canSkipCurrentStep:Ae}=ve({workflowConfig:e,workflowState:a,workflowContext:G,conditionsHelpers:_,setCurrentStep:k,setTransitioning:h,markStepVisited:S,markStepPassed:I,setStepData:P,onStepChange:o.current}),ae=useRef(false);useEffect(()=>{if(ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){for(let g=0;g<e.steps.length;g++)if(_.isStepVisible(g)){k(g),S(g,e.steps[g].id);break}}ae.current=true;},[a.currentStepIndex,e.steps,k,S,_]),useEffect(()=>{if(!ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){let g=null;for(let E=a.currentStepIndex+1;E<e.steps.length;E++)if(_.isStepVisible(E)){g=E;break}if(g===null){for(let E=a.currentStepIndex-1;E>=0;E--)if(_.isStepVisible(E)){g=E;break}}g!==null&&(k(g),S(g,e.steps[g].id));}},[_,a.currentStepIndex,e.steps,k,S]);let{submitWorkflow:ee,isSubmitting:_e,canSubmit:Ve}=ke({workflowConfig:e,workflowState:a,workflowContext:G,setSubmitting:x,onWorkflowComplete:f.current,analyticsStartTime:Xe}),le=useCallback((v,g)=>{D(v,g,C?.id||"");},[D,C?.id]),Ne=useCallback(v=>{P(v,C?.id||"");},[P,C?.id]),Ye=useCallback(async v=>{C?.id&&v&&P(v,C.id),G.isLastStep?await ee():await Y();},[G.isLastStep,ee,Y,C?.id,P]),Fe=useMemo(()=>({goToStep:De,goNext:Y,goPrevious:we,skipStep:Re,canGoToStep:Ee,canGoNext:Te,canGoPrevious:Ce,canSkipCurrentStep:Ae}),[De,Y,we,Re,Ee,Te,Ce,Ae]),Be=useMemo(()=>({setValue:le,setStepData:Ne,resetWorkflow:L}),[le,Ne,L]),Me=useMemo(()=>({submitWorkflow:ee,isSubmitting:_e,canSubmit:Ve}),[ee,_e,Ve]),et=useMemo(()=>({workflowState:a,workflowConfig:e,currentStep:C,context:G,formConfig:K,conditionsHelpers:_,currentStepMetadata:C?.metadata,...Fe,...Be,...Me,persistNow:z.persistNow,isPersisting:z.isPersisting,persistenceError:z.persistenceError}),[a,e,C,G,K,_,Fe,Be,Me,z]),tt=useMemo(()=>{if(!C?.id)return {};let v=a?.allData[C.id]||{};if(!K?.allFields)return v;let g=new Set(K.allFields.map(w=>w.id)),E={};for(let[w,te]of Object.entries(v))g.has(w)&&(E[w]=te);return E},[a?.allData,C?.id,K?.allFields]),rt=useMemo(()=>a.isInitializing.toString(),[a.isInitializing]);return jsx(xe.Provider,{value:l,children:jsx(je.Provider,{value:et,children:jsx(FormProvider,{formConfig:K,defaultValues:tt,onFieldChange:le,"data-workflow-id":e.id,className:d,onSubmit:Ye,children:t},rt)})})}function N(){let t=useContext(je);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function wt({children:t,workflowConfig:e,...r}){let n=useMemo(()=>e instanceof H?e.build():e,[e]);return jsx(he,{...r,workflowConfig:n,children:t})}var Ct=Tt.memo(function({stepId:e,children:r}){let{currentStep:n}=N();if(!n||e&&n.id!==e)return null;let{formConfig:i,renderer:s}=n;return i?s?s(n):r??jsx(FormBody,{}):null});var Ot=Tt.memo(function({className:e,isSubmitting:r,...n}){let{context:i,workflowState:s,workflowConfig:d,currentStep:o}=N(),{submit:f}=useFormConfigContext(),u=useFormSubmitting(),b=useFormValues(),c=useMemo(()=>{let y=u||s.isSubmitting,k=r??y,P=!s.isTransitioning&&!k;return {finalIsSubmitting:k,canGoNext:P}},[u,s.isSubmitting,s.isTransitioning,r]),l=useCallback(async y=>{y?.preventDefault(),c.canGoNext&&await f(y);},[c.canGoNext,f]),a=useMemo(()=>({isLastStep:i.isLastStep,canGoNext:c.canGoNext,isSubmitting:c.finalIsSubmitting,onSubmit:l,className:e,currentStep:o,stepData:b,allData:i.allData,context:i}),[i.isLastStep,c.canGoNext,c.finalIsSubmitting,l,e,o,b,i.allData,i]);return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:d.renderConfig?.nextButtonRenderer,props:a,...n})});var qt=Tt.memo(function({className:e,isSubmitting:r,...n}){let{context:i,goPrevious:s,workflowState:d,workflowConfig:o,currentStep:f,canGoPrevious:u}=N(),b=useFormSubmitting(),c=useFormValues(),l=useMemo(()=>{let k=b||d.isSubmitting,P=r??k,D=u()&&!d.isTransitioning&&!P;return {finalIsSubmitting:P,canGoPrevious:D}},[b,d.isSubmitting,d.isTransitioning,u,r]),a=useCallback(async k=>{k?.preventDefault(),l.canGoPrevious&&await s();},[l.canGoPrevious,s]),y=useMemo(()=>({canGoPrevious:l.canGoPrevious,isSubmitting:l.finalIsSubmitting,onPrevious:a,className:e,currentStep:f,stepData:c,allData:i.allData,context:i}),[l.canGoPrevious,l.finalIsSubmitting,a,e,f,c,i.allData,i]);return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:o.renderConfig?.previousButtonRenderer,props:y,...n})});var Yt=Tt.memo(function({className:e,isSubmitting:r,...n}){let{currentStep:i,skipStep:s,workflowState:d,workflowConfig:o,context:f,conditionsHelpers:u}=N(),b=useFormSubmitting(),c=useFormValues(),l=useMemo(()=>{let k=b||d.isSubmitting,P=r??k,D=(!!i?.allowSkip||u.isStepSkippable(d.currentStepIndex))&&!d.isTransitioning&&!P;return {finalIsSubmitting:P,canSkip:D}},[b,d.isSubmitting,d.isTransitioning,d.currentStepIndex,i?.allowSkip,u.isStepSkippable,r]),a=useCallback(async k=>{k?.preventDefault(),l.canSkip&&await s();},[l.canSkip,s]),y=useMemo(()=>({canSkip:l.canSkip,isSubmitting:l.finalIsSubmitting,onSkip:a,className:e,currentStep:i,stepData:c,allData:f.allData,context:f}),[l.canSkip,l.finalIsSubmitting,a,e,i,c,f.allData,f]);return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:o.renderConfig?.skipButtonRenderer,props:y,...n})});var ir=Tt.memo(function({onStepClick:e,className:r,...n}){let{workflowConfig:i,workflowState:s,context:d,goToStep:o,conditionsHelpers:f}=N(),{visibleSteps:u,visibleToOriginalIndexMap:b,originalToVisibleIndexMap:c}=useMemo(()=>{let k=[],P=new Map,D=new Map;return i.steps.forEach((x,h)=>{if(f.isStepVisible(h)){let S=k.length;k.push(x),P.set(S,h),D.set(h,S);}}),{visibleSteps:k,visibleToOriginalIndexMap:P,originalToVisibleIndexMap:D}},[i.steps,f]),l=useCallback(k=>{let P=b.get(k);P!==void 0&&(e?e(P):o(P));},[b,e,o]),a=useMemo(()=>c.get(s.currentStepIndex)??-1,[c,s.currentStepIndex]),y=useMemo(()=>({steps:u,currentStepIndex:a,visitedSteps:d.visibleVisitedSteps,onStepClick:l,className:r}),[u,a,d.visibleVisitedSteps,l,r]);return jsx(ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:y,...n})});var We=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,r){if(this._isAvailable)try{let n=this.getStorageKey(e),i={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(i),d=this.compress?this.compressData(s):s;localStorage.setItem(n,d);}catch(n){if(n instanceof Error)if(n.name==="QuotaExceededError"||n.message.includes("quota")){await this.clearExpiredData();try{let i=this.getStorageKey(e),s={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},d=JSON.stringify(s),o=this.compress?this.compressData(d):d;localStorage.setItem(i,o);}catch(i){throw new R("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",i)}}else throw new R(`Failed to save to localStorage: ${n.message}`,"SAVE_FAILED",n);else throw new R("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return null;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(r){throw r instanceof Error?new R(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new R("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new R(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new R("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return !1;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix)){let i=n.substring(this.keyPrefix.length);await this.exists(i)&&e.push(i);}}return e}catch(e){throw e instanceof Error?new R(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new R("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);n?.startsWith(this.keyPrefix)&&e.push(n);}for(let r of e)localStorage.removeItem(r);}catch(e){throw e instanceof Error?new R(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new R("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix))try{let i=localStorage.getItem(n);if(i){let s=this.compress?this.decompressData(i):i,d=JSON.parse(s);d.expiresAt&&Date.now()>d.expiresAt&&e.push(n);}}catch{e.push(n);}}for(let r of e)localStorage.removeItem(r);}};export{We as LocalStorageAdapter,wt as Workflow,Ct as WorkflowBody,Ot as WorkflowNextButton,R as WorkflowPersistenceError,qt as WorkflowPreviousButton,he as WorkflowProvider,Yt as WorkflowSkipButton,ir as WorkflowStepper,xe as WorkflowStoreContext,be as combineWorkflowDataForConditions,Je as createWorkflowStore,Se as debounce,se as flattenObject,H as flow,fe as generateStorageKey,lt as mergePersistedState,Ue as persistedToWorkflowState,ue as useConditionEvaluation,jr as useCurrentStepIndex,sn as useIsStepPassed,nn as useIsStepVisited,rn as usePassedSteps,q as usePersistence,en as useStepDataById,pt as useStepMetadata,tn as useVisitedSteps,ln as useWorkflowActions,Xr as useWorkflowAllData,ge as useWorkflowAnalytics,ye as useWorkflowConditions,N as useWorkflowContext,Hr as useWorkflowInitializing,ve as useWorkflowNavigation,on as useWorkflowNavigationState,St as useWorkflowState,Yr as useWorkflowStepData,A as useWorkflowStore,pn as useWorkflowStoreApi,ke as useWorkflowSubmission,an as useWorkflowSubmitState,Qr as useWorkflowSubmitting,Zr as useWorkflowTransitioning,at as validatePersistedData,ce as workflowStateToPersisted};
1
+ import {ComponentRendererWrapper,IdGenerator,normalizeToArray,deepClone,ensureUnique,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {FormBody,useFormConfigContext,useFormSubmitting,useFormValues,form,FormProvider}from'@rilaykit/forms';import Ct,{createContext,useMemo,useCallback,useContext,useState,useRef,useEffect,useReducer}from'react';import {createStore,useStore}from'zustand';import {subscribeWithSelector}from'zustand/middleware';import {jsx}from'react/jsx-runtime';function pe(t,e,r,n){return {data:t,next:{prefill:i=>{e.setNextStepFields(i);},skip:()=>{console.warn("step.next.skip() not yet implemented");}},workflow:{get:i=>e.getStepData(i),all:()=>e.getAllData(),goto:i=>{console.warn("step.workflow.goto() not yet implemented");}},meta:n||{},isFirst:r.isFirstStep,isLast:r.isLastStep}}var Z=class t{constructor(e,r,n,i){this.steps=[];this.plugins=[];this.idGenerator=new IdGenerator;this.config=e,this.workflowId=r||`workflow-${Math.random().toString(36).substring(2,15)}`,this.workflowName=n||"Workflow",this.workflowDescription=i;}static create(e,r,n,i){return new t(e,r,n,i)}createStepFromDefinition(e){let r=e.after?(n,i,s)=>{let p=pe(n,i,s,e.metadata);return e.after(p)}:e.onAfterValidation;return {id:e.id||this.idGenerator.next("step"),title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,renderer:e.renderer,conditions:e.conditions,metadata:e.metadata,onAfterValidation:r}}_addStepsInternal(e){let r=normalizeToArray(e);for(let n of r){let i=this.createStepFromDefinition(n);this.steps.push(i);}return this}addStep(e){return this._addStepsInternal(e)}step(e){return this._addStepsInternal(e)}configure(e){return e.analytics&&(this.analytics=e.analytics),e.persistence&&(this.persistenceConfig=e.persistence),this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(r){throw new Error(`Failed to install plugin "${e.name}": ${r instanceof Error?r.message:String(r)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let r=e.dependencies.filter(n=>!this.plugins.some(i=>i.name===n));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 n=this.steps.findIndex(i=>i.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[n]={...this.steps[n],...r},this}addStepConditions(e,r){let n=this.steps.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Step with ID "${e}" not found`);let i={...this.steps[n].conditions,...r};return this.steps[n]={...this.steps[n],conditions:i},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 n=new t(this.config,e||`${this.workflowId}-clone`,r||this.workflowName);return n.steps=deepClone(this.steps),n.analytics=this.analytics?deepClone(this.analytics):void 0,n.persistenceConfig=this.persistenceConfig?deepClone(this.persistenceConfig):void 0,n.plugins=[...this.plugins],n}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let r=this.steps.map(n=>n.id);try{ensureUnique(r,"step");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of this.plugins)if(n.dependencies){let i=n.dependencies.filter(s=>!this.plugins.some(p=>p.name===s));i.length>0&&e.push(`Plugin "${n.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){let e=this.steps.reduce((n,i)=>n+i.formConfig.allFields.length,0),r=this.steps.map(n=>n.formConfig.allFields.length);return {totalSteps:this.steps.length,totalFields:e,averageFieldsPerStep:this.steps.length>0?e/this.steps.length:0,maxFieldsInStep:r.length>0?Math.max(...r):0,minFieldsInStep:r.length>0?Math.min(...r):0,hasAnalytics:!!this.analytics}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins,renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,analytics:this.analytics,persistence:this.persistenceConfig,plugins:this.plugins.map(e=>({name:e.name,version:e.version}))}}fromJSON(e){return this.workflowId=e.workflowId,this.workflowName=e.workflowName,this.workflowDescription=e.workflowDescription,this.steps=e.steps,this.analytics=e.analytics,this.persistenceConfig=e.persistence,this.plugins=e.plugins||[],this}};function ce(t,e={},r={}){return useMemo(()=>{if(!t)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let n=i=>{try{let s;return i&&typeof i=="object"&&"build"in i?s=i.build():s=i,evaluateCondition(s,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:t.visible?n(t.visible):true,disabled:t.disabled?n(t.disabled):false,required:t.required?n(t.required):false,readonly:t.readonly?n(t.readonly):false}},[t,e,r])}function Le(t,e={}){return useMemo(()=>{let r={};for(let[n,i]of Object.entries(t))if(r[n]={visible:true,disabled:false,required:false,readonly:false},i){let s=p=>{try{return p&&typeof p=="object"&&"build"in p?evaluateCondition(p.build(),e):evaluateCondition(p,e)}catch(o){return console.warn(`Error evaluating condition for field ${n}:`,o),false}};r[n]={visible:i.visible?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[t,e])}function Ue(t,e={}){return useMemo(()=>{let r={};for(let[n,i]of Object.entries(t)){let s=Number.parseInt(n,10);if(r[s]={visible:true,disabled:false,required:false,readonly:false},i){let p=o=>{try{return o&&typeof o=="object"&&"build"in o?evaluateCondition(o.build(),e):evaluateCondition(o,e)}catch(f){return console.warn(`Error evaluating condition for step ${s}:`,f),false}};r[s]={visible:i.visible?p(i.visible):true,disabled:i.disabled?p(i.disabled):false,required:i.required?p(i.required):false,readonly:i.readonly?p(i.readonly):false};}}return r},[t,e])}var R=class extends Error{constructor(r,n,i){super(`[WorkflowPersistence] ${r} (Code: ${n})`);this.code=n;this.cause=i;this.name="WorkflowPersistenceError";}};function fe(t,e,r){return {workflowId:t,currentStepIndex:e.currentStepIndex,allData:{...e.allData},stepData:{...e.stepData},visitedSteps:Array.from(e.visitedSteps),passedSteps:Array.from(e.passedSteps),lastSaved:Date.now(),metadata:r}}function ze(t){return {currentStepIndex:t.currentStepIndex,allData:{...t.allData},stepData:{...t.stepData},visitedSteps:new Set(t.visitedSteps),passedSteps:new Set(t.passedSteps||[]),isSubmitting:false,isTransitioning:false}}function lt(t){if(!t||typeof t!="object")return false;let e=["workflowId","currentStepIndex","allData","stepData","visitedSteps","lastSaved"];for(let r of e)if(!(r in t))return false;return !(typeof t.workflowId!="string"||typeof t.currentStepIndex!="number"||typeof t.allData!="object"||typeof t.stepData!="object"||!Array.isArray(t.visitedSteps)||typeof t.lastSaved!="number")}function Se(t,e){return e?`${e}:${t}`:t}function me(t,e){let r=null;return (...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{t(...n);},e);}}function pt(t,e,r="persist"){let n=ze(e);switch(r){case "persist":return {...n,isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};case "current":return {...t,visitedSteps:new Set([...t.visitedSteps,...n.visitedSteps]),passedSteps:new Set([...t.passedSteps,...n.passedSteps||[]])};case "merge":return {currentStepIndex:t.currentStepIndex,allData:{...n.allData,...t.allData},stepData:{...n.stepData,...t.stepData},visitedSteps:new Set([...n.visitedSteps,...t.visitedSteps]),passedSteps:new Set([...n.passedSteps||[],...t.passedSteps]),isSubmitting:t.isSubmitting,isTransitioning:t.isTransitioning};default:return n}}function q({workflowId:t,workflowState:e,adapter:r,options:n={},userId:i}){let[s,p]=useState(false),[o,f]=useState(null),[u,b]=useState(false),c=useRef(r),l=useRef(n),a=useRef({hasPendingChanges:false});useEffect(()=>{c.current=r,l.current=n;},[r,n]);let y=Se(l.current.storageKey||t,i),k=useCallback(()=>{f(null);},[]),P=useCallback((d,W)=>{let V=d instanceof R?d:new R(`${W} failed: ${d.message}`,"OPERATION_FAILED",d);f(V),console.error("[WorkflowPersistence]",V);},[]),D=useCallback(async d=>{k(),p(true);try{let W=fe(t,d,l.current.metadata);await c.current.save(y,W),a.current.lastSavedState={...d},a.current.hasPendingChanges=!1;}catch(W){throw P(W,"Save"),W}finally{p(false);}},[t,y,k,P]),v=useRef(me(async d=>{try{await D(d);}catch(W){console.debug("[WorkflowPersistence] Auto-save failed:",W);}},n.debounceMs||500)),I=useCallback((d,W)=>W?d.currentStepIndex!==W.currentStepIndex||JSON.stringify(d.allData)!==JSON.stringify(W.allData)||JSON.stringify(d.stepData)!==JSON.stringify(W.stepData)||d.visitedSteps.size!==W.visitedSteps.size||!Array.from(d.visitedSteps).every(V=>W.visitedSteps.has(V)):true,[]),S=useCallback(async()=>{k(),b(true);try{let d=await c.current.load(y);return d&&(a.current.lastSavedState={currentStepIndex:d.currentStepIndex,allData:d.allData,stepData:d.stepData,visitedSteps:new Set(d.visitedSteps),passedSteps:new Set(d.passedSteps||[]),isSubmitting:!1,isTransitioning:!1,isInitializing:!1},a.current.hasPendingChanges=!1),d}catch(d){return P(d,"Load"),null}finally{setTimeout(()=>b(false),100);}},[y,k,P]),h=useCallback(async()=>{k();try{await c.current.remove(y),a.current.lastSavedState=void 0,a.current.hasPendingChanges=!1;}catch(d){throw P(d,"Clear"),d}},[y,k,P]),L=useCallback(async()=>{try{return await c.current.exists(y)}catch(d){return P(d,"Exists check"),false}},[y,P]);useEffect(()=>{l.current.autoPersist&&(s||u||e.isInitializing||e.isSubmitting||e.isTransitioning||I(e,a.current.lastSavedState)&&(a.current.hasPendingChanges=true,v.current(e)));},[e,s,u,I]);let m=useCallback(async()=>{await D(e);},[D,e]);return {isPersisting:s,persistenceError:o,persistNow:m,loadPersistedData:S,clearPersistedData:h,hasPersistedData:L}}function dt(){let{workflowConfig:t,currentStep:e}=N(),r=useMemo(()=>e?.metadata,[e?.metadata]),n=useMemo(()=>u=>t.steps.find(c=>c.id===u)?.metadata,[t.steps]),i=useMemo(()=>u=>t.steps[u]?.metadata,[t.steps]),s=useMemo(()=>u=>r?u in r:false,[r]),p=useMemo(()=>(u,b)=>r&&u in r?r[u]:b,[r]),o=useMemo(()=>()=>t.steps.map((u,b)=>({id:u.id,title:u.title,index:b,metadata:u.metadata})),[t.steps]),f=useMemo(()=>u=>t.steps.map((b,c)=>({step:b,index:c})).filter(({step:b,index:c})=>u(b.metadata,b.id,c)).map(({step:b})=>b.id),[t.steps]);return {current:r,getByStepId:n,getByStepIndex:i,hasCurrentKey:s,getCurrentValue:p,getAllStepsMetadata:o,findStepsByMetadata:f}}function be({workflowConfig:t,workflowState:e,workflowContext:r}){let n=useRef(Date.now()),i=useRef(new Map),s=useRef(false),p=useRef(null),o=getGlobalMonitor();useEffect(()=>{t.analytics?.onWorkflowStart&&!s.current&&(s.current=true,t.analytics.onWorkflowStart(t.id,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"start",totalSteps:t.steps.length},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:0,navigationDuration:0,conditionEvaluationDuration:0},"low"));},[t.id,t.analytics,r,o,t.steps.length]),useEffect(()=>{let l=t.steps[e.currentStepIndex];if(l&&p.current!==l.id){if(p.current&&t.analytics?.onStepComplete){let a=i.current.get(p.current);if(a){let y=Date.now()-a;t.analytics.onStepComplete(p.current,y,e.stepData,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_complete",stepId:p.current,duration:y},{timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:y,conditionEvaluationDuration:0},"low");}}p.current=l.id,i.current.set(l.id,Date.now()),t.analytics?.onStepStart&&t.analytics.onStepStart(l.id,Date.now(),r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_start",stepId:l.id,stepIndex:e.currentStepIndex},{timestamp:Date.now(),duration:0,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:0},"low");}},[e.currentStepIndex,t.steps,t.analytics,r,e.stepData,o,t.id]);let f=useCallback((l,a)=>{t.analytics?.onStepSkip&&t.analytics.onStepSkip(l,a,r),o&&o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"step_skip",stepId:l,reason:a},void 0,"medium");},[t.analytics,r,o,t.id]),u=useCallback(l=>{t.analytics?.onError&&t.analytics.onError(l,r),o&&o.trackError(l,`workflow_${t.id}`,{workflowId:t.id,currentStepIndex:e.currentStepIndex,currentStepId:t.steps[e.currentStepIndex]?.id,workflowContext:r});},[t.analytics,r,o,t.id,e.currentStepIndex,t.steps]),b=useCallback((l,a,y)=>{if(!o)return;let k={timestamp:Date.now(),duration:y,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:a,navigationDuration:y,conditionEvaluationDuration:0};o.track("workflow_navigation",`workflow_${t.id}`,{workflowId:t.id,action:"navigation",fromStep:l,toStep:a,direction:a>l?"forward":"backward"},k,y>1e3?"medium":"low");},[o,t.id,t.steps.length]),c=useCallback((l,a)=>{if(!o)return;let y={timestamp:Date.now(),duration:l,workflowId:t.id,stepCount:t.steps.length,currentStepIndex:e.currentStepIndex,navigationDuration:0,conditionEvaluationDuration:l};o.track("condition_evaluation",`workflow_${t.id}`,{workflowId:t.id,conditionsCount:a,currentStepIndex:e.currentStepIndex},y,l>100?"medium":"low");},[o,t.id,t.steps.length,e.currentStepIndex]);return {analyticsStartTime:n,trackStepSkip:f,trackError:u,trackNavigation:b,trackConditionEvaluation:c}}function se(t,e=""){let r={};for(let n in t)if(n in t){let i=t[n],s=e?`${e}.${n}`:n;i!==null&&typeof i=="object"&&!Array.isArray(i)&&!(i instanceof Date)?Object.assign(r,se(i,s)):r[s]=i;}return r}function ye(t,e){let r=se(t),n=se(e);return {...{...t,...e},...r,...n}}function Ke(t,e){return {visible:t.visible,skippable:e===true||t.required}}function xe({workflowConfig:t,workflowState:e,currentStep:r}){let n=useMemo(()=>ye(e.allData,e.stepData),[e.allData,e.stepData]),i=useMemo(()=>{if(r?.conditions)return {visible:r.conditions.visible,required:r.conditions.skippable}},[r?.conditions]),s=ce(i,n,{visible:true,disabled:false,required:false,readonly:false}),p=useMemo(()=>Ke(s,r?.allowSkip),[s,r?.allowSkip]),o=useMemo(()=>{let v={};return t.steps.forEach((I,S)=>{I.conditions&&(v[S]={visible:I.conditions.visible,required:I.conditions.skippable});}),v},[t.steps]),f=Ue(o,n),u=useMemo(()=>{let v={};return t.steps.forEach((I,S)=>{let h=f[S];h?v[S]=Ke(h,I.allowSkip):v[S]={visible:true,skippable:I.allowSkip===true};}),v},[t.steps,f]),b=useMemo(()=>{if(!r?.formConfig?.allFields)return {};let v={};for(let I of r.formConfig.allFields)I.conditions&&(v[I.id]=I.conditions);return v},[r?.formConfig?.allFields]),c=Le(b,n),l=useCallback(v=>v<0||v>=t.steps.length?false:u[v]?.visible??true,[u,t.steps.length]),a=useCallback(v=>v<0||v>=t.steps.length?false:u[v]?.skippable??false,[u,t.steps.length]),y=useCallback(v=>c[v]?.visible??true,[c]),k=useCallback(v=>c[v]?.disabled??false,[c]),P=useCallback(v=>c[v]?.required??false,[c]),D=useCallback(v=>c[v]?.readonly??false,[c]);return {stepConditions:p,fieldConditions:c,allStepConditions:u,isStepVisible:l,isStepSkippable:a,isFieldVisible:y,isFieldDisabled:k,isFieldRequired:P,isFieldReadonly:D}}function ke({workflowConfig:t,workflowState:e,workflowContext:r,conditionsHelpers:n,setCurrentStep:i,setTransitioning:s,markStepVisited:p,markStepPassed:o,setStepData:f,onStepChange:u}){let b=useRef(u);b.current=u;let c=t.steps[e.currentStepIndex],l=useCallback(()=>({setStepData:(m,d)=>{f(d,m);},setStepFields:(m,d)=>{let V={...e.allData[m]||{},...d};f(V,m);},getStepData:m=>e.allData[m]||{},setNextStepField:(m,d)=>{let W=e.currentStepIndex+1;if(W<t.steps.length){let V=t.steps[W].id,X={...e.allData[V]||{},[m]:d};f(X,V);}},setNextStepFields:m=>{let d=e.currentStepIndex+1;if(d<t.steps.length){let W=t.steps[d].id,z={...e.allData[W]||{},...m};f(z,W);}},getAllData:()=>({...e.allData}),getSteps:()=>[...t.steps]}),[e.allData,e.currentStepIndex,t.steps,f]),a=useCallback(async m=>{if(m<0||m>=t.steps.length||!n.isStepVisible(m))return false;s(true);try{return b.current&&b.current(e.currentStepIndex,m,r),i(m),p(m,t.steps[m].id),!0}catch(d){return console.error("Step transition failed:",d),t.analytics?.onError&&t.analytics.onError(d,r),false}finally{s(false);}},[t.steps,t.analytics,n,e.currentStepIndex,r,s,i,p]),y=useCallback(m=>{for(let d=m+1;d<t.steps.length;d++)if(n.isStepVisible(d))return d;return null},[t.steps.length,n]),k=useCallback(m=>{for(let d=m-1;d>=0;d--)if(n.isStepVisible(d))return d;return null},[n]),P=useCallback(async()=>{if(c?.onAfterValidation)try{let d=l();await c.onAfterValidation(e.stepData,d,r);}catch(d){return console.error("onAfterValidation failed:",d),t.analytics?.onError&&t.analytics.onError(d,r),false}o(c.id);let m=y(e.currentStepIndex);return m===null?false:a(m)},[c,l,e.stepData,r,t.analytics,e.currentStepIndex,y,a,o]),D=useCallback(async()=>{let m=k(e.currentStepIndex);return m===null?false:a(m)},[e.currentStepIndex,k,a]),v=useCallback(async()=>!c?.allowSkip&&!n.isStepSkippable(e.currentStepIndex)?false:(t.analytics?.onStepSkip&&t.analytics.onStepSkip(c.id,"user_skip",r),P()),[c,n,e.currentStepIndex,t.analytics,r,P]),I=useCallback(m=>m<0||m>=t.steps.length?false:n.isStepVisible(m),[t.steps.length,n]),S=useCallback(()=>{let m=y(e.currentStepIndex);return m!==null&&I(m)},[e.currentStepIndex,y,I]),h=useCallback(()=>{let m=k(e.currentStepIndex);return m!==null&&I(m)},[e.currentStepIndex,k,I]),L=useCallback(()=>c?.allowSkip===true&&n.isStepSkippable(e.currentStepIndex),[c?.allowSkip,n,e.currentStepIndex]);return {goToStep:a,goNext:P,goPrevious:D,skipStep:v,canGoToStep:I,canGoNext:S,canGoPrevious:h,canSkipCurrentStep:L}}function St(t,e){switch(e.type){case "SET_CURRENT_STEP":return {...t,currentStepIndex:e.stepIndex};case "SET_STEP_DATA":return {...t,stepData:e.data,allData:{...t.allData,[e.stepId]:e.data}};case "SET_ALL_DATA":return {...t,allData:e.data};case "SET_FIELD_VALUE":{let r={...t.stepData,[e.fieldId]:e.value};return {...t,stepData:r,allData:{...t.allData,[e.stepId]:r}}}case "SET_SUBMITTING":return {...t,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...t,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...t,visitedSteps:new Set([...t.visitedSteps,e.stepId])};case "MARK_STEP_PASSED":return {...t,passedSteps:new Set([...t.passedSteps,e.stepId])};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false};case "LOAD_PERSISTED_STATE":return {...t,...e.state};case "SET_INITIALIZATION_COMPLETE":return {...t,isInitializing:false};default:return t}}function mt({defaultValues:t={},defaultStepIndex:e,workflowSteps:r,persistence:n}){let i=useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let h=0;h<e;h++)r[h]&&S.add(r[h].id);return S},[e,r]),s=useMemo(()=>{let S=new Set;if(e&&e>0&&r)for(let h=0;h<e;h++)r[h]&&S.add(r[h].id);return S},[e,r]),p={currentStepIndex:e??0,allData:t,stepData:{},visitedSteps:i,passedSteps:s,isSubmitting:false,isTransitioning:false,isInitializing:true},[o,f]=useReducer(St,p),u=n?.adapter?q({workflowId:n.workflowId,workflowState:o,adapter:n.adapter,options:n.options,userId:n.userId}):null,b=useCallback(S=>{f({type:"SET_CURRENT_STEP",stepIndex:S});},[]),c=useCallback((S,h)=>{f({type:"SET_STEP_DATA",data:S,stepId:h});},[]),l=useCallback((S,h,L)=>{f({type:"SET_FIELD_VALUE",fieldId:S,value:h,stepId:L});},[]),a=useCallback(S=>{f({type:"SET_SUBMITTING",isSubmitting:S});},[]),y=useCallback(S=>{f({type:"SET_TRANSITIONING",isTransitioning:S});},[]),k=useCallback((S,h)=>{f({type:"MARK_STEP_VISITED",stepIndex:S,stepId:h});},[]),P=useCallback(S=>{f({type:"MARK_STEP_PASSED",stepId:S});},[]),D=useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),v=useCallback(()=>{f({type:"SET_INITIALIZATION_COMPLETE"});},[]),I=useCallback(async()=>{if(!u)return v(),false;try{let S=await u.loadPersistedData();if(S){let h={currentStepIndex:S.currentStepIndex,allData:S.allData,stepData:S.stepData,visitedSteps:new Set(S.visitedSteps),passedSteps:new Set(S.passedSteps||[])};return f({type:"LOAD_PERSISTED_STATE",state:h}),v(),!0}}catch(S){console.error("Failed to load persisted state:",S);}return v(),false},[u,v]);return {workflowState:o,setCurrentStep:b,setStepData:c,setFieldValue:l,setSubmitting:a,setTransitioning:y,markStepVisited:k,markStepPassed:P,resetWorkflow:D,loadPersistedState:I,persistence:u?{isPersisting:u.isPersisting,persistenceError:u.persistenceError,persistNow:u.persistNow,clearPersistedData:u.clearPersistedData,hasPersistedData:u.hasPersistedData}:null}}function ve({workflowConfig:t,workflowState:e,workflowContext:r,setSubmitting:n,onWorkflowComplete:i,analyticsStartTime:s}){let p=useRef(i);p.current=i;let o=useCallback(async()=>{n(true);try{if(p.current&&await p.current(e.allData),t.analytics?.onWorkflowComplete){let u=Date.now()-s.current;t.analytics.onWorkflowComplete(t.id,u,e.allData);}}catch(u){throw console.error("Workflow submission failed:",u),t.analytics?.onError&&t.analytics.onError(u,r),u}finally{n(false);}},[e.allData,t.analytics,t.id,r,s,n]),f=useCallback(()=>e.isSubmitting?false:e.currentStepIndex===t.steps.length-1,[e.isSubmitting,e.currentStepIndex,t.steps.length]);return {submitWorkflow:o,isSubmitting:e.isSubmitting,canSubmit:f()}}function He(t={}){let{defaultValues:e={},defaultStepIndex:r=0,initialVisitedSteps:n=new Set,initialPassedSteps:i=new Set}=t;return createStore()(subscribeWithSelector((s,p)=>({currentStepIndex:r,isTransitioning:false,isInitializing:true,allData:{...e},stepData:{},visitedSteps:new Set(n),passedSteps:new Set(i),isSubmitting:false,_defaultValues:{...e},_defaultStepIndex:r,_setCurrentStep:o=>{s({currentStepIndex:o});},_setStepData:(o,f)=>{s(u=>({stepData:o,allData:{...u.allData,[f]:o}}));},_setAllData:o=>{s({allData:o});},_setFieldValue:(o,f,u)=>{s(b=>{let c={...b.stepData,[o]:f};return {stepData:c,allData:{...b.allData,[u]:c}}});},_setSubmitting:o=>{s({isSubmitting:o});},_setTransitioning:o=>{s({isTransitioning:o});},_setInitializing:o=>{s({isInitializing:o});},_markStepVisited:o=>{s(f=>({visitedSteps:new Set([...f.visitedSteps,o])}));},_markStepPassed:o=>{s(f=>({passedSteps:new Set([...f.passedSteps,o])}));},_reset:()=>{let o=p();s({currentStepIndex:o._defaultStepIndex,allData:{...o._defaultValues},stepData:{},visitedSteps:new Set,passedSteps:new Set,isSubmitting:false,isTransitioning:false,isInitializing:false});},_loadPersistedState:o=>{s(f=>({...f,...o,isInitializing:false}));}})))}var Pe=createContext(null);function A(){let t=useContext(Pe);if(!t)throw new Error("useWorkflowStore must be used within a WorkflowProvider");return t}function Qr(){let t=A();return useStore(t,e=>e.currentStepIndex)}function Xr(){let t=A();return useStore(t,e=>e.isTransitioning)}function Yr(){let t=A();return useStore(t,e=>e.isInitializing)}function en(){let t=A();return useStore(t,e=>e.isSubmitting)}function tn(){let t=A();return useStore(t,e=>e.allData)}function rn(){let t=A();return useStore(t,e=>e.stepData)}function nn(t){let e=A();return useStore(e,r=>r.allData[t])}function sn(){let t=A();return useStore(t,e=>e.visitedSteps)}function on(){let t=A();return useStore(t,e=>e.passedSteps)}function an(t){let e=A();return useStore(e,r=>r.visitedSteps.has(t))}function ln(t){let e=A();return useStore(e,r=>r.passedSteps.has(t))}function pn(){let t=A(),e=useStore(t,i=>i.currentStepIndex),r=useStore(t,i=>i.isTransitioning),n=useStore(t,i=>i.isSubmitting);return {currentStepIndex:e,isTransitioning:r,isSubmitting:n}}function dn(){let t=A(),e=useStore(t,i=>i.isSubmitting),r=useStore(t,i=>i.isTransitioning),n=useStore(t,i=>i.isInitializing);return {isSubmitting:e,isTransitioning:r,isInitializing:n}}function un(){let t=A();return {setCurrentStep:e=>t.getState()._setCurrentStep(e),setStepData:(e,r)=>t.getState()._setStepData(e,r),setAllData:e=>t.getState()._setAllData(e),setFieldValue:(e,r,n)=>t.getState()._setFieldValue(e,r,n),setSubmitting:e=>t.getState()._setSubmitting(e),setTransitioning:e=>t.getState()._setTransitioning(e),setInitializing:e=>t.getState()._setInitializing(e),markStepVisited:e=>t.getState()._markStepVisited(e),markStepPassed:e=>t.getState()._markStepPassed(e),reset:()=>t.getState()._reset(),loadPersistedState:e=>t.getState()._loadPersistedState(e)}}function cn(){return A()}var Wt={save:async()=>{},load:async()=>null,remove:async()=>{},exists:async()=>false},je=createContext(null);function Dt(t,e){let r=new Set,n=new Set;if(t>0)for(let i=0;i<t;i++)e[i]&&(r.add(e[i].id),n.add(e[i].id));return {visitedSteps:r,passedSteps:n}}function he({children:t,workflowConfig:e,defaultValues:r={},defaultStep:n,onStepChange:i,onWorkflowComplete:s,className:p}){let o=useRef(i),f=useRef(s);o.current=i,f.current=s;let u=useMemo(()=>{if(!n)return 0;let x=e.steps.findIndex(g=>g.id===n);return x===-1?(console.warn(`Default step with ID "${n}" not found. Starting at step 0.`),0):x},[n,e.steps]),b=useMemo(()=>Dt(u,e.steps),[u,e.steps]),c=useRef(null);c.current||(c.current=He({defaultValues:r,defaultStepIndex:u,initialVisitedSteps:b.visitedSteps,initialPassedSteps:b.passedSteps}));let l=c.current,[a,y]=useState(()=>{let x=l.getState();return {currentStepIndex:x.currentStepIndex,allData:x.allData,stepData:x.stepData,visitedSteps:x.visitedSteps,passedSteps:x.passedSteps,isSubmitting:x.isSubmitting,isTransitioning:x.isTransitioning,isInitializing:x.isInitializing}});useEffect(()=>l.subscribe(g=>{y({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:g.visitedSteps,passedSteps:g.passedSteps,isSubmitting:g.isSubmitting,isTransitioning:g.isTransitioning,isInitializing:g.isInitializing});}),[l]);let k=useCallback(x=>l.getState()._setCurrentStep(x),[l]),P=useCallback((x,g)=>l.getState()._setStepData(x,g),[l]),D=useCallback((x,g,E)=>l.getState()._setFieldValue(x,g,E),[l]),v=useCallback(x=>l.getState()._setSubmitting(x),[l]),I=useCallback(x=>l.getState()._setTransitioning(x),[l]),S=useCallback((x,g)=>l.getState()._markStepVisited(g),[l]),h=useCallback(x=>l.getState()._markStepPassed(x),[l]),L=useCallback(()=>l.getState()._reset(),[l]),m=!!e.persistence?.adapter,d=q({workflowId:e.id,workflowState:a,adapter:e.persistence?.adapter??Wt,options:e.persistence?.options,userId:e.persistence?.userId}),W=useRef(d);W.current=d;let V=useRef(false);useEffect(()=>{if(V.current)return;V.current=true,(async()=>{if(m)try{let g=await W.current.loadPersistedData();if(g){l.getState()._loadPersistedState({currentStepIndex:g.currentStepIndex,allData:g.allData,stepData:g.stepData,visitedSteps:new Set(g.visitedSteps),passedSteps:new Set(g.passedSteps||[])});return}}catch(g){console.error("Failed to load persisted state:",g);}l.getState()._setInitializing(false);})();},[l,m]);let z=useMemo(()=>({isPersisting:m?d.isPersisting:false,persistenceError:m?d.persistenceError:null,persistNow:m?d.persistNow:void 0}),[m,d.isPersisting,d.persistenceError,d.persistNow]),X=useMemo(()=>({workflowId:e.id,currentStepIndex:a.currentStepIndex,totalSteps:e.steps.length,allData:a.allData,stepData:a.stepData,visitedSteps:a.visitedSteps}),[e.id,e.steps.length,a.currentStepIndex,a.allData,a.stepData,a.visitedSteps]),C=useMemo(()=>e.steps[a.currentStepIndex],[e.steps,a.currentStepIndex]),K=useMemo(()=>C?.formConfig,[C?.formConfig]),_=xe({workflowConfig:e,workflowState:a,currentStep:C}),G=useMemo(()=>{let x=-1;for(let w=0;w<e.steps.length;w++)if(_.isStepVisible(w)){x=w;break}let g=-1;for(let w=e.steps.length-1;w>=0;w--)if(_.isStepVisible(w)){g=w;break}let E=new Set;for(let w=0;w<e.steps.length;w++){let te=e.steps[w];_.isStepVisible(w)&&a.visitedSteps.has(te.id)&&E.add(te.id);}return {...X,isFirstStep:a.currentStepIndex===x,isLastStep:a.currentStepIndex===g,visibleVisitedSteps:E,passedSteps:a.passedSteps}},[X,a.currentStepIndex,a.visitedSteps,a.passedSteps,_,e.steps]),{analyticsStartTime:Ye}=be({workflowConfig:e,workflowState:a,workflowContext:G}),{goToStep:we,goNext:Y,goPrevious:Re,skipStep:Ee,canGoToStep:Te,canGoNext:Ce,canGoPrevious:Ae,canSkipCurrentStep:_e}=ke({workflowConfig:e,workflowState:a,workflowContext:G,conditionsHelpers:_,setCurrentStep:k,setTransitioning:I,markStepVisited:S,markStepPassed:h,setStepData:P,onStepChange:o.current}),ae=useRef(false);useEffect(()=>{if(ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){for(let g=0;g<e.steps.length;g++)if(_.isStepVisible(g)){k(g),S(g,e.steps[g].id);break}}ae.current=true;},[a.currentStepIndex,e.steps,k,S,_]),useEffect(()=>{if(!ae.current)return;if(!_.isStepVisible(a.currentStepIndex)){let g=null;for(let E=a.currentStepIndex+1;E<e.steps.length;E++)if(_.isStepVisible(E)){g=E;break}if(g===null){for(let E=a.currentStepIndex-1;E>=0;E--)if(_.isStepVisible(E)){g=E;break}}g!==null&&(k(g),S(g,e.steps[g].id));}},[_,a.currentStepIndex,e.steps,k,S]);let{submitWorkflow:ee,isSubmitting:Ve,canSubmit:Ne}=ve({workflowConfig:e,workflowState:a,workflowContext:G,setSubmitting:v,onWorkflowComplete:f.current,analyticsStartTime:Ye}),le=useCallback((x,g)=>{D(x,g,C?.id||"");},[D,C?.id]),Fe=useCallback(x=>{P(x,C?.id||"");},[P,C?.id]),et=useCallback(async x=>{C?.id&&x&&P(x,C.id),G.isLastStep?await ee():await Y();},[G.isLastStep,ee,Y,C?.id,P]),Me=useMemo(()=>({goToStep:we,goNext:Y,goPrevious:Re,skipStep:Ee,canGoToStep:Te,canGoNext:Ce,canGoPrevious:Ae,canSkipCurrentStep:_e}),[we,Y,Re,Ee,Te,Ce,Ae,_e]),Be=useMemo(()=>({setValue:le,setStepData:Fe,resetWorkflow:L}),[le,Fe,L]),Oe=useMemo(()=>({submitWorkflow:ee,isSubmitting:Ve,canSubmit:Ne}),[ee,Ve,Ne]),tt=useMemo(()=>({workflowState:a,workflowConfig:e,currentStep:C,context:G,formConfig:K,conditionsHelpers:_,currentStepMetadata:C?.metadata,...Me,...Be,...Oe,persistNow:z.persistNow,isPersisting:z.isPersisting,persistenceError:z.persistenceError}),[a,e,C,G,K,_,Me,Be,Oe,z]),rt=useMemo(()=>{if(!C?.id)return {};let x=a?.allData[C.id]||{};if(!K?.allFields)return x;let g=new Set(K.allFields.map(w=>w.id)),E={};for(let[w,te]of Object.entries(x))g.has(w)&&(E[w]=te);return E},[a?.allData,C?.id,K?.allFields]),nt=useMemo(()=>a.isInitializing.toString(),[a.isInitializing]);return jsx(Pe.Provider,{value:l,children:jsx(je.Provider,{value:tt,children:jsx(FormProvider,{formConfig:K,defaultValues:rt,onFieldChange:le,"data-workflow-id":e.id,className:p,onSubmit:et,children:t},nt)})})}function N(){let t=useContext(je);if(!t)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return t}function Rt({children:t,workflowConfig:e,...r}){let n=useMemo(()=>e instanceof Z?e.build():e,[e]);return jsx(he,{...r,workflowConfig:n,children:t})}var At=Ct.memo(function({stepId:e,children:r}){let{currentStep:n}=N();if(!n||e&&n.id!==e)return null;let{formConfig:i,renderer:s}=n;return i?s?s(n):r??jsx(FormBody,{}):null});var Lt=Ct.memo(function({className:e,isSubmitting:r,...n}){let{context:i,workflowState:s,workflowConfig:p,currentStep:o}=N(),{submit:f}=useFormConfigContext(),u=useFormSubmitting(),b=useFormValues(),c=useMemo(()=>{let y=u||s.isSubmitting,k=r??y,P=!s.isTransitioning&&!k;return {finalIsSubmitting:k,canGoNext:P}},[u,s.isSubmitting,s.isTransitioning,r]),l=useCallback(async y=>{y?.preventDefault(),c.canGoNext&&await f(y);},[c.canGoNext,f]),a=useMemo(()=>({isLastStep:i.isLastStep,canGoNext:c.canGoNext,isSubmitting:c.finalIsSubmitting,onSubmit:l,className:e,currentStep:o,stepData:b,allData:i.allData,context:i}),[i.isLastStep,c.canGoNext,c.finalIsSubmitting,l,e,o,b,i.allData,i]);return jsx(ComponentRendererWrapper,{name:"WorkflowNextButton",renderer:p.renderConfig?.nextButtonRenderer,props:a,...n})});var Jt=Ct.memo(function({className:e,isSubmitting:r,...n}){let{context:i,goPrevious:s,workflowState:p,workflowConfig:o,currentStep:f,canGoPrevious:u}=N(),b=useFormSubmitting(),c=useFormValues(),l=useMemo(()=>{let k=b||p.isSubmitting,P=r??k,D=u()&&!p.isTransitioning&&!P;return {finalIsSubmitting:P,canGoPrevious:D}},[b,p.isSubmitting,p.isTransitioning,u,r]),a=useCallback(async k=>{k?.preventDefault(),l.canGoPrevious&&await s();},[l.canGoPrevious,s]),y=useMemo(()=>({canGoPrevious:l.canGoPrevious,isSubmitting:l.finalIsSubmitting,onPrevious:a,className:e,currentStep:f,stepData:c,allData:i.allData,context:i}),[l.canGoPrevious,l.finalIsSubmitting,a,e,f,c,i.allData,i]);return jsx(ComponentRendererWrapper,{name:"WorkflowPreviousButton",renderer:o.renderConfig?.previousButtonRenderer,props:y,...n})});var er=Ct.memo(function({className:e,isSubmitting:r,...n}){let{currentStep:i,skipStep:s,workflowState:p,workflowConfig:o,context:f,conditionsHelpers:u}=N(),b=useFormSubmitting(),c=useFormValues(),l=useMemo(()=>{let k=b||p.isSubmitting,P=r??k,D=(!!i?.allowSkip||u.isStepSkippable(p.currentStepIndex))&&!p.isTransitioning&&!P;return {finalIsSubmitting:P,canSkip:D}},[b,p.isSubmitting,p.isTransitioning,p.currentStepIndex,i?.allowSkip,u.isStepSkippable,r]),a=useCallback(async k=>{k?.preventDefault(),l.canSkip&&await s();},[l.canSkip,s]),y=useMemo(()=>({canSkip:l.canSkip,isSubmitting:l.finalIsSubmitting,onSkip:a,className:e,currentStep:i,stepData:c,allData:f.allData,context:f}),[l.canSkip,l.finalIsSubmitting,a,e,i,c,f.allData,f]);return jsx(ComponentRendererWrapper,{name:"WorkflowSkipButton",renderer:o.renderConfig?.skipButtonRenderer,props:y,...n})});var sr=Ct.memo(function({onStepClick:e,className:r,...n}){let{workflowConfig:i,workflowState:s,context:p,goToStep:o,conditionsHelpers:f}=N(),{visibleSteps:u,visibleToOriginalIndexMap:b,originalToVisibleIndexMap:c}=useMemo(()=>{let k=[],P=new Map,D=new Map;return i.steps.forEach((v,I)=>{if(f.isStepVisible(I)){let S=k.length;k.push(v),P.set(S,I),D.set(I,S);}}),{visibleSteps:k,visibleToOriginalIndexMap:P,originalToVisibleIndexMap:D}},[i.steps,f]),l=useCallback(k=>{let P=b.get(k);P!==void 0&&(e?e(P):o(P));},[b,e,o]),a=useMemo(()=>c.get(s.currentStepIndex)??-1,[c,s.currentStepIndex]),y=useMemo(()=>({steps:u,currentStepIndex:a,visitedSteps:p.visibleVisitedSteps,onStepClick:l,className:r}),[u,a,p.visibleVisitedSteps,l,r]);return jsx(ComponentRendererWrapper,{name:"WorkflowStepper",renderer:i.renderConfig?.stepperRenderer,props:y,...n})});var De=class{constructor(e={}){this.version="1.0.0";this.keyPrefix=e.keyPrefix??"rilay_workflow_",this.compress=e.compress??false,this.maxAge=e.maxAge,this._isAvailable=this.isLocalStorageAvailable();}async save(e,r){if(this._isAvailable)try{let n=this.getStorageKey(e),i={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},s=JSON.stringify(i),p=this.compress?this.compressData(s):s;localStorage.setItem(n,p);}catch(n){if(n instanceof Error)if(n.name==="QuotaExceededError"||n.message.includes("quota")){await this.clearExpiredData();try{let i=this.getStorageKey(e),s={data:{...r,lastSaved:Date.now()},version:this.version,expiresAt:this.maxAge?Date.now()+this.maxAge:void 0},p=JSON.stringify(s),o=this.compress?this.compressData(p):p;localStorage.setItem(i,o);}catch(i){throw new R("localStorage quota exceeded and cleanup failed","QUOTA_EXCEEDED",i)}}else throw new R(`Failed to save to localStorage: ${n.message}`,"SAVE_FAILED",n);else throw new R("Unknown error occurred while saving","SAVE_FAILED")}}async load(e){if(!this._isAvailable)return null;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return null;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),null):{...s.data,visitedSteps:Array.isArray(s.data.visitedSteps)?s.data.visitedSteps:[]}}catch(r){throw r instanceof Error?new R(`Failed to load from localStorage: ${r.message}`,"LOAD_FAILED",r):new R("Unknown error occurred while loading","LOAD_FAILED")}}async remove(e){if(this._isAvailable)try{let r=this.getStorageKey(e);localStorage.removeItem(r);}catch(r){throw r instanceof Error?new R(`Failed to remove from localStorage: ${r.message}`,"REMOVE_FAILED",r):new R("Unknown error occurred while removing","REMOVE_FAILED")}}async exists(e){if(!this._isAvailable)return false;try{let r=this.getStorageKey(e),n=localStorage.getItem(r);if(!n)return !1;let i=this.compress?this.decompressData(n):n,s=JSON.parse(i);return s.expiresAt&&Date.now()>s.expiresAt?(await this.remove(e),!1):!0}catch{return false}}async listKeys(){if(!this._isAvailable)return [];try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix)){let i=n.substring(this.keyPrefix.length);await this.exists(i)&&e.push(i);}}return e}catch(e){throw e instanceof Error?new R(`Failed to list keys: ${e.message}`,"LIST_FAILED",e):new R("Unknown error occurred while listing keys","LIST_FAILED")}}async clear(){try{let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);n?.startsWith(this.keyPrefix)&&e.push(n);}for(let r of e)localStorage.removeItem(r);}catch(e){throw e instanceof Error?new R(`Failed to clear localStorage: ${e.message}`,"CLEAR_FAILED",e):new R("Unknown error occurred while clearing","CLEAR_FAILED")}}getStorageKey(e){return `${this.keyPrefix}${e}`}isLocalStorageAvailable(){try{let e="__rilay_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}compressData(e){return btoa(e)}decompressData(e){try{return atob(e)}catch{return e}}async clearExpiredData(){if(!this._isAvailable)return;let e=[];for(let r=0;r<localStorage.length;r++){let n=localStorage.key(r);if(n?.startsWith(this.keyPrefix))try{let i=localStorage.getItem(n);if(i){let s=this.compress?this.decompressData(i):i,p=JSON.parse(s);p.expiresAt&&Date.now()>p.expiresAt&&e.push(n);}}catch{e.push(n);}}for(let r of e)localStorage.removeItem(r);}};export{De as LocalStorageAdapter,Rt as Workflow,At as WorkflowBody,Lt as WorkflowNextButton,R as WorkflowPersistenceError,Jt as WorkflowPreviousButton,he as WorkflowProvider,er as WorkflowSkipButton,sr as WorkflowStepper,Pe as WorkflowStoreContext,ye as combineWorkflowDataForConditions,pe as createStepContext,He as createWorkflowStore,me as debounce,se as flattenObject,Z as flow,Se as generateStorageKey,pt as mergePersistedState,ze as persistedToWorkflowState,ce as useConditionEvaluation,Qr as useCurrentStepIndex,ln as useIsStepPassed,an as useIsStepVisited,on as usePassedSteps,q as usePersistence,nn as useStepDataById,dt as useStepMetadata,sn as useVisitedSteps,un as useWorkflowActions,tn as useWorkflowAllData,be as useWorkflowAnalytics,xe as useWorkflowConditions,N as useWorkflowContext,Yr as useWorkflowInitializing,ke as useWorkflowNavigation,pn as useWorkflowNavigationState,mt as useWorkflowState,rn as useWorkflowStepData,A as useWorkflowStore,cn as useWorkflowStoreApi,ve as useWorkflowSubmission,dn as useWorkflowSubmitState,en as useWorkflowSubmitting,Xr as useWorkflowTransitioning,lt as validatePersistedData,fe as workflowStateToPersisted};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rilaykit/workflow",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "description": "Workflow and multi-step form utilities for RilayKit",
6
6
  "main": "dist/index.js",
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "zustand": "^5.0.9",
41
- "@rilaykit/core": "0.1.3",
42
- "@rilaykit/forms": "0.1.3"
41
+ "@rilaykit/core": "0.1.4",
42
+ "@rilaykit/forms": "0.1.4"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": ">=18.0.0",