Skip to content

Commit 78f6ea9

Browse files
authored
Merge branch 'next' into fix-optional
2 parents db8e7b8 + e949360 commit 78f6ea9

11 files changed

Lines changed: 82 additions & 89 deletions

File tree

crates/pack-api/src/app.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,23 @@ impl AppEndpoint {
252252

253253
#[turbo_tasks::function]
254254
pub async fn app_runtime_entries(self: Vc<Self>) -> Result<Vc<EvaluatableAssets>> {
255+
let watch = self.project().await?.watch.enable;
255256
Ok(get_client_runtime_entries(
256257
self.project().project_path().owned().await?,
257258
self.project().mode(),
258259
self.project().config(),
259260
self.project().execution_context(),
260261
self.project().pack_path().owned().await?,
262+
Vc::cell(watch),
261263
Vc::cell(
262-
self.project().await?.watch.enable
263-
&& *self.project().config().is_hmr_enabled().await?,
264+
watch
265+
&& self
266+
.project()
267+
.config()
268+
.dev_server()
269+
.await?
270+
.hot
271+
.unwrap_or_default(),
264272
),
265273
)
266274
.resolve_entries(Vc::upcast(self.app_module_context())))

crates/pack-api/src/library.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ impl LibraryEndpoint {
170170
self.project().pack_path().owned().await?,
171171
// Library project not support watch mode
172172
Vc::cell(false),
173+
Vc::cell(false),
173174
)
174175
.resolve_entries(Vc::upcast(self.library_module_context())))
175176
}

