insite-ws-transfers
Version:
inSite file transfers over WebSockets
3 lines (2 loc) • 15 kB
JavaScript
var Ae=Object.defineProperty;var Te=o=>{throw TypeError(o)};var Pe=(o,e,t)=>e in o?Ae(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var i=(o,e,t)=>Pe(o,typeof e!="symbol"?e+"":e,t),oe=(o,e,t)=>e.has(o)||Te("Cannot "+t);var s=(o,e,t)=>(oe(o,e,"read from private field"),t?t.call(o):e.get(o)),n=(o,e,t)=>e.has(o)?Te("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(o):e.set(o,t),h=(o,e,t,r)=>(oe(o,e,"write to private field"),r?r.call(o,t):e.set(o,t),t),d=(o,e,t)=>(oe(o,e,"access private method"),t);var l={request:"~t-request",confirm:"~t-confirm",chunk:"~t-c",progress:"~t-p",sent:"~t-sent",completed:"~t-completed",abort:"~t-abort",error:"~t-error"},Ce=10*1024*1024*1024,Oe=1024*256,be=250;var T,C,O,D,S,P,x,z,I,U,c,Re,he,le,b=class{constructor(e,t,r,{type:a,collect:f,encoding:g,size:j,metadata:A},ne,ae){n(this,c);i(this,"ws");n(this,T);i(this,"kind");i(this,"id");i(this,"type");i(this,"collect");i(this,"encoding");i(this,"size");i(this,"metadata");n(this,C);n(this,O);n(this,D);i(this,"data");n(this,S);i(this,"isAborted",!1);i(this,"isAbortedBySender",!1);i(this,"isAbortedByReceiver",!1);i(this,"isTransfered",!1);i(this,"confirmResponse");i(this,"beginAt",null);n(this,P,null);n(this,x,[]);n(this,z,!1);i(this,"duration",null);i(this,"transferedSize",0);i(this,"processedSize",0);i(this,"bytesPerMs",null);i(this,"progress",0);i(this,"endAt",null);i(this,"error",null);n(this,I);n(this,U,0);this.ws=e,h(this,T,e.isWebSocket?[e]:[e.wss,e]),this.kind=t,this.id=r,this.type=a,this.collect=!!f,this.encoding=g,this.size=j,this.metadata=A,h(this,C,ne),h(this,O,ae),h(this,D,d(this,c,Re).call(this))}whenSetUp(){return s(this,D)}async confirm(){for(let{begin:e}of s(this,O))if(await e?.call(...s(this,T),this)===!1)return this.throw("Transfer was rejected by receiver");this.beginAt=h(this,P,Date.now()),this.ws.sendMessage(l.confirm,this.id,this.confirmResponse),h(this,I,setInterval(()=>{s(this,U)!==this.progress&&(h(this,U,this.progress),this.ws.sendMessage(l.progress,this.id,this.progress))},be))}async handleChunk(e,t=e.length){let r=Date.now();this.bytesPerMs=t/(r-s(this,P)),h(this,P,r),this.transferedSize+=t,s(this,x).push([e,t]),s(this,z)||(h(this,z,!0),await d(this,c,he).call(this))}async handleSent(){this.isTransfered=!0,this.size||(this.size=this.transferedSize),this.endAt=Date.now(),this.duration=this.endAt-this.beginAt,this.bytesPerMs=this.size/this.duration,s(this,z)||await d(this,c,le).call(this)}abort(e=!1){return this.isAborted=!0,this.isAbortedBySender=e,this.isAbortedByReceiver=!e,this.throw(`Transfer is aborted by ${e?"sender":"receiver"}`,!e)}throw(e,t=!0){s(this,C).delete(this.id),clearInterval(s(this,I)),this.error=new Error(e);for(let r of s(this,O))r.once&&s(this,C).removeListener(this.kind,r),r.error?.call(...s(this,T),this,this.error);t&&this.ws.sendMessage(l.error,this.id,e)}serialize(){return{id:this.id,kind:this.kind,type:this.type,collect:this.collect,encoding:this.encoding,size:this.size,metadata:this.metadata,isAborted:this.isAborted,isAbortedBySender:this.isAbortedBySender,isAbortedByReceiver:this.isAbortedByReceiver,isTransfered:this.isTransfered,confirmResponse:this.confirmResponse,beginAt:this.beginAt,duration:this.duration,transferedSize:this.transferedSize,processedSize:this.processedSize,bytesPerMs:this.bytesPerMs,progress:this.progress,endAt:this.endAt,error:this.error}}};T=new WeakMap,C=new WeakMap,O=new WeakMap,D=new WeakMap,S=new WeakMap,P=new WeakMap,x=new WeakMap,z=new WeakMap,I=new WeakMap,U=new WeakMap,c=new WeakSet,Re=async function(){if(h(this,S,this.constructor.types[this.type]),s(this,S))await s(this,S).setup.call(this);else throw new Error(`Unknown type of transfer "${String(this.type)}"`);await this.confirm()},he=async function(){let[e,t]=s(this,x).shift();s(this,S).transformChunk&&(e=await s(this,S).transformChunk.call(this,e)),this.collect&&await s(this,S).collect.call(this,e);for(let{chunk:r,progress:a}of s(this,O))await(r??a)?.call(...s(this,T),this,e);this.processedSize+=t,this.size&&(this.progress=this.processedSize/this.size),s(this,x).length?d(this,c,he).call(this):(h(this,z,!1),this.isTransfered&&d(this,c,le).call(this))},le=async function(){this.progress=1,await s(this,S).done?.call(this);for(let e of s(this,O))e.once&&s(this,C).removeListener(this.kind,e),await e.end?.call(...s(this,T),this);clearInterval(s(this,I)),s(this,C).delete(this.id),this.ws.sendMessage(l.completed,this.id)},i(b,"types",{object:{setup(){this.data=""},collect(e){this.data+=e},done(){this.data=JSON.parse(this.data)}},datauri:{setup(){this.collect&&(this.data="")},collect(e){this.data+=e},done(){this.collect&&(this.data=`data:${this.metadata.type};base64,${this.data}`)}},string:{setup(){this.collect&&(this.data="")},collect(e){this.data+=e}}});var p,u,_,J=class{constructor(e,t={}){i(this,"sizeLimit");n(this,p,new Map);i(this,"on",this.addTransferListener);i(this,"off",this.removeTransferListener);n(this,u,new Map);n(this,_,{delete:e=>s(this,u).delete(e),removeListener:(e,t)=>this.removeTransferListener(e,t)});let{sizeLimit:r=Ce}=t;this.sizeLimit=r,e.isWebSocketServer?(e.on(`client-message:${l.request}`,(a,...f)=>this.handleRequest(a,...f)),e.on(`client-message:${l.chunk}`,(a,...f)=>this.handleChunk(a,...f)),e.on(`client-message:${l.sent}`,(a,...f)=>this.handleSent(a,...f)),e.on(`client-message:${l.abort}`,(a,...f)=>this.handleAbort(a,...f))):(e.on(`message:${l.request}`,(...a)=>this.handleRequest(e,...a)),e.on(`message:${l.chunk}`,(...a)=>this.handleChunk(e,...a)),e.on(`message:${l.sent}`,(...a)=>this.handleSent(e,...a)),e.on(`message:${l.abort}`,(...a)=>this.handleAbort(e,...a))),Object.assign(e,{onTransfer:(a,f,g)=>this.on(a,f,g),onceTransfer:(a,f,g)=>this.once(a,f,g)})}addTransferListener(e,t,r){return r?.once&&(t.once=!0),s(this,p).get(e)?.add(t)??s(this,p).set(e,new Set([t])),this}once(e,t,r){return this.addTransferListener(e,t,{...r,once:!0})}removeTransferListener(e,t){if(t){let r=s(this,p).get(e);r&&(r.delete(t),r.size||s(this,p).delete(e))}else s(this,p).delete(e);return this}handleRequest(e,t,r,{type:a,size:f,metadata:g,...j}){let{Transfer:A}=this.constructor;s(this,p).has(t)?s(this,u).has(r)?e.sendMessage(l.error,r,"Transfer already exists"):a in A.types?f>this.sizeLimit?e.sendMessage(l.error,r,`Transfer size (${f} bytes) exeeds limit of ${this.sizeLimit} bytes`):s(this,u).set(r,new A(e,t,r,{type:a,size:f,metadata:g,...j},s(this,_),s(this,p).get(t))):e.sendMessage(l.error,r,"Unknown type of transfer"):e.sendMessage(l.error,r,`Unknown kind of file "${t}"`)}async handleChunk(e,t,r,a=r.length){await s(this,u).get(t)?.handleChunk(r,a)}async handleSent(e,t){await s(this,u).get(t)?.handleSent()}handleAbort(e,t){s(this,u).get(t)?.abort(!0)}};p=new WeakMap,u=new WeakMap,_=new WeakMap,i(J,"Transfer",b);var ee=class extends b{};i(ee,"types",{file:{setup(){this.collect&&(this.data="")},collect(e){this.data+=e},done(){this.collect&&this.encoding==="utf8"&&(this.data=atob(this.data))}},...b.types});var fe=class extends J{};i(fe,"Transfer",ee);import{uid as xe}from"@nesvet/n";var L,k,N,de,M=class{constructor(e,t={}){n(this,N);i(this,"string");i(this,"size");i(this,"chunkSize");i(this,"listener");n(this,L,0);n(this,k,0);i(this,"isAborted",!1);this.string=e,this.size=this.string.length;let{chunkSize:r=1024*256}=t;this.chunkSize=r}start(e){this.listener=e,d(this,N,de).call(this)}abort(){this.isAborted=!0}};L=new WeakMap,k=new WeakMap,N=new WeakSet,de=async function(){if(!this.isAborted){h(this,k,Math.min(s(this,L)+this.chunkSize,this.size));let e=await new Promise(t=>{t(this.string.slice(s(this,L),s(this,k)))});this.isAborted||(await this.listener(e),s(this,k)<this.size&&(h(this,L,s(this,k)),d(this,N,de).call(this)))}};var m,F,Q,G,B,K,V,X,R,E,$,q,v,ze,Se,W=class{constructor(e,t,{data:r,type:a,incomingType:f,collect:g,metadata:j,size:A,chunkSize:ne,encoding:ae,incomingEncoding:ve,onBegin:me,onSenderProgress:ge,onProgress:ue,onEnd:We,onError:ye},we){n(this,v);i(this,"ws");n(this,m);i(this,"kind");i(this,"data");i(this,"type");i(this,"collect");i(this,"metadata");i(this,"size");i(this,"encoding");i(this,"chunkSize");n(this,F);n(this,Q);n(this,G);n(this,B);n(this,K);n(this,V);n(this,X);i(this,"id",xe());n(this,R);i(this,"isAborted",!1);i(this,"isTransfered",!1);i(this,"confirmResponse");i(this,"beginAt",null);n(this,E,null);n(this,$,[]);n(this,q,!1);i(this,"duration",null);i(this,"transferedSize",0);i(this,"bytesPerMs",null);i(this,"senderProgress",0);i(this,"progress",0);i(this,"endAt",null);i(this,"error",null);i(this,"stringStreamer");i(this,"fileStreamer");i(this,"handleChunk",e=>{s(this,$).push(e),s(this,q)||(h(this,q,!0),d(this,v,Se).call(this))});i(this,"sent",()=>this.ws.sendMessage(l.sent,this.id));this.ws=e,h(this,m,e.isWebSocket?[e]:[e.wss,e]),this.kind=t,this.data=r,this.type=a,this.collect=g??!1,this.metadata=j,this.size=A??null,this.encoding=ae,this.chunkSize=ne??this.constructor.chunkSize,h(this,F,we),me&&h(this,Q,me),ge&&h(this,G,ge),ue&&h(this,B,ue),We&&h(this,K,We),ye&&h(this,V,ye),h(this,X,d(this,v,ze).call(this,f,ve))}whenSetUp(){return s(this,X)}async handleConfirm(e){this.confirmResponse=e,this.beginAt=h(this,E,Date.now()),await s(this,Q)?.call(...s(this,m),this),await s(this,R).confirm.call(this)}handleProgress(e){this.progress=e,s(this,B)?.call(...s(this,m),this)}async handleCompleted(){this.isTransfered=!0,this.size||(this.size=this.transferedSize,this.senderProgress=1),this.endAt=Date.now(),this.duration=this.endAt-this.beginAt,this.bytesPerMs=this.size/this.duration,s(this,F).delete(this.id),this.progress!==1&&(this.progress=1,await s(this,B)?.call(...s(this,m),this)),s(this,K)?.call(...s(this,m),this)}throw(e){s(this,F).delete(this.id),this.error=new Error(e),s(this,V)?.call(...s(this,m),this,this.error)}abort(){return this.isAborted=!0,this.ws.sendMessage(l.abort,this.id),this.throw("Transfer is aborted by sender")}serialize(){return{id:this.id,kind:this.kind,type:this.type,collect:this.collect,encoding:this.encoding,size:this.size,metadata:this.metadata,isAborted:this.isAborted,isTransfered:this.isTransfered,confirmResponse:this.confirmResponse,beginAt:this.beginAt,duration:this.duration,transferedSize:this.transferedSize,bytesPerMs:this.bytesPerMs,senderProgress:this.senderProgress,progress:this.progress,endAt:this.endAt,error:this.error}}};m=new WeakMap,F=new WeakMap,Q=new WeakMap,G=new WeakMap,B=new WeakMap,K=new WeakMap,V=new WeakMap,X=new WeakMap,R=new WeakMap,E=new WeakMap,$=new WeakMap,q=new WeakMap,v=new WeakSet,ze=async function(e,t){for(let[r,a,f]of this.constructor.types)if(this.type===r||a(this.data)){this.type=r,h(this,R,f);break}if(this.type)await s(this,R).setup.call(this),delete this.data;else throw new Error("Unknown type of transfer");this.ws.sendMessage(l.request,this.kind,this.id,{type:e??this.type,collect:this.collect,encoding:t??this.encoding,size:this.size,metadata:this.metadata})},Se=async function(){let e=s(this,$).shift(),t=e.length;s(this,R).transformChunk&&(e=await s(this,R).transformChunk.call(this,e)),this.ws.sendMessage(l.chunk,this.id,e,t);let r=Date.now();this.bytesPerMs=t/(r-s(this,E)),h(this,E,r),this.transferedSize+=t,this.size&&(this.senderProgress=this.transferedSize/this.size),await s(this,G)?.call(...s(this,m),this),s(this,$).length?d(this,v,Se).call(this):(h(this,q,!1),this.senderProgress===1&&this.sent())},i(W,"types",[["object",e=>typeof e=="object",{setup(){this.stringStreamer=new M(JSON.stringify(this.data),{chunkSize:this.chunkSize}),this.collect=!0,this.size=this.stringStreamer.size,this.encoding="utf8"},confirm(){this.stringStreamer.start(this.handleChunk)}}],["datauri",e=>typeof e=="string"&&/^data:[\w-.]+\/[\w-.+,]+(?:;base64)?,/.test(e),{setup(){let[e,t]=this.data.split(/^data:|;base64,|,/).slice(1);this.stringStreamer=new M(t,{chunkSize:this.chunkSize}),this.size=this.stringStreamer.size,this.encoding="base64",this.metadata={...this.metadata,type:e}},confirm(){this.stringStreamer.start(this.handleChunk)}}],["string",e=>typeof e=="string",{setup(){this.stringStreamer=new M(this.data,{chunkSize:this.chunkSize}),this.size=this.stringStreamer.size,this.encoding||(this.encoding="utf8")},confirm(){this.stringStreamer.start(this.handleChunk)}}]]),i(W,"chunkSize",Oe);var y,te,Y=class{constructor(e){n(this,y,new Map);n(this,te,{delete:e=>s(this,y).delete(e)});e.isWebSocketServer?(e.on(`client-message:${l.confirm}`,(t,...r)=>this.handleConfirm(t,...r)),e.on(`client-message:${l.progress}`,(t,...r)=>this.handleProgress(t,...r)),e.on(`client-message:${l.completed}`,(t,...r)=>this.handleCompleted(t,...r)),e.on(`client-message:${l.error}`,(t,...r)=>this.handleError(t,...r)),Object.assign(e,{transfer:(t,r,a)=>this.transfer(t,r,a)})):(e.on(`message:${l.confirm}`,(...t)=>this.handleConfirm(e,...t)),e.on(`message:${l.progress}`,(...t)=>this.handleProgress(e,...t)),e.on(`message:${l.completed}`,(...t)=>this.handleCompleted(e,...t)),e.on(`message:${l.error}`,(...t)=>this.handleError(e,...t)),Object.assign(e,{transfer:(t,r)=>this.transfer(e,t,r)}))}transfer(e,t,r){let{Transfer:a}=this.constructor,f=new a(e,t,r,s(this,te));return s(this,y).set(f.id,f),f}async handleConfirm(e,t,r){await s(this,y).get(t)?.handleConfirm(r)}handleProgress(e,t,r){s(this,y).get(t)?.handleProgress(r)}async handleCompleted(e,t){await s(this,y).get(t)?.handleCompleted()}handleError(e,t,r){s(this,y).get(t)?.throw(r)}};y=new WeakMap,te=new WeakMap,i(Y,"Transfer",W);function ke(o){return new Promise(e=>{let t=new FileReader;t.onload=()=>e(typeof t?.result=="string"?t.result.slice(Math.max(0,t.result.indexOf(",")+1)):""),t.readAsDataURL(new Blob([o]))})}var H,w,Z,ce,ie,se=class{constructor(e,t={}){n(this,Z);i(this,"file");i(this,"size");i(this,"chunkSize");i(this,"fileReader");i(this,"listener");n(this,H,0);n(this,w,0);i(this,"isAborted",!1);n(this,ie,async()=>{if(!this.isAborted){let e=this.fileReader.result;e.length=e.byteLength,await this.listener(e),s(this,w)<this.size&&(h(this,H,s(this,w)),d(this,Z,ce).call(this))}});this.file=e,this.size=this.file.size;let{chunkSize:r=1024*256}=t;this.chunkSize=r,this.fileReader=new FileReader,this.fileReader.onload=s(this,ie)}start(e){this.listener=e,d(this,Z,ce).call(this)}abort(){this.isAborted=!0}};H=new WeakMap,w=new WeakMap,Z=new WeakSet,ce=function(){this.isAborted||(h(this,w,Math.min(s(this,H)+this.chunkSize,this.size)),this.fileReader.readAsArrayBuffer(this.file.slice(s(this,H),s(this,w))))},ie=new WeakMap;var re=class extends W{};i(re,"types",[["file",e=>typeof e=="object"&&e instanceof File,{setup(){let e=this.data;this.fileStreamer=new se(e,{chunkSize:this.chunkSize});let t={name:e.name,type:e.type,size:e.size,modifiedAt:e.lastModified};this.metadata?Object.assign(this.metadata,t):this.metadata=t,this.size=this.fileStreamer.size,this.encoding="buffer"},confirm(){this.fileStreamer.start(this.handleChunk)},transformChunk(e){return ke(e)}}],...W.types]);var pe=class extends Y{};i(pe,"Transfer",re);export{ee as IncomingTransfer,fe as IncomingTransport,re as OutgoingTransfer,pe as OutgoingTransport};
//# sourceMappingURL=index.js.map