@php-wasm/progress
Advanced tools
+1
-1
@@ -1,2 +0,2 @@ | ||
| "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; | ||
| "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; | ||
| //# sourceMappingURL=index.cjs.map |
+1
-1
@@ -1,1 +0,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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"} | ||
| {"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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"} |
+14
-14
@@ -1,6 +0,6 @@ | ||
| var P = (i) => { | ||
| var w = (i) => { | ||
| throw TypeError(i); | ||
| }; | ||
| var E = (i, e, t) => e.has(i) || P("Cannot " + t); | ||
| 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); | ||
| var E = (i, e, t) => e.has(i) || w("Cannot " + t); | ||
| 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); | ||
| var b = (i, e, t, s) => ({ | ||
@@ -52,4 +52,4 @@ set _(r) { | ||
| detail: { | ||
| loaded: w(o(this, l)), | ||
| total: w(o(this, h)) | ||
| loaded: y(o(this, l)), | ||
| total: y(o(this, h)) | ||
| } | ||
@@ -59,3 +59,3 @@ }) | ||
| }; | ||
| function w(i) { | ||
| function y(i) { | ||
| return Object.values(i).reduce((e, t) => e + t, 0); | ||
@@ -108,3 +108,3 @@ } | ||
| } | ||
| var g, f, u, L; | ||
| var g, f, u, P; | ||
| class S extends EventTarget { | ||
@@ -122,3 +122,3 @@ constructor() { | ||
| const { loaded: d, total: a } = (n == null ? void 0 : n.detail) || {}; | ||
| o(this, g)[r] = d / a * t, _(this, u, L).call(this, this.totalProgress, "REAL_TIME", s); | ||
| o(this, g)[r] = d / a * t, _(this, u, P).call(this, this.totalProgress, "REAL_TIME", s); | ||
| }; | ||
@@ -128,3 +128,3 @@ } | ||
| const s = ++b(this, f)._; | ||
| o(this, g)[s] = t, _(this, u, L).call(this, this.totalProgress, "SLOWLY_INCREMENT"); | ||
| o(this, g)[s] = t, _(this, u, P).call(this, this.totalProgress, "SLOWLY_INCREMENT"); | ||
| } | ||
@@ -138,3 +138,3 @@ get totalProgress() { | ||
| } | ||
| g = new WeakMap(), f = new WeakMap(), u = new WeakSet(), L = function(t, s, r) { | ||
| g = new WeakMap(), f = new WeakMap(), u = new WeakSet(), P = function(t, s, r) { | ||
| this.dispatchEvent( | ||
@@ -150,3 +150,3 @@ new CustomEvent("progress", { | ||
| }; | ||
| const y = 1e-5; | ||
| const L = 1e-5; | ||
| class C extends EventTarget { | ||
@@ -196,3 +196,3 @@ constructor({ | ||
| stage(e, t = "") { | ||
| if (e || (e = this._selfWeight), this._selfWeight - e < -1e-5) | ||
| if (e || (e = this._selfWeight), this._selfWeight - e < -L) | ||
| throw new Error( | ||
@@ -239,3 +239,3 @@ `Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.` | ||
| set(e) { | ||
| this._selfProgress = Math.min(e, 100), this.notifyProgress(), this._selfProgress + y >= 100 && this.finish(); | ||
| this._selfProgress = Math.min(e, 100), this.notifyProgress(), this._selfProgress + L >= 100 && this.finish(); | ||
| } | ||
@@ -258,3 +258,3 @@ finish() { | ||
| get done() { | ||
| return this.progress + y >= 100; | ||
| return this.progress + L >= 100; | ||
| } | ||
@@ -261,0 +261,0 @@ get progress() { |
+1
-1
@@ -1,1 +0,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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"} | ||
| {"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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"} |
+4
-4
| { | ||
| "name": "@php-wasm/progress", | ||
| "version": "3.0.15", | ||
| "version": "3.0.16", | ||
| "description": "PHP.wasm – loading progress monitoring", | ||
@@ -40,3 +40,3 @@ "repository": { | ||
| "types": "index.d.ts", | ||
| "gitHead": "4e8addef4a0fa0e76f26785689a1a676bbb823e1", | ||
| "gitHead": "1f96a559fda4946f36f8543a2715cee411a5c8f2", | ||
| "engines": { | ||
@@ -58,4 +58,4 @@ "node": ">=20.18.3", | ||
| "dependencies": { | ||
| "@php-wasm/node-polyfills": "3.0.15", | ||
| "@php-wasm/logger": "3.0.15" | ||
| "@php-wasm/node-polyfills": "3.0.16", | ||
| "@php-wasm/logger": "3.0.16" | ||
| }, | ||
@@ -62,0 +62,0 @@ "optionalDependencies": { |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
94690
0.02%599
-0.17%+ Added
+ Added
- Removed
- Removed
Updated