Skip to main content

napi_async_runtime/
js_callback.rs

1//! Generic JavaScript-callback alias used by the host protocol exports.
2
3use std::{ptr, sync::Arc};
4
5use napi::{
6  Either, Status, ValueType,
7  bindgen_prelude::{FromNapiValue, TypeName, ValidateNapiValue},
8  sys,
9  threadsafe_function::ThreadsafeFunction,
10};
11
12/// Used as the fallback branch in `Either<Ret, InvalidReturnValue>` to catch
13/// type mismatches from JS function options. Always passes NAPI validation so
14/// that when `Ret` validation fails, the error is handled in Rust with a clear
15/// message instead of becoming an uncatchable `napi_fatal_exception`.
16pub struct InvalidReturnValue {
17  pub value_type: ValueType,
18}
19
20impl TypeName for InvalidReturnValue {
21  fn type_name() -> &'static str {
22    "InvalidReturnValue"
23  }
24
25  fn value_type() -> ValueType {
26    ValueType::Unknown
27  }
28}
29
30impl ValidateNapiValue for InvalidReturnValue {
31  unsafe fn validate(
32    _env: sys::napi_env,
33    _napi_val: sys::napi_value,
34  ) -> napi::Result<sys::napi_value> {
35    Ok(ptr::null_mut())
36  }
37}
38
39impl FromNapiValue for InvalidReturnValue {
40  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> napi::Result<Self> {
41    let value_type = napi::type_of!(env, napi_val)?;
42    Ok(InvalidReturnValue { value_type })
43  }
44}
45
46/// `JsCallback` is a type alias for a weak, caller-handled
47/// [`ThreadsafeFunction`] whose return value is validated in Rust: it
48/// represents a JavaScript function passed to the Rust side.
49///
50/// - Rust: `JsCallback<FnArgs<(u32, f64)>, Promise<()>>`
51/// - JS: `(id: number, ms: number) => Promise<void>`
52///
53/// The `Weak = true` parameter means the callback does not keep its owning
54/// event loop alive, which is exactly what the host protocol needs: a worker
55/// that registered a timer or task host may exit at any time, and the runtime
56/// detects that through the threadsafe function's `aborted` flag instead of
57/// pinning the worker.
58pub type JsCallback<Args = (), Ret = ()> =
59  Arc<ThreadsafeFunction<Args, Either<Ret, InvalidReturnValue>, Args, Status, false, true>>;