UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 2.51 kB
import*as Handlers from"./handlers/handlers.js";export class TraceParseProgressEvent extends Event{data;static eventName="traceparseprogress";constructor(e,t={bubbles:!0}){super(TraceParseProgressEvent.eventName,t),this.data=e}}export class TraceProcessor extends EventTarget{#e;#t;#s;#r="IDLE";static createWithAllHandlers(){return new TraceProcessor(Handlers.ModelHandlers)}constructor(e,{pauseDuration:t=1,eventsPerChunk:s=15e3}={}){super(),this.#n(e),this.#e={Meta:Handlers.ModelHandlers.Meta,...e},this.#t=t,this.#s=s}#n(e){if(Object.keys(e).length===Object.keys(Handlers.ModelHandlers).length)return;const t=new Set;for(const[s,r]of Object.entries(e)){t.add(s);for(const e of r.deps?.()||[])t.add(e)}const s=new Set(Object.keys(e));t.delete("Meta");for(const e of t)if(!s.has(e))throw new Error(`Required handler ${e} not provided.`)}reset(){if("PARSING"===this.#r)throw new Error("Trace processor can't reset while parsing.");const e=Object.values(this.#e);for(const t of e)t.reset();this.#r="IDLE"}async parse(e,t=!1){if("IDLE"!==this.#r)throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#r}`);try{this.#r="PARSING",await this.#a(e,t),this.#r="FINISHED_PARSING"}catch(e){throw this.#r="ERRORED_WHILE_PARSING",e}}async#a(e,t){const s=new TraceEventIterator(e,this.#t,this.#s),r=[...sortHandlers(this.#e).values()];for(const e of r)e.reset();for(const e of r)e.initialize?.(t);for await(const e of s)if(2!==e.kind)for(const t of r)t.handleEvent(e.data);else this.dispatchEvent(new TraceParseProgressEvent(e.data));for(const e of r)await(e.finalize?.())}get data(){if("FINISHED_PARSING"!==this.#r)return null;const e={};for(const[t,s]of Object.entries(this.#e))Object.assign(e,{[t]:s.data()});return e}}export function sortHandlers(e){const t=new Map,s=new Set,r=n=>{if(t.has(n))return;if(s.has(n)){let e="";for(const t of s)(e||t===n)&&(e+=`${t}->`);throw e+=n,new Error(`Found dependency cycle in trace event handlers: ${e}`)}s.add(n);const a=e[n];if(!a)return;const o=a.deps?.();o&&o.forEach(r),t.set(n,a)};for(const t of Object.keys(e))r(t);return t}class TraceEventIterator{traceEvents;pauseDuration;eventsPerChunk;#o;constructor(e,t,s){this.traceEvents=e,this.pauseDuration=t,this.eventsPerChunk=s,this.#o=0}async*[Symbol.asyncIterator](){for(let e=0,t=this.traceEvents.length;e<t;e++)++this.#o%this.eventsPerChunk==0&&(yield{kind:2,data:{index:e,total:t}},await new Promise((e=>setTimeout(e,this.pauseDuration)))),yield{kind:1,data:this.traceEvents[e]}}}