UNPKG

coincident

Version:

An Atomics based Proxy to simplify, and synchronize, Worker related tasks

2 lines (1 loc) 4.45 kB
const{ArrayBuffer:e,Atomics:t,Promise:s}=globalThis,{isArray:r}=Array,{create:n,getPrototypeOf:a,values:o}=Object,c=a(Int32Array),i=n(t),l=()=>s.withResolvers();let p=0;const f=new Map,u=(e,t)=>class extends e{constructor(e,...s){super(e,...s),e instanceof t&&f.set(this,[p++,0,l()])}},g=new WeakSet,d=e=>(g.add(e),e),y=(e,t)=>{const{data:s}=e,n=r(s)&&(s.at(0)===t||0===s.at(1)&&!t);return n&&(e.stopImmediatePropagation(),e.preventDefault()),n},h=e=>null!==e&&"object"==typeof e&&!g.has(e),w=new WeakMap,v=(t,s,r)=>{if(f.has(t))s.set(t,f.get(t)[0]);else if(!(t instanceof c||t instanceof e))for(const e of o(t))h(e)&&!r.has(e)&&(r.add(e),v(e,s,r))},m=(...e)=>({value:new s((t=>{let s=new Worker("data:application/javascript,onmessage%3De%3D%3EpostMessage(!Atomics.wait(...e.data))");s.onmessage=()=>t("ok"),s.postMessage(e)}))}),M=(e,t,s)=>{for(const[s,r]of t)w.set(s,[r,e.currentTarget]);(({currentTarget:e,type:t,origin:s,lastEventId:r,source:n,ports:a},o)=>{e.dispatchEvent(new MessageEvent(t,{data:o,origin:s,lastEventId:r,source:n,ports:a}))})(e,s)};let{BigInt64Array:A,Int32Array:E,SharedArrayBuffer:k,Worker:x}=globalThis,T=e=>e,b=!1;const I=e=>({...e,type:"module"});try{new k(4),x=class extends x{constructor(e,t){super(e,I(t))}},i.waitAsync||(i.waitAsync=m)}catch(t){const s=crypto.randomUUID(),r=new Map,n=(e,t,s,...r)=>{e.addEventListener(t,s,...r)},a=({serviceWorker:e},t,a)=>{let o,c=!0;n(e,"message",(e=>{if(y(e,s)){const[t,n,a]=e.data,c=[n,a].join(","),i=e=>{r.delete(c),o.postMessage([s,n,a,e])},p=r.get(c);if(p)i(p);else{const{promise:e,resolve:t}=l();r.set(c,t),e.then(i)}}})),e.getRegistration(t).then((s=>s??e.register(t))).then((function t(s){c=c&&!!e.controller,o=s.installing||s.waiting||s.active,"activated"===o.state?c?a():location.reload():n(o,"statechange",(()=>t(s)),{once:!0})}))};T=d,b=!0,i.notify=(e,t)=>{const[n,a]=(e=>w.get(e))(e),o=[n,t].join(","),c=r.get(o);return c?c(e):r.set(o,e),a.postMessage([s,1,e,n,t]),0},i.waitAsync=(e,...t)=>{const[s,r]=((e,t)=>{const s=f.get(e),[r,n,{promise:a}]=s;return s[1]=t,[r,a]})(e,...t);return{value:r}},k=class extends e{},A=u(A,k),E=u(E,k);let o=null;x=class extends x{constructor(e,t){let r=t?.serviceWorker||"";if(r){if(r=new URL(r,location.href).href,t={...t,serviceWorker:r},!o){const{promise:e,resolve:t}=l();a(navigator,r,t),o=e}o.then((()=>super.postMessage([s,3])))}super(e,I(t)),super.postMessage([s,0,t]),n(this,"message",(e=>{if(y(e,s)){const[t,s,...r]=e.data;switch(s){case 1:((e,t,s)=>{for(const[r,[n,a,{resolve:o}]]of f)if(t===n&&s===a){for(let t=0;t<e.length;t++)r[t]=e[t];f.delete(r),o("ok");break}})(...r);break;case 2:M(e,...r)}}}))}postMessage(e,...t){return super.postMessage(((e,t)=>{const s=new Map;return h(t)&&v(t,s,new Set),s.size?[e,2,s,t]:t})(s,e),...t)}}}const{BYTES_PER_ELEMENT:U}=Int32Array,{BYTES_PER_ELEMENT:W}=Uint16Array,{notify:S}=i,D=new TextDecoder("utf-16"),P=new WeakSet,j=(...e)=>(P.add(e),e);let B="";let L=0;const R=([e,t,s,r,n,a,o,c,i],l)=>(...p)=>{let f=""!==B,u=0;f&&"="!==B[0]&&"-"!==B[0]&&(u=((e,t)=>setTimeout(console.warn,3e3,`💀🔒 - proxy.${e}() in proxy.${t}()`))(l,B));const g=L++;let d=[];P.has(p.at(-1)||d)&&P.delete(d=p.pop());const y=s(c?p.map(c):p);let h=t(2*U);return o([e,2,l,g,h,y,r],{transfer:d}),i(h,0).value.then((()=>{f&&clearTimeout(u);const s=h[1];if(!s)return;const r=W*s;return h=t(r+r%U),o([e,1,g,h]),i(h,0).value.then((()=>{const e=new Uint16Array(h.buffer),t=a?e.subarray(0,s):e.slice(0,s);return n(D.decode(t))}))}))};var _=({parse:e,stringify:t,transform:s}=JSON)=>{const r=((e,t)=>async(s,r,[n,a,o,c,i])=>{i&&(B=n);try{const n=await s(...c);if(void 0!==n){const s=e(t?t(n):n);r.set(a,s),o[1]=s.length}}finally{i&&(B=""),o[0]=1,S(o,0)}})(t,s);return{Worker:class extends x{constructor(t,n){const a=crypto.randomUUID(),o=new Map,c=new Map;super(t,n),this.proxy=((e,t)=>new Proxy(t,{get:(t,s)=>{let r;return"then"!==s&&(r=t.get(s),r||(r=R(e,s),t.set(s,r))),r},set:(e,t,s)=>"then"!==t&&!!e.set(t,s)}))([a,e=>new E(new k(e)),T,!1,e,b,(...e)=>this.postMessage(...e),s,i.waitAsync],o),this.postMessage(T([a,0,n])),this.addEventListener("message",(e=>{if(y(e,a)){const[t,s,...n]=e.data;switch(s){case 2:((e,t,s,r)=>{const[n]=r,a=s.get(n);if(!a)throw new Error(`Unknown proxy.${n}()`);e(a,t,r)})(r,c,o,n);break;case 1:((e,[t,s])=>{const r=e.get(t);e.delete(t);for(let e=new Uint16Array(s.buffer),t=0,{length:n}=r;t<n;t++)e[t]=r.charCodeAt(t);S(s,0)})(c,n)}}}))}},polyfill:b,transfer:j}};export{_ as default};