@rilaykit/workflow 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -68,7 +68,25 @@ declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
68
68
  interface WorkflowNavigationProps {
69
69
  className?: string;
70
70
  }
71
- declare function WorkflowNavigation({ className }: WorkflowNavigationProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
71
+ declare function WorkflowNavigation({ className }: WorkflowNavigationProps): react_jsx_runtime.JSX.Element;
72
+
73
+ interface WorkflowNextButtonProps {
74
+ className?: string;
75
+ children?: React.ReactNode;
76
+ }
77
+ declare function WorkflowNextButton({ className, children }: WorkflowNextButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
78
+
79
+ interface WorkflowPreviousButtonProps {
80
+ className?: string;
81
+ children?: React.ReactNode;
82
+ }
83
+ declare function WorkflowPreviousButton({ className, children }: WorkflowPreviousButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
84
+
85
+ interface WorkflowSkipButtonProps {
86
+ className?: string;
87
+ children?: React.ReactNode;
88
+ }
89
+ declare function WorkflowSkipButton({ className, children }: WorkflowSkipButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
72
90
 
73
91
  interface WorkflowStepperProps {
74
92
  onStepClick?: (stepIndex: number) => void;
@@ -371,13 +389,6 @@ interface LicensePayload {
371
389
  expiry: number;
372
390
  iat: number;
373
391
  }
374
- interface CompressedLicensePayload {
375
- p: number;
376
- c: string;
377
- i: number;
378
- e: number;
379
- t: number;
380
- }
381
392
  interface LicenseResult {
382
393
  valid: boolean;
383
394
  data?: LicensePayload;
@@ -400,14 +411,6 @@ declare class RilayLicenseManager {
400
411
  * Validate license using Ed25519 signature verification
401
412
  */
402
413
  private static validateLicense;
403
- /**
404
- * Validate license key format
405
- */
406
- private static validateFormat;
407
- /**
408
- * Extract payload from license key
409
- */
410
- static extractPayload(licenseKey: string): CompressedLicensePayload | null;
411
414
  /**
412
415
  * Convert compressed payload to full payload
413
416
  */
@@ -417,9 +420,9 @@ declare class RilayLicenseManager {
417
420
  */
418
421
  private static hexToBytes;
419
422
  /**
420
- * Decode base64url string
423
+ * Convert base64 string to text (browser-compatible)
421
424
  */
422
- private static base64UrlDecode;
425
+ private static base64ToString;
423
426
  /**
424
427
  * Get license validation result
425
428
  */
@@ -446,4 +449,4 @@ declare class RilayLicenseManager {
446
449
  }>;
447
450
  }
448
451
 
449
- export { AnalyticsPlugin, RilayLicenseManager, ValidationPlugin, Workflow, WorkflowBody, flow as WorkflowBuilder, type WorkflowContextValue, WorkflowNavigation, type WorkflowNavigationProps, type WorkflowProviderProps, WorkflowStepper, type WorkflowStepperProps, flow };
452
+ export { AnalyticsPlugin, RilayLicenseManager, ValidationPlugin, Workflow, WorkflowBody, flow as WorkflowBuilder, type WorkflowContextValue, WorkflowNavigation, type WorkflowNavigationProps, WorkflowNextButton, type WorkflowNextButtonProps, WorkflowPreviousButton, type WorkflowPreviousButtonProps, type WorkflowProviderProps, WorkflowSkipButton, type WorkflowSkipButtonProps, WorkflowStepper, type WorkflowStepperProps, flow };
package/dist/index.d.ts CHANGED
@@ -68,7 +68,25 @@ declare function WorkflowBody(): react_jsx_runtime.JSX.Element | null;
68
68
  interface WorkflowNavigationProps {
69
69
  className?: string;
70
70
  }
71
- declare function WorkflowNavigation({ className }: WorkflowNavigationProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
71
+ declare function WorkflowNavigation({ className }: WorkflowNavigationProps): react_jsx_runtime.JSX.Element;
72
+
73
+ interface WorkflowNextButtonProps {
74
+ className?: string;
75
+ children?: React.ReactNode;
76
+ }
77
+ declare function WorkflowNextButton({ className, children }: WorkflowNextButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
78
+
79
+ interface WorkflowPreviousButtonProps {
80
+ className?: string;
81
+ children?: React.ReactNode;
82
+ }
83
+ declare function WorkflowPreviousButton({ className, children }: WorkflowPreviousButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
84
+
85
+ interface WorkflowSkipButtonProps {
86
+ className?: string;
87
+ children?: React.ReactNode;
88
+ }
89
+ declare function WorkflowSkipButton({ className, children }: WorkflowSkipButtonProps): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
72
90
 
73
91
  interface WorkflowStepperProps {
74
92
  onStepClick?: (stepIndex: number) => void;
@@ -371,13 +389,6 @@ interface LicensePayload {
371
389
  expiry: number;
372
390
  iat: number;
373
391
  }
374
- interface CompressedLicensePayload {
375
- p: number;
376
- c: string;
377
- i: number;
378
- e: number;
379
- t: number;
380
- }
381
392
  interface LicenseResult {
382
393
  valid: boolean;
383
394
  data?: LicensePayload;
@@ -400,14 +411,6 @@ declare class RilayLicenseManager {
400
411
  * Validate license using Ed25519 signature verification
401
412
  */
402
413
  private static validateLicense;
403
- /**
404
- * Validate license key format
405
- */
406
- private static validateFormat;
407
- /**
408
- * Extract payload from license key
409
- */
410
- static extractPayload(licenseKey: string): CompressedLicensePayload | null;
411
414
  /**
412
415
  * Convert compressed payload to full payload
413
416
  */
@@ -417,9 +420,9 @@ declare class RilayLicenseManager {
417
420
  */
418
421
  private static hexToBytes;
419
422
  /**
420
- * Decode base64url string
423
+ * Convert base64 string to text (browser-compatible)
421
424
  */
422
- private static base64UrlDecode;
425
+ private static base64ToString;
423
426
  /**
424
427
  * Get license validation result
425
428
  */
@@ -446,4 +449,4 @@ declare class RilayLicenseManager {
446
449
  }>;
447
450
  }
448
451
 
449
- export { AnalyticsPlugin, RilayLicenseManager, ValidationPlugin, Workflow, WorkflowBody, flow as WorkflowBuilder, type WorkflowContextValue, WorkflowNavigation, type WorkflowNavigationProps, type WorkflowProviderProps, WorkflowStepper, type WorkflowStepperProps, flow };
452
+ export { AnalyticsPlugin, RilayLicenseManager, ValidationPlugin, Workflow, WorkflowBody, flow as WorkflowBuilder, type WorkflowContextValue, WorkflowNavigation, type WorkflowNavigationProps, WorkflowNextButton, type WorkflowNextButtonProps, WorkflowPreviousButton, type WorkflowPreviousButtonProps, type WorkflowProviderProps, WorkflowSkipButton, type WorkflowSkipButtonProps, WorkflowStepper, type WorkflowStepperProps, flow };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),K=require('@noble/ed25519'),forms=require('@rilaykit/forms'),jsxRuntime=require('react/jsx-runtime'),core=require('@rilaykit/core');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var K__namespace=/*#__PURE__*/_interopNamespace(K);var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",d=class d{static async setLicenseKey(e){d.licenseKey=e||"",d.licenseKey?d.licenseResult=await d.validateLicense():d.licenseResult={valid:false,error:"MISSING"},d.isInitialized=true;}static async validateLicense(){if(!d.licenseKey)return {valid:false,error:"MISSING"};try{if(!d.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=d.licenseKey.slice(4),t=Buffer.from(e,"base64").toString().split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,s,l]=t,o=`${r}.${s}`,f=new TextEncoder().encode(o),h=l.match(/.{2}/g);if(!h)return {valid:!1,error:"INVALID"};let v=new Uint8Array(h.map(u=>Number.parseInt(u,16))),R=d.hexToBytes(ee);if(!await K__namespace.verify(v,f,R))return {valid:!1,error:"SIGNATURE_INVALID"};let y=Buffer.from(s.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString(),m=JSON.parse(y),E=Math.floor(Date.now()/1e3);return m.e<E?{valid:!1,error:"EXPIRED",data:d.decompressPayload(m)}:j>m.e*1e3?{valid:!1,error:"EXPIRED",data:d.decompressPayload(m)}:m.p===void 0||!m.c||!m.i||!m.e||!m.t?{valid:!1,error:"INVALID"}:{valid:!0,data:d.decompressPayload(m)}}catch{return {valid:false,error:"INVALID"}}}static validateFormat(e){return e.startsWith("ril_")&&e.length>20&&/^ril_[A-Za-z0-9_-]+$/.test(e)}static extractPayload(e){try{if(!d.validateFormat(e))return null;let t=d.base64UrlDecode(e.slice(4)).split(".");return t.length!==3?null:JSON.parse(d.base64UrlDecode(t[1]))}catch{return null}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let i=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)i[t/2]=Number.parseInt(e.substring(t,t+2),16);return i}static base64UrlDecode(e){let i=e+"=".repeat((4-e.length%4)%4);return atob(i.replace(/-/g,"+").replace(/_/g,"/"))}static getLicenseResult(){return d.isInitialized?d.licenseResult?d.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!d.getLicenseResult().valid}static getWatermarkMessage(){let e=d.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=d.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=d.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};d.licenseKey="",d.licenseResult=null,d.isInitialized=false;var T=d;function se(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let i=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[i]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let i=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[i]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "SET_WARNING":return {...a,warnings:{...a.warnings,[e.fieldId]:e.warnings}};case "CLEAR_ERROR":{let i={...a.errors};return delete i[e.fieldId],{...a,errors:i}}case "CLEAR_WARNING":{let i={...a.warnings};return delete i[e.fieldId],{...a,warnings:i}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let i=new Set(a.isValidating);return e.isValidating?i.add(e.fieldId):i.delete(e.fieldId),{...a,isValidating:i}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var J=react.createContext(null);function Y({children:a,workflowConfig:e,defaultValues:i={},onStepChange:t,onWorkflowComplete:r,className:s,user:l}){let[o,f]=react.useReducer(se,{currentStepIndex:0,allData:i,stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),h=react.useRef(null),v=react.useRef(Date.now()),R=react.useRef(new Map),I=react.useRef(false),y=react.useRef(null),m=react.useRef(t),E=react.useRef(r);m.current=t,E.current=r;let n=react.useMemo(()=>e,[e]),u=react.useMemo(()=>({workflowId:n.id,currentStepIndex:o.currentStepIndex,totalSteps:o.resolvedSteps.length,allData:o.allData,stepData:o.stepData,isFirstStep:o.currentStepIndex===0,isLastStep:o.currentStepIndex===o.resolvedSteps.length-1,visitedSteps:o.visitedSteps,user:l}),[n.id,o.currentStepIndex,o.resolvedSteps.length,o.allData,o.stepData,o.visitedSteps,l]);react.useEffect(()=>{(async()=>{let p=[];for(let g of n.steps)if(g.isDynamic&&g.dynamicConfig)try{let N=await g.dynamicConfig.resolver(o.allData,u);p.push(...N);}catch(N){console.error(`Failed to resolve dynamic step "${g.id}":`,N),p.push({...g,isDynamic:false});}else p.push(g);f({type:"SET_RESOLVED_STEPS",steps:p});})();},[n.steps,o.allData,u]),react.useEffect(()=>{n.analytics?.onWorkflowStart&&!I.current&&(I.current=true,n.analytics.onWorkflowStart(n.id,u));},[n.id,n.analytics,u]),react.useEffect(()=>{let c=o.resolvedSteps[o.currentStepIndex];if(c&&y.current!==c.id){if(y.current&&n.analytics?.onStepComplete){let p=R.current.get(y.current);p&&n.analytics.onStepComplete(y.current,Date.now()-p,o.stepData,u);}y.current=c.id,R.current.set(c.id,Date.now()),n.analytics?.onStepStart&&n.analytics.onStepStart(c.id,Date.now(),u);}},[o.currentStepIndex,o.resolvedSteps,n.analytics,u]);let w=react.useCallback(async()=>{if(n.persistence)try{let c={workflowId:n.id,currentStepIndex:o.currentStepIndex,allData:o.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=n.persistence.key||`workflow-${n.id}`;await n.persistence.adapter.save(p,c),n.persistence.onSave&&await n.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"save");}},[n,o.currentStepIndex,o.allData,l]),F=react.useCallback(async()=>{if(n.persistence)try{let c=n.persistence.key||`workflow-${n.id}`,p=await n.persistence.adapter.load(c);p&&p.workflowId===n.id&&(f({type:"SET_ALL_DATA",data:p.allData}),f({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),f({type:"SET_PERSISTED_DATA",data:p}),n.persistence.onLoad&&await n.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"load");}},[n]),W=react.useCallback(async()=>{if(n.persistence)try{let c=n.persistence.key||`workflow-${n.id}`;await n.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"remove");}},[n]);react.useEffect(()=>{n.persistence&&(async()=>{try{let p=n.persistence.key||`workflow-${n.id}`,g=await n.persistence.adapter.load(p);g&&g.workflowId===n.id&&(f({type:"SET_ALL_DATA",data:g.allData}),f({type:"SET_CURRENT_STEP",stepIndex:g.currentStepIndex}),f({type:"SET_PERSISTED_DATA",data:g}),n.persistence.onLoad&&await n.persistence.onLoad(g),console.log("Workflow data loaded from persistence:",g));}catch(p){console.error("Failed to load workflow draft on mount:",p),n.persistence.onError&&await n.persistence.onError(p,"load");}})();},[n.id]),react.useEffect(()=>{if(n.persistence?.saveOnStepChange)return h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{w();},n.persistence.debounceMs||1e3),()=>{h.current&&clearTimeout(h.current);}},[o.allData,w,n.persistence]);let k=react.useMemo(()=>o.resolvedSteps[o.currentStepIndex],[o.resolvedSteps,o.currentStepIndex]),M=react.useMemo(()=>k?.formConfig,[k]),C=react.useCallback(async c=>{if(c<0||c>=o.resolvedSteps.length)return false;let p=o.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,u):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(g){return console.error(`Permission check failed for step "${p.id}":`,g),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(o.stepData,o.allData,u);}catch(g){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,g),n.analytics?.onError&&n.analytics.onError(g,u),false}f({type:"SET_TRANSITIONING",isTransitioning:true});try{return m.current&&m.current(o.currentStepIndex,c,u),f({type:"SET_CURRENT_STEP",stepIndex:c}),f({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(g){return console.error("Step transition failed:",g),n.analytics?.onError&&n.analytics.onError(g,u),false}finally{f({type:"SET_TRANSITIONING",isTransitioning:false});}},[o.resolvedSteps,o.currentStepIndex,o.stepData,o.allData,l,u,n.analytics]),V=react.useCallback((c,p)=>{f({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=react.useCallback(c=>{f({type:"SET_STEP_DATA",data:c});},[]),G=react.useCallback(async()=>k?{isValid:true,errors:[]}:{isValid:true,errors:[]},[k]),A=react.useCallback(async()=>C(o.currentStepIndex+1),[C,o.currentStepIndex]),U=react.useCallback(async()=>n.navigation?.allowBackNavigation?C(o.currentStepIndex-1):false,[n.navigation,o.currentStepIndex,C]),B=react.useCallback(async()=>!k?.allowSkip||!n.navigation?.allowStepSkipping?false:(n.analytics?.onStepSkip&&n.analytics.onStepSkip(k.id,"user_skip",u),C(o.currentStepIndex+1)),[k,n.navigation,n.analytics,u,C,o.currentStepIndex]),z=react.useCallback(async()=>{f({type:"SET_SUBMITTING",isSubmitting:true});try{if(E.current&&await E.current(o.allData),await W(),n.analytics?.onWorkflowComplete){let c=Date.now()-v.current;n.analytics.onWorkflowComplete(n.id,c,o.allData);}}catch(c){throw console.error("Workflow submission failed:",c),n.analytics?.onError&&n.analytics.onError(c,u),c}finally{f({type:"SET_SUBMITTING",isSubmitting:false});}},[o.allData,E,W,n.analytics,u]),H=react.useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),Z=react.useMemo(()=>({workflowState:o,workflowConfig:n,currentStep:k,context:u,formConfig:M,goToStep:C,goNext:A,goPrevious:U,skipStep:B,setValue:V,setStepData:$,validateCurrentStep:G,submitWorkflow:z,resetWorkflow:H,saveDraft:w,loadDraft:F,clearDraft:W}),[o,n,k,u,M,C,A,U,B,V,$,G,z,H,w,F,W]),Q=react.useCallback(async()=>{await A();},[A]);return jsxRuntime.jsx(J.Provider,{value:Z,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:k?.formConfig,defaultValues:o?.allData[k?.id]||{},onFieldChange:V,"data-workflow-id":n.id,className:s,onSubmit:Q,children:a},k?.id)})}function P(){let a=react.useContext(J);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function le({children:a,...e}){let[i,t]=react.useState(false),r=T.shouldDisplayWatermark(),s=T.getWatermarkMessage();return react.useEffect(()=>{t(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(Y,{...e,children:a}),i&&r&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:s})]})}function de(){let{currentStep:a}=P();if(!a)return null;let{formConfig:e,renderer:i}=a;return e?i?i(a):jsxRuntime.jsx(forms.FormBody,{}):null}function ge({className:a}){let{workflowConfig:e,currentStep:i,context:t,goPrevious:r,skipStep:s,submitWorkflow:l,workflowState:o}=P(),{submit:f}=forms.useFormContext(),h=e.renderConfig?.navigationRenderer;if(!h)throw new Error(`No navigationRenderer configured for workflow "${e.id}". Please configure a navigationRenderer using config.setWorkflowNavigationRenderer() or config.setWorkflowRenderConfig().`);let v=!o.isTransitioning&&!o.isSubmitting,R=t.currentStepIndex>0&&e.navigation?.allowBackNavigation!==false&&!o.isTransitioning&&!o.isSubmitting,I=!!i?.allowSkip&&e.navigation?.allowStepSkipping!==false&&!o.isTransitioning&&!o.isSubmitting,y=async w=>{w?.preventDefault(),v&&await f(w);},m=async w=>{w?.preventDefault(),R&&await r();},E=async w=>{w?.preventDefault(),I&&await s();},n=async w=>{w?.preventDefault(),v&&await l();},u={currentStep:i,context:t,canGoNext:v,canGoPrevious:R,canSkip:I,isSubmitting:o.isSubmitting,onNext:y,onPrevious:m,onSkip:I?E:w=>w?.preventDefault(),onSubmit:n,className:a};return h(u)}function me({onStepClick:a,className:e}){let{workflowConfig:i,workflowState:t,goToStep:r}=P(),s=i.renderConfig?.stepperRenderer;if(!s)throw new Error(`No stepperRenderer configured for workflow "${i.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);let l=f=>{a?a(f):r(f);},o={steps:t.resolvedSteps,currentStepIndex:t.currentStepIndex,visitedSteps:t.visitedSteps,onStepClick:l,className:e};return s(o)}var _=class a{constructor(e,i,t,r){this.steps=[];this.branches=[];this.navigation={};this.plugins=[];this.config=e,this.workflowId=i,this.workflowName=t,this.workflowDescription=r,T.logLicenseStatus();}static create(e,i,t,r){return new a(e,i,t,r)}addStep(e,i,t,r){let s={id:e,title:i,description:r?.description,formConfig:t,allowSkip:r?.allowSkip||false,requiredToComplete:r?.requiredToComplete!==false,hooks:r?.hooks,permissions:r?.permissions,isDynamic:false,renderer:r?.renderer};return this.steps.push(s),this}addDynamicStep(e,i,t,r,s){let l={id:e,title:i,description:s?.description,formConfig:r,allowSkip:s?.allowSkip||false,requiredToComplete:s?.requiredToComplete!==false,hooks:s?.hooks,permissions:s?.permissions,isDynamic:true,dynamicConfig:t};return this.steps.push(l),this}addSteps(e){for(let i of e)this.addStep(i.stepId,i.title,i.formConfig,{description:i.description,allowSkip:i.allowSkip,requiredToComplete:i.requiredToComplete,hooks:i.hooks,permissions:i.permissions});return this}addConditionalBranch(e){return this.branches.push(e),this}addConditionalBranches(e){return this.branches.push(...e),this}setNavigation(e){return this.navigation=e,this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setOptimizations(e){return this.optimizations=e,this}setVersion(e){return this.version=e,this}setCompletion(e){return this.completion=e,this}use(e){if(e.dependencies){let i=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(i.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${i.join(", ")}`)}this.plugins.push(e);try{e.install(this);}catch(i){throw new Error(`Failed to install plugin "${e.name}": ${i instanceof Error?i.message:String(i)}`)}return this}removePlugin(e){return this.plugins=this.plugins.filter(i=>i.name!==e),this}updateStep(e,i){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...i},this}removeStep(e){return this.steps=this.steps.filter(i=>i.id!==e),this}getStep(e){return this.steps.find(i=>i.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,i){let t=new a(this.config,e||`${this.workflowId}-clone`,i||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.branches=this.branches.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.optimizations=this.optimizations?{...this.optimizations}:void 0,t.version=this.version?{...this.version}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let i=this.steps.map(r=>r.id),t=i.filter((r,s)=>i.indexOf(r)!==s);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let s=r.dependencies.filter(l=>!this.plugins.some(o=>o.name===l));s.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${s.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,conditionalBranches:this.branches.length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,i)=>e+i.formConfig.allFields.length,0),hasPersistence:!!this.persistence,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],branches:[...this.branches],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,branches:this.branches,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.branches&&(this.branches=e.branches),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),e.optimizations&&(this.optimizations=e.optimizations),e.version&&(this.version=e.version),this}};var L=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let i={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,s)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(s):void 0,...this.config.includeFormData?{form_data:s}:{}});},onWorkflowAbandon:(t,r,s)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(s)});},onStepStart:(t,r,s)=>{this.track("step_start",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,...this.getContextData(s)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,s,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(s).length,...this.getContextData(l)});},onStepSkip:(t,r,s)=>{this.track("step_skip",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,skip_reason:r,...this.getContextData(s)});},onValidationError:(t,r,s)=>{this.track("validation_error",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(s)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(i);}track(e,i){let t=this.config.eventMapping?.[e]||e,r={...i,timestamp:Date.now(),plugin_version:this.version};for(let[s,l]of Object.entries(this.config.providers))switch(s){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,i,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...i,custom_map:t.customDimensions});}trackMixpanel(e,i){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,i);}trackAmplitude(e,i){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,i);}async trackCustom(e,i,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:i})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let i=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return i>0?t/i*100:0}};var O=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let i=e.getSteps();for(let t of i){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(s,l)=>{let o=await this.validateStep(s,l);return this.config.onValidationComplete&&this.config.onValidationComplete(o,l),o}}});}}async validateStep(e,i){let t=[];try{if(this.config.schema){let s=await this.validateWithSchema(e,i);t.push(...s.errors);}let r=await this.validateWithRules(e,i);if(t.push(...r.errors),this.config.crossFieldValidation){let s=await this.validateCrossField(i.allData,i);t.push(...s.errors);}if(this.config.asyncRules){let s=await this.validateAsync(e,i);t.push(...s.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,i){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,i);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,i){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let s of this.config.rules.email)e[s]&&!r.test(e[s])&&t.push({code:"INVALID_EMAIL",message:`${s} must be a valid email address`,path:[s]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let s of this.config.rules.phone)e[s]&&!r.test(e[s].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${s} must be a valid phone number`,path:[s]});}if(this.config.rules.minLength)for(let[r,s]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<s&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${s} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,s]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>s&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${s} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,s]of Object.entries(this.config.rules.pattern))e[r]&&!s.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,s]of Object.entries(this.config.rules.custom))if(e[r]){let l=await s(e[r],i);l.isValid||t.push(...l.errors.map(o=>({...o,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,i){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let s={},l=true;for(let o of r.fields)if(e[o]!==void 0)s[o]=e[o];else {l=false;break}l&&((await r.validator(s,i)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,i){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,o])=>{if(!e[l])return null;let f=`${l}_${i.workflowId}`;return this.debounceTimers.has(f)&&clearTimeout(this.debounceTimers.get(f)),new Promise(h=>{let v=setTimeout(async()=>{try{let R=o.method==="GET"?`${o.url}?value=${encodeURIComponent(e[l])}`:o.url,y=await(await fetch(R,{method:o.method||"POST",headers:{"Content-Type":"application/json",...o.headers},body:o.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();y.isValid?h(null):h({code:"ASYNC_VALIDATION_ERROR",message:y.message||`${l} validation failed`,path:[l]});}catch{h({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},o.debounceMs||500);this.debounceTimers.set(f,v);})}),s=await Promise.all(r);return t.push(...s.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
2
- Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});Object.defineProperty(exports,"createZodValidator",{enumerable:true,get:function(){return core.createZodValidator}});Object.defineProperty(exports,"ril",{enumerable:true,get:function(){return core.ril}});exports.AnalyticsPlugin=L;exports.RilayLicenseManager=T;exports.ValidationPlugin=O;exports.Workflow=le;exports.WorkflowBody=de;exports.WorkflowBuilder=_;exports.WorkflowNavigation=ge;exports.WorkflowStepper=me;exports.flow=_;
1
+ 'use strict';var react=require('react'),X=require('@noble/ed25519'),forms=require('@rilaykit/forms'),jsxRuntime=require('react/jsx-runtime'),core=require('@rilaykit/core');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var X__namespace=/*#__PURE__*/_interopNamespace(X);var ie=1751361139160,ne="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,p=new TextEncoder().encode(n),m=l.match(/.{2}/g);if(!m)return {valid:!1,error:"INVALID"};let w=new Uint8Array(m.map(u=>Number.parseInt(u,16))),C=f.hexToBytes(ne);if(!await X__namespace.verify(w,p,C))return {valid:!1,error:"SIGNATURE_INVALID"};let v=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(v),E=Math.floor(Date.now()/1e3);return h.e<E?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:ie>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),p=o.indexOf(i.charAt(r++)),m=o.indexOf(i.charAt(r++)),w=l<<18|n<<12|p<<6|m;t+=String.fromCharCode(w>>16&255),p!==64&&(t+=String.fromCharCode(w>>8&255)),m!==64&&(t+=String.fromCharCode(w&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;function pe(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "SET_WARNING":return {...a,warnings:{...a.warnings,[e.fieldId]:e.warnings}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "CLEAR_WARNING":{let o={...a.warnings};return delete o[e.fieldId],{...a,warnings:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Q=react.createContext(null);function j({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,p]=react.useReducer(pe,{currentStepIndex:0,allData:o,stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),m=react.useRef(null),w=react.useRef(Date.now()),C=react.useRef(new Map),k=react.useRef(false),v=react.useRef(null),h=react.useRef(t),E=react.useRef(r);h.current=t,E.current=r;let s=react.useMemo(()=>e,[e]),u=react.useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);react.useEffect(()=>{(async()=>{let d=[];for(let g of s.steps)if(g.isDynamic&&g.dynamicConfig)try{let V=await g.dynamicConfig.resolver(n.allData,u);d.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${g.id}":`,V),d.push({...g,isDynamic:false});}else d.push(g);p({type:"SET_RESOLVED_STEPS",steps:d});})();},[s.steps,n.allData,u]),react.useEffect(()=>{s.analytics?.onWorkflowStart&&!k.current&&(k.current=true,s.analytics.onWorkflowStart(s.id,u));},[s.id,s.analytics,u]),react.useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&v.current!==c.id){if(v.current&&s.analytics?.onStepComplete){let d=C.current.get(v.current);d&&s.analytics.onStepComplete(v.current,Date.now()-d,n.stepData,u);}v.current=c.id,C.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),u);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,u]);let S=react.useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},d=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(d,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),G=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,d=await s.persistence.adapter.load(c);d&&d.workflowId===s.id&&(p({type:"SET_ALL_DATA",data:d.allData}),p({type:"SET_CURRENT_STEP",stepIndex:d.currentStepIndex}),p({type:"SET_PERSISTED_DATA",data:d}),s.persistence.onLoad&&await s.persistence.onLoad(d));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),b=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);react.useEffect(()=>{s.persistence&&(async()=>{try{let d=s.persistence.key||`workflow-${s.id}`,g=await s.persistence.adapter.load(d);g&&g.workflowId===s.id&&(p({type:"SET_ALL_DATA",data:g.allData}),p({type:"SET_CURRENT_STEP",stepIndex:g.currentStepIndex}),p({type:"SET_PERSISTED_DATA",data:g}),s.persistence.onLoad&&await s.persistence.onLoad(g),console.log("Workflow data loaded from persistence:",g));}catch(d){console.error("Failed to load workflow draft on mount:",d),s.persistence.onError&&await s.persistence.onError(d,"load");}})();},[s.id]),react.useEffect(()=>{if(s.persistence?.saveOnStepChange)return m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{S();},s.persistence.debounceMs||1e3),()=>{m.current&&clearTimeout(m.current);}},[n.allData,S,s.persistence]);let R=react.useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),U=react.useMemo(()=>R?.formConfig,[R]),P=react.useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let d=n.resolvedSteps[c];if(d.permissions)try{if(!(d.permissions.customGuard?await d.permissions.customGuard(l,u):!0))return console.warn(`Access denied to step "${d.id}"`),!1}catch(g){return console.error(`Permission check failed for step "${d.id}":`,g),false}if(d.hooks?.onBeforeEnter)try{await d.hooks.onBeforeEnter(n.stepData,n.allData,u);}catch(g){return console.error(`onBeforeEnter hook failed for step "${d.id}":`,g),s.analytics?.onError&&s.analytics.onError(g,u),false}p({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,u),p({type:"SET_CURRENT_STEP",stepIndex:c}),p({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(g){return console.error("Step transition failed:",g),s.analytics?.onError&&s.analytics.onError(g,u),false}finally{p({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,u,s.analytics]),_=react.useCallback((c,d)=>{p({type:"SET_FIELD_VALUE",fieldId:c,value:d});},[]),z=react.useCallback(c=>{p({type:"SET_STEP_DATA",data:c});},[]),K=react.useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),A=react.useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),H=react.useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),q=react.useCallback(async()=>!R?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(R.id,"user_skip",u),P(n.currentStepIndex+1)),[R,s.navigation,s.analytics,u,P,n.currentStepIndex]),J=react.useCallback(async()=>{p({type:"SET_SUBMITTING",isSubmitting:true});try{if(E.current&&await E.current(n.allData),await b(),s.analytics?.onWorkflowComplete){let c=Date.now()-w.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,u),c}finally{p({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,E,b,s.analytics,u]),Y=react.useCallback(()=>{p({type:"RESET_WORKFLOW"});},[]),re=react.useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:R,context:u,formConfig:U,goToStep:P,goNext:A,goPrevious:H,skipStep:q,setValue:_,setStepData:z,validateCurrentStep:K,submitWorkflow:J,resetWorkflow:Y,saveDraft:S,loadDraft:G,clearDraft:b}),[n,s,R,u,U,P,A,H,q,_,z,K,J,Y,S,G,b]),oe=react.useCallback(async()=>{await A();},[A]);return jsxRuntime.jsx(Q.Provider,{value:re,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:_,"data-workflow-id":s.id,className:i,onSubmit:oe,children:a},R?.id)})}function I(){let a=react.useContext(Q);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function ue({children:a,...e}){let[o,t]=react.useState(false),r=x.shouldDisplayWatermark(),i=x.getWatermarkMessage();return react.useEffect(()=>{t(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(j,{...e,children:a}),o&&r&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function we(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsxRuntime.jsx(forms.FormBody,{}):null}function L({className:a,children:e}){let{context:o,submitWorkflow:t,workflowState:r,workflowConfig:i}=I(),{submit:l}=forms.useFormContext(),n=i.renderConfig?.nextButtonRenderer;if(!n)throw new Error(`No nextButtonRenderer configured for workflow "${i.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let p=!r.isTransitioning&&!r.isSubmitting,m=async k=>{k?.preventDefault(),p&&await l(k);},w=async k=>{k?.preventDefault(),p&&await t();},C={isLastStep:o.isLastStep,canGoNext:p,isSubmitting:r.isSubmitting,onNext:m,onSubmit:w,className:a,children:e};return n(C)}function B({className:a,children:e}){let{workflowConfig:o,context:t,goPrevious:r,workflowState:i}=I(),l=o.renderConfig?.previousButtonRenderer;if(!l)throw new Error(`No previousButtonRenderer configured for workflow "${o.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let n=t.currentStepIndex>0&&o.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;return l({canGoPrevious:n,onPrevious:async w=>{w?.preventDefault(),n&&await r();},className:a,children:e})}function O({className:a,children:e}){let{workflowConfig:o,currentStep:t,skipStep:r,workflowState:i}=I(),l=o.renderConfig?.skipButtonRenderer;if(!l)throw new Error(`No skipButtonRenderer configured for workflow "${o.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let n=!!t?.allowSkip&&o.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting;return l({canSkip:n,onSkip:async w=>{w?.preventDefault(),n&&await r();},className:a,children:e})}function ye({className:a}){let{workflowConfig:e,currentStep:o,context:t,goPrevious:r,skipStep:i,submitWorkflow:l,workflowState:n}=I(),{submit:p}=forms.useFormContext(),m=e.renderConfig?.navigationRenderer;if(m){let w=!n.isTransitioning&&!n.isSubmitting,C=t.currentStepIndex>0&&e.navigation?.allowBackNavigation!==false&&!n.isTransitioning&&!n.isSubmitting,k=!!o?.allowSkip&&e.navigation?.allowStepSkipping!==false&&!n.isTransitioning&&!n.isSubmitting,v=async S=>{S?.preventDefault(),w&&await p(S);},h=async S=>{S?.preventDefault(),C&&await r();},E=async S=>{S?.preventDefault(),k&&await i();},s=async S=>{S?.preventDefault(),w&&await l();},u={currentStep:o,context:t,canGoNext:w,canGoPrevious:C,canSkip:k,isSubmitting:n.isSubmitting,onNext:v,onPrevious:h,onSkip:k?E:S=>S?.preventDefault(),onSubmit:s,className:a};return m(u)}return jsxRuntime.jsxs("div",{className:`flex justify-between items-center ${a||""}`,children:[jsxRuntime.jsx(B,{}),jsxRuntime.jsxs("div",{className:"flex gap-2",children:[jsxRuntime.jsx(O,{}),jsxRuntime.jsx(L,{})]})]})}function ve({onStepClick:a,className:e}){let{workflowConfig:o,workflowState:t,goToStep:r}=I(),i=o.renderConfig?.stepperRenderer;if(!i)throw new Error(`No stepperRenderer configured for workflow "${o.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);let l=p=>{a?a(p):r(p);},n={steps:t.resolvedSteps,currentStepIndex:t.currentStepIndex,visitedSteps:t.visitedSteps,onStepClick:l,className:e};return i(n)}var N=class a{constructor(e,o,t,r){this.steps=[];this.branches=[];this.navigation={};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}addStep(e,o,t,r){let i={id:e,title:o,description:r?.description,formConfig:t,allowSkip:r?.allowSkip||false,requiredToComplete:r?.requiredToComplete!==false,hooks:r?.hooks,permissions:r?.permissions,isDynamic:false,renderer:r?.renderer};return this.steps.push(i),this}addDynamicStep(e,o,t,r,i){let l={id:e,title:o,description:i?.description,formConfig:r,allowSkip:i?.allowSkip||false,requiredToComplete:i?.requiredToComplete!==false,hooks:i?.hooks,permissions:i?.permissions,isDynamic:true,dynamicConfig:t};return this.steps.push(l),this}addSteps(e){for(let o of e)this.addStep(o.stepId,o.title,o.formConfig,{description:o.description,allowSkip:o.allowSkip,requiredToComplete:o.requiredToComplete,hooks:o.hooks,permissions:o.permissions});return this}addConditionalBranch(e){return this.branches.push(e),this}addConditionalBranches(e){return this.branches.push(...e),this}setNavigation(e){return this.navigation=e,this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setOptimizations(e){return this.optimizations=e,this}setVersion(e){return this.version=e,this}setCompletion(e){return this.completion=e,this}use(e){if(e.dependencies){let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.branches=this.branches.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.optimizations=this.optimizations?{...this.optimizations}:void 0,t.version=this.version?{...this.version}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,conditionalBranches:this.branches.length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,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],branches:[...this.branches],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,branches:this.branches,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.branches&&(this.branches=e.branches),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),e.optimizations&&(this.optimizations=e.optimizations),e.version&&(this.version=e.version),this}};var M=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var $=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let p=`${l}_${o.workflowId}`;return this.debounceTimers.has(p)&&clearTimeout(this.debounceTimers.get(p)),new Promise(m=>{let w=setTimeout(async()=>{try{let C=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,v=await(await fetch(C,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();v.isValid?m(null):m({code:"ASYNC_VALIDATION_ERROR",message:v.message||`${l} validation failed`,path:[l]});}catch{m({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(p,w);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
2
+ Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});Object.defineProperty(exports,"createZodValidator",{enumerable:true,get:function(){return core.createZodValidator}});Object.defineProperty(exports,"ril",{enumerable:true,get:function(){return core.ril}});exports.AnalyticsPlugin=M;exports.RilayLicenseManager=x;exports.ValidationPlugin=$;exports.Workflow=ue;exports.WorkflowBody=we;exports.WorkflowBuilder=N;exports.WorkflowNavigation=ye;exports.WorkflowNextButton=L;exports.WorkflowPreviousButton=B;exports.WorkflowSkipButton=O;exports.WorkflowStepper=ve;exports.flow=N;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {createContext,useState,useEffect,useReducer,useRef,useMemo,useCallback,useContext}from'react';import*as K from'@noble/ed25519';import {FormBody,useFormContext,FormProvider}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import {jsxs,jsx}from'react/jsx-runtime';export{createZodValidator,ril}from'@rilaykit/core';var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",d=class d{static async setLicenseKey(e){d.licenseKey=e||"",d.licenseKey?d.licenseResult=await d.validateLicense():d.licenseResult={valid:false,error:"MISSING"},d.isInitialized=true;}static async validateLicense(){if(!d.licenseKey)return {valid:false,error:"MISSING"};try{if(!d.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=d.licenseKey.slice(4),t=Buffer.from(e,"base64").toString().split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,s,l]=t,o=`${r}.${s}`,f=new TextEncoder().encode(o),h=l.match(/.{2}/g);if(!h)return {valid:!1,error:"INVALID"};let v=new Uint8Array(h.map(u=>Number.parseInt(u,16))),R=d.hexToBytes(ee);if(!await K.verify(v,f,R))return {valid:!1,error:"SIGNATURE_INVALID"};let y=Buffer.from(s.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString(),m=JSON.parse(y),E=Math.floor(Date.now()/1e3);return m.e<E?{valid:!1,error:"EXPIRED",data:d.decompressPayload(m)}:j>m.e*1e3?{valid:!1,error:"EXPIRED",data:d.decompressPayload(m)}:m.p===void 0||!m.c||!m.i||!m.e||!m.t?{valid:!1,error:"INVALID"}:{valid:!0,data:d.decompressPayload(m)}}catch{return {valid:false,error:"INVALID"}}}static validateFormat(e){return e.startsWith("ril_")&&e.length>20&&/^ril_[A-Za-z0-9_-]+$/.test(e)}static extractPayload(e){try{if(!d.validateFormat(e))return null;let t=d.base64UrlDecode(e.slice(4)).split(".");return t.length!==3?null:JSON.parse(d.base64UrlDecode(t[1]))}catch{return null}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let i=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)i[t/2]=Number.parseInt(e.substring(t,t+2),16);return i}static base64UrlDecode(e){let i=e+"=".repeat((4-e.length%4)%4);return atob(i.replace(/-/g,"+").replace(/_/g,"/"))}static getLicenseResult(){return d.isInitialized?d.licenseResult?d.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!d.getLicenseResult().valid}static getWatermarkMessage(){let e=d.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=d.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=d.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};d.licenseKey="",d.licenseResult=null,d.isInitialized=false;var T=d;function se(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let i=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[i]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let i=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[i]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "SET_WARNING":return {...a,warnings:{...a.warnings,[e.fieldId]:e.warnings}};case "CLEAR_ERROR":{let i={...a.errors};return delete i[e.fieldId],{...a,errors:i}}case "CLEAR_WARNING":{let i={...a.warnings};return delete i[e.fieldId],{...a,warnings:i}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let i=new Set(a.isValidating);return e.isValidating?i.add(e.fieldId):i.delete(e.fieldId),{...a,isValidating:i}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var J=createContext(null);function Y({children:a,workflowConfig:e,defaultValues:i={},onStepChange:t,onWorkflowComplete:r,className:s,user:l}){let[o,f]=useReducer(se,{currentStepIndex:0,allData:i,stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),h=useRef(null),v=useRef(Date.now()),R=useRef(new Map),I=useRef(false),y=useRef(null),m=useRef(t),E=useRef(r);m.current=t,E.current=r;let n=useMemo(()=>e,[e]),u=useMemo(()=>({workflowId:n.id,currentStepIndex:o.currentStepIndex,totalSteps:o.resolvedSteps.length,allData:o.allData,stepData:o.stepData,isFirstStep:o.currentStepIndex===0,isLastStep:o.currentStepIndex===o.resolvedSteps.length-1,visitedSteps:o.visitedSteps,user:l}),[n.id,o.currentStepIndex,o.resolvedSteps.length,o.allData,o.stepData,o.visitedSteps,l]);useEffect(()=>{(async()=>{let p=[];for(let g of n.steps)if(g.isDynamic&&g.dynamicConfig)try{let N=await g.dynamicConfig.resolver(o.allData,u);p.push(...N);}catch(N){console.error(`Failed to resolve dynamic step "${g.id}":`,N),p.push({...g,isDynamic:false});}else p.push(g);f({type:"SET_RESOLVED_STEPS",steps:p});})();},[n.steps,o.allData,u]),useEffect(()=>{n.analytics?.onWorkflowStart&&!I.current&&(I.current=true,n.analytics.onWorkflowStart(n.id,u));},[n.id,n.analytics,u]),useEffect(()=>{let c=o.resolvedSteps[o.currentStepIndex];if(c&&y.current!==c.id){if(y.current&&n.analytics?.onStepComplete){let p=R.current.get(y.current);p&&n.analytics.onStepComplete(y.current,Date.now()-p,o.stepData,u);}y.current=c.id,R.current.set(c.id,Date.now()),n.analytics?.onStepStart&&n.analytics.onStepStart(c.id,Date.now(),u);}},[o.currentStepIndex,o.resolvedSteps,n.analytics,u]);let w=useCallback(async()=>{if(n.persistence)try{let c={workflowId:n.id,currentStepIndex:o.currentStepIndex,allData:o.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=n.persistence.key||`workflow-${n.id}`;await n.persistence.adapter.save(p,c),n.persistence.onSave&&await n.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"save");}},[n,o.currentStepIndex,o.allData,l]),F=useCallback(async()=>{if(n.persistence)try{let c=n.persistence.key||`workflow-${n.id}`,p=await n.persistence.adapter.load(c);p&&p.workflowId===n.id&&(f({type:"SET_ALL_DATA",data:p.allData}),f({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),f({type:"SET_PERSISTED_DATA",data:p}),n.persistence.onLoad&&await n.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"load");}},[n]),W=useCallback(async()=>{if(n.persistence)try{let c=n.persistence.key||`workflow-${n.id}`;await n.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),n.persistence.onError&&await n.persistence.onError(c,"remove");}},[n]);useEffect(()=>{n.persistence&&(async()=>{try{let p=n.persistence.key||`workflow-${n.id}`,g=await n.persistence.adapter.load(p);g&&g.workflowId===n.id&&(f({type:"SET_ALL_DATA",data:g.allData}),f({type:"SET_CURRENT_STEP",stepIndex:g.currentStepIndex}),f({type:"SET_PERSISTED_DATA",data:g}),n.persistence.onLoad&&await n.persistence.onLoad(g),console.log("Workflow data loaded from persistence:",g));}catch(p){console.error("Failed to load workflow draft on mount:",p),n.persistence.onError&&await n.persistence.onError(p,"load");}})();},[n.id]),useEffect(()=>{if(n.persistence?.saveOnStepChange)return h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{w();},n.persistence.debounceMs||1e3),()=>{h.current&&clearTimeout(h.current);}},[o.allData,w,n.persistence]);let k=useMemo(()=>o.resolvedSteps[o.currentStepIndex],[o.resolvedSteps,o.currentStepIndex]),M=useMemo(()=>k?.formConfig,[k]),C=useCallback(async c=>{if(c<0||c>=o.resolvedSteps.length)return false;let p=o.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,u):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(g){return console.error(`Permission check failed for step "${p.id}":`,g),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(o.stepData,o.allData,u);}catch(g){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,g),n.analytics?.onError&&n.analytics.onError(g,u),false}f({type:"SET_TRANSITIONING",isTransitioning:true});try{return m.current&&m.current(o.currentStepIndex,c,u),f({type:"SET_CURRENT_STEP",stepIndex:c}),f({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(g){return console.error("Step transition failed:",g),n.analytics?.onError&&n.analytics.onError(g,u),false}finally{f({type:"SET_TRANSITIONING",isTransitioning:false});}},[o.resolvedSteps,o.currentStepIndex,o.stepData,o.allData,l,u,n.analytics]),V=useCallback((c,p)=>{f({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=useCallback(c=>{f({type:"SET_STEP_DATA",data:c});},[]),G=useCallback(async()=>k?{isValid:true,errors:[]}:{isValid:true,errors:[]},[k]),A=useCallback(async()=>C(o.currentStepIndex+1),[C,o.currentStepIndex]),U=useCallback(async()=>n.navigation?.allowBackNavigation?C(o.currentStepIndex-1):false,[n.navigation,o.currentStepIndex,C]),B=useCallback(async()=>!k?.allowSkip||!n.navigation?.allowStepSkipping?false:(n.analytics?.onStepSkip&&n.analytics.onStepSkip(k.id,"user_skip",u),C(o.currentStepIndex+1)),[k,n.navigation,n.analytics,u,C,o.currentStepIndex]),z=useCallback(async()=>{f({type:"SET_SUBMITTING",isSubmitting:true});try{if(E.current&&await E.current(o.allData),await W(),n.analytics?.onWorkflowComplete){let c=Date.now()-v.current;n.analytics.onWorkflowComplete(n.id,c,o.allData);}}catch(c){throw console.error("Workflow submission failed:",c),n.analytics?.onError&&n.analytics.onError(c,u),c}finally{f({type:"SET_SUBMITTING",isSubmitting:false});}},[o.allData,E,W,n.analytics,u]),H=useCallback(()=>{f({type:"RESET_WORKFLOW"});},[]),Z=useMemo(()=>({workflowState:o,workflowConfig:n,currentStep:k,context:u,formConfig:M,goToStep:C,goNext:A,goPrevious:U,skipStep:B,setValue:V,setStepData:$,validateCurrentStep:G,submitWorkflow:z,resetWorkflow:H,saveDraft:w,loadDraft:F,clearDraft:W}),[o,n,k,u,M,C,A,U,B,V,$,G,z,H,w,F,W]),Q=useCallback(async()=>{await A();},[A]);return jsx(J.Provider,{value:Z,children:jsx(FormProvider,{formConfig:k?.formConfig,defaultValues:o?.allData[k?.id]||{},onFieldChange:V,"data-workflow-id":n.id,className:s,onSubmit:Q,children:a},k?.id)})}function P(){let a=useContext(J);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function le({children:a,...e}){let[i,t]=useState(false),r=T.shouldDisplayWatermark(),s=T.getWatermarkMessage();return useEffect(()=>{t(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(Y,{...e,children:a}),i&&r&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:s})]})}function de(){let{currentStep:a}=P();if(!a)return null;let{formConfig:e,renderer:i}=a;return e?i?i(a):jsx(FormBody,{}):null}function ge({className:a}){let{workflowConfig:e,currentStep:i,context:t,goPrevious:r,skipStep:s,submitWorkflow:l,workflowState:o}=P(),{submit:f}=useFormContext(),h=e.renderConfig?.navigationRenderer;if(!h)throw new Error(`No navigationRenderer configured for workflow "${e.id}". Please configure a navigationRenderer using config.setWorkflowNavigationRenderer() or config.setWorkflowRenderConfig().`);let v=!o.isTransitioning&&!o.isSubmitting,R=t.currentStepIndex>0&&e.navigation?.allowBackNavigation!==false&&!o.isTransitioning&&!o.isSubmitting,I=!!i?.allowSkip&&e.navigation?.allowStepSkipping!==false&&!o.isTransitioning&&!o.isSubmitting,y=async w=>{w?.preventDefault(),v&&await f(w);},m=async w=>{w?.preventDefault(),R&&await r();},E=async w=>{w?.preventDefault(),I&&await s();},n=async w=>{w?.preventDefault(),v&&await l();},u={currentStep:i,context:t,canGoNext:v,canGoPrevious:R,canSkip:I,isSubmitting:o.isSubmitting,onNext:y,onPrevious:m,onSkip:I?E:w=>w?.preventDefault(),onSubmit:n,className:a};return h(u)}function me({onStepClick:a,className:e}){let{workflowConfig:i,workflowState:t,goToStep:r}=P(),s=i.renderConfig?.stepperRenderer;if(!s)throw new Error(`No stepperRenderer configured for workflow "${i.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);let l=f=>{a?a(f):r(f);},o={steps:t.resolvedSteps,currentStepIndex:t.currentStepIndex,visitedSteps:t.visitedSteps,onStepClick:l,className:e};return s(o)}var _=class a{constructor(e,i,t,r){this.steps=[];this.branches=[];this.navigation={};this.plugins=[];this.config=e,this.workflowId=i,this.workflowName=t,this.workflowDescription=r,T.logLicenseStatus();}static create(e,i,t,r){return new a(e,i,t,r)}addStep(e,i,t,r){let s={id:e,title:i,description:r?.description,formConfig:t,allowSkip:r?.allowSkip||false,requiredToComplete:r?.requiredToComplete!==false,hooks:r?.hooks,permissions:r?.permissions,isDynamic:false,renderer:r?.renderer};return this.steps.push(s),this}addDynamicStep(e,i,t,r,s){let l={id:e,title:i,description:s?.description,formConfig:r,allowSkip:s?.allowSkip||false,requiredToComplete:s?.requiredToComplete!==false,hooks:s?.hooks,permissions:s?.permissions,isDynamic:true,dynamicConfig:t};return this.steps.push(l),this}addSteps(e){for(let i of e)this.addStep(i.stepId,i.title,i.formConfig,{description:i.description,allowSkip:i.allowSkip,requiredToComplete:i.requiredToComplete,hooks:i.hooks,permissions:i.permissions});return this}addConditionalBranch(e){return this.branches.push(e),this}addConditionalBranches(e){return this.branches.push(...e),this}setNavigation(e){return this.navigation=e,this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setOptimizations(e){return this.optimizations=e,this}setVersion(e){return this.version=e,this}setCompletion(e){return this.completion=e,this}use(e){if(e.dependencies){let i=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(i.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${i.join(", ")}`)}this.plugins.push(e);try{e.install(this);}catch(i){throw new Error(`Failed to install plugin "${e.name}": ${i instanceof Error?i.message:String(i)}`)}return this}removePlugin(e){return this.plugins=this.plugins.filter(i=>i.name!==e),this}updateStep(e,i){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...i},this}removeStep(e){return this.steps=this.steps.filter(i=>i.id!==e),this}getStep(e){return this.steps.find(i=>i.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,i){let t=new a(this.config,e||`${this.workflowId}-clone`,i||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.branches=this.branches.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.optimizations=this.optimizations?{...this.optimizations}:void 0,t.version=this.version?{...this.version}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let i=this.steps.map(r=>r.id),t=i.filter((r,s)=>i.indexOf(r)!==s);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let s=r.dependencies.filter(l=>!this.plugins.some(o=>o.name===l));s.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${s.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,conditionalBranches:this.branches.length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,i)=>e+i.formConfig.allFields.length,0),hasPersistence:!!this.persistence,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],branches:[...this.branches],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,branches:this.branches,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.branches&&(this.branches=e.branches),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),e.optimizations&&(this.optimizations=e.optimizations),e.version&&(this.version=e.version),this}};var L=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let i={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,s)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(s):void 0,...this.config.includeFormData?{form_data:s}:{}});},onWorkflowAbandon:(t,r,s)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(s)});},onStepStart:(t,r,s)=>{this.track("step_start",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,...this.getContextData(s)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,s,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(s).length,...this.getContextData(l)});},onStepSkip:(t,r,s)=>{this.track("step_skip",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,skip_reason:r,...this.getContextData(s)});},onValidationError:(t,r,s)=>{this.track("validation_error",{step_id:t,step_index:s.currentStepIndex,workflow_id:s.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(s)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(i);}track(e,i){let t=this.config.eventMapping?.[e]||e,r={...i,timestamp:Date.now(),plugin_version:this.version};for(let[s,l]of Object.entries(this.config.providers))switch(s){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,i,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...i,custom_map:t.customDimensions});}trackMixpanel(e,i){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,i);}trackAmplitude(e,i){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,i);}async trackCustom(e,i,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:i})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let i=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return i>0?t/i*100:0}};var O=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let i=e.getSteps();for(let t of i){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(s,l)=>{let o=await this.validateStep(s,l);return this.config.onValidationComplete&&this.config.onValidationComplete(o,l),o}}});}}async validateStep(e,i){let t=[];try{if(this.config.schema){let s=await this.validateWithSchema(e,i);t.push(...s.errors);}let r=await this.validateWithRules(e,i);if(t.push(...r.errors),this.config.crossFieldValidation){let s=await this.validateCrossField(i.allData,i);t.push(...s.errors);}if(this.config.asyncRules){let s=await this.validateAsync(e,i);t.push(...s.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,i){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,i);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,i){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let s of this.config.rules.email)e[s]&&!r.test(e[s])&&t.push({code:"INVALID_EMAIL",message:`${s} must be a valid email address`,path:[s]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let s of this.config.rules.phone)e[s]&&!r.test(e[s].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${s} must be a valid phone number`,path:[s]});}if(this.config.rules.minLength)for(let[r,s]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<s&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${s} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,s]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>s&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${s} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,s]of Object.entries(this.config.rules.pattern))e[r]&&!s.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,s]of Object.entries(this.config.rules.custom))if(e[r]){let l=await s(e[r],i);l.isValid||t.push(...l.errors.map(o=>({...o,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,i){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let s={},l=true;for(let o of r.fields)if(e[o]!==void 0)s[o]=e[o];else {l=false;break}l&&((await r.validator(s,i)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,i){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,o])=>{if(!e[l])return null;let f=`${l}_${i.workflowId}`;return this.debounceTimers.has(f)&&clearTimeout(this.debounceTimers.get(f)),new Promise(h=>{let v=setTimeout(async()=>{try{let R=o.method==="GET"?`${o.url}?value=${encodeURIComponent(e[l])}`:o.url,y=await(await fetch(R,{method:o.method||"POST",headers:{"Content-Type":"application/json",...o.headers},body:o.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();y.isValid?h(null):h({code:"ASYNC_VALIDATION_ERROR",message:y.message||`${l} validation failed`,path:[l]});}catch{h({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},o.debounceMs||500);this.debounceTimers.set(f,v);})}),s=await Promise.all(r);return t.push(...s.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
2
- export{L as AnalyticsPlugin,T as RilayLicenseManager,O as ValidationPlugin,le as Workflow,de as WorkflowBody,_ as WorkflowBuilder,ge as WorkflowNavigation,me as WorkflowStepper,_ as flow};
1
+ import {createContext,useState,useEffect,useReducer,useRef,useMemo,useCallback,useContext}from'react';import*as X from'@noble/ed25519';import {FormBody,useFormContext,FormProvider}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import {jsxs,jsx}from'react/jsx-runtime';export{createZodValidator,ril}from'@rilaykit/core';var ie=1751361139160,ne="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,p=new TextEncoder().encode(n),m=l.match(/.{2}/g);if(!m)return {valid:!1,error:"INVALID"};let w=new Uint8Array(m.map(u=>Number.parseInt(u,16))),C=f.hexToBytes(ne);if(!await X.verify(w,p,C))return {valid:!1,error:"SIGNATURE_INVALID"};let v=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(v),E=Math.floor(Date.now()/1e3);return h.e<E?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:ie>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),p=o.indexOf(i.charAt(r++)),m=o.indexOf(i.charAt(r++)),w=l<<18|n<<12|p<<6|m;t+=String.fromCharCode(w>>16&255),p!==64&&(t+=String.fromCharCode(w>>8&255)),m!==64&&(t+=String.fromCharCode(w&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;function pe(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "SET_WARNING":return {...a,warnings:{...a.warnings,[e.fieldId]:e.warnings}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "CLEAR_WARNING":{let o={...a.warnings};return delete o[e.fieldId],{...a,warnings:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Q=createContext(null);function j({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,p]=useReducer(pe,{currentStepIndex:0,allData:o,stepData:{},errors:{},warnings:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),m=useRef(null),w=useRef(Date.now()),C=useRef(new Map),k=useRef(false),v=useRef(null),h=useRef(t),E=useRef(r);h.current=t,E.current=r;let s=useMemo(()=>e,[e]),u=useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);useEffect(()=>{(async()=>{let d=[];for(let g of s.steps)if(g.isDynamic&&g.dynamicConfig)try{let V=await g.dynamicConfig.resolver(n.allData,u);d.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${g.id}":`,V),d.push({...g,isDynamic:false});}else d.push(g);p({type:"SET_RESOLVED_STEPS",steps:d});})();},[s.steps,n.allData,u]),useEffect(()=>{s.analytics?.onWorkflowStart&&!k.current&&(k.current=true,s.analytics.onWorkflowStart(s.id,u));},[s.id,s.analytics,u]),useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&v.current!==c.id){if(v.current&&s.analytics?.onStepComplete){let d=C.current.get(v.current);d&&s.analytics.onStepComplete(v.current,Date.now()-d,n.stepData,u);}v.current=c.id,C.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),u);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,u]);let S=useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},d=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(d,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),G=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,d=await s.persistence.adapter.load(c);d&&d.workflowId===s.id&&(p({type:"SET_ALL_DATA",data:d.allData}),p({type:"SET_CURRENT_STEP",stepIndex:d.currentStepIndex}),p({type:"SET_PERSISTED_DATA",data:d}),s.persistence.onLoad&&await s.persistence.onLoad(d));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),b=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);useEffect(()=>{s.persistence&&(async()=>{try{let d=s.persistence.key||`workflow-${s.id}`,g=await s.persistence.adapter.load(d);g&&g.workflowId===s.id&&(p({type:"SET_ALL_DATA",data:g.allData}),p({type:"SET_CURRENT_STEP",stepIndex:g.currentStepIndex}),p({type:"SET_PERSISTED_DATA",data:g}),s.persistence.onLoad&&await s.persistence.onLoad(g),console.log("Workflow data loaded from persistence:",g));}catch(d){console.error("Failed to load workflow draft on mount:",d),s.persistence.onError&&await s.persistence.onError(d,"load");}})();},[s.id]),useEffect(()=>{if(s.persistence?.saveOnStepChange)return m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{S();},s.persistence.debounceMs||1e3),()=>{m.current&&clearTimeout(m.current);}},[n.allData,S,s.persistence]);let R=useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),U=useMemo(()=>R?.formConfig,[R]),P=useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let d=n.resolvedSteps[c];if(d.permissions)try{if(!(d.permissions.customGuard?await d.permissions.customGuard(l,u):!0))return console.warn(`Access denied to step "${d.id}"`),!1}catch(g){return console.error(`Permission check failed for step "${d.id}":`,g),false}if(d.hooks?.onBeforeEnter)try{await d.hooks.onBeforeEnter(n.stepData,n.allData,u);}catch(g){return console.error(`onBeforeEnter hook failed for step "${d.id}":`,g),s.analytics?.onError&&s.analytics.onError(g,u),false}p({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,u),p({type:"SET_CURRENT_STEP",stepIndex:c}),p({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(g){return console.error("Step transition failed:",g),s.analytics?.onError&&s.analytics.onError(g,u),false}finally{p({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,u,s.analytics]),_=useCallback((c,d)=>{p({type:"SET_FIELD_VALUE",fieldId:c,value:d});},[]),z=useCallback(c=>{p({type:"SET_STEP_DATA",data:c});},[]),K=useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),A=useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),H=useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),q=useCallback(async()=>!R?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(R.id,"user_skip",u),P(n.currentStepIndex+1)),[R,s.navigation,s.analytics,u,P,n.currentStepIndex]),J=useCallback(async()=>{p({type:"SET_SUBMITTING",isSubmitting:true});try{if(E.current&&await E.current(n.allData),await b(),s.analytics?.onWorkflowComplete){let c=Date.now()-w.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,u),c}finally{p({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,E,b,s.analytics,u]),Y=useCallback(()=>{p({type:"RESET_WORKFLOW"});},[]),re=useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:R,context:u,formConfig:U,goToStep:P,goNext:A,goPrevious:H,skipStep:q,setValue:_,setStepData:z,validateCurrentStep:K,submitWorkflow:J,resetWorkflow:Y,saveDraft:S,loadDraft:G,clearDraft:b}),[n,s,R,u,U,P,A,H,q,_,z,K,J,Y,S,G,b]),oe=useCallback(async()=>{await A();},[A]);return jsx(Q.Provider,{value:re,children:jsx(FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:_,"data-workflow-id":s.id,className:i,onSubmit:oe,children:a},R?.id)})}function I(){let a=useContext(Q);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function ue({children:a,...e}){let[o,t]=useState(false),r=x.shouldDisplayWatermark(),i=x.getWatermarkMessage();return useEffect(()=>{t(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(j,{...e,children:a}),o&&r&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:i})]})}function we(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsx(FormBody,{}):null}function L({className:a,children:e}){let{context:o,submitWorkflow:t,workflowState:r,workflowConfig:i}=I(),{submit:l}=useFormContext(),n=i.renderConfig?.nextButtonRenderer;if(!n)throw new Error(`No nextButtonRenderer configured for workflow "${i.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let p=!r.isTransitioning&&!r.isSubmitting,m=async k=>{k?.preventDefault(),p&&await l(k);},w=async k=>{k?.preventDefault(),p&&await t();},C={isLastStep:o.isLastStep,canGoNext:p,isSubmitting:r.isSubmitting,onNext:m,onSubmit:w,className:a,children:e};return n(C)}function B({className:a,children:e}){let{workflowConfig:o,context:t,goPrevious:r,workflowState:i}=I(),l=o.renderConfig?.previousButtonRenderer;if(!l)throw new Error(`No previousButtonRenderer configured for workflow "${o.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let n=t.currentStepIndex>0&&o.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;return l({canGoPrevious:n,onPrevious:async w=>{w?.preventDefault(),n&&await r();},className:a,children:e})}function O({className:a,children:e}){let{workflowConfig:o,currentStep:t,skipStep:r,workflowState:i}=I(),l=o.renderConfig?.skipButtonRenderer;if(!l)throw new Error(`No skipButtonRenderer configured for workflow "${o.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let n=!!t?.allowSkip&&o.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting;return l({canSkip:n,onSkip:async w=>{w?.preventDefault(),n&&await r();},className:a,children:e})}function ye({className:a}){let{workflowConfig:e,currentStep:o,context:t,goPrevious:r,skipStep:i,submitWorkflow:l,workflowState:n}=I(),{submit:p}=useFormContext(),m=e.renderConfig?.navigationRenderer;if(m){let w=!n.isTransitioning&&!n.isSubmitting,C=t.currentStepIndex>0&&e.navigation?.allowBackNavigation!==false&&!n.isTransitioning&&!n.isSubmitting,k=!!o?.allowSkip&&e.navigation?.allowStepSkipping!==false&&!n.isTransitioning&&!n.isSubmitting,v=async S=>{S?.preventDefault(),w&&await p(S);},h=async S=>{S?.preventDefault(),C&&await r();},E=async S=>{S?.preventDefault(),k&&await i();},s=async S=>{S?.preventDefault(),w&&await l();},u={currentStep:o,context:t,canGoNext:w,canGoPrevious:C,canSkip:k,isSubmitting:n.isSubmitting,onNext:v,onPrevious:h,onSkip:k?E:S=>S?.preventDefault(),onSubmit:s,className:a};return m(u)}return jsxs("div",{className:`flex justify-between items-center ${a||""}`,children:[jsx(B,{}),jsxs("div",{className:"flex gap-2",children:[jsx(O,{}),jsx(L,{})]})]})}function ve({onStepClick:a,className:e}){let{workflowConfig:o,workflowState:t,goToStep:r}=I(),i=o.renderConfig?.stepperRenderer;if(!i)throw new Error(`No stepperRenderer configured for workflow "${o.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);let l=p=>{a?a(p):r(p);},n={steps:t.resolvedSteps,currentStepIndex:t.currentStepIndex,visitedSteps:t.visitedSteps,onStepClick:l,className:e};return i(n)}var N=class a{constructor(e,o,t,r){this.steps=[];this.branches=[];this.navigation={};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}addStep(e,o,t,r){let i={id:e,title:o,description:r?.description,formConfig:t,allowSkip:r?.allowSkip||false,requiredToComplete:r?.requiredToComplete!==false,hooks:r?.hooks,permissions:r?.permissions,isDynamic:false,renderer:r?.renderer};return this.steps.push(i),this}addDynamicStep(e,o,t,r,i){let l={id:e,title:o,description:i?.description,formConfig:r,allowSkip:i?.allowSkip||false,requiredToComplete:i?.requiredToComplete!==false,hooks:i?.hooks,permissions:i?.permissions,isDynamic:true,dynamicConfig:t};return this.steps.push(l),this}addSteps(e){for(let o of e)this.addStep(o.stepId,o.title,o.formConfig,{description:o.description,allowSkip:o.allowSkip,requiredToComplete:o.requiredToComplete,hooks:o.hooks,permissions:o.permissions});return this}addConditionalBranch(e){return this.branches.push(e),this}addConditionalBranches(e){return this.branches.push(...e),this}setNavigation(e){return this.navigation=e,this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setOptimizations(e){return this.optimizations=e,this}setVersion(e){return this.version=e,this}setCompletion(e){return this.completion=e,this}use(e){if(e.dependencies){let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.branches=this.branches.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.optimizations=this.optimizations?{...this.optimizations}:void 0,t.version=this.version?{...this.version}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,conditionalBranches:this.branches.length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,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],branches:[...this.branches],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,branches:this.branches,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,optimizations:this.optimizations,version:this.version,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.branches&&(this.branches=e.branches),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),e.optimizations&&(this.optimizations=e.optimizations),e.version&&(this.version=e.version),this}};var M=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var $=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let p=`${l}_${o.workflowId}`;return this.debounceTimers.has(p)&&clearTimeout(this.debounceTimers.get(p)),new Promise(m=>{let w=setTimeout(async()=>{try{let C=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,v=await(await fetch(C,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();v.isValid?m(null):m({code:"ASYNC_VALIDATION_ERROR",message:v.message||`${l} validation failed`,path:[l]});}catch{m({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(p,w);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
2
+ export{M as AnalyticsPlugin,x as RilayLicenseManager,$ as ValidationPlugin,ue as Workflow,we as WorkflowBody,N as WorkflowBuilder,ye as WorkflowNavigation,L as WorkflowNextButton,B as WorkflowPreviousButton,O as WorkflowSkipButton,ve as WorkflowStepper,N as flow};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rilaykit/workflow",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "Commercial workflow and multi-step form utilities for RilayKit - License required for all use",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,8 +26,8 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@noble/ed25519": "^1.7.1",
29
- "@rilaykit/core": "1.1.0",
30
- "@rilaykit/forms": "1.1.0"
29
+ "@rilaykit/core": "1.3.0",
30
+ "@rilaykit/forms": "1.3.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "react": ">=18.0.0",