UNPKG

@robotical/martyblocks

Version:

MartyBlocks based on Scratch for Marty the Robot by Robotical

1 lines 4.45 kB
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.ScratchStorage=t():e.ScratchStorage=t()}(self,()=>(()=>{"use strict";const e="Task cancelled",t="Task cost exceeds maximum bucket size";function s(){let e,t;return{promise:new Promise((s,i)=>{e=s,t=i}),resolve:e,reject:t}}var i=class{cost;promise;run;cancel;constructor(e,t={}){this.cost=t.cost??1;let{promise:i,resolve:n,reject:r}=s();this.promise=i,this.cancel=e=>{r(e)},this.run=async()=>{try{n(await e())}catch(e){r(e)}}}},n=class{burstLimit;sustainRate;queueCostLimit;concurrencyLimit;tokenCount;runningTasks=0;pendingTaskRecords=[];lastRefillTime=Date.now();onTaskAdded=s().resolve;onTaskFinished=s().resolve;constructor(e){this.burstLimit=e.burstLimit,this.sustainRate=e.sustainRate,this.tokenCount=e.startingTokens??e.burstLimit,this.queueCostLimit=e.queueCostLimit??1/0,this.concurrencyLimit=e.concurrency??1,this.runTasks()}get length(){return this.pendingTaskRecords.length}get options(){return{burstLimit:this.burstLimit,sustainRate:this.sustainRate,startingTokens:this.tokenCount,queueCostLimit:this.queueCostLimit,concurrency:this.concurrencyLimit}}do(e,s={}){let n=new i(e,s);return n.cost>this.burstLimit?Promise.reject(Error(t)):this.queueCostLimit<1/0&&this.pendingTaskRecords.reduce((e,t)=>e+t.cost,n.cost)>this.queueCostLimit?Promise.reject(Error("Queue cost limit exceeded")):(this.pendingTaskRecords.push(n),s.signal?.addEventListener("abort",()=>{this.cancel(n.promise,Error("Task aborted"))}),this.onTaskAdded(),n.promise)}cancel(t,s){let i=this.pendingTaskRecords.findIndex(e=>e.promise===t);if(-1!==i){let[t]=this.pendingTaskRecords.splice(i,1);return t.cancel(s??Error(e)),!0}return!1}cancelAll(t){let s=this.pendingTaskRecords;return this.pendingTaskRecords=[],t??=Error(e),s.forEach(e=>{e.cancel(t)}),s.length}refillAndSpend(e){return this.refill(),this.spend(e)}refill(){let e=Date.now(),t=e-this.lastRefillTime;if(t<=0)return;this.lastRefillTime=e;let s=t/1e3*this.sustainRate;this.tokenCount=Math.min(this.burstLimit,this.tokenCount+s)}spend(e){return this.tokenCount>=e&&(this.tokenCount-=e,!0)}async runTasks(){for(;;){let e=this.pendingTaskRecords.shift();if(!e){let{promise:e,resolve:t}=s();this.onTaskAdded=t,await e;continue}if(e.cost>this.burstLimit)e.cancel(Error(t));else if(this.refillAndSpend(e.cost)){if(this.runningTasks>=this.concurrencyLimit){let{promise:e,resolve:t}=s();this.onTaskFinished=t,await e}this.runTask(e)}else{this.pendingTaskRecords.unshift(e);let t=Math.max(e.cost-this.tokenCount,0),s=Math.ceil(1e3*t/this.sustainRate);await new Promise(e=>setTimeout(e,s))}}}async runTask(e){this.runningTasks++;try{await e.run()}finally{this.runningTasks--,this.onTaskFinished()}}};const r={burstLimit:64,sustainRate:64,concurrency:64},o=new class{queues;defaultOptions;constructor(e,t){this.queues=new Map(t),this.defaultOptions=e}create(e,t={}){let s=new n({...this.defaultOptions,...t});return this.queues.set(e,s),s}get(e){return this.queues.get(e)}getOrCreate(e,t={}){return this.get(e)??this.create(e,t)}options(){return{...this.defaultOptions}}}({burstLimit:5,sustainRate:1,concurrency:1}),a=globalThis.Headers;var u;!function(e){e.ProjectId="X-Project-ID",e.RunId="X-Run-ID"}(u||(u={}));const c=new a;let l=0;const h=[];let d;return postMessage({support:{fetch:!0}}),self.addEventListener("message",async e=>{let{data:t}=e;0!==l||d||(d=setInterval(()=>{h.length&&(postMessage(h.slice(),h.map(e=>e.buffer).filter(Boolean)),h.length=0),0===l&&(clearInterval(d),d=void 0)},1)),l++;try{const e=await((e,t,s)=>{t=(e=>{if((()=>{if(!("undefined"!=typeof self&&self&&self.location&&self.location.search&&self.location.search.split(/[?&]/)||[]).includes("scratchMetadata=1"))return!1;for(const e of c)return!0;return!1})()){const t=Object.assign({},e);if(t.headers=new a(c),e&&e.headers){const s=e.headers instanceof a?e.headers:new a(e.headers);for(const[e,i]of s.entries())t.headers.set(e,i)}return t}return e})(t);let i=null==s?void 0:s.queueName;return i||(e=new Request(e,t),i=new URL(e.url).hostname),o.getOrCreate(i,null==s?void 0:s.queueOptions).do(()=>fetch(e,t))})(t.url,t.options,{queueOptions:r}),s={id:t.id};if(e.ok)s.buffer=await e.arrayBuffer();else{if(404!==e.status)throw e.status;s.buffer=null}h.push(s)}catch(e){h.push({id:t.id,error:(null==e?void 0:e.message)||"Failed request: ".concat(t.url)})}finally{l--}}),{}})());