Socket
Socket
Sign inDemoInstall

mps3

Package Overview
Dependencies
0
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.80 to 0.0.81

2

dist/mps3.js

@@ -1,1 +0,1 @@

async function x($,z){const W=await crypto.subtle.importKey("raw",typeof $==="string"?k.encode($):$,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",W,k.encode(z))}async function s($){return crypto.subtle.digest("SHA-256",typeof $==="string"?k.encode($):$)}var v=function($){return Array.prototype.map.call(new Uint8Array($),(z)=>("0"+z.toString(16)).slice(-2)).join("")},e=function($){return $.replace(/[!'()*]/g,(z)=>"%"+z.charCodeAt(0).toString(16).toUpperCase())},C0=function($,z){const{hostname:W,pathname:X}=$;if(W.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(W.endsWith(".backblazeb2.com")){const Q=W.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);return Q!=null?["s3",Q[1]]:["",""]}const J=W.replace("dualstack.","").match(/([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(?:\.cn)?$/);let[Z,D]=(J||["",""]).slice(1,3);if(D==="us-gov")D="us-gov-west-1";else if(D==="s3"||D==="s3-accelerate")D="us-east-1",Z="s3";else if(Z==="iot")if(W.startsWith("iot."))Z="execute-api";else if(W.startsWith("data.jobs.iot."))Z="iot-jobs-data";else Z=X==="/mqtt"?"iotdevicegateway":"iotdata";else if(Z==="autoscaling"){const Q=(z.get("X-Amz-Target")||"").split(".")[0];if(Q==="AnyScaleFrontendService")Z="application-autoscaling";else if(Q==="AnyScaleScalingPlannerFrontendService")Z="autoscaling-plans"}else if(D==null&&Z.startsWith("s3-"))D=Z.slice(3).replace(/^fips-|^external-1/,""),Z="s3";else if(Z.endsWith("-fips"))Z=Z.slice(0,-5);else if(D&&/-\d$/.test(Z)&&!/-\d$/.test(D))[Z,D]=[D,Z];return[H0[Z]||Z,D]},k=new TextEncoder,H0={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"},U0=new Set(["authorization","content-type","content-length","user-agent","presigned-expires","expect","x-amzn-trace-id","range","connection"]);class g{constructor({accessKeyId:$,secretAccessKey:z,sessionToken:W,service:X,region:J,cache:Z,retries:D,initRetryMs:Q}){if($==null)throw new TypeError("accessKeyId is a required option");if(z==null)throw new TypeError("secretAccessKey is a required option");this.accessKeyId=$,this.secretAccessKey=z,this.sessionToken=W,this.service=X,this.region=J,this.cache=Z||new Map,this.retries=D!=null?D:10,this.initRetryMs=Q||50}async sign($,z){if($ instanceof Request){const{method:J,url:Z,headers:D,body:Q}=$;if(z=Object.assign({method:J,url:Z,headers:D},z),z.body==null&&D.has("Content-Type"))z.body=Q!=null&&D.has("X-Amz-Content-Sha256")?Q:await $.clone().arrayBuffer();$=Z}const W=new $0(Object.assign({url:$},z,this,z&&z.aws)),X=Object.assign({},z,await W.sign());delete X.aws;try{return new Request(X.url.toString(),X)}catch(J){if(J instanceof TypeError)return new Request(X.url.toString(),Object.assign({duplex:"half"},X));throw J}}async fetch($,z){for(let W=0;W<=this.retries;W++){const X=fetch(await this.sign($,z));if(W===this.retries)return X;const J=await X;if(J.status<500&&J.status!==429)return J;await new Promise((Z)=>setTimeout(Z,Math.random()*this.initRetryMs*Math.pow(2,W)))}throw new Error("An unknown error occurred, ensure retries is not negative")}}class $0{constructor({method:$,url:z,headers:W,body:X,accessKeyId:J,secretAccessKey:Z,sessionToken:D,service:Q,region:Y,cache:O,datetime:H,signQuery:U,appendSessionToken:L,allHeaders:F,singleEncode:_}){if(z==null)throw new TypeError("url is a required option");if(J==null)throw new TypeError("accessKeyId is a required option");if(Z==null)throw new TypeError("secretAccessKey is a required option");this.method=$||(X?"POST":"GET"),this.url=new URL(z),this.headers=new Headers(W||{}),this.body=X,this.accessKeyId=J,this.secretAccessKey=Z,this.sessionToken=D;let q,K;if(!Q||!Y)[q,K]=C0(this.url,this.headers);if(this.service=Q||q||"",this.region=Y||K||"us-east-1",this.cache=O||new Map,this.datetime=H||(new Date()).toISOString().replace(/[:-]|\.\d{3}/g,""),this.signQuery=U,this.appendSessionToken=L||this.service==="iotdevicegateway",this.headers.delete("Host"),this.service==="s3"&&!this.signQuery&&!this.headers.has("X-Amz-Content-Sha256"))this.headers.set("X-Amz-Content-Sha256","UNSIGNED-PAYLOAD");const G=this.signQuery?this.url.searchParams:this.headers;if(G.set("X-Amz-Date",this.datetime),this.sessionToken&&!this.appendSessionToken)G.set("X-Amz-Security-Token",this.sessionToken);if(this.signableHeaders=["host",...this.headers.keys()].filter((P)=>F||!U0.has(P)).sort(),this.signedHeaders=this.signableHeaders.join(";"),this.canonicalHeaders=this.signableHeaders.map((P)=>P+":"+(P==="host"?this.url.host:(this.headers.get(P)||"").replace(/\s+/g," "))).join("\n"),this.credentialString=[this.datetime.slice(0,8),this.region,this.service,"aws4_request"].join("/"),this.signQuery){if(this.service==="s3"&&!G.has("X-Amz-Expires"))G.set("X-Amz-Expires","86400");G.set("X-Amz-Algorithm","AWS4-HMAC-SHA256"),G.set("X-Amz-Credential",this.accessKeyId+"/"+this.credentialString),G.set("X-Amz-SignedHeaders",this.signedHeaders)}if(this.service==="s3")try{this.encodedPath=decodeURIComponent(this.url.pathname.replace(/\+/g," "))}catch(P){this.encodedPath=this.url.pathname}else this.encodedPath=this.url.pathname.replace(/\/+/g,"/");if(!_)this.encodedPath=encodeURIComponent(this.encodedPath).replace(/%2F/g,"/");this.encodedPath=e(this.encodedPath);const o=new Set;this.encodedSearch=[...this.url.searchParams].filter(([P])=>{if(!P)return!1;if(this.service==="s3"){if(o.has(P))return!1;o.add(P)}return!0}).map((P)=>P.map((R)=>e(encodeURIComponent(R)))).sort(([P,R],[t,r])=>P<t?-1:P>t?1:R<r?-1:R>r?1:0).map((P)=>P.join("=")).join("&")}async sign(){if(this.signQuery){if(this.url.searchParams.set("X-Amz-Signature",await this.signature()),this.sessionToken&&this.appendSessionToken)this.url.searchParams.set("X-Amz-Security-Token",this.sessionToken)}else this.headers.set("Authorization",await this.authHeader());return{method:this.method,url:this.url,headers:this.headers,body:this.body}}async authHeader(){return["AWS4-HMAC-SHA256 Credential="+this.accessKeyId+"/"+this.credentialString,"SignedHeaders="+this.signedHeaders,"Signature="+await this.signature()].join(", ")}async signature(){const $=this.datetime.slice(0,8),z=[this.secretAccessKey,$,this.region,this.service].join();let W=this.cache.get(z);if(!W){const X=await x("AWS4"+this.secretAccessKey,$),J=await x(X,this.region),Z=await x(J,this.service);W=await x(Z,"aws4_request"),this.cache.set(z,W)}return v(await x(W,await this.stringToSign()))}async stringToSign(){return["AWS4-HMAC-SHA256",this.datetime,this.credentialString,v(await s(await this.canonicalString()))].join("\n")}async canonicalString(){return[this.method.toUpperCase(),this.encodedPath,this.encodedSearch,this.canonicalHeaders+"\n",this.signedHeaders,await this.hexBodyHash()].join("\n")}async hexBodyHash(){let $=this.headers.get("X-Amz-Content-Sha256")||(this.service==="s3"&&this.signQuery?"UNSIGNED-PAYLOAD":null);if($==null){if(this.body&&typeof this.body!=="string"&&!("byteLength"in this.body))throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");$=v(await s(this.body||""))}return $}}var A=()=>crypto.randomUUID(),z0=($)=>p($,10);var C=($)=>`${$.bucket}/${$.key}`;var F0=($,z)=>{const W=Math.ceil(z/5);return $.toString(32).padStart(W,"0")};var p=($,z)=>{const W=Math.pow(2,z)-1;return F0(W-$,z)},W0=($,z)=>{const W=Math.pow(2,z)-1,X=parseInt($,32);return W-X};var h=($=0)=>p($,42);var T=async($)=>{const z=Date.now();return[await $,Date.now()-z]},f=($,z)=>{if(z.adaptiveClock)return T($).then(([W,X])=>{if(W.status!==200)return W;const J=W.headers.get("date");if(J){let Z=0;const D=new Date(J).getTime(),Q=Date.now()+z.clockOffset;if(Q<D-X)Z=D-Q-X;else if(Q>D+1000+X)Z=D+1000-Q+X;if(Z>0)z.clockOffset=z.clockOffset+Z;if(Z>0)console.log("latency",X,"error",Z,"local_time",Q,"server_time",D,"config.clockOffset",z.clockOffset)}return W});return $};var X0=($,z)=>{const W=z.parseFromString($,"text/xml");if(!W)throw new Error(`Invalid XML: ${$}`);const X=W.getElementsByTagName("Contents"),J=(Z,D)=>{const Q=Z.getElementsByTagName(D)[0]?.textContent;return Q?decodeURIComponent(Q.replace(/\+/g," ")):void 0};return{$metadata:{},Contents:Array.from(X).map((Z)=>{const D=J(Z,"LastModified");return{ETag:J(Z,"ETag"),Key:J(Z,"Key"),LastModified:D?new Date(D):void 0}}),KeyCount:parseInt(J(W,"KeyCount")),ContinuationToken:J(W,"ContinuationToken"),NextContinuationToken:J(W,"NextContinuationToken"),StartAfter:J(W,"StartAfter")}};var w=async($,{retries:z=Number.MAX_VALUE,delay:W=100,max_delay:X=1e4}={})=>{try{return await $()}catch(J){if(z>0)return await new Promise((Z)=>setTimeout(Z,W)),w($,{retries:z-1,max_delay:X,delay:Math.min(W*1.5,X)});throw J}};class d{$;z;W;constructor($,z,W){this.fetch=$;this.endpoint=z;this.mps3=W}getUrl($,z,W){return`${this.endpoint}/${$}${z?`/${encodeURIComponent(z)}`:""}${W||""}`}async listObjectV2($){for(let z=0;z<10;z++){const W=this.getUrl($.Bucket,void 0,`/?list-type=2&prefix=${$.Prefix}&start-after=${$.StartAfter}`),X=await w(()=>this.fetch(W,{}));if(X.status===200)return X0(await X.text(),this.mps3.config.parser);else if(X.status===429)console.warn("listObjectV2: 429, retrying"),await new Promise((J)=>setTimeout(J,1000));else throw new Error(`Unexpected response: ${X.status} ${await X.text()}`)}throw new Error("Cannot contact server")}async putObject({Bucket:$,Key:z,Body:W,ChecksumSHA256:X}){const J=this.getUrl($,z),Z=await w(()=>f(this.fetch(J,{method:"PUT",body:W,headers:{"Content-Type":"application/json"}}),this.mps3.config));if(Z.status!==200)throw new Error(`Failed to PUT: ${await Z.text()}`);return{$metadata:{httpStatusCode:Z.status},Date:new Date(Z.headers.get("date")),ETag:Z.headers.get("ETag"),...Z.headers.get("x-amz-version-id")&&{VersionId:Z.headers.get("x-amz-version-id")}}}async deleteObject({Bucket:$,Key:z}){return{$metadata:{httpStatusCode:(await w(()=>this.fetch(this.getUrl($,z),{method:"DELETE"}))).status}}}async getObject({Bucket:$,Key:z,VersionId:W,IfNoneMatch:X}){const J=this.getUrl($,z,W?`?versionId=${W}`:""),Z=await w(()=>f(this.fetch(J,{method:"GET",headers:{"If-None-Match":X}}),this.mps3.config));switch(Z.status){case 304:throw new Error("304");case 404:return{$metadata:{httpStatusCode:404}};case 403:throw new Error("Access denied");default:{let D;const Q=Z.headers.get("content-type"),Y=await Z.text();if(Q==="application/json"||Y&&Y!=="")try{D=JSON.parse(Y)}catch(O){throw new Error(`Failed to parse response as JSON ${J}`)}return{$metadata:{httpStatusCode:Z.status},Body:D,ETag:Z.headers.get("ETag"),...Z.headers.get("x-amz-version-id")&&{VersionId:Z.headers.get("x-amz-version-id")}}}}}}class M{key;_vals;_keys;constructor($,z){if(this.key=$,this._vals=new Map,this._keys=new Map,z)for(let[W,X]of z)this.set(W,X)}get size(){return this._vals.size}set($,z){const W=this.key($);return this._vals.set(W,z),this._keys.set(W,$),this}get($){return this._vals.get(this.key($))}delete($){const z=this.key($);return this._keys.delete(z),this._vals.delete(z)}has($){return this._vals.has(this.key($))}values(){return this._vals.values()}keys(){return this._keys.values()}forEach($){return this._vals.forEach((z,W,X)=>$(z,this._keys.get(W)))}}var V=function($){return new Promise((z,W)=>{$.oncomplete=$.onsuccess=()=>z($.result),$.onabort=$.onerror=()=>W($.error)})},N=function($,z){const W=indexedDB.open($);W.onupgradeneeded=()=>W.result.createObjectStore(z);const X=V(W);return(J,Z)=>X.then((D)=>Z(D.transaction(z,J).objectStore(z)))},I=function(){if(!y)y=N("keyval-store","keyval");return y},j=function($,z=I()){return z("readonly",(W)=>V(W.get($)))},B=function($,z,W=I()){return W("readwrite",(X)=>{return X.put(z,$),V(X.transaction)})};var J0=function($,z=I()){return z("readonly",(W)=>Promise.all($.map((X)=>V(W.get(X)))))};var Z0=function($,z=I()){return z("readwrite",(W)=>{return W.delete($),V(W.transaction)})},S=function($,z=I()){return z("readwrite",(W)=>{return $.forEach((X)=>W.delete(X)),V(W.transaction)})};var B0=function($,z){return $.openCursor().onsuccess=function(){if(!this.result)return;z(this.result),this.result.continue()},V($.transaction)},b=function($=I()){return $("readonly",(z)=>{if(z.getAllKeys)return V(z.getAllKeys());const W=[];return B0(z,(X)=>W.push(X.key)).then(()=>W)})};var y;var E0=6,D0=($)=>`write-${$.toString().padStart(E0,"0")}`;class u{session=A();proposedOperations=new Map;operationLabels=new Map;db;lastIndex=0;load=void 0;op=0;constructor($){this.db=$}async propose($,z,W=!1){if(this.proposedOperations.set($,[z,this.op++]),this.db){if(this.load&&!W)await this.load,this.proposedOperations.delete($),this.proposedOperations.set($,[z,this.op-1]);this.lastIndex++;const X=D0(this.lastIndex);$[this.session]=this.lastIndex,await B(X,[...z.entries()].map(([J,Z])=>[JSON.stringify(J),Z]),this.db),console.log(`STORE ${X} ${JSON.stringify([...z.entries()])}`)}}async label($,z,W=!1){if(this.operationLabels.set(z,$),this.db){if(this.load&&!W)await this.load;const X=$[this.session];if(X===void 0)throw new Error("Cannot label an unproposed operation");const J=`label-${X}`;await B(J,z,this.db),console.log(`STORE ${J} ${z}`)}}async confirm($,z=!1){if(this.operationLabels.has($)){const W=this.operationLabels.get($);if(this.proposedOperations.delete(W),this.operationLabels.delete($),this.db){if(this.load&&!z)await this.load;const X=W[this.session],J=[D0(X),`label-${X}`];await S(J,this.db),console.log(`DEL ${J}`)}}}async cancel($,z=!1){if(this.operationLabels.forEach((W,X)=>{if(W===$)this.operationLabels.delete(X)}),this.proposedOperations.delete($),this.db){if(this.load&&!z)await this.load;const W=$[this.session];await S([`write-${W}`,`label-${W}`],this.db)}}async flatten(){if(this.load)await this.load;const $=new M(C);return this.proposedOperations.forEach(([z,W])=>{z.forEach((X,J)=>{$.set(J,[X,W])})}),$}async restore($,z){return this.db=$,this.proposedOperations.clear(),this.operationLabels.clear(),this.lastIndex=0,this.load=new Promise(async(W)=>{const J=(await b(this.db)).filter((D)=>D.startsWith("write-")).sort();console.log("RESTORE",J);const Z=await J0(J,this.db);for(let D=0;D<J.length;D++){const Q=parseInt(J[D].split("-")[1]);this.lastIndex=Math.max(this.lastIndex,Q)}for(let D=0;D<J.length;D++){const Q=J[D],Y=parseInt(Q.split("-")[1]),O=Z[D].map(([L,F])=>[JSON.parse(L),F]),H=await j(`label-${Y}`,this.db);if(!O)continue;const U=new Map(O);await z(U,H),await S([`write-${Y}`,`label-${Y}`],this.db)}W(void 0)}),this.load}}function c($,z){if(z===void 0)return $;if(z===null)return;if(typeof z!=="object"||typeof $!=="object")return z;const W=typeof $==="object"?{...$}:{};for(let X in z)if(z[X]===null)delete W[X];else W[X]=c($[X],z[X]);return W}var l=($)=>JSON.parse(JSON.stringify($));var i="manifest",n={files:{},update:{}};class E{$;session_id=A().substring(0,3);latest_key=".";latest_state=l(n);loading;cache;db;latest_timestamp=0;writes=0;static manifestRegex=/@([0-9a-z]+)_[0-9a-z]+_[0-9a-z]{2}$/;constructor($){this.manifest=$}static manifestTimestamp=($)=>{const z=$.match(E.manifestRegex);if(!z)return 0;return W0(z[1],42)};static isValid($,z){if(!$.match(E.manifestRegex))return console.warn(`Rejecting manifest key ${$}`),!1;if(z===void 0)return!0;const X=this.manifestTimestamp($),J=z,Z=Math.abs(X-J.getTime())<5000;if(!Z)console.warn(`Clock skew detected ${$} vs ${J.getTime()}`);return Z}async restore($){this.db=$,this.loading=j(i,$).then((z)=>{if(z)this.latest_state=z,this.manifest.service.config.log(`RESTORE ${i}`)})}async getLatest(){if(this.loading)await this.loading;if(this.loading=void 0,!this.manifest.service.config.online)return this.latest_state;try{if(this.manifest.service.config.minimizeListObjectsCalls){if((await this.manifest.service._getObject({operation:"POLL_LATEST_CHANGE",ref:this.manifest.ref,ifNoneMatch:this.cache?.etag,useCache:!1})).$metadata.httpStatusCode===304)return this.latest_state}const $=`${this.manifest.ref.key}@${h(Date.now()+this.manifest.service.config.clockOffset+1e4)}`,[z,W]=await T(this.manifest.service.s3ClientLite.listObjectV2({Bucket:this.manifest.ref.bucket,Prefix:this.manifest.ref.key+"@",StartAfter:$})),X=z.Contents?.filter((Z)=>{if(!E.isValid(Z.Key,Z.LastModified)){if(this.manifest.service.config.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:Z.Key}});return!1}return!0});if(this.manifest.service.config.log(`${W}ms LIST ${this.manifest.ref.bucket}/${this.manifest.ref.key} from ${$}`),X===void 0)return this.latest_state=l(n),this.latest_state;if(this.latest_timestamp=Math.max(this.latest_timestamp,E.manifestTimestamp(this.latest_key)),X.length>0){this.latest_key=X[0].Key;const Z=await this.manifest.service._getObject({operation:"GET_LATEST",ref:{bucket:this.manifest.ref.bucket,key:this.latest_key}});this.latest_state=Z.data}const J=`${this.manifest.ref.key}@${h(Math.max(E.manifestTimestamp(this.latest_key)-5000,0))}`;for(let Z=X.length-1;Z>=0;Z--){const D=X[Z].Key;if(D>this.latest_key&&D>J){if(this.manifest.service.config.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:D}});continue}const Q=await this.manifest.service._getObject({operation:"REPLAY",ref:{bucket:this.manifest.ref.bucket,key:D}}),Y=D.substring(D.lastIndexOf("@")+1);this.latest_state=c(this.latest_state,Q.data?.update),this.manifest.observeVersionId(Y)}if(this.db)B(i,this.latest_state,this.db);return this.latest_state}catch($){if($.name==="NoSuchKey")return this.latest_state=n,this.latest_state;else throw $}}updateContent($,z,W){const X=()=>h(Math.max(Date.now()+this.manifest.service.config.clockOffset,this.latest_timestamp))+"_"+this.session_id+"_"+z0(this.writes++);let J=X();const Z=this.manifest.operationQueue.propose(z,$,W.isLoad),D=Z.then(async()=>{try{const Q=await z;let Y,O,H=!1;do{const U=await this.getLatest();U.update={files:{}};for(let[F,_]of Q){const q=C(F);if(_){const K={version:_};U.update.files[q]=K}else U.update.files[q]=null}O=this.manifest.ref.key+"@"+J,this.manifest.operationQueue.label(z,J,W.isLoad);const L=await this.manifest.service._putObject({operation:"PUT_MANIFEST",ref:{key:O,bucket:this.manifest.ref.bucket},value:U});if(this.manifest.service.config.adaptiveClock&&!E.isValid(O,L.Date))this.manifest.service.config.clockOffset=L.Date.getTime()-Date.now()+L.latency,console.log(this.manifest.service.config.clockOffset),J=X(),H=!0;else H=!1}while(H);if(this.manifest.service.config.minimizeListObjectsCalls)Y=await this.manifest.service._putObject({operation:"TOUCH_LATEST_CHANGE",ref:{key:this.manifest.ref.key,bucket:this.manifest.ref.bucket},value:""});return this.manifest.poll(),Y}catch(Q){throw console.error(Q),this.manifest.operationQueue.cancel(z,W.isLoad),Q}});if(W.await==="local")return Z;else return D}}class Q0{$;z;W;queue=Promise.resolve();constructor($,z,W){this.ref=$;this.handler=z;this.lastVersion=W}notify($,z,W){this.queue=this.queue.then(()=>W).then((X)=>{if(z!==this.lastVersion)$.config.log(`${$.config.label} NOTIFY ${C(this.ref)} ${z}`),this.lastVersion=z,this.handler(X)})}}class a{$;z;subscribers=new Set;poller;pollInProgress=!1;syncer=new E(this);operationQueue=new u;constructor($,z){this.service=$;this.ref=z;console.log("Create manifest",C(z))}load($){this.syncer.restore($),this.operationQueue.restore($,async(z,W)=>{if(!W)await this.service._putAll(z,{manifests:[this.ref],await:"local",isLoad:!0});else await this.updateContent(z,Promise.resolve(new Map([[this.ref,W]])),{await:"local",isLoad:!0})})}observeVersionId($){this.operationQueue.confirm($)}async poll(){if(this.pollInProgress)return;if(this.pollInProgress=!0,this.subscriberCount===0&&this.poller)clearInterval(this.poller),this.poller=void 0;if(this.subscriberCount>0&&!this.poller)this.poller=setInterval(()=>this.poll(),this.service.config.pollFrequency);const $=await this.syncer.getLatest();if($===void 0){this.pollInProgress=!1;return}const z=await this.operationQueue.flatten();this.subscribers.forEach(async(W)=>{if(z.has(W.ref)){const[X,J]=z.get(W.ref);W.notify(this.service,`local-${J}`,Promise.resolve(X))}else{const X=$.files[C(W.ref)];if(X){const J=this.service._getObject({operation:"GET_CONTENT",ref:W.ref,version:X.version});W.notify(this.service,X.version,J.then((Z)=>Z.data))}else if(X===null)W.notify(this.service,void 0,Promise.resolve(void 0))}}),this.pollInProgress=!1}updateContent($,z,W){return this.syncer.updateContent($,z,W)}async getVersion($){return(await this.syncer.getLatest()).files[C($)]?.version}subscribe($,z){this.service.config.log(`SUBSCRIBE ${C($)} ${this.subscriberCount+1}`);const W=new Q0($,z);return this.subscribers.add(W),()=>this.subscribers.delete(W)}get subscriberCount(){return this.subscribers.size}}var Y0=async($,z)=>{const W=new URL($),X=new URLSearchParams(W.search),J=W.pathname.split("/"),Z=J[1],D=J.slice(2).join("/"),Q=N(Z,"v0");let Y,O=200;if(X.get("list-type")){const H=encodeURIComponent(X.get("prefix")||""),U=encodeURIComponent(X.get("start-after")||"");Y=`<ListBucketResult>${(await b(Q)).filter((F)=>`${F}`.startsWith(H)&&`${F}`>U).map((F)=>`<Contents><Key>${F}</Key></Contents>`)}</ListBucketResult>`}else if(z?.method==="GET")Y=await j(D,Q),O=Y===void 0?404:200;else if(z?.method==="PUT")Y=await z.body,await B(D,Y,Q);else if(z?.method==="DELETE")await Z0(D,Q);else throw new Error;return new Response(Y,{status:O})};async function O0($){const z=(new TextEncoder()).encode($),W=await crypto.subtle.digest("SHA-256",z);return btoa(String.fromCharCode(...new Uint8Array(W)))}class P0{static LOCAL_ENDPOINT="indexdb:";config;s3ClientLite;manifests=new M(C);memCache=new M(($)=>`${$.Bucket}${$.Key}${$.VersionId}${$.IfNoneMatch}`);diskCache;endpoint;constructor($){if(this.config={...$,label:$.label||"default",useChecksum:$.useChecksum===!1?!1:!0,autoclean:$.autoclean===!1?!1:!0,online:$.online===!1?!1:!0,offlineStorage:$.offlineStorage===!1?!1:!0,useVersioning:$.useVersioning||!1,pollFrequency:$.pollFrequency||1000,clockOffset:Math.floor($.clockOffset)||0,adaptiveClock:$.adaptiveClock===!1?!1:!0,minimizeListObjectsCalls:$.minimizeListObjectsCalls===!1?!1:!0,parser:$.parser||new DOMParser,defaultManifest:{bucket:$.defaultManifest?.bucket||$.defaultBucket,key:typeof $.defaultManifest=="string"?$.defaultManifest:$.defaultManifest?.key||"manifest.json"},log:(...W)=>($.log||console.log)(this.config.label,...W)},this.config.s3Config?.credentials instanceof Function)throw Error("We can't do that yet");this.endpoint=$.s3Config.endpoint||`https://s3.${$.s3Config.region}.amazonaws.com`;let z;if(this.config.s3Config?.credentials){const W=new g({accessKeyId:this.config.s3Config.credentials.accessKeyId,secretAccessKey:this.config.s3Config.credentials.secretAccessKey,sessionToken:this.config.s3Config.credentials.sessionToken,region:this.config.s3Config.region||"us-east-1",service:"s3",retries:0});z=(...X)=>W.fetch(...X)}else if(this.endpoint==P0.LOCAL_ENDPOINT)z=Y0;else z=(global||window).fetch.bind(global||window);if(this.config.offlineStorage){const W=`mps3-${this.config.label}`;this.diskCache=N(W,"v0")}this.s3ClientLite=new d(this.config.online?z:()=>new Promise(()=>{}),this.endpoint,this)}getOrCreateManifest($){if(!this.manifests.has($)){const z=new a(this,$);if(this.manifests.set($,z),this.config.offlineStorage){const W=`mps3-${this.config.label}-${$.bucket}-${$.key}`,X=N(W,"v0");this.config.log(`Restoring manifest from ${W}`),z.load(X)}}return this.manifests.get($)}async get($,z={}){const W={...this.config.defaultManifest,...z.manifest},X=this.getOrCreateManifest(W),J={bucket:$.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof $==="string"?$:$.key},Z=await X.operationQueue.flatten();if(Z.has(J))return this.config.log(`GET (cached) ${J} ${Z.get(J)}`),Z.get(J)[0];const D=await X.getVersion(J);if(D===void 0)return;return(await this._getObject({operation:"GET",ref:J,version:D})).data}async _getObject($){let z;if(this.config.useVersioning)z={Bucket:$.ref.bucket,Key:$.ref.key,IfNoneMatch:$.ifNoneMatch,...$.version&&{VersionId:$.version}};else z={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,IfNoneMatch:$.ifNoneMatch};const W=`${z.Bucket}${z.Key}${z.VersionId}`;if($.useCache!==!1){if(this.memCache.has(z))return this.memCache.get(z);if(this.diskCache){const J=await j(W,this.diskCache);if(J)return this.config.log(`${$.operation} (disk cached) ${W}`),this.memCache.set(z,Promise.resolve(J)),J}}if(!this.config.online)throw new Error(`${this.config.label} Offline and value not cached for ${W}`);const X=T(this.s3ClientLite.getObject(z)).then(async([J,Z])=>{const D={$metadata:J.$metadata,ETag:J.ETag,data:J.Body};return this.config.log(`${Z}ms ${$.operation} ${$.ref.bucket}/${$.ref.key}@${$.version} => ${D.VersionId}`),D}).catch((J)=>{if(J?.name==="304")return{$metadata:{httpStatusCode:304},data:void 0};else throw J});if($.useCache!==!1){if(this.memCache.set(z,X),this.diskCache)X.then((J)=>{B(`${z.Bucket}${z.Key}${z.VersionId}`,J,this.diskCache).then(()=>this.config.log(`STORE ${z.Bucket}${z.Key}`))})}return X}async delete($,z={}){return this.putAll(new Map([[$,void 0]]),z)}async put($,z,W={}){return this.putAll(new Map([[$,z]]),W)}async putAll($,z={}){const W=new Map([...$].map(([J,Z])=>[{bucket:J.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof J==="string"?J:J.key},Z])),X=(z?.manifests||[this.config.defaultManifest]).map((J)=>({...this.config.defaultManifest,...J}));return this._putAll(W,{manifests:X,await:z.await||this.config.online?"remote":"local"})}async _putAll($,z){const W=new Map,X=new Promise(async(J,Z)=>{const D=new Map,Q=[];$.forEach((Y,O)=>{if(Y!==void 0){let H=this.config.useVersioning?void 0:A();W.set(O,Y),Q.push(this._putObject({operation:"PUT_CONTENT",ref:O,value:Y,version:H}).then((U)=>{if(this.config.useVersioning)if(U.VersionId===void 0)throw console.error(U),Error(`Bucket ${O.bucket} is not version enabled!`);else H=U.VersionId;D.set(O,H)}))}else Q.push(this._deleteObject({ref:O}).then((H)=>{D.set(O,void 0)}))}),await Promise.all(Q).catch(Z),J(D)});return Promise.all(z.manifests.map((J)=>{return this.getOrCreateManifest(J).updateContent(W,X,{await:z.await,isLoad:z.isLoad===!0})}))}async _putObject($){const z=JSON.stringify($.value,null,2);let W;if(this.config.useVersioning)W={Bucket:$.ref.bucket,Key:$.ref.key,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await O0(z)}};else W={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await O0(z)}};const[X,J]=await T(this.s3ClientLite.putObject(W));if(this.config.log(`${J}ms ${$.operation} ${W.Bucket}/${W.Key} => ${X.VersionId}`),this.diskCache){const Z=`${W.Bucket}${W.Key}${$.version||X.VersionId}`,D=JSON.parse(z);await B(Z,{$metadata:{httpStatusCode:200},etag:X.ETag,data:D},this.diskCache).then(()=>this.config.log(`STORE ${Z}`))}return{...X,latency:J}}async _deleteObject($){const z={Bucket:$.ref.bucket,Key:$.ref.key},[W,X]=await T(this.s3ClientLite.deleteObject(z));return this.config.log(`${X}ms ${$.operation||"DELETE"} ${$.ref.bucket}/${$.ref.key} (${W.$metadata.httpStatusCode})}`),W}subscribe($,z,W){const X={...this.config.defaultManifest,...W?.manifest},J={key:typeof $==="string"?$:$.key,bucket:$.bucket||this.config.defaultBucket||X.bucket},Z=this.getOrCreateManifest(X),D=Z.subscribe(J,z);return this.get(J,{manifest:X}).then((Q)=>{this.config.log(`NOTIFY (initial) ${C(J)}`),queueMicrotask(()=>{z(Q,void 0),Z.poll()})}).catch((Q)=>{z(void 0,Q)}),D}refresh(){return Promise.all([...this.manifests.values()].map(($)=>$.poll()))}get subscriberCount(){return[...this.manifests.values()].reduce(($,z)=>$+z.subscriberCount,0)}}export{P0 as MPS3};
async function w($,z){const J=await crypto.subtle.importKey("raw",typeof $==="string"?k.encode($):$,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",J,k.encode(z))}async function s($){return crypto.subtle.digest("SHA-256",typeof $==="string"?k.encode($):$)}var v=function($){return Array.prototype.map.call(new Uint8Array($),(z)=>("0"+z.toString(16)).slice(-2)).join("")},e=function($){return $.replace(/[!'()*]/g,(z)=>"%"+z.charCodeAt(0).toString(16).toUpperCase())},F0=function($,z){const{hostname:J,pathname:W}=$;if(J.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(J.endsWith(".backblazeb2.com")){const D=J.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);return D!=null?["s3",D[1]]:["",""]}const X=J.replace("dualstack.","").match(/([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(?:\.cn)?$/);let[Z,Q]=(X||["",""]).slice(1,3);if(Q==="us-gov")Q="us-gov-west-1";else if(Q==="s3"||Q==="s3-accelerate")Q="us-east-1",Z="s3";else if(Z==="iot")if(J.startsWith("iot."))Z="execute-api";else if(J.startsWith("data.jobs.iot."))Z="iot-jobs-data";else Z=W==="/mqtt"?"iotdevicegateway":"iotdata";else if(Z==="autoscaling"){const D=(z.get("X-Amz-Target")||"").split(".")[0];if(D==="AnyScaleFrontendService")Z="application-autoscaling";else if(D==="AnyScaleScalingPlannerFrontendService")Z="autoscaling-plans"}else if(Q==null&&Z.startsWith("s3-"))Q=Z.slice(3).replace(/^fips-|^external-1/,""),Z="s3";else if(Z.endsWith("-fips"))Z=Z.slice(0,-5);else if(Q&&/-\d$/.test(Z)&&!/-\d$/.test(Q))[Z,Q]=[Q,Z];return[P0[Z]||Z,Q]},k=new TextEncoder,P0={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"},H0=new Set(["authorization","content-type","content-length","user-agent","presigned-expires","expect","x-amzn-trace-id","range","connection"]);class g{constructor({accessKeyId:$,secretAccessKey:z,sessionToken:J,service:W,region:X,cache:Z,retries:Q,initRetryMs:D}){if($==null)throw new TypeError("accessKeyId is a required option");if(z==null)throw new TypeError("secretAccessKey is a required option");this.accessKeyId=$,this.secretAccessKey=z,this.sessionToken=J,this.service=W,this.region=X,this.cache=Z||new Map,this.retries=Q!=null?Q:10,this.initRetryMs=D||50}async sign($,z){if($ instanceof Request){const{method:X,url:Z,headers:Q,body:D}=$;if(z=Object.assign({method:X,url:Z,headers:Q},z),z.body==null&&Q.has("Content-Type"))z.body=D!=null&&Q.has("X-Amz-Content-Sha256")?D:await $.clone().arrayBuffer();$=Z}const J=new $0(Object.assign({url:$},z,this,z&&z.aws)),W=Object.assign({},z,await J.sign());delete W.aws;try{return new Request(W.url.toString(),W)}catch(X){if(X instanceof TypeError)return new Request(W.url.toString(),Object.assign({duplex:"half"},W));throw X}}async fetch($,z){for(let J=0;J<=this.retries;J++){const W=fetch(await this.sign($,z));if(J===this.retries)return W;const X=await W;if(X.status<500&&X.status!==429)return X;await new Promise((Z)=>setTimeout(Z,Math.random()*this.initRetryMs*Math.pow(2,J)))}throw new Error("An unknown error occurred, ensure retries is not negative")}}class $0{constructor({method:$,url:z,headers:J,body:W,accessKeyId:X,secretAccessKey:Z,sessionToken:Q,service:D,region:O,cache:Y,datetime:P,signQuery:H,appendSessionToken:E,allHeaders:B,singleEncode:_}){if(z==null)throw new TypeError("url is a required option");if(X==null)throw new TypeError("accessKeyId is a required option");if(Z==null)throw new TypeError("secretAccessKey is a required option");this.method=$||(W?"POST":"GET"),this.url=new URL(z),this.headers=new Headers(J||{}),this.body=W,this.accessKeyId=X,this.secretAccessKey=Z,this.sessionToken=Q;let q,K;if(!D||!O)[q,K]=F0(this.url,this.headers);if(this.service=D||q||"",this.region=O||K||"us-east-1",this.cache=Y||new Map,this.datetime=P||(new Date()).toISOString().replace(/[:-]|\.\d{3}/g,""),this.signQuery=H,this.appendSessionToken=E||this.service==="iotdevicegateway",this.headers.delete("Host"),this.service==="s3"&&!this.signQuery&&!this.headers.has("X-Amz-Content-Sha256"))this.headers.set("X-Amz-Content-Sha256","UNSIGNED-PAYLOAD");const G=this.signQuery?this.url.searchParams:this.headers;if(G.set("X-Amz-Date",this.datetime),this.sessionToken&&!this.appendSessionToken)G.set("X-Amz-Security-Token",this.sessionToken);if(this.signableHeaders=["host",...this.headers.keys()].filter((U)=>B||!H0.has(U)).sort(),this.signedHeaders=this.signableHeaders.join(";"),this.canonicalHeaders=this.signableHeaders.map((U)=>U+":"+(U==="host"?this.url.host:(this.headers.get(U)||"").replace(/\s+/g," "))).join("\n"),this.credentialString=[this.datetime.slice(0,8),this.region,this.service,"aws4_request"].join("/"),this.signQuery){if(this.service==="s3"&&!G.has("X-Amz-Expires"))G.set("X-Amz-Expires","86400");G.set("X-Amz-Algorithm","AWS4-HMAC-SHA256"),G.set("X-Amz-Credential",this.accessKeyId+"/"+this.credentialString),G.set("X-Amz-SignedHeaders",this.signedHeaders)}if(this.service==="s3")try{this.encodedPath=decodeURIComponent(this.url.pathname.replace(/\+/g," "))}catch(U){this.encodedPath=this.url.pathname}else this.encodedPath=this.url.pathname.replace(/\/+/g,"/");if(!_)this.encodedPath=encodeURIComponent(this.encodedPath).replace(/%2F/g,"/");this.encodedPath=e(this.encodedPath);const o=new Set;this.encodedSearch=[...this.url.searchParams].filter(([U])=>{if(!U)return!1;if(this.service==="s3"){if(o.has(U))return!1;o.add(U)}return!0}).map((U)=>U.map((R)=>e(encodeURIComponent(R)))).sort(([U,R],[t,r])=>U<t?-1:U>t?1:R<r?-1:R>r?1:0).map((U)=>U.join("=")).join("&")}async sign(){if(this.signQuery){if(this.url.searchParams.set("X-Amz-Signature",await this.signature()),this.sessionToken&&this.appendSessionToken)this.url.searchParams.set("X-Amz-Security-Token",this.sessionToken)}else this.headers.set("Authorization",await this.authHeader());return{method:this.method,url:this.url,headers:this.headers,body:this.body}}async authHeader(){return["AWS4-HMAC-SHA256 Credential="+this.accessKeyId+"/"+this.credentialString,"SignedHeaders="+this.signedHeaders,"Signature="+await this.signature()].join(", ")}async signature(){const $=this.datetime.slice(0,8),z=[this.secretAccessKey,$,this.region,this.service].join();let J=this.cache.get(z);if(!J){const W=await w("AWS4"+this.secretAccessKey,$),X=await w(W,this.region),Z=await w(X,this.service);J=await w(Z,"aws4_request"),this.cache.set(z,J)}return v(await w(J,await this.stringToSign()))}async stringToSign(){return["AWS4-HMAC-SHA256",this.datetime,this.credentialString,v(await s(await this.canonicalString()))].join("\n")}async canonicalString(){return[this.method.toUpperCase(),this.encodedPath,this.encodedSearch,this.canonicalHeaders+"\n",this.signedHeaders,await this.hexBodyHash()].join("\n")}async hexBodyHash(){let $=this.headers.get("X-Amz-Content-Sha256")||(this.service==="s3"&&this.signQuery?"UNSIGNED-PAYLOAD":null);if($==null){if(this.body&&typeof this.body!=="string"&&!("byteLength"in this.body))throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");$=v(await s(this.body||""))}return $}}var T=()=>crypto.randomUUID(),z0=($)=>p($,10);var F=($)=>`${$.bucket}/${$.key}`;var B0=($,z)=>{const J=Math.ceil(z/5);return $.toString(32).padStart(J,"0")};var p=($,z)=>{const J=Math.pow(2,z)-1;return B0(J-$,z)},J0=($,z)=>{const J=Math.pow(2,z)-1,W=parseInt($,32);return J-W};var h=($=0)=>p($,42);var N=async($)=>{const z=Date.now();return[await $,Date.now()-z]},f=($,z)=>{if(z.adaptiveClock)return N($).then(([J,W])=>{if(J.status!==200)return J;const X=J.headers.get("date");if(X){let Z=0;const Q=new Date(X).getTime(),D=Date.now()+z.clockOffset;if(D<Q-W)Z=Q-D-W;else if(D>Q+1000+W)Z=Q+1000-D+W;if(Z>0)z.clockOffset=z.clockOffset+Z;if(Z>0)console.log("latency",W,"error",Z,"local_time",D,"server_time",Q,"config.clockOffset",z.clockOffset)}return J});return $};var W0=($,z)=>{const J=z.parseFromString($,"text/xml");if(!J)throw new Error(`Invalid XML: ${$}`);const W=J.getElementsByTagName("Contents"),X=(Z,Q)=>{const D=Z.getElementsByTagName(Q)[0]?.textContent;return D?decodeURIComponent(D.replace(/\+/g," ")):void 0};return{$metadata:{},Contents:Array.from(W).map((Z)=>{const Q=X(Z,"LastModified");return{ETag:X(Z,"ETag"),Key:X(Z,"Key"),LastModified:Q?new Date(Q):void 0}}),KeyCount:parseInt(X(J,"KeyCount")),ContinuationToken:X(J,"ContinuationToken"),NextContinuationToken:X(J,"NextContinuationToken"),StartAfter:X(J,"StartAfter")}};var x=async($,{retries:z=Number.MAX_VALUE,delay:J=100,max_delay:W=1e4}={})=>{try{return await $()}catch(X){if(z>0)return await new Promise((Z)=>setTimeout(Z,J)),x($,{retries:z-1,max_delay:W,delay:Math.min(J*1.5,W)});throw X}};class d{$;z;J;constructor($,z,J){this.fetch=$;this.endpoint=z;this.mps3=J}getUrl($,z,J){return`${this.endpoint}/${$}${z?`/${encodeURIComponent(z)}`:""}${J||""}`}async listObjectV2($){for(let z=0;z<10;z++){const J=this.getUrl($.Bucket,void 0,`/?list-type=2&prefix=${$.Prefix}&start-after=${$.StartAfter}`),W=await x(()=>this.fetch(J,{}));if(W.status===200)return W0(await W.text(),this.mps3.config.parser);else if(W.status===429)console.warn("listObjectV2: 429, retrying"),await new Promise((X)=>setTimeout(X,1000));else throw new Error(`Unexpected response: ${W.status} ${await W.text()}`)}throw new Error("Cannot contact server")}async putObject({Bucket:$,Key:z,Body:J,ChecksumSHA256:W}){const X=this.getUrl($,z),Z=await x(()=>f(this.fetch(X,{method:"PUT",body:J,headers:{"Content-Type":"application/json"}}),this.mps3.config));if(Z.status!==200)throw new Error(`Failed to PUT: ${await Z.text()}`);return{$metadata:{httpStatusCode:Z.status},Date:new Date(Z.headers.get("date")),ETag:Z.headers.get("ETag"),...Z.headers.get("x-amz-version-id")&&{VersionId:Z.headers.get("x-amz-version-id")}}}async deleteObject({Bucket:$,Key:z}){return{$metadata:{httpStatusCode:(await x(()=>this.fetch(this.getUrl($,z),{method:"DELETE"}))).status}}}async getObject({Bucket:$,Key:z,VersionId:J,IfNoneMatch:W}){const X=this.getUrl($,z,J?`?versionId=${J}`:""),Z=await x(()=>f(this.fetch(X,{method:"GET",headers:{"If-None-Match":W}}),this.mps3.config));switch(Z.status){case 404:return{$metadata:{httpStatusCode:404}};case 403:throw new Error("Access denied");default:{let Q;const D=Z.headers.get("content-type"),O=await Z.text();if(D==="application/json"||O&&O!=="")try{Q=JSON.parse(O)}catch(Y){throw new Error(`Failed to parse response as JSON ${X}`)}return{$metadata:{httpStatusCode:Z.status},Body:Q,ETag:Z.headers.get("ETag"),...Z.headers.get("x-amz-version-id")&&{VersionId:Z.headers.get("x-amz-version-id")}}}}}}class A{key;_vals;_keys;constructor($,z){if(this.key=$,this._vals=new Map,this._keys=new Map,z)for(let[J,W]of z)this.set(J,W)}get size(){return this._vals.size}set($,z){const J=this.key($);return this._vals.set(J,z),this._keys.set(J,$),this}get($){return this._vals.get(this.key($))}delete($){const z=this.key($);return this._keys.delete(z),this._vals.delete(z)}has($){return this._vals.has(this.key($))}values(){return this._vals.values()}keys(){return this._keys.values()}forEach($){return this._vals.forEach((z,J,W)=>$(z,this._keys.get(J)))}}var j=function($){return new Promise((z,J)=>{$.oncomplete=$.onsuccess=()=>z($.result),$.onabort=$.onerror=()=>J($.error)})},M=function($,z){const J=indexedDB.open($);J.onupgradeneeded=()=>J.result.createObjectStore(z);const W=j(J);return(X,Z)=>W.then((Q)=>Z(Q.transaction(z,X).objectStore(z)))},I=function(){if(!y)y=M("keyval-store","keyval");return y},L=function($,z=I()){return z("readonly",(J)=>j(J.get($)))},C=function($,z,J=I()){return J("readwrite",(W)=>{return W.put(z,$),j(W.transaction)})};var X0=function($,z=I()){return z("readonly",(J)=>Promise.all($.map((W)=>j(J.get(W)))))};var Z0=function($,z=I()){return z("readwrite",(J)=>{return J.delete($),j(J.transaction)})},S=function($,z=I()){return z("readwrite",(J)=>{return $.forEach((W)=>J.delete(W)),j(J.transaction)})};var C0=function($,z){return $.openCursor().onsuccess=function(){if(!this.result)return;z(this.result),this.result.continue()},j($.transaction)},b=function($=I()){return $("readonly",(z)=>{if(z.getAllKeys)return j(z.getAllKeys());const J=[];return C0(z,(W)=>J.push(W.key)).then(()=>J)})};var y;var V0=6,Q0=($)=>`write-${$.toString().padStart(V0,"0")}`;class u{session=T();proposedOperations=new Map;operationLabels=new Map;db;lastIndex=0;load=void 0;op=0;constructor($){this.db=$}async propose($,z,J=!1){if(this.proposedOperations.set($,[z,this.op++]),this.db){if(this.load&&!J)await this.load,this.proposedOperations.delete($),this.proposedOperations.set($,[z,this.op-1]);this.lastIndex++;const W=Q0(this.lastIndex);$[this.session]=this.lastIndex,await C(W,[...z.entries()].map(([X,Z])=>[JSON.stringify(X),Z]),this.db),console.log(`STORE ${W} ${JSON.stringify([...z.entries()])}`)}}async label($,z,J=!1){if(this.operationLabels.set(z,$),this.db){if(this.load&&!J)await this.load;const W=$[this.session];if(W===void 0)throw new Error("Cannot label an unproposed operation");const X=`label-${W}`;await C(X,z,this.db),console.log(`STORE ${X} ${z}`)}}async confirm($,z=!1){if(this.operationLabels.has($)){const J=this.operationLabels.get($);if(this.proposedOperations.delete(J),this.operationLabels.delete($),this.db){if(this.load&&!z)await this.load;const W=J[this.session],X=[Q0(W),`label-${W}`];await S(X,this.db),console.log(`DEL ${X}`)}}}async cancel($,z=!1){if(this.operationLabels.forEach((J,W)=>{if(J===$)this.operationLabels.delete(W)}),this.proposedOperations.delete($),this.db){if(this.load&&!z)await this.load;const J=$[this.session];await S([`write-${J}`,`label-${J}`],this.db)}}async flatten(){if(this.load)await this.load;const $=new A(F);return this.proposedOperations.forEach(([z,J])=>{z.forEach((W,X)=>{$.set(X,[W,J])})}),$}async restore($,z){return this.db=$,this.proposedOperations.clear(),this.operationLabels.clear(),this.lastIndex=0,this.load=new Promise(async(J)=>{const X=(await b(this.db)).filter((Q)=>Q.startsWith("write-")).sort();console.log("RESTORE",X);const Z=await X0(X,this.db);for(let Q=0;Q<X.length;Q++){const D=parseInt(X[Q].split("-")[1]);this.lastIndex=Math.max(this.lastIndex,D)}for(let Q=0;Q<X.length;Q++){const D=X[Q],O=parseInt(D.split("-")[1]),Y=Z[Q].map(([E,B])=>[JSON.parse(E),B]),P=await L(`label-${O}`,this.db);if(!Y)continue;const H=new Map(Y);await z(H,P),await S([`write-${O}`,`label-${O}`],this.db)}J(void 0)}),this.load}}function c($,z){if(z===void 0)return $;if(z===null)return;if(typeof z!=="object"||typeof $!=="object")return z;const J=typeof $==="object"?{...$}:{};for(let W in z)if(z[W]===null)delete J[W];else J[W]=c($[W],z[W]);return J}var l=($)=>JSON.parse(JSON.stringify($));var i="manifest",n={files:{},update:{}};class V{$;session_id=T().substring(0,3);latest_key=".";latest_state=l(n);loading;cache;db;latest_timestamp=0;writes=0;static manifestRegex=/@([0-9a-z]+)_[0-9a-z]+_[0-9a-z]{2}$/;constructor($){this.manifest=$}static manifestTimestamp=($)=>{const z=$.match(V.manifestRegex);if(!z)return 0;return J0(z[1],42)};static isValid($,z){if(!$.match(V.manifestRegex))return console.warn(`Rejecting manifest key ${$}`),!1;if(z===void 0)return!0;const W=this.manifestTimestamp($),X=z,Z=Math.abs(W-X.getTime())<5000;if(!Z)console.warn(`Clock skew detected ${$} vs ${X.getTime()}`);return Z}async restore($){this.db=$,this.loading=L(i,$).then((z)=>{if(z)this.latest_state=z,this.manifest.service.config.log(`RESTORE ${i}`)})}async getLatest(){if(this.loading)await this.loading;if(this.loading=void 0,!this.manifest.service.config.online)return this.latest_state;try{let $=void 0;if(this.manifest.service.config.minimizeListObjectsCalls){const Q=await this.manifest.service._getObject({operation:"POLL_LATEST_CHANGE",ref:this.manifest.ref,ifNoneMatch:this.cache?.etag,useCache:!1});if(Q.$metadata.httpStatusCode===304)return this.latest_state;$=Q.ETag}const z=`${this.manifest.ref.key}@${h(Date.now()+this.manifest.service.config.clockOffset+1e4)}`,[J,W]=await N(this.manifest.service.s3ClientLite.listObjectV2({Bucket:this.manifest.ref.bucket,Prefix:this.manifest.ref.key+"@",StartAfter:z})),X=J.Contents?.filter((Q)=>{if(!V.isValid(Q.Key,Q.LastModified)){if(this.manifest.service.config.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:Q.Key}});return!1}return!0});if(this.manifest.service.config.log(`${W}ms LIST ${this.manifest.ref.bucket}/${this.manifest.ref.key} from ${z}`),X===void 0)return this.latest_state=l(n),this.latest_state;if(this.latest_timestamp=Math.max(this.latest_timestamp,V.manifestTimestamp(this.latest_key)),X.length>0){this.latest_key=X[0].Key;const Q=await this.manifest.service._getObject({operation:"GET_LATEST",ref:{bucket:this.manifest.ref.bucket,key:this.latest_key}});this.latest_state=Q.data}const Z=`${this.manifest.ref.key}@${h(Math.max(V.manifestTimestamp(this.latest_key)-5000,0))}`;for(let Q=X.length-1;Q>=0;Q--){const D=X[Q].Key;if(D>this.latest_key&&D>Z){if(this.manifest.service.config.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:D}});continue}const O=await this.manifest.service._getObject({operation:"REPLAY",ref:{bucket:this.manifest.ref.bucket,key:D}}),Y=D.substring(D.lastIndexOf("@")+1);this.latest_state=c(this.latest_state,O.data?.update),this.manifest.observeVersionId(Y)}if(this.db)C(i,this.latest_state,this.db);return this.latest_state}catch($){if($.name==="NoSuchKey")return this.latest_state=n,this.latest_state;else throw $}}updateContent($,z,J){const W=()=>h(Math.max(Date.now()+this.manifest.service.config.clockOffset,this.latest_timestamp))+"_"+this.session_id+"_"+z0(this.writes++);let X=W();const Z=this.manifest.operationQueue.propose(z,$,J.isLoad),Q=Z.then(async()=>{try{const D=await z;let O,Y,P=!1;do{const H=await this.getLatest();H.update={files:{}};for(let[B,_]of D){const q=F(B);if(_){const K={version:_};H.update.files[q]=K}else H.update.files[q]=null}Y=this.manifest.ref.key+"@"+X,this.manifest.operationQueue.label(z,X,J.isLoad);const E=await this.manifest.service._putObject({operation:"PUT_MANIFEST",ref:{key:Y,bucket:this.manifest.ref.bucket},value:H});if(this.manifest.service.config.adaptiveClock&&!V.isValid(Y,E.Date))this.manifest.service.config.clockOffset=E.Date.getTime()-Date.now()+E.latency,console.log(this.manifest.service.config.clockOffset),X=W(),P=!0;else P=!1}while(P);if(this.manifest.service.config.minimizeListObjectsCalls)O=await this.manifest.service._putObject({operation:"TOUCH_LATEST_CHANGE",ref:{key:this.manifest.ref.key,bucket:this.manifest.ref.bucket},value:""});return this.manifest.poll(),O}catch(D){throw console.error(D),this.manifest.operationQueue.cancel(z,J.isLoad),D}});if(J.await==="local")return Z;else return Q}}class D0{$;z;J;queue=Promise.resolve();constructor($,z,J){this.ref=$;this.handler=z;this.lastVersion=J}notify($,z,J){this.queue=this.queue.then(()=>J).then((W)=>{if(z!==this.lastVersion)$.config.log(`${$.config.label} NOTIFY ${F(this.ref)} ${z}`),this.lastVersion=z,this.handler(W)})}}class a{$;z;subscribers=new Set;poller;pollInProgress=!1;syncer=new V(this);operationQueue=new u;constructor($,z){this.service=$;this.ref=z;console.log("Create manifest",F(z))}load($){this.syncer.restore($),this.operationQueue.restore($,async(z,J)=>{if(!J)await this.service._putAll(z,{manifests:[this.ref],await:"local",isLoad:!0});else await this.updateContent(z,Promise.resolve(new Map([[this.ref,J]])),{await:"local",isLoad:!0})})}observeVersionId($){this.operationQueue.confirm($)}async poll(){if(this.pollInProgress)return;if(this.pollInProgress=!0,this.subscriberCount===0&&this.poller)clearInterval(this.poller),this.poller=void 0;if(this.subscriberCount>0&&!this.poller)this.poller=setInterval(()=>this.poll(),this.service.config.pollFrequency);const $=await this.syncer.getLatest();if($===void 0){this.pollInProgress=!1;return}const z=await this.operationQueue.flatten();this.subscribers.forEach(async(J)=>{if(z.has(J.ref)){const[W,X]=z.get(J.ref);J.notify(this.service,`local-${X}`,Promise.resolve(W))}else{const W=$.files[F(J.ref)];if(W){const X=this.service._getObject({operation:"GET_CONTENT",ref:J.ref,version:W.version});J.notify(this.service,W.version,X.then((Z)=>Z.data))}else if(W===null)J.notify(this.service,void 0,Promise.resolve(void 0))}}),this.pollInProgress=!1}updateContent($,z,J){return this.syncer.updateContent($,z,J)}async getVersion($){return(await this.syncer.getLatest()).files[F($)]?.version}subscribe($,z){this.service.config.log(`SUBSCRIBE ${F($)} ${this.subscriberCount+1}`);const J=new D0($,z);return this.subscribers.add(J),()=>this.subscribers.delete(J)}get subscriberCount(){return this.subscribers.size}}var O0=async($,z)=>{const J=new URL($),W=new URLSearchParams(J.search),X=J.pathname.split("/"),Z=X[1],Q=X.slice(2).join("/"),D=M(Z,"v0");let O,Y=200;if(W.get("list-type")){const P=encodeURIComponent(W.get("prefix")||""),H=encodeURIComponent(W.get("start-after")||"");O=`<ListBucketResult>${(await b(D)).filter((B)=>`${B}`.startsWith(P)&&`${B}`>H).map((B)=>`<Contents><Key>${B}</Key></Contents>`)}</ListBucketResult>`}else if(z?.method==="GET")O=await L(Q,D),Y=O===void 0?404:200;else if(z?.method==="PUT")O=await z.body,await C(Q,O,D);else if(z?.method==="DELETE")await Z0(Q,D);else throw new Error;return new Response(O,{status:Y})};async function Y0($){const z=(new TextEncoder()).encode($),J=await crypto.subtle.digest("SHA-256",z);return btoa(String.fromCharCode(...new Uint8Array(J)))}class U0{static LOCAL_ENDPOINT="indexdb:";config;s3ClientLite;manifests=new A(F);memCache=new A(($)=>`${$.Bucket}${$.Key}${$.VersionId}${$.IfNoneMatch}`);diskCache;endpoint;constructor($){if(this.config={...$,label:$.label||"default",useChecksum:$.useChecksum===!1?!1:!0,autoclean:$.autoclean===!1?!1:!0,online:$.online===!1?!1:!0,offlineStorage:$.offlineStorage===!1?!1:!0,useVersioning:$.useVersioning||!1,pollFrequency:$.pollFrequency||1000,clockOffset:Math.floor($.clockOffset)||0,adaptiveClock:$.adaptiveClock===!1?!1:!0,minimizeListObjectsCalls:$.minimizeListObjectsCalls===!1?!1:!0,parser:$.parser||new DOMParser,defaultManifest:{bucket:$.defaultManifest?.bucket||$.defaultBucket,key:typeof $.defaultManifest=="string"?$.defaultManifest:$.defaultManifest?.key||"manifest.json"},log:(...J)=>($.log===!0?console.log:$.log||(()=>{}))(this.config.label,...J)},this.config.s3Config?.credentials instanceof Function)throw Error("We can't do that yet");this.endpoint=$.s3Config.endpoint||`https://s3.${$.s3Config.region}.amazonaws.com`;let z;if(this.config.s3Config?.credentials){const J=new g({accessKeyId:this.config.s3Config.credentials.accessKeyId,secretAccessKey:this.config.s3Config.credentials.secretAccessKey,sessionToken:this.config.s3Config.credentials.sessionToken,region:this.config.s3Config.region||"us-east-1",service:"s3",retries:0});z=(...W)=>J.fetch(...W)}else if(this.endpoint==U0.LOCAL_ENDPOINT)z=O0;else z=(global||window).fetch.bind(global||window);if(this.config.offlineStorage){const J=`mps3-${this.config.label}`;this.diskCache=M(J,"v0")}this.s3ClientLite=new d(this.config.online?z:()=>new Promise(()=>{}),this.endpoint,this)}getOrCreateManifest($){if(!this.manifests.has($)){const z=new a(this,$);if(this.manifests.set($,z),this.config.offlineStorage){const J=`mps3-${this.config.label}-${$.bucket}-${$.key}`,W=M(J,"v0");this.config.log(`Restoring manifest from ${J}`),z.load(W)}}return this.manifests.get($)}async get($,z={}){const J={...this.config.defaultManifest,...z.manifest},W=this.getOrCreateManifest(J),X={bucket:$.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof $==="string"?$:$.key},Z=await W.operationQueue.flatten();if(Z.has(X))return this.config.log(`GET (cached) ${X} ${Z.get(X)}`),Z.get(X)[0];const Q=await W.getVersion(X);if(Q===void 0)return;return(await this._getObject({operation:"GET",ref:X,version:Q})).data}async _getObject($){let z;if(this.config.useVersioning)z={Bucket:$.ref.bucket,Key:$.ref.key,IfNoneMatch:$.ifNoneMatch,...$.version&&{VersionId:$.version}};else z={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,IfNoneMatch:$.ifNoneMatch};const J=`${z.Bucket}${z.Key}${z.VersionId}`;if($.useCache!==!1){if(this.memCache.has(z))return this.memCache.get(z);if(this.diskCache){const X=await L(J,this.diskCache);if(X)return this.config.log(`${$.operation} (disk cached) ${J}`),this.memCache.set(z,Promise.resolve(X)),X}}if(!this.config.online)throw new Error(`${this.config.label} Offline and value not cached for ${J}`);const W=N(this.s3ClientLite.getObject(z)).then(async([X,Z])=>{const Q={$metadata:X.$metadata,ETag:X.ETag,data:X.Body};return this.config.log(`${Z}ms ${$.operation} ${$.ref.bucket}/${$.ref.key}@${$.version} => ${Q.VersionId}`),Q}).catch((X)=>{if(X?.name==="304")return{$metadata:{httpStatusCode:304},data:void 0};else throw X});if($.useCache!==!1){if(this.memCache.set(z,W),this.diskCache)W.then((X)=>{C(`${z.Bucket}${z.Key}${z.VersionId}`,X,this.diskCache).then(()=>this.config.log(`STORE ${z.Bucket}${z.Key}`))})}return W}async delete($,z={}){return this.putAll(new Map([[$,void 0]]),z)}async put($,z,J={}){return this.putAll(new Map([[$,z]]),J)}async putAll($,z={}){const J=new Map([...$].map(([X,Z])=>[{bucket:X.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof X==="string"?X:X.key},Z])),W=(z?.manifests||[this.config.defaultManifest]).map((X)=>({...this.config.defaultManifest,...X}));return this._putAll(J,{manifests:W,await:z.await||this.config.online?"remote":"local"})}async _putAll($,z){const J=new Map,W=new Promise(async(X,Z)=>{const Q=new Map,D=[];$.forEach((O,Y)=>{if(O!==void 0){let P=this.config.useVersioning?void 0:T();J.set(Y,O),D.push(this._putObject({operation:"PUT_CONTENT",ref:Y,value:O,version:P}).then((H)=>{if(this.config.useVersioning)if(H.VersionId===void 0)throw console.error(H),Error(`Bucket ${Y.bucket} is not version enabled!`);else P=H.VersionId;Q.set(Y,P)}))}else D.push(this._deleteObject({ref:Y}).then((P)=>{Q.set(Y,void 0)}))}),await Promise.all(D).catch(Z),X(Q)});return Promise.all(z.manifests.map((X)=>{return this.getOrCreateManifest(X).updateContent(J,W,{await:z.await,isLoad:z.isLoad===!0})}))}async _putObject($){const z=JSON.stringify($.value,null,2);let J;if(this.config.useVersioning)J={Bucket:$.ref.bucket,Key:$.ref.key,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await Y0(z)}};else J={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await Y0(z)}};const[W,X]=await N(this.s3ClientLite.putObject(J));if(this.config.log(`${X}ms ${$.operation} ${J.Bucket}/${J.Key} => ${W.VersionId}`),this.diskCache){const Z=`${J.Bucket}${J.Key}${$.version||W.VersionId}`,Q=JSON.parse(z);await C(Z,{$metadata:{httpStatusCode:200},etag:W.ETag,data:Q},this.diskCache).then(()=>this.config.log(`STORE ${Z}`))}return{...W,latency:X}}async _deleteObject($){const z={Bucket:$.ref.bucket,Key:$.ref.key},[J,W]=await N(this.s3ClientLite.deleteObject(z));return this.config.log(`${W}ms ${$.operation||"DELETE"} ${$.ref.bucket}/${$.ref.key} (${J.$metadata.httpStatusCode})}`),J}subscribe($,z,J){const W={...this.config.defaultManifest,...J?.manifest},X={key:typeof $==="string"?$:$.key,bucket:$.bucket||this.config.defaultBucket||W.bucket},Z=this.getOrCreateManifest(W),Q=Z.subscribe(X,z);return this.get(X,{manifest:W}).then((D)=>{this.config.log(`NOTIFY (initial) ${F(X)}`),queueMicrotask(()=>{z(D,void 0),Z.poll()})}).catch((D)=>{z(void 0,D)}),Q}refresh(){return Promise.all([...this.manifests.values()].map(($)=>$.poll()))}get subscriberCount(){return[...this.manifests.values()].reduce(($,z)=>$+z.subscriberCount,0)}}export{U0 as MPS3};
{
"name": "mps3",
"description": "Provide clientside multiplayer and optimistic updates over any s3-compatible storage API",
"version": "0.0.80",
"version": "0.0.81",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc