@utoo/web 1.2.0-rc.5 → 1.2.0-rc.7
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/README.md +52 -0
- package/esm/{8df7dc7828270e8a8ece.wasm → b0afc1b3f31b4fb74f6b.wasm} +0 -0
- package/esm/forkedProject.d.ts +2 -1
- package/esm/forkedProject.js +5 -0
- package/esm/internalProject.d.ts +3 -3
- package/esm/internalProject.js +36 -20
- package/esm/loaderWorker.js +1 -1
- package/esm/project.d.ts +2 -1
- package/esm/project.js +12 -3
- package/esm/sabcom.d.ts +17 -0
- package/esm/sabcom.js +93 -26
- package/esm/serviceWorker.js +1 -0
- package/esm/type.d.ts +38 -0
- package/esm/type.js +44 -0
- package/esm/utoo/index.d.ts +27 -24
- package/esm/utoo/index.js +104 -102
- package/esm/utoo/index_bg.wasm +0 -0
- package/esm/webpackLoaders/{worker/cjs.js → cjs.js} +71 -64
- package/esm/webpackLoaders/loaderWorkerPool.d.ts +2 -0
- package/esm/{loaderWorkerPool.js → webpackLoaders/loaderWorkerPool.js} +30 -18
- package/esm/webpackLoaders/polyfills/fsPolyfill.d.ts +78 -0
- package/esm/webpackLoaders/polyfills/fsPolyfill.js +279 -0
- package/esm/webpackLoaders/polyfills/fsPromisesPolyfill.d.ts +26 -0
- package/esm/webpackLoaders/polyfills/fsPromisesPolyfill.js +112 -0
- package/esm/webpackLoaders/{worker/type.d.ts → type.d.ts} +1 -0
- package/esm/webpackLoaders/{worker/index.js → worker.js} +8 -3
- package/package.json +6 -6
- package/esm/loaderWorkerPool.d.ts +0 -3
- package/esm/webpackLoaders/worker/polyfills/fsPolyfill.d.ts +0 -244
- package/esm/webpackLoaders/worker/polyfills/fsPolyfill.js +0 -369
- package/esm/webpackLoaders/worker/polyfills/fsPromisesPolyfill.d.ts +0 -9
- package/esm/webpackLoaders/worker/polyfills/fsPromisesPolyfill.js +0 -9
- /package/esm/webpackLoaders/{worker/cjs.d.ts → cjs.d.ts} +0 -0
- /package/esm/webpackLoaders/{worker/polyfills → polyfills}/nodePolyFills.d.ts +0 -0
- /package/esm/webpackLoaders/{worker/polyfills → polyfills}/nodePolyFills.js +0 -0
- /package/esm/webpackLoaders/{worker/polyfills → polyfills}/workerThreadsPolyfill.d.ts +0 -0
- /package/esm/webpackLoaders/{worker/polyfills → polyfills}/workerThreadsPolyfill.js +0 -0
- /package/esm/webpackLoaders/{worker/type.js → type.js} +0 -0
- /package/esm/webpackLoaders/{worker/index.d.ts → worker.d.ts} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @utoo/web
|
|
2
|
+
|
|
3
|
+
> 🌖 Web-compatible version of the Utoo toolchain, powered by [Turbopack](https://turbo.build/pack) and WebAssembly.
|
|
4
|
+
|
|
5
|
+
`@utoo/web` brings the power of the Utoo bundler to the browser, leveraging WebAssembly to provide high-performance bundling in non-native environments. It enables a complete web development environment, including a virtual file system and dependency management, entirely within the browser.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🌐 **Browser-based Bundling**: Run the Utoo bundler directly in the browser.
|
|
10
|
+
- ⚡ **WASM Powered**: High performance via WebAssembly bindings of the Turbopack-based core.
|
|
11
|
+
- 🛠️ **Web Worker Support**: Offloads heavy bundling tasks to background workers to keep the UI responsive.
|
|
12
|
+
- 🔌 **Webpack Compatibility**: Supports a subset of Webpack configurations in the browser.
|
|
13
|
+
- 📂 **Virtual File System**: Uses Origin Private File System (OPFS) for a Node.js-like file system experience.
|
|
14
|
+
|
|
15
|
+
## 🧠 Core Concepts
|
|
16
|
+
|
|
17
|
+
1. **Virtual File System**: The project lives in the browser's OPFS.
|
|
18
|
+
2. **Project Main Worker**: Core logic runs in a dedicated worker to keep the UI responsive.
|
|
19
|
+
3. **Thread Worker**: Heavy bundling tasks are offloaded to a worker powered by a ported `tokio` runtime.
|
|
20
|
+
4. **Service Worker**: Acts as a local server to intercept requests and serve built files for preview.
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @utoo/web
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 🛠️ Development
|
|
29
|
+
|
|
30
|
+
### Prerequisites
|
|
31
|
+
|
|
32
|
+
- Rust toolchain (nightly)
|
|
33
|
+
- `wasm-bindgen-cli`
|
|
34
|
+
- `binaryen` (for `wasm-opt`)
|
|
35
|
+
|
|
36
|
+
### Build
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Install toolchain
|
|
40
|
+
npm run install-toolchain
|
|
41
|
+
|
|
42
|
+
# Build WASM and TypeScript
|
|
43
|
+
npm run build
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 📚 Documentation
|
|
47
|
+
|
|
48
|
+
For detailed API usage and examples, please refer to the [API Documentation](./API.md) ([中文版](./API_zh-CN.md)).
|
|
49
|
+
|
|
50
|
+
## �📄 License
|
|
51
|
+
|
|
52
|
+
[MIT](./LICENSE)
|
|
Binary file
|
package/esm/forkedProject.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PackFile, ProjectEndpoint } from "./type";
|
|
1
|
+
import { PackFile, ProjectEndpoint, Stats } from "./type";
|
|
2
2
|
export declare class ForkedProject implements ProjectEndpoint {
|
|
3
3
|
private endpoint;
|
|
4
4
|
constructor(port: MessagePort);
|
|
@@ -19,6 +19,7 @@ export declare class ForkedProject implements ProjectEndpoint {
|
|
|
19
19
|
rmdir(path: string, options?: {
|
|
20
20
|
recursive?: boolean;
|
|
21
21
|
}): Promise<void>;
|
|
22
|
+
stat(path: string): Promise<Stats>;
|
|
22
23
|
gzip(files: PackFile[]): Promise<Uint8Array>;
|
|
23
24
|
sigMd5(content: Uint8Array): Promise<string>;
|
|
24
25
|
}
|
package/esm/forkedProject.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as comlink from "comlink";
|
|
2
|
+
import { Stats } from "./type";
|
|
2
3
|
export class ForkedProject {
|
|
3
4
|
constructor(port) {
|
|
4
5
|
var _a;
|
|
@@ -31,6 +32,10 @@ export class ForkedProject {
|
|
|
31
32
|
async rmdir(path, options) {
|
|
32
33
|
return await this.endpoint.rmdir(path, options);
|
|
33
34
|
}
|
|
35
|
+
async stat(path) {
|
|
36
|
+
const raw = (await this.endpoint.stat(path));
|
|
37
|
+
return new Stats(raw);
|
|
38
|
+
}
|
|
34
39
|
async gzip(files) {
|
|
35
40
|
return await this.endpoint.gzip(files);
|
|
36
41
|
}
|
package/esm/internalProject.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { PackFile, ProjectEndpoint, ProjectOptions } from "./type";
|
|
2
|
-
import initWasm
|
|
1
|
+
import { PackFile, ProjectEndpoint, ProjectOptions, Stats } from "./type";
|
|
2
|
+
import initWasm from "./utoo";
|
|
3
3
|
declare class InternalEndpoint implements ProjectEndpoint {
|
|
4
|
-
projectInternal?: ProjectInternal;
|
|
5
4
|
wasmInit?: ReturnType<typeof initWasm>;
|
|
6
5
|
options?: Omit<ProjectOptions, "workerUrl" | "serviceWorker">;
|
|
7
6
|
loaderWorkerPoolInitialized: boolean;
|
|
@@ -11,6 +10,7 @@ declare class InternalEndpoint implements ProjectEndpoint {
|
|
|
11
10
|
readFile(path: string, encoding?: "utf8"): Promise<any>;
|
|
12
11
|
writeFile(path: string, content: string | Uint8Array, _encoding?: "utf8"): Promise<void>;
|
|
13
12
|
copyFile(src: string, dst: string): Promise<void>;
|
|
13
|
+
stat(path: string): Promise<Stats>;
|
|
14
14
|
readdir(path: string, options?: {
|
|
15
15
|
recursive?: boolean;
|
|
16
16
|
}): Promise<any>;
|
package/esm/internalProject.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as comlink from "comlink";
|
|
2
2
|
import initWasm, { init_log_filter, Project as ProjectInternal, } from "./utoo";
|
|
3
|
+
import { runLoaderWorkerPool } from "./webpackLoaders/loaderWorkerPool";
|
|
3
4
|
class InternalEndpoint {
|
|
4
5
|
constructor() {
|
|
5
6
|
this.loaderWorkerPoolInitialized = false;
|
|
@@ -14,53 +15,67 @@ class InternalEndpoint {
|
|
|
14
15
|
// Initialize log filter after wasm init
|
|
15
16
|
const filter = logFilter || "pack_core=info,pack_api=info,utoo_wasm=info";
|
|
16
17
|
init_log_filter(filter);
|
|
17
|
-
|
|
18
|
+
const absoluteCwd = cwd.startsWith("/") ? cwd : "/" + cwd;
|
|
19
|
+
ProjectInternal.init(threadWorkerUrl || "");
|
|
20
|
+
ProjectInternal.setCwd(absoluteCwd);
|
|
18
21
|
return;
|
|
19
22
|
}
|
|
20
23
|
async install(packageLock, maxConcurrentDownloads) {
|
|
21
24
|
await this.wasmInit;
|
|
22
|
-
await
|
|
25
|
+
await ProjectInternal.install(packageLock, maxConcurrentDownloads);
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
28
|
async build() {
|
|
26
29
|
var _a, _b;
|
|
27
30
|
const binding = await this.wasmInit;
|
|
28
31
|
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.loaderWorkerUrl) && !this.loaderWorkerPoolInitialized) {
|
|
29
|
-
runLoaderWorkerPool(binding, this.options.cwd, this.
|
|
32
|
+
runLoaderWorkerPool(binding, this.options.cwd, this.options.loaderWorkerUrl, (_b = this.options) === null || _b === void 0 ? void 0 : _b.loadersImportMap);
|
|
30
33
|
this.loaderWorkerPoolInitialized = true;
|
|
31
34
|
}
|
|
32
|
-
return await
|
|
35
|
+
return await ProjectInternal.build();
|
|
33
36
|
}
|
|
34
37
|
async readFile(path, encoding) {
|
|
35
38
|
await this.wasmInit;
|
|
36
39
|
let ret;
|
|
37
40
|
if (encoding === "utf8") {
|
|
38
|
-
ret = await
|
|
41
|
+
ret = await ProjectInternal.readToString(path);
|
|
39
42
|
}
|
|
40
43
|
else {
|
|
41
|
-
ret = await
|
|
44
|
+
ret = await ProjectInternal.read(path);
|
|
45
|
+
return comlink.transfer(ret, [ret.buffer]);
|
|
42
46
|
}
|
|
43
47
|
return ret;
|
|
44
48
|
}
|
|
45
49
|
async writeFile(path, content, _encoding) {
|
|
46
50
|
await this.wasmInit;
|
|
47
51
|
if (typeof content === "string") {
|
|
48
|
-
return await
|
|
52
|
+
return await ProjectInternal.writeString(path, content);
|
|
49
53
|
}
|
|
50
54
|
else {
|
|
51
|
-
return await
|
|
55
|
+
return await ProjectInternal.write(path, content);
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
async copyFile(src, dst) {
|
|
55
59
|
await this.wasmInit;
|
|
56
|
-
return await
|
|
60
|
+
return await ProjectInternal.copyFile(src, dst);
|
|
61
|
+
}
|
|
62
|
+
async stat(path) {
|
|
63
|
+
await this.wasmInit;
|
|
64
|
+
const metadata = await ProjectInternal.metadata(path);
|
|
65
|
+
const json = metadata.toJSON();
|
|
66
|
+
const raw = {
|
|
67
|
+
type: json.type,
|
|
68
|
+
size: Number(json.file_size),
|
|
69
|
+
};
|
|
70
|
+
// WARN: This is a hack, functions can not be structurally cloned
|
|
71
|
+
return raw;
|
|
57
72
|
}
|
|
58
73
|
async readdir(path, options) {
|
|
59
74
|
await this.wasmInit;
|
|
60
75
|
const dirEntries = (options === null || options === void 0 ? void 0 : options.recursive)
|
|
61
|
-
? await
|
|
76
|
+
? await ProjectInternal.readDir(path)
|
|
62
77
|
: // TODO: support recursive readDirAll
|
|
63
|
-
await
|
|
78
|
+
await ProjectInternal.readDir(path);
|
|
64
79
|
const rawDirents = dirEntries.map((e) => {
|
|
65
80
|
const dir = e.toJSON();
|
|
66
81
|
return {
|
|
@@ -74,20 +89,20 @@ class InternalEndpoint {
|
|
|
74
89
|
async mkdir(path, options) {
|
|
75
90
|
await this.wasmInit;
|
|
76
91
|
if (options === null || options === void 0 ? void 0 : options.recursive) {
|
|
77
|
-
return await
|
|
92
|
+
return await ProjectInternal.createDirAll(path);
|
|
78
93
|
}
|
|
79
94
|
else {
|
|
80
|
-
return await
|
|
95
|
+
return await ProjectInternal.createDir(path);
|
|
81
96
|
}
|
|
82
97
|
}
|
|
83
98
|
async rm(path, options) {
|
|
84
99
|
await this.wasmInit;
|
|
85
|
-
let metadata = (await
|
|
100
|
+
let metadata = (await ProjectInternal.metadata(path)).toJSON();
|
|
86
101
|
switch (metadata.type) {
|
|
87
102
|
case "file":
|
|
88
|
-
return await
|
|
103
|
+
return await ProjectInternal.removeFile(path);
|
|
89
104
|
case "directory":
|
|
90
|
-
return await
|
|
105
|
+
return await ProjectInternal.removeDir(path, !!(options === null || options === void 0 ? void 0 : options.recursive));
|
|
91
106
|
default:
|
|
92
107
|
// nothing to remove now
|
|
93
108
|
break;
|
|
@@ -95,15 +110,16 @@ class InternalEndpoint {
|
|
|
95
110
|
}
|
|
96
111
|
async rmdir(path, options) {
|
|
97
112
|
await this.wasmInit;
|
|
98
|
-
return await
|
|
113
|
+
return await ProjectInternal.removeDir(path, !!(options === null || options === void 0 ? void 0 : options.recursive));
|
|
99
114
|
}
|
|
100
115
|
async gzip(files) {
|
|
101
116
|
await this.wasmInit;
|
|
102
|
-
|
|
117
|
+
const ret = await ProjectInternal.gzip(files);
|
|
118
|
+
return comlink.transfer(ret, [ret.buffer]);
|
|
103
119
|
}
|
|
104
120
|
async sigMd5(content) {
|
|
105
121
|
await this.wasmInit;
|
|
106
|
-
return await
|
|
122
|
+
return await ProjectInternal.sigMd5(content);
|
|
107
123
|
}
|
|
108
124
|
}
|
|
109
125
|
const internalEndpoint = new InternalEndpoint();
|