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.77 to 0.0.78

2

dist/mps3.js

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

async function M($,z){const D=await crypto.subtle.importKey("raw",typeof $==="string"?R.encode($):$,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",D,R.encode(z))}async function a($){return crypto.subtle.digest("SHA-256",typeof $==="string"?R.encode($):$)}var K=function($){return Array.prototype.map.call(new Uint8Array($),(z)=>("0"+z.toString(16)).slice(-2)).join("")},o=function($){return $.replace(/[!'()*]/g,(z)=>"%"+z.charCodeAt(0).toString(16).toUpperCase())},U0=function($,z){const{hostname:D,pathname:W}=$;if(D.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(D.endsWith(".backblazeb2.com")){const O=D.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);return O!=null?["s3",O[1]]:["",""]}const X=D.replace("dualstack.","").match(/([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(?:\.cn)?$/);let[J,Z]=(X||["",""]).slice(1,3);if(Z==="us-gov")Z="us-gov-west-1";else if(Z==="s3"||Z==="s3-accelerate")Z="us-east-1",J="s3";else if(J==="iot")if(D.startsWith("iot."))J="execute-api";else if(D.startsWith("data.jobs.iot."))J="iot-jobs-data";else J=W==="/mqtt"?"iotdevicegateway":"iotdata";else if(J==="autoscaling"){const O=(z.get("X-Amz-Target")||"").split(".")[0];if(O==="AnyScaleFrontendService")J="application-autoscaling";else if(O==="AnyScaleScalingPlannerFrontendService")J="autoscaling-plans"}else if(Z==null&&J.startsWith("s3-"))Z=J.slice(3).replace(/^fips-|^external-1/,""),J="s3";else if(J.endsWith("-fips"))J=J.slice(0,-5);else if(Z&&/-\d$/.test(J)&&!/-\d$/.test(Z))[J,Z]=[Z,J];return[Y0[J]||J,Z]},R=new TextEncoder,Y0={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"},P0=new Set(["authorization","content-type","content-length","user-agent","presigned-expires","expect","x-amzn-trace-id","range","connection"]);class h{constructor({accessKeyId:$,secretAccessKey:z,sessionToken:D,service:W,region:X,cache:J,retries:Z,initRetryMs:O}){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=D,this.service=W,this.region=X,this.cache=J||new Map,this.retries=Z!=null?Z:10,this.initRetryMs=O||50}async sign($,z){if($ instanceof Request){const{method:X,url:J,headers:Z,body:O}=$;if(z=Object.assign({method:X,url:J,headers:Z},z),z.body==null&&Z.has("Content-Type"))z.body=O!=null&&Z.has("X-Amz-Content-Sha256")?O:await $.clone().arrayBuffer();$=J}const D=new t(Object.assign({url:$},z,this,z&&z.aws)),W=Object.assign({},z,await D.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 D=0;D<=this.retries;D++){const W=fetch(await this.sign($,z));if(D===this.retries)return W;const X=await W;if(X.status<500&&X.status!==429)return X;await new Promise((J)=>setTimeout(J,Math.random()*this.initRetryMs*Math.pow(2,D)))}throw new Error("An unknown error occurred, ensure retries is not negative")}}class t{constructor({method:$,url:z,headers:D,body:W,accessKeyId:X,secretAccessKey:J,sessionToken:Z,service:O,region:Q,cache:Y,datetime:U,signQuery:B,appendSessionToken:V,allHeaders:N,singleEncode:Q0}){if(z==null)throw new TypeError("url is a required option");if(X==null)throw new TypeError("accessKeyId is a required option");if(J==null)throw new TypeError("secretAccessKey is a required option");this.method=$||(W?"POST":"GET"),this.url=new URL(z),this.headers=new Headers(D||{}),this.body=W,this.accessKeyId=X,this.secretAccessKey=J,this.sessionToken=Z;let u,l;if(!O||!Q)[u,l]=U0(this.url,this.headers);if(this.service=O||u||"",this.region=Q||l||"us-east-1",this.cache=Y||new Map,this.datetime=U||(new Date()).toISOString().replace(/[:-]|\.\d{3}/g,""),this.signQuery=B,this.appendSessionToken=V||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 _=this.signQuery?this.url.searchParams:this.headers;if(_.set("X-Amz-Date",this.datetime),this.sessionToken&&!this.appendSessionToken)_.set("X-Amz-Security-Token",this.sessionToken);if(this.signableHeaders=["host",...this.headers.keys()].filter((P)=>N||!P0.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"&&!_.has("X-Amz-Expires"))_.set("X-Amz-Expires","86400");_.set("X-Amz-Algorithm","AWS4-HMAC-SHA256"),_.set("X-Amz-Credential",this.accessKeyId+"/"+this.credentialString),_.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(!Q0)this.encodedPath=encodeURIComponent(this.encodedPath).replace(/%2F/g,"/");this.encodedPath=o(this.encodedPath);const c=new Set;this.encodedSearch=[...this.url.searchParams].filter(([P])=>{if(!P)return!1;if(this.service==="s3"){if(c.has(P))return!1;c.add(P)}return!0}).map((P)=>P.map((w)=>o(encodeURIComponent(w)))).sort(([P,w],[i,n])=>P<i?-1:P>i?1:w<n?-1:w>n?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 D=this.cache.get(z);if(!D){const W=await M("AWS4"+this.secretAccessKey,$),X=await M(W,this.region),J=await M(X,this.service);D=await M(J,"aws4_request"),this.cache.set(z,D)}return K(await M(D,await this.stringToSign()))}async stringToSign(){return["AWS4-HMAC-SHA256",this.datetime,this.credentialString,K(await a(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");$=K(await a(this.body||""))}return $}}var r=($,z)=>{const D=z.parseFromString($,"text/xml");if(!D)throw new Error(`Invalid XML: ${$}`);const W=D.getElementsByTagName("Contents"),X=(J,Z)=>{const O=J.getElementsByTagName(Z)[0]?.textContent;return O?decodeURIComponent(O.replace(/\+/g," ")):void 0};return{$metadata:{},Contents:Array.from(W).map((J)=>({ETag:X(J,"ETag"),Key:X(J,"Key")})),KeyCount:parseInt(X(D,"KeyCount")),ContinuationToken:X(D,"ContinuationToken"),NextContinuationToken:X(D,"NextContinuationToken"),StartAfter:X(D,"StartAfter")}};var q=async($,{retries:z=Number.MAX_VALUE,delay:D=100,max_delay:W=1e4}={})=>{try{return await $()}catch(X){if(z>0)return await new Promise((J)=>setTimeout(J,D)),q($,{retries:z-1,max_delay:W,delay:Math.min(D*1.5,W)});throw X}};class S{$;z;D;constructor($,z,D){this.fetch=$;this.endpoint=z;this.parser=D}getUrl($,z,D){return`${this.endpoint}/${$}${z?`/${encodeURIComponent(z)}`:""}${D||""}`}async listObjectV2($){for(let z=0;z<10;z++){const D=this.getUrl($.Bucket,void 0,`/?list-type=2&prefix=${$.Prefix}`),W=await q(()=>this.fetch(D,{}));if(W.status===200)return r(await W.text(),this.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:D,ChecksumSHA256:W}){const X=this.getUrl($,z),J=await q(()=>this.fetch(X,{method:"PUT",body:D,headers:{"Content-Type":"application/json",...W&&{"x-amz-content-sha256":W}}}));if(J.status!==200)throw new Error(`Failed to PUT: ${await J.text()}`);return{$metadata:{httpStatusCode:J.status},ETag:J.headers.get("ETag"),...J.headers.get("x-amz-version-id")&&{VersionId:J.headers.get("x-amz-version-id")}}}async deleteObject({Bucket:$,Key:z}){return{$metadata:{httpStatusCode:(await q(()=>this.fetch(this.getUrl($,z),{method:"DELETE"}))).status}}}async getObject({Bucket:$,Key:z,VersionId:D,IfNoneMatch:W}){const X=this.getUrl($,z,D?`?versionId=${D}`:""),J=await q(()=>this.fetch(X,{method:"GET",headers:{"If-None-Match":W}}));switch(J.status){case 304:throw new Error("304");case 404:return{$metadata:{httpStatusCode:404}};case 403:throw new Error("Access denied");default:{let Z;const O=J.headers.get("content-type"),Q=await J.text();if(O==="application/json"||Q&&Q!=="")try{Z=JSON.parse(Q)}catch(Y){throw new Error(`Failed to parse response as JSON ${X}`)}return{$metadata:{httpStatusCode:J.status},Body:Z,ETag:J.headers.get("ETag"),...J.headers.get("x-amz-version-id")&&{VersionId:J.headers.get("x-amz-version-id")}}}}}}class j{key;_vals;_keys;constructor($,z){if(this.key=$,this._vals=new Map,this._keys=new Map,z)for(let[D,W]of z)this.set(D,W)}get size(){return this._vals.size}set($,z){const D=this.key($);return this._vals.set(D,z),this._keys.set(D,$),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,D,W)=>$(z,this._keys.get(D)))}}var s=()=>`${Date.now()-200}`.padStart(14,"0"),e=()=>`${Date.now()+200}`.padStart(14,"0");var G=async($)=>{const z=Date.now(),D=await $,W=Date.now();return[D,W-z]};var L=()=>crypto.randomUUID(),$0=($)=>$.toString(36).padStart(4,"0");var F=($)=>`${$.bucket}/${$.key}`;var C=function($){return new Promise((z,D)=>{$.oncomplete=$.onsuccess=()=>z($.result),$.onabort=$.onerror=()=>D($.error)})},E=function($,z){const D=indexedDB.open($);D.onupgradeneeded=()=>D.result.createObjectStore(z);const W=C(D);return(X,J)=>W.then((Z)=>J(Z.transaction(z,X).objectStore(z)))},A=function(){if(!v)v=E("keyval-store","keyval");return v},T=function($,z=A()){return z("readonly",(D)=>C(D.get($)))},H=function($,z,D=A()){return D("readwrite",(W)=>{return W.put(z,$),C(W.transaction)})};var z0=function($,z=A()){return z("readonly",(D)=>Promise.all($.map((W)=>C(D.get(W)))))};var D0=function($,z=A()){return z("readwrite",(D)=>{return D.delete($),C(D.transaction)})},I=function($,z=A()){return z("readwrite",(D)=>{return $.forEach((W)=>D.delete(W)),C(D.transaction)})};var F0=function($,z){return $.openCursor().onsuccess=function(){if(!this.result)return;z(this.result),this.result.continue()},C($.transaction)},x=function($=A()){return $("readonly",(z)=>{if(z.getAllKeys)return C(z.getAllKeys());const D=[];return F0(z,(W)=>D.push(W.key)).then(()=>D)})};var v;var B0=6,W0=($)=>`write-${$.toString().padStart(B0,"0")}`;class g{session=L();proposedOperations=new Map;operationLabels=new Map;db;lastIndex=0;load=void 0;constructor($){this.db=$}async propose($,z,D=!1){if(this.proposedOperations.set($,z),this.db){if(this.load&&!D)await this.load,this.proposedOperations.delete($),this.proposedOperations.set($,z);this.lastIndex++;const W=W0(this.lastIndex);$[this.session]=this.lastIndex,await H(W,[...z.entries()].map(([X,J])=>[JSON.stringify(X),J]),this.db),console.log(`STORE ${W} ${JSON.stringify([...z.entries()])}`)}}async label($,z,D=!1){if(this.operationLabels.set(z,$),this.db){if(this.load&&!D)await this.load;const W=$[this.session];if(W===void 0)throw new Error("Cannot label an unproposed operation");const X=`label-${W}`;await H(X,z,this.db),console.log(`STORE ${X} ${z}`)}}async confirm($,z=!1){if(this.operationLabels.has($)){const D=this.operationLabels.get($);if(this.proposedOperations.delete(D),this.operationLabels.delete($),this.db){if(this.load&&!z)await this.load;const W=D[this.session],X=[W0(W),`label-${W}`];await I(X,this.db),console.log(`DEL ${X}`)}}}async cancel($,z=!1){if(this.operationLabels.forEach((D,W)=>{if(D===$)this.operationLabels.delete(W)}),this.proposedOperations.delete($),this.db){if(this.load&&!z)await this.load;const D=$[this.session];await I([`write-${D}`,`label-${D}`],this.db)}}async flatten(){if(this.load)await this.load;const $=new j(F);return this.proposedOperations.forEach((z)=>{z.forEach((D,W)=>{$.set(W,D)})}),$}async restore($,z){return this.db=$,this.proposedOperations.clear(),this.operationLabels.clear(),this.lastIndex=0,this.load=new Promise(async(D)=>{const X=(await x(this.db)).filter((Z)=>Z.startsWith("write-")).sort();console.log("RESTORE",X);const J=await z0(X,this.db);for(let Z=0;Z<X.length;Z++){const O=parseInt(X[Z].split("-")[1]);this.lastIndex=Math.max(this.lastIndex,O)}for(let Z=0;Z<X.length;Z++){const O=X[Z],Q=parseInt(O.split("-")[1]),Y=J[Z].map(([V,N])=>[JSON.parse(V),N]),U=await T(`label-${Q}`,this.db);if(!Y)continue;const B=new Map(Y);await z(B,U),await I([`write-${Q}`,`label-${Q}`],this.db)}D(void 0)}),this.load}}function p($,z){if(z===void 0)return $;if(z===null)return;if(typeof z!=="object"||typeof $!=="object")return z;const D=typeof $==="object"?{...$}:{};for(let W in z)if(z[W]===null)delete D[W];else D[W]=p($[W],z[W]);return D}var k=($)=>JSON.parse(JSON.stringify($));var f="manifest",m={previous:".",files:{},update:{}};class y{$;authoritative_key="";authoritative_state=k(m);loading;cache;db;constructor($){this.manifest=$}async restore($){this.db=$,this.loading=T(f,$).then((z)=>{if(z)this.authoritative_state=z,this.manifest.service.config.log(`RESTORE ${f}`)})}async getLatest(){if(this.loading)await this.loading;if(this.loading=void 0,!this.manifest.service.config.online)return this.authoritative_state;try{const $=await this.manifest.service._getObject({operation:"POLL_TIME",ref:this.manifest.ref,ifNoneMatch:this.cache?.etag,useCache:!1});if($.$metadata.httpStatusCode===304)return this.authoritative_state;if($.data===void 0)this.authoritative_key=".";else this.authoritative_key=$.data;const[z,D]=await G(this.manifest.service.s3ClientLite.listObjectV2({Bucket:this.manifest.ref.bucket,Prefix:this.manifest.ref.key,StartAfter:this.authoritative_key}));if(this.manifest.service.config.log(`${D}ms LIST ${this.manifest.ref.bucket}/${this.manifest.ref.key}`),z.Contents===void 0)return this.authoritative_state=k(m),this.authoritative_state;const W=`${this.manifest.ref.key}@${s()}`;for(let X=z.Contents.length-1;X>=0;X--){const J=z.Contents[X].Key;if(J==this.manifest.ref.key)continue;const Z={bucket:this.manifest.ref.bucket,key:J},O=await this.manifest.service._getObject({operation:"LOOK_BACK",ref:Z});if(O.data===void 0){if(this.manifest.service.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:Z});continue}if(O.data.previous<W){this.authoritative_key=O.data.previous,this.authoritative_state=O.data;break}}for(let X=0;X<z.Contents.length;X++){const J=z.Contents[X].Key;if(J==this.manifest.ref.key)continue;if(J<this.authoritative_key){if(this.manifest.service.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:J}});continue}const Z=await this.manifest.service._getObject({operation:"SWEEP",ref:{bucket:this.manifest.ref.bucket,key:J}}),O=J.substring(J.lastIndexOf("@")+1);this.authoritative_state=p(this.authoritative_state,Z.data?.update),this.authoritative_key=J,this.manifest.observeVersionId(O)}if(this.db)H(f,this.authoritative_state,this.db);return this.authoritative_state}catch($){if($.name==="NoSuchKey")return this.authoritative_state=m,this.authoritative_state;else throw $}}}class X0{$;z;D;queue=Promise.resolve();constructor($,z,D){this.ref=$;this.handler=z;this.lastVersion=D}notify($,z,D){this.queue=this.queue.then(()=>D).then((W)=>{if(z!==this.lastVersion)$.config.log(`${$.config.label} NOTIFY ${F(this.ref)} ${z}`),this.lastVersion=z,this.handler(W)})}}class d{$;z;session_id=L().substring(0,3);writes=0;subscribers=new Set;poller;pollInProgress=!1;manifestState=new y(this);operationQueue=new g;constructor($,z){this.service=$;this.ref=z;console.log("Create manifest",F(z))}load($){this.manifestState.restore($),this.operationQueue.restore($,async(z,D)=>{if(!D)await this.service._putAll(z,{manifests:[this.ref],await:"local",isLoad:!0});else await this.updateContent(z,Promise.resolve(new Map([[this.ref,D]])),{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.manifestState.getLatest();if($===void 0){this.pollInProgress=!1;return}const z=await this.operationQueue.flatten();this.subscribers.forEach(async(D)=>{if(z.has(D.ref))D.notify(this.service,"local",Promise.resolve(z.get(D.ref)));else{const W=$.files[F(D.ref)];if(W){const X=this.service._getObject({operation:"GET_CONTENT",ref:D.ref,version:W.version});D.notify(this.service,W.version,X.then((J)=>J.data))}else if(W===null)D.notify(this.service,void 0,Promise.resolve(void 0))}}),this.pollInProgress=!1}updateContent($,z,D){const W=e()+"_"+this.session_id+"_"+$0(this.writes++),X=this.operationQueue.propose(z,$,D.isLoad),J=X.then(async()=>{try{const Z=await z,O=await this.manifestState.getLatest();O.previous=this.manifestState.authoritative_key,O.update={files:{}};for(let[U,B]of Z){const V=F(U);if(B){const N={version:B};O.update.files[V]=N}else O.update.files[V]=null}const Q=this.ref.key+"@"+W;this.operationQueue.label(z,W,D.isLoad),await this.service._putObject({operation:"PUT_MANIFEST",ref:{key:Q,bucket:this.ref.bucket},value:O});const Y=await this.service._putObject({operation:"PUT_POLL",ref:{key:this.ref.key,bucket:this.ref.bucket},value:this.manifestState.authoritative_key});return this.poll(),Y}catch(Z){throw console.error(Z),this.operationQueue.cancel(z,D.isLoad),Z}});if(D.await==="local")return X;else return J}async getVersion($){return(await this.manifestState.getLatest()).files[F($)]?.version}subscribe($,z){this.service.config.log(`SUBSCRIBE ${F($)} ${this.subscriberCount+1}`);const D=new X0($,z);return this.subscribers.add(D),()=>this.subscribers.delete(D)}get subscriberCount(){return this.subscribers.size}}var J0=async($,z)=>{const D=new URL($),W=new URLSearchParams(D.search),X=D.pathname.split("/"),J=X[1],Z=X.slice(2).join("/"),O=E(J,"v0");let Q,Y=200;if(W.get("list-type")){const U=W.get("prefix")||"";Q=`<ListBucketResult>${(await x(O)).filter((V)=>`${V}`.startsWith(U)).map((V)=>`<Contents><Key>${V}</Key></Contents>`)}</ListBucketResult>`}else if(z?.method==="GET")Q=await T(Z,O),Y=Q===void 0?404:200;else if(z?.method==="PUT")Q=await z.body,await H(Z,Q,O);else if(z?.method==="DELETE")await D0(Z,O);else throw new Error;return new Response(Q,{status:Y})};async function Z0($){const z=(new TextEncoder()).encode($),D=await crypto.subtle.digest("SHA-256",z);return[...new Uint8Array(D)].map((W)=>W.toString(16).padStart(2,"0")).join("")}class O0{static LOCAL_ENDPOINT="indexdb://";config;s3ClientLite;manifests=new j(F);memCache=new j(($)=>`${$.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,defaultManifest:{bucket:$.defaultManifest?.bucket||$.defaultBucket,key:typeof $.defaultManifest=="string"?$.defaultManifest:$.defaultManifest?.key||"manifest.json"},log:(...D)=>($.log||console.log)(this.config.label,...D)},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 D=new h({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)=>D.fetch(...W)}else if(this.endpoint==O0.LOCAL_ENDPOINT)z=J0;else z=(global||window).fetch.bind(global||window);if(this.config.offlineStorage){const D=`mps3-${this.config.label}`;this.diskCache=E(D,"v0")}this.s3ClientLite=new S(this.config.online?z:()=>new Promise(()=>{}),this.endpoint,$.parser||new DOMParser)}getOrCreateManifest($){if(!this.manifests.has($)){const z=new d(this,$);if(this.manifests.set($,z),this.config.offlineStorage){const D=`mps3-${this.config.label}-${$.bucket}-${$.key}`,W=E(D,"v0");this.config.log(`Restoring manifest from ${D}`),z.load(W)}}return this.manifests.get($)}async get($,z={}){const D={...this.config.defaultManifest,...z.manifest},W=this.getOrCreateManifest(D),X={bucket:$.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof $==="string"?$:$.key},J=await W.operationQueue.flatten();if(J.has(X))return this.config.log(`GET (cached) ${X} ${J.get(X)}`),J.get(X);const Z=await W.getVersion(X);if(Z===void 0)return;return(await this._getObject({operation:"GET",ref:X,version:Z})).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 D=`${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 T(D,this.diskCache);if(X)return this.config.log(`${$.operation} (disk cached) ${D}`),this.memCache.set(z,Promise.resolve(X)),X}}if(!this.config.online)throw new Error(`${this.config.label} Offline and value not cached for ${D}`);const W=G(this.s3ClientLite.getObject(z)).then(async([X,J])=>{const Z={$metadata:X.$metadata,ETag:X.ETag,data:X.Body};return this.config.log(`${J}ms ${$.operation} ${$.ref.bucket}/${$.ref.key}@${$.version} => ${Z.VersionId}`),Z}).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)=>{H(`${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,D={}){return this.putAll(new Map([[$,z]]),D)}async putAll($,z={}){const D=new Map([...$].map(([X,J])=>[{bucket:X.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof X==="string"?X:X.key},J])),W=(z?.manifests||[this.config.defaultManifest]).map((X)=>({...this.config.defaultManifest,...X}));return this._putAll(D,{manifests:W,await:z.await||this.config.online?"remote":"local"})}async _putAll($,z){const D=new Map,W=new Promise(async(X,J)=>{const Z=new Map,O=[];$.forEach((Q,Y)=>{if(Q!==void 0){let U=this.config.useVersioning?void 0:L();D.set(Y,Q),O.push(this._putObject({operation:"PUT_CONTENT",ref:Y,value:Q,version:U}).then((B)=>{if(this.config.useVersioning)if(B.VersionId===void 0)throw console.error(B),Error(`Bucket ${Y.bucket} is not version enabled!`);else U=B.VersionId;Z.set(Y,U)}))}else O.push(this._deleteObject({ref:Y}).then((U)=>{Z.set(Y,void 0)}))}),await Promise.all(O).catch(J),X(Z)});return Promise.all(z.manifests.map((X)=>{return this.getOrCreateManifest(X).updateContent(D,W,{await:z.await,isLoad:z.isLoad===!0})}))}async _putObject($){const z=JSON.stringify($.value,null,2);let D;if(this.config.useVersioning)D={Bucket:$.ref.bucket,Key:$.ref.key,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await Z0(z)}};else D={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,ContentType:"application/json",Body:z,...this.config.useChecksum&&{ChecksumSHA256:await Z0(z)}};const[W,X]=await G(this.s3ClientLite.putObject(D));if(this.config.log(`${X}ms ${$.operation} ${D.Bucket}/${D.Key} => ${W.VersionId}`),this.diskCache){const J=`${D.Bucket}${D.Key}${$.version||W.VersionId}`;await H(J,{$metadata:{httpStatusCode:200},etag:W.ETag,data:JSON.parse(z)},this.diskCache).then(()=>this.config.log(`STORE ${J}`))}return W}async _deleteObject($){const z={Bucket:$.ref.bucket,Key:$.ref.key},[D,W]=await G(this.s3ClientLite.deleteObject(z));return this.config.log(`${W}ms ${$.operation||"DELETE"} ${$.ref.bucket}/${$.ref.key} (${D.$metadata.httpStatusCode})}`),D}subscribe($,z,D){const W={...this.config.defaultManifest,...D?.manifest},X={key:typeof $==="string"?$:$.key,bucket:$.bucket||this.config.defaultBucket||W.bucket},J=this.getOrCreateManifest(W),Z=J.subscribe(X,z);return this.get(X,{manifest:W}).then((O)=>{this.config.log(`NOTIFY (initial) ${F(X)}`),queueMicrotask(()=>{z(O,void 0),J.poll()})}).catch((O)=>{z(void 0,O)}),Z}refresh(){return Promise.all([...this.manifests.values()].map(($)=>$.poll()))}get subscriberCount(){return[...this.manifests.values()].reduce(($,z)=>$+z.subscriberCount,0)}}export{O0 as MPS3};
async function A($,D){const z=await crypto.subtle.importKey("raw",typeof $==="string"?R.encode($):$,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",z,R.encode(D))}async function a($){return crypto.subtle.digest("SHA-256",typeof $==="string"?R.encode($):$)}var K=function($){return Array.prototype.map.call(new Uint8Array($),(D)=>("0"+D.toString(16)).slice(-2)).join("")},o=function($){return $.replace(/[!'()*]/g,(D)=>"%"+D.charCodeAt(0).toString(16).toUpperCase())},B0=function($,D){const{hostname:z,pathname:W}=$;if(z.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(z.endsWith(".backblazeb2.com")){const O=z.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);return O!=null?["s3",O[1]]:["",""]}const X=z.replace("dualstack.","").match(/([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(?:\.cn)?$/);let[J,Z]=(X||["",""]).slice(1,3);if(Z==="us-gov")Z="us-gov-west-1";else if(Z==="s3"||Z==="s3-accelerate")Z="us-east-1",J="s3";else if(J==="iot")if(z.startsWith("iot."))J="execute-api";else if(z.startsWith("data.jobs.iot."))J="iot-jobs-data";else J=W==="/mqtt"?"iotdevicegateway":"iotdata";else if(J==="autoscaling"){const O=(D.get("X-Amz-Target")||"").split(".")[0];if(O==="AnyScaleFrontendService")J="application-autoscaling";else if(O==="AnyScaleScalingPlannerFrontendService")J="autoscaling-plans"}else if(Z==null&&J.startsWith("s3-"))Z=J.slice(3).replace(/^fips-|^external-1/,""),J="s3";else if(J.endsWith("-fips"))J=J.slice(0,-5);else if(Z&&/-\d$/.test(J)&&!/-\d$/.test(Z))[J,Z]=[Z,J];return[Y0[J]||J,Z]},R=new TextEncoder,Y0={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"},P0=new Set(["authorization","content-type","content-length","user-agent","presigned-expires","expect","x-amzn-trace-id","range","connection"]);class S{constructor({accessKeyId:$,secretAccessKey:D,sessionToken:z,service:W,region:X,cache:J,retries:Z,initRetryMs:O}){if($==null)throw new TypeError("accessKeyId is a required option");if(D==null)throw new TypeError("secretAccessKey is a required option");this.accessKeyId=$,this.secretAccessKey=D,this.sessionToken=z,this.service=W,this.region=X,this.cache=J||new Map,this.retries=Z!=null?Z:10,this.initRetryMs=O||50}async sign($,D){if($ instanceof Request){const{method:X,url:J,headers:Z,body:O}=$;if(D=Object.assign({method:X,url:J,headers:Z},D),D.body==null&&Z.has("Content-Type"))D.body=O!=null&&Z.has("X-Amz-Content-Sha256")?O:await $.clone().arrayBuffer();$=J}const z=new t(Object.assign({url:$},D,this,D&&D.aws)),W=Object.assign({},D,await z.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($,D){for(let z=0;z<=this.retries;z++){const W=fetch(await this.sign($,D));if(z===this.retries)return W;const X=await W;if(X.status<500&&X.status!==429)return X;await new Promise((J)=>setTimeout(J,Math.random()*this.initRetryMs*Math.pow(2,z)))}throw new Error("An unknown error occurred, ensure retries is not negative")}}class t{constructor({method:$,url:D,headers:z,body:W,accessKeyId:X,secretAccessKey:J,sessionToken:Z,service:O,region:Q,cache:Y,datetime:B,signQuery:F,appendSessionToken:C,allHeaders:M,singleEncode:Q0}){if(D==null)throw new TypeError("url is a required option");if(X==null)throw new TypeError("accessKeyId is a required option");if(J==null)throw new TypeError("secretAccessKey is a required option");this.method=$||(W?"POST":"GET"),this.url=new URL(D),this.headers=new Headers(z||{}),this.body=W,this.accessKeyId=X,this.secretAccessKey=J,this.sessionToken=Z;let u,l;if(!O||!Q)[u,l]=B0(this.url,this.headers);if(this.service=O||u||"",this.region=Q||l||"us-east-1",this.cache=Y||new Map,this.datetime=B||(new Date()).toISOString().replace(/[:-]|\.\d{3}/g,""),this.signQuery=F,this.appendSessionToken=C||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 j=this.signQuery?this.url.searchParams:this.headers;if(j.set("X-Amz-Date",this.datetime),this.sessionToken&&!this.appendSessionToken)j.set("X-Amz-Security-Token",this.sessionToken);if(this.signableHeaders=["host",...this.headers.keys()].filter((P)=>M||!P0.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"&&!j.has("X-Amz-Expires"))j.set("X-Amz-Expires","86400");j.set("X-Amz-Algorithm","AWS4-HMAC-SHA256"),j.set("X-Amz-Credential",this.accessKeyId+"/"+this.credentialString),j.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(!Q0)this.encodedPath=encodeURIComponent(this.encodedPath).replace(/%2F/g,"/");this.encodedPath=o(this.encodedPath);const c=new Set;this.encodedSearch=[...this.url.searchParams].filter(([P])=>{if(!P)return!1;if(this.service==="s3"){if(c.has(P))return!1;c.add(P)}return!0}).map((P)=>P.map((I)=>o(encodeURIComponent(I)))).sort(([P,I],[n,i])=>P<n?-1:P>n?1:I<i?-1:I>i?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),D=[this.secretAccessKey,$,this.region,this.service].join();let z=this.cache.get(D);if(!z){const W=await A("AWS4"+this.secretAccessKey,$),X=await A(W,this.region),J=await A(X,this.service);z=await A(J,"aws4_request"),this.cache.set(D,z)}return K(await A(z,await this.stringToSign()))}async stringToSign(){return["AWS4-HMAC-SHA256",this.datetime,this.credentialString,K(await a(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");$=K(await a(this.body||""))}return $}}var r=($,D)=>{const z=D.parseFromString($,"text/xml");if(!z)throw new Error(`Invalid XML: ${$}`);const W=z.getElementsByTagName("Contents"),X=(J,Z)=>{const O=J.getElementsByTagName(Z)[0]?.textContent;return O?decodeURIComponent(O.replace(/\+/g," ")):void 0};return{$metadata:{},Contents:Array.from(W).map((J)=>({ETag:X(J,"ETag"),Key:X(J,"Key")})),KeyCount:parseInt(X(z,"KeyCount")),ContinuationToken:X(z,"ContinuationToken"),NextContinuationToken:X(z,"NextContinuationToken"),StartAfter:X(z,"StartAfter")}};var q=async($,{retries:D=Number.MAX_VALUE,delay:z=100,max_delay:W=1e4}={})=>{try{return await $()}catch(X){if(D>0)return await new Promise((J)=>setTimeout(J,z)),q($,{retries:D-1,max_delay:W,delay:Math.min(z*1.5,W)});throw X}};class h{$;D;z;constructor($,D,z){this.fetch=$;this.endpoint=D;this.parser=z}getUrl($,D,z){return`${this.endpoint}/${$}${D?`/${encodeURIComponent(D)}`:""}${z||""}`}async listObjectV2($){for(let D=0;D<10;D++){const z=this.getUrl($.Bucket,void 0,`/?list-type=2&prefix=${$.Prefix}`),W=await q(()=>this.fetch(z,{}));if(W.status===200)return r(await W.text(),this.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:D,Body:z,ChecksumSHA256:W}){const X=this.getUrl($,D),J=await q(()=>this.fetch(X,{method:"PUT",body:z,headers:{"Content-Type":"application/json",...W&&{"x-amz-content-sha256":W}}}));if(J.status!==200)throw new Error(`Failed to PUT: ${await J.text()}`);return{$metadata:{httpStatusCode:J.status},ETag:J.headers.get("ETag"),...J.headers.get("x-amz-version-id")&&{VersionId:J.headers.get("x-amz-version-id")}}}async deleteObject({Bucket:$,Key:D}){return{$metadata:{httpStatusCode:(await q(()=>this.fetch(this.getUrl($,D),{method:"DELETE"}))).status}}}async getObject({Bucket:$,Key:D,VersionId:z,IfNoneMatch:W}){const X=this.getUrl($,D,z?`?versionId=${z}`:""),J=await q(()=>this.fetch(X,{method:"GET",headers:{"If-None-Match":W}}));switch(J.status){case 304:throw new Error("304");case 404:return{$metadata:{httpStatusCode:404}};case 403:throw new Error("Access denied");default:{let Z;const O=J.headers.get("content-type"),Q=await J.text();if(O==="application/json"||Q&&Q!=="")try{Z=JSON.parse(Q)}catch(Y){throw new Error(`Failed to parse response as JSON ${X}`)}return{$metadata:{httpStatusCode:J.status},Body:Z,ETag:J.headers.get("ETag"),...J.headers.get("x-amz-version-id")&&{VersionId:J.headers.get("x-amz-version-id")}}}}}}class G{key;_vals;_keys;constructor($,D){if(this.key=$,this._vals=new Map,this._keys=new Map,D)for(let[z,W]of D)this.set(z,W)}get size(){return this._vals.size}set($,D){const z=this.key($);return this._vals.set(z,D),this._keys.set(z,$),this}get($){return this._vals.get(this.key($))}delete($){const D=this.key($);return this._keys.delete(D),this._vals.delete(D)}has($){return this._vals.has(this.key($))}values(){return this._vals.values()}keys(){return this._keys.values()}forEach($){return this._vals.forEach((D,z,W)=>$(D,this._keys.get(z)))}}var s=()=>`${Date.now()-200}`.padStart(14,"0"),e=()=>`${Date.now()+200}`.padStart(14,"0");var L=async($)=>{const D=Date.now(),z=await $,W=Date.now();return[z,W-D]};var E=()=>crypto.randomUUID(),$0=($)=>$.toString(36).padStart(4,"0");var U=($)=>`${$.bucket}/${$.key}`;var V=function($){return new Promise((D,z)=>{$.oncomplete=$.onsuccess=()=>D($.result),$.onabort=$.onerror=()=>z($.error)})},_=function($,D){const z=indexedDB.open($);z.onupgradeneeded=()=>z.result.createObjectStore(D);const W=V(z);return(X,J)=>W.then((Z)=>J(Z.transaction(D,X).objectStore(D)))},N=function(){if(!v)v=_("keyval-store","keyval");return v},T=function($,D=N()){return D("readonly",(z)=>V(z.get($)))},H=function($,D,z=N()){return z("readwrite",(W)=>{return W.put(D,$),V(W.transaction)})};var D0=function($,D=N()){return D("readonly",(z)=>Promise.all($.map((W)=>V(z.get(W)))))};var z0=function($,D=N()){return D("readwrite",(z)=>{return z.delete($),V(z.transaction)})},w=function($,D=N()){return D("readwrite",(z)=>{return $.forEach((W)=>z.delete(W)),V(z.transaction)})};var U0=function($,D){return $.openCursor().onsuccess=function(){if(!this.result)return;D(this.result),this.result.continue()},V($.transaction)},x=function($=N()){return $("readonly",(D)=>{if(D.getAllKeys)return V(D.getAllKeys());const z=[];return U0(D,(W)=>z.push(W.key)).then(()=>z)})};var v;var F0=6,W0=($)=>`write-${$.toString().padStart(F0,"0")}`;class g{session=E();proposedOperations=new Map;operationLabels=new Map;db;lastIndex=0;load=void 0;constructor($){this.db=$}async propose($,D,z=!1){if(this.proposedOperations.set($,D),this.db){if(this.load&&!z)await this.load,this.proposedOperations.delete($),this.proposedOperations.set($,D);this.lastIndex++;const W=W0(this.lastIndex);$[this.session]=this.lastIndex,await H(W,[...D.entries()].map(([X,J])=>[JSON.stringify(X),J]),this.db),console.log(`STORE ${W} ${JSON.stringify([...D.entries()])}`)}}async label($,D,z=!1){if(this.operationLabels.set(D,$),this.db){if(this.load&&!z)await this.load;const W=$[this.session];if(W===void 0)throw new Error("Cannot label an unproposed operation");const X=`label-${W}`;await H(X,D,this.db),console.log(`STORE ${X} ${D}`)}}async confirm($,D=!1){if(this.operationLabels.has($)){const z=this.operationLabels.get($);if(this.proposedOperations.delete(z),this.operationLabels.delete($),this.db){if(this.load&&!D)await this.load;const W=z[this.session],X=[W0(W),`label-${W}`];await w(X,this.db),console.log(`DEL ${X}`)}}}async cancel($,D=!1){if(this.operationLabels.forEach((z,W)=>{if(z===$)this.operationLabels.delete(W)}),this.proposedOperations.delete($),this.db){if(this.load&&!D)await this.load;const z=$[this.session];await w([`write-${z}`,`label-${z}`],this.db)}}async flatten(){if(this.load)await this.load;const $=new G(U);return this.proposedOperations.forEach((D)=>{D.forEach((z,W)=>{$.set(W,z)})}),$}async restore($,D){return this.db=$,this.proposedOperations.clear(),this.operationLabels.clear(),this.lastIndex=0,this.load=new Promise(async(z)=>{const X=(await x(this.db)).filter((Z)=>Z.startsWith("write-")).sort();console.log("RESTORE",X);const J=await D0(X,this.db);for(let Z=0;Z<X.length;Z++){const O=parseInt(X[Z].split("-")[1]);this.lastIndex=Math.max(this.lastIndex,O)}for(let Z=0;Z<X.length;Z++){const O=X[Z],Q=parseInt(O.split("-")[1]),Y=J[Z].map(([C,M])=>[JSON.parse(C),M]),B=await T(`label-${Q}`,this.db);if(!Y)continue;const F=new Map(Y);await D(F,B),await w([`write-${Q}`,`label-${Q}`],this.db)}z(void 0)}),this.load}}function k($,D){if(D===void 0)return $;if(D===null)return;if(typeof D!=="object"||typeof $!=="object")return D;const z=typeof $==="object"?{...$}:{};for(let W in D)if(D[W]===null)delete z[W];else z[W]=k($[W],D[W]);return z}var p=($)=>JSON.parse(JSON.stringify($));var f="manifest",m={previous:".",files:{},update:{}};class y{$;authoritative_key="";authoritative_state=p(m);loading;cache;db;constructor($){this.manifest=$}async restore($){this.db=$,this.loading=T(f,$).then((D)=>{if(D)this.authoritative_state=D,this.manifest.service.config.log(`RESTORE ${f}`)})}async getLatest(){if(this.loading)await this.loading;if(this.loading=void 0,!this.manifest.service.config.online)return this.authoritative_state;try{const $=await this.manifest.service._getObject({operation:"POLL_TIME",ref:this.manifest.ref,ifNoneMatch:this.cache?.etag,useCache:!1});if($.$metadata.httpStatusCode===304)return this.authoritative_state;if($.data===void 0)this.authoritative_key=".";else this.authoritative_key=$.data;const[D,z]=await L(this.manifest.service.s3ClientLite.listObjectV2({Bucket:this.manifest.ref.bucket,Prefix:this.manifest.ref.key,StartAfter:this.authoritative_key}));if(this.manifest.service.config.log(`${z}ms LIST ${this.manifest.ref.bucket}/${this.manifest.ref.key}`),D.Contents===void 0)return this.authoritative_state=p(m),this.authoritative_state;const W=`${this.manifest.ref.key}@${s()}`;for(let X=D.Contents.length-1;X>=0;X--){const J=D.Contents[X].Key;if(J==this.manifest.ref.key)continue;const Z={bucket:this.manifest.ref.bucket,key:J},O=await this.manifest.service._getObject({operation:"LOOK_BACK",ref:Z});if(O.data===void 0){if(this.manifest.service.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:Z});continue}if(O.data.previous<W){this.authoritative_key=O.data.previous,this.authoritative_state=O.data;break}}for(let X=0;X<D.Contents.length;X++){const J=D.Contents[X].Key;if(J==this.manifest.ref.key)continue;if(J<this.authoritative_key){if(this.manifest.service.autoclean)this.manifest.service._deleteObject({operation:"CLEANUP",ref:{bucket:this.manifest.ref.bucket,key:J}});continue}const Z=await this.manifest.service._getObject({operation:"SWEEP",ref:{bucket:this.manifest.ref.bucket,key:J}}),O=J.substring(J.lastIndexOf("@")+1);this.authoritative_state=k(this.authoritative_state,Z.data?.update),this.authoritative_key=J,this.manifest.observeVersionId(O)}if(this.db)H(f,this.authoritative_state,this.db);return this.authoritative_state}catch($){if($.name==="NoSuchKey")return this.authoritative_state=m,this.authoritative_state;else throw $}}}class X0{$;D;z;queue=Promise.resolve();constructor($,D,z){this.ref=$;this.handler=D;this.lastVersion=z}notify($,D,z){this.queue=this.queue.then(()=>z).then((W)=>{if(D!==this.lastVersion)$.config.log(`${$.config.label} NOTIFY ${U(this.ref)} ${D}`),this.lastVersion=D,this.handler(W)})}}class d{$;D;session_id=E().substring(0,3);writes=0;subscribers=new Set;poller;pollInProgress=!1;manifestState=new y(this);operationQueue=new g;constructor($,D){this.service=$;this.ref=D;console.log("Create manifest",U(D))}load($){this.manifestState.restore($),this.operationQueue.restore($,async(D,z)=>{if(!z)await this.service._putAll(D,{manifests:[this.ref],await:"local",isLoad:!0});else await this.updateContent(D,Promise.resolve(new Map([[this.ref,z]])),{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.manifestState.getLatest();if($===void 0){this.pollInProgress=!1;return}const D=await this.operationQueue.flatten();this.subscribers.forEach(async(z)=>{if(D.has(z.ref))z.notify(this.service,"local",Promise.resolve(D.get(z.ref)));else{const W=$.files[U(z.ref)];if(W){const X=this.service._getObject({operation:"GET_CONTENT",ref:z.ref,version:W.version});z.notify(this.service,W.version,X.then((J)=>J.data))}else if(W===null)z.notify(this.service,void 0,Promise.resolve(void 0))}}),this.pollInProgress=!1}updateContent($,D,z){const W=e()+"_"+this.session_id+"_"+$0(this.writes++),X=this.operationQueue.propose(D,$,z.isLoad),J=X.then(async()=>{try{const Z=await D,O=await this.manifestState.getLatest();O.previous=this.manifestState.authoritative_key,O.update={files:{}};for(let[B,F]of Z){const C=U(B);if(F){const M={version:F};O.update.files[C]=M}else O.update.files[C]=null}const Q=this.ref.key+"@"+W;this.operationQueue.label(D,W,z.isLoad),await this.service._putObject({operation:"PUT_MANIFEST",ref:{key:Q,bucket:this.ref.bucket},value:O});const Y=await this.service._putObject({operation:"PUT_POLL",ref:{key:this.ref.key,bucket:this.ref.bucket},value:this.manifestState.authoritative_key});return this.poll(),Y}catch(Z){throw console.error(Z),this.operationQueue.cancel(D,z.isLoad),Z}});if(z.await==="local")return X;else return J}async getVersion($){return(await this.manifestState.getLatest()).files[U($)]?.version}subscribe($,D){this.service.config.log(`SUBSCRIBE ${U($)} ${this.subscriberCount+1}`);const z=new X0($,D);return this.subscribers.add(z),()=>this.subscribers.delete(z)}get subscriberCount(){return this.subscribers.size}}var J0=async($,D)=>{const z=new URL($),W=new URLSearchParams(z.search),X=z.pathname.split("/"),J=X[1],Z=X.slice(2).join("/"),O=_(J,"v0");let Q,Y=200;if(W.get("list-type")){const B=W.get("prefix")||"";Q=`<ListBucketResult>${(await x(O)).filter((C)=>`${C}`.startsWith(B)).map((C)=>`<Contents><Key>${C}</Key></Contents>`)}</ListBucketResult>`}else if(D?.method==="GET")Q=await T(Z,O),Y=Q===void 0?404:200;else if(D?.method==="PUT")Q=await D.body,await H(Z,Q,O);else if(D?.method==="DELETE")await z0(Z,O);else throw new Error;return new Response(Q,{status:Y})};async function Z0($){const D=(new TextEncoder()).encode($),z=await crypto.subtle.digest("SHA-256",D);return[...new Uint8Array(z)].map((W)=>W.toString(16).padStart(2,"0")).join("")}class O0{static LOCAL_ENDPOINT="indexdb:";config;s3ClientLite;manifests=new G(U);memCache=new G(($)=>`${$.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,defaultManifest:{bucket:$.defaultManifest?.bucket||$.defaultBucket,key:typeof $.defaultManifest=="string"?$.defaultManifest:$.defaultManifest?.key||"manifest.json"},log:(...z)=>($.log||console.log)(this.config.label,...z)},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 D;if(this.config.s3Config?.credentials){const z=new S({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});D=(...W)=>z.fetch(...W)}else if(this.endpoint==O0.LOCAL_ENDPOINT)D=J0;else D=(global||window).fetch.bind(global||window);if(this.config.offlineStorage){const z=`mps3-${this.config.label}`;this.diskCache=_(z,"v0")}this.s3ClientLite=new h(this.config.online?D:()=>new Promise(()=>{}),this.endpoint,$.parser||new DOMParser)}getOrCreateManifest($){if(!this.manifests.has($)){const D=new d(this,$);if(this.manifests.set($,D),this.config.offlineStorage){const z=`mps3-${this.config.label}-${$.bucket}-${$.key}`,W=_(z,"v0");this.config.log(`Restoring manifest from ${z}`),D.load(W)}}return this.manifests.get($)}async get($,D={}){const z={...this.config.defaultManifest,...D.manifest},W=this.getOrCreateManifest(z),X={bucket:$.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof $==="string"?$:$.key},J=await W.operationQueue.flatten();if(J.has(X))return this.config.log(`GET (cached) ${X} ${J.get(X)}`),J.get(X);const Z=await W.getVersion(X);if(Z===void 0)return;return(await this._getObject({operation:"GET",ref:X,version:Z})).data}async _getObject($){let D;if(this.config.useVersioning)D={Bucket:$.ref.bucket,Key:$.ref.key,IfNoneMatch:$.ifNoneMatch,...$.version&&{VersionId:$.version}};else D={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,IfNoneMatch:$.ifNoneMatch};const z=`${D.Bucket}${D.Key}${D.VersionId}`;if($.useCache!==!1){if(this.memCache.has(D))return this.memCache.get(D);if(this.diskCache){const X=await T(z,this.diskCache);if(X)return this.config.log(`${$.operation} (disk cached) ${z}`),this.memCache.set(D,Promise.resolve(X)),X}}if(!this.config.online)throw new Error(`${this.config.label} Offline and value not cached for ${z}`);const W=L(this.s3ClientLite.getObject(D)).then(async([X,J])=>{const Z={$metadata:X.$metadata,ETag:X.ETag,data:X.Body};return this.config.log(`${J}ms ${$.operation} ${$.ref.bucket}/${$.ref.key}@${$.version} => ${Z.VersionId}`),Z}).catch((X)=>{if(X?.name==="304")return{$metadata:{httpStatusCode:304},data:void 0};else throw X});if($.useCache!==!1){if(this.memCache.set(D,W),this.diskCache)W.then((X)=>{H(`${D.Bucket}${D.Key}${D.VersionId}`,X,this.diskCache).then(()=>this.config.log(`STORE ${D.Bucket}${D.Key}`))})}return W}async delete($,D={}){return this.putAll(new Map([[$,void 0]]),D)}async put($,D,z={}){return this.putAll(new Map([[$,D]]),z)}async putAll($,D={}){const z=new Map([...$].map(([X,J])=>[{bucket:X.bucket||this.config.defaultBucket||this.config.defaultManifest.bucket,key:typeof X==="string"?X:X.key},J])),W=(D?.manifests||[this.config.defaultManifest]).map((X)=>({...this.config.defaultManifest,...X}));return this._putAll(z,{manifests:W,await:D.await||this.config.online?"remote":"local"})}async _putAll($,D){const z=new Map,W=new Promise(async(X,J)=>{const Z=new Map,O=[];$.forEach((Q,Y)=>{if(Q!==void 0){let B=this.config.useVersioning?void 0:E();z.set(Y,Q),O.push(this._putObject({operation:"PUT_CONTENT",ref:Y,value:Q,version:B}).then((F)=>{if(this.config.useVersioning)if(F.VersionId===void 0)throw console.error(F),Error(`Bucket ${Y.bucket} is not version enabled!`);else B=F.VersionId;Z.set(Y,B)}))}else O.push(this._deleteObject({ref:Y}).then((B)=>{Z.set(Y,void 0)}))}),await Promise.all(O).catch(J),X(Z)});return Promise.all(D.manifests.map((X)=>{return this.getOrCreateManifest(X).updateContent(z,W,{await:D.await,isLoad:D.isLoad===!0})}))}async _putObject($){const D=JSON.stringify($.value,null,2);let z;if(this.config.useVersioning)z={Bucket:$.ref.bucket,Key:$.ref.key,ContentType:"application/json",Body:D,...this.config.useChecksum&&{ChecksumSHA256:await Z0(D)}};else z={Bucket:$.ref.bucket,Key:`${$.ref.key}${$.version?`@${$.version}`:""}`,ContentType:"application/json",Body:D,...this.config.useChecksum&&{ChecksumSHA256:await Z0(D)}};const[W,X]=await L(this.s3ClientLite.putObject(z));if(this.config.log(`${X}ms ${$.operation} ${z.Bucket}/${z.Key} => ${W.VersionId}`),this.diskCache){const J=`${z.Bucket}${z.Key}${$.version||W.VersionId}`;await H(J,{$metadata:{httpStatusCode:200},etag:W.ETag,data:JSON.parse(D)},this.diskCache).then(()=>this.config.log(`STORE ${J}`))}return W}async _deleteObject($){const D={Bucket:$.ref.bucket,Key:$.ref.key},[z,W]=await L(this.s3ClientLite.deleteObject(D));return this.config.log(`${W}ms ${$.operation||"DELETE"} ${$.ref.bucket}/${$.ref.key} (${z.$metadata.httpStatusCode})}`),z}subscribe($,D,z){const W={...this.config.defaultManifest,...z?.manifest},X={key:typeof $==="string"?$:$.key,bucket:$.bucket||this.config.defaultBucket||W.bucket},J=this.getOrCreateManifest(W),Z=J.subscribe(X,D);return this.get(X,{manifest:W}).then((O)=>{this.config.log(`NOTIFY (initial) ${U(X)}`),queueMicrotask(()=>{D(O,void 0),J.poll()})}).catch((O)=>{D(void 0,O)}),Z}refresh(){return Promise.all([...this.manifests.values()].map(($)=>$.poll()))}get subscriberCount(){return[...this.manifests.values()].reduce(($,D)=>$+D.subscriberCount,0)}}export{O0 as MPS3};
{
"name": "mps3",
"description": "Provide clientside multiplayer and optimistic updates over any s3-compatible storage API",
"version": "0.0.77",
"version": "0.0.78",
"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