@flows/react
Version:
Flows React SDK – Build native product growth experiences, your way
3 lines (2 loc) • 14.1 kB
JavaScript
"use client"
var Go=Object.defineProperty,Jo=Object.defineProperties;var Xo=Object.getOwnPropertyDescriptors;var io=Object.getOwnPropertySymbols;var Ho=Object.prototype.hasOwnProperty,Qo=Object.prototype.propertyIsEnumerable;var po=(o,e,t)=>e in o?Go(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,d=(o,e)=>{for(var t in e||(e={}))Ho.call(e,t)&&po(o,t,e[t]);if(io)for(var t of io(e))Qo.call(e,t)&&po(o,t,e[t]);return o},b=(o,e)=>Jo(o,Xo(e));import{createContext as Yo,useContext as Zo}from"react";var fo=()=>{},$=Yo({blocks:[],components:{},tourComponents:{},runningTours:[],removeBlock:fo,updateBlock:fo}),v=()=>Zo($);import{useEffect as se,useMemo as ie,useState as pe}from"react";var mo=(o,{body:e,method:t,version:n})=>fetch(o,{method:t,headers:{"Content-Type":"application/json","x-flows-version":n},body:e?JSON.stringify(e):void 0}).then(async r=>{var s;let i=await r.text(),p=i?JSON.parse(i):void 0;if(!r.ok){let f=p;throw new Error((s=f==null?void 0:f.message)!=null?s:r.statusText)}return p}),M=(o,e)=>({getBlocks:t=>mo(`${o}/v2/sdk/blocks`,{method:"POST",body:t,version:e}),sendEvent:t=>mo(`${o}/v2/sdk/events`,{method:"POST",body:t,version:e})});var V=(o,e)=>{let t=new Set([...e.exitedBlockIds,...e.updatedBlocks.map(n=>n.id)]);return[...o.filter(n=>!t.has(n.id)),...e.updatedBlocks]};function ao(o){var e;return typeof o=="string"||typeof o=="symbol"?o:Object.is((e=o==null?void 0:o.valueOf)==null?void 0:e.call(o),-0)?"-0":String(o)}function co(o){let e=[],t=o.length;if(t===0)return e;let n=0,r="",i="",p=!1;for(o.charCodeAt(0)===46&&(e.push(""),n++);n<t;){let s=o[n];i?s==="\\"&&n+1<t?(n++,r+=o[n]):s===i?i="":r+=s:p?s==='"'||s==="'"?i=s:s==="]"?(p=!1,e.push(r),r=""):r+=s:s==="["?(p=!0,r&&(e.push(r),r="")):s==="."?r&&(e.push(r),r=""):r+=s,n++}return r&&e.push(r),e}function q(o){return o!==null&&(typeof o=="object"||typeof o=="function")}function uo(o,e){return o===e||Number.isNaN(o)&&Number.isNaN(e)}var oe=/^(?:0|[1-9]\d*)$/;function lo(o,e=Number.MAX_SAFE_INTEGER){switch(typeof o){case"number":return Number.isInteger(o)&&o>=0&&o<e;case"symbol":return!1;case"string":return oe.test(o)}}function xo(o){return typeof o=="symbol"||o instanceof Symbol}var ee=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,te=/^\w*$/;function go(o,e){return Array.isArray(o)?!1:typeof o=="number"||typeof o=="boolean"||o==null||xo(o)?!0:typeof o=="string"&&(te.test(o)||!ee.test(o))||e!=null&&Object.hasOwn(e,o)}var yo=(o,e,t)=>{let n=o[e];(!(Object.hasOwn(o,e)&&uo(n,t))||t===void 0&&!(e in o))&&(o[e]=t)};function ko(o,e,t,n){if(o==null&&!q(o))return o;let r=go(e,o)?[e]:Array.isArray(e)?e:typeof e=="string"?co(e):[e],i=o;for(let p=0;p<r.length&&i!=null;p++){let s=ao(r[p]),f;if(p===r.length-1)f=t(i[s]);else{let m=i[s],c=n(m);f=c!==void 0?c:q(m)?m:lo(r[p+1])?[]:{}}yo(i,s,f),i=i[s]}return o}function j(o,e,t){return ko(o,e,()=>t,()=>{})}var ho=({block:o,exitNodeCb:e,removeBlock:t,setStateMemory:n})=>{var s,f,m;let r=({properties:c,parentKey:l})=>{var y;let a=d({},c);return Object.entries(c).forEach(([h,w])=>{Array.isArray(w)&&(a[h]=w.map((g,I)=>typeof g=="object"?r({properties:g,parentKey:[l,h,I].filter(S=>S!==void 0).join(".")}):g))}),delete a.f__exit_nodes,(y=c.f__exit_nodes)==null||y.forEach(h=>{let w=()=>e([l,h].filter(g=>g!==void 0).join("."));a[h]=w}),a},i=r({properties:o.data});for(let c of(s=o.propertyMeta)!=null?s:[])if(c.type==="state-memory"){let l={value:(f=c.value)!=null?f:!1,setValue:a=>{n(c.key,a)},triggers:(m=c.triggers)!=null?m:[]};j(i,c.key,l)}let p=o.exitNodes.reduce((c,l)=>{let a=()=>(t(o.id),e(l));return c[l]=a,c},{});return d(d({__flows:{id:o.id,key:o.key,workflowId:o.workflowId}},i),p)};var re="#22262d",ne="#fff",Bo="%cFlows%c",vo=`color:${ne};background:${re};padding:2px 4px;border-radius:4px`,P={error:(o,...e)=>{console.error(`${Bo} ${o}`,vo,"",...e)},warn:(o,...e)=>{console.warn(`${Bo} ${o}`,vo,"",...e)}};var z=(o,e)=>e?Array.isArray(e)?e.some(t=>z(o,t)):typeof o!="string"?!1:new RegExp(e).test(o):!0,K=(o,e)=>e===void 0?!0:Array.isArray(e)?e.some(t=>K(o,t)):o===e,G=(o,e)=>e===void 0?!0:Array.isArray(e)?e.every(t=>G(o,t)):o!==e;var J=(o,e)=>e?Array.isArray(e)?e.some(t=>J(o,t)):typeof o!="string"?!1:o.includes(e):!0,X=(o,e)=>e?Array.isArray(e)?e.every(t=>X(o,t)):typeof o!="string"?!1:!o.includes(e):!0;var T=({operator:o,pathname:e,value:t})=>o==="eq"?K(e,t):o==="ne"?G(e,t):o==="contains"?J(e,t):o==="notContains"?X(e,t):o==="regex"?z(e,t):!0,wo=({eventTarget:o,value:e})=>e?Array.from(document.querySelectorAll(e)).some(t=>t.contains(o)):!1;var R=()=>window.location.pathname+window.location.search;var bo=o=>{var e;if(!(!o||o==="disabled"))return o==="automatic"?(e=navigator.languages.at(0))!=null?e:navigator.language:o};var H=(o,e)=>new Proxy(o,{get(t,n,r){return n==="props"&&e(o.id),Reflect.get(t,n,r)}});var C={};var Co="@flows/react",Io="1.10.3";var O=`${Co}@${Io}`;var B=async o=>{let{apiUrl:e,environment:t,organizationId:n,userId:r}=C;!e||!t||!n||!r||await M(e,O).sendEvent(b(d({},o),{environment:t,organizationId:n,userId:r}))},So=new Set,Q=async o=>{So.has(o)||(So.add(o),await B({name:"block-activated",blockId:o}))};var To=({blocks:o,removeBlock:e})=>{let[t,n]=pe([]);return se(()=>{n(i=>{let p=o.filter(m=>m.type==="tour"),s=new Map(i.map(m=>[m.blockId,m]));return p.map(m=>{var a,y;let c=s.get(m.id),l=(y=(a=c==null?void 0:c.currentBlockIndex)!=null?a:m.currentTourIndex)!=null?y:0;return{blockId:m.id,currentBlockIndex:l}})})},[o]),ie(()=>{let i=(s,f)=>{n(m=>m.map(c=>c.blockId===s?f(c):c))},p=(s,f)=>{i(s,m=>b(d({},m),{currentBlockIndex:f}))};return t.map(({blockId:s,currentBlockIndex:f})=>{var g,I,S;let m=o.find(u=>u.id===s);if(!m)return;let c=(g=m.tourBlocks)==null?void 0:g[f],l=f===((S=(I=m.tourBlocks)==null?void 0:I.length)!=null?S:0)-1,a=u=>{B({name:"tour-update",blockId:s,properties:{currentTourIndex:u}})};return{block:m,currentBlockIndex:f,activeStep:c,continue:()=>{if(l)e(s),B({name:"transition",propertyKey:"complete",blockId:s});else{let u=f+1;p(s,u),a(u)}},previous:()=>{var x;let u=f===0?f:f-1;for(;u>0&&m.tourBlocks&&!((x=m.tourBlocks.at(u))!=null&&x.componentType);)u-=1;p(s,u),a(u)},cancel:()=>{e(s),B({name:"transition",blockId:s,propertyKey:"cancel"})}}}).filter(s=>!!s)},[o,e,t])};import{useCallback as W,useEffect as Fo,useMemo as Z,useRef as Mo,useState as Oo}from"react";import{useCallback as Ro,useEffect as A,useRef as Y,useState as Ao}from"react";var Eo=({url:o,onMessage:e,onOpen:t})=>{let[n,r]=Ao(),i=Y(void 0),[p,s]=Ao(0),f=Y(t);A(()=>{f.current=t},[t]);let m=Y(e);A(()=>{m.current=e},[e]);let c=Ro(a=>{m.current(a)},[]),l=Ro(()=>{if(i.current&&(i.current(),i.current=void 0),!o)return;let a=new WebSocket(o);r(a);let y=()=>{var g;(g=f.current)==null||g.call(f),s(0)},h=()=>{r(void 0),s(g=>g+1)};a.addEventListener("open",y),a.addEventListener("close",h),a.addEventListener("message",c);let w=()=>{a.removeEventListener("open",y),a.removeEventListener("close",h),a.removeEventListener("message",c),a.readyState===WebSocket.CONNECTING?a.addEventListener("open",()=>{a.close()}):a.close(),r(void 0)};return i.current=w,w},[c,o]);A(()=>{let a=l();return()=>{a==null||a()}},[l]),A(()=>{if(n)return;let a=setTimeout(()=>{l()},Math.min(1e3*4**p,12e4));return()=>{clearTimeout(a)}},[p,n,l]),A(()=>()=>{i.current&&i.current()},[])};var No=({apiUrl:o,environment:e,organizationId:t,userId:n,userProperties:r,language:i})=>{let[p,s]=Oo(null),f=Z(()=>p!=null?p:[],[p]),[m,c]=Oo(!1),l=Mo([]),a=Z(()=>({environment:e,organizationId:t,userId:n}),[e,t,n]),y=Mo(r);Fo(()=>{y.current=r},[r]);let h=W(()=>{M(o,O).getBlocks(b(d({},a),{language:bo(i),userProperties:y.current})).then(u=>{var k;let x=l.current.reduce(V,u.blocks);s(x),l.current=[],(k=u.meta)!=null&&k.usage_limited&&c(!0)}).catch(u=>{P.error("Failed to load blocks",u)})},[o,i,a]),w=Z(()=>m?void 0:`${o.replace("https://","wss://").replace("http://","ws://")}/ws/sdk/block-updates?${new URLSearchParams(a).toString()}`,[o,a,m]),g=W(u=>{let x=JSON.parse(u.data);s(k=>k?V(k,x):(l.current.push(x),k))},[]);Eo({url:w,onMessage:g,onOpen:h}),Fo(()=>{f.forEach(u=>{var x;Wo(u),(x=u.tourBlocks)==null||x.forEach(k=>{Wo(k)})})},[f]);let I=W(u=>{s(x=>x&&x.filter(k=>k.id!==u))},[]),S=W((u,x)=>{s(k=>k&&k.map(U=>U.id===u?x(U):U))},[]);return{blocks:f,removeBlock:I,updateBlock:S}},Wo=o=>{o.slottable&&!o.slotId&&P.error(`Encountered workflow block "${o.componentType}" that is slottable but has no slotId`)};import{createContext as fe,useContext as me,useEffect as Lo,useRef as ae,useState as ce}from"react";import{jsx as de}from"react/jsx-runtime";var ue=200,le=()=>{let[o,e]=ce(),t=ae(o);return Lo(()=>{t.current=o},[o]),Lo(()=>{let n=window.setInterval(()=>{let r=R();t.current!==r&&e(r)},ue);return()=>{clearInterval(n)}}),o},Do=fe(void 0),E=()=>{if(me(Do)!==void 0)return R()},_o=({children:o})=>{let e=le();return de(Do.Provider,{value:e,children:o})};import{useEffect as N,useMemo as xe}from"react";import{useState as ge}from"react";var Uo=()=>{let{runningTours:o}=v(),e=E(),[t]=ge(new Map),n=xe(()=>o.filter(r=>{var i;return!!((i=r.activeStep)!=null&&i.tourWait)}),[o]);return N(()=>{n.forEach(r=>{var p,s,f;let i=(p=r.activeStep)==null?void 0:p.tourWait;(i==null?void 0:i.interaction)==="navigation"&&T({pathname:e,operator:(s=i.page)==null?void 0:s.operator,value:(f=i.page)==null?void 0:f.value})&&r.continue()})},[e,n]),N(()=>{let r=i=>{let p=i.target;if(!p||!(p instanceof Element))return;let s=R();n.forEach(f=>{var c,l,a;let m=(c=f.activeStep)==null?void 0:c.tourWait;if((m==null?void 0:m.interaction)==="click"){let y=T({pathname:s,operator:(l=m.page)==null?void 0:l.operator,value:(a=m.page)==null?void 0:a.value});wo({eventTarget:p,value:m.element})&&y&&f.continue()}})};return addEventListener("click",r),()=>{removeEventListener("click",r)}},[e,n]),N(()=>{o.forEach(r=>{let i=r.activeStep,p=t.get(r.block.id);p&&p.stepId!==(i==null?void 0:i.id)&&(clearTimeout(p.timeoutId),t.delete(r.block.id))})},[o,t]),N(()=>{n.forEach(r=>{let i=r.activeStep,p=i==null?void 0:i.tourWait;if(i&&(p==null?void 0:p.interaction)==="delay"&&p.ms!==void 0&&!t.has(r.block.id)){let s=window.setTimeout(()=>{r.continue(),t.delete(r.block.id)},p.ms);t.set(r.block.id,{timeoutId:s,stepId:i.id})}})},[n,t]),null};import{useMemo as F}from"react";var oo=({block:o,removeBlock:e,updateBlock:t})=>{if(!o.componentType)return[];let r=ho({block:o,removeBlock:e,exitNodeCb:p=>B({name:"transition",blockId:o.id,propertyKey:p}),setStateMemory:async(p,s)=>{t(o.id,f=>{var m;return b(d({},f),{propertyMeta:(m=f.propertyMeta)==null?void 0:m.map(c=>c.type==="state-memory"&&c.key===p?b(d({},c),{value:s}):c)})}),await B({name:"set-state-memory",blockId:o.id,propertyKey:p,properties:{value:s}})}}),i={id:o.id,type:"component",component:o.componentType,props:r};return H(i,Q)},eo=o=>{let e=o.activeStep;if(!(e!=null&&e.componentType))return[];let t=o.currentBlockIndex===0,n={id:e.id,tourBlockId:o.block.id,type:"tour-component",component:e.componentType,props:b(d({__flows:{id:e.id,key:e.key,workflowId:e.workflowId}},e.data),{continue:o.continue,previous:t?void 0:o.previous,cancel:o.cancel})};return H(n,Q)};var to=o=>o==null?void 0:o.slotId;var Vo=()=>{let{blocks:o}=v(),e=E();return F(()=>o.filter(t=>T({pathname:e,operator:t.page_targeting_operator,value:t.page_targeting_values})),[o,e])},qo=()=>{let{runningTours:o}=v(),e=E();return F(()=>o.filter(t=>{let n=t.activeStep;return n&&T({pathname:e,operator:n.page_targeting_operator,value:n.page_targeting_values})}),[e,o])},ro=()=>{let o=Vo(),e=qo(),{removeBlock:t,updateBlock:n}=v(),r=F(()=>o.filter(p=>!p.slottable).flatMap(p=>oo({block:p,removeBlock:t,updateBlock:n})),[t,n,o]),i=F(()=>e.filter(p=>{let s=p.activeStep;return s&&!s.slottable}).flatMap(eo),[e]);return[...r,...i]},jo=o=>"type"in o,$o=o=>{var e,t,n;return jo(o)?(e=o.slotIndex)!=null?e:0:(n=(t=o.activeStep)==null?void 0:t.slotIndex)!=null?n:0},no=o=>{let e=Vo(),t=qo(),{removeBlock:n,updateBlock:r}=v();return F(()=>{let p=e.filter(f=>f.slottable&&to(f)===o),s=t.filter(f=>{var m;return((m=f.activeStep)==null?void 0:m.slottable)&&to(f.activeStep)===o});return[...p,...s].sort((f,m)=>$o(f)-$o(m)).flatMap(f=>jo(f)?oo({block:f,removeBlock:n,updateBlock:r}):eo(f))},[n,o,r,e,t])};import{useEffect as ye}from"react";import{jsx as ke}from"react/jsx-runtime";var L=({block:o})=>{let{components:e}=v(),t=e[o.component];return ye(()=>{t||P.error(`Component not found for workflow block "${o.component}"`)},[t,o.component]),t?ke(t,d({},o.props)):null};import{useEffect as he}from"react";import{jsx as Be}from"react/jsx-runtime";var D=({block:o})=>{let{tourComponents:e}=v(),t=e[o.component];return he(()=>{t||P.error(`Tour Component not found for tour block "${o.component}"`)},[t,o.component]),t?Be(t,d({},o.props)):null};import{Fragment as ve,jsx as so}from"react/jsx-runtime";var zo=()=>{let o=ro();return so(ve,{children:o.map(e=>e.type==="component"?so(L,{block:e},e.id):e.type==="tour-component"?so(D,{block:e},e.tourBlockId):null)})};import{jsx as _,jsxs as Ce}from"react/jsx-runtime";var we=o=>be(o)?_(Pe,d({},o)):o.children,be=o=>typeof o.userId=="string",Pe=({children:o,apiUrl:e="https://api.flows-cloud.com",environment:t,organizationId:n,userId:r,components:i,tourComponents:p,userProperties:s,language:f})=>{C.apiUrl=e,C.environment=t,C.organizationId=n,C.userId=r;let{blocks:m,removeBlock:c,updateBlock:l}=No({apiUrl:e,environment:t,organizationId:n,userId:r,userProperties:s,language:f}),a=To({blocks:m,removeBlock:c});return _(_o,{children:Ce($.Provider,{value:{blocks:m,components:i,runningTours:a,tourComponents:p,removeBlock:c,updateBlock:l},children:[o,_(zo,{}),_(Uo,{})]})})};import{jsx as Ko}from"react/jsx-runtime";var Sr=({id:o,placeholder:e})=>{let t=no(o);return t.length?t.map(n=>n.type==="component"?Ko(L,{block:n},n.id):n.type==="tour-component"?Ko(D,{block:n},n.id):null):e!=null?e:null};var Er=()=>B({name:"reset-progress"}),Fr=o=>B({name:"reset-progress",workflowId:o}),Mr=o=>B({name:"workflow-start",blockKey:o});export{we as FlowsProvider,Sr as FlowsSlot,Er as resetAllWorkflowsProgress,Fr as resetWorkflowProgress,Mr as startWorkflow,ro as useCurrentFloatingBlocks,no as useCurrentSlotBlocks};