Skip to content

Commit 9f2e369

Browse files
committed
Bump napi-rs and use new deferred API
1 parent 5a12639 commit 9f2e369

File tree

3 files changed

+13
-84
lines changed

3 files changed

+13
-84
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ parcel_sourcemap = { version = "2.1.1", features = ["json"] }
1919
jemallocator = { version = "0.3.2", features = ["disable_initial_exec_tls"] }
2020

2121
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
22-
napi = {version = "2.2.0", default-features = false, features = ["napi4", "napi5", "compat-mode", "serde-json"]}
22+
napi = {version = "2.10.0", default-features = false, features = ["napi4", "napi5", "compat-mode", "serde-json"]}
2323
napi-derive = "2"
2424
crossbeam-channel = "0.5.6"
2525
rayon = "1.5.1"

node/src/lib.rs

Lines changed: 10 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use lightningcss::targets::Browsers;
1313
use parcel_sourcemap::SourceMap;
1414
use serde::{Deserialize, Serialize};
1515
use std::collections::HashSet;
16-
use std::ffi::c_void;
1716
use std::path::{Path, PathBuf};
1817
use std::str::FromStr;
1918
use std::sync::{Arc, Mutex, RwLock};
@@ -125,7 +124,7 @@ fn transform_style_attribute(ctx: CallContext) -> napi::Result<JsUnknown> {
125124
mod bundle {
126125
use super::*;
127126
use crossbeam_channel::{self, Receiver, Sender};
128-
use napi::{Env, JsFunction, JsString, NapiRaw, NapiValue};
127+
use napi::{Env, JsFunction, JsString, NapiRaw};
129128
use threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunction, ThreadsafeFunctionCallMode};
130129

131130
#[js_function(1)]
@@ -306,7 +305,7 @@ mod bundle {
306305

307306
#[cfg(not(target_arch = "wasm32"))]
308307
#[js_function(1)]
309-
pub fn bundle_async(ctx: CallContext) -> napi::Result<JsUnknown> {
308+
pub fn bundle_async(ctx: CallContext) -> napi::Result<JsObject> {
310309
let opts = ctx.get::<JsObject>(0)?;
311310
let config: BundleConfig = ctx.env.from_js_value(&opts)?;
312311

@@ -348,9 +347,6 @@ mod bundle {
348347
}
349348
}
350349

351-
struct TSFNValue(napi::sys::napi_threadsafe_function);
352-
unsafe impl Send for TSFNValue {}
353-
354350
// Runs bundling on a background thread managed by rayon. This is similar to AsyncTask from napi-rs, however,
355351
// because we call back into the JS thread, which might call other tasks in the node threadpool (e.g. fs.readFile),
356352
// we may end up deadlocking if the number of rayon threads exceeds node's threadpool size. Therefore, we must
@@ -359,85 +355,18 @@ mod bundle {
359355
provider: P,
360356
config: BundleConfig,
361357
env: Env,
362-
) -> napi::Result<JsUnknown> {
363-
// Create a promise.
364-
let mut raw_promise = std::ptr::null_mut();
365-
let mut deferred = std::ptr::null_mut();
366-
let status = unsafe { napi::sys::napi_create_promise(env.raw(), &mut deferred, &mut raw_promise) };
367-
assert_eq!(napi::Status::from(status), napi::Status::Ok);
368-
369-
// Create a threadsafe function so we can call back into the JS thread when we are done.
370-
let async_resource_name = env.create_string("run_bundle_task").unwrap();
371-
let mut tsfn = std::ptr::null_mut();
372-
napi::check_status! {unsafe {
373-
napi::sys::napi_create_threadsafe_function(
374-
env.raw(),
375-
std::ptr::null_mut(),
376-
std::ptr::null_mut(),
377-
async_resource_name.raw(),
378-
0,
379-
1,
380-
std::ptr::null_mut(),
381-
None,
382-
deferred as *mut c_void,
383-
Some(bundle_task_cb),
384-
&mut tsfn,
385-
)
386-
}}?;
387-
388-
// Wrap raw pointer so it is Send compatible.
389-
let tsfn_value = TSFNValue(tsfn);
358+
) -> napi::Result<JsObject> {
359+
let (deferred, promise) = env.create_deferred()?;
390360

391361
// Run bundling task in rayon threadpool.
392362
rayon::spawn(move || {
393-
let provider = provider;
394-
let result = compile_bundle(unsafe { std::mem::transmute::<&'_ P, &'static P>(&provider) }, &config)
395-
.map_err(|e| e.into());
396-
resolve_task(result, tsfn_value);
363+
match compile_bundle(unsafe { std::mem::transmute::<&'_ P, &'static P>(&provider) }, &config) {
364+
Ok(v) => deferred.resolve(|env| v.into_js(env)),
365+
Err(err) => deferred.reject(err.into()),
366+
}
397367
});
398368

399-
Ok(unsafe { JsUnknown::from_raw_unchecked(env.raw(), raw_promise) })
400-
}
401-
402-
fn resolve_task(result: napi::Result<TransformResult<'static>>, tsfn_value: TSFNValue) {
403-
// Call back into the JS thread via a threadsafe function. This results in bundle_task_cb being called.
404-
let status = unsafe {
405-
napi::sys::napi_call_threadsafe_function(
406-
tsfn_value.0,
407-
Box::into_raw(Box::from(result)) as *mut c_void,
408-
napi::sys::ThreadsafeFunctionCallMode::nonblocking,
409-
)
410-
};
411-
assert_eq!(napi::Status::from(status), napi::Status::Ok);
412-
413-
let status = unsafe {
414-
napi::sys::napi_release_threadsafe_function(tsfn_value.0, napi::sys::ThreadsafeFunctionReleaseMode::release)
415-
};
416-
assert_eq!(napi::Status::from(status), napi::Status::Ok);
417-
}
418-
419-
extern "C" fn bundle_task_cb(
420-
env: napi::sys::napi_env,
421-
_js_callback: napi::sys::napi_value,
422-
context: *mut c_void,
423-
data: *mut c_void,
424-
) {
425-
let deferred = context as napi::sys::napi_deferred;
426-
let value = unsafe { Box::from_raw(data as *mut napi::Result<TransformResult<'static>>) };
427-
let value = value.and_then(|res| res.into_js(unsafe { Env::from_raw(env) }));
428-
429-
// Resolve or reject the promise based on the result.
430-
match value {
431-
Ok(res) => {
432-
let status = unsafe { napi::sys::napi_resolve_deferred(env, deferred, res.raw()) };
433-
assert_eq!(napi::Status::from(status), napi::Status::Ok);
434-
}
435-
Err(e) => {
436-
let status =
437-
unsafe { napi::sys::napi_reject_deferred(env, deferred, napi::JsError::from(e).into_value(env)) };
438-
assert_eq!(napi::Status::from(status), napi::Status::Ok);
439-
}
440-
}
369+
Ok(promise)
441370
}
442371
}
443372

@@ -588,7 +517,7 @@ fn compile<'i>(code: &'i str, config: &Config) -> Result<TransformResult<'i>, Co
588517
source_index: 0,
589518
error_recovery: config.error_recovery.unwrap_or_default(),
590519
warnings: warnings.clone(),
591-
at_rule_parser: ParserOptions::default_at_rule_parser()
520+
at_rule_parser: ParserOptions::default_at_rule_parser(),
592521
},
593522
)?;
594523
stylesheet.minify(MinifyOptions {

0 commit comments

Comments
 (0)