@php-wasm/progress 3.0.15 → 3.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var w=r=>{throw TypeError(r)};var E=(r,e,s)=>e.has(r)||w("Cannot "+s);var o=(r,e,s)=>(E(r,e,"read from private field"),s?s.call(r):e.get(r)),c=(r,e,s)=>e.has(r)?w("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,s),p=(r,e,s,t)=>(E(r,e,"write to private field"),t?t.call(r,s):e.set(r,s),s),_=(r,e,s)=>(E(r,e,"access private method"),s);var P=(r,e,s,t)=>({set _(i){p(r,e,i,s)},get _(){return o(r,e,t)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("@php-wasm/node-polyfills");const I=require("@php-wasm/logger"),R=5*1024*1024;var h,l,v,O;class k extends EventTarget{constructor(){super(...arguments);c(this,v);c(this,h,{});c(this,l,{})}expectAssets(s){for(const[t,i]of Object.entries(s)){const n="http://example.com/",a=new URL(t,n).pathname.split("/").pop();a in o(this,h)||(o(this,h)[a]=i),a in o(this,l)||(o(this,l)[a]=0)}}async monitorFetch(s){const t=await s;return C(t,n=>{_(this,v,O).call(this,t.url,n.detail.loaded,n.detail.total)})}}h=new WeakMap,l=new WeakMap,v=new WeakSet,O=function(s,t,i){const n=new URL(s,"http://example.com").pathname.split("/").pop();i?n in o(this,h)||(o(this,h)[n]=i,o(this,l)[n]=t):i=o(this,h)[n],n in o(this,l)||I.logger.warn(`Registered a download #progress of an unregistered file "${n}". This may cause a sudden **decrease** in the #progress percentage as the length number of bytes increases during the download.`),o(this,l)[n]=t,this.dispatchEvent(new CustomEvent("progress",{detail:{loaded:y(o(this,l)),total:y(o(this,h))}}))};function y(r){return Object.values(r).reduce((e,s)=>e+s,0)}function C(r,e){const s=r.headers.get("content-length")||"",t=parseInt(s,10)||R;return new Response(M(r.body,t,e),{status:r.status,statusText:r.statusText,headers:r.headers})}function M(r,e,s){function t(i,n){s(new CustomEvent("progress",{detail:{loaded:i,total:n}}))}return new ReadableStream({async start(i){if(!r){i.close();return}const n=r.getReader();let d=0;for(;;)try{const{done:a,value:m}=await n.read();if(m&&(d+=m.byteLength),a){t(d,d),i.close();break}else t(d,e),i.enqueue(m)}catch(a){I.logger.error({e:a}),i.error(a);break}}})}var g,f,u,b;class S extends EventTarget{constructor(){super(...arguments);c(this,u);c(this,g);c(this,f);p(this,g,{}),p(this,f,0),this.progress=0,this.mode="REAL_TIME",this.caption=""}partialObserver(s,t=""){const i=++P(this,f)._;return o(this,g)[i]=0,n=>{const{loaded:d,total:a}=(n==null?void 0:n.detail)||{};o(this,g)[i]=d/a*s,_(this,u,b).call(this,this.totalProgress,"REAL_TIME",t)}}slowlyIncrementBy(s){const t=++P(this,f)._;o(this,g)[t]=s,_(this,u,b).call(this,this.totalProgress,"SLOWLY_INCREMENT")}get totalProgress(){return Object.values(o(this,g)).reduce((s,t)=>s+t,0)}}g=new WeakMap,f=new WeakMap,u=new WeakSet,b=function(s,t,i){this.dispatchEvent(new CustomEvent("progress",{detail:{progress:s,mode:t,caption:i}}))};const T=1e-5;class L extends EventTarget{constructor({weight:e=1,caption:s="",fillTime:t=4}={}){super(),this._selfWeight=1,this._selfDone=!1,this._selfProgress=0,this._selfCaption="",this._isFilling=!1,this._subTrackers=[],this._weight=e,this._selfCaption=s,this._fillTime=t}stage(e,s=""){if(e||(e=this._selfWeight),this._selfWeight-e<-1e-5)throw new Error(`Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.`);this._selfWeight-=e;const t=new L({caption:s,weight:e,fillTime:this._fillTime});return this._subTrackers.push(t),t.addEventListener("progress",()=>this.notifyProgress()),t.addEventListener("done",()=>{this.done&&this.notifyDone()}),t}fillSlowly({stopBeforeFinishing:e=!0}={}){if(this._isFilling)return;this._isFilling=!0;const t=this._fillTime/100;this._fillInterval=setInterval(()=>{this.set(this._selfProgress+1),e&&this._selfProgress>=99&&clearInterval(this._fillInterval)},t)}set(e){this._selfProgress=Math.min(e,100),this.notifyProgress(),this._selfProgress+T>=100&&this.finish()}finish(){this._fillInterval&&clearInterval(this._fillInterval),this._selfDone=!0,this._selfProgress=100,this._isFilling=!1,this._fillInterval=void 0,this.notifyProgress(),this.notifyDone()}get caption(){for(let e=this._subTrackers.length-1;e>=0;e--)if(!this._subTrackers[e].done){const s=this._subTrackers[e].caption;if(s)return s}return this._selfCaption}setCaption(e){this._selfCaption=e,this.notifyProgress()}get done(){return this.progress+T>=100}get progress(){if(this._selfDone)return 100;const e=this._subTrackers.reduce((s,t)=>s+t.progress*t.weight,this._selfProgress*this._selfWeight);return Math.round(e*1e4)/1e4}get weight(){return this._weight}get observer(){return this._progressObserver||(this._progressObserver=e=>{this.set(e)}),this._progressObserver}get loadingListener(){return this._loadingListener||(this._loadingListener=e=>{this.set(e.detail.loaded/e.detail.total*100)}),this._loadingListener}pipe(e){e.setProgress({progress:this.progress,caption:this.caption}),this.addEventListener("progress",s=>{e.setProgress({progress:s.detail.progress,caption:s.detail.caption})}),this.addEventListener("done",()=>{e.setLoaded()})}addEventListener(e,s){super.addEventListener(e,s)}removeEventListener(e,s){super.removeEventListener(e,s)}notifyProgress(){const e=this;this.dispatchEvent(new CustomEvent("progress",{detail:{get progress(){return e.progress},get caption(){return e.caption}}}))}notifyDone(){this.dispatchEvent(new CustomEvent("done"))}}exports.EmscriptenDownloadMonitor=k;exports.ProgressObserver=S;exports.ProgressTracker=L;exports.cloneResponseMonitorProgress=C;exports.cloneStreamMonitorProgress=M;
1
+ "use strict";var y=r=>{throw TypeError(r)};var E=(r,e,s)=>e.has(r)||y("Cannot "+s);var o=(r,e,s)=>(E(r,e,"read from private field"),s?s.call(r):e.get(r)),c=(r,e,s)=>e.has(r)?y("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,s),p=(r,e,s,t)=>(E(r,e,"write to private field"),t?t.call(r,s):e.set(r,s),s),_=(r,e,s)=>(E(r,e,"access private method"),s);var P=(r,e,s,t)=>({set _(i){p(r,e,i,s)},get _(){return o(r,e,t)}});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("@php-wasm/node-polyfills");const I=require("@php-wasm/logger"),R=5*1024*1024;var h,l,v,O;class k extends EventTarget{constructor(){super(...arguments);c(this,v);c(this,h,{});c(this,l,{})}expectAssets(s){for(const[t,i]of Object.entries(s)){const n="http://example.com/",a=new URL(t,n).pathname.split("/").pop();a in o(this,h)||(o(this,h)[a]=i),a in o(this,l)||(o(this,l)[a]=0)}}async monitorFetch(s){const t=await s;return C(t,n=>{_(this,v,O).call(this,t.url,n.detail.loaded,n.detail.total)})}}h=new WeakMap,l=new WeakMap,v=new WeakSet,O=function(s,t,i){const n=new URL(s,"http://example.com").pathname.split("/").pop();i?n in o(this,h)||(o(this,h)[n]=i,o(this,l)[n]=t):i=o(this,h)[n],n in o(this,l)||I.logger.warn(`Registered a download #progress of an unregistered file "${n}". This may cause a sudden **decrease** in the #progress percentage as the length number of bytes increases during the download.`),o(this,l)[n]=t,this.dispatchEvent(new CustomEvent("progress",{detail:{loaded:T(o(this,l)),total:T(o(this,h))}}))};function T(r){return Object.values(r).reduce((e,s)=>e+s,0)}function C(r,e){const s=r.headers.get("content-length")||"",t=parseInt(s,10)||R;return new Response(M(r.body,t,e),{status:r.status,statusText:r.statusText,headers:r.headers})}function M(r,e,s){function t(i,n){s(new CustomEvent("progress",{detail:{loaded:i,total:n}}))}return new ReadableStream({async start(i){if(!r){i.close();return}const n=r.getReader();let d=0;for(;;)try{const{done:a,value:m}=await n.read();if(m&&(d+=m.byteLength),a){t(d,d),i.close();break}else t(d,e),i.enqueue(m)}catch(a){I.logger.error({e:a}),i.error(a);break}}})}var g,f,u,L;class S extends EventTarget{constructor(){super(...arguments);c(this,u);c(this,g);c(this,f);p(this,g,{}),p(this,f,0),this.progress=0,this.mode="REAL_TIME",this.caption=""}partialObserver(s,t=""){const i=++P(this,f)._;return o(this,g)[i]=0,n=>{const{loaded:d,total:a}=(n==null?void 0:n.detail)||{};o(this,g)[i]=d/a*s,_(this,u,L).call(this,this.totalProgress,"REAL_TIME",t)}}slowlyIncrementBy(s){const t=++P(this,f)._;o(this,g)[t]=s,_(this,u,L).call(this,this.totalProgress,"SLOWLY_INCREMENT")}get totalProgress(){return Object.values(o(this,g)).reduce((s,t)=>s+t,0)}}g=new WeakMap,f=new WeakMap,u=new WeakSet,L=function(s,t,i){this.dispatchEvent(new CustomEvent("progress",{detail:{progress:s,mode:t,caption:i}}))};const b=1e-5;class w extends EventTarget{constructor({weight:e=1,caption:s="",fillTime:t=4}={}){super(),this._selfWeight=1,this._selfDone=!1,this._selfProgress=0,this._selfCaption="",this._isFilling=!1,this._subTrackers=[],this._weight=e,this._selfCaption=s,this._fillTime=t}stage(e,s=""){if(e||(e=this._selfWeight),this._selfWeight-e<-b)throw new Error(`Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.`);this._selfWeight-=e;const t=new w({caption:s,weight:e,fillTime:this._fillTime});return this._subTrackers.push(t),t.addEventListener("progress",()=>this.notifyProgress()),t.addEventListener("done",()=>{this.done&&this.notifyDone()}),t}fillSlowly({stopBeforeFinishing:e=!0}={}){if(this._isFilling)return;this._isFilling=!0;const t=this._fillTime/100;this._fillInterval=setInterval(()=>{this.set(this._selfProgress+1),e&&this._selfProgress>=99&&clearInterval(this._fillInterval)},t)}set(e){this._selfProgress=Math.min(e,100),this.notifyProgress(),this._selfProgress+b>=100&&this.finish()}finish(){this._fillInterval&&clearInterval(this._fillInterval),this._selfDone=!0,this._selfProgress=100,this._isFilling=!1,this._fillInterval=void 0,this.notifyProgress(),this.notifyDone()}get caption(){for(let e=this._subTrackers.length-1;e>=0;e--)if(!this._subTrackers[e].done){const s=this._subTrackers[e].caption;if(s)return s}return this._selfCaption}setCaption(e){this._selfCaption=e,this.notifyProgress()}get done(){return this.progress+b>=100}get progress(){if(this._selfDone)return 100;const e=this._subTrackers.reduce((s,t)=>s+t.progress*t.weight,this._selfProgress*this._selfWeight);return Math.round(e*1e4)/1e4}get weight(){return this._weight}get observer(){return this._progressObserver||(this._progressObserver=e=>{this.set(e)}),this._progressObserver}get loadingListener(){return this._loadingListener||(this._loadingListener=e=>{this.set(e.detail.loaded/e.detail.total*100)}),this._loadingListener}pipe(e){e.setProgress({progress:this.progress,caption:this.caption}),this.addEventListener("progress",s=>{e.setProgress({progress:s.detail.progress,caption:s.detail.caption})}),this.addEventListener("done",()=>{e.setLoaded()})}addEventListener(e,s){super.addEventListener(e,s)}removeEventListener(e,s){super.removeEventListener(e,s)}notifyProgress(){const e=this;this.dispatchEvent(new CustomEvent("progress",{detail:{get progress(){return e.progress},get caption(){return e.caption}}}))}notifyDone(){this.dispatchEvent(new CustomEvent("done"))}}exports.EmscriptenDownloadMonitor=k;exports.ProgressObserver=S;exports.ProgressTracker=w;exports.cloneResponseMonitorProgress=C;exports.cloneStreamMonitorProgress=M;
2
2
  //# sourceMappingURL=index.cjs.map
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/progress/src/lib/emscripten-download-monitor.ts","../../../../packages/php-wasm/progress/src/lib/progress-observer.ts","../../../../packages/php-wasm/progress/src/lib/progress-tracker.ts"],"sourcesContent":["import { logger } from '@php-wasm/logger';\n/*\n * An approximate file length to use when the actual\n * length number of bytes is missing.\n *\n * This may happen when the files are compressed before transmission\n * and no content-length header is being sent.\n *\n * The approximation isn't accurate, but it's better than nothing.\n * It's not about being exact but about giving the user a rough sense\n * of #progress.\n */\nconst FALLBACK_FILE_SIZE = 5 * 1024 * 1024;\n\n/**\n * Monitors the download #progress of Emscripten modules\n *\n * Usage:\n *\n * ```js\n * const downloadMonitor = new EmscriptenDownloadMonitor();\n * \t const php = await startPHP(\n * phpLoaderModule,\n * 'web',\n * downloadMonitor.phpArgs\n * );\n * downloadMonitor.addEventListener('#progress', (e) => {\n * console.log( e.detail.#progress);\n * })\n * ```\n */\nexport class EmscriptenDownloadMonitor extends EventTarget {\n\t#assetsSizes: Record<string, number> = {};\n\t#progress: Record<string, number> = {};\n\n\texpectAssets(assets: Record<string, number>) {\n\t\tfor (const [urlLike, size] of Object.entries(assets)) {\n\t\t\tconst dummyBaseUrl = 'http://example.com/';\n\t\t\tconst pathname = new URL(urlLike, dummyBaseUrl).pathname;\n\t\t\tconst filename = pathname.split('/').pop()!;\n\t\t\tif (!(filename in this.#assetsSizes)) {\n\t\t\t\tthis.#assetsSizes[filename] = size;\n\t\t\t}\n\t\t\tif (!(filename in this.#progress)) {\n\t\t\t\tthis.#progress[filename] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync monitorFetch(fetchPromise: Promise<Response>): Promise<Response> {\n\t\tconst response = await fetchPromise;\n\t\tconst onProgress = (event: CustomEvent<DownloadProgress>) => {\n\t\t\tthis.#notify(response.url, event.detail.loaded, event.detail.total);\n\t\t};\n\t\treturn cloneResponseMonitorProgress(response, onProgress);\n\t}\n\n\t/**\n\t * Notifies about the download #progress of a file.\n\t *\n\t * @param file The file name.\n\t * @param loaded The number of bytes of that file loaded so far.\n\t * @param fileSize The length number of bytes in the loaded file.\n\t */\n\t#notify(file: string, loaded: number, fileSize: number) {\n\t\tconst fileName = new URL(file, 'http://example.com').pathname\n\t\t\t.split('/')\n\t\t\t.pop()!;\n\t\tif (!fileSize) {\n\t\t\tfileSize = this.#assetsSizes[fileName];\n\t\t} else if (!(fileName in this.#assetsSizes)) {\n\t\t\tthis.#assetsSizes[fileName] = fileSize;\n\t\t\tthis.#progress[fileName] = loaded;\n\t\t}\n\t\tif (!(fileName in this.#progress)) {\n\t\t\tlogger.warn(\n\t\t\t\t`Registered a download #progress of an unregistered file \"${fileName}\". ` +\n\t\t\t\t\t`This may cause a sudden **decrease** in the #progress percentage as the ` +\n\t\t\t\t\t`length number of bytes increases during the download.`\n\t\t\t);\n\t\t}\n\n\t\tthis.#progress[fileName] = loaded;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded: sumValues(this.#progress),\n\t\t\t\t\ttotal: sumValues(this.#assetsSizes),\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n\nfunction sumValues(obj: Record<string, number>) {\n\treturn Object.values(obj).reduce((length, value) => length + value, 0);\n}\n\nexport default EmscriptenDownloadMonitor;\n\nexport interface DownloadProgress {\n\t/**\n\t * The number of bytes loaded so far.\n\t */\n\tloaded: number;\n\t/**\n\t * The length number of bytes to load.\n\t */\n\ttotal: number;\n}\n\n/**\n * Clones a fetch Response object and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param response The fetch Response object to clone.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned response\n */\nexport function cloneResponseMonitorProgress(\n\tresponse: Response,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): Response {\n\tconst contentLength = response.headers.get('content-length') || '';\n\tconst length = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;\n\n\treturn new Response(\n\t\tcloneStreamMonitorProgress(response.body, length, onProgress),\n\t\t{\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t}\n\t);\n}\n\n/**\n * Clones a ReadableStream and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param stream The ReadableStream to clone.\n * @param total The total number of bytes to load.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned ReadableStream\n */\nexport function cloneStreamMonitorProgress(\n\tstream: ReadableStream<Uint8Array> | null,\n\ttotal: number,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): ReadableStream<Uint8Array> {\n\tfunction notify(loaded: number, total: number) {\n\t\tonProgress(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded,\n\t\t\t\t\ttotal,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\treturn new ReadableStream({\n\t\tasync start(controller) {\n\t\t\tif (!stream) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reader = stream.getReader();\n\t\t\tlet loaded = 0;\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\tloaded += value.byteLength;\n\t\t\t\t\t}\n\t\t\t\t\tif (done) {\n\t\t\t\t\t\tnotify(loaded, loaded);\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(loaded, total);\n\t\t\t\t\t\tcontroller.enqueue(value);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error({ e });\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport type DownloadProgressCallback = (progress: DownloadProgress) => void;\n","import type { DownloadProgress } from './emscripten-download-monitor';\n\nexport type ProgressMode =\n\t/**\n\t * Real-time progress is used when we get real-time reports\n\t * about the progress.\n\t */\n\t| 'REAL_TIME'\n\n\t/**\n\t * Slowly increment progress is used when we don't know how long\n\t * an operation will take and just want to keep slowly incrementing\n\t * the progress bar.\n\t */\n\t| 'SLOWLY_INCREMENT';\n\nexport type ProgressObserverEvent = {\n\tprogress: number;\n\tmode: ProgressMode;\n\tcaption: string;\n};\n\nexport class ProgressObserver extends EventTarget {\n\t#observedProgresses: Record<number, number> = {};\n\t#lastObserverId = 0;\n\n\tprogress = 0;\n\tmode: ProgressMode = 'REAL_TIME';\n\tcaption = '';\n\n\tpartialObserver(progressBudget: number, caption = '') {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = 0;\n\t\treturn (progress: CustomEvent<DownloadProgress>) => {\n\t\t\tconst { loaded, total } = progress?.detail || {};\n\t\t\tthis.#observedProgresses[id] = (loaded / total) * progressBudget;\n\t\t\tthis.#onProgress(this.totalProgress, 'REAL_TIME', caption);\n\t\t};\n\t}\n\n\tslowlyIncrementBy(progress: number) {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = progress;\n\t\tthis.#onProgress(this.totalProgress, 'SLOWLY_INCREMENT');\n\t}\n\n\tget totalProgress() {\n\t\treturn Object.values(this.#observedProgresses).reduce(\n\t\t\t(total, progress) => total + progress,\n\t\t\t0\n\t\t);\n\t}\n\n\t#onProgress(progress: number, mode: ProgressMode, caption?: string) {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tprogress,\n\t\t\t\t\tmode,\n\t\t\t\t\tcaption,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n","/**\n * Options for customizing the progress tracker.\n */\nexport interface ProgressTrackerOptions {\n\t/** The weight of the progress, a number between 0 and 1. */\n\tweight?: number;\n\t/** The caption to display during progress, a string. */\n\tcaption?: string;\n\t/** The time in milliseconds to fill the progress, a number. */\n\tfillTime?: number;\n}\n\n/**\n * Custom event providing information about a loading process.\n */\nexport type LoadingEvent = CustomEvent<{\n\t/** The number representing how much was loaded. */\n\tloaded: number;\n\t/** The number representing how much needs to loaded in total. */\n\ttotal: number;\n}>;\n\n/**\n * Custom event providing progress details.\n */\nexport type ProgressTrackerEvent = CustomEvent<ProgressDetails>;\n\n/**\n * Custom event providing progress details when the task is done.\n */\nexport type DoneEvent = CustomEvent<ProgressDetails>;\n\nexport interface ProgressDetails {\n\t/** The progress percentage as a number between 0 and 100. */\n\tprogress: number;\n\t/** The caption to display during progress, a string. */\n\tcaption: string;\n}\n\n/**\n * ProgressObserver A function that receives progress updates.\n *\n * @param progress The progress percentage as a number between 0 and 100.\n */\ntype ProgressObserver = (progress: number) => void;\n\n/**\n * Listener A function for handling specific event types.\n *\n * @param event The event of type T.\n */\nexport type Listener<T> = (event: T) => void;\n\nexport type TSCompatibleListener<T> =\n\t| EventListenerOrEventListenerObject\n\t| null\n\t| Listener<T>;\n\nexport interface ProgressReceiver {\n\tsetProgress(details: ProgressDetails): any;\n\tsetLoaded(): any;\n}\n\n/*\n * Like Number.EPSILON, but better tuned to tracking progress.\n *\n * With Number.EPSILON, progress like 99.99999999999997 is still\n * considered to be below 100 – this is highly undeisrable.\n */\nconst PROGRESS_EPSILON = 0.00001;\n\n/**\n * The ProgressTracker class is a tool for tracking progress in an operation\n * that is divided into multiple stages. It allows you to create sub-trackers\n * for each stage, with individual weights and captions. The main tracker\n * automatically calculates the progress based on the weighted sum of each\n * sub-tracker's progress. This makes it easy to keep track of a complex,\n * multi-stage process and report progress in a user-friendly way.\n *\n * After creating the sub-trackers, you can call the set() method to update the\n * progress of the current stage. You can also call the finish() method to mark\n * the current stage as complete and move on to the next one. Alternatively,\n * you can call the fillSlowly() method to simulate progress filling up slowly\n * to 100% before calling finish().\n *\n * @example\n * ```ts\n * const tracker = new ProgressTracker();\n * tracker.addEventListener('progress', (e) => {\n * \t\tconsole.log(\n * \t\t\t\te.detail.progress,\n * \t\t\t\te.detail.caption\n * \t\t);\n * });\n *\n * const stage1 = tracker.stage(0.5, 'Calculating pi digits');\n * const stage2 = tracker.stage(0.5, 'Downloading data');\n *\n * stage1.fillSlowly();\n * await calc100DigitsOfPi();\n * stage1.finish();\n *\n * await fetchWithProgress(function onProgress(loaded, total) {\n * \t\tstage2.set( loaded / total * 100);\n * });\n * stage2.finish();\n */\nexport class ProgressTracker extends EventTarget {\n\tprivate _selfWeight = 1;\n\tprivate _selfDone = false;\n\tprivate _selfProgress = 0;\n\tprivate _selfCaption = '';\n\tprivate _weight: number;\n\tprivate _progressObserver?: ProgressObserver;\n\tprivate _loadingListener?: Listener<LoadingEvent>;\n\tprivate _isFilling = false;\n\tprivate _fillTime: number;\n\tprivate _fillInterval?: any;\n\tprivate _subTrackers: ProgressTracker[] = [];\n\n\tconstructor({\n\t\tweight = 1,\n\t\tcaption = '',\n\t\tfillTime = 4,\n\t}: ProgressTrackerOptions = {}) {\n\t\tsuper();\n\t\tthis._weight = weight;\n\t\tthis._selfCaption = caption;\n\t\tthis._fillTime = fillTime;\n\t}\n\n\t/**\n\t * Creates a new sub-tracker with a specific weight.\n\t *\n\t * The weight determines what percentage of the overall progress\n\t * the sub-tracker represents. For example, if the main tracker is\n\t * monitoring a process that has two stages, and the first stage\n\t * is expected to take twice as long as the second stage, you could\n\t * create the first sub-tracker with a weight of 0.67 and the second\n\t * sub-tracker with a weight of 0.33.\n\t *\n\t * The caption is an optional string that describes the current stage\n\t * of the operation. If provided, it will be used as the progress caption\n\t * for the sub-tracker. If not provided, the main tracker will look for\n\t * the next sub-tracker with a non-empty caption and use that as the progress\n\t * caption instead.\n\t *\n\t * Returns the newly-created sub-tracker.\n\t *\n\t * @throws {Error} If the weight of the new stage would cause the total weight of all stages to exceed 1.\n\t *\n\t * @param weight The weight of the new stage, as a decimal value between 0 and 1.\n\t * @param caption The caption for the new stage, which will be used as the progress caption for the sub-tracker.\n\t *\n\t * @example\n\t * ```ts\n\t * const tracker = new ProgressTracker();\n\t * const subTracker1 = tracker.stage(0.67, 'Slow stage');\n\t * const subTracker2 = tracker.stage(0.33, 'Fast stage');\n\t *\n\t * subTracker2.set(50);\n\t * subTracker1.set(75);\n\t * subTracker2.set(100);\n\t * subTracker1.set(100);\n\t * ```\n\t */\n\tstage(weight?: number, caption = ''): ProgressTracker {\n\t\tif (!weight) {\n\t\t\tweight = this._selfWeight;\n\t\t}\n\t\tif (this._selfWeight - weight < -PROGRESS_EPSILON) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot add a stage with weight ${weight} as the total weight of registered stages would exceed 1.`\n\t\t\t);\n\t\t}\n\t\tthis._selfWeight -= weight;\n\n\t\tconst subTracker = new ProgressTracker({\n\t\t\tcaption,\n\t\t\tweight,\n\t\t\tfillTime: this._fillTime,\n\t\t});\n\t\tthis._subTrackers.push(subTracker);\n\t\tsubTracker.addEventListener('progress', () => this.notifyProgress());\n\t\tsubTracker.addEventListener('done', () => {\n\t\t\tif (this.done) {\n\t\t\t\tthis.notifyDone();\n\t\t\t}\n\t\t});\n\t\treturn subTracker;\n\t}\n\n\t/**\n\t * Fills the progress bar slowly over time, simulating progress.\n\t *\n\t * The progress bar is filled in a 100 steps, and each step, the progress\n\t * is increased by 1. If `stopBeforeFinishing` is true, the progress bar\n\t * will stop filling when it reaches 99% so that you can call `finish()`\n\t * explicitly.\n\t *\n\t * If the progress bar is filling or already filled, this method does nothing.\n\t *\n\t * @example\n\t * ```ts\n\t * const progress = new ProgressTracker({ caption: 'Processing...' });\n\t * progress.fillSlowly();\n\t * ```\n\t *\n\t * @param options Optional options.\n\t */\n\tfillSlowly({ stopBeforeFinishing = true } = {}): void {\n\t\tif (this._isFilling) {\n\t\t\treturn;\n\t\t}\n\t\tthis._isFilling = true;\n\t\tconst steps = 100;\n\t\tconst interval = this._fillTime / steps;\n\t\tthis._fillInterval = setInterval(() => {\n\t\t\tthis.set(this._selfProgress + 1);\n\t\t\tif (stopBeforeFinishing && this._selfProgress >= 99) {\n\t\t\t\tclearInterval(this._fillInterval);\n\t\t\t}\n\t\t}, interval);\n\t}\n\n\tset(value: number): void {\n\t\tthis._selfProgress = Math.min(value, 100);\n\t\tthis.notifyProgress();\n\t\tif (this._selfProgress + PROGRESS_EPSILON >= 100) {\n\t\t\tthis.finish();\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this._fillInterval) {\n\t\t\tclearInterval(this._fillInterval);\n\t\t}\n\t\tthis._selfDone = true;\n\t\tthis._selfProgress = 100;\n\t\tthis._isFilling = false;\n\t\tthis._fillInterval = undefined;\n\t\tthis.notifyProgress();\n\t\tthis.notifyDone();\n\t}\n\n\tget caption(): string {\n\t\tfor (let i = this._subTrackers.length - 1; i >= 0; i--) {\n\t\t\tif (!this._subTrackers[i].done) {\n\t\t\t\tconst captionMaybe = this._subTrackers[i].caption;\n\t\t\t\tif (captionMaybe) {\n\t\t\t\t\treturn captionMaybe;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this._selfCaption;\n\t}\n\n\tsetCaption(caption: string) {\n\t\tthis._selfCaption = caption;\n\t\tthis.notifyProgress();\n\t}\n\n\tget done(): boolean {\n\t\treturn this.progress + PROGRESS_EPSILON >= 100;\n\t}\n\n\tget progress(): number {\n\t\tif (this._selfDone) {\n\t\t\treturn 100;\n\t\t}\n\t\tconst sum = this._subTrackers.reduce(\n\t\t\t(sum, tracker) => sum + tracker.progress * tracker.weight,\n\t\t\tthis._selfProgress * this._selfWeight\n\t\t);\n\t\treturn Math.round(sum * 10000) / 10000;\n\t}\n\n\tget weight(): number {\n\t\treturn this._weight;\n\t}\n\n\tget observer() {\n\t\tif (!this._progressObserver) {\n\t\t\tthis._progressObserver = (progress: number) => {\n\t\t\t\tthis.set(progress);\n\t\t\t};\n\t\t}\n\t\treturn this._progressObserver;\n\t}\n\n\tget loadingListener() {\n\t\tif (!this._loadingListener) {\n\t\t\tthis._loadingListener = (event: LoadingEvent) => {\n\t\t\t\tthis.set((event.detail.loaded / event.detail.total) * 100);\n\t\t\t};\n\t\t}\n\t\treturn this._loadingListener;\n\t}\n\n\tpipe(receiver: ProgressReceiver) {\n\t\treceiver.setProgress({\n\t\t\tprogress: this.progress,\n\t\t\tcaption: this.caption,\n\t\t});\n\t\tthis.addEventListener('progress', (event: ProgressTrackerEvent) => {\n\t\t\treceiver.setProgress({\n\t\t\t\tprogress: event.detail.progress,\n\t\t\t\tcaption: event.detail.caption,\n\t\t\t});\n\t\t});\n\t\tthis.addEventListener('done', () => {\n\t\t\treceiver.setLoaded();\n\t\t});\n\t}\n\n\toverride addEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.addEventListener(type, listener as any);\n\t}\n\n\toverride removeEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.removeEventListener(type, listener as any);\n\t}\n\n\tprivate notifyProgress() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tget progress() {\n\t\t\t\t\t\treturn self.progress;\n\t\t\t\t\t},\n\t\t\t\t\tget caption() {\n\t\t\t\t\t\treturn self.caption;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\tprivate notifyDone() {\n\t\tthis.dispatchEvent(new CustomEvent('done'));\n\t}\n}\n"],"names":["FALLBACK_FILE_SIZE","EmscriptenDownloadMonitor","__privateAdd","_EmscriptenDownloadMonitor_instances","_assetsSizes","_progress","assets","urlLike","size","dummyBaseUrl","filename","__privateGet","fetchPromise","response","cloneResponseMonitorProgress","event","__privateMethod","notify_fn","file","loaded","fileSize","fileName","logger","sumValues","obj","length","value","onProgress","contentLength","cloneStreamMonitorProgress","stream","total","notify","controller","reader","done","e","ProgressObserver","_ProgressObserver_instances","_observedProgresses","_lastObserverId","__privateSet","progressBudget","caption","id","__privateWrapper","progress","onProgress_fn","mode","PROGRESS_EPSILON","ProgressTracker","weight","fillTime","subTracker","stopBeforeFinishing","interval","i","captionMaybe","sum","tracker","receiver","type","listener","self"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/progress/src/lib/emscripten-download-monitor.ts","../../../../packages/php-wasm/progress/src/lib/progress-observer.ts","../../../../packages/php-wasm/progress/src/lib/progress-tracker.ts"],"sourcesContent":["import { logger } from '@php-wasm/logger';\n/*\n * An approximate file length to use when the actual\n * length number of bytes is missing.\n *\n * This may happen when the files are compressed before transmission\n * and no content-length header is being sent.\n *\n * The approximation isn't accurate, but it's better than nothing.\n * It's not about being exact but about giving the user a rough sense\n * of #progress.\n */\nconst FALLBACK_FILE_SIZE = 5 * 1024 * 1024;\n\n/**\n * Monitors the download #progress of Emscripten modules\n *\n * Usage:\n *\n * ```js\n * const downloadMonitor = new EmscriptenDownloadMonitor();\n * \t const php = await startPHP(\n * phpLoaderModule,\n * 'web',\n * downloadMonitor.phpArgs\n * );\n * downloadMonitor.addEventListener('#progress', (e) => {\n * console.log( e.detail.#progress);\n * })\n * ```\n */\nexport class EmscriptenDownloadMonitor extends EventTarget {\n\t#assetsSizes: Record<string, number> = {};\n\t#progress: Record<string, number> = {};\n\n\texpectAssets(assets: Record<string, number>) {\n\t\tfor (const [urlLike, size] of Object.entries(assets)) {\n\t\t\tconst dummyBaseUrl = 'http://example.com/';\n\t\t\tconst pathname = new URL(urlLike, dummyBaseUrl).pathname;\n\t\t\tconst filename = pathname.split('/').pop()!;\n\t\t\tif (!(filename in this.#assetsSizes)) {\n\t\t\t\tthis.#assetsSizes[filename] = size;\n\t\t\t}\n\t\t\tif (!(filename in this.#progress)) {\n\t\t\t\tthis.#progress[filename] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync monitorFetch(fetchPromise: Promise<Response>): Promise<Response> {\n\t\tconst response = await fetchPromise;\n\t\tconst onProgress = (event: CustomEvent<DownloadProgress>) => {\n\t\t\tthis.#notify(response.url, event.detail.loaded, event.detail.total);\n\t\t};\n\t\treturn cloneResponseMonitorProgress(response, onProgress);\n\t}\n\n\t/**\n\t * Notifies about the download #progress of a file.\n\t *\n\t * @param file The file name.\n\t * @param loaded The number of bytes of that file loaded so far.\n\t * @param fileSize The length number of bytes in the loaded file.\n\t */\n\t#notify(file: string, loaded: number, fileSize: number) {\n\t\tconst fileName = new URL(file, 'http://example.com').pathname\n\t\t\t.split('/')\n\t\t\t.pop()!;\n\t\tif (!fileSize) {\n\t\t\tfileSize = this.#assetsSizes[fileName];\n\t\t} else if (!(fileName in this.#assetsSizes)) {\n\t\t\tthis.#assetsSizes[fileName] = fileSize;\n\t\t\tthis.#progress[fileName] = loaded;\n\t\t}\n\t\tif (!(fileName in this.#progress)) {\n\t\t\tlogger.warn(\n\t\t\t\t`Registered a download #progress of an unregistered file \"${fileName}\". ` +\n\t\t\t\t\t`This may cause a sudden **decrease** in the #progress percentage as the ` +\n\t\t\t\t\t`length number of bytes increases during the download.`\n\t\t\t);\n\t\t}\n\n\t\tthis.#progress[fileName] = loaded;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded: sumValues(this.#progress),\n\t\t\t\t\ttotal: sumValues(this.#assetsSizes),\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n\nfunction sumValues(obj: Record<string, number>) {\n\treturn Object.values(obj).reduce((length, value) => length + value, 0);\n}\n\nexport default EmscriptenDownloadMonitor;\n\nexport interface DownloadProgress {\n\t/**\n\t * The number of bytes loaded so far.\n\t */\n\tloaded: number;\n\t/**\n\t * The length number of bytes to load.\n\t */\n\ttotal: number;\n}\n\n/**\n * Clones a fetch Response object and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param response The fetch Response object to clone.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned response\n */\nexport function cloneResponseMonitorProgress(\n\tresponse: Response,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): Response {\n\tconst contentLength = response.headers.get('content-length') || '';\n\tconst length = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;\n\n\treturn new Response(\n\t\tcloneStreamMonitorProgress(response.body, length, onProgress),\n\t\t{\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t}\n\t);\n}\n\n/**\n * Clones a ReadableStream and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param stream The ReadableStream to clone.\n * @param total The total number of bytes to load.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned ReadableStream\n */\nexport function cloneStreamMonitorProgress(\n\tstream: ReadableStream<Uint8Array> | null,\n\ttotal: number,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): ReadableStream<Uint8Array> {\n\tfunction notify(loaded: number, total: number) {\n\t\tonProgress(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded,\n\t\t\t\t\ttotal,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\treturn new ReadableStream({\n\t\tasync start(controller) {\n\t\t\tif (!stream) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reader = stream.getReader();\n\t\t\tlet loaded = 0;\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\tloaded += value.byteLength;\n\t\t\t\t\t}\n\t\t\t\t\tif (done) {\n\t\t\t\t\t\tnotify(loaded, loaded);\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(loaded, total);\n\t\t\t\t\t\tcontroller.enqueue(value);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error({ e });\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport type DownloadProgressCallback = (progress: DownloadProgress) => void;\n","import type { DownloadProgress } from './emscripten-download-monitor';\n\nexport type ProgressMode =\n\t/**\n\t * Real-time progress is used when we get real-time reports\n\t * about the progress.\n\t */\n\t| 'REAL_TIME'\n\n\t/**\n\t * Slowly increment progress is used when we don't know how long\n\t * an operation will take and just want to keep slowly incrementing\n\t * the progress bar.\n\t */\n\t| 'SLOWLY_INCREMENT';\n\nexport type ProgressObserverEvent = {\n\tprogress: number;\n\tmode: ProgressMode;\n\tcaption: string;\n};\n\nexport class ProgressObserver extends EventTarget {\n\t#observedProgresses: Record<number, number> = {};\n\t#lastObserverId = 0;\n\n\tprogress = 0;\n\tmode: ProgressMode = 'REAL_TIME';\n\tcaption = '';\n\n\tpartialObserver(progressBudget: number, caption = '') {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = 0;\n\t\treturn (progress: CustomEvent<DownloadProgress>) => {\n\t\t\tconst { loaded, total } = progress?.detail || {};\n\t\t\tthis.#observedProgresses[id] = (loaded / total) * progressBudget;\n\t\t\tthis.#onProgress(this.totalProgress, 'REAL_TIME', caption);\n\t\t};\n\t}\n\n\tslowlyIncrementBy(progress: number) {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = progress;\n\t\tthis.#onProgress(this.totalProgress, 'SLOWLY_INCREMENT');\n\t}\n\n\tget totalProgress() {\n\t\treturn Object.values(this.#observedProgresses).reduce(\n\t\t\t(total, progress) => total + progress,\n\t\t\t0\n\t\t);\n\t}\n\n\t#onProgress(progress: number, mode: ProgressMode, caption?: string) {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tprogress,\n\t\t\t\t\tmode,\n\t\t\t\t\tcaption,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n","/**\n * Options for customizing the progress tracker.\n */\nexport interface ProgressTrackerOptions {\n\t/** The weight of the progress, a number between 0 and 1. */\n\tweight?: number;\n\t/** The caption to display during progress, a string. */\n\tcaption?: string;\n\t/** The time in milliseconds to fill the progress, a number. */\n\tfillTime?: number;\n}\n\n/**\n * Custom event providing information about a loading process.\n */\nexport type LoadingEvent = CustomEvent<{\n\t/** The number representing how much was loaded. */\n\tloaded: number;\n\t/** The number representing how much needs to loaded in total. */\n\ttotal: number;\n}>;\n\n/**\n * Custom event providing progress details.\n */\nexport type ProgressTrackerEvent = CustomEvent<ProgressDetails>;\n\n/**\n * Custom event providing progress details when the task is done.\n */\nexport type DoneEvent = CustomEvent<ProgressDetails>;\n\nexport interface ProgressDetails {\n\t/** The progress percentage as a number between 0 and 100. */\n\tprogress: number;\n\t/** The caption to display during progress, a string. */\n\tcaption: string;\n}\n\n/**\n * ProgressObserver A function that receives progress updates.\n *\n * @param progress The progress percentage as a number between 0 and 100.\n */\ntype ProgressObserver = (progress: number) => void;\n\n/**\n * Listener A function for handling specific event types.\n *\n * @param event The event of type T.\n */\nexport type Listener<T> = (event: T) => void;\n\nexport type TSCompatibleListener<T> =\n\t| EventListenerOrEventListenerObject\n\t| null\n\t| Listener<T>;\n\nexport interface ProgressReceiver {\n\tsetProgress(details: ProgressDetails): any;\n\tsetLoaded(): any;\n}\n\n/*\n * Like Number.EPSILON, but better tuned to tracking progress.\n *\n * With Number.EPSILON, progress like 99.99999999999997 is still\n * considered to be below 100 – this is highly undeisrable.\n */\nconst PROGRESS_EPSILON = 0.00001;\n\n/**\n * The ProgressTracker class is a tool for tracking progress in an operation\n * that is divided into multiple stages. It allows you to create sub-trackers\n * for each stage, with individual weights and captions. The main tracker\n * automatically calculates the progress based on the weighted sum of each\n * sub-tracker's progress. This makes it easy to keep track of a complex,\n * multi-stage process and report progress in a user-friendly way.\n *\n * After creating the sub-trackers, you can call the set() method to update the\n * progress of the current stage. You can also call the finish() method to mark\n * the current stage as complete and move on to the next one. Alternatively,\n * you can call the fillSlowly() method to simulate progress filling up slowly\n * to 100% before calling finish().\n *\n * @example\n * ```ts\n * const tracker = new ProgressTracker();\n * tracker.addEventListener('progress', (e) => {\n * \t\tconsole.log(\n * \t\t\t\te.detail.progress,\n * \t\t\t\te.detail.caption\n * \t\t);\n * });\n *\n * const stage1 = tracker.stage(0.5, 'Calculating pi digits');\n * const stage2 = tracker.stage(0.5, 'Downloading data');\n *\n * stage1.fillSlowly();\n * await calc100DigitsOfPi();\n * stage1.finish();\n *\n * await fetchWithProgress(function onProgress(loaded, total) {\n * \t\tstage2.set( loaded / total * 100);\n * });\n * stage2.finish();\n */\nexport class ProgressTracker extends EventTarget {\n\tprivate _selfWeight = 1;\n\tprivate _selfDone = false;\n\tprivate _selfProgress = 0;\n\tprivate _selfCaption = '';\n\tprivate _weight: number;\n\tprivate _progressObserver?: ProgressObserver;\n\tprivate _loadingListener?: Listener<LoadingEvent>;\n\tprivate _isFilling = false;\n\tprivate _fillTime: number;\n\tprivate _fillInterval?: any;\n\tprivate _subTrackers: ProgressTracker[] = [];\n\n\tconstructor({\n\t\tweight = 1,\n\t\tcaption = '',\n\t\tfillTime = 4,\n\t}: ProgressTrackerOptions = {}) {\n\t\tsuper();\n\t\tthis._weight = weight;\n\t\tthis._selfCaption = caption;\n\t\tthis._fillTime = fillTime;\n\t}\n\n\t/**\n\t * Creates a new sub-tracker with a specific weight.\n\t *\n\t * The weight determines what percentage of the overall progress\n\t * the sub-tracker represents. For example, if the main tracker is\n\t * monitoring a process that has two stages, and the first stage\n\t * is expected to take twice as long as the second stage, you could\n\t * create the first sub-tracker with a weight of 0.67 and the second\n\t * sub-tracker with a weight of 0.33.\n\t *\n\t * The caption is an optional string that describes the current stage\n\t * of the operation. If provided, it will be used as the progress caption\n\t * for the sub-tracker. If not provided, the main tracker will look for\n\t * the next sub-tracker with a non-empty caption and use that as the progress\n\t * caption instead.\n\t *\n\t * Returns the newly-created sub-tracker.\n\t *\n\t * @throws {Error} If the weight of the new stage would cause the total weight of all stages to exceed 1.\n\t *\n\t * @param weight The weight of the new stage, as a decimal value between 0 and 1.\n\t * @param caption The caption for the new stage, which will be used as the progress caption for the sub-tracker.\n\t *\n\t * @example\n\t * ```ts\n\t * const tracker = new ProgressTracker();\n\t * const subTracker1 = tracker.stage(0.67, 'Slow stage');\n\t * const subTracker2 = tracker.stage(0.33, 'Fast stage');\n\t *\n\t * subTracker2.set(50);\n\t * subTracker1.set(75);\n\t * subTracker2.set(100);\n\t * subTracker1.set(100);\n\t * ```\n\t */\n\tstage(weight?: number, caption = ''): ProgressTracker {\n\t\tif (!weight) {\n\t\t\tweight = this._selfWeight;\n\t\t}\n\t\tif (this._selfWeight - weight < -PROGRESS_EPSILON) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot add a stage with weight ${weight} as the total weight of registered stages would exceed 1.`\n\t\t\t);\n\t\t}\n\t\tthis._selfWeight -= weight;\n\n\t\tconst subTracker = new ProgressTracker({\n\t\t\tcaption,\n\t\t\tweight,\n\t\t\tfillTime: this._fillTime,\n\t\t});\n\t\tthis._subTrackers.push(subTracker);\n\t\tsubTracker.addEventListener('progress', () => this.notifyProgress());\n\t\tsubTracker.addEventListener('done', () => {\n\t\t\tif (this.done) {\n\t\t\t\tthis.notifyDone();\n\t\t\t}\n\t\t});\n\t\treturn subTracker;\n\t}\n\n\t/**\n\t * Fills the progress bar slowly over time, simulating progress.\n\t *\n\t * The progress bar is filled in a 100 steps, and each step, the progress\n\t * is increased by 1. If `stopBeforeFinishing` is true, the progress bar\n\t * will stop filling when it reaches 99% so that you can call `finish()`\n\t * explicitly.\n\t *\n\t * If the progress bar is filling or already filled, this method does nothing.\n\t *\n\t * @example\n\t * ```ts\n\t * const progress = new ProgressTracker({ caption: 'Processing...' });\n\t * progress.fillSlowly();\n\t * ```\n\t *\n\t * @param options Optional options.\n\t */\n\tfillSlowly({ stopBeforeFinishing = true } = {}): void {\n\t\tif (this._isFilling) {\n\t\t\treturn;\n\t\t}\n\t\tthis._isFilling = true;\n\t\tconst steps = 100;\n\t\tconst interval = this._fillTime / steps;\n\t\tthis._fillInterval = setInterval(() => {\n\t\t\tthis.set(this._selfProgress + 1);\n\t\t\tif (stopBeforeFinishing && this._selfProgress >= 99) {\n\t\t\t\tclearInterval(this._fillInterval);\n\t\t\t}\n\t\t}, interval);\n\t}\n\n\tset(value: number): void {\n\t\tthis._selfProgress = Math.min(value, 100);\n\t\tthis.notifyProgress();\n\t\tif (this._selfProgress + PROGRESS_EPSILON >= 100) {\n\t\t\tthis.finish();\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this._fillInterval) {\n\t\t\tclearInterval(this._fillInterval);\n\t\t}\n\t\tthis._selfDone = true;\n\t\tthis._selfProgress = 100;\n\t\tthis._isFilling = false;\n\t\tthis._fillInterval = undefined;\n\t\tthis.notifyProgress();\n\t\tthis.notifyDone();\n\t}\n\n\tget caption(): string {\n\t\tfor (let i = this._subTrackers.length - 1; i >= 0; i--) {\n\t\t\tif (!this._subTrackers[i].done) {\n\t\t\t\tconst captionMaybe = this._subTrackers[i].caption;\n\t\t\t\tif (captionMaybe) {\n\t\t\t\t\treturn captionMaybe;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this._selfCaption;\n\t}\n\n\tsetCaption(caption: string) {\n\t\tthis._selfCaption = caption;\n\t\tthis.notifyProgress();\n\t}\n\n\tget done(): boolean {\n\t\treturn this.progress + PROGRESS_EPSILON >= 100;\n\t}\n\n\tget progress(): number {\n\t\tif (this._selfDone) {\n\t\t\treturn 100;\n\t\t}\n\t\tconst sum = this._subTrackers.reduce(\n\t\t\t(sum, tracker) => sum + tracker.progress * tracker.weight,\n\t\t\tthis._selfProgress * this._selfWeight\n\t\t);\n\t\treturn Math.round(sum * 10000) / 10000;\n\t}\n\n\tget weight(): number {\n\t\treturn this._weight;\n\t}\n\n\tget observer() {\n\t\tif (!this._progressObserver) {\n\t\t\tthis._progressObserver = (progress: number) => {\n\t\t\t\tthis.set(progress);\n\t\t\t};\n\t\t}\n\t\treturn this._progressObserver;\n\t}\n\n\tget loadingListener() {\n\t\tif (!this._loadingListener) {\n\t\t\tthis._loadingListener = (event: LoadingEvent) => {\n\t\t\t\tthis.set((event.detail.loaded / event.detail.total) * 100);\n\t\t\t};\n\t\t}\n\t\treturn this._loadingListener;\n\t}\n\n\tpipe(receiver: ProgressReceiver) {\n\t\treceiver.setProgress({\n\t\t\tprogress: this.progress,\n\t\t\tcaption: this.caption,\n\t\t});\n\t\tthis.addEventListener('progress', (event: ProgressTrackerEvent) => {\n\t\t\treceiver.setProgress({\n\t\t\t\tprogress: event.detail.progress,\n\t\t\t\tcaption: event.detail.caption,\n\t\t\t});\n\t\t});\n\t\tthis.addEventListener('done', () => {\n\t\t\treceiver.setLoaded();\n\t\t});\n\t}\n\n\toverride addEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.addEventListener(type, listener as any);\n\t}\n\n\toverride removeEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.removeEventListener(type, listener as any);\n\t}\n\n\tprivate notifyProgress() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tget progress() {\n\t\t\t\t\t\treturn self.progress;\n\t\t\t\t\t},\n\t\t\t\t\tget caption() {\n\t\t\t\t\t\treturn self.caption;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\tprivate notifyDone() {\n\t\tthis.dispatchEvent(new CustomEvent('done'));\n\t}\n}\n"],"names":["FALLBACK_FILE_SIZE","EmscriptenDownloadMonitor","__privateAdd","_EmscriptenDownloadMonitor_instances","_assetsSizes","_progress","assets","urlLike","size","dummyBaseUrl","filename","__privateGet","fetchPromise","response","cloneResponseMonitorProgress","event","__privateMethod","notify_fn","file","loaded","fileSize","fileName","logger","sumValues","obj","length","value","onProgress","contentLength","cloneStreamMonitorProgress","stream","total","notify","controller","reader","done","e","ProgressObserver","_ProgressObserver_instances","_observedProgresses","_lastObserverId","__privateSet","progressBudget","caption","id","__privateWrapper","progress","onProgress_fn","mode","PROGRESS_EPSILON","ProgressTracker","weight","fillTime","subTracker","stopBeforeFinishing","interval","i","captionMaybe","sum","tracker","receiver","type","listener","self"],"mappings":"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"}
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
- var P = (i) => {
1
+ var w = (i) => {
2
2
  throw TypeError(i);
3
3
  };
4
- var E = (i, e, t) => e.has(i) || P("Cannot " + t);
5
- var o = (i, e, t) => (E(i, e, "read from private field"), t ? t.call(i) : e.get(i)), c = (i, e, t) => e.has(i) ? P("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(i) : e.set(i, t), p = (i, e, t, s) => (E(i, e, "write to private field"), s ? s.call(i, t) : e.set(i, t), t), _ = (i, e, t) => (E(i, e, "access private method"), t);
4
+ var E = (i, e, t) => e.has(i) || w("Cannot " + t);
5
+ var o = (i, e, t) => (E(i, e, "read from private field"), t ? t.call(i) : e.get(i)), c = (i, e, t) => e.has(i) ? w("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(i) : e.set(i, t), p = (i, e, t, s) => (E(i, e, "write to private field"), s ? s.call(i, t) : e.set(i, t), t), _ = (i, e, t) => (E(i, e, "access private method"), t);
6
6
  var b = (i, e, t, s) => ({
7
7
  set _(r) {
8
8
  p(i, e, r, t);
@@ -49,13 +49,13 @@ I = function(t, s, r) {
49
49
  ), o(this, l)[n] = s, this.dispatchEvent(
50
50
  new CustomEvent("progress", {
51
51
  detail: {
52
- loaded: w(o(this, l)),
53
- total: w(o(this, h))
52
+ loaded: y(o(this, l)),
53
+ total: y(o(this, h))
54
54
  }
55
55
  })
56
56
  );
57
57
  };
58
- function w(i) {
58
+ function y(i) {
59
59
  return Object.values(i).reduce((e, t) => e + t, 0);
60
60
  }
61
61
  function R(i, e) {
@@ -103,7 +103,7 @@ function x(i, e, t) {
103
103
  }
104
104
  });
105
105
  }
106
- var g, f, u, L;
106
+ var g, f, u, P;
107
107
  class S extends EventTarget {
108
108
  constructor() {
109
109
  super(...arguments);
@@ -116,12 +116,12 @@ class S extends EventTarget {
116
116
  const r = ++b(this, f)._;
117
117
  return o(this, g)[r] = 0, (n) => {
118
118
  const { loaded: d, total: a } = (n == null ? void 0 : n.detail) || {};
119
- o(this, g)[r] = d / a * t, _(this, u, L).call(this, this.totalProgress, "REAL_TIME", s);
119
+ o(this, g)[r] = d / a * t, _(this, u, P).call(this, this.totalProgress, "REAL_TIME", s);
120
120
  };
121
121
  }
122
122
  slowlyIncrementBy(t) {
123
123
  const s = ++b(this, f)._;
124
- o(this, g)[s] = t, _(this, u, L).call(this, this.totalProgress, "SLOWLY_INCREMENT");
124
+ o(this, g)[s] = t, _(this, u, P).call(this, this.totalProgress, "SLOWLY_INCREMENT");
125
125
  }
126
126
  get totalProgress() {
127
127
  return Object.values(o(this, g)).reduce(
@@ -130,7 +130,7 @@ class S extends EventTarget {
130
130
  );
131
131
  }
132
132
  }
133
- g = new WeakMap(), f = new WeakMap(), u = new WeakSet(), L = function(t, s, r) {
133
+ g = new WeakMap(), f = new WeakMap(), u = new WeakSet(), P = function(t, s, r) {
134
134
  this.dispatchEvent(
135
135
  new CustomEvent("progress", {
136
136
  detail: {
@@ -141,7 +141,7 @@ g = new WeakMap(), f = new WeakMap(), u = new WeakSet(), L = function(t, s, r) {
141
141
  })
142
142
  );
143
143
  };
144
- const y = 1e-5;
144
+ const L = 1e-5;
145
145
  class C extends EventTarget {
146
146
  constructor({
147
147
  weight: e = 1,
@@ -186,7 +186,7 @@ class C extends EventTarget {
186
186
  * ```
187
187
  */
188
188
  stage(e, t = "") {
189
- if (e || (e = this._selfWeight), this._selfWeight - e < -1e-5)
189
+ if (e || (e = this._selfWeight), this._selfWeight - e < -L)
190
190
  throw new Error(
191
191
  `Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.`
192
192
  );
@@ -228,7 +228,7 @@ class C extends EventTarget {
228
228
  }, s);
229
229
  }
230
230
  set(e) {
231
- this._selfProgress = Math.min(e, 100), this.notifyProgress(), this._selfProgress + y >= 100 && this.finish();
231
+ this._selfProgress = Math.min(e, 100), this.notifyProgress(), this._selfProgress + L >= 100 && this.finish();
232
232
  }
233
233
  finish() {
234
234
  this._fillInterval && clearInterval(this._fillInterval), this._selfDone = !0, this._selfProgress = 100, this._isFilling = !1, this._fillInterval = void 0, this.notifyProgress(), this.notifyDone();
@@ -246,7 +246,7 @@ class C extends EventTarget {
246
246
  this._selfCaption = e, this.notifyProgress();
247
247
  }
248
248
  get done() {
249
- return this.progress + y >= 100;
249
+ return this.progress + L >= 100;
250
250
  }
251
251
  get progress() {
252
252
  if (this._selfDone)
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/progress/src/lib/emscripten-download-monitor.ts","../../../../packages/php-wasm/progress/src/lib/progress-observer.ts","../../../../packages/php-wasm/progress/src/lib/progress-tracker.ts"],"sourcesContent":["import { logger } from '@php-wasm/logger';\n/*\n * An approximate file length to use when the actual\n * length number of bytes is missing.\n *\n * This may happen when the files are compressed before transmission\n * and no content-length header is being sent.\n *\n * The approximation isn't accurate, but it's better than nothing.\n * It's not about being exact but about giving the user a rough sense\n * of #progress.\n */\nconst FALLBACK_FILE_SIZE = 5 * 1024 * 1024;\n\n/**\n * Monitors the download #progress of Emscripten modules\n *\n * Usage:\n *\n * ```js\n * const downloadMonitor = new EmscriptenDownloadMonitor();\n * \t const php = await startPHP(\n * phpLoaderModule,\n * 'web',\n * downloadMonitor.phpArgs\n * );\n * downloadMonitor.addEventListener('#progress', (e) => {\n * console.log( e.detail.#progress);\n * })\n * ```\n */\nexport class EmscriptenDownloadMonitor extends EventTarget {\n\t#assetsSizes: Record<string, number> = {};\n\t#progress: Record<string, number> = {};\n\n\texpectAssets(assets: Record<string, number>) {\n\t\tfor (const [urlLike, size] of Object.entries(assets)) {\n\t\t\tconst dummyBaseUrl = 'http://example.com/';\n\t\t\tconst pathname = new URL(urlLike, dummyBaseUrl).pathname;\n\t\t\tconst filename = pathname.split('/').pop()!;\n\t\t\tif (!(filename in this.#assetsSizes)) {\n\t\t\t\tthis.#assetsSizes[filename] = size;\n\t\t\t}\n\t\t\tif (!(filename in this.#progress)) {\n\t\t\t\tthis.#progress[filename] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync monitorFetch(fetchPromise: Promise<Response>): Promise<Response> {\n\t\tconst response = await fetchPromise;\n\t\tconst onProgress = (event: CustomEvent<DownloadProgress>) => {\n\t\t\tthis.#notify(response.url, event.detail.loaded, event.detail.total);\n\t\t};\n\t\treturn cloneResponseMonitorProgress(response, onProgress);\n\t}\n\n\t/**\n\t * Notifies about the download #progress of a file.\n\t *\n\t * @param file The file name.\n\t * @param loaded The number of bytes of that file loaded so far.\n\t * @param fileSize The length number of bytes in the loaded file.\n\t */\n\t#notify(file: string, loaded: number, fileSize: number) {\n\t\tconst fileName = new URL(file, 'http://example.com').pathname\n\t\t\t.split('/')\n\t\t\t.pop()!;\n\t\tif (!fileSize) {\n\t\t\tfileSize = this.#assetsSizes[fileName];\n\t\t} else if (!(fileName in this.#assetsSizes)) {\n\t\t\tthis.#assetsSizes[fileName] = fileSize;\n\t\t\tthis.#progress[fileName] = loaded;\n\t\t}\n\t\tif (!(fileName in this.#progress)) {\n\t\t\tlogger.warn(\n\t\t\t\t`Registered a download #progress of an unregistered file \"${fileName}\". ` +\n\t\t\t\t\t`This may cause a sudden **decrease** in the #progress percentage as the ` +\n\t\t\t\t\t`length number of bytes increases during the download.`\n\t\t\t);\n\t\t}\n\n\t\tthis.#progress[fileName] = loaded;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded: sumValues(this.#progress),\n\t\t\t\t\ttotal: sumValues(this.#assetsSizes),\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n\nfunction sumValues(obj: Record<string, number>) {\n\treturn Object.values(obj).reduce((length, value) => length + value, 0);\n}\n\nexport default EmscriptenDownloadMonitor;\n\nexport interface DownloadProgress {\n\t/**\n\t * The number of bytes loaded so far.\n\t */\n\tloaded: number;\n\t/**\n\t * The length number of bytes to load.\n\t */\n\ttotal: number;\n}\n\n/**\n * Clones a fetch Response object and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param response The fetch Response object to clone.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned response\n */\nexport function cloneResponseMonitorProgress(\n\tresponse: Response,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): Response {\n\tconst contentLength = response.headers.get('content-length') || '';\n\tconst length = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;\n\n\treturn new Response(\n\t\tcloneStreamMonitorProgress(response.body, length, onProgress),\n\t\t{\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t}\n\t);\n}\n\n/**\n * Clones a ReadableStream and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param stream The ReadableStream to clone.\n * @param total The total number of bytes to load.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned ReadableStream\n */\nexport function cloneStreamMonitorProgress(\n\tstream: ReadableStream<Uint8Array> | null,\n\ttotal: number,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): ReadableStream<Uint8Array> {\n\tfunction notify(loaded: number, total: number) {\n\t\tonProgress(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded,\n\t\t\t\t\ttotal,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\treturn new ReadableStream({\n\t\tasync start(controller) {\n\t\t\tif (!stream) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reader = stream.getReader();\n\t\t\tlet loaded = 0;\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\tloaded += value.byteLength;\n\t\t\t\t\t}\n\t\t\t\t\tif (done) {\n\t\t\t\t\t\tnotify(loaded, loaded);\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(loaded, total);\n\t\t\t\t\t\tcontroller.enqueue(value);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error({ e });\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport type DownloadProgressCallback = (progress: DownloadProgress) => void;\n","import type { DownloadProgress } from './emscripten-download-monitor';\n\nexport type ProgressMode =\n\t/**\n\t * Real-time progress is used when we get real-time reports\n\t * about the progress.\n\t */\n\t| 'REAL_TIME'\n\n\t/**\n\t * Slowly increment progress is used when we don't know how long\n\t * an operation will take and just want to keep slowly incrementing\n\t * the progress bar.\n\t */\n\t| 'SLOWLY_INCREMENT';\n\nexport type ProgressObserverEvent = {\n\tprogress: number;\n\tmode: ProgressMode;\n\tcaption: string;\n};\n\nexport class ProgressObserver extends EventTarget {\n\t#observedProgresses: Record<number, number> = {};\n\t#lastObserverId = 0;\n\n\tprogress = 0;\n\tmode: ProgressMode = 'REAL_TIME';\n\tcaption = '';\n\n\tpartialObserver(progressBudget: number, caption = '') {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = 0;\n\t\treturn (progress: CustomEvent<DownloadProgress>) => {\n\t\t\tconst { loaded, total } = progress?.detail || {};\n\t\t\tthis.#observedProgresses[id] = (loaded / total) * progressBudget;\n\t\t\tthis.#onProgress(this.totalProgress, 'REAL_TIME', caption);\n\t\t};\n\t}\n\n\tslowlyIncrementBy(progress: number) {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = progress;\n\t\tthis.#onProgress(this.totalProgress, 'SLOWLY_INCREMENT');\n\t}\n\n\tget totalProgress() {\n\t\treturn Object.values(this.#observedProgresses).reduce(\n\t\t\t(total, progress) => total + progress,\n\t\t\t0\n\t\t);\n\t}\n\n\t#onProgress(progress: number, mode: ProgressMode, caption?: string) {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tprogress,\n\t\t\t\t\tmode,\n\t\t\t\t\tcaption,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n","/**\n * Options for customizing the progress tracker.\n */\nexport interface ProgressTrackerOptions {\n\t/** The weight of the progress, a number between 0 and 1. */\n\tweight?: number;\n\t/** The caption to display during progress, a string. */\n\tcaption?: string;\n\t/** The time in milliseconds to fill the progress, a number. */\n\tfillTime?: number;\n}\n\n/**\n * Custom event providing information about a loading process.\n */\nexport type LoadingEvent = CustomEvent<{\n\t/** The number representing how much was loaded. */\n\tloaded: number;\n\t/** The number representing how much needs to loaded in total. */\n\ttotal: number;\n}>;\n\n/**\n * Custom event providing progress details.\n */\nexport type ProgressTrackerEvent = CustomEvent<ProgressDetails>;\n\n/**\n * Custom event providing progress details when the task is done.\n */\nexport type DoneEvent = CustomEvent<ProgressDetails>;\n\nexport interface ProgressDetails {\n\t/** The progress percentage as a number between 0 and 100. */\n\tprogress: number;\n\t/** The caption to display during progress, a string. */\n\tcaption: string;\n}\n\n/**\n * ProgressObserver A function that receives progress updates.\n *\n * @param progress The progress percentage as a number between 0 and 100.\n */\ntype ProgressObserver = (progress: number) => void;\n\n/**\n * Listener A function for handling specific event types.\n *\n * @param event The event of type T.\n */\nexport type Listener<T> = (event: T) => void;\n\nexport type TSCompatibleListener<T> =\n\t| EventListenerOrEventListenerObject\n\t| null\n\t| Listener<T>;\n\nexport interface ProgressReceiver {\n\tsetProgress(details: ProgressDetails): any;\n\tsetLoaded(): any;\n}\n\n/*\n * Like Number.EPSILON, but better tuned to tracking progress.\n *\n * With Number.EPSILON, progress like 99.99999999999997 is still\n * considered to be below 100 – this is highly undeisrable.\n */\nconst PROGRESS_EPSILON = 0.00001;\n\n/**\n * The ProgressTracker class is a tool for tracking progress in an operation\n * that is divided into multiple stages. It allows you to create sub-trackers\n * for each stage, with individual weights and captions. The main tracker\n * automatically calculates the progress based on the weighted sum of each\n * sub-tracker's progress. This makes it easy to keep track of a complex,\n * multi-stage process and report progress in a user-friendly way.\n *\n * After creating the sub-trackers, you can call the set() method to update the\n * progress of the current stage. You can also call the finish() method to mark\n * the current stage as complete and move on to the next one. Alternatively,\n * you can call the fillSlowly() method to simulate progress filling up slowly\n * to 100% before calling finish().\n *\n * @example\n * ```ts\n * const tracker = new ProgressTracker();\n * tracker.addEventListener('progress', (e) => {\n * \t\tconsole.log(\n * \t\t\t\te.detail.progress,\n * \t\t\t\te.detail.caption\n * \t\t);\n * });\n *\n * const stage1 = tracker.stage(0.5, 'Calculating pi digits');\n * const stage2 = tracker.stage(0.5, 'Downloading data');\n *\n * stage1.fillSlowly();\n * await calc100DigitsOfPi();\n * stage1.finish();\n *\n * await fetchWithProgress(function onProgress(loaded, total) {\n * \t\tstage2.set( loaded / total * 100);\n * });\n * stage2.finish();\n */\nexport class ProgressTracker extends EventTarget {\n\tprivate _selfWeight = 1;\n\tprivate _selfDone = false;\n\tprivate _selfProgress = 0;\n\tprivate _selfCaption = '';\n\tprivate _weight: number;\n\tprivate _progressObserver?: ProgressObserver;\n\tprivate _loadingListener?: Listener<LoadingEvent>;\n\tprivate _isFilling = false;\n\tprivate _fillTime: number;\n\tprivate _fillInterval?: any;\n\tprivate _subTrackers: ProgressTracker[] = [];\n\n\tconstructor({\n\t\tweight = 1,\n\t\tcaption = '',\n\t\tfillTime = 4,\n\t}: ProgressTrackerOptions = {}) {\n\t\tsuper();\n\t\tthis._weight = weight;\n\t\tthis._selfCaption = caption;\n\t\tthis._fillTime = fillTime;\n\t}\n\n\t/**\n\t * Creates a new sub-tracker with a specific weight.\n\t *\n\t * The weight determines what percentage of the overall progress\n\t * the sub-tracker represents. For example, if the main tracker is\n\t * monitoring a process that has two stages, and the first stage\n\t * is expected to take twice as long as the second stage, you could\n\t * create the first sub-tracker with a weight of 0.67 and the second\n\t * sub-tracker with a weight of 0.33.\n\t *\n\t * The caption is an optional string that describes the current stage\n\t * of the operation. If provided, it will be used as the progress caption\n\t * for the sub-tracker. If not provided, the main tracker will look for\n\t * the next sub-tracker with a non-empty caption and use that as the progress\n\t * caption instead.\n\t *\n\t * Returns the newly-created sub-tracker.\n\t *\n\t * @throws {Error} If the weight of the new stage would cause the total weight of all stages to exceed 1.\n\t *\n\t * @param weight The weight of the new stage, as a decimal value between 0 and 1.\n\t * @param caption The caption for the new stage, which will be used as the progress caption for the sub-tracker.\n\t *\n\t * @example\n\t * ```ts\n\t * const tracker = new ProgressTracker();\n\t * const subTracker1 = tracker.stage(0.67, 'Slow stage');\n\t * const subTracker2 = tracker.stage(0.33, 'Fast stage');\n\t *\n\t * subTracker2.set(50);\n\t * subTracker1.set(75);\n\t * subTracker2.set(100);\n\t * subTracker1.set(100);\n\t * ```\n\t */\n\tstage(weight?: number, caption = ''): ProgressTracker {\n\t\tif (!weight) {\n\t\t\tweight = this._selfWeight;\n\t\t}\n\t\tif (this._selfWeight - weight < -PROGRESS_EPSILON) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot add a stage with weight ${weight} as the total weight of registered stages would exceed 1.`\n\t\t\t);\n\t\t}\n\t\tthis._selfWeight -= weight;\n\n\t\tconst subTracker = new ProgressTracker({\n\t\t\tcaption,\n\t\t\tweight,\n\t\t\tfillTime: this._fillTime,\n\t\t});\n\t\tthis._subTrackers.push(subTracker);\n\t\tsubTracker.addEventListener('progress', () => this.notifyProgress());\n\t\tsubTracker.addEventListener('done', () => {\n\t\t\tif (this.done) {\n\t\t\t\tthis.notifyDone();\n\t\t\t}\n\t\t});\n\t\treturn subTracker;\n\t}\n\n\t/**\n\t * Fills the progress bar slowly over time, simulating progress.\n\t *\n\t * The progress bar is filled in a 100 steps, and each step, the progress\n\t * is increased by 1. If `stopBeforeFinishing` is true, the progress bar\n\t * will stop filling when it reaches 99% so that you can call `finish()`\n\t * explicitly.\n\t *\n\t * If the progress bar is filling or already filled, this method does nothing.\n\t *\n\t * @example\n\t * ```ts\n\t * const progress = new ProgressTracker({ caption: 'Processing...' });\n\t * progress.fillSlowly();\n\t * ```\n\t *\n\t * @param options Optional options.\n\t */\n\tfillSlowly({ stopBeforeFinishing = true } = {}): void {\n\t\tif (this._isFilling) {\n\t\t\treturn;\n\t\t}\n\t\tthis._isFilling = true;\n\t\tconst steps = 100;\n\t\tconst interval = this._fillTime / steps;\n\t\tthis._fillInterval = setInterval(() => {\n\t\t\tthis.set(this._selfProgress + 1);\n\t\t\tif (stopBeforeFinishing && this._selfProgress >= 99) {\n\t\t\t\tclearInterval(this._fillInterval);\n\t\t\t}\n\t\t}, interval);\n\t}\n\n\tset(value: number): void {\n\t\tthis._selfProgress = Math.min(value, 100);\n\t\tthis.notifyProgress();\n\t\tif (this._selfProgress + PROGRESS_EPSILON >= 100) {\n\t\t\tthis.finish();\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this._fillInterval) {\n\t\t\tclearInterval(this._fillInterval);\n\t\t}\n\t\tthis._selfDone = true;\n\t\tthis._selfProgress = 100;\n\t\tthis._isFilling = false;\n\t\tthis._fillInterval = undefined;\n\t\tthis.notifyProgress();\n\t\tthis.notifyDone();\n\t}\n\n\tget caption(): string {\n\t\tfor (let i = this._subTrackers.length - 1; i >= 0; i--) {\n\t\t\tif (!this._subTrackers[i].done) {\n\t\t\t\tconst captionMaybe = this._subTrackers[i].caption;\n\t\t\t\tif (captionMaybe) {\n\t\t\t\t\treturn captionMaybe;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this._selfCaption;\n\t}\n\n\tsetCaption(caption: string) {\n\t\tthis._selfCaption = caption;\n\t\tthis.notifyProgress();\n\t}\n\n\tget done(): boolean {\n\t\treturn this.progress + PROGRESS_EPSILON >= 100;\n\t}\n\n\tget progress(): number {\n\t\tif (this._selfDone) {\n\t\t\treturn 100;\n\t\t}\n\t\tconst sum = this._subTrackers.reduce(\n\t\t\t(sum, tracker) => sum + tracker.progress * tracker.weight,\n\t\t\tthis._selfProgress * this._selfWeight\n\t\t);\n\t\treturn Math.round(sum * 10000) / 10000;\n\t}\n\n\tget weight(): number {\n\t\treturn this._weight;\n\t}\n\n\tget observer() {\n\t\tif (!this._progressObserver) {\n\t\t\tthis._progressObserver = (progress: number) => {\n\t\t\t\tthis.set(progress);\n\t\t\t};\n\t\t}\n\t\treturn this._progressObserver;\n\t}\n\n\tget loadingListener() {\n\t\tif (!this._loadingListener) {\n\t\t\tthis._loadingListener = (event: LoadingEvent) => {\n\t\t\t\tthis.set((event.detail.loaded / event.detail.total) * 100);\n\t\t\t};\n\t\t}\n\t\treturn this._loadingListener;\n\t}\n\n\tpipe(receiver: ProgressReceiver) {\n\t\treceiver.setProgress({\n\t\t\tprogress: this.progress,\n\t\t\tcaption: this.caption,\n\t\t});\n\t\tthis.addEventListener('progress', (event: ProgressTrackerEvent) => {\n\t\t\treceiver.setProgress({\n\t\t\t\tprogress: event.detail.progress,\n\t\t\t\tcaption: event.detail.caption,\n\t\t\t});\n\t\t});\n\t\tthis.addEventListener('done', () => {\n\t\t\treceiver.setLoaded();\n\t\t});\n\t}\n\n\toverride addEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.addEventListener(type, listener as any);\n\t}\n\n\toverride removeEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.removeEventListener(type, listener as any);\n\t}\n\n\tprivate notifyProgress() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tget progress() {\n\t\t\t\t\t\treturn self.progress;\n\t\t\t\t\t},\n\t\t\t\t\tget caption() {\n\t\t\t\t\t\treturn self.caption;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\tprivate notifyDone() {\n\t\tthis.dispatchEvent(new CustomEvent('done'));\n\t}\n}\n"],"names":["FALLBACK_FILE_SIZE","EmscriptenDownloadMonitor","__privateAdd","_EmscriptenDownloadMonitor_instances","_assetsSizes","_progress","assets","urlLike","size","dummyBaseUrl","filename","__privateGet","fetchPromise","response","cloneResponseMonitorProgress","event","__privateMethod","notify_fn","file","loaded","fileSize","fileName","logger","sumValues","obj","length","value","onProgress","contentLength","cloneStreamMonitorProgress","stream","total","notify","controller","reader","done","e","ProgressObserver","_ProgressObserver_instances","_observedProgresses","_lastObserverId","__privateSet","progressBudget","caption","id","__privateWrapper","progress","onProgress_fn","mode","PROGRESS_EPSILON","ProgressTracker","weight","fillTime","subTracker","stopBeforeFinishing","interval","i","captionMaybe","sum","tracker","receiver","type","listener","self"],"mappings":";;;;;;;;;;;;;;;AAYA,MAAMA,IAAqB,IAAI,OAAO;;AAmB/B,MAAMC,UAAkC,YAAY;AAAA,EAApD;AAAA;AAAA,IAAAC,EAAA,MAAAC;AACN,IAAAD,EAAA,MAAAE,GAAuC,CAAC;AACxC,IAAAF,EAAA,MAAAG,GAAoC,CAAC;AAAA;AAAA,EAErC,aAAaC,GAAgC;AAC5C,eAAW,CAACC,GAASC,CAAI,KAAK,OAAO,QAAQF,CAAM,GAAG;AACrD,YAAMG,IAAe,uBAEfC,IADW,IAAI,IAAIH,GAASE,CAAY,EAAE,SACtB,MAAM,GAAG,EAAE,IAAI;AACrC,MAAEC,KAAYC,EAAA,MAAKP,OACjBO,EAAA,MAAAP,GAAaM,CAAQ,IAAIF,IAEzBE,KAAYC,EAAA,MAAKN,OACjBM,EAAA,MAAAN,GAAUK,CAAQ,IAAI;AAAA,IAC5B;AAAA,EACD;AAAA,EAGD,MAAM,aAAaE,GAAoD;AACtE,UAAMC,IAAW,MAAMD;AAIhB,WAAAE,EAA6BD,GAHjB,CAACE,MAAyC;AACvD,MAAAC,EAAA,MAAAb,GAAAc,GAAA,WAAQJ,EAAS,KAAKE,EAAM,OAAO,QAAQA,EAAM,OAAO;AAAA,IAC9D,CACwD;AAAA,EAAA;AAsC1D;AA5DCX,IAAA,eACAC,IAAA,eAFMF,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCNc,IAAA,SAAQC,GAAcC,GAAgBC,GAAkB;AACjD,QAAAC,IAAW,IAAI,IAAIH,GAAM,oBAAoB,EAAE,SACnD,MAAM,GAAG,EACT,IAAI;AACN,EAAKE,IAEQC,KAAYV,EAAA,MAAKP,OACxBO,EAAA,MAAAP,GAAaiB,CAAQ,IAAID,GACzBT,EAAA,MAAAN,GAAUgB,CAAQ,IAAIF,KAHhBC,IAAAT,EAAA,MAAKP,GAAaiB,CAAQ,GAKhCA,KAAYV,EAAA,MAAKN,MACfiB,EAAA;AAAA,IACN,4DAA4DD,CAAQ;AAAA,EAGrE,GAGIV,EAAA,MAAAN,GAAUgB,CAAQ,IAAIF,GACtB,KAAA;AAAA,IACJ,IAAI,YAAY,YAAY;AAAA,MAC3B,QAAQ;AAAA,QACP,QAAQI,EAAUZ,EAAA,MAAKN,EAAS;AAAA,QAChC,OAAOkB,EAAUZ,EAAA,MAAKP,EAAY;AAAA,MAAA;AAAA,IAEnC,CAAA;AAAA,EACF;AAAA;AAIF,SAASmB,EAAUC,GAA6B;AACxC,SAAA,OAAO,OAAOA,CAAG,EAAE,OAAO,CAACC,GAAQC,MAAUD,IAASC,GAAO,CAAC;AACtE;AAwBgB,SAAAZ,EACfD,GACAc,GACW;AACX,QAAMC,IAAgBf,EAAS,QAAQ,IAAI,gBAAgB,KAAK,IAC1DY,IAAS,SAASG,GAAe,EAAE,KAAK5B;AAE9C,SAAO,IAAI;AAAA,IACV6B,EAA2BhB,EAAS,MAAMY,GAAQE,CAAU;AAAA,IAC5D;AAAA,MACC,QAAQd,EAAS;AAAA,MACjB,YAAYA,EAAS;AAAA,MACrB,SAASA,EAAS;AAAA,IAAA;AAAA,EAEpB;AACD;AAYgB,SAAAgB,EACfC,GACAC,GACAJ,GAC6B;AACpB,WAAAK,EAAOb,GAAgBY,GAAe;AAC9C,IAAAJ;AAAA,MACC,IAAI,YAAY,YAAY;AAAA,QAC3B,QAAQ;AAAA,UACP,QAAAR;AAAA,UACA,OAAAY;AAAAA,QAAA;AAAA,MAED,CAAA;AAAA,IACF;AAAA,EAAA;AAGD,SAAO,IAAI,eAAe;AAAA,IACzB,MAAM,MAAME,GAAY;AACvB,UAAI,CAACH,GAAQ;AACZ,QAAAG,EAAW,MAAM;AACjB;AAAA,MAAA;AAEK,YAAAC,IAASJ,EAAO,UAAU;AAChC,UAAIX,IAAS;AACb;AACK,YAAA;AACH,gBAAM,EAAE,MAAAgB,GAAM,OAAAT,EAAU,IAAA,MAAMQ,EAAO,KAAK;AAI1C,cAHIR,MACHP,KAAUO,EAAM,aAEbS,GAAM;AACT,YAAAH,EAAOb,GAAQA,CAAM,GACrBc,EAAW,MAAM;AACjB;AAAA,UAAA;AAEA,YAAAD,EAAOb,GAAQY,CAAK,GACpBE,EAAW,QAAQP,CAAK;AAAA,iBAEjBU,GAAG;AACJ,UAAAd,EAAA,MAAM,EAAE,GAAAc,GAAG,GAClBH,EAAW,MAAMG,CAAC;AAClB;AAAA,QAAA;AAAA,IAEF;AAAA,EACD,CACA;AACF;;AC3KO,MAAMC,UAAyB,YAAY;AAAA,EAA3C,cAAA;AAAA,UAAA,GAAA,SAAA;AAAA,IAAAnC,EAAA,MAAAoC;AACN,IAAApC,EAAA,MAAAqC;AACA,IAAArC,EAAA,MAAAsC;AADA,IAAAC,EAAA,MAAAF,GAA8C,CAAC,IAC7BE,EAAA,MAAAD,GAAA,IAEP,KAAA,WAAA,GACU,KAAA,OAAA,aACX,KAAA,UAAA;AAAA,EAAA;AAAA,EAEV,gBAAgBE,GAAwBC,IAAU,IAAI;AAC/C,UAAAC,IAAY,EAALC,EAAA,MAAKL,GAAL;AACR,WAAA7B,EAAA,MAAA4B,GAAoBK,CAAE,IAAI,GACxB,CAACE,MAA4C;AACnD,YAAM,EAAE,QAAA3B,GAAQ,OAAAY,EAAU,KAAAe,KAAA,gBAAAA,EAAU,WAAU,CAAC;AAC/C,MAAAnC,EAAA,MAAK4B,GAAoBK,CAAE,IAAKzB,IAASY,IAASW,GAClD1B,EAAA,MAAKsB,GAAAS,GAAL,WAAiB,KAAK,eAAe,aAAaJ;AAAA,IACnD;AAAA,EAAA;AAAA,EAGD,kBAAkBG,GAAkB;AAC7B,UAAAF,IAAY,EAALC,EAAA,MAAKL,GAAL;AACR,IAAA7B,EAAA,MAAA4B,GAAoBK,CAAE,IAAIE,GAC1B9B,EAAA,MAAAsB,GAAAS,GAAA,WAAY,KAAK,eAAe;AAAA,EAAkB;AAAA,EAGxD,IAAI,gBAAgB;AACnB,WAAO,OAAO,OAAOpC,EAAA,MAAK4B,EAAmB,EAAE;AAAA,MAC9C,CAACR,GAAOe,MAAaf,IAAQe;AAAA,MAC7B;AAAA,IACD;AAAA,EAAA;AAcF;AAzCCP,IAAA,eACAC,IAAA,eAFMF,IAAA,eA+BNS,IAAA,SAAYD,GAAkBE,GAAoBL,GAAkB;AAC9D,OAAA;AAAA,IACJ,IAAI,YAAY,YAAY;AAAA,MAC3B,QAAQ;AAAA,QACP,UAAAG;AAAA,QACA,MAAAE;AAAA,QACA,SAAAL;AAAA,MAAA;AAAA,IAED,CAAA;AAAA,EACF;AAAA;ACOF,MAAMM,IAAmB;AAsClB,MAAMC,UAAwB,YAAY;AAAA,EAahD,YAAY;AAAA,IACX,QAAAC,IAAS;AAAA,IACT,SAAAR,IAAU;AAAA,IACV,UAAAS,IAAW;AAAA,EACZ,IAA4B,IAAI;AACzB,UAAA,GAjBP,KAAQ,cAAc,GACtB,KAAQ,YAAY,IACpB,KAAQ,gBAAgB,GACxB,KAAQ,eAAe,IAIvB,KAAQ,aAAa,IAGrB,KAAQ,eAAkC,CAAC,GAQ1C,KAAK,UAAUD,GACf,KAAK,eAAeR,GACpB,KAAK,YAAYS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsClB,MAAMD,GAAiBR,IAAU,IAAqB;AAIrD,QAHKQ,MACJA,IAAS,KAAK,cAEX,KAAK,cAAcA,IAAS;AAC/B,YAAM,IAAI;AAAA,QACT,kCAAkCA,CAAM;AAAA,MACzC;AAED,SAAK,eAAeA;AAEd,UAAAE,IAAa,IAAIH,EAAgB;AAAA,MACtC,SAAAP;AAAA,MACA,QAAAQ;AAAA,MACA,UAAU,KAAK;AAAA,IAAA,CACf;AACI,gBAAA,aAAa,KAAKE,CAAU,GACjCA,EAAW,iBAAiB,YAAY,MAAM,KAAK,gBAAgB,GACxDA,EAAA,iBAAiB,QAAQ,MAAM;AACzC,MAAI,KAAK,QACR,KAAK,WAAW;AAAA,IACjB,CACA,GACMA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBR,WAAW,EAAE,qBAAAC,IAAsB,GAAK,IAAI,CAAA,GAAU;AACrD,QAAI,KAAK;AACR;AAED,SAAK,aAAa;AAEZ,UAAAC,IAAW,KAAK,YADR;AAET,SAAA,gBAAgB,YAAY,MAAM;AACjC,WAAA,IAAI,KAAK,gBAAgB,CAAC,GAC3BD,KAAuB,KAAK,iBAAiB,MAChD,cAAc,KAAK,aAAa;AAAA,OAE/BC,CAAQ;AAAA,EAAA;AAAA,EAGZ,IAAI7B,GAAqB;AACxB,SAAK,gBAAgB,KAAK,IAAIA,GAAO,GAAG,GACxC,KAAK,eAAe,GAChB,KAAK,gBAAgBuB,KAAoB,OAC5C,KAAK,OAAO;AAAA,EACb;AAAA,EAGD,SAAe;AACd,IAAI,KAAK,iBACR,cAAc,KAAK,aAAa,GAEjC,KAAK,YAAY,IACjB,KAAK,gBAAgB,KACrB,KAAK,aAAa,IAClB,KAAK,gBAAgB,QACrB,KAAK,eAAe,GACpB,KAAK,WAAW;AAAA,EAAA;AAAA,EAGjB,IAAI,UAAkB;AACrB,aAASO,IAAI,KAAK,aAAa,SAAS,GAAGA,KAAK,GAAGA;AAClD,UAAI,CAAC,KAAK,aAAaA,CAAC,EAAE,MAAM;AAC/B,cAAMC,IAAe,KAAK,aAAaD,CAAC,EAAE;AAC1C,YAAIC;AACI,iBAAAA;AAAA,MACR;AAGF,WAAO,KAAK;AAAA,EAAA;AAAA,EAGb,WAAWd,GAAiB;AAC3B,SAAK,eAAeA,GACpB,KAAK,eAAe;AAAA,EAAA;AAAA,EAGrB,IAAI,OAAgB;AACZ,WAAA,KAAK,WAAWM,KAAoB;AAAA,EAAA;AAAA,EAG5C,IAAI,WAAmB;AACtB,QAAI,KAAK;AACD,aAAA;AAEF,UAAAS,IAAM,KAAK,aAAa;AAAA,MAC7B,CAACA,GAAKC,MAAYD,IAAMC,EAAQ,WAAWA,EAAQ;AAAA,MACnD,KAAK,gBAAgB,KAAK;AAAA,IAC3B;AACA,WAAO,KAAK,MAAMD,IAAM,GAAK,IAAI;AAAA,EAAA;AAAA,EAGlC,IAAI,SAAiB;AACpB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGb,IAAI,WAAW;AACV,WAAC,KAAK,sBACJ,KAAA,oBAAoB,CAACZ,MAAqB;AAC9C,WAAK,IAAIA,CAAQ;AAAA,IAClB,IAEM,KAAK;AAAA,EAAA;AAAA,EAGb,IAAI,kBAAkB;AACjB,WAAC,KAAK,qBACJ,KAAA,mBAAmB,CAAC/B,MAAwB;AAChD,WAAK,IAAKA,EAAM,OAAO,SAASA,EAAM,OAAO,QAAS,GAAG;AAAA,IAC1D,IAEM,KAAK;AAAA,EAAA;AAAA,EAGb,KAAK6C,GAA4B;AAChC,IAAAA,EAAS,YAAY;AAAA,MACpB,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,IAAA,CACd,GACI,KAAA,iBAAiB,YAAY,CAAC7C,MAAgC;AAClE,MAAA6C,EAAS,YAAY;AAAA,QACpB,UAAU7C,EAAM,OAAO;AAAA,QACvB,SAASA,EAAM,OAAO;AAAA,MAAA,CACtB;AAAA,IAAA,CACD,GACI,KAAA,iBAAiB,QAAQ,MAAM;AACnC,MAAA6C,EAAS,UAAU;AAAA,IAAA,CACnB;AAAA,EAAA;AAAA,EAGO,iBACRC,GACAC,GACC;AACK,UAAA,iBAAiBD,GAAMC,CAAe;AAAA,EAAA;AAAA,EAGpC,oBACRD,GACAC,GACC;AACK,UAAA,oBAAoBD,GAAMC,CAAe;AAAA,EAAA;AAAA,EAGxC,iBAAiB;AAExB,UAAMC,IAAO;AACR,SAAA;AAAA,MACJ,IAAI,YAAY,YAAY;AAAA,QAC3B,QAAQ;AAAA,UACP,IAAI,WAAW;AACd,mBAAOA,EAAK;AAAA,UACb;AAAA,UACA,IAAI,UAAU;AACb,mBAAOA,EAAK;AAAA,UAAA;AAAA,QACb;AAAA,MAED,CAAA;AAAA,IACF;AAAA,EAAA;AAAA,EAGO,aAAa;AACpB,SAAK,cAAc,IAAI,YAAY,MAAM,CAAC;AAAA,EAAA;AAE5C;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/progress/src/lib/emscripten-download-monitor.ts","../../../../packages/php-wasm/progress/src/lib/progress-observer.ts","../../../../packages/php-wasm/progress/src/lib/progress-tracker.ts"],"sourcesContent":["import { logger } from '@php-wasm/logger';\n/*\n * An approximate file length to use when the actual\n * length number of bytes is missing.\n *\n * This may happen when the files are compressed before transmission\n * and no content-length header is being sent.\n *\n * The approximation isn't accurate, but it's better than nothing.\n * It's not about being exact but about giving the user a rough sense\n * of #progress.\n */\nconst FALLBACK_FILE_SIZE = 5 * 1024 * 1024;\n\n/**\n * Monitors the download #progress of Emscripten modules\n *\n * Usage:\n *\n * ```js\n * const downloadMonitor = new EmscriptenDownloadMonitor();\n * \t const php = await startPHP(\n * phpLoaderModule,\n * 'web',\n * downloadMonitor.phpArgs\n * );\n * downloadMonitor.addEventListener('#progress', (e) => {\n * console.log( e.detail.#progress);\n * })\n * ```\n */\nexport class EmscriptenDownloadMonitor extends EventTarget {\n\t#assetsSizes: Record<string, number> = {};\n\t#progress: Record<string, number> = {};\n\n\texpectAssets(assets: Record<string, number>) {\n\t\tfor (const [urlLike, size] of Object.entries(assets)) {\n\t\t\tconst dummyBaseUrl = 'http://example.com/';\n\t\t\tconst pathname = new URL(urlLike, dummyBaseUrl).pathname;\n\t\t\tconst filename = pathname.split('/').pop()!;\n\t\t\tif (!(filename in this.#assetsSizes)) {\n\t\t\t\tthis.#assetsSizes[filename] = size;\n\t\t\t}\n\t\t\tif (!(filename in this.#progress)) {\n\t\t\t\tthis.#progress[filename] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync monitorFetch(fetchPromise: Promise<Response>): Promise<Response> {\n\t\tconst response = await fetchPromise;\n\t\tconst onProgress = (event: CustomEvent<DownloadProgress>) => {\n\t\t\tthis.#notify(response.url, event.detail.loaded, event.detail.total);\n\t\t};\n\t\treturn cloneResponseMonitorProgress(response, onProgress);\n\t}\n\n\t/**\n\t * Notifies about the download #progress of a file.\n\t *\n\t * @param file The file name.\n\t * @param loaded The number of bytes of that file loaded so far.\n\t * @param fileSize The length number of bytes in the loaded file.\n\t */\n\t#notify(file: string, loaded: number, fileSize: number) {\n\t\tconst fileName = new URL(file, 'http://example.com').pathname\n\t\t\t.split('/')\n\t\t\t.pop()!;\n\t\tif (!fileSize) {\n\t\t\tfileSize = this.#assetsSizes[fileName];\n\t\t} else if (!(fileName in this.#assetsSizes)) {\n\t\t\tthis.#assetsSizes[fileName] = fileSize;\n\t\t\tthis.#progress[fileName] = loaded;\n\t\t}\n\t\tif (!(fileName in this.#progress)) {\n\t\t\tlogger.warn(\n\t\t\t\t`Registered a download #progress of an unregistered file \"${fileName}\". ` +\n\t\t\t\t\t`This may cause a sudden **decrease** in the #progress percentage as the ` +\n\t\t\t\t\t`length number of bytes increases during the download.`\n\t\t\t);\n\t\t}\n\n\t\tthis.#progress[fileName] = loaded;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded: sumValues(this.#progress),\n\t\t\t\t\ttotal: sumValues(this.#assetsSizes),\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n\nfunction sumValues(obj: Record<string, number>) {\n\treturn Object.values(obj).reduce((length, value) => length + value, 0);\n}\n\nexport default EmscriptenDownloadMonitor;\n\nexport interface DownloadProgress {\n\t/**\n\t * The number of bytes loaded so far.\n\t */\n\tloaded: number;\n\t/**\n\t * The length number of bytes to load.\n\t */\n\ttotal: number;\n}\n\n/**\n * Clones a fetch Response object and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param response The fetch Response object to clone.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned response\n */\nexport function cloneResponseMonitorProgress(\n\tresponse: Response,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): Response {\n\tconst contentLength = response.headers.get('content-length') || '';\n\tconst length = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;\n\n\treturn new Response(\n\t\tcloneStreamMonitorProgress(response.body, length, onProgress),\n\t\t{\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t}\n\t);\n}\n\n/**\n * Clones a ReadableStream and returns a version\n * that calls the `onProgress` callback as the #progress\n * changes.\n *\n * @param stream The ReadableStream to clone.\n * @param total The total number of bytes to load.\n * @param onProgress The callback to call when the download #progress changes.\n * @returns The cloned ReadableStream\n */\nexport function cloneStreamMonitorProgress(\n\tstream: ReadableStream<Uint8Array> | null,\n\ttotal: number,\n\tonProgress: (event: CustomEvent<DownloadProgress>) => void\n): ReadableStream<Uint8Array> {\n\tfunction notify(loaded: number, total: number) {\n\t\tonProgress(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tloaded,\n\t\t\t\t\ttotal,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\treturn new ReadableStream({\n\t\tasync start(controller) {\n\t\t\tif (!stream) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reader = stream.getReader();\n\t\t\tlet loaded = 0;\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\tloaded += value.byteLength;\n\t\t\t\t\t}\n\t\t\t\t\tif (done) {\n\t\t\t\t\t\tnotify(loaded, loaded);\n\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(loaded, total);\n\t\t\t\t\t\tcontroller.enqueue(value);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger.error({ e });\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport type DownloadProgressCallback = (progress: DownloadProgress) => void;\n","import type { DownloadProgress } from './emscripten-download-monitor';\n\nexport type ProgressMode =\n\t/**\n\t * Real-time progress is used when we get real-time reports\n\t * about the progress.\n\t */\n\t| 'REAL_TIME'\n\n\t/**\n\t * Slowly increment progress is used when we don't know how long\n\t * an operation will take and just want to keep slowly incrementing\n\t * the progress bar.\n\t */\n\t| 'SLOWLY_INCREMENT';\n\nexport type ProgressObserverEvent = {\n\tprogress: number;\n\tmode: ProgressMode;\n\tcaption: string;\n};\n\nexport class ProgressObserver extends EventTarget {\n\t#observedProgresses: Record<number, number> = {};\n\t#lastObserverId = 0;\n\n\tprogress = 0;\n\tmode: ProgressMode = 'REAL_TIME';\n\tcaption = '';\n\n\tpartialObserver(progressBudget: number, caption = '') {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = 0;\n\t\treturn (progress: CustomEvent<DownloadProgress>) => {\n\t\t\tconst { loaded, total } = progress?.detail || {};\n\t\t\tthis.#observedProgresses[id] = (loaded / total) * progressBudget;\n\t\t\tthis.#onProgress(this.totalProgress, 'REAL_TIME', caption);\n\t\t};\n\t}\n\n\tslowlyIncrementBy(progress: number) {\n\t\tconst id = ++this.#lastObserverId;\n\t\tthis.#observedProgresses[id] = progress;\n\t\tthis.#onProgress(this.totalProgress, 'SLOWLY_INCREMENT');\n\t}\n\n\tget totalProgress() {\n\t\treturn Object.values(this.#observedProgresses).reduce(\n\t\t\t(total, progress) => total + progress,\n\t\t\t0\n\t\t);\n\t}\n\n\t#onProgress(progress: number, mode: ProgressMode, caption?: string) {\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tprogress,\n\t\t\t\t\tmode,\n\t\t\t\t\tcaption,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n}\n","/**\n * Options for customizing the progress tracker.\n */\nexport interface ProgressTrackerOptions {\n\t/** The weight of the progress, a number between 0 and 1. */\n\tweight?: number;\n\t/** The caption to display during progress, a string. */\n\tcaption?: string;\n\t/** The time in milliseconds to fill the progress, a number. */\n\tfillTime?: number;\n}\n\n/**\n * Custom event providing information about a loading process.\n */\nexport type LoadingEvent = CustomEvent<{\n\t/** The number representing how much was loaded. */\n\tloaded: number;\n\t/** The number representing how much needs to loaded in total. */\n\ttotal: number;\n}>;\n\n/**\n * Custom event providing progress details.\n */\nexport type ProgressTrackerEvent = CustomEvent<ProgressDetails>;\n\n/**\n * Custom event providing progress details when the task is done.\n */\nexport type DoneEvent = CustomEvent<ProgressDetails>;\n\nexport interface ProgressDetails {\n\t/** The progress percentage as a number between 0 and 100. */\n\tprogress: number;\n\t/** The caption to display during progress, a string. */\n\tcaption: string;\n}\n\n/**\n * ProgressObserver A function that receives progress updates.\n *\n * @param progress The progress percentage as a number between 0 and 100.\n */\ntype ProgressObserver = (progress: number) => void;\n\n/**\n * Listener A function for handling specific event types.\n *\n * @param event The event of type T.\n */\nexport type Listener<T> = (event: T) => void;\n\nexport type TSCompatibleListener<T> =\n\t| EventListenerOrEventListenerObject\n\t| null\n\t| Listener<T>;\n\nexport interface ProgressReceiver {\n\tsetProgress(details: ProgressDetails): any;\n\tsetLoaded(): any;\n}\n\n/*\n * Like Number.EPSILON, but better tuned to tracking progress.\n *\n * With Number.EPSILON, progress like 99.99999999999997 is still\n * considered to be below 100 – this is highly undeisrable.\n */\nconst PROGRESS_EPSILON = 0.00001;\n\n/**\n * The ProgressTracker class is a tool for tracking progress in an operation\n * that is divided into multiple stages. It allows you to create sub-trackers\n * for each stage, with individual weights and captions. The main tracker\n * automatically calculates the progress based on the weighted sum of each\n * sub-tracker's progress. This makes it easy to keep track of a complex,\n * multi-stage process and report progress in a user-friendly way.\n *\n * After creating the sub-trackers, you can call the set() method to update the\n * progress of the current stage. You can also call the finish() method to mark\n * the current stage as complete and move on to the next one. Alternatively,\n * you can call the fillSlowly() method to simulate progress filling up slowly\n * to 100% before calling finish().\n *\n * @example\n * ```ts\n * const tracker = new ProgressTracker();\n * tracker.addEventListener('progress', (e) => {\n * \t\tconsole.log(\n * \t\t\t\te.detail.progress,\n * \t\t\t\te.detail.caption\n * \t\t);\n * });\n *\n * const stage1 = tracker.stage(0.5, 'Calculating pi digits');\n * const stage2 = tracker.stage(0.5, 'Downloading data');\n *\n * stage1.fillSlowly();\n * await calc100DigitsOfPi();\n * stage1.finish();\n *\n * await fetchWithProgress(function onProgress(loaded, total) {\n * \t\tstage2.set( loaded / total * 100);\n * });\n * stage2.finish();\n */\nexport class ProgressTracker extends EventTarget {\n\tprivate _selfWeight = 1;\n\tprivate _selfDone = false;\n\tprivate _selfProgress = 0;\n\tprivate _selfCaption = '';\n\tprivate _weight: number;\n\tprivate _progressObserver?: ProgressObserver;\n\tprivate _loadingListener?: Listener<LoadingEvent>;\n\tprivate _isFilling = false;\n\tprivate _fillTime: number;\n\tprivate _fillInterval?: any;\n\tprivate _subTrackers: ProgressTracker[] = [];\n\n\tconstructor({\n\t\tweight = 1,\n\t\tcaption = '',\n\t\tfillTime = 4,\n\t}: ProgressTrackerOptions = {}) {\n\t\tsuper();\n\t\tthis._weight = weight;\n\t\tthis._selfCaption = caption;\n\t\tthis._fillTime = fillTime;\n\t}\n\n\t/**\n\t * Creates a new sub-tracker with a specific weight.\n\t *\n\t * The weight determines what percentage of the overall progress\n\t * the sub-tracker represents. For example, if the main tracker is\n\t * monitoring a process that has two stages, and the first stage\n\t * is expected to take twice as long as the second stage, you could\n\t * create the first sub-tracker with a weight of 0.67 and the second\n\t * sub-tracker with a weight of 0.33.\n\t *\n\t * The caption is an optional string that describes the current stage\n\t * of the operation. If provided, it will be used as the progress caption\n\t * for the sub-tracker. If not provided, the main tracker will look for\n\t * the next sub-tracker with a non-empty caption and use that as the progress\n\t * caption instead.\n\t *\n\t * Returns the newly-created sub-tracker.\n\t *\n\t * @throws {Error} If the weight of the new stage would cause the total weight of all stages to exceed 1.\n\t *\n\t * @param weight The weight of the new stage, as a decimal value between 0 and 1.\n\t * @param caption The caption for the new stage, which will be used as the progress caption for the sub-tracker.\n\t *\n\t * @example\n\t * ```ts\n\t * const tracker = new ProgressTracker();\n\t * const subTracker1 = tracker.stage(0.67, 'Slow stage');\n\t * const subTracker2 = tracker.stage(0.33, 'Fast stage');\n\t *\n\t * subTracker2.set(50);\n\t * subTracker1.set(75);\n\t * subTracker2.set(100);\n\t * subTracker1.set(100);\n\t * ```\n\t */\n\tstage(weight?: number, caption = ''): ProgressTracker {\n\t\tif (!weight) {\n\t\t\tweight = this._selfWeight;\n\t\t}\n\t\tif (this._selfWeight - weight < -PROGRESS_EPSILON) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot add a stage with weight ${weight} as the total weight of registered stages would exceed 1.`\n\t\t\t);\n\t\t}\n\t\tthis._selfWeight -= weight;\n\n\t\tconst subTracker = new ProgressTracker({\n\t\t\tcaption,\n\t\t\tweight,\n\t\t\tfillTime: this._fillTime,\n\t\t});\n\t\tthis._subTrackers.push(subTracker);\n\t\tsubTracker.addEventListener('progress', () => this.notifyProgress());\n\t\tsubTracker.addEventListener('done', () => {\n\t\t\tif (this.done) {\n\t\t\t\tthis.notifyDone();\n\t\t\t}\n\t\t});\n\t\treturn subTracker;\n\t}\n\n\t/**\n\t * Fills the progress bar slowly over time, simulating progress.\n\t *\n\t * The progress bar is filled in a 100 steps, and each step, the progress\n\t * is increased by 1. If `stopBeforeFinishing` is true, the progress bar\n\t * will stop filling when it reaches 99% so that you can call `finish()`\n\t * explicitly.\n\t *\n\t * If the progress bar is filling or already filled, this method does nothing.\n\t *\n\t * @example\n\t * ```ts\n\t * const progress = new ProgressTracker({ caption: 'Processing...' });\n\t * progress.fillSlowly();\n\t * ```\n\t *\n\t * @param options Optional options.\n\t */\n\tfillSlowly({ stopBeforeFinishing = true } = {}): void {\n\t\tif (this._isFilling) {\n\t\t\treturn;\n\t\t}\n\t\tthis._isFilling = true;\n\t\tconst steps = 100;\n\t\tconst interval = this._fillTime / steps;\n\t\tthis._fillInterval = setInterval(() => {\n\t\t\tthis.set(this._selfProgress + 1);\n\t\t\tif (stopBeforeFinishing && this._selfProgress >= 99) {\n\t\t\t\tclearInterval(this._fillInterval);\n\t\t\t}\n\t\t}, interval);\n\t}\n\n\tset(value: number): void {\n\t\tthis._selfProgress = Math.min(value, 100);\n\t\tthis.notifyProgress();\n\t\tif (this._selfProgress + PROGRESS_EPSILON >= 100) {\n\t\t\tthis.finish();\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this._fillInterval) {\n\t\t\tclearInterval(this._fillInterval);\n\t\t}\n\t\tthis._selfDone = true;\n\t\tthis._selfProgress = 100;\n\t\tthis._isFilling = false;\n\t\tthis._fillInterval = undefined;\n\t\tthis.notifyProgress();\n\t\tthis.notifyDone();\n\t}\n\n\tget caption(): string {\n\t\tfor (let i = this._subTrackers.length - 1; i >= 0; i--) {\n\t\t\tif (!this._subTrackers[i].done) {\n\t\t\t\tconst captionMaybe = this._subTrackers[i].caption;\n\t\t\t\tif (captionMaybe) {\n\t\t\t\t\treturn captionMaybe;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this._selfCaption;\n\t}\n\n\tsetCaption(caption: string) {\n\t\tthis._selfCaption = caption;\n\t\tthis.notifyProgress();\n\t}\n\n\tget done(): boolean {\n\t\treturn this.progress + PROGRESS_EPSILON >= 100;\n\t}\n\n\tget progress(): number {\n\t\tif (this._selfDone) {\n\t\t\treturn 100;\n\t\t}\n\t\tconst sum = this._subTrackers.reduce(\n\t\t\t(sum, tracker) => sum + tracker.progress * tracker.weight,\n\t\t\tthis._selfProgress * this._selfWeight\n\t\t);\n\t\treturn Math.round(sum * 10000) / 10000;\n\t}\n\n\tget weight(): number {\n\t\treturn this._weight;\n\t}\n\n\tget observer() {\n\t\tif (!this._progressObserver) {\n\t\t\tthis._progressObserver = (progress: number) => {\n\t\t\t\tthis.set(progress);\n\t\t\t};\n\t\t}\n\t\treturn this._progressObserver;\n\t}\n\n\tget loadingListener() {\n\t\tif (!this._loadingListener) {\n\t\t\tthis._loadingListener = (event: LoadingEvent) => {\n\t\t\t\tthis.set((event.detail.loaded / event.detail.total) * 100);\n\t\t\t};\n\t\t}\n\t\treturn this._loadingListener;\n\t}\n\n\tpipe(receiver: ProgressReceiver) {\n\t\treceiver.setProgress({\n\t\t\tprogress: this.progress,\n\t\t\tcaption: this.caption,\n\t\t});\n\t\tthis.addEventListener('progress', (event: ProgressTrackerEvent) => {\n\t\t\treceiver.setProgress({\n\t\t\t\tprogress: event.detail.progress,\n\t\t\t\tcaption: event.detail.caption,\n\t\t\t});\n\t\t});\n\t\tthis.addEventListener('done', () => {\n\t\t\treceiver.setLoaded();\n\t\t});\n\t}\n\n\toverride addEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.addEventListener(type, listener as any);\n\t}\n\n\toverride removeEventListener(\n\t\ttype: string,\n\t\tlistener: TSCompatibleListener<ProgressTrackerEvent>\n\t) {\n\t\tsuper.removeEventListener(type, listener as any);\n\t}\n\n\tprivate notifyProgress() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent('progress', {\n\t\t\t\tdetail: {\n\t\t\t\t\tget progress() {\n\t\t\t\t\t\treturn self.progress;\n\t\t\t\t\t},\n\t\t\t\t\tget caption() {\n\t\t\t\t\t\treturn self.caption;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\tprivate notifyDone() {\n\t\tthis.dispatchEvent(new CustomEvent('done'));\n\t}\n}\n"],"names":["FALLBACK_FILE_SIZE","EmscriptenDownloadMonitor","__privateAdd","_EmscriptenDownloadMonitor_instances","_assetsSizes","_progress","assets","urlLike","size","dummyBaseUrl","filename","__privateGet","fetchPromise","response","cloneResponseMonitorProgress","event","__privateMethod","notify_fn","file","loaded","fileSize","fileName","logger","sumValues","obj","length","value","onProgress","contentLength","cloneStreamMonitorProgress","stream","total","notify","controller","reader","done","e","ProgressObserver","_ProgressObserver_instances","_observedProgresses","_lastObserverId","__privateSet","progressBudget","caption","id","__privateWrapper","progress","onProgress_fn","mode","PROGRESS_EPSILON","ProgressTracker","weight","fillTime","subTracker","stopBeforeFinishing","interval","i","captionMaybe","sum","tracker","receiver","type","listener","self"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/progress",
3
- "version": "3.0.15",
3
+ "version": "3.0.16",
4
4
  "description": "PHP.wasm – loading progress monitoring",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,7 +37,7 @@
37
37
  "main": "./index.cjs",
38
38
  "module": "./index.js",
39
39
  "types": "index.d.ts",
40
- "gitHead": "4e8addef4a0fa0e76f26785689a1a676bbb823e1",
40
+ "gitHead": "1f96a559fda4946f36f8543a2715cee411a5c8f2",
41
41
  "engines": {
42
42
  "node": ">=20.18.3",
43
43
  "npm": ">=10.1.0"
@@ -54,8 +54,8 @@
54
54
  "form-data": "^4.0.4"
55
55
  },
56
56
  "dependencies": {
57
- "@php-wasm/node-polyfills": "3.0.15",
58
- "@php-wasm/logger": "3.0.15"
57
+ "@php-wasm/node-polyfills": "3.0.16",
58
+ "@php-wasm/logger": "3.0.16"
59
59
  },
60
60
  "optionalDependencies": {
61
61
  "fs-ext": "2.1.1"