@php-wasm/progress 0.1.2 → 0.1.3

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 ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=5*1024*1024;class g extends EventTarget{#e={};#t={};constructor(t=[]){super(),this.setModules(t),this.#s()}getEmscriptenArgs(){return{dataFileDownloads:this.#r()}}setModules(t){this.#e=t.reduce((e,n)=>{if(n.dependenciesTotalSize>0){const s="http://example.com/",o=new URL(n.dependencyFilename,s).pathname.split("/").pop();e[o]=Math.max(o in e?e[o]:0,n.dependenciesTotalSize)}return e},{}),this.#t=Object.fromEntries(Object.entries(this.#e).map(([e])=>[e,0]))}#s(){const t=WebAssembly.instantiateStreaming;WebAssembly.instantiateStreaming=async(e,...n)=>{const s=await e,r=s.url.substring(new URL(s.url).origin.length+1),o=u(s,({detail:{loaded:i,total:l}})=>this.#n(r,i,l));return t(o,...n)}}#r(){const t=this,e={};return new Proxy(e,{set(n,s,r){return t.#n(s,r.loaded,r.total),n[s]=new Proxy(JSON.parse(JSON.stringify(r)),{set(o,i,l){return o[i]=l,t.#n(s,o.loaded,o.total),!0}}),!0}})}#n(t,e,n){const s=new URL(t,"http://example.com").pathname.split("/").pop();n||(n=this.#e[s]),s in this.#t||console.warn(`Registered a download #progress of an unregistered file "${s}". This may cause a sudden **decrease** in the #progress percentage as the total number of bytes increases during the download.`),this.#t[t]=e,this.dispatchEvent(new CustomEvent("progress",{detail:{loaded:c(this.#t),total:c(this.#e)}}))}}function c(a){return Object.values(a).reduce((t,e)=>t+e,0)}function u(a,t){const e=a.headers.get("content-length")||"",n=parseInt(e,10)||h;function s(r,o){t(new CustomEvent("progress",{detail:{loaded:r,total:o}}))}return new Response(new ReadableStream({async start(r){if(!a.body){r.close();return}const o=a.body.getReader();let i=0;for(;;)try{const{done:l,value:d}=await o.read();if(d&&(i+=d.byteLength),l){s(i,i),r.close();break}else s(i,n),r.enqueue(d)}catch(l){console.error({e:l}),r.error(l);break}}}),{status:a.status,statusText:a.statusText,headers:a.headers})}class p extends EventTarget{constructor(){super(...arguments),this.#e={},this.#t=0,this.progress=0,this.mode="REAL_TIME",this.caption=""}#e;#t;partialObserver(t,e=""){const n=++this.#t;return this.#e[n]=0,s=>{const{loaded:r,total:o}=s?.detail||{};this.#e[n]=r/o*t,this.#s(this.totalProgress,"REAL_TIME",e)}}slowlyIncrementBy(t){const e=++this.#t;this.#e[e]=t,this.#s(this.totalProgress,"SLOWLY_INCREMENT")}get totalProgress(){return Object.values(this.#e).reduce((t,e)=>t+e,0)}#s(t,e,n){this.dispatchEvent(new CustomEvent("progress",{detail:{progress:t,mode:e,caption:n}}))}}exports.EmscriptenDownloadMonitor=g;exports.ProgressObserver=p;exports.cloneResponseMonitorProgress=u;
package/index.js ADDED
@@ -0,0 +1,164 @@
1
+ class u extends EventTarget {
2
+ #e = {};
3
+ #t = {};
4
+ constructor(t = []) {
5
+ super(), this.setModules(t), this.#s();
6
+ }
7
+ getEmscriptenArgs() {
8
+ return {
9
+ dataFileDownloads: this.#r()
10
+ };
11
+ }
12
+ setModules(t) {
13
+ this.#e = t.reduce((e, n) => {
14
+ if (n.dependenciesTotalSize > 0) {
15
+ const s = "http://example.com/", a = new URL(n.dependencyFilename, s).pathname.split("/").pop();
16
+ e[a] = Math.max(
17
+ a in e ? e[a] : 0,
18
+ n.dependenciesTotalSize
19
+ );
20
+ }
21
+ return e;
22
+ }, {}), this.#t = Object.fromEntries(
23
+ Object.entries(this.#e).map(([e]) => [e, 0])
24
+ );
25
+ }
26
+ /**
27
+ * Replaces the default WebAssembly.instantiateStreaming with a version
28
+ * that monitors the download #progress.
29
+ */
30
+ #s() {
31
+ const t = WebAssembly.instantiateStreaming;
32
+ WebAssembly.instantiateStreaming = async (e, ...n) => {
33
+ const s = await e, r = s.url.substring(
34
+ new URL(s.url).origin.length + 1
35
+ ), a = h(
36
+ s,
37
+ ({ detail: { loaded: i, total: l } }) => this.#n(r, i, l)
38
+ );
39
+ return t(a, ...n);
40
+ };
41
+ }
42
+ /**
43
+ * Creates a `dataFileDownloads` Proxy object that can be passed
44
+ * to `startPHP` to monitor the download #progress of the data
45
+ * dependencies.
46
+ */
47
+ #r() {
48
+ const t = this, e = {};
49
+ return new Proxy(e, {
50
+ set(n, s, r) {
51
+ return t.#n(s, r.loaded, r.total), n[s] = new Proxy(JSON.parse(JSON.stringify(r)), {
52
+ set(a, i, l) {
53
+ return a[i] = l, t.#n(s, a.loaded, a.total), !0;
54
+ }
55
+ }), !0;
56
+ }
57
+ });
58
+ }
59
+ /**
60
+ * Notifies about the download #progress of a file.
61
+ *
62
+ * @param file The file name.
63
+ * @param loaded The number of bytes of that file loaded so far.
64
+ * @param fileSize The total number of bytes in the loaded file.
65
+ */
66
+ #n(t, e, n) {
67
+ const s = new URL(t, "http://example.com").pathname.split("/").pop();
68
+ n || (n = this.#e[s]), s in this.#t || console.warn(
69
+ `Registered a download #progress of an unregistered file "${s}". This may cause a sudden **decrease** in the #progress percentage as the total number of bytes increases during the download.`
70
+ ), this.#t[t] = e, this.dispatchEvent(
71
+ new CustomEvent("progress", {
72
+ detail: {
73
+ loaded: c(this.#t),
74
+ total: c(this.#e)
75
+ }
76
+ })
77
+ );
78
+ }
79
+ }
80
+ function c(o) {
81
+ return Object.values(o).reduce((t, e) => t + e, 0);
82
+ }
83
+ function h(o, t) {
84
+ const e = o.headers.get("content-length") || "", n = parseInt(e, 10) || 5242880;
85
+ function s(r, a) {
86
+ t(
87
+ new CustomEvent("progress", {
88
+ detail: {
89
+ loaded: r,
90
+ total: a
91
+ }
92
+ })
93
+ );
94
+ }
95
+ return new Response(
96
+ new ReadableStream({
97
+ async start(r) {
98
+ if (!o.body) {
99
+ r.close();
100
+ return;
101
+ }
102
+ const a = o.body.getReader();
103
+ let i = 0;
104
+ for (; ; )
105
+ try {
106
+ const { done: l, value: d } = await a.read();
107
+ if (d && (i += d.byteLength), l) {
108
+ s(i, i), r.close();
109
+ break;
110
+ } else
111
+ s(i, n), r.enqueue(d);
112
+ } catch (l) {
113
+ console.error({ e: l }), r.error(l);
114
+ break;
115
+ }
116
+ }
117
+ }),
118
+ {
119
+ status: o.status,
120
+ statusText: o.statusText,
121
+ headers: o.headers
122
+ }
123
+ );
124
+ }
125
+ class g extends EventTarget {
126
+ constructor() {
127
+ super(...arguments), this.#e = {}, this.#t = 0, this.progress = 0, this.mode = "REAL_TIME", this.caption = "";
128
+ }
129
+ #e;
130
+ #t;
131
+ partialObserver(t, e = "") {
132
+ const n = ++this.#t;
133
+ return this.#e[n] = 0, (s) => {
134
+ const { loaded: r, total: a } = s?.detail || {};
135
+ this.#e[n] = r / a * t, this.#s(this.totalProgress, "REAL_TIME", e);
136
+ };
137
+ }
138
+ slowlyIncrementBy(t) {
139
+ const e = ++this.#t;
140
+ this.#e[e] = t, this.#s(this.totalProgress, "SLOWLY_INCREMENT");
141
+ }
142
+ get totalProgress() {
143
+ return Object.values(this.#e).reduce(
144
+ (t, e) => t + e,
145
+ 0
146
+ );
147
+ }
148
+ #s(t, e, n) {
149
+ this.dispatchEvent(
150
+ new CustomEvent("progress", {
151
+ detail: {
152
+ progress: t,
153
+ mode: e,
154
+ caption: n
155
+ }
156
+ })
157
+ );
158
+ }
159
+ }
160
+ export {
161
+ u as EmscriptenDownloadMonitor,
162
+ g as ProgressObserver,
163
+ h as cloneResponseMonitorProgress
164
+ };
@@ -0,0 +1,51 @@
1
+ export interface MonitoredModule {
2
+ dependencyFilename: string;
3
+ dependenciesTotalSize: number;
4
+ }
5
+ /**
6
+ * Monitors the download #progress of Emscripten modules
7
+ *
8
+ * Usage:
9
+ *
10
+ * ```js
11
+ * const downloadMonitor = new EmscriptenDownloadMonitor();
12
+ * const php = await startPHP(
13
+ * phpLoaderModule,
14
+ * 'web',
15
+ * downloadMonitor.phpArgs
16
+ * );
17
+ * downloadMonitor.addEventListener('#progress', (e) => {
18
+ * console.log( e.detail.#progress);
19
+ * })
20
+ * ```
21
+ */
22
+ export declare class EmscriptenDownloadMonitor extends EventTarget {
23
+ #private;
24
+ constructor(modules?: MonitoredModule[]);
25
+ getEmscriptenArgs(): {
26
+ dataFileDownloads: Record<string, any>;
27
+ };
28
+ setModules(modules: MonitoredModule[]): void;
29
+ }
30
+ export default EmscriptenDownloadMonitor;
31
+ export interface DownloadProgress {
32
+ /**
33
+ * The number of bytes loaded so far.
34
+ */
35
+ loaded: number;
36
+ /**
37
+ * The total number of bytes to load.
38
+ */
39
+ total: number;
40
+ }
41
+ /**
42
+ * Clones a fetch Response object and returns a version
43
+ * that calls the `onProgress` callback as the #progress
44
+ * changes.
45
+ *
46
+ * @param response The fetch Response object to clone.
47
+ * @param onProgress The callback to call when the download #progress changes.
48
+ * @returns The cloned response
49
+ */
50
+ export declare function cloneResponseMonitorProgress(response: Response, onProgress: (event: CustomEvent<DownloadProgress>) => void): Response;
51
+ export type DownloadProgressCallback = (progress: DownloadProgress) => void;
@@ -0,0 +1,27 @@
1
+ import { DownloadProgress } from './emscripten-download-monitor';
2
+ export type ProgressMode =
3
+ /**
4
+ * Real-time progress is used when we get real-time reports
5
+ * about the progress.
6
+ */
7
+ 'REAL_TIME'
8
+ /**
9
+ * Slowly increment progress is used when we don't know how long
10
+ * an operation will take and just want to keep slowly incrementing
11
+ * the progress bar.
12
+ */
13
+ | 'SLOWLY_INCREMENT';
14
+ export type ProgressObserverEvent = {
15
+ progress: number;
16
+ mode: ProgressMode;
17
+ caption: string;
18
+ };
19
+ export declare class ProgressObserver extends EventTarget {
20
+ #private;
21
+ progress: number;
22
+ mode: ProgressMode;
23
+ caption: string;
24
+ partialObserver(progressBudget: number, caption?: string): (progress: CustomEvent<DownloadProgress>) => void;
25
+ slowlyIncrementBy(progress: number): void;
26
+ get totalProgress(): number;
27
+ }
package/package.json CHANGED
@@ -1,29 +1,34 @@
1
1
  {
2
- "name": "@php-wasm/progress",
3
- "version": "0.1.2",
4
- "description": "PHP.wasm – loading progress monitoring",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/WordPress/wordpress-playground"
8
- },
9
- "homepage": "https://developer.wordpress.org/playground",
10
- "author": "The WordPress contributors",
11
- "contributors": [
12
- {
13
- "name": "Adam Zielinski",
14
- "email": "adam@adamziel.com",
15
- "url": "https://github.com/adamziel"
16
- }
17
- ],
18
- "typedoc": {
19
- "entryPoint": "./src/index.ts",
20
- "readmeFile": "./README.md",
21
- "displayName": "@php-wasm/progress",
22
- "tsconfig": "./tsconfig.lib.json"
23
- },
24
- "license": "GPL-2.0-or-later",
25
- "type": "module",
26
- "main": "index.js",
27
- "types": "index.d.ts",
28
- "gitHead": "a0eeb66fd5386bb56715fca2b89e9669a5b8618b"
2
+ "name": "@php-wasm/progress",
3
+ "version": "0.1.3",
4
+ "description": "PHP.wasm – loading progress monitoring",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/WordPress/wordpress-playground"
8
+ },
9
+ "homepage": "https://developer.wordpress.org/playground",
10
+ "author": "The WordPress contributors",
11
+ "contributors": [
12
+ {
13
+ "name": "Adam Zielinski",
14
+ "email": "adam@adamziel.com",
15
+ "url": "https://github.com/adamziel"
16
+ }
17
+ ],
18
+ "typedoc": {
19
+ "entryPoint": "./src/index.ts",
20
+ "readmeFile": "./README.md",
21
+ "displayName": "@php-wasm/progress",
22
+ "tsconfig": "./tsconfig.lib.json"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "directory": "../../../dist/packages/php-wasm/progress"
27
+ },
28
+ "license": "GPL-2.0-or-later",
29
+ "type": "module",
30
+ "main": "index.js",
31
+ "types": "index.d.ts",
32
+ "gitHead": "ac5bf6b09cb425d650bc57eff03eac6417cccd49",
33
+ "dependencies": {}
29
34
  }
