@sanity/comlink
Advanced tools
Comparing version 0.0.2-canary.8 to 0.0.2-canary.9
@@ -1,1 +0,1 @@ | ||
import{v4 as e}from"uuid";import{fromEventObservable as t,setup as s,sendTo as n,assign as a,fromCallback as r,enqueueActions as o,assertEvent as c,raise as i,stopChild as d,createActor as u,emit as p}from"xstate";import{defer as l,fromEvent as g,map as f,pipe as m,filter as h,bufferCount as b,concatMap as y,take as v,EMPTY as q,takeUntil as k}from"rxjs";const x=e=>({context:t})=>{const{count:s,include:n,exclude:a,responseType:r="message.received"}=e;return{count:s,domain:t.domain,from:t.connectTo,include:n?Array.isArray(n)?n:[n]:[],exclude:a?Array.isArray(a)?a:[a]:[],responseType:r,target:t.target,to:t.name}},T=l((()=>g(window,"message"))),E=e=>t((({input:t})=>{return T.pipe(e?f(e):m(),h((e=>t=>{const{data:s}=t;return(!e.include.length||e.include.includes(s.type))&&(!e.exclude.length||!e.exclude.includes(s.type))&&s.domain===e.domain&&s.from===e.from&&s.to===e.to&&(!e.target||t.source===e.target)})(t)),f((s=t.responseType,e=>({type:s,message:e}))),t.count?m(b(t.count),y((e=>e)),v(t.count)):m());var s})),I="sanity/comlink",w=1e3,S=1e3,R=500,O="comlink/response",$="comlink/heartbeat",A="comlink/disconnect",B="comlink/handshake/syn",M="comlink/handshake/syn-ack",j="comlink/handshake/ack",_=[B,M,j],z=[O,A,$,..._],D=()=>s({types:{},actors:{listen:t((({input:e})=>{const t=e.signal?g(e.signal,"abort").pipe((s=`Request ${e.requestId} aborted`,e=>e.pipe(v(1),f((()=>{throw new Error(s)}))))):q;var s;return g(window,"message").pipe(h((t=>t.data?.type===O&&t.data?.responseTo===e.requestId&&!!t.source&&e.sources.has(t.source))),v(e.sources.size),k(t))}))},actions:{"send message":({context:e},t)=>{const{sources:s,targetOrigin:n}=e,{message:a}=t;s.forEach((e=>{e.postMessage(a,{targetOrigin:n})}))},"on success":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(e.response&&e.resolvable?.resolve(e.response),{type:"request.success",requestId:t.id,response:e.response,responseTo:e.responseTo}))),"on fail":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(console.warn(`Received no response to message '${e.type}' on client '${e.from}' (ID: '${e.id}').`),e.resolvable?.reject(new Error("No response received")),{type:"request.failed",requestId:t.id}))),"on abort":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(e.resolvable?.reject(new Error("Request aborted")),{type:"request.aborted",requestId:t.id})))},guards:{expectsResponse:({context:e})=>e.expectResponse},delays:{initialTimeout:0,responseTimeout:1e3}}).createMachine({context:({input:t})=>({connectionId:t.connectionId,data:t.data,domain:t.domain,expectResponse:t.expectResponse??!1,from:t.from,id:`msg-${e()}`,parentRef:t.parentRef,resolvable:t.resolvable,response:null,responseTo:t.responseTo,signal:t.signal,sources:t.sources instanceof Set?t.sources:new Set([t.sources]),targetOrigin:t.targetOrigin,to:t.to,type:t.type}),initial:"idle",on:{abort:".aborted"},states:{idle:{after:{initialTimeout:[{target:"sending"}]}},sending:{entry:{type:"send message",params:({context:e})=>{const{connectionId:t,data:s,domain:n,from:a,id:r,responseTo:o,to:c,type:i}=e;return{message:{connectionId:t,data:s,domain:n,from:a,id:r,to:c,type:i,responseTo:o}}}},always:[{guard:"expectsResponse",target:"awaiting"},"success"]},awaiting:{invoke:{id:"listen for response",src:"listen",input:({context:e})=>({requestId:e.id,sources:e.sources,signal:e.signal}),onError:"aborted"},after:{responseTimeout:"failed"},on:{message:{actions:a({response:({event:e})=>e.data.data,responseTo:({event:e})=>e.data.responseTo}),target:"success"}}},failed:{type:"final",entry:"on fail"},success:{type:"final",entry:"on success"},aborted:{type:"final",entry:"on abort"}},output:({context:e,self:t})=>({requestId:t.id,response:e.response,responseTo:e.responseTo})}),C=r((({sendBack:e,input:t})=>{const s=()=>{e(t.event)};t.immediate&&s();const n=setInterval(s,t.interval);return()=>{clearInterval(n)}})),N=()=>s({types:{},actors:{requestMachine:D(),listen:E(),sendBackAtInterval:C},actions:{"buffer message":o((({enqueue:e})=>{e.assign({buffer:({event:e,context:t})=>(c(e,"post"),[...t.buffer,e.data])}),e.emit((({event:e})=>(c(e,"post"),{type:"_buffer.added",message:e.data})))})),"create request":a({requests:({context:t,event:s,self:n,spawn:a})=>{c(s,"request");const r=(Array.isArray(s.data)?s.data:[s.data]).map((s=>{const r=`req-${e()}`;return a("requestMachine",{id:r,input:{connectionId:t.connectionId,data:s.data,domain:t.domain,expectResponse:s.expectResponse,from:t.name,parentRef:n,responseTo:s.responseTo,sources:t.target,targetOrigin:t.targetOrigin,to:t.connectTo,type:s.type}})}));return[...t.requests,...r]}}),"emit received message":o((({enqueue:e})=>{e.emit((({event:e})=>(c(e,"message.received"),{type:"_message",message:e.message.data}))),e.emit((({event:e})=>(c(e,"message.received"),{type:e.message.data.type,message:e.message.data})))})),"flush buffer":o((({enqueue:e})=>{e.raise((({context:e})=>({type:"request",data:e.buffer.map((({data:e,type:t})=>({data:e,type:t})))}))),e.emit((({context:e})=>({type:"_buffer.flushed",messages:e.buffer}))),e.assign({buffer:[]})})),post:i((({event:e})=>(c(e,"post"),{type:"request",data:{data:e.data.data,expectResponse:!0,type:e.data.type}}))),"remove request":o((({context:e,enqueue:t,event:s})=>{c(s,["request.success","request.failed","request.aborted"]),d(s.requestId),t.assign({requests:e.requests.filter((({id:e})=>e!==s.requestId))})})),respond:i((({event:e})=>(c(e,"response"),{type:"request",data:{data:e.data,type:O,responseTo:e.respondTo}}))),"send handshake ack":i({type:"request",data:{type:j}}),"send disconnect":i((()=>({type:"request",data:{type:A}}))),"send handshake syn":i({type:"request",data:{type:B}}),"set target":a({target:({event:e})=>(c(e,"target.set"),e.target)})},guards:{"has target":({context:e})=>!!e.target,"should send heartbeats":({context:e})=>e.heartbeat}}).createMachine({id:"channel",context:({input:t})=>({id:t.id||`${t.name}-${e()}`,buffer:[],connectionId:`cnx-${e()}`,connectTo:t.connectTo,domain:t.domain??I,heartbeat:t.heartbeat??!1,name:t.name,requests:[],target:t.target,targetOrigin:t.targetOrigin}),on:{"target.set":{actions:"set target"},"request.success":{actions:"remove request"},"request.failed":{actions:"remove request"}},initial:"idle",states:{idle:{on:{connect:{target:"handshaking",guard:"has target"},post:{actions:"buffer message"}}},handshaking:{invoke:[{id:"send syn",src:"sendBackAtInterval",input:()=>({event:{type:"syn"},interval:500,immediate:!0})},{id:"listen for handshake",src:"listen",input:e=>x({include:M,count:1})(e)}],on:{syn:{actions:"send handshake syn"},request:{actions:"create request"},post:{actions:"buffer message"},"message.received":{target:"connected"},disconnect:{target:"disconnected"}},exit:"send handshake ack"},connected:{entry:"flush buffer",invoke:{id:"listen for messages",src:"listen",input:x({exclude:[O,$]})},on:{post:{actions:"post"},request:{actions:"create request"},response:{actions:"respond"},"message.received":{actions:"emit received message"},disconnect:{target:"disconnected"}},initial:"heartbeat",states:{heartbeat:{initial:"checking",states:{checking:{always:{guard:"should send heartbeats",target:"sending"}},sending:{on:{"request.failed":{target:"#disconnected"}},invoke:{id:"send heartbeat",src:"sendBackAtInterval",input:()=>({event:{type:"post",data:{type:$,data:void 0}},interval:2e3,immediate:!1})}}}}}},disconnected:{id:"disconnected",entry:"send disconnect",on:{request:{actions:"create request"},post:{actions:"buffer message"},connect:{target:"handshaking",guard:"has target"}}}}}),P=(t,s=N())=>{const n=t.id||`${t.name}-${e()}`,a=u(s,{input:{...t,id:n}}),r=()=>{a.stop()};return{actor:a,connect:()=>{a.send({type:"connect"})},disconnect:()=>{a.send({type:"disconnect"})},id:n,name:t.name,machine:s,on:(e,t)=>{const{unsubscribe:s}=a.on(e,(async e=>{const s=await t(e.message.data);s&&a.send({type:"response",respondTo:e.message.id,data:s})}));return s},onStatus:e=>{const t=a.getSnapshot();let s="string"==typeof t.value?t.value:Object.keys(t.value)[0];const{unsubscribe:n}=a.subscribe((t=>{const n="string"==typeof t.value?t.value:Object.keys(t.value)[0];s!==n&&(s=n,e(n))}));return n},post:e=>{a.send({type:"post",data:e})},setTarget:e=>{a.send({type:"target.set",target:e})},start:()=>(a.start(),r),stop:r,get target(){return a.getSnapshot().context.target}}},F=()=>{},G=e=>{const{targetOrigin:t}=e,s=new Set,n=new Set,a=e=>{e.disconnect(),setTimeout((()=>{e.stop()}),0)};return{addTarget:e=>{if(s.has(e))return F;if(!s.size||!n.size)return s.add(e),n.forEach((t=>{t.channels.forEach((t=>{t.setTarget(e),t.connect()}))})),()=>{s.delete(e),n.forEach((t=>{t.channels.forEach((t=>{t.target===e&&t.disconnect()}))}))};s.add(e);const r=new Set;return n.forEach((s=>{const n=P({...s.input,target:e,targetOrigin:t},s.machine);r.add(n),s.channels.add(n),s.subscribers.forEach((({type:e,handler:t,unsubscribers:s})=>{s.push(n.on(e,t))})),s.internalEventSubscribers.forEach((({type:e,handler:t,unsubscribers:s})=>{s.push(n.actor.on(e,t).unsubscribe)})),s.statusSubscribers.forEach((({handler:e,unsubscribers:t})=>{t.push(n.onStatus((t=>e({channel:n.id,status:t}))))})),n.start(),n.connect()})),()=>{s.delete(e),r.forEach((e=>{a(e),n.forEach((t=>{t.channels.delete(e)}))}))}},createConnection:(e,a=N())=>{const r={channels:new Set,input:e,internalEventSubscribers:new Set,machine:a,statusSubscribers:new Set,subscribers:new Set};n.add(r);const{channels:o,internalEventSubscribers:c,statusSubscribers:i,subscribers:d}=r;if(s.size)s.forEach((s=>{const n=P({...e,target:s,targetOrigin:t},a);o.add(n),n.start(),n.connect()}));else{const s=P({...e,targetOrigin:t},a);o.add(s)}const u=()=>{o.forEach((e=>{e.stop()}))},p=()=>{o.forEach((e=>{e.disconnect()}))};return{connect:()=>(o.forEach((e=>{e.connect()})),p),disconnect:p,on:(e,t)=>{const s=[];o.forEach((n=>{s.push(n.on(e,t))}));const n={type:e,handler:t,unsubscribers:s};return d.add(n),()=>{s.forEach((e=>e())),d.delete(n)}},onStatus:e=>{const t=[];o.forEach((s=>{t.push(s.onStatus((t=>e({channel:s.id,status:t}))))}));const s={handler:e,unsubscribers:t};return i.add(s),()=>{t.forEach((e=>e())),i.delete(s)}},onInternalEvent:(e,t)=>{const s=[];o.forEach((n=>{s.push(n.actor.on(e,t).unsubscribe)}));const n={type:e,handler:t,unsubscribers:s};return c.add(n),()=>{s.forEach((e=>e())),c.delete(n)}},post:e=>{o.forEach((t=>{t.post(e)}))},start:()=>(o.forEach((e=>{e.start()})),u),stop:u}},destroy:()=>{n.forEach((({channels:e})=>{e.forEach((t=>{a(t),e.delete(t)}))}))}}},H=()=>s({types:{},actors:{requestMachine:D(),listen:E()},actions:{"buffer incoming message":a({handshakeBuffer:({event:e,context:t})=>(c(e,"message.received"),[...t.handshakeBuffer,e])}),"buffer message":o((({enqueue:e})=>{e.assign({buffer:({event:e,context:t})=>(c(e,"post"),[...t.buffer,{data:e.data,resolvable:e.resolvable,signal:e.signal}])}),e.emit((({event:e})=>(c(e,"post"),{type:"_buffer.added",message:e.data})))})),"create request":a({requests:({context:t,event:s,self:n,spawn:a})=>{c(s,"request");const r=(Array.isArray(s.data)?s.data:[s.data]).map((s=>{const r=`req-${e()}`;return a("requestMachine",{id:r,input:{connectionId:t.connectionId,data:s.data,domain:t.domain,expectResponse:s.expectResponse,from:t.name,parentRef:n,resolvable:s.resolvable,responseTo:s.responseTo,sources:t.target,targetOrigin:t.targetOrigin,to:t.connectTo,type:s.type,signal:s.signal}})}));return[...t.requests,...r]}}),"emit heartbeat":p((()=>({type:"_heartbeat"}))),"emit received message":o((({enqueue:e})=>{e.emit((({event:e})=>(c(e,"message.received"),{type:"_message",message:e.message.data}))),e.emit((({event:e})=>(c(e,"message.received"),{type:e.message.data.type,message:e.message.data})))})),"flush buffer":o((({enqueue:e})=>{e.raise((({context:e})=>({type:"request",data:e.buffer.map((({data:e,resolvable:t,signal:s})=>({data:e.data,type:e.type,expectResponse:!!t,resolvable:t,signal:s})))}))),e.emit((({context:e})=>({type:"_buffer.flushed",messages:e.buffer.map((({data:e})=>e))}))),e.assign({buffer:[]})})),"flush handshake buffer":o((({context:e,enqueue:t})=>{e.handshakeBuffer.forEach((e=>t.raise(e))),t.assign({handshakeBuffer:[]})})),post:i((({event:e})=>(c(e,"post"),{type:"request",data:{data:e.data.data,expectResponse:!!e.resolvable,type:e.data.type,resolvable:e.resolvable,signal:e.signal}}))),"remove request":o((({context:e,enqueue:t,event:s})=>{c(s,["request.success","request.failed","request.aborted"]),d(s.requestId),t.assign({requests:e.requests.filter((({id:e})=>e!==s.requestId))})})),"send response":i((({event:e})=>(c(e,["message.received","heartbeat.received"]),{type:"request",data:{type:O,responseTo:e.message.data.id,data:void 0}}))),"send handshake syn ack":i({type:"request",data:{type:M}}),"set connection config":a({connectionId:({event:e})=>(c(e,"message.received"),e.message.data.connectionId),target:({event:e})=>(c(e,"message.received"),e.message.source||void 0),targetOrigin:({event:e})=>(c(e,"message.received"),e.message.origin)})},guards:{hasSource:({context:e})=>null!==e.target}}).createMachine({id:"node",context:({input:e})=>({buffer:[],connectionId:null,connectTo:e.connectTo,domain:e.domain??I,handshakeBuffer:[],name:e.name,requests:[],target:void 0,targetOrigin:null}),on:{"request.success":{actions:"remove request"},"request.failed":{actions:"remove request"},"request.aborted":{actions:"remove request"}},initial:"idle",states:{idle:{invoke:{id:"listen for handshake syn",src:"listen",input:x({include:B,count:1}),onDone:{target:"handshaking",guard:"hasSource"}},on:{"message.received":{actions:"set connection config"},post:{actions:"buffer message"}}},handshaking:{entry:"send handshake syn ack",invoke:[{id:"listen for handshake ack",src:"listen",input:x({include:j,count:1}),onDone:"connected"},{id:"listen for disconnect",src:"listen",input:x({include:A,count:1,responseType:"disconnect"})},{id:"listen for messages",src:"listen",input:x({exclude:[A,j,$,O]})}],on:{request:{actions:"create request"},post:{actions:"buffer message"},"message.received":{actions:"buffer incoming message"},disconnect:{target:"idle"}}},connected:{entry:["flush handshake buffer","flush buffer"],invoke:[{id:"listen for messages",src:"listen",input:x({exclude:[O,$]})},{id:"listen for heartbeat",src:"listen",input:x({include:$,responseType:"heartbeat.received"})},{id:"listen for disconnect",src:"listen",input:x({include:A,count:1,responseType:"disconnect"})}],on:{request:{actions:"create request"},post:{actions:"post"},disconnect:{target:"idle"},"message.received":{actions:["send response","emit received message"]},"heartbeat.received":{actions:["send response","emit heartbeat"]}}}}}),J=(e,t=H())=>{const s=u(t,{input:e}),n=()=>{s.stop()};return{actor:s,fetch:(e,t)=>{const n=Promise.withResolvers();return s.send({type:"post",data:e,resolvable:n,signal:t?.signal}),n.promise},machine:t,on:(e,t)=>{const{unsubscribe:n}=s.on(e,(e=>{t(e.message.data)}));return n},onStatus:e=>{const t=s.getSnapshot();let n="string"==typeof t.value?t.value:Object.keys(t.value)[0];const{unsubscribe:a}=s.subscribe((t=>{const s="string"==typeof t.value?t.value:Object.keys(t.value)[0];n!==s&&(n=s,e(s))}));return a},post:e=>{s.send({type:"post",data:e})},start:()=>(s.start(),n),stop:n}};export{I as DOMAIN,R as HANDSHAKE_INTERVAL,_ as HANDSHAKE_MSG_TYPES,S as HEARTBEAT_INTERVAL,z as INTERNAL_MSG_TYPES,A as MSG_DISCONNECT,j as MSG_HANDSHAKE_ACK,B as MSG_HANDSHAKE_SYN,M as MSG_HANDSHAKE_SYN_ACK,$ as MSG_HEARTBEAT,O as MSG_RESPONSE,w as RESPONSE_TIMEOUT,P as createChannel,N as createChannelMachine,G as createController,E as createListenLogic,J as createNode,H as createNodeMachine,D as createRequestMachine};//# sourceMappingURL=index.js.map | ||
import{v4 as e}from"uuid";import{fromEventObservable as t,setup as s,sendTo as n,assign as a,fromCallback as r,enqueueActions as o,assertEvent as c,raise as i,stopChild as d,createActor as u,emit as p}from"xstate";import{defer as l,fromEvent as g,map as f,pipe as m,filter as h,bufferCount as b,concatMap as y,take as v,EMPTY as q,takeUntil as k}from"rxjs";const x=e=>({context:t})=>{const{count:s,include:n,exclude:a,responseType:r="message.received"}=e;return{count:s,domain:t.domain,from:t.connectTo,include:n?Array.isArray(n)?n:[n]:[],exclude:a?Array.isArray(a)?a:[a]:[],responseType:r,target:t.target,to:t.name}},T=l((()=>g(window,"message"))),E=e=>t((({input:t})=>{return T.pipe(e?f(e):m(),h((e=>t=>{const{data:s}=t;return(!e.include.length||e.include.includes(s.type))&&(!e.exclude.length||!e.exclude.includes(s.type))&&s.domain===e.domain&&s.from===e.from&&s.to===e.to&&(!e.target||t.source===e.target)})(t)),f((s=t.responseType,e=>({type:s,message:e}))),t.count?m(b(t.count),y((e=>e)),v(t.count)):m());var s})),I="sanity/comlink",w=1e4,S=1e3,R=500,O="comlink/response",$="comlink/heartbeat",A="comlink/disconnect",B="comlink/handshake/syn",M="comlink/handshake/syn-ack",j="comlink/handshake/ack",_=[B,M,j],z=[O,A,$,..._],D=()=>s({types:{},actors:{listen:t((({input:e})=>{const t=e.signal?g(e.signal,"abort").pipe((s=`Request ${e.requestId} aborted`,e=>e.pipe(v(1),f((()=>{throw new Error(s)}))))):q;var s;return g(window,"message").pipe(h((t=>t.data?.type===O&&t.data?.responseTo===e.requestId&&!!t.source&&e.sources.has(t.source))),v(e.sources.size),k(t))}))},actions:{"send message":({context:e},t)=>{const{sources:s,targetOrigin:n}=e,{message:a}=t;s.forEach((e=>{e.postMessage(a,{targetOrigin:n})}))},"on success":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(e.response&&e.resolvable?.resolve(e.response),{type:"request.success",requestId:t.id,response:e.response,responseTo:e.responseTo}))),"on fail":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(console.warn(`Received no response to message '${e.type}' on client '${e.from}' (ID: '${e.id}').`),e.resolvable?.reject(new Error("No response received")),{type:"request.failed",requestId:t.id}))),"on abort":n((({context:e})=>e.parentRef),(({context:e,self:t})=>(e.resolvable?.reject(new Error("Request aborted")),{type:"request.aborted",requestId:t.id})))},guards:{expectsResponse:({context:e})=>e.expectResponse},delays:{initialTimeout:0,responseTimeout:1e4}}).createMachine({context:({input:t})=>({connectionId:t.connectionId,data:t.data,domain:t.domain,expectResponse:t.expectResponse??!1,from:t.from,id:`msg-${e()}`,parentRef:t.parentRef,resolvable:t.resolvable,response:null,responseTo:t.responseTo,signal:t.signal,sources:t.sources instanceof Set?t.sources:new Set([t.sources]),targetOrigin:t.targetOrigin,to:t.to,type:t.type}),initial:"idle",on:{abort:".aborted"},states:{idle:{after:{initialTimeout:[{target:"sending"}]}},sending:{entry:{type:"send message",params:({context:e})=>{const{connectionId:t,data:s,domain:n,from:a,id:r,responseTo:o,to:c,type:i}=e;return{message:{connectionId:t,data:s,domain:n,from:a,id:r,to:c,type:i,responseTo:o}}}},always:[{guard:"expectsResponse",target:"awaiting"},"success"]},awaiting:{invoke:{id:"listen for response",src:"listen",input:({context:e})=>({requestId:e.id,sources:e.sources,signal:e.signal}),onError:"aborted"},after:{responseTimeout:"failed"},on:{message:{actions:a({response:({event:e})=>e.data.data,responseTo:({event:e})=>e.data.responseTo}),target:"success"}}},failed:{type:"final",entry:"on fail"},success:{type:"final",entry:"on success"},aborted:{type:"final",entry:"on abort"}},output:({context:e,self:t})=>({requestId:t.id,response:e.response,responseTo:e.responseTo})}),C=r((({sendBack:e,input:t})=>{const s=()=>{e(t.event)};t.immediate&&s();const n=setInterval(s,t.interval);return()=>{clearInterval(n)}})),N=()=>s({types:{},actors:{requestMachine:D(),listen:E(),sendBackAtInterval:C},actions:{"buffer message":o((({enqueue:e})=>{e.assign({buffer:({event:e,context:t})=>(c(e,"post"),[...t.buffer,e.data])}),e.emit((({event:e})=>(c(e,"post"),{type:"_buffer.added",message:e.data})))})),"create request":a({requests:({context:t,event:s,self:n,spawn:a})=>{c(s,"request");const r=(Array.isArray(s.data)?s.data:[s.data]).map((s=>{const r=`req-${e()}`;return a("requestMachine",{id:r,input:{connectionId:t.connectionId,data:s.data,domain:t.domain,expectResponse:s.expectResponse,from:t.name,parentRef:n,responseTo:s.responseTo,sources:t.target,targetOrigin:t.targetOrigin,to:t.connectTo,type:s.type}})}));return[...t.requests,...r]}}),"emit received message":o((({enqueue:e})=>{e.emit((({event:e})=>(c(e,"message.received"),{type:"_message",message:e.message.data}))),e.emit((({event:e})=>(c(e,"message.received"),{type:e.message.data.type,message:e.message.data})))})),"flush buffer":o((({enqueue:e})=>{e.raise((({context:e})=>({type:"request",data:e.buffer.map((({data:e,type:t})=>({data:e,type:t})))}))),e.emit((({context:e})=>({type:"_buffer.flushed",messages:e.buffer}))),e.assign({buffer:[]})})),post:i((({event:e})=>(c(e,"post"),{type:"request",data:{data:e.data.data,expectResponse:!0,type:e.data.type}}))),"remove request":o((({context:e,enqueue:t,event:s})=>{c(s,["request.success","request.failed","request.aborted"]),d(s.requestId),t.assign({requests:e.requests.filter((({id:e})=>e!==s.requestId))})})),respond:i((({event:e})=>(c(e,"response"),{type:"request",data:{data:e.data,type:O,responseTo:e.respondTo}}))),"send handshake ack":i({type:"request",data:{type:j}}),"send disconnect":i((()=>({type:"request",data:{type:A}}))),"send handshake syn":i({type:"request",data:{type:B}}),"set target":a({target:({event:e})=>(c(e,"target.set"),e.target)})},guards:{"has target":({context:e})=>!!e.target,"should send heartbeats":({context:e})=>e.heartbeat}}).createMachine({id:"channel",context:({input:t})=>({id:t.id||`${t.name}-${e()}`,buffer:[],connectionId:`cnx-${e()}`,connectTo:t.connectTo,domain:t.domain??I,heartbeat:t.heartbeat??!1,name:t.name,requests:[],target:t.target,targetOrigin:t.targetOrigin}),on:{"target.set":{actions:"set target"},"request.success":{actions:"remove request"},"request.failed":{actions:"remove request"}},initial:"idle",states:{idle:{on:{connect:{target:"handshaking",guard:"has target"},post:{actions:"buffer message"}}},handshaking:{invoke:[{id:"send syn",src:"sendBackAtInterval",input:()=>({event:{type:"syn"},interval:500,immediate:!0})},{id:"listen for handshake",src:"listen",input:e=>x({include:M,count:1})(e)}],on:{syn:{actions:"send handshake syn"},request:{actions:"create request"},post:{actions:"buffer message"},"message.received":{target:"connected"},disconnect:{target:"disconnected"}},exit:"send handshake ack"},connected:{entry:"flush buffer",invoke:{id:"listen for messages",src:"listen",input:x({exclude:[O,$]})},on:{post:{actions:"post"},request:{actions:"create request"},response:{actions:"respond"},"message.received":{actions:"emit received message"},disconnect:{target:"disconnected"}},initial:"heartbeat",states:{heartbeat:{initial:"checking",states:{checking:{always:{guard:"should send heartbeats",target:"sending"}},sending:{on:{"request.failed":{target:"#disconnected"}},invoke:{id:"send heartbeat",src:"sendBackAtInterval",input:()=>({event:{type:"post",data:{type:$,data:void 0}},interval:2e3,immediate:!1})}}}}}},disconnected:{id:"disconnected",entry:"send disconnect",on:{request:{actions:"create request"},post:{actions:"buffer message"},connect:{target:"handshaking",guard:"has target"}}}}}),P=(t,s=N())=>{const n=t.id||`${t.name}-${e()}`,a=u(s,{input:{...t,id:n}}),r=()=>{a.stop()};return{actor:a,connect:()=>{a.send({type:"connect"})},disconnect:()=>{a.send({type:"disconnect"})},id:n,name:t.name,machine:s,on:(e,t)=>{const{unsubscribe:s}=a.on(e,(async e=>{const s=await t(e.message.data);s&&a.send({type:"response",respondTo:e.message.id,data:s})}));return s},onStatus:e=>{const t=a.getSnapshot();let s="string"==typeof t.value?t.value:Object.keys(t.value)[0];const{unsubscribe:n}=a.subscribe((t=>{const n="string"==typeof t.value?t.value:Object.keys(t.value)[0];s!==n&&(s=n,e(n))}));return n},post:e=>{a.send({type:"post",data:e})},setTarget:e=>{a.send({type:"target.set",target:e})},start:()=>(a.start(),r),stop:r,get target(){return a.getSnapshot().context.target}}},F=()=>{},G=e=>{const{targetOrigin:t}=e,s=new Set,n=new Set,a=e=>{e.disconnect(),setTimeout((()=>{e.stop()}),0)};return{addTarget:e=>{if(s.has(e))return F;if(!s.size||!n.size)return s.add(e),n.forEach((t=>{t.channels.forEach((t=>{t.setTarget(e),t.connect()}))})),()=>{s.delete(e),n.forEach((t=>{t.channels.forEach((t=>{t.target===e&&t.disconnect()}))}))};s.add(e);const r=new Set;return n.forEach((s=>{const n=P({...s.input,target:e,targetOrigin:t},s.machine);r.add(n),s.channels.add(n),s.subscribers.forEach((({type:e,handler:t,unsubscribers:s})=>{s.push(n.on(e,t))})),s.internalEventSubscribers.forEach((({type:e,handler:t,unsubscribers:s})=>{s.push(n.actor.on(e,t).unsubscribe)})),s.statusSubscribers.forEach((({handler:e,unsubscribers:t})=>{t.push(n.onStatus((t=>e({channel:n.id,status:t}))))})),n.start(),n.connect()})),()=>{s.delete(e),r.forEach((e=>{a(e),n.forEach((t=>{t.channels.delete(e)}))}))}},createConnection:(e,a=N())=>{const r={channels:new Set,input:e,internalEventSubscribers:new Set,machine:a,statusSubscribers:new Set,subscribers:new Set};n.add(r);const{channels:o,internalEventSubscribers:c,statusSubscribers:i,subscribers:d}=r;if(s.size)s.forEach((s=>{const n=P({...e,target:s,targetOrigin:t},a);o.add(n),n.start(),n.connect()}));else{const s=P({...e,targetOrigin:t},a);o.add(s)}const u=()=>{o.forEach((e=>{e.stop()}))},p=()=>{o.forEach((e=>{e.disconnect()}))};return{connect:()=>(o.forEach((e=>{e.connect()})),p),disconnect:p,on:(e,t)=>{const s=[];o.forEach((n=>{s.push(n.on(e,t))}));const n={type:e,handler:t,unsubscribers:s};return d.add(n),()=>{s.forEach((e=>e())),d.delete(n)}},onStatus:e=>{const t=[];o.forEach((s=>{t.push(s.onStatus((t=>e({channel:s.id,status:t}))))}));const s={handler:e,unsubscribers:t};return i.add(s),()=>{t.forEach((e=>e())),i.delete(s)}},onInternalEvent:(e,t)=>{const s=[];o.forEach((n=>{s.push(n.actor.on(e,t).unsubscribe)}));const n={type:e,handler:t,unsubscribers:s};return c.add(n),()=>{s.forEach((e=>e())),c.delete(n)}},post:e=>{o.forEach((t=>{t.post(e)}))},start:()=>(o.forEach((e=>{e.start()})),u),stop:u}},destroy:()=>{n.forEach((({channels:e})=>{e.forEach((t=>{a(t),e.delete(t)}))}))}}},H=()=>s({types:{},actors:{requestMachine:D(),listen:E()},actions:{"buffer incoming message":a({handshakeBuffer:({event:e,context:t})=>(c(e,"message.received"),[...t.handshakeBuffer,e])}),"buffer message":o((({enqueue:e})=>{e.assign({buffer:({event:e,context:t})=>(c(e,"post"),[...t.buffer,{data:e.data,resolvable:e.resolvable,signal:e.signal}])}),e.emit((({event:e})=>(c(e,"post"),{type:"_buffer.added",message:e.data})))})),"create request":a({requests:({context:t,event:s,self:n,spawn:a})=>{c(s,"request");const r=(Array.isArray(s.data)?s.data:[s.data]).map((s=>{const r=`req-${e()}`;return a("requestMachine",{id:r,input:{connectionId:t.connectionId,data:s.data,domain:t.domain,expectResponse:s.expectResponse,from:t.name,parentRef:n,resolvable:s.resolvable,responseTo:s.responseTo,sources:t.target,targetOrigin:t.targetOrigin,to:t.connectTo,type:s.type,signal:s.signal}})}));return[...t.requests,...r]}}),"emit heartbeat":p((()=>({type:"_heartbeat"}))),"emit received message":o((({enqueue:e})=>{e.emit((({event:e})=>(c(e,"message.received"),{type:"_message",message:e.message.data}))),e.emit((({event:e})=>(c(e,"message.received"),{type:e.message.data.type,message:e.message.data})))})),"flush buffer":o((({enqueue:e})=>{e.raise((({context:e})=>({type:"request",data:e.buffer.map((({data:e,resolvable:t,signal:s})=>({data:e.data,type:e.type,expectResponse:!!t,resolvable:t,signal:s})))}))),e.emit((({context:e})=>({type:"_buffer.flushed",messages:e.buffer.map((({data:e})=>e))}))),e.assign({buffer:[]})})),"flush handshake buffer":o((({context:e,enqueue:t})=>{e.handshakeBuffer.forEach((e=>t.raise(e))),t.assign({handshakeBuffer:[]})})),post:i((({event:e})=>(c(e,"post"),{type:"request",data:{data:e.data.data,expectResponse:!!e.resolvable,type:e.data.type,resolvable:e.resolvable,signal:e.signal}}))),"remove request":o((({context:e,enqueue:t,event:s})=>{c(s,["request.success","request.failed","request.aborted"]),d(s.requestId),t.assign({requests:e.requests.filter((({id:e})=>e!==s.requestId))})})),"send response":i((({event:e})=>(c(e,["message.received","heartbeat.received"]),{type:"request",data:{type:O,responseTo:e.message.data.id,data:void 0}}))),"send handshake syn ack":i({type:"request",data:{type:M}}),"set connection config":a({connectionId:({event:e})=>(c(e,"message.received"),e.message.data.connectionId),target:({event:e})=>(c(e,"message.received"),e.message.source||void 0),targetOrigin:({event:e})=>(c(e,"message.received"),e.message.origin)})},guards:{hasSource:({context:e})=>null!==e.target}}).createMachine({id:"node",context:({input:e})=>({buffer:[],connectionId:null,connectTo:e.connectTo,domain:e.domain??I,handshakeBuffer:[],name:e.name,requests:[],target:void 0,targetOrigin:null}),on:{"request.success":{actions:"remove request"},"request.failed":{actions:"remove request"},"request.aborted":{actions:"remove request"}},initial:"idle",states:{idle:{invoke:{id:"listen for handshake syn",src:"listen",input:x({include:B,count:1}),onDone:{target:"handshaking",guard:"hasSource"}},on:{"message.received":{actions:"set connection config"},post:{actions:"buffer message"}}},handshaking:{entry:"send handshake syn ack",invoke:[{id:"listen for handshake ack",src:"listen",input:x({include:j,count:1}),onDone:"connected"},{id:"listen for disconnect",src:"listen",input:x({include:A,count:1,responseType:"disconnect"})},{id:"listen for messages",src:"listen",input:x({exclude:[A,j,$,O]})}],on:{request:{actions:"create request"},post:{actions:"buffer message"},"message.received":{actions:"buffer incoming message"},disconnect:{target:"idle"}}},connected:{entry:["flush handshake buffer","flush buffer"],invoke:[{id:"listen for messages",src:"listen",input:x({exclude:[O,$]})},{id:"listen for heartbeat",src:"listen",input:x({include:$,responseType:"heartbeat.received"})},{id:"listen for disconnect",src:"listen",input:x({include:A,count:1,responseType:"disconnect"})}],on:{request:{actions:"create request"},post:{actions:"post"},disconnect:{target:"idle"},"message.received":{actions:["send response","emit received message"]},"heartbeat.received":{actions:["send response","emit heartbeat"]}}}}}),J=(e,t=H())=>{const s=u(t,{input:e}),n=()=>{s.stop()};return{actor:s,fetch:(e,t)=>{const n=Promise.withResolvers();return s.send({type:"post",data:e,resolvable:n,signal:t?.signal}),n.promise},machine:t,on:(e,t)=>{const{unsubscribe:n}=s.on(e,(e=>{t(e.message.data)}));return n},onStatus:e=>{const t=s.getSnapshot();let n="string"==typeof t.value?t.value:Object.keys(t.value)[0];const{unsubscribe:a}=s.subscribe((t=>{const s="string"==typeof t.value?t.value:Object.keys(t.value)[0];n!==s&&(n=s,e(s))}));return a},post:e=>{s.send({type:"post",data:e})},start:()=>(s.start(),n),stop:n}};export{I as DOMAIN,R as HANDSHAKE_INTERVAL,_ as HANDSHAKE_MSG_TYPES,S as HEARTBEAT_INTERVAL,z as INTERNAL_MSG_TYPES,A as MSG_DISCONNECT,j as MSG_HANDSHAKE_ACK,B as MSG_HANDSHAKE_SYN,M as MSG_HANDSHAKE_SYN_ACK,$ as MSG_HEARTBEAT,O as MSG_RESPONSE,w as RESPONSE_TIMEOUT,P as createChannel,N as createChannelMachine,G as createController,E as createListenLogic,J as createNode,H as createNodeMachine,D as createRequestMachine};//# sourceMappingURL=index.js.map |
{ | ||
"name": "@sanity/comlink", | ||
"version": "0.0.2-canary.8", | ||
"version": "0.0.2-canary.9", | ||
"keywords": [ | ||
@@ -5,0 +5,0 @@ "sanity.io", |
@@ -7,3 +7,3 @@ import type {MessageType} from './types' | ||
/** @internal */ | ||
export const RESPONSE_TIMEOUT = 1000 | ||
export const RESPONSE_TIMEOUT = 10000 | ||
@@ -10,0 +10,0 @@ /** @internal */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
705766