awaitly-visualizer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.cjs +1677 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.d.cts +166 -0
- package/dist/index.browser.d.ts +166 -0
- package/dist/index.browser.js +1677 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.cjs +1680 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +242 -0
- package/dist/index.d.ts +242 -0
- package/dist/index.js +1680 -0
- package/dist/index.js.map +1 -0
- package/dist/kroki/fetch.cjs +3 -0
- package/dist/kroki/fetch.cjs.map +1 -0
- package/dist/kroki/fetch.d.cts +86 -0
- package/dist/kroki/fetch.d.ts +86 -0
- package/dist/kroki/fetch.js +3 -0
- package/dist/kroki/fetch.js.map +1 -0
- package/dist/notifiers/discord.cjs +3 -0
- package/dist/notifiers/discord.cjs.map +1 -0
- package/dist/notifiers/discord.d.cts +70 -0
- package/dist/notifiers/discord.d.ts +70 -0
- package/dist/notifiers/discord.js +3 -0
- package/dist/notifiers/discord.js.map +1 -0
- package/dist/notifiers/slack.cjs +38 -0
- package/dist/notifiers/slack.cjs.map +1 -0
- package/dist/notifiers/slack.d.cts +95 -0
- package/dist/notifiers/slack.d.ts +95 -0
- package/dist/notifiers/slack.js +38 -0
- package/dist/notifiers/slack.js.map +1 -0
- package/dist/notifiers/webhook.cjs +3 -0
- package/dist/notifiers/webhook.cjs.map +1 -0
- package/dist/notifiers/webhook.d.cts +115 -0
- package/dist/notifiers/webhook.d.ts +115 -0
- package/dist/notifiers/webhook.js +3 -0
- package/dist/notifiers/webhook.js.map +1 -0
- package/dist/performance-analyzer-B5VF5b1F.d.ts +663 -0
- package/dist/performance-analyzer-BNwE4AiO.d.cts +663 -0
- package/dist/types-BIZSmXif.d.ts +350 -0
- package/dist/types-BnWc9Wlr.d.cts +350 -0
- package/dist/url-PkfQz4V5.d.cts +750 -0
- package/dist/url-PkfQz4V5.d.ts +750 -0
- package/package.json +105 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1680 @@
|
|
|
1
|
+
"use strict";var Xt=Object.create;var $e=Object.defineProperty;var qt=Object.getOwnPropertyDescriptor;var Zt=Object.getOwnPropertyNames;var Qt=Object.getPrototypeOf,er=Object.prototype.hasOwnProperty;var tr=(e,t)=>{for(var r in t)$e(e,r,{get:t[r],enumerable:!0})},ot=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Zt(t))!er.call(e,i)&&i!==r&&$e(e,i,{get:()=>t[i],enumerable:!(o=qt(t,i))||o.enumerable});return e};var rr=(e,t,r)=>(r=e!=null?Xt(Qt(e)):{},ot(t||!e||!e.__esModule?$e(r,"default",{value:e,enumerable:!0}):r,e)),nr=e=>ot($e({},"__esModule",{value:!0}),e);var kn={};tr(kn,{asciiRenderer:()=>ie,buildMermaidInkUrl:()=>Ie,combineEventHandlers:()=>wn,createEventCollector:()=>yn,createIRBuilder:()=>ce,createLiveVisualizer:()=>Ft,createMermaidInkGenerator:()=>Ot,createParallelDetector:()=>it,createPerformanceAnalyzer:()=>pt,createTimeTravelController:()=>jt,createUrlGenerator:()=>Rt,createVisualizer:()=>ze,defaultColorScheme:()=>F,detectParallelGroups:()=>ve,encodeForMermaidInk:()=>Qe,flowchartRenderer:()=>fe,getHeatLevel:()=>he,hasChildren:()=>sr,htmlRenderer:()=>Ut,isDecisionNode:()=>Y,isParallelNode:()=>V,isRaceNode:()=>H,isSequenceNode:()=>Ke,isStepNode:()=>K,isStreamNode:()=>te,loggerRenderer:()=>Re,mermaidRenderer:()=>se,renderToHTML:()=>Ht,toExportUrl:()=>be,toKrokiPngUrl:()=>St,toKrokiSvgUrl:()=>xt,toKrokiUrl:()=>de,toMermaidInkJpegUrl:()=>Nt,toMermaidInkPdfUrl:()=>Mt,toMermaidInkPngUrl:()=>$t,toMermaidInkSvgUrl:()=>Et,toMermaidInkUrl:()=>G,toMermaidInkWebpUrl:()=>Tt,trackDecision:()=>Fe,trackIf:()=>zt,trackSwitch:()=>Kt,visualizeEvents:()=>bn});module.exports=nr(kn);function A(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1).replace(/\.0$/,"")}s`;let t=Math.floor(e/6e4),r=Math.round(e%6e4/1e3);return r>=60&&(t+=1,r=0),r===0?`${t}m`:`${t}m ${r}s`}function Ne(){return`node_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function or(e){for(let t of e)if((t.type==="parallel"||t.type==="race"||t.type==="sequence")&&!t.id.startsWith("detected_")||t.type==="decision")return!0;return!1}function ve(e,t={}){if(or(e))return e;let{minOverlapMs:r=0,maxGapMs:o=5}=t,i=[],n=[];for(let c=0;c<e.length;c++){let l=e[c];l.type==="step"&&l.startTs!==void 0?i.push({node:l,startTs:l.startTs,endTs:l.endTs??l.startTs+(l.durationMs??0),originalIndex:c}):n.push({node:l,originalIndex:c})}if(i.length<=1)return e;i.sort((c,l)=>c.startTs-l.startTs);let s=[],a=[i[0]];for(let c=1;c<i.length;c++){let l=i[c],p=Math.min(...a.map(E=>E.startTs)),h=Math.max(...a.map(E=>E.endTs)),f=l.startTs<=p+o,b=l.startTs<h;if(!f&&!b){s.push(a),a=[l];continue}let k=b?Math.min(l.endTs,h)-l.startTs:0;f||k>=r?a.push(l):(s.push(a),a=[l])}s.push(a);let u=[];for(let c of s){let l=Math.min(...c.map(p=>p.originalIndex));if(c.length===1)u.push({node:c[0].node,position:l});else{let p=c.map(k=>k.node),h=Math.min(...c.map(k=>k.startTs)),f=Math.max(...c.map(k=>k.endTs)),b={type:"parallel",id:`detected_parallel_${h}`,name:`${p.length} parallel steps`,state:ir(p),mode:"all",children:p,startTs:h,endTs:f,durationMs:f-h};u.push({node:b,position:l})}}for(let{node:c,originalIndex:l}of n)u.push({node:c,position:l});return u.sort((c,l)=>c.position-l.position),u.map(c=>c.node)}function ir(e){return e.some(n=>n.state==="error")?"error":e.some(n=>n.state==="running")?"running":e.some(n=>n.state==="pending")?"pending":(e.every(n=>n.state==="success"||n.state==="cached"),"success")}function it(e={}){return{detect:t=>ve(t,e)}}function ce(e={}){let{detectParallel:t=!0,parallelDetection:r,enableSnapshots:o=!1,maxSnapshots:i=1e3}=e,n=o,s=Ne(),a,u,c,l="pending",p,h,f=new Map,b=[],k=[],E=new Map,D=[],T=Date.now(),N=T,v={onAfterStep:new Map},x,g=[],y=0;function $(d){return d.stepId??d.stepKey??d.name??Ne()}function C(d){if(b.length>0){b[b.length-1].children.push(d),N=Date.now();return}if(k.length>0){let w=k[k.length-1];for(let m of w.branches.values())if(m.taken){m.children.push(d),N=Date.now();return}w.pendingChildren.push(d),N=Date.now();return}D.push(d),N=Date.now()}function M(d){if(!n)return;let w=ne(),m=new Map;for(let[W,X]of f)m.set(W,{id:X.id,name:X.name,key:X.key,startTs:X.startTs,retryCount:X.retryCount,timedOut:X.timedOut,timeoutMs:X.timeoutMs});let U={id:`snapshot_${y}`,eventIndex:y,event:structuredClone(d),ir:structuredClone(w),timestamp:Date.now(),activeSteps:m};g.push(U),g.length>i&&g.shift(),y++}function L(d){switch(d.type){case"workflow_start":{D=[],c=void 0,h=void 0,p=void 0,f.clear(),b.length=0,k.length=0,E.clear(),a=d.workflowId,u=d.ts,l="running",T=Date.now(),N=T,x!==void 0&&x!==d.workflowId&&(v.shouldRun=void 0,v.onBeforeStart=void 0),x=d.workflowId,v.onAfterStep=new Map;break}case"workflow_success":l="success",c=d.ts,h=d.durationMs,N=Date.now();break;case"workflow_error":l="error",c=d.ts,p=d.error,h=d.durationMs,N=Date.now();break;case"workflow_cancelled":l="aborted",c=d.ts,h=d.durationMs,N=Date.now();break;case"step_start":{let w=$(d);f.set(w,{id:w,name:d.name,key:d.stepKey,startTs:d.ts,retryCount:0,timedOut:!1}),N=Date.now();break}case"step_success":{let w=$(d),m=f.get(w);if(m){let U={type:"step",id:m.id,name:m.name,key:m.key,state:"success",startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,...m.retryCount>0&&{retryCount:m.retryCount},...m.timedOut&&{timedOut:!0,timeoutMs:m.timeoutMs}};C(U),f.delete(w)}break}case"step_error":{let w=$(d),m=f.get(w);if(m){let U={type:"step",id:m.id,name:m.name,key:m.key,state:"error",startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,error:d.error,...m.retryCount>0&&{retryCount:m.retryCount},...m.timedOut&&{timedOut:!0,timeoutMs:m.timeoutMs}};C(U),f.delete(w)}break}case"step_aborted":{let w=$(d),m=f.get(w);if(m){let U={type:"step",id:m.id,name:m.name,key:m.key,state:"aborted",startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,...m.retryCount>0&&{retryCount:m.retryCount},...m.timedOut&&{timedOut:!0,timeoutMs:m.timeoutMs}};C(U),f.delete(w)}break}case"step_cache_hit":{let m={type:"step",id:$(d),name:d.name,key:d.stepKey,state:"cached",startTs:d.ts,endTs:d.ts,durationMs:0};C(m);break}case"step_cache_miss":break;case"step_complete":break;case"step_timeout":{let w=$(d),m=f.get(w);m&&(m.timedOut=!0,m.timeoutMs=d.timeoutMs),N=Date.now();break}case"step_retry":{let w=$(d),m=f.get(w);m&&(m.retryCount=(d.attempt??1)-1),N=Date.now();break}case"step_retries_exhausted":N=Date.now();break;case"step_skipped":{let m={type:"step",id:$(d),name:d.name,key:d.stepKey,state:"skipped",startTs:d.ts,endTs:d.ts,durationMs:0};C(m);break}case"hook_should_run":{let w={type:"shouldRun",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.shouldRun=w,x=d.workflowId,N=Date.now();break}case"hook_should_run_error":{let w={type:"shouldRun",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.shouldRun=w,x=d.workflowId,N=Date.now();break}case"hook_before_start":{let w={type:"onBeforeStart",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.onBeforeStart=w,x=d.workflowId,N=Date.now();break}case"hook_before_start_error":{let w={type:"onBeforeStart",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.onBeforeStart=w,x=d.workflowId,N=Date.now();break}case"hook_after_step":{let w={type:"onAfterStep",state:"success",ts:d.ts,durationMs:d.durationMs,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,w),N=Date.now();break}case"hook_after_step_error":{let w={type:"onAfterStep",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,w),N=Date.now();break}case"stream_created":{let w=`${d.workflowId}:${d.namespace}`;E.set(w,{id:Ne(),namespace:d.namespace,startTs:d.ts,writeCount:0,readCount:0,streamState:"active",backpressureOccurred:!1,finalPosition:0}),N=Date.now();break}case"stream_write":{let w=`${d.workflowId}:${d.namespace}`,m=E.get(w);m&&(m.writeCount++,m.finalPosition=Math.max(m.finalPosition,d.position)),N=Date.now();break}case"stream_read":{let w=`${d.workflowId}:${d.namespace}`,m=E.get(w);m&&m.readCount++,N=Date.now();break}case"stream_close":{let w=`${d.workflowId}:${d.namespace}`,m=E.get(w);if(m){m.streamState="closed",m.finalPosition=d.finalPosition;let U={type:"stream",id:m.id,namespace:m.namespace,state:"success",startTs:m.startTs,endTs:d.ts,durationMs:d.ts-m.startTs,writeCount:m.writeCount,readCount:m.readCount,finalPosition:d.finalPosition,streamState:"closed",backpressureOccurred:m.backpressureOccurred};C(U),E.delete(w)}N=Date.now();break}case"stream_error":{let w=`${d.workflowId}:${d.namespace}`,m=E.get(w);if(m){m.streamState="error";let U={type:"stream",id:m.id,namespace:m.namespace,state:"error",error:d.error,startTs:m.startTs,endTs:d.ts,durationMs:d.ts-m.startTs,writeCount:m.writeCount,readCount:m.readCount,finalPosition:d.position,streamState:"error",backpressureOccurred:m.backpressureOccurred};C(U),E.delete(w)}N=Date.now();break}case"stream_backpressure":{let w=`${d.workflowId}:${d.namespace}`,m=E.get(w);m&&(m.backpressureOccurred=!0),N=Date.now();break}}M(d)}function O(d){if(d.type==="scope_start")b.push({id:d.scopeId,name:d.name,type:d.scopeType,startTs:d.ts,children:[]}),N=Date.now();else if(d.type==="scope_end"){let w=b.findIndex(W=>W.id===d.scopeId);if(w===-1)return;for(;b.length>w+1;){let W=b.pop(),X=W.type==="race"?{type:"race",id:W.id,name:W.name,state:R(W.children),startTs:W.startTs,endTs:d.ts,children:W.children}:{type:"parallel",id:W.id,name:W.name,state:R(W.children),startTs:W.startTs,endTs:d.ts,children:W.children,mode:W.type==="allSettled"?"allSettled":"all"};b[b.length-1].children.push(X)}let[m]=b.splice(w,1),U=m.type==="race"?{type:"race",id:m.id,name:m.name,state:R(m.children),startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,children:m.children,winnerId:d.winnerId}:{type:"parallel",id:m.id,name:m.name,state:R(m.children),startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,children:m.children,mode:m.type==="allSettled"?"allSettled":"all"};C(U)}}function S(d){if(d.type==="decision_start")k.push({id:d.decisionId,name:d.name,condition:d.condition,decisionValue:d.decisionValue,startTs:d.ts,branches:new Map,pendingChildren:[]}),N=Date.now();else if(d.type==="decision_branch"){let w=k.find(m=>m.id===d.decisionId);if(w){let m=d.branchLabel,U=w.branches.get(m);if(U)U.taken=d.taken,d.taken&&w.pendingChildren.length>0&&(U.children.unshift(...w.pendingChildren),w.pendingChildren=[]);else{let W=d.taken?[...w.pendingChildren]:[];d.taken&&(w.pendingChildren=[]),w.branches.set(m,{label:d.branchLabel,condition:d.condition,taken:d.taken,children:W})}N=Date.now()}}else if(d.type==="decision_end"){let w=k.findIndex(m=>m.id===d.decisionId);if(w!==-1){let[m]=k.splice(w,1),U=k.splice(w),W=Array.from(m.branches.values());W.length===0&&m.pendingChildren.length>0&&(W=[{label:"default",taken:!0,children:[...m.pendingChildren]}]);let X=W.find(Ee=>Ee.taken)?.label,Jt={type:"decision",id:m.id,name:m.name,state:R(W.flatMap(Ee=>Ee.taken?Ee.children:[])),startTs:m.startTs,endTs:d.ts,durationMs:d.durationMs,condition:m.condition,decisionValue:m.decisionValue,branchTaken:d.branchTaken??X,branches:W};C(Jt),k.push(...U),N=Date.now()}}}function R(d){return d.length===0?"success":d.some(W=>W.state==="error")?"error":d.every(W=>W.state==="success"||W.state==="cached")?"success":d.some(W=>W.state==="running")?"running":"pending"}function J(){let d=[...D];for(let[,w]of f)d.push({type:"step",id:w.id,name:w.name,key:w.key,state:"running",startTs:w.startTs,...w.retryCount>0&&{retryCount:w.retryCount},...w.timedOut&&{timedOut:!0,timeoutMs:w.timeoutMs}});for(let[,w]of E)d.push({type:"stream",id:w.id,namespace:w.namespace,state:"running",startTs:w.startTs,writeCount:w.writeCount,readCount:w.readCount,finalPosition:w.finalPosition,streamState:w.streamState,backpressureOccurred:w.backpressureOccurred});return d}function ne(){let d=J();t&&(d=ve(d,r));let w={type:"workflow",id:a??s,workflowId:a??s,state:l,startTs:u,endTs:c,durationMs:h,children:d,error:p},m=v.shouldRun!==void 0||v.onBeforeStart!==void 0||v.onAfterStep.size>0;return{root:w,metadata:{createdAt:T,lastUpdatedAt:N},...m&&{hooks:v}}}function oe(){a=void 0,u=void 0,c=void 0,l="pending",p=void 0,h=void 0,f.clear(),b.length=0,k.length=0,E.clear(),D=[],T=Date.now(),N=T,v={onAfterStep:new Map},x=void 0,g.length=0,y=0}function ke(){return[...g]}function Vt(d){return g[d]}function Gt(d){return g[d]?.ir}function Yt(){g.length=0,y=0}return{handleEvent:L,handleScopeEvent:O,handleDecisionEvent:S,getIR:ne,reset:oe,getSnapshots:ke,getSnapshotAt:Vt,getIRAt:Gt,clearSnapshots:Yt,get hasActiveSteps(){return f.size>0},get state(){return l},get snapshotCount(){return g.length},get snapshotsEnabled(){return n},setSnapshotsEnabled(d){n=d}}}var Me=require("awaitly");function K(e){return e.type==="step"}function Ke(e){return e.type==="sequence"}function V(e){return e.type==="parallel"}function H(e){return e.type==="race"}function Y(e){return e.type==="decision"}function te(e){return e.type==="stream"}function sr(e){return"children"in e||e.type==="decision"&&"branches"in e}var je="\x1B[0m",ar="\x1B[1m",at="\x1B[2m",cr="\x1B[31m",dr="\x1B[32m",lr="\x1B[33m",ur="\x1B[34m",st="\x1B[90m",pr="\x1B[37m";function q(e,t){return t?`${t}${e}${je}`:e}function xe(e){return`${ar}${e}${je}`}function _(e){return`${at}${e}${je}`}var F={pending:pr,running:lr,success:dr,error:cr,aborted:st,cached:ur,skipped:at+st};function fr(e){switch(e){case"pending":return"\u25CB";case"running":return"\u27F3";case"success":return"\u2713";case"error":return"\u2717";case"aborted":return"\u2298";case"cached":return"\u21BA";case"skipped":return"\u2298"}}function Se(e,t){let r=fr(e);return q(r,t[e])}function Te(e,t,r){return q(e,r[t])}function re(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}var I={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeRight:"\u251C",teeLeft:"\u2524",teeDown:"\u252C",teeUp:"\u2534",cross:"\u253C"},me={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},mr="\x1B[0m";function hr(e){return e<.2?me.cold:e<.4?me.cool:e<.6?me.neutral:e<.8?me.warm:e<.95?me.hot:me.critical}function ct(e,t){let r=hr(t);return r?`${r}${e}${mr}`:e}function gr(e){try{return(0,Me.ok)(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return(0,Me.err)("STRINGIFY_ERROR")}}function dt(e){let t=gr(e);return t.ok?t.value:"[unserializable]"}var lt="\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";function Ge(e,t=10){if(e.length===0)return"";let r=e.slice(-t),o=Math.min(...r),n=Math.max(...r)-o||1;return r.map(s=>{let a=(s-o)/n,u=Math.floor(a*(lt.length-1));return lt[u]}).join("")}function Ve(e,t){let r=re(e).length,o=Math.max(0,t-r);return e+" ".repeat(o)}function wr(e,t){if(!t)return I.horizontal.repeat(e);let r=` ${t} `,o=re(r).length,i=e-o;if(i<4)return I.horizontal.repeat(e);let n=2,s=i-n;return I.horizontal.repeat(n)+r+I.horizontal.repeat(s)}function ut(e,t,r){let o=e.state==="success"?q("\u2699",r.success):q("\u26A0",r.error),i=e.durationMs!==void 0?_(` [${A(e.durationMs)}]`):"",n="";e.type==="shouldRun"&&e.context?.skipped?n=_(" \u2192 workflow skipped"):e.type==="shouldRun"&&e.context?.result===!0?n=_(" \u2192 proceed"):e.type==="onBeforeStart"&&e.context?.skipped?n=_(" \u2192 workflow skipped"):e.type==="onAfterStep"&&e.context?.stepKey&&(n=_(` (${e.context.stepKey})`));let s=e.state==="error"&&e.error?_(` error: ${String(e.error)}`):"";return`${o} ${_(t)}${n}${i}${s}`}function br(e,t){let r=[];return e.shouldRun&&r.push(ut(e.shouldRun,"shouldRun",t)),e.onBeforeStart&&r.push(ut(e.onBeforeStart,"onBeforeStart",t)),r.length>0&&r.push(_("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),r}function ie(){return{name:"ascii",supportsLive:!0,render(e,t){let r={...F,...t.colors},o=Math.max(t.terminalWidth??60,5),i=o-4,n=[],s=e.root.name??"workflow",a=xe(s);if(n.push(`${I.topLeft}${wr(o-2,a)}${I.topRight}`),n.push(`${I.vertical}${" ".repeat(o-2)}${I.vertical}`),e.hooks){let c=br(e.hooks,r);for(let l of c)n.push(`${I.vertical} ${Ve(l,i)}${I.vertical}`)}let u=Oe(e.root.children,t,r,0,e.hooks);for(let c of u)n.push(`${I.vertical} ${Ve(c,i)}${I.vertical}`);if(n.push(`${I.vertical}${" ".repeat(o-2)}${I.vertical}`),e.root.durationMs!==void 0&&t.showTimings){let c=e.root.state==="success"?"Completed":e.root.state==="aborted"?"Cancelled":"Failed",p=`${Te(c,e.root.state,r)} in ${A(e.root.durationMs)}`;n.push(`${I.vertical} ${Ve(p,i)}${I.vertical}`),n.push(`${I.vertical}${" ".repeat(o-2)}${I.vertical}`)}return n.push(`${I.bottomLeft}${I.horizontal.repeat(o-2)}${I.bottomRight}`),n.join(`
|
|
2
|
+
`)}}}function Oe(e,t,r,o,i){let n=[];for(let s of e)K(s)?n.push(Ye(s,t,r,i)):V(s)?n.push(...kr(s,t,r,o,i)):H(s)?n.push(...vr(s,t,r,o,i)):Y(s)?n.push(...xr(s,t,r,o,i)):te(s)&&n.push(yr(s,t,r));return n}function Ye(e,t,r,o){let i=Se(e.state,r),n=e.name??e.key??"step",s=t,a=s.showHeatmap&&s.heatmapData?s.heatmapData.heat.get(e.key??"")??s.heatmapData.heat.get(e.name??"")??s.heatmapData.heat.get(e.id):void 0,u;a!==void 0?u=ct(n,a):u=Te(n,e.state,r);let c=`${i} ${u}`;if(t.showKeys&&e.key&&e.name&&(c+=_(` [key: ${e.key}]`)),e.input!==void 0){let p=typeof e.input=="string"?e.input:dt(e.input).slice(0,30);c+=_(` [in: ${p}${p.length>=30?"...":""}]`)}if(e.output!==void 0&&e.state==="success"){let p=typeof e.output=="string"?e.output:dt(e.output).slice(0,30);c+=_(` [out: ${p}${p.length>=30?"...":""}]`)}if(t.showTimings&&e.durationMs!==void 0){let p=A(e.durationMs),h=a!==void 0?ct(`[${p}]`,a):_(`[${p}]`);c+=` ${h}`}if(s.showSparklines&&s.timingHistory){let p=s.timingHistory.get(e.key??"")??s.timingHistory.get(e.name??"")??s.timingHistory.get(e.id);p&&p.length>1&&(c+=` ${_(Ge(p))}`)}if(e.retryCount!==void 0&&e.retryCount>0&&(c+=_(` [${e.retryCount} ${e.retryCount===1?"retry":"retries"}]`)),e.timedOut){let p=e.timeoutMs!==void 0?` ${e.timeoutMs}ms`:"";c+=_(` [timeout${p}]`)}let l=e.key??e.id;if(o&&l&&o.onAfterStep.has(l)){let p=o.onAfterStep.get(l),h=p.state==="success"?q("\u2699",r.success):q("\u26A0",r.error),f=p.durationMs!==void 0?_(` ${A(p.durationMs)}`):"";c+=` ${h}${f}`}return c}function yr(e,t,r){let o=e.streamState==="active"?q("\u27F3",r.running):e.streamState==="closed"?q("\u2713",r.success):q("\u2717",r.error),i=`stream:${e.namespace}`,n=Te(i,e.state,r),s=_(`[W:${e.writeCount} R:${e.readCount}]`),a=`${o} ${n} ${s}`;return t.showTimings&&e.durationMs!==void 0&&(a+=` ${_(`[${A(e.durationMs)}]`)}`),e.backpressureOccurred&&(a+=_(" [backpressure]")),e.streamState==="closed"&&(a+=_(` pos:${e.finalPosition}`)),a}function kr(e,t,r,o,i){let n=[],s=" ".repeat(o),a=Se(e.state,r),u=e.name??"parallel",c=e.mode==="allSettled"?" (allSettled)":"";if(n.push(`${s}${I.teeRight}${I.teeDown}${I.horizontal} ${a} ${xe(u)}${c}`),e.children.length===0)n.push(`${s}${I.vertical} ${_("(operations not individually tracked)")}`),n.push(`${s}${I.vertical} ${_("(wrap each operation with step() to see individual steps)")}`);else for(let l=0;l<e.children.length;l++){let p=e.children[l],f=l===e.children.length-1?`${s}${I.vertical} ${I.bottomLeft}`:`${s}${I.vertical} ${I.teeRight}`;if(K(p))n.push(`${f} ${Ye(p,t,r,i)}`);else{let b=Oe([p],t,r,o+1,i);for(let k of b)n.push(`${s}${I.vertical} ${k}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${s}${I.bottomLeft}${I.horizontal}${I.horizontal} ${_(`[${A(e.durationMs)}]`)}`),n}function vr(e,t,r,o,i){let n=[],s=" ".repeat(o),a=Se(e.state,r),u=e.name??"race";if(n.push(`${s}${I.teeRight}\u26A1 ${a} ${xe(u)}`),e.children.length===0)n.push(`${s}${I.vertical} ${_("(operations not individually tracked)")}`),n.push(`${s}${I.vertical} ${_("(wrap each operation with step() to see individual steps)")}`);else for(let c=0;c<e.children.length;c++){let l=e.children[c],h=c===e.children.length-1?`${s}${I.vertical} ${I.bottomLeft}`:`${s}${I.vertical} ${I.teeRight}`,b=e.winnerId&&l.id===e.winnerId?_(" (winner)"):"";if(K(l))n.push(`${h} ${Ye(l,t,r,i)}${b}`);else{let k=Oe([l],t,r,o+1,i);for(let E of k)n.push(`${s}${I.vertical} ${E}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${s}${I.bottomLeft}${I.horizontal}${I.horizontal} ${_(`[${A(e.durationMs)}]`)}`),n}function xr(e,t,r,o,i){let n=[],s=" ".repeat(o),a=Se(e.state,r),u=e.name??"decision",c=e.condition?_(` (${e.condition})`):"",l=e.decisionValue!==void 0?_(` = ${String(e.decisionValue)}`):"",p=e.branchTaken!==void 0?_(` \u2192 ${String(e.branchTaken)}`):"";n.push(`${s}${I.teeRight}${I.teeDown}${I.horizontal} ${a} ${xe(u)}${c}${l}${p}`);for(let h=0;h<e.branches.length;h++){let f=e.branches[h],k=h===e.branches.length-1?`${s}${I.vertical} ${I.bottomLeft}`:`${s}${I.vertical} ${I.teeRight}`,E=f.taken?"\u2713":"\u2298",D=f.taken?r.success:r.skipped,T=q(`${E} ${f.label}`,D),N=f.condition?_(` (${f.condition})`):"";if(n.push(`${k} ${T}${N}`),f.children.length>0){let v=Oe(f.children,t,r,o+1,i);for(let x of v)n.push(`${s}${I.vertical} ${x}`)}else f.taken||n.push(`${s}${I.vertical} ${_("(skipped)")}`)}return t.showTimings&&e.durationMs!==void 0&&n.push(`${s}${I.bottomLeft}${I.horizontal}${I.horizontal} ${_(`[${A(e.durationMs)}]`)}`),n}var _e=require("awaitly");function Je(e){let t=[];for(let r of e)if(t.push(r),"children"in r&&Array.isArray(r.children)&&t.push(...Je(r.children)),"branches"in r)for(let o of r.branches)t.push(...Je(o.children));return t}function De(e,t){if(e.length===0)return 0;let r=Math.floor(e.length*t);return e[Math.min(r,e.length-1)]}function he(e){return e<.2?"cold":e<.4?"cool":e<.6?"neutral":e<.8?"warm":e<.95?"hot":"critical"}function pt(){let e=new Map,t=new Map,r=new Map,o=new Map,i=[];function n(v){return v.stepKey??v.stepId??v.name??"unknown"}function s(v){let x=new Map;for(let g of v)switch(g.type){case"step_start":{let y=n(g);x.set(y,{retried:!1,timedOut:!1});break}case"step_retry":{let y=n(g),$=x.get(y);$&&($.retried=!0);break}case"step_timeout":{let y=n(g),$=x.get(y);$&&($.timedOut=!0);break}case"step_success":{let y=n(g),$=x.get(y),C=e.get(y)??[];C.push(g.durationMs),e.set(y,C);let M=t.get(y)??{retried:0,total:0};M.total++,$?.retried&&M.retried++,t.set(y,M);let L=o.get(y)??{timedOut:0,total:0};L.total++,$?.timedOut&&L.timedOut++,o.set(y,L);let O=r.get(y)??{errors:0,total:0};O.total++,r.set(y,O),x.delete(y);break}case"step_error":{let y=n(g),$=x.get(y),C=e.get(y)??[];C.push(g.durationMs),e.set(y,C);let M=t.get(y)??{retried:0,total:0};M.total++,$?.retried&&M.retried++,t.set(y,M);let L=o.get(y)??{timedOut:0,total:0};L.total++,$?.timedOut&&L.timedOut++,o.set(y,L);let O=r.get(y)??{errors:0,total:0};O.total++,O.errors++,r.set(y,O),x.delete(y);break}}}function a(v){s(v.events)}function u(v){i.push(v)}function c(v){i.length>0&&(s(i),i=[])}function l(v){let x=e.get(v);if(!x||x.length===0)return;let g=[...x].sort((S,R)=>S-R),$=g.reduce((S,R)=>S+R,0)/g.length,C=g.reduce((S,R)=>S+(R-$)**2,0)/g.length,M=t.get(v)??{retried:0,total:1},L=r.get(v)??{errors:0,total:1},O=o.get(v)??{timedOut:0,total:1};return{nodeId:v,avgDurationMs:$,minDurationMs:g[0],maxDurationMs:g[g.length-1],stdDevMs:Math.sqrt(C),samples:g.length,retryRate:M.total>0?M.retried/M.total:0,timeoutRate:O.total>0?O.timedOut/O.total:0,errorRate:L.total>0?L.errors/L.total:0,percentiles:{p50:De(g,.5),p90:De(g,.9),p95:De(g,.95),p99:De(g,.99)}}}function p(v){return l(v)}function h(v,x="duration"){let g=new Map,y=Je(v.root.children),$=[];for(let R of y){let J=("key"in R?R.key:void 0)??R.id??R.name,ne=l(J);if(ne){let oe;switch(x){case"duration":oe=ne.avgDurationMs;break;case"retryRate":oe=ne.retryRate;break;case"errorRate":oe=ne.errorRate;break}$.push({id:R.id,value:oe})}}if($.length===0)return{heat:g,metric:x,stats:{min:0,max:0,mean:0,threshold:0}};let C=$.map(R=>R.value),M=Math.min(...C),L=Math.max(...C),O=C.reduce((R,J)=>R+J,0)/C.length,S=L-M||1;for(let{id:R,value:J}of $)g.set(R,(J-M)/S);return{heat:g,metric:x,stats:{min:M,max:L,mean:O,threshold:O+(L-O)*.5}}}function f(){let v=new Map;for(let x of e.keys()){let g=l(x);g&&v.set(x,g)}return v}function b(v=10){return[...f().values()].sort((g,y)=>y.avgDurationMs-g.avgDurationMs).slice(0,v)}function k(v=10){return[...f().values()].filter(g=>g.errorRate>0).sort((g,y)=>y.errorRate-g.errorRate).slice(0,v)}function E(v=10){return[...f().values()].filter(g=>g.retryRate>0).sort((g,y)=>y.retryRate-g.retryRate).slice(0,v)}function D(){return JSON.stringify({timingData:Object.fromEntries(e),retryData:Object.fromEntries(t),errorData:Object.fromEntries(r),timeoutData:Object.fromEntries(o)})}function T(v){let x=JSON.parse(v);e.clear(),t.clear(),r.clear(),o.clear();for(let[g,y]of Object.entries(x.timingData??{}))e.set(g,y);for(let[g,y]of Object.entries(x.retryData??{}))t.set(g,y);for(let[g,y]of Object.entries(x.errorData??{}))r.set(g,y);for(let[g,y]of Object.entries(x.timeoutData??{}))o.set(g,y)}function N(){e.clear(),t.clear(),r.clear(),o.clear(),i=[]}return{addRun:a,addEvent:u,finalizeRun:c,getNodePerformance:p,getHeatmap:h,getSlowestNodes:b,getErrorProneNodes:k,getRetryProneNodes:E,getAllPerformance:f,exportData:D,importData:T,clear:N}}function Sr(){return[" classDef pending fill:#f3f4f6,stroke:#9ca3af,stroke-width:2px,color:#374151"," classDef running fill:#fef3c7,stroke:#f59e0b,stroke-width:3px,color:#92400e"," classDef success fill:#d1fae5,stroke:#10b981,stroke-width:3px,color:#065f46"," classDef error fill:#fee2e2,stroke:#ef4444,stroke-width:3px,color:#991b1b"," classDef aborted fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#4b5563,stroke-dasharray: 5 5"," classDef cached fill:#dbeafe,stroke:#3b82f6,stroke-width:3px,color:#1e40af"," classDef skipped fill:#f9fafb,stroke:#d1d5db,stroke-width:2px,color:#6b7280,stroke-dasharray: 5 5"," classDef stream fill:#ede9fe,stroke:#8b5cf6,stroke-width:3px,color:#5b21b6"," classDef streamActive fill:#ddd6fe,stroke:#7c3aed,stroke-width:3px,color:#4c1d95"," classDef streamError fill:#fce7f3,stroke:#db2777,stroke-width:3px,color:#9d174d"]}function Rr(){return[" classDef heat_cold fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af"," classDef heat_cool fill:#ccfbf1,stroke:#14b8a6,stroke-width:2px,color:#0f766e"," classDef heat_neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#374151"," classDef heat_warm fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e"," classDef heat_hot fill:#fed7aa,stroke:#f97316,stroke-width:3px,color:#c2410c"," classDef heat_critical fill:#fecaca,stroke:#ef4444,stroke-width:3px,color:#b91c1c"]}function Ir(e){return`heat_${e}`}function Er(){return[" classDef hook_success fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e"," classDef hook_error fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d"]}function $r(e){try{return(0,_e.ok)(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return(0,_e.err)("STRINGIFY_ERROR")}}function ft(e){let t=$r(e);return t.ok?t.value:"[unserializable]"}function Nr(e,t,r){let o;if(e.shouldRun){let i="hook_shouldRun",n=e.shouldRun.state==="success"?"hook_success":"hook_error",s=e.shouldRun.state==="success"?"\u2699":"\u26A0",a=r.showTimings&&e.shouldRun.durationMs!==void 0?` ${A(e.shouldRun.durationMs)}`:"",u=e.shouldRun.context?.skipped?"\\nskipped workflow":e.shouldRun.context?.result===!0?"\\nproceed":"";t.push(` ${i}[["${s} shouldRun${u}${a}"]]:::${n}`),o=i}if(e.onBeforeStart){let i="hook_beforeStart",n=e.onBeforeStart.state==="success"?"hook_success":"hook_error",s=e.onBeforeStart.state==="success"?"\u2699":"\u26A0",a=r.showTimings&&e.onBeforeStart.durationMs!==void 0?` ${A(e.onBeforeStart.durationMs)}`:"",u=e.onBeforeStart.context?.skipped?"\\nskipped workflow":"";t.push(` ${i}[["${s} onBeforeStart${u}${a}"]]:::${n}`),o&&t.push(` ${o} --> ${i}`),o=i}return{lastHookId:o}}var mt=0,Ce=new Set,Le=new Set;function ge(e="node"){return`${e}_${++mt}`}function Tr(){mt=0,Ce.clear(),Le.clear()}function j(e){return e.replace(/"/g,"#quot;").replace(/</g,"<").replace(/>/g,">").trim()}function ht(e){return j(e).replace(/[{}[\]()]/g,"")}function se(){return{name:"mermaid",supportsLive:!1,render(e,t){Tr();let r=[],o=t;r.push("flowchart TD");let i;e.hooks&&(i=Nr(e.hooks,r,t).lastHookId);let n="start";r.push(` ${n}(("\u25B6 Start"))`),i&&r.push(` ${i} --> ${n}`);let s=n;for(let u of e.root.children){let c=We(u,t,r,o,e.hooks);r.push(` ${s} --> ${c.entryId}`),s=c.exitId}if(["success","error","aborted"].includes(e.root.state)){let u="finish",c=e.root.state==="success"?"\u2713":e.root.state==="error"?"\u2717":"\u2298",l=e.root.state==="success"?"Done":e.root.state==="error"?"Failed":"Cancelled",p=`(("${c} ${l}"))`,h=e.root.state==="success"?":::success":e.root.state==="error"?":::error":":::aborted";r.push(` ${u}${p}${h}`),r.push(` ${s} --> ${u}`)}return r.push(""),r.push(...Sr()),o.showHeatmap&&r.push(...Rr()),e.hooks&&r.push(...Er()),r.join(`
|
|
3
|
+
`)}}}function We(e,t,r,o,i){if(K(e))return Mr(e,t,r,o,i);if(V(e))return Or(e,t,r,o,i);if(H(e))return Dr(e,t,r,o,i);if(Y(e))return Cr(e,t,r,o,i);if(te(e))return Lr(e,t,r);let n=ge("unknown");return r.push(` ${n}["Unknown Node"]`),{entryId:n,exitId:n}}function Mr(e,t,r,o,i){let n=t,s=n.showRetryEdges??!0,a=n.showErrorEdges??!0,u=n.showTimeoutEdges??!0,c=e.key?`step_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:ge("step");if(Le.has(c)){let g=2;for(;Le.has(`${c}_${g}`);)g++;c=`${c}_${g}`}Le.add(c);let l=e.name??e.key??"Step",p=t.showKeys&&e.key&&e.name?`${l} [${e.key}]`:l,h=j(p),f=t.showTimings&&e.durationMs!==void 0?` ${A(e.durationMs)}`:"",b="";switch(e.state){case"success":b="\u2713 ";break;case"error":b="\u2717 ";break;case"cached":b="\u{1F4BE} ";break;case"running":b="\u23F3 ";break;case"skipped":b="\u2298 ";break}let k="";if(e.input!==void 0){let g=typeof e.input=="string"?j(e.input):j(ft(e.input).slice(0,20));k+=`\\nin: ${g}`}if(e.output!==void 0&&e.state==="success"){let g=typeof e.output=="string"?j(e.output):j(ft(e.output).slice(0,20));k+=`\\nout: ${g}`}let E="",D=e.key??e.id;if(i&&D&&i.onAfterStep.has(D)){let g=i.onAfterStep.get(D),y=g.state==="success"?"\u2699":"\u26A0",$=t.showTimings&&g.durationMs!==void 0?` ${A(g.durationMs)}`:"";E=`\\n${y} hook${$}`}let T=(b+h+k+E+f).trim(),N,v=o?.showHeatmap&&o.heatmapData?o.heatmapData.heat.get(e.key??"")??o.heatmapData.heat.get(e.name??"")??o.heatmapData.heat.get(e.id):void 0;if(v!==void 0){let g=he(v);N=Ir(g)}else N=e.state;let x;switch(e.state){case"error":x=`{{"${T}"}}`;break;case"cached":x=`[("${T}")]`;break;case"skipped":x=`["${T}"]`;break;default:x=`["${T}"]`}if(r.push(` ${c}${x}:::${N}`),s&&e.retryCount!==void 0&&e.retryCount>0){let g=`\u21BB ${e.retryCount} retr${e.retryCount===1?"y":"ies"}`;r.push(` ${c} -.->|"${g}"| ${c}`)}if(a&&e.state==="error"&&e.error!==void 0){let g=`ERR_${c}`,y=j(String(e.error)).slice(0,30);r.push(` ${g}{{"${y}"}}`),r.push(` ${c} -->|error| ${g}`),r.push(` style ${g} fill:#fee2e2,stroke:#dc2626`)}if(u&&e.timedOut){let g=`TO_${c}`,y=e.timeoutMs!==void 0?`${e.timeoutMs}ms`:"";r.push(` ${g}{{"\u23F1 Timeout ${y}"}}`),r.push(` ${c} -.->|timeout| ${g}`),r.push(` style ${g} fill:#fef3c7,stroke:#f59e0b`)}return{entryId:c,exitId:c}}function Or(e,t,r,o,i){let n=ge("parallel"),s=`${n}_fork`,a=`${n}_join`,u=ht(e.name??"Parallel"),c=e.mode==="allSettled"?" (allSettled)":"";if(e.children.length===0){let h=n,f=j(`${u}${c}`),b="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${A(e.durationMs)}`:"";return r.push(` ${h}["${f}${k}\\n${b}"]:::${e.state}`),{entryId:h,exitId:h}}r.push(` subgraph ${n}["${u}${c}"]`),r.push(" direction TB"),r.push(` ${s}{"\u26A1 Fork"}`);let l=[];for(let h of e.children){let f=We(h,t,r,o,i);r.push(` ${s} --> ${f.entryId}`),l.push(f.exitId)}r.push(` ${a}{"\u2713 Join"}`);for(let h of l)r.push(` ${h} --> ${a}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:s,exitId:a}}function Dr(e,t,r,o,i){let n=ge("race"),s=`${n}_start`,a=`${n}_end`,u=ht(e.name??"Race");if(e.children.length===0){let h=n,f=j(u),b="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${A(e.durationMs)}`:"";return r.push(` ${h}["\u26A1 ${f}${k}\\n${b}"]:::${e.state}`),{entryId:h,exitId:h}}r.push(` subgraph ${n}["\u26A1 ${u}"]`),r.push(" direction TB"),r.push(` ${s}(("\u{1F3C1} Start"))`);let c=[],l;for(let h of e.children){let f=We(h,t,r,o,i),b=e.winnerId===h.id;r.push(` ${s} --> ${f.entryId}`),b&&(l=f.exitId),c.push({exitId:f.exitId,isWinner:b})}r.push(` ${a}(("\u2713 First"))`);for(let{exitId:h,isWinner:f}of c)f&&l?r.push(` ${h} ==>|\u{1F3C6} Winner| ${a}`):e.winnerId?r.push(` ${h} -. cancelled .-> ${a}`):r.push(` ${h} --> ${a}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:s,exitId:a}}function Cr(e,t,r,o,i){let n=e.key?`decision_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:ge("decision");if(Ce.has(n)){let h=2;for(;Ce.has(`${n}_${h}`);)h++;n=`${n}_${h}`}Ce.add(n);let s=j(e.condition??"condition"),a=e.decisionValue!==void 0?` = ${j(String(e.decisionValue)).slice(0,30)}`:"",u=`${s}${a}`.trim();r.push(` ${n}{"${u}"}`);let c=[],l,p=new Set;for(let h of e.branches){let f=`${n}_${h.label.replace(/[^a-zA-Z0-9]/g,"_")}`;if(p.has(f)){let T=2;for(;p.has(`${f}_${T}`);)T++;f=`${f}_${T}`}p.add(f);let b=j(h.label),k=h.taken?`${b} \u2713`:`${b} skipped`,E=h.taken?":::success":":::skipped";r.push(` ${f}["${k}"]${E}`);let D=h.condition?`|${j(h.condition).replace(/\|/g,"")}|`:"";if(r.push(` ${n} -->${D} ${f}`),h.children.length>0){let T=f;for(let N of h.children){let v=We(N,t,r,o,i);r.push(` ${T} --> ${v.entryId}`),T=v.exitId}c.push(T),h.taken&&(l=T)}else c.push(f),h.taken&&(l=f)}return l?{entryId:n,exitId:l}:{entryId:n,exitId:n}}function Lr(e,t,r){let o=`stream_${e.namespace.replace(/[^a-zA-Z0-9]/g,"_")}_${ge("")}`,i=`W:${e.writeCount} R:${e.readCount}`,n="";switch(e.streamState){case"active":n="\u27F3 ";break;case"closed":n="\u2713 ";break;case"error":n="\u2717 ";break}let s=t.showTimings&&e.durationMs!==void 0?` ${A(e.durationMs)}`:"",a=e.backpressureOccurred?"\\nbackpressure":"",u=`${n}stream:${j(e.namespace)}\\n${i}${a}${s}`,c;return e.streamState==="error"?c="streamError":e.streamState==="active"?c="streamActive":c="stream",r.push(` ${o}{{"${u}"}}:::${c}`),{entryId:o,exitId:o}}var B={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeDown:"\u252C",teeUp:"\u2534",teeRight:"\u251C",teeLeft:"\u2524",cross:"\u253C",arrowDown:"\u25BC",arrowUp:"\u25B2"},_r={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},Wr="\x1B[0m";function Br(e,t){let r=[],o=[];for(let i=0;i<t;i++)r.push(Array(e).fill(" ")),o.push(Array(e).fill(void 0));return{cells:r,colors:o,width:e,height:t}}function P(e,t,r,o,i){t>=0&&t<e.width&&r>=0&&r<e.height&&(e.cells[r][t]=o,i&&(e.colors[r][t]=i))}function bt(e,t,r){return t>=0&&t<e.width&&r>=0&&r<e.height?e.cells[r][t]:" "}function Pr(e,t,r,o,i){P(e,t,r,B.topLeft);for(let n=1;n<o-1;n++)P(e,t+n,r,B.horizontal);P(e,t+o-1,r,B.topRight);for(let n=1;n<i-1;n++)P(e,t,r+n,B.vertical),P(e,t+o-1,r+n,B.vertical);P(e,t,r+i-1,B.bottomLeft);for(let n=1;n<o-1;n++)P(e,t+n,r+i-1,B.horizontal);P(e,t+o-1,r+i-1,B.bottomRight)}function gt(e,t,r,o,i){let n=re(o).split("");for(let s=0;s<n.length;s++)P(e,t+s,r,n[s],i)}function ae(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let s=i;s<=n;s++){let a=bt(e,t,s);a===B.horizontal?P(e,t,s,B.cross):(a===" "||a===B.vertical)&&P(e,t,s,B.vertical)}}function wt(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let s=i;s<=n;s++){let a=bt(e,s,t);a===B.vertical?P(e,s,t,B.cross):(a===" "||a===B.horizontal)&&P(e,s,t,B.horizontal)}}function pe(e,t,r){P(e,t,r,B.arrowDown)}function Ar(e){let t=[];for(let r=0;r<e.height;r++){let o="";for(let i=0;i<e.width;i++){let n=e.colors[r][i],s=e.cells[r][i];n?o+=n+s+Wr:o+=s}t.push(o.trimEnd())}for(;t.length>0&&t[t.length-1]==="";)t.pop();return t.join(`
|
|
4
|
+
`)}var Z=11,Q=2,we=2,Be=3;function qe(e,t){if(e.length<=t)return[e];let r=e.split(" "),o=[],i="";for(let n of r)i?i.length+1+n.length<=t?i+=" "+n:(o.push(i),i=n):i=n;if(i&&o.push(i),o.length===0)for(let n=0;n<e.length;n+=t)o.push(e.slice(n,n+t));return o}function yt(e){switch(e){case"success":return"\u2713";case"error":return"\u2717";case"running":return"\u27F3";case"pending":return"\u25CB";case"aborted":case"skipped":return"\u2298";case"cached":return"\u21BA";default:return"\u25CB"}}function Ur(e,t,r){let o=t.showStartEnd??!0,i=t,n=Math.floor(r/2),s=[],a=0;if(o){let c=Pe("start","start",["\u25B6 Start"],"success",n,a);s.push(c),a=c.bottomY+we}for(let c of e.root.children){let l=Ae(c,n,a,r-4,t,i);s.push(l.node),a=l.bottomY+we}if(o&&["success","error","aborted"].includes(e.root.state)){let c=e.root.state==="success"?"\u2713 Done":e.root.state==="error"?"\u2717 Failed":"\u2298 Cancelled",l=Pe("end","end",[c],e.root.state,n,a);s.push(l),a=l.bottomY}return{nodes:s,totalHeight:a+2}}function Pe(e,t,r,o,i,n){let s=Math.max(...r.map(l=>re(l).length)),a=Math.max(Z,s+Q*2),u=r.length+2,c=i-Math.floor(a/2);return{id:e,type:t,label:r,state:o,x:c,y:n,width:a,height:u,centerX:i,bottomY:n+u-1}}function Ae(e,t,r,o,i,n){if(K(e))return Hr(e,t,r,o,i,n);if(V(e)||H(e))return zr(e,t,r,o,i,n);if(Y(e))return Kr(e,t,r,o,i,n);if(te(e))return Fr(e,t,r,o,i,n);let s=Pe(e.id,"step",["?"],e.state,t,r);return{node:s,bottomY:s.bottomY}}function Hr(e,t,r,o,i,n){let s=e.name??e.key??"step",a=yt(e.state),u=[],c=`${a} ${s}`;i.showKeys&&e.key&&e.name&&(c+=` [${e.key}]`);let l=Math.min(o-Q*2,40);if(u.push(...qe(c,l)),i.showTimings&&e.durationMs!==void 0&&u.push(`[${A(e.durationMs)}]`),e.retryCount&&e.retryCount>0&&u.push(`${e.retryCount}x retry`),e.timedOut&&u.push("timeout"),n?.showSparklines&&n.timingHistory){let D=n.timingHistory.get(e.key??"")??n.timingHistory.get(e.name??"")??n.timingHistory.get(e.id);D&&D.length>1&&u.push(Ge(D,8))}let p=Math.max(...u.map(D=>re(D).length)),h=Math.max(Z,p+Q*2),f=u.length+2,b=t-Math.floor(h/2),k;if(n?.showHeatmap&&n.heatmapData){let D=e.key??e.name??e.id;k=n.heatmapData.heat.get(e.id)??n.heatmapData.heat.get(D)}let E={id:e.id,type:"step",label:u,state:e.state,x:b,y:r,width:h,height:f,centerX:t,bottomY:r+f-1,metadata:k!==void 0?{heat:k}:void 0};return{node:E,bottomY:E.bottomY}}function Fr(e,t,r,o,i,n){let s=`stream:${e.namespace}`,a=e.streamState==="active"?"\u27F3":e.streamState==="closed"?"\u2713":"\u2717",u=[],c=`${a} ${s}`,l=Math.min(o-Q*2,40);u.push(...qe(c,l)),u.push(`W:${e.writeCount} R:${e.readCount}`),i.showTimings&&e.durationMs!==void 0&&u.push(`[${A(e.durationMs)}]`),e.backpressureOccurred&&u.push("backpressure");let p=Math.max(...u.map(E=>re(E).length)),h=Math.max(Z,p+Q*2),f=u.length+2,b=t-Math.floor(h/2),k={id:e.id,type:"stream",label:u,state:e.state,x:b,y:r,width:h,height:f,centerX:t,bottomY:r+f-1,metadata:{streamState:e.streamState,backpressureOccurred:e.backpressureOccurred}};return{node:k,bottomY:k.bottomY}}function zr(e,t,r,o,i,n){let s=H(e),a=e.name??(s?"race":"parallel"),c=`${s?"\u26A1":"\u2AD8"} ${a}`;if(e.children.length===0){let y=[c,"(not tracked)"],$=Pe(e.id,s?"race":"parallel",y,e.state,t,r);return{node:$,bottomY:$.bottomY}}let l=Math.floor((o-Be*(e.children.length-1))/e.children.length),p=[];for(let y of e.children){let $=Xe(y,Math.max(l,Z),i,n);p.push($.width)}let h=p.reduce((y,$)=>y+$,0)+Be*(e.children.length-1),f=h>o&&e.children.length>1,b=Math.max(Z,c.length+Q*2),k=3,E=t-Math.floor(b/2),D=r;D+=k,D+=1,D+=1;let T=[];if(f)for(let y=0;y<e.children.length;y++){let $=e.children[y],C=Ae($,t,D,o,i,n);s&&H(e)&&e.winnerId===$.id&&(C.node.metadata={...C.node.metadata,isWinner:!0}),T.push(C.node),D=C.bottomY+we}else{let y=t-Math.floor(h/2);for(let $=0;$<e.children.length;$++){let C=e.children[$],M=y+Math.floor(p[$]/2),L=Ae(C,M,D,p[$],i,n);s&&H(e)&&e.winnerId===C.id&&(L.node.metadata={...L.node.metadata,isWinner:!0}),T.push(L.node),y+=p[$]+Be}}let N=Math.max(...T.map(y=>y.bottomY)),x=!f&&T.length>1?N+2:N;return{node:{id:e.id,type:s?"race":"parallel",label:[c],state:e.state,x:E,y:r,width:b,height:k,centerX:t,bottomY:x,children:T,metadata:{verticalLayout:f}},bottomY:x}}function Kr(e,t,r,o,i,n){let s=e.name??"decision",a=e.condition?` (${e.condition.slice(0,20)})`:"",u=`\u25C7 ${s}${a}`,c=Math.min(o-Q*2,40),l=qe(u,c),p=Math.max(...l.map(x=>re(x).length)),h=Math.max(Z,p+Q*2),f=l.length+2,b=t-Math.floor(h/2),k=e.branches.find(x=>x.taken),E=k&&k.children.length>0?k:e.branches.find(x=>x.children.length>0);if(!E||E.children.length===0){let x={id:e.id,type:"decision",label:l,state:e.state,x:b,y:r,width:h,height:f,centerX:t,bottomY:r+f-1};return{node:x,bottomY:x.bottomY}}let D=r+f+we,T=[];for(let x of E.children){let g=Ae(x,t,D,o,i,n);T.push(g.node),D=g.bottomY+we}let N=T.length>0?T[T.length-1].bottomY:r+f-1;return{node:{id:e.id,type:"decision",label:l,state:e.state,x:b,y:r,width:h,height:f,centerX:t,bottomY:N,children:T},bottomY:N}}function Xe(e,t,r,o){if(K(e)){let i=e.name??e.key??"step",n=yt(e.state),s=1;r.showTimings&&e.durationMs!==void 0&&s++,e.retryCount&&e.retryCount>0&&s++,e.timedOut&&s++,o?.showSparklines&&(o.timingHistory?.has(e.key??"")||o.timingHistory?.has(e.name??"")||o.timingHistory?.has(e.id))&&s++;let a=`${n} ${i}`;r.showKeys&&e.key&&e.name&&(a+=` [${e.key}]`);let u=Math.min(t,Math.max(Z,a.length+Q*2)),c=s+2;return{width:u,height:c}}if(V(e)||H(e)){if(e.children.length===0)return{width:Z+4,height:4};let i=Math.floor(t/e.children.length),n=0,s=0;for(let a of e.children){let u=Xe(a,i,r,o);n+=u.width,s=Math.max(s,u.height)}return n+=Be*(e.children.length-1),{width:Math.max(n,Z),height:5+s+2}}if(Y(e)){let i=e.branches.find(s=>s.taken),n=0;if(i)for(let s of i.children){let a=Xe(s,t,r,o);n+=a.height+we}return{width:Math.min(t,30),height:3+n}}if(te(e)){let i=`stream:${e.namespace}`,n=2;r.showTimings&&e.durationMs!==void 0&&n++,e.backpressureOccurred&&n++;let s=Math.min(t,Math.max(Z,i.length+Q*2+4)),a=n+2;return{width:s,height:a}}return{width:Z,height:3}}function jr(e,t,r){let o={...F,...r.colors};for(let i=0;i<t.length;i++){let n=t[i],s=i===t.length-1;if(Ue(e,n,o),!s){let a=t[i+1],u=n.centerX,c=n.bottomY+1,l=a.centerX,p=a.y-1;ae(e,u,c,p-1),pe(e,l,p)}}}function Ue(e,t,r){let o=t.type!=="start",i=t.type!=="end"&&(!t.children||t.children.length===0);Pr(e,t.x,t.y,t.width,t.height),o&&P(e,t.centerX,t.y,B.teeUp),(i||t.children&&t.children.length>0)&&P(e,t.centerX,t.y+t.height-1,B.teeDown);let n=t.width-Q*2,s=Jr(t,r);for(let a=0;a<t.label.length;a++){let u=t.label[a],c=t.x+1+Math.floor((n-re(u).length)/2),l=t.y+1+a;gt(e,c,l,u,s)}t.metadata?.isWinner&>(e,t.x+t.width-2,t.y,"\u{1F3C6}"),t.children&&t.children.length>0&&(t.type==="parallel"||t.type==="race"?Vr(e,t,r):Gr(e,t,r))}function Vr(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=t.centerX;if(t.metadata?.verticalLayout===!0){let a=o[0];ae(e,n,i,a.y-2),pe(e,a.centerX,a.y-1);for(let u=0;u<o.length;u++){let c=o[u];if(Ue(e,c,r),u<o.length-1){let l=o[u+1];ae(e,c.centerX,c.bottomY+1,l.y-2),pe(e,l.centerX,l.y-1)}}return}if(o.length===1)ae(e,n,i,o[0].y-2),pe(e,o[0].centerX,o[0].y-1);else{let a=o.map(l=>l.centerX),u=Math.min(...a),c=Math.max(...a);ae(e,n,i,i+1),wt(e,i+1,u,c),P(e,n,i+1,B.teeUp);for(let l of o){let p=l.centerX;p===u?P(e,p,i+1,B.topLeft):p===c?P(e,p,i+1,B.topRight):p!==n&&P(e,p,i+1,B.teeDown),ae(e,p,i+2,l.y-2),pe(e,p,l.y-1)}}for(let a of o)Ue(e,a,r);if(o.length>1){let a=o.map(f=>f.bottomY),u=Math.max(...a),c=u+1,l=o.map(f=>f.centerX),p=Math.min(...l),h=Math.max(...l);for(let f of o)f.bottomY<u&&ae(e,f.centerX,f.bottomY+1,c-1);wt(e,c,p,h);for(let f of o){let b=f.centerX;b===p?P(e,b,c,B.bottomLeft):b===h?P(e,b,c,B.bottomRight):P(e,b,c,B.teeUp)}P(e,t.centerX,c,B.teeDown),P(e,t.centerX,c+1,B.vertical)}}function Gr(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=o[0];ae(e,t.centerX,i,n.y-2),pe(e,n.centerX,n.y-1);for(let s=0;s<o.length;s++){let a=o[s];if(Ue(e,a,r),s<o.length-1){let u=o[s+1];ae(e,a.centerX,a.bottomY+1,u.y-2),pe(e,u.centerX,u.y-1)}}}var Yr={active:"\x1B[36m",closed:"\x1B[32m",error:"\x1B[31m"};function Jr(e,t){if(e.metadata?.heat!==void 0){let r=he(e.metadata.heat);return _r[r]||void 0}return e.type==="stream"&&e.metadata?.streamState?Yr[e.metadata.streamState]||void 0:t[e.state]||void 0}function fe(){return{name:"flowchart",supportsLive:!1,render(e,t){let r=t.terminalWidth??80,{nodes:o,totalHeight:i}=Ur(e,t,r),n=Br(r,i);return jr(n,o,t),Ar(n)}}}function Xr(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function qr(e){let t=[];function r(o){for(let i of o)if(K(i))t.push(i);else if(Ke(i))r(i.children);else if(V(i)||H(i))r(i.children);else if(Y(i))for(let n of i.branches)n.taken&&r(n.children)}return r(e),t}function Zr(e){let t={id:e.id,name:e.name??e.key??e.id,state:e.state};return e.key&&(t.key=e.key),e.durationMs!==void 0&&(t.durationMs=e.durationMs),e.startTs!==void 0&&(t.startTs=e.startTs),e.endTs!==void 0&&(t.endTs=e.endTs),e.retryCount!==void 0&&e.retryCount>0&&(t.retryCount=e.retryCount),e.timedOut&&(t.timedOut=!0,e.timeoutMs!==void 0&&(t.timeoutMs=e.timeoutMs)),e.error!==void 0&&(t.error=typeof e.error=="string"?e.error:String(e.error)),t}function Qr(e){let t=0,r=0,o=0,i=0,n=0,s;for(let a of e)a.state==="success"&&t++,a.state==="error"&&r++,a.state==="cached"&&o++,a.state==="skipped"&&i++,a.retryCount!==void 0&&(n+=a.retryCount),a.durationMs!==void 0&&(!s||a.durationMs>s.durationMs)&&(s={name:a.name??a.key??a.id,durationMs:a.durationMs});return{totalSteps:e.length,successCount:t,errorCount:r,cacheHits:o,skippedCount:i,totalRetries:n,slowestStep:s}}function en(e){let t={};if(e.shouldRun&&(t.shouldRun={result:e.shouldRun.context?.result,durationMs:e.shouldRun.durationMs},e.shouldRun.error!==void 0&&e.shouldRun.error!==null&&(t.shouldRun.error=String(e.shouldRun.error))),e.onBeforeStart&&(t.onBeforeStart={durationMs:e.onBeforeStart.durationMs},e.onBeforeStart.error!==void 0&&e.onBeforeStart.error!==null&&(t.onBeforeStart.error=String(e.onBeforeStart.error))),e.onAfterStep.size>0){t.onAfterStep=[];for(let[r,o]of e.onAfterStep){let i={stepKey:r};o.durationMs!==void 0&&(i.durationMs=o.durationMs),o.error!==void 0&&o.error!==null&&(i.error=String(o.error)),t.onAfterStep.push(i)}}return t}function tn(e,t){let r=e.root,o=qr(r.children),i=t.includeDiagram??!0,n=t.stripAnsiColors??!0,s={workflow:{id:r.workflowId,name:r.name,state:r.state,durationMs:r.durationMs,startedAt:r.startTs,completedAt:r.endTs},steps:o.map(Zr),summary:Qr(o)};if(e.hooks){let a=en(e.hooks);Object.keys(a).length>0&&(s.hooks=a)}if(i){let c=((t.diagramFormat??"ascii")==="flowchart"?fe():ie()).render(e,t);n&&(c=Xr(c)),s.diagram=c}return s}function Re(){return{name:"logger",supportsLive:!1,render(e,t){let o=tn(e,t);return JSON.stringify(o)}}}var ee=require("awaitly");var kt=rr(require("pako"),1),rn=typeof globalThis<"u"&&"Buffer"in globalThis&&typeof globalThis.Buffer=="function";function nn(e){let t;if(rn)t=globalThis.Buffer.from(e).toString("base64");else{let r="";for(let o=0;o<e.length;o++)r+=String.fromCharCode(e[o]);t=btoa(r)}return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function He(e){let r=new TextEncoder().encode(e),o=kt.default.deflate(r);return nn(o)}var vt="https://kroki.io";function Ze(e,t,r,o={}){let i=o.baseUrl??vt,n=He(r);return`${i}/${e}/${t}/${n}`}function de(e,t="svg",r={}){let o=se(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:F},n=o.render(e,i);return Ze("mermaid",t,n,r)}function xt(e,t={}){return de(e,"svg",t)}function St(e,t={}){return de(e,"png",t)}function Rt(e={}){let t=e.baseUrl??vt;return{toUrl(r,o){return de(r,o,{baseUrl:t})},toSvgUrl(r){return de(r,"svg",{baseUrl:t})},toPngUrl(r){return de(r,"png",{baseUrl:t})},toPdfUrl(r){return de(r,"pdf",{baseUrl:t})},getBaseUrl(){return t}}}var It="https://mermaid.ink";function Qe(e){return`pako:${He(e)}`}function on(e){if("provider"in e){let t=e;return{theme:t.mermaidTheme,bgColor:t.background,scale:t.scale,fit:t.fit,width:t.width,height:t.height,paper:t.paper,imageType:"png"}}return e}function sn(e,t){let r=[];return t.bgColor&&r.push(`bgColor=${encodeURIComponent(t.bgColor)}`),t.theme&&r.push(`theme=${t.theme}`),t.width!==void 0&&r.push(`width=${t.width}`),t.height!==void 0&&r.push(`height=${t.height}`),t.scale!==void 0&&(t.width!==void 0||t.height!==void 0)&&r.push(`scale=${t.scale}`),e==="img"&&t.imageType&&t.imageType!=="jpeg"&&r.push(`type=${t.imageType}`),e==="pdf"&&(t.fit&&r.push("fit"),t.paper&&!t.fit&&r.push(`paper=${t.paper}`),t.landscape&&!t.fit&&r.push("landscape")),r.length>0?`?${r.join("&")}`:""}function Ie(e,t,r={}){let o=on(r),i=o.baseUrl??It,n=Qe(t),s=sn(e,o);return`${i}/${e}/${n}${s}`}function G(e,t="svg",r={}){let o=se(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:F},n=o.render(e,i);return Ie(t,n,r)}function Et(e,t={}){return G(e,"svg",t)}function $t(e,t={}){return G(e,"img",{...t,imageType:"png"})}function Nt(e,t={}){return G(e,"img",{...t,imageType:"jpeg"})}function Tt(e,t={}){return G(e,"img",{...t,imageType:"webp"})}function Mt(e,t={}){return G(e,"pdf",t)}function Ot(e={}){let t=e.baseUrl??It;return{toUrl(r,o){return G(r,o,e)},toSvgUrl(r){return G(r,"svg",e)},toPngUrl(r){return G(r,"img",{...e,imageType:"png"})},toJpegUrl(r){return G(r,"img",{...e,imageType:"jpeg"})},toWebpUrl(r){return G(r,"img",{...e,imageType:"webp"})},toPdfUrl(r){return G(r,"pdf",e)},getBaseUrl(){return t},getOptions(){return{...e}}}}function an(e,t,r){return e==="mermaid-ink"&&t==="mermaid"?(0,ee.ok)(void 0):e==="kroki"&&t==="mermaid"?r==="pdf"?(0,ee.err)("UNSUPPORTED_FORMAT"):(0,ee.ok)(void 0):(0,ee.err)("UNSUPPORTED_FORMAT")}function cn(e){switch(e){case"mermaid":return"mermaid";case"graphviz":return"graphviz";case"plantuml":return"plantuml"}}function dn(e){switch(e){case"svg":return"svg";case"png":return"img";case"pdf":return"pdf"}}function be(e,t,r,o={}){switch(e.kind){case"mermaid":break;case"graphviz":case"plantuml":return(0,ee.err)("UNSUPPORTED_DIAGRAM_KIND");default:{let n=e;return(0,ee.err)("UNSUPPORTED_DIAGRAM_KIND")}}let i=an(r.provider,e.kind,t);if(!i.ok)return i;switch(r.provider){case"kroki":return(0,ee.ok)(Ze(cn(e.kind),t,e.source,r));case"mermaid-ink":return(0,ee.ok)(Ie(dn(t),e.source,r));default:{let n=r;return(0,ee.err)("UNKNOWN_PROVIDER")}}}function Dt(e){let t={bg:"#ffffff",bgSecondary:"#f8f9fa",text:"#212529",textMuted:"#6c757d",border:"#dee2e6",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#e9ecef",nodeRunning:"#fff3cd",nodeSuccess:"#d1e7dd",nodeError:"#f8d7da",nodeAborted:"#e9ecef",nodeCached:"#cfe2ff",nodeSkipped:"#f8f9fa",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},r={bg:"#212529",bgSecondary:"#343a40",text:"#f8f9fa",textMuted:"#adb5bd",border:"#495057",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#495057",nodeRunning:"#664d03",nodeSuccess:"#0f5132",nodeError:"#842029",nodeAborted:"#495057",nodeCached:"#084298",nodeSkipped:"#343a40",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},o=n=>`
|
|
5
|
+
--bg: ${n.bg};
|
|
6
|
+
--bg-secondary: ${n.bgSecondary};
|
|
7
|
+
--text: ${n.text};
|
|
8
|
+
--text-muted: ${n.textMuted};
|
|
9
|
+
--border: ${n.border};
|
|
10
|
+
--primary: ${n.primary};
|
|
11
|
+
--success: ${n.success};
|
|
12
|
+
--error: ${n.error};
|
|
13
|
+
--warning: ${n.warning};
|
|
14
|
+
--info: ${n.info};
|
|
15
|
+
--muted: ${n.muted};
|
|
16
|
+
--node-pending: ${n.nodePending};
|
|
17
|
+
--node-running: ${n.nodeRunning};
|
|
18
|
+
--node-success: ${n.nodeSuccess};
|
|
19
|
+
--node-error: ${n.nodeError};
|
|
20
|
+
--node-aborted: ${n.nodeAborted};
|
|
21
|
+
--node-cached: ${n.nodeCached};
|
|
22
|
+
--node-skipped: ${n.nodeSkipped};
|
|
23
|
+
--heat-cold: ${n.heatCold};
|
|
24
|
+
--heat-cool: ${n.heatCool};
|
|
25
|
+
--heat-neutral: ${n.heatNeutral};
|
|
26
|
+
--heat-warm: ${n.heatWarm};
|
|
27
|
+
--heat-hot: ${n.heatHot};
|
|
28
|
+
--heat-critical: ${n.heatCritical};
|
|
29
|
+
`,i;return e==="auto"?i=`
|
|
30
|
+
:root {
|
|
31
|
+
${o(t)}
|
|
32
|
+
}
|
|
33
|
+
@media (prefers-color-scheme: dark) {
|
|
34
|
+
:root {
|
|
35
|
+
${o(r)}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
`:e==="dark"?i=`
|
|
39
|
+
:root {
|
|
40
|
+
${o(r)}
|
|
41
|
+
}
|
|
42
|
+
`:i=`
|
|
43
|
+
:root {
|
|
44
|
+
${o(t)}
|
|
45
|
+
}
|
|
46
|
+
`,`
|
|
47
|
+
${i}
|
|
48
|
+
|
|
49
|
+
* {
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
body {
|
|
56
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
57
|
+
background-color: var(--bg);
|
|
58
|
+
color: var(--text);
|
|
59
|
+
line-height: 1.5;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.workflow-visualizer {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
height: 100vh;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Header */
|
|
70
|
+
.wv-header {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: space-between;
|
|
74
|
+
padding: 12px 20px;
|
|
75
|
+
background-color: var(--bg-secondary);
|
|
76
|
+
border-bottom: 1px solid var(--border);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.wv-header h1 {
|
|
80
|
+
font-size: 1.25rem;
|
|
81
|
+
font-weight: 600;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.wv-controls {
|
|
85
|
+
display: flex;
|
|
86
|
+
gap: 8px;
|
|
87
|
+
align-items: center;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.wv-btn {
|
|
91
|
+
display: inline-flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
padding: 6px 12px;
|
|
95
|
+
font-size: 0.875rem;
|
|
96
|
+
font-weight: 500;
|
|
97
|
+
border: 1px solid var(--border);
|
|
98
|
+
border-radius: 6px;
|
|
99
|
+
background-color: var(--bg);
|
|
100
|
+
color: var(--text);
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
transition: all 0.15s ease;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.wv-btn:hover {
|
|
106
|
+
background-color: var(--bg-secondary);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.wv-btn:disabled {
|
|
110
|
+
opacity: 0.5;
|
|
111
|
+
cursor: not-allowed;
|
|
112
|
+
background-color: var(--bg-secondary);
|
|
113
|
+
color: var(--text-muted);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.wv-btn--primary {
|
|
117
|
+
background-color: var(--primary);
|
|
118
|
+
border-color: var(--primary);
|
|
119
|
+
color: white;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.wv-btn--primary:hover {
|
|
123
|
+
opacity: 0.9;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.wv-btn--icon {
|
|
127
|
+
padding: 6px;
|
|
128
|
+
min-width: 32px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* Main content area */
|
|
132
|
+
.wv-main {
|
|
133
|
+
display: flex;
|
|
134
|
+
flex: 1;
|
|
135
|
+
overflow: hidden;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Diagram container */
|
|
139
|
+
.wv-diagram {
|
|
140
|
+
flex: 1;
|
|
141
|
+
position: relative;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
background-color: var(--bg);
|
|
144
|
+
background-image:
|
|
145
|
+
radial-gradient(circle, var(--border) 1px, transparent 1px);
|
|
146
|
+
background-size: 20px 20px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.wv-diagram svg {
|
|
150
|
+
width: 100%;
|
|
151
|
+
height: 100%;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* SVG Node styles */
|
|
155
|
+
.wv-node {
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
transition: filter 0.15s ease;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.wv-node:hover {
|
|
161
|
+
filter: brightness(1.1) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.wv-node rect,
|
|
165
|
+
.wv-node circle {
|
|
166
|
+
stroke: var(--border);
|
|
167
|
+
stroke-width: 2;
|
|
168
|
+
transition: all 0.2s ease;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.wv-node:hover rect,
|
|
172
|
+
.wv-node:hover circle {
|
|
173
|
+
stroke-width: 3;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.wv-node--pending rect { fill: var(--node-pending); }
|
|
177
|
+
.wv-node--running rect { fill: var(--node-running); stroke: var(--warning); }
|
|
178
|
+
.wv-node--success rect { fill: var(--node-success); stroke: var(--success); }
|
|
179
|
+
.wv-node--error rect { fill: var(--node-error); stroke: var(--error); }
|
|
180
|
+
.wv-node--aborted rect { fill: var(--node-aborted); }
|
|
181
|
+
.wv-node--cached rect { fill: var(--node-cached); stroke: var(--info); }
|
|
182
|
+
.wv-node--skipped rect { fill: var(--node-skipped); opacity: 0.6; }
|
|
183
|
+
|
|
184
|
+
.wv-node--selected rect {
|
|
185
|
+
stroke: var(--primary);
|
|
186
|
+
stroke-width: 3;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.wv-node text {
|
|
190
|
+
fill: var(--text);
|
|
191
|
+
font-size: 12px;
|
|
192
|
+
font-weight: 500;
|
|
193
|
+
dominant-baseline: middle;
|
|
194
|
+
text-anchor: middle;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.wv-node .wv-node-timing {
|
|
198
|
+
fill: var(--text-muted);
|
|
199
|
+
font-size: 10px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Edge styles */
|
|
203
|
+
.wv-edge {
|
|
204
|
+
fill: none;
|
|
205
|
+
stroke: var(--border);
|
|
206
|
+
stroke-width: 2;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.wv-edge--active {
|
|
210
|
+
stroke: var(--success);
|
|
211
|
+
stroke-width: 2.5;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.wv-edge-arrow {
|
|
215
|
+
fill: var(--border);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Parallel/Race container */
|
|
219
|
+
.wv-container {
|
|
220
|
+
fill: transparent;
|
|
221
|
+
stroke: var(--border);
|
|
222
|
+
stroke-dasharray: 5 3;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.wv-container--parallel { stroke: var(--info); }
|
|
226
|
+
.wv-container--race { stroke: var(--warning); }
|
|
227
|
+
|
|
228
|
+
.wv-container-label {
|
|
229
|
+
fill: var(--text-muted);
|
|
230
|
+
font-size: 10px;
|
|
231
|
+
font-weight: 600;
|
|
232
|
+
text-transform: uppercase;
|
|
233
|
+
letter-spacing: 0.5px;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Heatmap overlay */
|
|
237
|
+
.wv-node--heat-cold rect { fill: var(--heat-cold) !important; opacity: 0.7; }
|
|
238
|
+
.wv-node--heat-cool rect { fill: var(--heat-cool) !important; opacity: 0.7; }
|
|
239
|
+
.wv-node--heat-neutral rect { fill: var(--heat-neutral) !important; opacity: 0.7; }
|
|
240
|
+
.wv-node--heat-warm rect { fill: var(--heat-warm) !important; opacity: 0.7; }
|
|
241
|
+
.wv-node--heat-hot rect { fill: var(--heat-hot) !important; opacity: 0.7; }
|
|
242
|
+
.wv-node--heat-critical rect { fill: var(--heat-critical) !important; opacity: 0.85; }
|
|
243
|
+
|
|
244
|
+
/* Timeline scrubber */
|
|
245
|
+
.wv-timeline {
|
|
246
|
+
height: 80px;
|
|
247
|
+
padding: 12px 20px;
|
|
248
|
+
background-color: var(--bg-secondary);
|
|
249
|
+
border-top: 1px solid var(--border);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.wv-timeline-track {
|
|
253
|
+
position: relative;
|
|
254
|
+
height: 24px;
|
|
255
|
+
background-color: var(--bg);
|
|
256
|
+
border-radius: 4px;
|
|
257
|
+
overflow: hidden;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.wv-timeline-progress {
|
|
261
|
+
position: absolute;
|
|
262
|
+
top: 0;
|
|
263
|
+
left: 0;
|
|
264
|
+
height: 100%;
|
|
265
|
+
background-color: var(--primary);
|
|
266
|
+
opacity: 0.3;
|
|
267
|
+
transition: width 0.1s ease;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.wv-timeline-marker {
|
|
271
|
+
position: absolute;
|
|
272
|
+
top: 0;
|
|
273
|
+
width: 3px;
|
|
274
|
+
height: 100%;
|
|
275
|
+
background-color: var(--primary);
|
|
276
|
+
cursor: ew-resize;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.wv-timeline-events {
|
|
280
|
+
display: flex;
|
|
281
|
+
gap: 2px;
|
|
282
|
+
height: 100%;
|
|
283
|
+
align-items: center;
|
|
284
|
+
padding: 4px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.wv-timeline-event {
|
|
288
|
+
width: 4px;
|
|
289
|
+
height: 16px;
|
|
290
|
+
border-radius: 2px;
|
|
291
|
+
background-color: var(--muted);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.wv-timeline-event--success { background-color: var(--success); }
|
|
295
|
+
.wv-timeline-event--error { background-color: var(--error); }
|
|
296
|
+
.wv-timeline-event--running { background-color: var(--warning); }
|
|
297
|
+
|
|
298
|
+
.wv-timeline-controls {
|
|
299
|
+
display: flex;
|
|
300
|
+
gap: 8px;
|
|
301
|
+
margin-top: 8px;
|
|
302
|
+
align-items: center;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.wv-timeline-time {
|
|
306
|
+
font-size: 0.75rem;
|
|
307
|
+
color: var(--text-muted);
|
|
308
|
+
font-family: monospace;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Inspector panel */
|
|
312
|
+
.wv-inspector {
|
|
313
|
+
width: 320px;
|
|
314
|
+
background-color: var(--bg-secondary);
|
|
315
|
+
border-left: 1px solid var(--border);
|
|
316
|
+
overflow-y: auto;
|
|
317
|
+
transition: width 0.2s ease;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.wv-inspector--collapsed {
|
|
321
|
+
width: 0;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.wv-inspector-header {
|
|
325
|
+
display: flex;
|
|
326
|
+
align-items: center;
|
|
327
|
+
justify-content: space-between;
|
|
328
|
+
padding: 12px 16px;
|
|
329
|
+
border-bottom: 1px solid var(--border);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.wv-inspector-header h2 {
|
|
333
|
+
font-size: 0.875rem;
|
|
334
|
+
font-weight: 600;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.wv-inspector-content {
|
|
338
|
+
padding: 16px;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.wv-inspector-section {
|
|
342
|
+
margin-bottom: 20px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.wv-inspector-section h3 {
|
|
346
|
+
font-size: 0.75rem;
|
|
347
|
+
font-weight: 600;
|
|
348
|
+
text-transform: uppercase;
|
|
349
|
+
letter-spacing: 0.5px;
|
|
350
|
+
color: var(--text-muted);
|
|
351
|
+
margin-bottom: 8px;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.wv-inspector-row {
|
|
355
|
+
display: flex;
|
|
356
|
+
justify-content: space-between;
|
|
357
|
+
padding: 4px 0;
|
|
358
|
+
font-size: 0.875rem;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.wv-inspector-label {
|
|
362
|
+
color: var(--text-muted);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.wv-inspector-value {
|
|
366
|
+
font-weight: 500;
|
|
367
|
+
font-family: monospace;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.wv-inspector-value--success { color: var(--success); }
|
|
371
|
+
.wv-inspector-value--error { color: var(--error); }
|
|
372
|
+
.wv-inspector-value--running { color: var(--warning); }
|
|
373
|
+
|
|
374
|
+
/* Status badge */
|
|
375
|
+
.wv-badge {
|
|
376
|
+
display: inline-flex;
|
|
377
|
+
align-items: center;
|
|
378
|
+
padding: 2px 8px;
|
|
379
|
+
font-size: 0.75rem;
|
|
380
|
+
font-weight: 500;
|
|
381
|
+
border-radius: 4px;
|
|
382
|
+
text-transform: capitalize;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.wv-badge--pending { background-color: var(--node-pending); }
|
|
386
|
+
.wv-badge--running { background-color: var(--node-running); color: #664d03; }
|
|
387
|
+
.wv-badge--success { background-color: var(--node-success); color: #0f5132; }
|
|
388
|
+
.wv-badge--error { background-color: var(--node-error); color: #842029; }
|
|
389
|
+
.wv-badge--cached { background-color: var(--node-cached); color: #084298; }
|
|
390
|
+
|
|
391
|
+
/* Live indicator */
|
|
392
|
+
.wv-live {
|
|
393
|
+
display: flex;
|
|
394
|
+
align-items: center;
|
|
395
|
+
gap: 6px;
|
|
396
|
+
padding: 4px 10px;
|
|
397
|
+
background-color: var(--error);
|
|
398
|
+
color: white;
|
|
399
|
+
font-size: 0.75rem;
|
|
400
|
+
font-weight: 600;
|
|
401
|
+
border-radius: 4px;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.wv-live-dot {
|
|
405
|
+
width: 8px;
|
|
406
|
+
height: 8px;
|
|
407
|
+
background-color: white;
|
|
408
|
+
border-radius: 50%;
|
|
409
|
+
animation: wv-pulse 1.5s infinite;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
@keyframes wv-pulse {
|
|
413
|
+
0%, 100% { opacity: 1; }
|
|
414
|
+
50% { opacity: 0.5; }
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* Performance stats */
|
|
418
|
+
.wv-perf-bar {
|
|
419
|
+
height: 8px;
|
|
420
|
+
background-color: var(--bg);
|
|
421
|
+
border-radius: 4px;
|
|
422
|
+
overflow: hidden;
|
|
423
|
+
margin-top: 4px;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.wv-perf-bar-fill {
|
|
427
|
+
height: 100%;
|
|
428
|
+
border-radius: 4px;
|
|
429
|
+
transition: width 0.3s ease;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.wv-perf-bar-fill--cold { background-color: var(--heat-cold); }
|
|
433
|
+
.wv-perf-bar-fill--cool { background-color: var(--heat-cool); }
|
|
434
|
+
.wv-perf-bar-fill--neutral { background-color: var(--heat-neutral); }
|
|
435
|
+
.wv-perf-bar-fill--warm { background-color: var(--heat-warm); }
|
|
436
|
+
.wv-perf-bar-fill--hot { background-color: var(--heat-hot); }
|
|
437
|
+
.wv-perf-bar-fill--critical { background-color: var(--heat-critical); }
|
|
438
|
+
|
|
439
|
+
/* Tooltip */
|
|
440
|
+
.wv-tooltip {
|
|
441
|
+
position: fixed;
|
|
442
|
+
padding: 8px 12px;
|
|
443
|
+
background-color: var(--text);
|
|
444
|
+
color: var(--bg);
|
|
445
|
+
font-size: 0.75rem;
|
|
446
|
+
border-radius: 4px;
|
|
447
|
+
pointer-events: none;
|
|
448
|
+
z-index: 1000;
|
|
449
|
+
max-width: 300px;
|
|
450
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* Loading state */
|
|
454
|
+
.wv-loading {
|
|
455
|
+
display: flex;
|
|
456
|
+
align-items: center;
|
|
457
|
+
justify-content: center;
|
|
458
|
+
height: 100%;
|
|
459
|
+
color: var(--text-muted);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.wv-spinner {
|
|
463
|
+
width: 24px;
|
|
464
|
+
height: 24px;
|
|
465
|
+
border: 3px solid var(--border);
|
|
466
|
+
border-top-color: var(--primary);
|
|
467
|
+
border-radius: 50%;
|
|
468
|
+
animation: wv-spin 1s linear infinite;
|
|
469
|
+
margin-right: 8px;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
@keyframes wv-spin {
|
|
473
|
+
to { transform: rotate(360deg); }
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* Empty state */
|
|
477
|
+
.wv-empty {
|
|
478
|
+
display: flex;
|
|
479
|
+
flex-direction: column;
|
|
480
|
+
align-items: center;
|
|
481
|
+
justify-content: center;
|
|
482
|
+
height: 100%;
|
|
483
|
+
color: var(--text-muted);
|
|
484
|
+
text-align: center;
|
|
485
|
+
padding: 40px;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.wv-empty svg {
|
|
489
|
+
width: 64px;
|
|
490
|
+
height: 64px;
|
|
491
|
+
margin-bottom: 16px;
|
|
492
|
+
opacity: 0.5;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/* Modal */
|
|
496
|
+
.wv-modal {
|
|
497
|
+
position: fixed;
|
|
498
|
+
top: 0;
|
|
499
|
+
left: 0;
|
|
500
|
+
right: 0;
|
|
501
|
+
bottom: 0;
|
|
502
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
503
|
+
display: flex;
|
|
504
|
+
align-items: center;
|
|
505
|
+
justify-content: center;
|
|
506
|
+
z-index: 1000;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.wv-modal-content {
|
|
510
|
+
background-color: var(--bg);
|
|
511
|
+
border-radius: 8px;
|
|
512
|
+
width: 90%;
|
|
513
|
+
max-width: 600px;
|
|
514
|
+
max-height: 90vh;
|
|
515
|
+
display: flex;
|
|
516
|
+
flex-direction: column;
|
|
517
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.wv-modal-header {
|
|
521
|
+
display: flex;
|
|
522
|
+
align-items: center;
|
|
523
|
+
justify-content: space-between;
|
|
524
|
+
padding: 16px 20px;
|
|
525
|
+
border-bottom: 1px solid var(--border);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.wv-modal-header h2 {
|
|
529
|
+
font-size: 1.125rem;
|
|
530
|
+
font-weight: 600;
|
|
531
|
+
margin: 0;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.wv-modal-body {
|
|
535
|
+
padding: 20px;
|
|
536
|
+
overflow-y: auto;
|
|
537
|
+
flex: 1;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.wv-modal-body p {
|
|
541
|
+
margin: 0 0 12px 0;
|
|
542
|
+
font-size: 0.875rem;
|
|
543
|
+
color: var(--text-muted);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
.wv-modal-body code {
|
|
547
|
+
background-color: var(--bg-secondary);
|
|
548
|
+
padding: 2px 6px;
|
|
549
|
+
border-radius: 4px;
|
|
550
|
+
font-size: 0.875rem;
|
|
551
|
+
font-family: monospace;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.wv-textarea {
|
|
555
|
+
width: 100%;
|
|
556
|
+
padding: 12px;
|
|
557
|
+
font-family: monospace;
|
|
558
|
+
font-size: 0.875rem;
|
|
559
|
+
border: 1px solid var(--border);
|
|
560
|
+
border-radius: 6px;
|
|
561
|
+
background-color: var(--bg);
|
|
562
|
+
color: var(--text);
|
|
563
|
+
resize: vertical;
|
|
564
|
+
box-sizing: border-box;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.wv-textarea:focus {
|
|
568
|
+
outline: none;
|
|
569
|
+
border-color: var(--primary);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.wv-error {
|
|
573
|
+
margin-top: 12px;
|
|
574
|
+
padding: 12px;
|
|
575
|
+
background-color: var(--node-error);
|
|
576
|
+
color: #842029;
|
|
577
|
+
border-radius: 6px;
|
|
578
|
+
font-size: 0.875rem;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.wv-modal-footer {
|
|
582
|
+
display: flex;
|
|
583
|
+
gap: 8px;
|
|
584
|
+
justify-content: flex-end;
|
|
585
|
+
padding: 16px 20px;
|
|
586
|
+
border-top: 1px solid var(--border);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/* Responsive */
|
|
590
|
+
@media (max-width: 768px) {
|
|
591
|
+
.wv-inspector {
|
|
592
|
+
position: fixed;
|
|
593
|
+
right: 0;
|
|
594
|
+
top: 0;
|
|
595
|
+
bottom: 0;
|
|
596
|
+
z-index: 100;
|
|
597
|
+
box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.wv-timeline {
|
|
601
|
+
height: auto;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.wv-modal-content {
|
|
605
|
+
width: 95%;
|
|
606
|
+
max-height: 95vh;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
`}function Ct(e){return`
|
|
610
|
+
(function() {
|
|
611
|
+
'use strict';
|
|
612
|
+
|
|
613
|
+
// State
|
|
614
|
+
let selectedNodeId = null;
|
|
615
|
+
let transform = { x: 0, y: 0, scale: 1 };
|
|
616
|
+
let isDragging = false;
|
|
617
|
+
let dragStart = { x: 0, y: 0 };
|
|
618
|
+
let ws = null;
|
|
619
|
+
let snapshots = [];
|
|
620
|
+
let currentSnapshotIndex = -1;
|
|
621
|
+
let isPlaying = false;
|
|
622
|
+
let playbackSpeed = 1;
|
|
623
|
+
let heatmapEnabled = false;
|
|
624
|
+
let heatmapMetric = 'duration';
|
|
625
|
+
|
|
626
|
+
// DOM elements
|
|
627
|
+
const diagram = document.getElementById('diagram');
|
|
628
|
+
const svg = diagram?.querySelector('svg');
|
|
629
|
+
const inspector = document.getElementById('inspector');
|
|
630
|
+
const timeline = document.getElementById('timeline');
|
|
631
|
+
|
|
632
|
+
// Initialize
|
|
633
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
634
|
+
|
|
635
|
+
function init() {
|
|
636
|
+
${e.interactive?"setupInteractivity(); setupLoadJSON();":""}
|
|
637
|
+
// WebSocket must be initialized before time-travel and heatmap checks
|
|
638
|
+
${e.wsUrl?`setupWebSocket('${e.wsUrl}');`:""}
|
|
639
|
+
${e.timeTravel?"setupTimeTravel(); initializeTimeTravelFromData();":""}
|
|
640
|
+
${e.heatmap?"setupHeatmap();":""}
|
|
641
|
+
setupKeyboardShortcuts();
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Load JSON functionality
|
|
645
|
+
function setupLoadJSON() {
|
|
646
|
+
const loadBtn = document.getElementById('load-json-btn');
|
|
647
|
+
const modal = document.getElementById('load-json-modal');
|
|
648
|
+
const closeBtn = document.getElementById('load-json-close');
|
|
649
|
+
const cancelBtn = document.getElementById('load-json-cancel');
|
|
650
|
+
const submitBtn = document.getElementById('load-json-submit');
|
|
651
|
+
const input = document.getElementById('load-json-input');
|
|
652
|
+
const errorDiv = document.getElementById('load-json-error');
|
|
653
|
+
|
|
654
|
+
if (!loadBtn || !modal) return;
|
|
655
|
+
|
|
656
|
+
loadBtn.addEventListener('click', () => {
|
|
657
|
+
modal.style.display = 'flex';
|
|
658
|
+
if (input) {
|
|
659
|
+
input.value = '';
|
|
660
|
+
input.focus();
|
|
661
|
+
}
|
|
662
|
+
if (errorDiv) errorDiv.style.display = 'none';
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
const closeModal = () => {
|
|
666
|
+
modal.style.display = 'none';
|
|
667
|
+
if (errorDiv) errorDiv.style.display = 'none';
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
closeBtn?.addEventListener('click', closeModal);
|
|
671
|
+
cancelBtn?.addEventListener('click', closeModal);
|
|
672
|
+
modal.addEventListener('click', (e) => {
|
|
673
|
+
if (e.target === modal) closeModal();
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
submitBtn?.addEventListener('click', () => {
|
|
677
|
+
if (!input) return;
|
|
678
|
+
|
|
679
|
+
try {
|
|
680
|
+
const jsonText = input.value.trim();
|
|
681
|
+
if (!jsonText) {
|
|
682
|
+
showError('Please paste JSON data');
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const ir = JSON.parse(jsonText);
|
|
687
|
+
|
|
688
|
+
// Validate IR structure
|
|
689
|
+
if (!ir || !ir.root || !ir.root.type || ir.root.type !== 'workflow') {
|
|
690
|
+
showError('Invalid workflow IR. Expected object with root.type === "workflow"');
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Update global data
|
|
695
|
+
window.__WORKFLOW_IR__ = ir;
|
|
696
|
+
const newData = buildWorkflowDataFromIR(ir);
|
|
697
|
+
window.__WORKFLOW_DATA__ = newData;
|
|
698
|
+
|
|
699
|
+
// Save to sessionStorage for full rebuild on reload
|
|
700
|
+
try {
|
|
701
|
+
sessionStorage.setItem('workflow_ir', JSON.stringify(ir));
|
|
702
|
+
} catch (storageErr) {
|
|
703
|
+
console.warn('Failed to save IR to sessionStorage:', storageErr);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Rebuild the diagram (updates node states in-place)
|
|
707
|
+
rebuildDiagram(ir);
|
|
708
|
+
|
|
709
|
+
// Update inspector if node is selected
|
|
710
|
+
if (selectedNodeId) {
|
|
711
|
+
updateInspector(selectedNodeId);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
closeModal();
|
|
715
|
+
|
|
716
|
+
// Offer full rebuild via reload if structure changed significantly
|
|
717
|
+
console.log('IR loaded. Node states updated. Reload page for full layout rebuild with new structure.');
|
|
718
|
+
} catch (e) {
|
|
719
|
+
showError('Invalid JSON: ' + e.message);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
function showError(message) {
|
|
724
|
+
if (errorDiv) {
|
|
725
|
+
errorDiv.textContent = message;
|
|
726
|
+
errorDiv.style.display = 'block';
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
function buildWorkflowDataFromIR(ir) {
|
|
732
|
+
const nodes = {};
|
|
733
|
+
|
|
734
|
+
function collectNodes(flowNodes) {
|
|
735
|
+
for (const node of flowNodes || []) {
|
|
736
|
+
nodes[node.id] = {
|
|
737
|
+
id: node.id,
|
|
738
|
+
name: node.name,
|
|
739
|
+
type: node.type,
|
|
740
|
+
state: node.state,
|
|
741
|
+
key: node.key,
|
|
742
|
+
durationMs: node.durationMs,
|
|
743
|
+
startTs: node.startTs,
|
|
744
|
+
error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
|
|
745
|
+
retryCount: node.retryCount,
|
|
746
|
+
input: node.input,
|
|
747
|
+
output: node.output,
|
|
748
|
+
...(node.type === 'stream' && {
|
|
749
|
+
namespace: node.namespace,
|
|
750
|
+
writeCount: node.writeCount,
|
|
751
|
+
readCount: node.readCount,
|
|
752
|
+
finalPosition: node.finalPosition,
|
|
753
|
+
streamState: node.streamState,
|
|
754
|
+
backpressureOccurred: node.backpressureOccurred,
|
|
755
|
+
}),
|
|
756
|
+
...(node.type === 'decision' && {
|
|
757
|
+
condition: node.condition,
|
|
758
|
+
decisionValue: node.decisionValue,
|
|
759
|
+
branchTaken: node.branchTaken,
|
|
760
|
+
branches: node.branches,
|
|
761
|
+
}),
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
if (node.children) {
|
|
765
|
+
collectNodes(node.children);
|
|
766
|
+
}
|
|
767
|
+
if (node.branches) {
|
|
768
|
+
for (const branch of node.branches) {
|
|
769
|
+
collectNodes(branch.children);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
collectNodes(ir.root.children);
|
|
776
|
+
const hooks = ir.hooks
|
|
777
|
+
? {
|
|
778
|
+
...ir.hooks,
|
|
779
|
+
onAfterStep:
|
|
780
|
+
ir.hooks.onAfterStep instanceof Map
|
|
781
|
+
? Object.fromEntries(ir.hooks.onAfterStep)
|
|
782
|
+
: ir.hooks.onAfterStep,
|
|
783
|
+
}
|
|
784
|
+
: undefined;
|
|
785
|
+
return { nodes, hooks };
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function rebuildDiagram(ir) {
|
|
789
|
+
// Update workflow data and node states
|
|
790
|
+
const newData = buildWorkflowDataFromIR(ir);
|
|
791
|
+
window.__WORKFLOW_DATA__ = newData;
|
|
792
|
+
window.__WORKFLOW_IR__ = ir;
|
|
793
|
+
|
|
794
|
+
// Update existing node states in SVG
|
|
795
|
+
renderIR(ir);
|
|
796
|
+
|
|
797
|
+
// Note: Full diagram rebuild (new nodes, layout changes) requires regenerating the HTML
|
|
798
|
+
// For now, we update node states. Users can save the IR and regenerate HTML for full rebuild.
|
|
799
|
+
console.log('Workflow IR loaded. Node states updated. For full diagram rebuild, regenerate HTML with the new IR.');
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function initializeTimeTravelFromData() {
|
|
803
|
+
// For static HTML (no WebSocket), time travel doesn't work since we only have one state
|
|
804
|
+
// Initialize with empty snapshots and disable controls
|
|
805
|
+
if (!ws) {
|
|
806
|
+
snapshots = [];
|
|
807
|
+
currentSnapshotIndex = -1;
|
|
808
|
+
updateTimelineUI();
|
|
809
|
+
|
|
810
|
+
// Disable time travel controls for static HTML
|
|
811
|
+
const playBtn = document.getElementById('tt-play');
|
|
812
|
+
const pauseBtn = document.getElementById('tt-pause');
|
|
813
|
+
const prevBtn = document.getElementById('tt-prev');
|
|
814
|
+
const nextBtn = document.getElementById('tt-next');
|
|
815
|
+
const slider = document.getElementById('tt-slider');
|
|
816
|
+
|
|
817
|
+
[playBtn, pauseBtn, prevBtn, nextBtn, slider].forEach(btn => {
|
|
818
|
+
if (btn) {
|
|
819
|
+
btn.disabled = true;
|
|
820
|
+
btn.title = 'Time travel requires a live WebSocket connection';
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// Interactivity
|
|
827
|
+
function setupInteractivity() {
|
|
828
|
+
if (!diagram || !svg) return;
|
|
829
|
+
|
|
830
|
+
// Zoom with mouse wheel
|
|
831
|
+
diagram.addEventListener('wheel', (e) => {
|
|
832
|
+
e.preventDefault();
|
|
833
|
+
const delta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
834
|
+
const rect = diagram.getBoundingClientRect();
|
|
835
|
+
const x = e.clientX - rect.left;
|
|
836
|
+
const y = e.clientY - rect.top;
|
|
837
|
+
|
|
838
|
+
// Zoom towards cursor position
|
|
839
|
+
transform.scale *= delta;
|
|
840
|
+
transform.scale = Math.max(0.1, Math.min(5, transform.scale));
|
|
841
|
+
transform.x = x - (x - transform.x) * delta;
|
|
842
|
+
transform.y = y - (y - transform.y) * delta;
|
|
843
|
+
|
|
844
|
+
applyTransform();
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// Pan with drag
|
|
848
|
+
diagram.addEventListener('mousedown', (e) => {
|
|
849
|
+
if (e.target === diagram || e.target === svg) {
|
|
850
|
+
isDragging = true;
|
|
851
|
+
dragStart = { x: e.clientX - transform.x, y: e.clientY - transform.y };
|
|
852
|
+
diagram.style.cursor = 'grabbing';
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
document.addEventListener('mousemove', (e) => {
|
|
857
|
+
if (!isDragging) return;
|
|
858
|
+
transform.x = e.clientX - dragStart.x;
|
|
859
|
+
transform.y = e.clientY - dragStart.y;
|
|
860
|
+
applyTransform();
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
document.addEventListener('mouseup', () => {
|
|
864
|
+
isDragging = false;
|
|
865
|
+
if (diagram) diagram.style.cursor = 'grab';
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
// Node selection - handle clicks on nodes and their children (rect, text, etc.)
|
|
869
|
+
document.querySelectorAll('.wv-node').forEach((node) => {
|
|
870
|
+
node.addEventListener('click', (e) => {
|
|
871
|
+
e.stopPropagation();
|
|
872
|
+
const nodeId = node.dataset.nodeId;
|
|
873
|
+
if (nodeId) {
|
|
874
|
+
selectNode(nodeId);
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
// Also handle clicks directly on child elements (rect, text) that bubble up
|
|
880
|
+
if (svg) {
|
|
881
|
+
svg.addEventListener('click', (e) => {
|
|
882
|
+
// Find the closest .wv-node parent
|
|
883
|
+
let target = e.target;
|
|
884
|
+
while (target && target !== svg) {
|
|
885
|
+
if (target.classList && target.classList.contains('wv-node')) {
|
|
886
|
+
const nodeId = target.dataset?.nodeId;
|
|
887
|
+
if (nodeId) {
|
|
888
|
+
e.stopPropagation();
|
|
889
|
+
selectNode(nodeId);
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
target = target.parentElement;
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// Deselect on background click
|
|
899
|
+
diagram.addEventListener('click', (e) => {
|
|
900
|
+
if (e.target === diagram || e.target === svg) {
|
|
901
|
+
selectNode(null);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
// Zoom buttons
|
|
906
|
+
document.getElementById('zoom-in')?.addEventListener('click', () => zoom(1.2));
|
|
907
|
+
document.getElementById('zoom-out')?.addEventListener('click', () => zoom(0.8));
|
|
908
|
+
document.getElementById('zoom-reset')?.addEventListener('click', resetZoom);
|
|
909
|
+
|
|
910
|
+
// Set initial cursor
|
|
911
|
+
diagram.style.cursor = 'grab';
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
function applyTransform() {
|
|
915
|
+
if (!svg) return;
|
|
916
|
+
const g = svg.querySelector('g.wv-root');
|
|
917
|
+
if (g) {
|
|
918
|
+
g.setAttribute('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.scale + ')');
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
function zoom(factor) {
|
|
923
|
+
if (!diagram) return;
|
|
924
|
+
const rect = diagram.getBoundingClientRect();
|
|
925
|
+
const centerX = rect.width / 2;
|
|
926
|
+
const centerY = rect.height / 2;
|
|
927
|
+
|
|
928
|
+
transform.scale *= factor;
|
|
929
|
+
transform.scale = Math.max(0.1, Math.min(5, transform.scale));
|
|
930
|
+
transform.x = centerX - (centerX - transform.x) * factor;
|
|
931
|
+
transform.y = centerY - (centerY - transform.y) * factor;
|
|
932
|
+
|
|
933
|
+
applyTransform();
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
function resetZoom() {
|
|
937
|
+
transform = { x: 0, y: 0, scale: 1 };
|
|
938
|
+
applyTransform();
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
function selectNode(nodeId) {
|
|
942
|
+
// Remove previous selection
|
|
943
|
+
document.querySelectorAll('.wv-node--selected').forEach((n) => {
|
|
944
|
+
n.classList.remove('wv-node--selected');
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
selectedNodeId = nodeId;
|
|
948
|
+
|
|
949
|
+
if (nodeId) {
|
|
950
|
+
const node = document.querySelector('[data-node-id="' + nodeId + '"]');
|
|
951
|
+
if (node) {
|
|
952
|
+
node.classList.add('wv-node--selected');
|
|
953
|
+
updateInspector(nodeId);
|
|
954
|
+
}
|
|
955
|
+
} else {
|
|
956
|
+
clearInspector();
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function updateInspector(nodeId) {
|
|
961
|
+
const content = document.getElementById('inspector-content');
|
|
962
|
+
if (!content) return;
|
|
963
|
+
|
|
964
|
+
const nodeData = window.__WORKFLOW_DATA__?.nodes?.[nodeId];
|
|
965
|
+
if (!nodeData) {
|
|
966
|
+
// Clear and add empty message using safe DOM methods
|
|
967
|
+
while (content.firstChild) content.removeChild(content.firstChild);
|
|
968
|
+
const p = document.createElement('p');
|
|
969
|
+
p.className = 'wv-empty';
|
|
970
|
+
p.textContent = 'No data available';
|
|
971
|
+
content.appendChild(p);
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
renderInspectorContent(content, nodeData);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
function renderInspectorContent(container, node) {
|
|
979
|
+
// Clear container using safe DOM method
|
|
980
|
+
while (container.firstChild) container.removeChild(container.firstChild);
|
|
981
|
+
|
|
982
|
+
// Node Info section
|
|
983
|
+
const infoSection = createSection('Node Info');
|
|
984
|
+
infoSection.appendChild(createRow('Name', node.name || node.id));
|
|
985
|
+
infoSection.appendChild(createRow('Type', node.type));
|
|
986
|
+
|
|
987
|
+
// State badge
|
|
988
|
+
const stateRow = document.createElement('div');
|
|
989
|
+
stateRow.className = 'wv-inspector-row';
|
|
990
|
+
const stateLabel = document.createElement('span');
|
|
991
|
+
stateLabel.className = 'wv-inspector-label';
|
|
992
|
+
stateLabel.textContent = 'State';
|
|
993
|
+
const stateBadge = document.createElement('span');
|
|
994
|
+
stateBadge.className = 'wv-badge wv-badge--' + node.state;
|
|
995
|
+
stateBadge.textContent = node.state;
|
|
996
|
+
stateRow.appendChild(stateLabel);
|
|
997
|
+
stateRow.appendChild(stateBadge);
|
|
998
|
+
infoSection.appendChild(stateRow);
|
|
999
|
+
|
|
1000
|
+
if (node.key) {
|
|
1001
|
+
infoSection.appendChild(createRow('Key', node.key));
|
|
1002
|
+
}
|
|
1003
|
+
container.appendChild(infoSection);
|
|
1004
|
+
|
|
1005
|
+
// Timing section
|
|
1006
|
+
if (node.durationMs !== undefined) {
|
|
1007
|
+
const timingSection = createSection('Timing');
|
|
1008
|
+
timingSection.appendChild(createRow('Duration', formatDuration(node.durationMs)));
|
|
1009
|
+
if (node.startTs !== undefined) {
|
|
1010
|
+
timingSection.appendChild(createRow('Started', new Date(node.startTs).toLocaleTimeString()));
|
|
1011
|
+
}
|
|
1012
|
+
container.appendChild(timingSection);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Retries section
|
|
1016
|
+
if (node.retryCount !== undefined && node.retryCount > 0) {
|
|
1017
|
+
const retrySection = createSection('Retries');
|
|
1018
|
+
retrySection.appendChild(createRow('Retry Count', String(node.retryCount)));
|
|
1019
|
+
container.appendChild(retrySection);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
// Input/Output section
|
|
1023
|
+
if (node.input !== undefined || node.output !== undefined) {
|
|
1024
|
+
const ioSection = createSection('Input / Output');
|
|
1025
|
+
if (node.input !== undefined) {
|
|
1026
|
+
const inputPre = document.createElement('pre');
|
|
1027
|
+
inputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
|
|
1028
|
+
inputPre.textContent = typeof node.input === 'string' ? node.input : safeStringify(node.input);
|
|
1029
|
+
ioSection.appendChild(createRow('Input', ''));
|
|
1030
|
+
ioSection.appendChild(inputPre);
|
|
1031
|
+
}
|
|
1032
|
+
if (node.output !== undefined) {
|
|
1033
|
+
const outputPre = document.createElement('pre');
|
|
1034
|
+
outputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
|
|
1035
|
+
outputPre.textContent = typeof node.output === 'string' ? node.output : safeStringify(node.output);
|
|
1036
|
+
ioSection.appendChild(createRow('Output', ''));
|
|
1037
|
+
ioSection.appendChild(outputPre);
|
|
1038
|
+
}
|
|
1039
|
+
container.appendChild(ioSection);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// Hook timing (onAfterStep)
|
|
1043
|
+
const hookKey = node.key || node.id;
|
|
1044
|
+
const hookExec = window.__WORKFLOW_DATA__?.hooks?.onAfterStep?.[hookKey];
|
|
1045
|
+
if (hookExec && (hookExec.durationMs !== undefined || hookExec.ts !== undefined)) {
|
|
1046
|
+
const hookSection = createSection('Hook (onAfterStep)');
|
|
1047
|
+
if (hookExec.durationMs !== undefined) {
|
|
1048
|
+
hookSection.appendChild(createRow('Duration', formatDuration(hookExec.durationMs)));
|
|
1049
|
+
}
|
|
1050
|
+
if (hookExec.ts !== undefined) {
|
|
1051
|
+
hookSection.appendChild(createRow('At', new Date(hookExec.ts).toLocaleTimeString()));
|
|
1052
|
+
}
|
|
1053
|
+
container.appendChild(hookSection);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// Error section (preserve falsy errors: 0, "", false)
|
|
1057
|
+
if (node.error !== undefined && node.error !== null) {
|
|
1058
|
+
const errorSection = createSection('Error');
|
|
1059
|
+
const pre = document.createElement('pre');
|
|
1060
|
+
pre.style.cssText = 'font-size:11px;overflow:auto;max-height:150px;background:var(--bg);padding:8px;border-radius:4px;';
|
|
1061
|
+
pre.textContent = String(node.error);
|
|
1062
|
+
errorSection.appendChild(pre);
|
|
1063
|
+
container.appendChild(errorSection);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function createSection(title) {
|
|
1068
|
+
const section = document.createElement('div');
|
|
1069
|
+
section.className = 'wv-inspector-section';
|
|
1070
|
+
const h3 = document.createElement('h3');
|
|
1071
|
+
h3.textContent = title;
|
|
1072
|
+
section.appendChild(h3);
|
|
1073
|
+
return section;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
function createRow(label, value) {
|
|
1077
|
+
const row = document.createElement('div');
|
|
1078
|
+
row.className = 'wv-inspector-row';
|
|
1079
|
+
const labelSpan = document.createElement('span');
|
|
1080
|
+
labelSpan.className = 'wv-inspector-label';
|
|
1081
|
+
labelSpan.textContent = label;
|
|
1082
|
+
const valueSpan = document.createElement('span');
|
|
1083
|
+
valueSpan.className = 'wv-inspector-value';
|
|
1084
|
+
valueSpan.textContent = value;
|
|
1085
|
+
row.appendChild(labelSpan);
|
|
1086
|
+
row.appendChild(valueSpan);
|
|
1087
|
+
return row;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
function clearInspector() {
|
|
1091
|
+
const content = document.getElementById('inspector-content');
|
|
1092
|
+
if (content) {
|
|
1093
|
+
while (content.firstChild) content.removeChild(content.firstChild);
|
|
1094
|
+
const p = document.createElement('p');
|
|
1095
|
+
p.className = 'wv-empty';
|
|
1096
|
+
p.textContent = 'Select a node to inspect';
|
|
1097
|
+
content.appendChild(p);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// Time Travel
|
|
1102
|
+
function setupTimeTravel() {
|
|
1103
|
+
const playBtn = document.getElementById('tt-play');
|
|
1104
|
+
const pauseBtn = document.getElementById('tt-pause');
|
|
1105
|
+
const prevBtn = document.getElementById('tt-prev');
|
|
1106
|
+
const nextBtn = document.getElementById('tt-next');
|
|
1107
|
+
const speedSelect = document.getElementById('tt-speed');
|
|
1108
|
+
const slider = document.getElementById('tt-slider');
|
|
1109
|
+
|
|
1110
|
+
playBtn?.addEventListener('click', play);
|
|
1111
|
+
pauseBtn?.addEventListener('click', pause);
|
|
1112
|
+
prevBtn?.addEventListener('click', stepBackward);
|
|
1113
|
+
nextBtn?.addEventListener('click', stepForward);
|
|
1114
|
+
speedSelect?.addEventListener('change', (e) => {
|
|
1115
|
+
playbackSpeed = parseFloat(e.target.value);
|
|
1116
|
+
});
|
|
1117
|
+
slider?.addEventListener('input', (e) => {
|
|
1118
|
+
seek(parseInt(e.target.value, 10));
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
function play() {
|
|
1123
|
+
if (snapshots.length === 0) {
|
|
1124
|
+
console.warn('[Visualizer] No snapshots available for time travel. Time travel requires a live WebSocket connection.');
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
isPlaying = true;
|
|
1128
|
+
updatePlaybackUI();
|
|
1129
|
+
playNext();
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
function pause() {
|
|
1133
|
+
isPlaying = false;
|
|
1134
|
+
updatePlaybackUI();
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
function playNext() {
|
|
1138
|
+
if (!isPlaying) return;
|
|
1139
|
+
if (currentSnapshotIndex < snapshots.length - 1) {
|
|
1140
|
+
const current = snapshots[currentSnapshotIndex];
|
|
1141
|
+
const next = snapshots[currentSnapshotIndex + 1];
|
|
1142
|
+
const delay = (next.timestamp - current.timestamp) / playbackSpeed;
|
|
1143
|
+
|
|
1144
|
+
setTimeout(() => {
|
|
1145
|
+
stepForward();
|
|
1146
|
+
playNext();
|
|
1147
|
+
}, Math.max(16, delay));
|
|
1148
|
+
} else {
|
|
1149
|
+
pause();
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
function stepForward() {
|
|
1154
|
+
if (snapshots.length === 0) {
|
|
1155
|
+
console.warn('[Visualizer] No snapshots available for time travel.');
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
if (currentSnapshotIndex < snapshots.length - 1) {
|
|
1159
|
+
seek(currentSnapshotIndex + 1);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
function stepBackward() {
|
|
1164
|
+
if (snapshots.length === 0) {
|
|
1165
|
+
console.warn('[Visualizer] No snapshots available for time travel.');
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
if (currentSnapshotIndex > 0) {
|
|
1169
|
+
seek(currentSnapshotIndex - 1);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
function seek(index) {
|
|
1174
|
+
if (index < 0 || index >= snapshots.length) return;
|
|
1175
|
+
currentSnapshotIndex = index;
|
|
1176
|
+
updateTimelineUI();
|
|
1177
|
+
|
|
1178
|
+
// Request IR update from server or use cached
|
|
1179
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
1180
|
+
ws.send(JSON.stringify({ type: 'time_travel_seek', payload: { index } }));
|
|
1181
|
+
} else if (snapshots[index]?.ir) {
|
|
1182
|
+
renderIR(snapshots[index].ir);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
function updatePlaybackUI() {
|
|
1187
|
+
const playBtn = document.getElementById('tt-play');
|
|
1188
|
+
const pauseBtn = document.getElementById('tt-pause');
|
|
1189
|
+
|
|
1190
|
+
if (playBtn) playBtn.style.display = isPlaying ? 'none' : 'inline-flex';
|
|
1191
|
+
if (pauseBtn) pauseBtn.style.display = isPlaying ? 'inline-flex' : 'none';
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
function updateTimelineUI() {
|
|
1195
|
+
const slider = document.getElementById('tt-slider');
|
|
1196
|
+
const timeDisplay = document.getElementById('tt-time');
|
|
1197
|
+
|
|
1198
|
+
if (slider) {
|
|
1199
|
+
slider.max = String(Math.max(0, snapshots.length - 1));
|
|
1200
|
+
slider.value = String(Math.max(0, currentSnapshotIndex));
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if (timeDisplay) {
|
|
1204
|
+
timeDisplay.textContent = (currentSnapshotIndex + 1) + ' / ' + snapshots.length;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// WebSocket
|
|
1209
|
+
function setupWebSocket(url) {
|
|
1210
|
+
ws = new WebSocket(url);
|
|
1211
|
+
|
|
1212
|
+
ws.onopen = () => {
|
|
1213
|
+
console.log('[Visualizer] Connected to server');
|
|
1214
|
+
showLiveIndicator(true);
|
|
1215
|
+
${e.timeTravel?"if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'request_snapshots' }));":""}
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
ws.onclose = () => {
|
|
1219
|
+
console.log('[Visualizer] Disconnected from server');
|
|
1220
|
+
showLiveIndicator(false);
|
|
1221
|
+
// Attempt reconnect after 2 seconds
|
|
1222
|
+
setTimeout(() => setupWebSocket(url), 2000);
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
ws.onmessage = (event) => {
|
|
1226
|
+
try {
|
|
1227
|
+
const msg = JSON.parse(event.data);
|
|
1228
|
+
handleServerMessage(msg);
|
|
1229
|
+
} catch (e) {
|
|
1230
|
+
console.error('[Visualizer] Failed to parse message:', e);
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
ws.onerror = (error) => {
|
|
1235
|
+
console.error('[Visualizer] WebSocket error:', error);
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function handleServerMessage(msg) {
|
|
1240
|
+
switch (msg.type) {
|
|
1241
|
+
case 'ir_update':
|
|
1242
|
+
renderIR(msg.payload);
|
|
1243
|
+
break;
|
|
1244
|
+
case 'snapshot':
|
|
1245
|
+
snapshots.push(msg.payload);
|
|
1246
|
+
currentSnapshotIndex = snapshots.length - 1;
|
|
1247
|
+
updateTimelineUI();
|
|
1248
|
+
break;
|
|
1249
|
+
case 'snapshots_list':
|
|
1250
|
+
snapshots = msg.payload;
|
|
1251
|
+
currentSnapshotIndex = snapshots.length - 1;
|
|
1252
|
+
updateTimelineUI();
|
|
1253
|
+
break;
|
|
1254
|
+
case 'performance_data':
|
|
1255
|
+
window.__PERFORMANCE_DATA__ = msg.payload;
|
|
1256
|
+
if (heatmapEnabled) applyHeatmap();
|
|
1257
|
+
break;
|
|
1258
|
+
case 'workflow_complete':
|
|
1259
|
+
showLiveIndicator(false);
|
|
1260
|
+
break;
|
|
1261
|
+
case 'time_travel_state':
|
|
1262
|
+
currentSnapshotIndex = msg.payload.currentIndex;
|
|
1263
|
+
isPlaying = msg.payload.isPlaying;
|
|
1264
|
+
playbackSpeed = msg.payload.playbackSpeed;
|
|
1265
|
+
updateTimelineUI();
|
|
1266
|
+
updatePlaybackUI();
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
function showLiveIndicator(show) {
|
|
1272
|
+
const indicator = document.getElementById('live-indicator');
|
|
1273
|
+
if (indicator) {
|
|
1274
|
+
indicator.style.display = show ? 'flex' : 'none';
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// Heatmap
|
|
1279
|
+
function setupHeatmap() {
|
|
1280
|
+
const toggle = document.getElementById('heatmap-toggle');
|
|
1281
|
+
const metricSelect = document.getElementById('heatmap-metric');
|
|
1282
|
+
|
|
1283
|
+
// For static HTML (no WebSocket), disable heatmap controls
|
|
1284
|
+
if (!ws) {
|
|
1285
|
+
if (toggle) {
|
|
1286
|
+
toggle.disabled = true;
|
|
1287
|
+
toggle.title = 'Heatmap requires a live WebSocket connection with performance data';
|
|
1288
|
+
}
|
|
1289
|
+
if (metricSelect) {
|
|
1290
|
+
metricSelect.disabled = true;
|
|
1291
|
+
metricSelect.title = 'Heatmap requires a live WebSocket connection with performance data';
|
|
1292
|
+
}
|
|
1293
|
+
return;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
toggle?.addEventListener('click', () => {
|
|
1297
|
+
heatmapEnabled = !heatmapEnabled;
|
|
1298
|
+
toggle.classList.toggle('wv-btn--primary', heatmapEnabled);
|
|
1299
|
+
if (ws && ws.readyState === 1) {
|
|
1300
|
+
ws.send(JSON.stringify({ type: 'toggle_heatmap', payload: { enabled: heatmapEnabled } }));
|
|
1301
|
+
}
|
|
1302
|
+
if (heatmapEnabled) {
|
|
1303
|
+
applyHeatmap();
|
|
1304
|
+
} else {
|
|
1305
|
+
removeHeatmap();
|
|
1306
|
+
}
|
|
1307
|
+
});
|
|
1308
|
+
|
|
1309
|
+
metricSelect?.addEventListener('change', (e) => {
|
|
1310
|
+
heatmapMetric = e.target.value;
|
|
1311
|
+
if (ws && ws.readyState === 1) {
|
|
1312
|
+
ws.send(JSON.stringify({ type: 'set_heatmap_metric', payload: { metric: heatmapMetric } }));
|
|
1313
|
+
}
|
|
1314
|
+
if (heatmapEnabled) applyHeatmap();
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
function applyHeatmap() {
|
|
1319
|
+
const perfData = window.__PERFORMANCE_DATA__;
|
|
1320
|
+
if (!perfData) return;
|
|
1321
|
+
|
|
1322
|
+
const heat = perfData.heat;
|
|
1323
|
+
document.querySelectorAll('.wv-node').forEach((node) => {
|
|
1324
|
+
const nodeId = node.dataset.nodeId;
|
|
1325
|
+
const value = heat && (typeof heat.get === 'function' ? heat.get(nodeId) : heat[nodeId]);
|
|
1326
|
+
|
|
1327
|
+
// Remove existing heat classes
|
|
1328
|
+
node.classList.remove(
|
|
1329
|
+
'wv-node--heat-cold',
|
|
1330
|
+
'wv-node--heat-cool',
|
|
1331
|
+
'wv-node--heat-neutral',
|
|
1332
|
+
'wv-node--heat-warm',
|
|
1333
|
+
'wv-node--heat-hot',
|
|
1334
|
+
'wv-node--heat-critical'
|
|
1335
|
+
);
|
|
1336
|
+
|
|
1337
|
+
if (value !== undefined) {
|
|
1338
|
+
const level = getHeatLevel(value);
|
|
1339
|
+
node.classList.add('wv-node--heat-' + level);
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
function removeHeatmap() {
|
|
1345
|
+
document.querySelectorAll('.wv-node').forEach((node) => {
|
|
1346
|
+
node.classList.remove(
|
|
1347
|
+
'wv-node--heat-cold',
|
|
1348
|
+
'wv-node--heat-cool',
|
|
1349
|
+
'wv-node--heat-neutral',
|
|
1350
|
+
'wv-node--heat-warm',
|
|
1351
|
+
'wv-node--heat-hot',
|
|
1352
|
+
'wv-node--heat-critical'
|
|
1353
|
+
);
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
function getHeatLevel(heat) {
|
|
1358
|
+
if (heat < 0.2) return 'cold';
|
|
1359
|
+
if (heat < 0.4) return 'cool';
|
|
1360
|
+
if (heat < 0.6) return 'neutral';
|
|
1361
|
+
if (heat < 0.8) return 'warm';
|
|
1362
|
+
if (heat < 0.95) return 'hot';
|
|
1363
|
+
return 'critical';
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
// Keyboard shortcuts
|
|
1367
|
+
function setupKeyboardShortcuts() {
|
|
1368
|
+
document.addEventListener('keydown', (e) => {
|
|
1369
|
+
// Don't trigger shortcuts when typing in inputs
|
|
1370
|
+
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
|
1371
|
+
|
|
1372
|
+
switch (e.key) {
|
|
1373
|
+
case ' ':
|
|
1374
|
+
e.preventDefault();
|
|
1375
|
+
isPlaying ? pause() : play();
|
|
1376
|
+
break;
|
|
1377
|
+
case 'ArrowLeft':
|
|
1378
|
+
e.preventDefault();
|
|
1379
|
+
stepBackward();
|
|
1380
|
+
break;
|
|
1381
|
+
case 'ArrowRight':
|
|
1382
|
+
e.preventDefault();
|
|
1383
|
+
stepForward();
|
|
1384
|
+
break;
|
|
1385
|
+
case '0':
|
|
1386
|
+
resetZoom();
|
|
1387
|
+
break;
|
|
1388
|
+
case '+':
|
|
1389
|
+
case '=':
|
|
1390
|
+
zoom(1.2);
|
|
1391
|
+
break;
|
|
1392
|
+
case '-':
|
|
1393
|
+
zoom(0.8);
|
|
1394
|
+
break;
|
|
1395
|
+
case 'h':
|
|
1396
|
+
${e.heatmap?"document.getElementById('heatmap-toggle')?.click();":""}
|
|
1397
|
+
break;
|
|
1398
|
+
case 'Escape':
|
|
1399
|
+
selectNode(null);
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// Render functions
|
|
1406
|
+
function renderIR(ir) {
|
|
1407
|
+
window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(ir);
|
|
1408
|
+
|
|
1409
|
+
// Update SVG node states
|
|
1410
|
+
document.querySelectorAll('.wv-node').forEach((node) => {
|
|
1411
|
+
const nodeId = node.dataset.nodeId;
|
|
1412
|
+
const nodeData = window.__WORKFLOW_DATA__.nodes[nodeId];
|
|
1413
|
+
if (nodeData) {
|
|
1414
|
+
// Update only state class so heatmap (wv-node--heat-*) and other classes are preserved
|
|
1415
|
+
node.className = node.className.replace(/wv-node--(success|error|running|cached|skipped|pending|aborted)/g, '').replace(/\\s+/g, ' ').trim();
|
|
1416
|
+
node.classList.add('wv-node', 'wv-node--' + nodeData.state);
|
|
1417
|
+
|
|
1418
|
+
// Update timing text if present
|
|
1419
|
+
const timing = node.querySelector('.wv-node-timing');
|
|
1420
|
+
if (timing && nodeData.durationMs !== undefined) {
|
|
1421
|
+
timing.textContent = formatDuration(nodeData.durationMs);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
|
|
1426
|
+
// Re-apply selection so wv-node--selected is not lost after class updates
|
|
1427
|
+
if (selectedNodeId) {
|
|
1428
|
+
selectNode(selectedNodeId);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
function flattenNodes(nodes) {
|
|
1433
|
+
const result = [];
|
|
1434
|
+
for (const node of nodes) {
|
|
1435
|
+
result.push(node);
|
|
1436
|
+
if (node.children) {
|
|
1437
|
+
result.push(...flattenNodes(node.children));
|
|
1438
|
+
}
|
|
1439
|
+
if (node.branches) {
|
|
1440
|
+
for (const branch of node.branches) {
|
|
1441
|
+
result.push(...flattenNodes(branch.children));
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
return result;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
// Utilities
|
|
1449
|
+
function safeStringify(val) {
|
|
1450
|
+
const seen = new WeakSet();
|
|
1451
|
+
try {
|
|
1452
|
+
return JSON.stringify(val, function(key, value) {
|
|
1453
|
+
if (typeof value === 'bigint') return value.toString();
|
|
1454
|
+
if (typeof value === 'object' && value !== null) {
|
|
1455
|
+
if (seen.has(value)) return '[Circular]';
|
|
1456
|
+
seen.add(value);
|
|
1457
|
+
}
|
|
1458
|
+
return value;
|
|
1459
|
+
}, 2);
|
|
1460
|
+
} catch (e) {
|
|
1461
|
+
return String(val);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
function formatDuration(ms) {
|
|
1466
|
+
if (ms < 1000) return Math.round(ms) + 'ms';
|
|
1467
|
+
if (ms < 60000) {
|
|
1468
|
+
const s = (ms / 1000).toFixed(1).replace(/\\.0$/, '');
|
|
1469
|
+
return s + 's';
|
|
1470
|
+
}
|
|
1471
|
+
let min = Math.floor(ms / 60000);
|
|
1472
|
+
let sec = Math.round((ms % 60000) / 1000);
|
|
1473
|
+
if (sec >= 60) { min += 1; sec = 0; }
|
|
1474
|
+
if (sec === 0) return min + 'm';
|
|
1475
|
+
return min + 'm ' + sec + 's';
|
|
1476
|
+
}
|
|
1477
|
+
})();
|
|
1478
|
+
`}var le=160,ye=50,et=40,ln=30,z=20;function un(e,t="TB",r){let o=t==="TB"||t==="BT",i=t==="RL"||t==="BT",n=[],s=z,a=z,u=0,c=0;for(let h of e){let f=tt(h,s,a,o,r);n.push(f.node),o?(a+=f.height+ln,u=Math.max(u,f.width),c=a):(s+=f.width+et,c=Math.max(c,f.height),u=s)}let l=u+z,p=c+z;if(i)for(let h of n)_t(h,l,p,o);return{nodes:n,width:l,height:p}}function _t(e,t,r,o){if(o?e.y=r-e.y-e.height:e.x=t-e.x-e.width,e.children)for(let i of e.children)_t(i,t,r,o)}function tt(e,t,r,o,i){if(K(e)){let n=e.name??e.key??"step",s=i?.showKeys&&e.key&&e.name?`${n} [key: ${e.key}]`:n;return{node:{id:e.id,name:s,type:"step",state:e.state,x:t,y:r,width:le,height:ye,durationMs:e.durationMs},width:le,height:ye}}if(te(e)){let n=e.streamState==="active"?`stream:${e.namespace} \u27F3`:e.streamState==="error"?`stream:${e.namespace} \u2717`:`stream:${e.namespace} \u2713`;return{node:{id:e.id,name:n,type:"stream",state:e.state,x:t,y:r,width:le,height:ye,durationMs:e.durationMs},width:le,height:ye}}if(V(e)||H(e)){let n=V(e)?"parallel":"race",s=e.name??n,a=[],u=t+z,c=r+z+20,l=0,p=0;for(let b of e.children){let k=tt(b,u,c,!0,i);a.push(k.node),u+=k.width+et,p=Math.max(p,k.height)}l=u-t-z;let h=Math.max(l+z,le+z*2),f=p+z*2+20;return{node:{id:e.id,name:s,type:n,state:e.state,x:t,y:r,width:h,height:f,durationMs:e.durationMs,children:a,containerType:n,containerLabel:n==="parallel"?"PARALLEL":"RACE"},width:h,height:f}}if(Y(e)){let n=e.name??"decision",s=[],a=t+z,u=r+z+20,c=0;for(let h of e.branches)for(let f of h.children){let b=tt(f,a,u,!0,i);s.push(b.node),a+=b.width+et,c=Math.max(c,b.height)}let l=Math.max(a-t,le+z*2),p=c+z*2+20;return{node:{id:e.id,name:n,type:"decision",state:e.state,x:t,y:r,width:l,height:p,durationMs:e.durationMs,children:s,containerType:"decision",containerLabel:"DECISION"},width:l,height:p}}return{node:{id:e.id,name:e.name??"unknown",type:e.type,state:e.state,x:t,y:r,width:le,height:ye},width:le,height:ye}}function Wt(e,t){return e.containerType?fn(e,t):pn(e,t)}function pn(e,t){let o=t&&e.durationMs!==void 0?A(e.durationMs):"";return`
|
|
1479
|
+
<g class="wv-node wv-node--${e.state}" data-node-id="${Pt(e.id)}" transform="translate(${e.x}, ${e.y})">
|
|
1480
|
+
<rect width="${e.width}" height="${e.height}" rx="8" ry="8" />
|
|
1481
|
+
<text x="${e.width/2}" y="${e.height/2-(o?4:0)}">${nt(hn(e.name,e.name.includes("[key:")?40:20))}</text>
|
|
1482
|
+
${o?`<text class="wv-node-timing" x="${e.width/2}" y="${e.height/2+12}">${o}</text>`:""}
|
|
1483
|
+
</g>
|
|
1484
|
+
`}function fn(e,t){let o=e.children?.map(i=>Wt(i,t)).join(`
|
|
1485
|
+
`)??"";return`
|
|
1486
|
+
<g class="wv-container wv-container--${e.containerType}" data-node-id="${Pt(e.id)}" transform="translate(${e.x}, ${e.y})">
|
|
1487
|
+
<rect width="${e.width}" height="${e.height}" rx="12" ry="12" />
|
|
1488
|
+
<text class="wv-container-label" x="${z}" y="16">${e.containerLabel}</text>
|
|
1489
|
+
<g transform="translate(${-e.x}, ${-e.y})">
|
|
1490
|
+
${o}
|
|
1491
|
+
</g>
|
|
1492
|
+
</g>
|
|
1493
|
+
`}function rt(e,t){for(let r of e){if(r.id===t)return r;if("children"in r&&r.children){let o=rt(r.children,t);if(o)return o}if("branches"in r&&r.branches)for(let o of r.branches){let i=rt(o.children,t);if(i)return i}}}function mn(e,t){let r=[];function o(n,s){if(Math.abs(n.y-s.y)<n.height){let u=n.x+n.width,c=n.y+n.height/2,l=s.x,p=s.y+s.height/2;r.push(`
|
|
1494
|
+
<path class="wv-edge" d="M ${u} ${c} L ${l-8} ${p}" />
|
|
1495
|
+
<polygon class="wv-edge-arrow" points="${l-8},${p-4} ${l-8},${p+4} ${l},${p}" />
|
|
1496
|
+
`)}else{let u=n.x+n.width/2,c=n.y+n.height,l=s.x+s.width/2,p=s.y;r.push(`
|
|
1497
|
+
<path class="wv-edge" d="M ${u} ${c} L ${l} ${p-8}" />
|
|
1498
|
+
<polygon class="wv-edge-arrow" points="${l-4},${p-8} ${l+4},${p-8} ${l},${p}" />
|
|
1499
|
+
`)}}function i(n){for(let s=0;s<n.length-1;s++)o(n[s],n[s+1]);for(let s of n)if(s.children&&s.children.length>0)if(s.containerType==="decision"){let a=rt(t.root.children,s.id);if(a&&a.type==="decision"&&a.branches){let u=0;for(let c of a.branches){let l=c.children.length;l>0&&o(s,s.children[u]);for(let p=0;p<l-1;p++)o(s.children[u+p],s.children[u+p+1]);u+=l}}}else if(s.containerType==="parallel"||s.containerType==="race")for(let a of s.children)a.children&&a.children.length>0&&i([a]);else i(s.children)}return i(e),r.join(`
|
|
1500
|
+
`)}function Bt(e,t){let r=un(e.root.children,t.layout,t),o=Math.max(r.width,400),i=Math.max(r.height,300),n=r.nodes.map(l=>Wt(l,t.showTimings)).join(`
|
|
1501
|
+
`),s=mn(r.nodes,e),a=e.root.name??"Workflow",u=Dt(t.theme),c=Ct({wsUrl:t.wsUrl,interactive:t.interactive,timeTravel:t.timeTravel,heatmap:t.heatmap});return`<!DOCTYPE html>
|
|
1502
|
+
<html lang="en">
|
|
1503
|
+
<head>
|
|
1504
|
+
<meta charset="UTF-8">
|
|
1505
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1506
|
+
<title>${nt(a)} - Workflow Visualizer</title>
|
|
1507
|
+
<style>${u}</style>
|
|
1508
|
+
</head>
|
|
1509
|
+
<body>
|
|
1510
|
+
<div class="workflow-visualizer">
|
|
1511
|
+
<header class="wv-header">
|
|
1512
|
+
<h1>${nt(a)}</h1>
|
|
1513
|
+
<div class="wv-controls">
|
|
1514
|
+
${t.interactive?`
|
|
1515
|
+
<button id="load-json-btn" class="wv-btn" title="Load workflow state from JSON">Load JSON</button>
|
|
1516
|
+
`:""}
|
|
1517
|
+
${t.wsUrl?'<div id="live-indicator" class="wv-live" style="display:none"><span class="wv-live-dot"></span>LIVE</div>':""}
|
|
1518
|
+
${t.heatmap&&t.wsUrl?`
|
|
1519
|
+
<button id="heatmap-toggle" class="wv-btn">Heatmap</button>
|
|
1520
|
+
<select id="heatmap-metric" class="wv-btn">
|
|
1521
|
+
<option value="duration">Duration</option>
|
|
1522
|
+
<option value="retryRate">Retry Rate</option>
|
|
1523
|
+
<option value="errorRate">Error Rate</option>
|
|
1524
|
+
</select>
|
|
1525
|
+
`:""}
|
|
1526
|
+
${t.interactive?`
|
|
1527
|
+
<button id="zoom-out" class="wv-btn wv-btn--icon" title="Zoom out (-)">\u2212</button>
|
|
1528
|
+
<button id="zoom-reset" class="wv-btn wv-btn--icon" title="Reset zoom (0)">\u27F2</button>
|
|
1529
|
+
<button id="zoom-in" class="wv-btn wv-btn--icon" title="Zoom in (+)">+</button>
|
|
1530
|
+
`:""}
|
|
1531
|
+
</div>
|
|
1532
|
+
</header>
|
|
1533
|
+
|
|
1534
|
+
<div class="wv-main">
|
|
1535
|
+
<div id="diagram" class="wv-diagram">
|
|
1536
|
+
<svg viewBox="0 0 ${o} ${i}" preserveAspectRatio="xMidYMid meet">
|
|
1537
|
+
<g class="wv-root">
|
|
1538
|
+
${s}
|
|
1539
|
+
${n}
|
|
1540
|
+
</g>
|
|
1541
|
+
</svg>
|
|
1542
|
+
</div>
|
|
1543
|
+
|
|
1544
|
+
${t.interactive?`
|
|
1545
|
+
<aside id="inspector" class="wv-inspector">
|
|
1546
|
+
<div class="wv-inspector-header">
|
|
1547
|
+
<h2>Inspector</h2>
|
|
1548
|
+
</div>
|
|
1549
|
+
<div id="inspector-content" class="wv-inspector-content">
|
|
1550
|
+
<p class="wv-empty">Select a node to inspect</p>
|
|
1551
|
+
</div>
|
|
1552
|
+
</aside>
|
|
1553
|
+
`:""}
|
|
1554
|
+
</div>
|
|
1555
|
+
|
|
1556
|
+
${t.timeTravel?`
|
|
1557
|
+
<div id="timeline" class="wv-timeline">
|
|
1558
|
+
<div class="wv-timeline-track">
|
|
1559
|
+
<input type="range" id="tt-slider" min="0" max="0" value="0" style="width:100%">
|
|
1560
|
+
</div>
|
|
1561
|
+
<div class="wv-timeline-controls">
|
|
1562
|
+
<button id="tt-prev" class="wv-btn wv-btn--icon" title="Step backward (\u2190)">\u23EE</button>
|
|
1563
|
+
<button id="tt-play" class="wv-btn wv-btn--icon" title="Play (Space)">\u25B6</button>
|
|
1564
|
+
<button id="tt-pause" class="wv-btn wv-btn--icon" style="display:none" title="Pause (Space)">\u23F8</button>
|
|
1565
|
+
<button id="tt-next" class="wv-btn wv-btn--icon" title="Step forward (\u2192)">\u23ED</button>
|
|
1566
|
+
<select id="tt-speed" class="wv-btn">
|
|
1567
|
+
<option value="0.5">0.5x</option>
|
|
1568
|
+
<option value="1" selected>1x</option>
|
|
1569
|
+
<option value="2">2x</option>
|
|
1570
|
+
<option value="4">4x</option>
|
|
1571
|
+
<option value="10">10x</option>
|
|
1572
|
+
</select>
|
|
1573
|
+
<span id="tt-time" class="wv-timeline-time">0 / 0</span>
|
|
1574
|
+
</div>
|
|
1575
|
+
</div>
|
|
1576
|
+
`:""}
|
|
1577
|
+
</div>
|
|
1578
|
+
|
|
1579
|
+
${t.interactive?`
|
|
1580
|
+
<div id="load-json-modal" class="wv-modal" style="display:none">
|
|
1581
|
+
<div class="wv-modal-content">
|
|
1582
|
+
<div class="wv-modal-header">
|
|
1583
|
+
<h2>Load Workflow State</h2>
|
|
1584
|
+
<button id="load-json-close" class="wv-btn wv-btn--icon" title="Close">\xD7</button>
|
|
1585
|
+
</div>
|
|
1586
|
+
<div class="wv-modal-body">
|
|
1587
|
+
<p>Paste the workflow IR JSON (from <code>viz.getIR()</code> or <code>viz.renderAs('json')</code>):</p>
|
|
1588
|
+
<textarea id="load-json-input" class="wv-textarea" rows="15" placeholder='{"root":{"type":"workflow","id":"...","children":[...]}}'></textarea>
|
|
1589
|
+
<div id="load-json-error" class="wv-error" style="display:none"></div>
|
|
1590
|
+
</div>
|
|
1591
|
+
<div class="wv-modal-footer">
|
|
1592
|
+
<button id="load-json-submit" class="wv-btn wv-btn--primary">Load</button>
|
|
1593
|
+
<button id="load-json-cancel" class="wv-btn">Cancel</button>
|
|
1594
|
+
</div>
|
|
1595
|
+
</div>
|
|
1596
|
+
</div>
|
|
1597
|
+
`:""}
|
|
1598
|
+
|
|
1599
|
+
<script>
|
|
1600
|
+
// Check if we have a saved IR in sessionStorage (from Load JSON)
|
|
1601
|
+
(function() {
|
|
1602
|
+
let initialIR = ${Lt(gn(e))};
|
|
1603
|
+
try {
|
|
1604
|
+
const savedIR = sessionStorage.getItem('workflow_ir');
|
|
1605
|
+
if (savedIR) {
|
|
1606
|
+
initialIR = JSON.parse(savedIR);
|
|
1607
|
+
sessionStorage.removeItem('workflow_ir'); // Clear after use
|
|
1608
|
+
}
|
|
1609
|
+
} catch (e) {
|
|
1610
|
+
console.warn('Failed to load saved IR:', e);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
const irObj = typeof initialIR === 'string' ? JSON.parse(initialIR) : initialIR;
|
|
1614
|
+
window.__WORKFLOW_IR__ = irObj;
|
|
1615
|
+
|
|
1616
|
+
// Build workflow data from IR (nodes include input/output; hooks serialized for inspector)
|
|
1617
|
+
function buildWorkflowDataFromIR(ir) {
|
|
1618
|
+
const nodes = {};
|
|
1619
|
+
function collectNodes(flowNodes) {
|
|
1620
|
+
for (const node of flowNodes || []) {
|
|
1621
|
+
nodes[node.id] = {
|
|
1622
|
+
id: node.id,
|
|
1623
|
+
name: node.name,
|
|
1624
|
+
type: node.type,
|
|
1625
|
+
state: node.state,
|
|
1626
|
+
key: node.key,
|
|
1627
|
+
durationMs: node.durationMs,
|
|
1628
|
+
startTs: node.startTs,
|
|
1629
|
+
error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
|
|
1630
|
+
retryCount: node.retryCount,
|
|
1631
|
+
input: node.input,
|
|
1632
|
+
output: node.output,
|
|
1633
|
+
...(node.type === "stream" && {
|
|
1634
|
+
namespace: node.namespace,
|
|
1635
|
+
writeCount: node.writeCount,
|
|
1636
|
+
readCount: node.readCount,
|
|
1637
|
+
finalPosition: node.finalPosition,
|
|
1638
|
+
streamState: node.streamState,
|
|
1639
|
+
backpressureOccurred: node.backpressureOccurred,
|
|
1640
|
+
}),
|
|
1641
|
+
...(node.type === "decision" && {
|
|
1642
|
+
condition: node.condition,
|
|
1643
|
+
decisionValue: node.decisionValue,
|
|
1644
|
+
branchTaken: node.branchTaken,
|
|
1645
|
+
branches: node.branches,
|
|
1646
|
+
}),
|
|
1647
|
+
};
|
|
1648
|
+
if (node.children) collectNodes(node.children);
|
|
1649
|
+
if (node.branches) {
|
|
1650
|
+
for (const branch of node.branches) {
|
|
1651
|
+
collectNodes(branch.children);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
collectNodes(ir.root.children);
|
|
1657
|
+
const hooks = ir.hooks
|
|
1658
|
+
? {
|
|
1659
|
+
...ir.hooks,
|
|
1660
|
+
onAfterStep:
|
|
1661
|
+
ir.hooks.onAfterStep instanceof Map
|
|
1662
|
+
? Object.fromEntries(ir.hooks.onAfterStep)
|
|
1663
|
+
: ir.hooks.onAfterStep,
|
|
1664
|
+
}
|
|
1665
|
+
: undefined;
|
|
1666
|
+
return { nodes, hooks };
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(irObj);
|
|
1670
|
+
|
|
1671
|
+
${t.heatmapData?`window.__PERFORMANCE_DATA__ = ${Lt({heat:Object.fromEntries(t.heatmapData.heat),metric:t.heatmapData.metric,stats:t.heatmapData.stats})};`:""}
|
|
1672
|
+
})();
|
|
1673
|
+
</script>
|
|
1674
|
+
<script>${c}</script>
|
|
1675
|
+
</body>
|
|
1676
|
+
</html>`}function nt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Pt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function hn(e,t){return e.length<=t?e:e.slice(0,t-1)+"\u2026"}function gn(e){if(!e.hooks)return e;let t=e.hooks.onAfterStep instanceof Map?Object.fromEntries(e.hooks.onAfterStep):e.hooks.onAfterStep;return{...e,hooks:{...e.hooks,onAfterStep:t}}}function Lt(e){let t=new WeakSet;return JSON.stringify(e,(o,i)=>{if(typeof i=="bigint")return i.toString();if(o==="error"&&i!==void 0&&i!==null)return String(i);if(typeof i=="object"&&i!==null){if(t.has(i))return"[Circular]";t.add(i)}return i}).replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}var At={interactive:!0,timeTravel:!0,heatmap:!0,animationDuration:200,theme:"auto",layout:"TB"};function Ut(){return{name:"html",supportsLive:!0,render(e,t){let r={...t,...At,...t};return Bt(e,r)}}}function Ht(e,t={}){let r={showTimings:!0,showKeys:!1,colors:{pending:"#6c757d",running:"#ffc107",success:"#198754",error:"#dc3545",aborted:"#6c757d",cached:"#0dcaf0",skipped:"#adb5bd"},...At,...t};return Bt(e,r)}var ue={clearToEnd:"\x1B[J",cursorUp:e=>`\x1B[${e}A`,cursorToStart:"\x1B[G",hideCursor:"\x1B[?25l",showCursor:"\x1B[?25h",saveCursor:"\x1B[s",restoreCursor:"\x1B[u"};function Ft(e={}){let{workflowName:t,detectParallel:r=!0,showTimings:o=!0,showKeys:i=!1,colors:n,stream:s=process.stdout,updateInterval:a=100}=e,u=ce({detectParallel:r}),c=ie(),l={showTimings:o,showKeys:i,terminalWidth:s.columns??80,colors:{...F,...n}},p=!1,h="",f=0,b=null,k=!1;function E(O){s.writable&&s.write(O)}function D(){if(!p)return;let O=g(),S=c.render(O,l);S!==h&&(f>0&&(E(ue.cursorUp(f)),E(ue.cursorToStart),E(ue.clearToEnd)),E(S),E(`
|
|
1677
|
+
`),h=S,f=S.split(`
|
|
1678
|
+
`).length)}function T(){p&&(k=!0,b===null&&(b=setTimeout(()=>{b=null,k&&(k=!1,D())},a)))}function N(O){if(O.type==="scope_start"||O.type==="scope_end"){v(O);return}u.handleEvent(O),p&&(O.type==="workflow_start"||O.type==="workflow_success"||O.type==="workflow_error"?D():T())}function v(O){u.handleScopeEvent(O),p&&T()}function x(O){u.handleDecisionEvent(O),p&&T()}function g(){let O=u.getIR();return t&&!O.root.name&&(O.root.name=t),O}function y(){return c.render(g(),l)}function $(){p||(p=!0,h="",f=0,E(ue.hideCursor),D())}function C(){if(!p)return;p=!1,b!==null&&(clearTimeout(b),b=null);let O=g(),S=c.render(O,l);f>0&&(E(ue.cursorUp(f)),E(ue.cursorToStart),E(ue.clearToEnd)),E(S),E(`
|
|
1679
|
+
`),E(ue.showCursor)}function M(){b!==null&&(clearTimeout(b),b=null),k=!1,D()}function L(){u.reset(),h="",f=0}return{handleEvent:N,handleScopeEvent:v,handleDecisionEvent:x,getIR:g,render:y,start:$,stop:C,refresh:M,reset:L}}function Fe(e,t={}){let{condition:r,value:o,name:i,workflowId:n=crypto.randomUUID(),emit:s}=t,a=Date.now(),u,c=[];function l(h,f,b){c.push({label:h,condition:b,taken:f}),f&&(u=h),s?.({type:"decision_branch",workflowId:n,decisionId:e,branchLabel:h,condition:b,taken:f,ts:Date.now()})}function p(){let h=Date.now()-a;s?.({type:"decision_end",workflowId:n,decisionId:e,branchTaken:u,ts:Date.now(),durationMs:h})}return s?.({type:"decision_start",workflowId:n,decisionId:e,condition:r,decisionValue:o,name:i,ts:a}),{takeBranch:l,end:p,getBranchTaken:()=>u,getBranches:()=>[...c]}}function zt(e,t,r={}){let o=Fe(e,{...r,condition:r.condition??String(t),value:r.value??t}),i=!1;return{...o,condition:t,then:()=>{i||(i=!0,o.takeBranch("if",!0),o.takeBranch("else",!1))},else:()=>{i||(i=!0,o.takeBranch("if",!1),o.takeBranch("else",!0))}}}function Kt(e,t,r={}){let o=Fe(e,{...r,condition:r.condition??`switch(${String(t)})`,value:t});return{...o,value:t,case:(i,n)=>{o.takeBranch(`case '${i}'`,n,`value === '${i}'`)},default:i=>{o.takeBranch("default",i)}}}function jt(e={}){let{maxSnapshots:t=1e3,autoRecord:r=!0,builderOptions:o={}}=e,i=ce({...o,enableSnapshots:!0,maxSnapshots:t}),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},s=new Set,a=null;function u(){let M=v();for(let L of s)L(M)}function c(){n.snapshots=i.getSnapshots(),n.isRecording&&n.snapshots.length>0&&(n.currentIndex=n.snapshots.length-1)}function l(M){i.handleEvent(M),n.isRecording&&(c(),u())}function p(M){let L=i.getSnapshots();if(!(M<0||M>=L.length))return n.currentIndex=M,n.snapshots=L,u(),L[M].ir}function h(){return p(n.currentIndex+1)}function f(){return p(n.currentIndex-1)}function b(M=1){let L=i.getSnapshots();if(L.length===0)return;n.currentIndex===-1&&(n.currentIndex=0,n.snapshots=L),n.playbackSpeed=M,n.isPlaying=!0,u();let O=()=>{if(!n.isPlaying)return;let S=i.getSnapshots();if(n.currentIndex<S.length-1){let R=S[n.currentIndex],oe=(S[n.currentIndex+1].timestamp-R.timestamp)/n.playbackSpeed;a=setTimeout(()=>{h(),O()},Math.max(16,oe))}else k()};O()}function k(){n.isPlaying=!1,a&&(clearTimeout(a),a=null),u()}function E(){let M=i.getSnapshots();return n.currentIndex>=0&&n.currentIndex<M.length?M[n.currentIndex].ir:i.getIR()}function D(M){return i.getIRAt(M)}function T(){return i.getSnapshots()}function N(M){return i.getSnapshotAt(M)}function v(){return{snapshots:i.getSnapshots(),currentIndex:n.currentIndex,isPlaying:n.isPlaying,playbackSpeed:n.playbackSpeed,isRecording:n.isRecording}}function x(M){return s.add(M),()=>s.delete(M)}function g(){n.isRecording=!0,i.setSnapshotsEnabled(!0),c(),u()}function y(){n.isRecording=!1,i.setSnapshotsEnabled(!1),u()}function $(){k(),i.reset(),i.setSnapshotsEnabled(r),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},u()}function C(){return i}return{handleEvent:l,seek:p,stepForward:h,stepBackward:f,play:b,pause:k,getCurrentIR:E,getIRAt:D,getSnapshots:T,getSnapshotAt:N,getState:v,onStateChange:x,startRecording:g,stopRecording:y,reset:$,getBuilder:C}}function ze(e={}){let{workflowName:t,detectParallel:r=!0,showTimings:o=!0,showKeys:i=!1,colors:n,export:s}=e,a=ce({detectParallel:r}),u=new Set,c=ie(),l=se(),p=Re(),h=fe(),f={showTimings:o,showKeys:i,terminalWidth:process.stdout?.columns??80,colors:{...F,...n}};function b(){if(u.size>0){let S=T();for(let R of u)R(S)}}function k(S){if(S.type==="scope_start"||S.type==="scope_end"){E(S);return}a.handleEvent(S),S.type,b()}function E(S){a.handleScopeEvent(S),b()}function D(S){a.handleDecisionEvent(S),b()}function T(){let S=a.getIR();return t&&!S.root.name&&(S.root.name=t),S}function N(){let S=T();return c.render(S,f)}function v(S){let R=T();switch(S){case"ascii":return c.render(R,f);case"mermaid":return l.render(R,f);case"json":{let J=R.hooks?{...R,hooks:{...R.hooks,onAfterStep:R.hooks.onAfterStep instanceof Map?Object.fromEntries(R.hooks.onAfterStep):R.hooks.onAfterStep??{}}}:R;return JSON.stringify(J,(oe,ke)=>typeof ke=="bigint"?ke.toString():ke,2)}case"logger":return p.render(R,f);case"flowchart":return h.render(R,f);default:throw new Error(`Unknown format: ${S}`)}}function x(){a.reset(),b()}function g(S){return u.add(S),()=>u.delete(S)}function y(S,R){if(S)return S;if(s?.default)return s.default;throw new Error(`${R}(): No export provider configured. Pass { provider: 'kroki' } or { provider: 'mermaid-ink' }, or set export.default in createVisualizer().`)}function $(){let S=T();return{kind:"mermaid",source:l.render(S,f)}}function C(S){let R=be($(),"svg",y(S,"toSvgUrl"),{caller:"toSvgUrl"});if(!R.ok)throw new Error(`toSvgUrl: Export failed - ${R.error}`);return R.value}function M(S){let R=be($(),"png",y(S,"toPngUrl"),{caller:"toPngUrl"});if(!R.ok)throw new Error(`toPngUrl: Export failed - ${R.error}`);return R.value}function L(S){let R=be($(),"pdf",y(S,"toPdfUrl"),{caller:"toPdfUrl"});if(!R.ok)throw new Error(`toPdfUrl: Export failed - ${R.error}`);return R.value}function O(S,R){switch(S){case"svg":return C(R);case"png":return M(R);case"pdf":return L(R);default:return S}}return{handleEvent:k,handleScopeEvent:E,handleDecisionEvent:D,getIR:T,render:N,renderAs:v,reset:x,onUpdate:g,toUrl:O,toSvgUrl:C,toPngUrl:M,toPdfUrl:L}}function wn(...e){return(t,r)=>{for(let o of e)o(t,r)}}function bn(e,t={}){let r=ze(t);for(let o of e)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()}function yn(e={}){let t=[];return{handleEvent:r=>{t.push(r)},handleDecisionEvent:r=>{t.push(r)},getEvents:()=>[...t],getWorkflowEvents:()=>t.filter(r=>!r.type.startsWith("decision_")),getDecisionEvents:()=>t.filter(r=>r.type.startsWith("decision_")),clear:()=>{t.length=0},visualize:()=>{let r=ze(e);for(let o of t)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()},visualizeAs:r=>{let o=ze(e);for(let i of t)i.type.startsWith("decision_")?o.handleDecisionEvent(i):o.handleEvent(i);return o.renderAs(r)}}}0&&(module.exports={asciiRenderer,buildMermaidInkUrl,combineEventHandlers,createEventCollector,createIRBuilder,createLiveVisualizer,createMermaidInkGenerator,createParallelDetector,createPerformanceAnalyzer,createTimeTravelController,createUrlGenerator,createVisualizer,defaultColorScheme,detectParallelGroups,encodeForMermaidInk,flowchartRenderer,getHeatLevel,hasChildren,htmlRenderer,isDecisionNode,isParallelNode,isRaceNode,isSequenceNode,isStepNode,isStreamNode,loggerRenderer,mermaidRenderer,renderToHTML,toExportUrl,toKrokiPngUrl,toKrokiSvgUrl,toKrokiUrl,toMermaidInkJpegUrl,toMermaidInkPdfUrl,toMermaidInkPngUrl,toMermaidInkSvgUrl,toMermaidInkUrl,toMermaidInkWebpUrl,trackDecision,trackIf,trackSwitch,visualizeEvents});
|
|
1680
|
+
//# sourceMappingURL=index.cjs.map
|