@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 +28 -16
- package/dist/index.d.mts +159 -39
- package/dist/index.d.ts +159 -39
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
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 =
|
|
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 =
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
.
|
|
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
|
-
.
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.
|
|
132
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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 {
|
|
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
|
-
*
|
|
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?:
|
|
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
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* @param context -
|
|
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
|
-
*
|
|
264
|
-
* //
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
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
|
-
*
|
|
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 -
|
|
358
|
-
* @param workflowName -
|
|
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
|
|
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 -
|
|
372
|
-
* @param workflowName -
|
|
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
|
|
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 {
|
|
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
|
-
*
|
|
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?:
|
|
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
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* @param context -
|
|
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
|
-
*
|
|
264
|
-
* //
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
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
|
-
*
|
|
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 -
|
|
358
|
-
* @param workflowName -
|
|
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
|
|
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 -
|
|
372
|
-
* @param workflowName -
|
|
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
|
|
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
|
+
"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.
|
|
42
|
-
"@rilaykit/forms": "0.1.
|
|
41
|
+
"@rilaykit/core": "0.1.4",
|
|
42
|
+
"@rilaykit/forms": "0.1.4"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": ">=18.0.0",
|