@statewalker/webrun-http-browser 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- // @statewalker/webrun-http-browser v0.1.0 https://github.com/statewalker/statewalker-webrun-http-browser Copyright 2023 Mikhail Kotelnikov
2
- function e(e){return Object.assign({message:e,stack:e.stack},e)}function t(e){return"string"==typeof e&&(e={message:e}),Object.assign(new Error(e.message),e)}async function*n(e){yield*async function*(e,t=[]){let n,s,a=async(e,n,a)=>{const r={error:e,value:n,done:a};return r.promise=new Promise((e=>r.notify=e)),await t.push(r),s&&s(),s=null,r.promise};const r=e=>a(void 0,e,!1),o=()=>a(void 0,void 0,!0),i=e=>a(e,void 0,!0),c=e(Object.assign([r,o,i],{next:r,complete:o,error:i}));let l;try{for(;;)if(l=await t.shift(),l)try{if(l.error)throw l.error;if(l.done)break;yield l.value}finally{l.notify(!0)}else await(n=s?n:new Promise((e=>s=e)))}finally{for(s&&s(),a=()=>!1,"function"==typeof c&&await c();l=await t.shift();)l.notify(!1)}}((t=>e((async({done:e=!0,value:n,error:s}={})=>{s?await t.error(s):e?await t.complete():await t.next(n)}))))}async function*s(s,a,r={}){const o=new MessageChannel;s.postMessage({type:"START_CALL",params:r},[o.port2]);const i=function(s){let a=[],r=[];const o=async e=>{for(let t of a)await t(e)},i=function(n,s=(()=>{throw new Error("Handler not implemented")})){const a="REQUEST",r="RESPONSE",o="message",i={};let c=0;const l=async o=>{const c=o.data||{},{type:l,callId:d}=c;if(l===a)try{const{request:e}=c;let t=await s(e,...o.ports||[]);const[a,...i]=Array.isArray(t)?t:void 0!==t?[t]:[];n.postMessage({type:r,callId:d,response:a},i)}catch(t){n.postMessage({type:r,callId:d,error:e(t)})}else if(l===r){const{callId:e,response:n,error:s}=c,a=i[e];delete i[e],a&&(s?a.reject(t(s)):a.resolve(n))}},d=async()=>{n.addEventListener(o,l),await n.start()},u=async()=>{n.removeEventListener(o,l),await n.close()},f=async function(e={},...t){const s=++c;return new Promise(((r,o)=>{try{i[s]={resolve:r,reject:o},n.postMessage({type:a,callId:s,request:e},t)}catch(t){o(t),delete e[s]}}))};return{start:d,close:u,invoke:f}}(s,o),c=()=>i.start(),l=async()=>{await o({done:!0}),[...r].forEach((e=>e.return&&e.return())),await i.close()};async function*d(){yield*n((e=>(a.push(e),()=>a=a.filter((t=>t!==e)))))}async function u(e){await async function(e,t){let n;try{for await(let n of t)await e({done:!1,value:n})}catch(e){n=e}finally{await e({done:!0,error:n})}}(i.invoke,async function*(){try{r.push(e),yield*e}finally{r=r.filter((t=>t!==e))}}())}return{start:c,close:l,recieveAll:d,sendAll:u}}(o.port1);try{await i.start(),i.sendAll(a),yield*i.recieveAll()}finally{await i.close()}}function a(e){return async t=>{t=await t;const n=["url","method","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive"].reduce(((e,n)=>{const s=t[n];return void 0!==s&&(e[n]=s),e}),{}),s=t.body?async function*(e){const t=await e.getReader();let n,s;for(;({done:n,value:s}=await t.read())&&!n;)yield await s}(t.body):[],a=await e({options:n,content:s});let r=null,o={};if(a){o=a.options;const e=a.content;"HEAD"!==n.method&&"OPTIONS"!==n.method?(i=e,r=new ReadableStream({type:"bytes",async pull(e){let t=!1;try{for(;;){const t=await i.next();if(!t||t.done)break;e.enqueue(await t.value)}}catch(n){t=!0,e.error(n)}finally{!t&&e.close()}}})):e&&e.return&&e.return()}else o={status:404,statusText:"Error 404: Not Found"};var i;return new Response(r,o)}}async function r(e,t){const n=a((async t=>await async function(e){e=await e;const{done:t,value:n}=await e.next();let s={};if(!t&&n){const e=(new TextDecoder).decode(n);s=JSON.parse(e)}return{options:s,content:e}}(s(e,async function*(e){const{options:t,content:n}=await e,s=new TextEncoder;yield s.encode(JSON.stringify(t)),yield*n}(t)))));return await n(t)}async function o(e,n,s,...a){return new Promise(((r,o)=>{const i=new MessageChannel;i.port1.onmessage=e=>{const{result:n,error:s}=e.data;s?o(t(s)):r(n)},e.postMessage({type:n,params:s},[i.port2,...a])}))}function i(e){return new Promise(((t,n)=>{e.oncomplete=e.onsuccess=()=>t(e.result),e.onabort=e.onerror=()=>n(e.error)}))}let c;function l(){return c||(c=function(e,t){const n=indexedDB.open(e);n.onupgradeneeded=()=>n.result.createObjectStore(t);const s=i(n);return(e,n)=>s.then((s=>n(s.transaction(t,e).objectStore(t))))}("keyval-store","keyval")),c}class d{constructor({self:e,log:t}){this.self=e,this.log=t,this.handlersIndex=new Map}get scope(){return new URL("./",import.meta.url)+""}async loadChannelInfo(e){let t;await this._checkActivation();for(let n of this.handlersIndex.values()){if(n.key!==e)continue;const s=n.clientId;if(!await self.clients.get(s))throw this.handlersIndex.delete(s),Object.assign(new Error("Error 410: Resource Gone"),{status:410});t=n;break}return t}start(){this._cleanup=function(t,n,s){const a=async t=>{if(!t.data||t.data.type!==n)return;const[a,...r]=t.ports;let o={};try{const e=t.data.params;o.result=await s(t,e,...r)}catch(t){o.error=e(t)}a.postMessage(o)};t.addEventListener("message",a);try{t.start&&t.start()}catch(e){}return()=>t.removeEventListener("message",a)}(this.self,"UPDATE_COMMUNICATION_PORT",(async(e,t,n)=>{const s=e.source.id;return this.log("[UPDATE_COMMUNICATION_PORT]",s,t),await this._updateChannelInfo({...t,port:n,clientId:s}),{...t}})),this.self.onmessage=()=>{},this.self.addEventListener("install",(e=>{this.log("Skip waiting on install.",e),this.self.skipWaiting()})),this.self.addEventListener("activate",(async e=>{this.log("Claim control over all clients.",e,clients,this.self.clients),e.waitUntil((async()=>{await this.self.clients.claim(),await this._checkActivation()})())}))}async stop(){this._cleanup&&(await this._cleanup(),this._cleanup=void 0)}async _checkActivation(){return this._activationPromise=this._activationPromise||this._activate()}async _activate(){this.log("[checkActivation]");let e=await this._loadClientIds();for(let[t,n]of e.entries()){const e=new MessageChannel,s=e.port1,a=await o(n,"UPDATE_COMMUNICATION_PORT",{},e.port2);await this._updateChannelInfo({...a,port:s,clientId:t})}}async _updateChannelInfo(e){this.log("[updateClientInfo]",e),this.handlersIndex.set(e.clientId,e),await this._updateClientIds([])}async _loadClientIds(){const e=new Set(await function(e,t=l()){return t("readonly",(t=>i(t.get(e))))}("clientIds")||[]);return await this._updateClientIds(e)}async _updateClientIds(e){e=new Set(e);for(let t of this.handlersIndex.keys())e.add(t);const t=new Map;for(let n of e){const e=await this.self.clients.get(n);e?t.set(n,e):this.handlersIndex.delete(n)}return await function(e,t,n=l()){return n("readwrite",(n=>(n.put(t,e),i(n.transaction))))}("clientIds",[...t.keys()].sort()),t}}class u extends d{constructor(e){super(e)}start(){super.start(),this.self.addEventListener("fetch",this._handleFetchEvent.bind(this))}_handleFetchEvent(e){e.respondWith((async()=>{const t=e.request;try{const e=t.url,n=this.scope;let s;if(0===e.indexOf(n)){const t=e.substring(n.length).replace(/^\/?([^\/]+).*$/,"$1");s=await this.loadChannelInfo(t)}if(s&&s.port)return await r(s.port,t);{const n=new Request(e,{method:t.method,headers:t.headers,body:t.body,referrer:t.referrer,referrerPolicy:t.referrerPolicy,credentials:t.credentials,cache:t.cache,redirect:t.redirect,integrity:t.integrity});return await fetch(n)}}catch(e){return console.error(e),new Response(null,{status:500,statusText:"Error 500: Internal error"})}})())}}const f=function({self:e,log:t}){const n=new u({self:e,log:t});return n.start(),()=>{n.stop()}}({self:self,log:console.log.bind(console,"[sw]")});export{f as result};
1
+ // @statewalker/webrun-http-browser v0.2.0 https://github.com/statewalker/statewalker-webrun-http-browser Copyright 2023 Mikhail Kotelnikov
2
+ function t(t){return new Promise(((e,n)=>{t.oncomplete=t.onsuccess=()=>e(t.result),t.onabort=t.onerror=()=>n(t.error)}))}let e;function n(){return e||(e=function(e,n){const r=indexedDB.open(e);r.onupgradeneeded=()=>r.result.createObjectStore(n);const s=t(r);return(t,e)=>s.then((r=>e(r.transaction(n,t).objectStore(n))))}("keyval-store","keyval")),e}function r(e,r=n()){return r("readonly",(n=>t(n.get(e))))}function s(e,r,s=n()){return s("readwrite",(n=>(n.put(r,e),t(n.transaction))))}function a(t){return Object.assign({message:t,stack:t.stack},t)}function o(t){return"string"==typeof t&&(t={message:t}),Object.assign(new Error(t.message),t)}async function i(t,e,n,...r){return new Promise(((s,a)=>{const i=new MessageChannel;i.port1.onmessage=t=>{const{result:e,error:n}=t.data;n?a(o(n)):s(e)},t.postMessage({type:e,params:n},[i.port2,...r])}))}function c(t,e,n){const r=async t=>{if(!t.data||t.data.type!==e)return;const[r,...s]=t.ports;let o={};try{const e=t.data.params;o.result=await n(t,e,...s)}catch(t){o.error=a(t)}r.postMessage(o)};t.addEventListener("message",r);try{t.start&&t.start()}catch(t){}return()=>t.removeEventListener("message",r)}async function*l(t){yield*async function*(t,e=[]){let n,r,s=async(t,n,s)=>{const a={error:t,value:n,done:s};return a.promise=new Promise((t=>a.notify=t)),await e.push(a),r&&r(),r=null,a.promise};const a=t=>s(void 0,t,!1),o=()=>s(void 0,void 0,!0),i=t=>s(t,void 0,!0),c=t(Object.assign([a,o,i],{next:a,complete:o,error:i}));let l;try{for(;;)if(l=await e.shift(),l)try{if(l.error)throw l.error;if(l.done)break;yield l.value}finally{l.notify(!0)}else await(n=r?n:new Promise((t=>r=t)))}finally{for(r&&r(),s=()=>!1,"function"==typeof c&&await c();l=await e.shift();)l.notify(!1)}}((e=>t((async({done:t=!0,value:n,error:r}={})=>{r?await e.error(r):t?await e.complete():await e.next(n)}))))}async function*u(t,e,n={}){const r=new MessageChannel;t.postMessage({type:"START_CALL",params:n},[r.port2]);const s=function(t){let e=[],n=[];const r=async t=>{for(let n of e)await n(t)},s=d({port:t,handler:r});async function*a(){yield*l((t=>(e.push(t),()=>e=e.filter((e=>e!==t)))))}async function o(t){await async function(t,e){let n;try{for await(let n of e)await t({done:!1,value:n})}catch(t){n=t}finally{await t({done:!0,error:n})}}(s.invoke,async function*(){try{n.push(t),yield*t}finally{n=n.filter((e=>e!==t))}}())}return{start:()=>s.start(),close:async()=>{await r({done:!0}),[...n].forEach((t=>t.return&&t.return())),await s.close()},recieveAll:a,sendAll:o}}(r.port1);try{await s.start(),s.sendAll(e),yield*s.recieveAll()}finally{await s.close()}}function d({port:t,handler:e=(()=>{throw new Error("Handler not implemented")}),onError:n=console.error,newCallId:r=(()=>d.__counter=(d.__counter||0)+1)}){const s="REQUEST",i="RESPONSE",c="message",l={},u=async n=>{const r=n.data||{},{type:c,callId:u}=r;if(c===s)try{const{request:s}=r;let a=await e(s,...n.ports||[]);const[o,...c]=Array.isArray(a)?a:void 0!==a?[a]:[];t.postMessage({type:i,callId:u,response:o},c)}catch(e){t.postMessage({type:i,callId:u,error:a(e)})}else if(c===i){const{callId:t,response:e,error:n}=r,s=l[t];delete l[t],s&&(n?s.reject(o(n)):s.resolve(e))}};return{start:async()=>{try{t.addEventListener(c,u),t.start&&await t.start()}catch(t){n(t)}},close:async()=>{try{t.removeEventListener(c,u),t.close&&await t.close()}catch(t){n(t)}},invoke:async function(e={},...n){const a=r();return new Promise(((r,o)=>{try{l[a]={resolve:r,reject:o},t.postMessage({type:s,callId:a,request:e},n)}catch(t){o(t),delete e[a]}}))}}}function f(t){return async e=>{e=await e;const n=["url","method","mode","credentials","cache","redirect","referrer","referrerPolicy","integrity","keepalive"].reduce(((t,n)=>{const r=e[n];return void 0!==r&&(t[n]=r),t}),{}),r=e.body?async function*(t){const e=await t.getReader();let n,r;for(;({done:n,value:r}=await e.read())&&!n;)yield await r}(e.body):[],s=await t({options:n,content:r});let a=null,o={};if(s){o=s.options;const t=s.content;"HEAD"!==n.method&&"OPTIONS"!==n.method?(i=t,a=new ReadableStream({type:"bytes",async pull(t){let e=!1;try{for(;;){const e=await i.next();if(!e||e.done)break;t.enqueue(await e.value)}}catch(n){e=!0,t.error(n)}finally{!e&&t.close()}}})):t&&t.return&&t.return()}else o={status:404,statusText:"Error 404: Not Found"};var i;return new Response(a,o)}}async function y(t,e){const n=f((async e=>await async function(t){t=await t;const{done:e,value:n}=await t.next();let r={};if(!e&&n){const t=(new TextDecoder).decode(n);r=JSON.parse(t)}return{options:r,content:t}}(u(t,async function*(t){const{options:e,content:n}=await t,r=new TextEncoder;yield r.encode(JSON.stringify(e)),yield*n}(e)))));return await n(e)}class w extends Error{constructor(t){super(t.message),this.status=t.status,this.statusText=t.statusText}getResponseOptions(t={}){return Object.assign(this.toJson(),t)}toJson(){return{status:this.status,statusText:this.statusText,message:this.message}}static fromError(t){return t instanceof w||(t=new w(Object.assign({status:500,statusText:"Bad Request",reason:t.message}))),t}static errorResourceNotFound(t={}){return new w({status:404,statusText:"Error 404: Resource not found",...t})}static errorForbidden(t={}){return new w({status:403,statusText:"Error 403: Forbidden",...t})}static errorResourceGone(t={}){return new w({status:410,statusText:"Error 410: Resource Gone",...t})}static errorInternalError(t){return new w({...t,status:500,statusText:"Error 500: Internal error"})}}!function(t){const[e,n]=function(t=console.error){let e=0;const n={},r=r=>{const s=e++;return n[s]=Object.assign((function(e){try{return delete n[s],!e&&r&&r()}catch(e){t(e)}}),{action:r})},s=t=>Object.values(n).forEach((e=>e.action===t&&e(!0))),a=()=>Object.values(n).forEach((t=>t()));return Object.assign([r,a,s],{register:r,clear:a,unregister:s})}();"function"==typeof t.skipWaiting?(console.log("self.skipWaiting() is supported."),t.addEventListener("install",(e=>{e.waitUntil(t.skipWaiting())}))):console.log("self.skipWaiting() is not supported."),t.clients&&"function"==typeof t.clients.claim?(console.log("self.clients.claim() is supported."),t.addEventListener("activate",(e=>{e.waitUntil(t.clients.claim())}))):console.log("self.clients.claim() is not supported.");const a=function({self:t,key:e="clientsIds",get:n,set:r}){let s;async function a(){if(!s){const t=await n(e)||[];s=Object.fromEntries(t)}return s}async function o(){const t=await a(),n=Object.entries(t);return await r(e,n),t}async function i(t,e){const n=await a(),r=e.id;let s=!1;return r in n||(n[t]=r,await o(),s=!0),s}async function c(t){const e=await a();let n=!1;return t in e&&(delete e[t],await o(),n=!0),n}async function l(e){const n=await a(),r=n[e],s=await t.clients.get(r);return s||(delete n[e],await o()),s}return{getClient:l,addClient:i,removeClient:c}}({self:t,get:r,set:s});e(c(t,"REGISTER",(async(t,e)=>await a.addClient(e.key,t.source)))),e(c(t,"UNREGISTER",(async(t,e)=>await a.removeClient(e.key)))),e(c(t,"CONNECT",(async(t,e,n)=>{const{key:r}=e,s=await a.getClient(r);if(!s)throw new Error(`Target client was not found. Target key: "${r}".`);return await i(s,"CONNECT",e,n)})));const o=t=>{const e=t.request,n=function(t,e="~"){let n="",r="",s=t+"";const a=s.indexOf(e);let o="";return a>=0&&(o=s.substring(0,a+e.length),s.substring(a+e.length).replace(/^([^\/]+)/,((t,e)=>(o+=t,o.length<s.length&&(o+="/"),n=e,r=s.substring(o.length),"")))),{url:t,key:n,baseUrl:o,path:r}}(e.url),{key:r}=n;if(r){const s=async()=>{try{const t=new MessageChannel,s=await a.getClient(r);if(!s)throw w.errorResourceGone(n);const o={type:"http",key:r};if(!await i(s,"CONNECT",o,t.port2))throw w.errorForbidden(n);return await y(t.port1,e)}catch(t){const e=(t=w.fromError(t)).getResponseOptions(n);return new Response(JSON.stringify(e),{...e,headers:{"Content-Type":"text/javascript"}})}};t.respondWith(s())}};t.addEventListener("fetch",o),e((()=>t.removeEventListener("fetch",o)))}(self);