package/.eslintrc.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "extends": ["../../../.eslintrc.json"],
3
- "ignorePatterns": ["!**/*"],
4
- "overrides": [
5
- {
6
- "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
- "rules": {}
8
- },
9
- {
10
- "files": ["*.ts", "*.tsx"],
11
- "rules": {}
12
- },
13
- {
14
- "files": ["*.js", "*.jsx"],
15
- "rules": {}
16
- }
17
- ]
18
- }
package/README.md DELETED
@@ -1,11 +0,0 @@
1
- # php-wasm-progress
2
-
3
- PHP.wasm – loading progress monitoring utilities.
4
-
5
- ## Building
6
-
7
- Run `nx build php-wasm-progress` to build the library.
8
-
9
- ## Running unit tests
10
-
11
- Run `nx test php-wasm-progress` to execute the unit tests via [Jest](https://jestjs.io).
package/project.json DELETED
@@ -1,56 +0,0 @@
1
- {
2
- "name": "php-wasm-progress",
3
- "$schema": "../../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "packages/php-wasm/progress/src",
5
- "projectType": "library",
6
- "targets": {
7
- "build": {
8
- "executor": "@wp-playground/nx-extensions:package-json",
9
- "options": {
10
- "tsConfig": "packages/php-wasm/progress/tsconfig.lib.json",
11
- "outputPath": "dist/packages/php-wasm/progress",
12
- "buildTarget": "php-wasm-progress:build:bundle:production"
13
- }
14
- },
15
- "build:bundle": {
16
- "executor": "@nrwl/vite:build",
17
- "outputs": ["{options.outputPath}"],
18
- "options": {
19
- "outputPath": "dist/packages/php-wasm/progress"
20
- }
21
- },
22
- "publish": {
23
- "executor": "nx:run-commands",
24
- "options": {
25
- "command": "node tools/scripts/publish.mjs php-wasm-progress {args.ver} {args.tag}",
26
- "parallel": false
27
- },
28
- "dependsOn": ["build"]
29
- },
30
- "test": {
31
- "executor": "@nrwl/vite:test",
32
- "outputs": ["coverage/packages/php-wasm/progress"],
33
- "options": {
34
- "passWithNoTests": true,
35
- "reportsDirectory": "../../../coverage/packages/php-wasm/progress"
36
- }
37
- },
38
- "lint": {
39
- "executor": "@nrwl/linter:eslint",
40
- "outputs": ["{options.outputFile}"],
41
- "options": {
42
- "lintFilePatterns": ["packages/php-wasm/progress/**/*.ts"]
43
- }
44
- },
45
- "typecheck": {
46
- "executor": "@nrwl/workspace:run-commands",
47
- "options": {
48
- "commands": [
49
- "yarn tsc -p packages/php-wasm/progress/tsconfig.lib.json --noEmit",
50
- "yarn tsc -p packages/php-wasm/progress/tsconfig.spec.json --noEmit"
51
- ]
52
- }
53
- }
54
- },
55
- "tags": []
56
- }
@@ -1,242 +0,0 @@
1
- /*
2
- * An approximate total file size to use when the actual
3
- * total number of bytes is missing.
4
- *
5
- * This may happen when the files are compressed before transmission
6
- * and no content-length header is being sent.
7
- *
8
- * The approximation isn't accurate, but it's better than nothing.
9
- * It's not about being exact but about giving the user a rough sense
10
- * of #progress.
11
- */
12
- const FALLBACK_FILE_SIZE = 5 * 1024 * 1024;
13
-
14
- export interface MonitoredModule {
15
- dependencyFilename: string;
16
- dependenciesTotalSize: number;
17
- }
18
-
19
- /**
20
- * Monitors the download #progress of Emscripten modules
21
- *
22
- * Usage:
23
- *
24
- * ```js
25
- * const downloadMonitor = new EmscriptenDownloadMonitor();
26
- * const php = await startPHP(
27
- * phpLoaderModule,
28
- * 'web',
29
- * downloadMonitor.phpArgs
30
- * );
31
- * downloadMonitor.addEventListener('#progress', (e) => {
32
- * console.log( e.detail.#progress);
33
- * })
34
- * ```
35
- */
36
- export class EmscriptenDownloadMonitor extends EventTarget {
37
- #assetsSizes: Record<string, number> = {};
38
- #progress: Record<string, number> = {};
39
-
40
- constructor(modules: MonitoredModule[] = []) {
41
- super();
42
-
43
- this.setModules(modules);
44
- this.#monitorWebAssemblyStreaming();
45
- }
46
-
47
- getEmscriptenArgs() {
48
- return {
49
- dataFileDownloads: this.#createDataFileDownloadsProxy(),
50
- };
51
- }
52
-
53
- setModules(modules: MonitoredModule[]) {
54
- this.#assetsSizes = modules.reduce((acc, module) => {
55
- if (module.dependenciesTotalSize > 0) {
56
- // Required to create a valid URL object
57
- const dummyBaseUrl = 'http://example.com/';
58
- const url = new URL(module.dependencyFilename, dummyBaseUrl)
59
- .pathname;
60
- const filename = url.split('/').pop()!;
61
- acc[filename] = Math.max(
62
- filename in acc ? acc[filename] : 0,
63
- module.dependenciesTotalSize
64
- );
65
- }
66
- return acc;
67
- }, {} as Record<string, number>);
68
- this.#progress = Object.fromEntries(
69
- Object.entries(this.#assetsSizes).map(([name]) => [name, 0])
70
- );
71
- }
72
-
73
- /**
74
- * Replaces the default WebAssembly.instantiateStreaming with a version
75
- * that monitors the download #progress.
76
- */
77
- #monitorWebAssemblyStreaming() {
78
- const instantiateStreaming = WebAssembly.instantiateStreaming;
79
- WebAssembly.instantiateStreaming = async (
80
- responseOrPromise,
81
- ...args
82
- ) => {
83
- const response = await responseOrPromise;
84
- const file = response.url.substring(
85
- new URL(response.url).origin.length + 1
86
- );
87
-
88
- const reportingResponse = cloneResponseMonitorProgress(
89
- response,
90
- ({ detail: { loaded, total } }) =>
91
- this.#notify(file, loaded, total)
92
- );
93
-
94
- return instantiateStreaming(reportingResponse, ...args);
95
- };
96
- }
97
-
98
- /**
99
- * Creates a `dataFileDownloads` Proxy object that can be passed
100
- * to `startPHP` to monitor the download #progress of the data
101
- * dependencies.
102
- */
103
- #createDataFileDownloadsProxy() {
104
- // eslint-disable-next-line @typescript-eslint/no-this-alias
105
- const self = this;
106
- const dataFileDownloads: Record<string, any> = {};
107
- // Monitor assignments like dataFileDownloads[file] = #progress
108
- return new Proxy(dataFileDownloads, {
109
- set(obj, file: string, progress) {
110
- self.#notify(file, progress.loaded, progress.total);
111
-
112
- // Monitor assignments like dataFileDownloads[file].total += delta
113
- obj[file] = new Proxy(JSON.parse(JSON.stringify(progress)), {
114
- set(nestedObj, prop, value) {
115
- nestedObj[prop] = value;
116
- self.#notify(file, nestedObj.loaded, nestedObj.total);
117
- return true;
118
- },
119
- });
120
- return true;
121
- },
122
- });
123
- }
124
-
125
- /**
126
- * Notifies about the download #progress of a file.
127
- *
128
- * @param file The file name.
129
- * @param loaded The number of bytes of that file loaded so far.
130
- * @param fileSize The total number of bytes in the loaded file.
131
- */
132
- #notify(file: string, loaded: number, fileSize: number) {
133
- const fileName = new URL(file, 'http://example.com').pathname
134
- .split('/')
135
- .pop()!;
136
- if (!fileSize) {
137
- fileSize = this.#assetsSizes[fileName];
138
- }
139
- if (!(fileName in this.#progress)) {
140
- console.warn(
141
- `Registered a download #progress of an unregistered file "${fileName}". ` +
142
- `This may cause a sudden **decrease** in the #progress percentage as the ` +
143
- `total number of bytes increases during the download.`
144
- );
145
- }
146
-
147
- this.#progress[file] = loaded;
148
- this.dispatchEvent(
149
- new CustomEvent('progress', {
150
- detail: {
151
- loaded: sumValues(this.#progress),
152
- total: sumValues(this.#assetsSizes),
153
- },
154
- })
155
- );
156
- }
157
- }
158
-
159
- function sumValues(obj: Record<string, number>) {
160
- return Object.values(obj).reduce((total, value) => total + value, 0);
161
- }
162
-
163
- export default EmscriptenDownloadMonitor;
164
-
165
- export interface DownloadProgress {
166
- /**
167
- * The number of bytes loaded so far.
168
- */
169
- loaded: number;
170
- /**
171
- * The total number of bytes to load.
172
- */
173
- total: number;
174
- }
175
-
176
- /**
177
- * Clones a fetch Response object and returns a version
178
- * that calls the `onProgress` callback as the #progress
179
- * changes.
180
- *
181
- * @param response The fetch Response object to clone.
182
- * @param onProgress The callback to call when the download #progress changes.
183
- * @returns The cloned response
184
- */
185
- export function cloneResponseMonitorProgress(
186
- response: Response,
187
- onProgress: (event: CustomEvent<DownloadProgress>) => void
188
- ): Response {
189
- const contentLength = response.headers.get('content-length') || '';
190
- const total = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;
191
-
192
- function notify(loaded: number, total: number) {
193
- onProgress(
194
- new CustomEvent('progress', {
195
- detail: {
196
- loaded,
197
- total,
198
- },
199
- })
200
- );
201
- }
202
-
203
- return new Response(
204
- new ReadableStream({
205
- async start(controller) {
206
- if (!response.body) {
207
- controller.close();
208
- return;
209
- }
210
- const reader = response.body.getReader();
211
- let loaded = 0;
212
- for (;;) {
213
- try {
214
- const { done, value } = await reader.read();
215
- if (value) {
216
- loaded += value.byteLength;
217
- }
218
- if (done) {
219
- notify(loaded, loaded);
220
- controller.close();
221
- break;
222
- } else {
223
- notify(loaded, total);
224
- controller.enqueue(value);
225
- }
226
- } catch (e) {
227
- console.error({ e });
228
- controller.error(e);
229
- break;
230
- }
231
- }
232
- },
233
- }),
234
- {
235
- status: response.status,
236
- statusText: response.statusText,
237
- headers: response.headers,
238
- }
239
- );
240
- }
241
-
242
- export type DownloadProgressCallback = (progress: DownloadProgress) => void;
@@ -1,65 +0,0 @@
1
- import { DownloadProgress } from './emscripten-download-monitor';
2
-
3
- export type ProgressMode =
4
- /**
5
- * Real-time progress is used when we get real-time reports
6
- * about the progress.
7
- */
8
- | 'REAL_TIME'
9
-
10
- /**
11
- * Slowly increment progress is used when we don't know how long
12
- * an operation will take and just want to keep slowly incrementing
13
- * the progress bar.
14
- */
15
- | 'SLOWLY_INCREMENT';
16
-
17
- export type ProgressObserverEvent = {
18
- progress: number;
19
- mode: ProgressMode;
20
- caption: string;
21
- };
22
-
23
- export class ProgressObserver extends EventTarget {
24
- #observedProgresses: Record<number, number> = {};
25
- #lastObserverId = 0;
26
-
27
- progress = 0;
28
- mode: ProgressMode = 'REAL_TIME';
29
- caption = '';
30
-
31
- partialObserver(progressBudget: number, caption = '') {
32
- const id = ++this.#lastObserverId;
33
- this.#observedProgresses[id] = 0;
34
- return (progress: CustomEvent<DownloadProgress>) => {
35
- const { loaded, total } = progress?.detail || {};
36
- this.#observedProgresses[id] = (loaded / total) * progressBudget;
37
- this.#onProgress(this.totalProgress, 'REAL_TIME', caption);
38
- };
39
- }
40
-
41
- slowlyIncrementBy(progress: number) {
42
- const id = ++this.#lastObserverId;
43
- this.#observedProgresses[id] = progress;
44
- this.#onProgress(this.totalProgress, 'SLOWLY_INCREMENT');
45
- }
46
-
47
- get totalProgress() {
48
- return Object.values(this.#observedProgresses).reduce(
49
- (total, progress) => total + progress,
50
- 0
51
- );
52
- }
53
-
54
- #onProgress(progress: number, mode: ProgressMode, caption?: string) {
55
- this.dispatchEvent(
56
- new CustomEvent('progress', {
57
- detail: {
58
- progress,
59
- mode,
60
- caption,
61
- },
62
- })
63
- );
64
- }
65
- }
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "forceConsistentCasingInFileNames": true,
5
- "strict": true,
6
- "noImplicitOverride": true,
7
- "noPropertyAccessFromIndexSignature": true,
8
- "noImplicitReturns": true,
9
- "noFallthroughCasesInSwitch": true,
10
- "types": ["vitest"]
11
- },
12
- "files": [],
13
- "include": [],
14
- "references": [
15
- {
16
- "path": "./tsconfig.lib.json"
17
- },
18
- {
19
- "path": "./tsconfig.spec.json"
20
- }
21
- ]
22
- }
package/tsconfig.lib.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../../dist/out-tsc",
5
- "declaration": true,
6
- "types": ["node"]
7
- },
8
- "include": ["src/**/*.ts"],
9
- "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
10
- }
@@ -1,19 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../dist/out-tsc",
5
- "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"]
6
- },
7
- "include": [
8
- "vite.config.ts",
9
- "src/**/*.test.ts",
10
- "src/**/*.spec.ts",
11
- "src/**/*.test.tsx",
12
- "src/**/*.spec.tsx",
13
- "src/**/*.test.js",
14
- "src/**/*.spec.js",
15
- "src/**/*.test.jsx",
16
- "src/**/*.spec.jsx",
17
- "src/**/*.d.ts"
18
- ]
19
- }
package/vite.config.ts DELETED
@@ -1,58 +0,0 @@
1
- /// <reference types="vitest" />
2
- import { defineConfig } from 'vite';
3
-
4
- import viteTsConfigPaths from 'vite-tsconfig-paths';
5
- import dts from 'vite-plugin-dts';
6
- import { join } from 'path';
7
-
8
- export default defineConfig({
9
- cacheDir: '../../../node_modules/.vite/php-wasm-progress',
10
-
11
- plugins: [
12
- dts({
13
- entryRoot: 'src',
14
- tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
15
- skipDiagnostics: true,
16
- }),
17
-
18
- viteTsConfigPaths({
19
- root: '../../../',
20
- }),
21
- ],
22
-
23
- // Uncomment this if you are using workers.
24
- // worker: {
25
- // plugins: [
26
- // viteTsConfigPaths({
27
- // root: '../../../',
28
- // }),
29
- // ],
30
- // },
31
-
32
- // Configuration for building your library.
33
- // See: https://vitejs.dev/guide/build.html#library-mode
34
- build: {
35
- lib: {
36
- // Could also be a dictionary or array of multiple entry points.
37
- entry: 'src/index.ts',
38
- name: 'php-wasm-progress',
39
- fileName: 'index',
40
- // Change this to the formats you want to support.
41
- // Don't forgot to update your package.json as well.
42
- formats: ['es', 'cjs'],
43
- },
44
- rollupOptions: {
45
- // External packages that should not be bundled into your library.
46
- external: [],
47
- },
48
- },
49
-
50
- test: {
51
- globals: true,
52
- cache: {
53
- dir: '../../../node_modules/.vitest',
54
- },
55
- environment: 'jsdom',
56
- include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
57
- },
58
- });
File without changes