crates/pack-core/src/client/context.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ pub async fn get_client_runtime_entries(
196196
config: Vc<Config>,
197197
execution_context: Vc<ExecutionContext>,
198198
pack_path: FileSystemPath,
199-
hmr: Vc<bool>,
199+
watch: Vc<bool>,
200+
hot: Vc<bool>,
200201
) -> Result<Vc<RuntimeEntries>> {
201202
let mut runtime_entries = vec![];
202203
let resolve_options_context = get_client_resolve_options_context(
@@ -207,9 +208,11 @@ pub async fn get_client_runtime_entries(
207208
pack_path,
208209
);
209210

210-
let hmr = *hmr.await?;
211+
let is_development = mode.await?.is_development();
212+
let watch = *watch.await?;
213+
let hot = *hot.await?;
211214

212-
if hmr && mode.await?.is_development() {
215+
if is_development && watch {
213216
let enable_react_refresh =
214217
assert_can_resolve_react_refresh(project_root.clone(), resolve_options_context)
215218
.await?
@@ -224,7 +227,9 @@ pub async fn get_client_runtime_entries(
224227
.resolved_cell(),
225228
)
226229
};
230+
}
227231

232+
if is_development && watch && hot {
228233
runtime_entries.push(
229234
RuntimeEntry::Source(ResolvedVc::upcast(
230235
FileSource::new(embed_file_path(rcstr!("hmr/bootstrap.ts")).owned().await?)

crates/pack-core/src/config.rs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,8 @@ pub struct LibraryOptions {
9898
#[turbo_tasks::value(transparent)]
9999
pub struct Entries(Vec<EntryOptions>);
100100

101-
#[derive(
102-
Clone,
103-
Debug,
104-
Eq,
105-
Default,
106-
PartialEq,
107-
Serialize,
108-
Deserialize,
109-
TraceRawVcs,
110-
ValueDebugFormat,
111-
NonLocalValue,
112-
OperationValue,
113-
)]
101+
#[turbo_tasks::value(eq = "manual")]
102+
#[derive(Clone, Debug, PartialEq, Default, OperationValue)]
114103
#[serde(rename_all = "camelCase")]
115104
pub struct DevServer {
116105
pub hot: Option<bool>,
@@ -1025,13 +1014,8 @@ impl Config {
10251014
}
10261015

10271016
#[turbo_tasks::function]
1028-
pub fn is_hmr_enabled(&self) -> Vc<bool> {
1029-
Vc::cell(
1030-
self.dev_server
1031-
.as_ref()
1032-
.and_then(|ds| ds.hot)
1033-
.unwrap_or_default(),
1034-
)
1017+
pub fn dev_server(&self) -> Vc<DevServer> {
1018+
self.dev_server.clone().unwrap_or_default().cell()
10351019
}
10361020

10371021
#[turbo_tasks::function]

crates/utoo-wasm/src/project.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,14 @@ impl Project {
5858
/// Calculate MD5 hash of byte content (async for better thread scheduling)
5959
#[wasm_bindgen(js_name = sigMd5)]
6060
pub async fn sig_md5(content: Vec<u8>) -> Result<String, JsError> {
61-
let result = tokio::task::spawn_blocking(move || opfs_project::pack::sig_md5(&content))
61+
let rt = TOKIO_RUNTIME
62+
.get()
63+
.ok_or_else(|| JsError::new("tokio runtime not initialized"))?;
64+
65+
let result = rt
66+
.spawn_blocking(move || opfs_project::pack::sig_md5(&content))
6267
.await
63-
.map_err(|e| JsError::new(&format!("Task failed: {}", e)))?;
68+
.map_err(to_js_error)?;
6469
Ok(result)
6570
}
6671

@@ -85,9 +90,13 @@ impl Project {
8590
.map(|f| PackFile::new(f.path, f.content))
8691
.collect();
8792

88-
let bytes = tokio::task::spawn_blocking(move || opfs_project::pack::gzip(&pack_files))
89-
.await
90-
.map_err(|e| JsError::new(&format!("Task failed: {}", e)))?
93+
let rt = TOKIO_RUNTIME
94+
.get()
95+
.ok_or_else(|| JsError::new("tokio runtime not initialized"))?;
96+
97+
let bytes = rt
98+
.spawn_blocking(move || opfs_project::pack::gzip(&pack_files))
99+
.await?
91100
.map_err(to_js_error)?;
92101
Ok(js_sys::Uint8Array::from(&bytes[..]))
93102
}
@@ -143,12 +152,11 @@ impl Project {
143152
None => return Err(JsError::new("invalid pack project")),
144153
};
145154

146-
TOKIO_RUNTIME
147-
.with(|rt| {
148-
rt.get()
149-
.expect("tokio runtime not found")
150-
.spawn(async move { pack_project.build().await })
151-
})
155+
let rt = TOKIO_RUNTIME
156+
.get()
157+
.ok_or_else(|| JsError::new("tokio runtime not initialized"))?;
158+
159+
rt.spawn(async move { pack_project.build().await })
152160
.await
153161
.map_err(to_js_error)?
154162
.map_or_else(
@@ -206,12 +214,11 @@ impl Project {
206214
..Default::default()
207215
};
208216

209-
let pack_context = TOKIO_RUNTIME
210-
.with(|rt| {
211-
rt.get()
212-
.expect("tokio runtime not found")
213-
.spawn(PackProject::initialize(options))
214-
})
217+
let rt = TOKIO_RUNTIME
218+
.get()
219+
.ok_or_else(|| anyhow::anyhow!("tokio runtime not initialized"))?;
220+
let pack_context = rt
221+
.spawn(PackProject::initialize(options))
215222
.await
216223
.context("fail to initialize pack project")??;
217224

crates/utoo-wasm/src/tokio_runtime.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,26 @@ use std::{
22
cell::OnceCell,
33
sync::{
44
atomic::{AtomicUsize, Ordering},
5-
LazyLock,
5+
OnceLock,
66
},
77
time::Duration,
88
};
99

1010
use tokio::runtime;
1111

12-
thread_local! {
13-
pub static TOKIO_RUNTIME: OnceCell<runtime::Runtime> = const { OnceCell::new() };
14-
}
12+
pub static TOKIO_RUNTIME: OnceLock<runtime::Runtime> = OnceLock::new();
1513

1614
pub fn init_tokio_runtime(worker_url: String) {
17-
TOKIO_RUNTIME.with(|ctx| {
18-
ctx.get_or_init(|| {
19-
runtime::Builder::new_multi_thread()
20-
/* *
21-
* The default dlmalloc is a single global allocator,
22-
* it will block threads scheduling,
23-
* see https://web.dev/articles/scaling-multithreaded-webassembly-applications#heap_management_mallocfree
24-
*/
25-
.disable_lifo_slot()
26-
.thread_name_fn(|| {
27-
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(1);
28-
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
29-
format!("tokio-runtime-worker-{id}")
30-
})
31-
.wasm_bindgen_shim_url(worker_url.clone())
32-
.build()
33-
.unwrap()
34-
});
35-
})
15+
TOKIO_RUNTIME.get_or_init(|| {
16+
runtime::Builder::new_multi_thread()
17+
.disable_lifo_slot()
18+
.thread_name_fn(|| {
19+
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(1);
20+
let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
21+
format!("tokio-runtime-worker-{id}")
22+
})
23+
.wasm_bindgen_shim_url(worker_url.clone())
24+
.build()
25+
.expect("Failed to build tokio runtime")
26+
});
3627
}

packages/pack-shared/src/config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,12 @@ export interface ConfigComplete {
178178
stats?: boolean;
179179
persistentCaching?: boolean;
180180
nodePolyfill?: boolean;
181-
devServer?: { hot?: boolean; port?: number; host?: string; https?: boolean };
181+
devServer?: {
182+
hot?: boolean;
183+
port?: number;
184+
host?: string;
185+
https?: boolean;
186+
};
182187
cacheHandler?: string;
183188
experimental?: ExperimentalConfig;
184189
}

packages/pack/src/commands/dev.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ async function serveInternal(
7676
...options,
7777
config: {
7878
...options.config,
79-
devServer: { ...(options.config.devServer || {}), hot: true },
79+
devServer: {
80+
...(options.config.devServer || {}),
81+
hot: true,
82+
},
8083
},
8184
packPath: getPackPath(),
8285
},

packages/utoo-web/src/project/InternalProject.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ class InternalEndpoint implements ProjectEndpoint {
7777
if (encoding === "utf8") {
7878
ret = await ProjectInternal.readToString(path);
7979
} else {
80-
ret = await ProjectInternal.read(path);
81-
const copied = ret.slice(0);
82-
return comlink.transfer(copied, [copied.buffer]);
80+
return await ProjectInternal.read(path);
8381
}
8482
return ret as any;
8583
}
@@ -162,9 +160,7 @@ class InternalEndpoint implements ProjectEndpoint {
162160

163161
async gzip(files: PackFile[]) {
164162
await this.wasmInit!;
165-
const ret = await ProjectInternal.gzip(files);
166-
const copied = ret.slice(0);
167-
return comlink.transfer(copied, [copied.buffer]);
163+
return await ProjectInternal.gzip(files);
168164
}
169165

170166
async sigMd5(content: Uint8Array) {

packages/utoo-web/src/project/Project.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,7 @@ export class Project implements ProjectEndpoint {
126126
) {
127127
await this.#mount;
128128
if (content instanceof Uint8Array) {
129-
return await this.remote.writeFile(
130-
path,
131-
comlink.transfer(content, [content.buffer]),
132-
encoding,
133-
);
129+
return await this.remote.writeFile(path, content, encoding);
134130
}
135131
return await this.remote.writeFile(path, content, encoding);
136132
}
@@ -175,15 +171,12 @@ export class Project implements ProjectEndpoint {
175171

176172
public async gzip(files: PackFile[]): Promise<Uint8Array> {
177173
await this.#mount;
178-
const buffers = files.map((f) => f.content.buffer);
179-
return await this.remote.gzip(comlink.transfer(files, buffers));
174+
return await this.remote.gzip(files);
180175
}
181176

182177
public async sigMd5(content: Uint8Array): Promise<string> {
183178
await this.#mount;
184-
return await this.remote.sigMd5(
185-
comlink.transfer(content, [content.buffer]),
186-
);
179+
return await this.remote.sigMd5(content);
187180
}
188181

189182
public static fork(

0 commit comments

Comments
 (0)