Changelog
/
napi

napi

napi@2.4.3

5/12/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.4.2...napi@2.4.3

napi@2.4.2

5/10/2022

What's Changed

Experimental

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.4.1...napi@2.4.2

napi-sys@2.2.2

5/10/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-sys@2.2.1...napi-sys@2.2.2

napi@2.4.1

5/7/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-sys@2.2.0...napi@2.4.1

napi@2.4.0

5/7/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.3.3...napi@2.4.0

napi-sys@2.2.1

5/7/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-sys@2.2.0...napi-sys@2.2.1

napi-sys@2.2.0

5/7/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.3.3...napi-sys@2.2.0

napi-build@2.0.0

5/7/2022

What's Changed

BREAKING

You must use napi 2.4+ with the napi-build@2

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.3.3...napi-build@2.0.0

napi@2.3.3

4/27/2022

What's Changed

Experimental

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.3.2...napi@2.3.3

napi-derive@2.3.3

4/27/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.3.2...napi-derive@2.3.3

napi-derive@2.3.2

4/27/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.3.1...napi-derive@2.3.2

napi@2.3.2

4/25/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.3.1...napi@2.3.2

napi-derive@2.3.1

4/25/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.3.1...napi-derive@2.3.1

napi@2.3.1

4/15/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.3.0...napi@2.3.1

napi@2.3.0

4/15/2022

What's Changed

  • docs: add return Promise callback function @Brooooooklyn
  • feat(napi): relax the value type on ThreadSafeFunction @Brooooooklyn
  • feat(napi-derive): support generic types on fn @Brooooooklyn
  • fix(napi-derive): JsUnknown should be unknown type @Brooooooklyn
  • feat(napi): add from_unknown method on FromNapiValue @Brooooooklyn
  • fix(napi): typo unrwap -> unwrap @waltonseymour
  • chore(napi): show tips if create different buffers with same data @Brooooooklyn
  • test(napi): add memory tests for Reference@Brooooooklyn
  • fix(napi): make buffer Send & Sync safe @Brooooooklyn
  • feat(napi): redesign the Reference API (#1118) @Brooooooklyn
  • Revert "chore: unset CARGO_BUILD_TARGET in debian.Dockerfile" @Brooooooklyn
  • chore: unset CARGO_BUILD_TARGET in debian.Dockerfile @Brooooooklyn
  • build: migrate debian image to messense/manylinux2014-cross @Brooooooklyn
  • feat(napi): experimental class reference API @Brooooooklyn
  • fix(napi): remove CString::from_vec_with_nul_unchecked @Brooooooklyn
  • feat(napi): allow empty enums @antoniomuso
  • ci: add binary build check @messense
  • fix(napi): double allocation in create_buffer @Brooooooklyn

Reference API

use napi::bindgen_prelude::*;

pub struct Repository {
  dir: String,
}

impl Repository {
  fn remote(&self) -> Remote {
    Remote { inner: self }
  }
}

pub struct Remote<'repo> {
  inner: &'repo Repository,
}

impl<'repo> Remote<'repo> {
  fn name(&self) -> String {
    "origin".to_owned()
  }
}

#[napi]
pub struct JsRepo {
  inner: Repository,
}

#[napi]
impl JsRepo {
  #[napi(constructor)]
  pub fn new(dir: String) -> Self {
    JsRepo {
      inner: Repository { dir },
    }
  }

  #[napi]
  pub fn remote(&self, reference: Reference<JsRepo>, env: Env) -> Result<JsRemote> {
    Ok(JsRemote {
      inner: reference.share_with(env, |repo| Ok(repo.inner.remote()))?,
    })
  }
}

#[napi]
pub struct JsRemote {
  inner: SharedReference<JsRepo, Remote<'static>>,
}

#[napi]
impl JsRemote {
  #[napi]
  pub fn name(&self) -> String {
    self.inner.name()
  }
}
const repo = new JsRepo('.')
t.is(repo.remote().name(), 'origin')

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/@napi-rs/cli@2.2.0...napi@2.3.0

napi@2.3.0-alpha.1

4/7/2022

Features

  • Provide Reference API to keep class reference alive with JavaScript instance.
  • Allow injecting Reference into parameters like Env.
  • Add tests to ensure no memory leak happened in the new Reference API.
  • Buffer now can be used in struct which is implemented Task trait.
use napi::bindgen_prelude::*;

pub struct Repository {
  dir: String,
}

impl Repository {
  fn remote(&self) -> Remote {
    Remote { inner: self }
  }
}

pub struct Remote<'repo> {
  inner: &'repo Repository,
}

impl<'repo> Remote<'repo> {
  fn name(&self) -> String {
    "origin".to_owned()
  }
}

#[napi]
pub struct JsRepo {
  inner: Repository,
}

#[napi]
impl JsRepo {
  #[napi(constructor)]
  pub fn new(dir: String) -> Self {
    JsRepo {
      inner: Repository { dir },
    }
  }

  #[napi]
  pub fn remote(&self, reference: Reference<JsRepo>, env: Env) -> Result<JsRemote> {
    Ok(JsRemote {
      inner: reference.share_with(env, |repo| Ok(repo.inner.remote()))?,
    })
  }
}

#[napi]
pub struct JsRemote {
  inner: SharedReference<JsRepo, Remote<'static>>,
}

#[napi]
impl JsRemote {
  #[napi]
  pub fn name(&self) -> String {
    self.inner.name()
  }
}
const repo = new JsRepo('.')
t.is(repo.remote().name(), 'origin')

napi@2.2.0

3/6/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.1.0...napi@2.2.0

napi@2.1.0

2/9/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.4...napi@2.1.0

napi-derive@2.1.0

2/9/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.8...napi-derive@2.1.0

napi@2.0.4

1/18/2022

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.3...napi@2.0.4

napi-derive@2.0.8

1/18/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.7...napi-derive@2.0.8

napi@2.0.3

1/13/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.7...napi@2.0.3

napi-derive@2.0.7

1/7/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.6...napi-derive@2.0.7

napi-derive@2.0.6

1/6/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.5...napi-derive@2.0.6

napi-derive@2.0.5

1/4/2022

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.4...napi-derive@2.0.5

napi-derive@2.0.4

12/24/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.3...napi-derive@2.0.4

napi-derive@2.0.3

12/24/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.2...napi-derive@2.0.3

napi-derive@2.0.2

12/23/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.1...napi-derive@2.0.2

napi@2.0.2

12/22/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.1...napi@2.0.2

napi@2.0.1

12/21/2021

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0...napi@2.0.1

napi-derive@2.0.1

12/21/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0...napi-derive@2.0.1

napi-build@1.2.1

12/21/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0...napi-build@1.2.1

napi@2.0.0

12/17/2021 https://napi.rs/blog/announce-v2@Brooooooklyn

Special thanks to @forehalo for the initial version of NAPI-RS v2

And @timfish@h-a-n-a@joaomoreno@yisibl@idan-at@sam3d for contributing.

napi@2.0.0-beta.7

12/14/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-beta.6...napi@2.0.0-beta.7

napi@2.0.0-beta.6

12/13/2021

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/@napi-rs/cli@2.0.0-beta.5...napi@2.0.0-beta.6

napi@2.0.0-beta.5

12/8/2021

Feature

napi-derive@2.0.0-beta.5

12/8/2021

Bugfix

napi-derive@2.0.0-beta.4

12/8/2021

Feature

This feature is useful for sharing code between Node.js native addon and wasm

napi@2.0.0-beta.4

12/7/2021

Feature

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-beta.3...napi@2.0.0-beta.4

napi@2.0.0-beta.3

12/7/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0-beta.2...napi@2.0.0-beta.3

napi-derive@2.0.0-beta.3

12/7/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-beta.3...napi-derive@2.0.0-beta.3

napi-derive@2.0.0-beta.2

12/6/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0-beta.1...napi-derive@2.0.0-beta.2

napi@2.0.0-beta.2

12/3/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-beta.1...napi@2.0.0-beta.2

napi-sys@2.1.0

12/2/2021

Features

  • Enable node_api syntax error experimental functions #897 @idan-at

napi-build@1.2.0

12/2/2021

Features

  • Update Windows x64 and Windows x86 lib file to Node.js@17.2.0

⚠️ There is no official Node.js build for Windows ARM64 for now: https://github.com/nodejs/build/issues/2450

So if you want build library for Windows ARM64, you can not use experimental features for now.

napi@2.0.0-beta.1

12/2/2021

Bugfix

napi@2.0.0-beta.0

12/2/2021

What's Changed

#[napi]
fn convert_u32_array(input: Uint32Array) -> Vec<u32> {
  // AsRef<[u32]>, AsMut<[u32]>, Deref<[u32]>, DerefMut<u32>
  input.to_vec()
}

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

export function convertU32Array(input: Uint32Array): Array<number>

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-alpha.8...napi@2.0.0-beta.0

napi-derive@2.0.0-beta.1

12/2/2021

Bugfix

napi@1.8.0

11/29/2021

Features

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@1.7.11...napi@1.8.0

napi-sys@2.0.0

11/29/2021

Breaking Changes

  • Remove rust enum to avoid compatible issue #887 @Brooooooklyn
  • threadsafe_function related types now is under the napi4 feature flag @Brooooooklyn
  • Add experimental flag and node_api_get_module_file_name function @Brooooooklyn

napi-derive@2.0.0-alpha.10

11/29/2021

Features

  • Output Rust doc comments in definitions as jsdoc comments #885 @timfish
/// `constructor` option for `struct` requires all fields to be public,
/// otherwise tag impl fn as constructor
/// #[napi(constructor)]
#[napi]
pub struct Animal {
  #[napi(readonly)]
  /// Kind of animal
  pub kind: Kind,

  name: String,
}

#[napi]
impl Animal {
  /// This is the constructor
  #[napi(constructor)]
  pub fn new(kind: Kind, name: String) -> Self {
    Animal { kind, name }
  }

  /// This is a factory method
  #[napi(factory)]
  pub fn with_kind(kind: Kind) -> Self {
    Animal {
      kind,
      name: "Default".to_owned(),
    }
  }

  #[napi(getter)]
  pub fn get_name(&self) -> &str {
    self.name.as_str()
  }

  #[napi(setter)]
  pub fn set_name(&mut self, name: String) {
    self.name = name;
  }

  /// This is a
  /// multi-line comment
  /// with an emoji 🚀
  #[napi]
  pub fn whoami(&self) -> String {
    match self.kind {
      Kind::Dog => {
        format!("Dog: {}", self.name)
      }
      Kind::Cat => format!("Cat: {}", self.name),
      Kind::Duck => format!("Duck: {}", self.name),
    }
  }

  #[napi]
  /// This is static...
  pub fn get_dog_kind() -> Kind {
    Kind::Dog
  }
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️ ```ts /

  • constructor option for struct requires all fields to be public,
  • otherwise tag impl fn as constructor
  • #[napi(constructor)] */ export class Animal { / Kind of animal */ readonly kind: Kind / This is the constructor */ constructor(kind: Kind, name: string) / This is a factory method */ static withKind(kind: Kind): Animal get name(): string set name(name: string) /
    • This is a
    • multi-line comment
    • with an emoji 🚀 */ whoami(): string / This is static... */ static getDogKind(): Kind } ```

napi-derive@2.0.0-alpha.9

11/26/2021

Features

use napi::bindgen_prelude::*;
use napi_derive::napi;

#[napi(ts_args_type = "a: { foo: number }", ts_return_type = "string[]")]
fn ts_rename(a: Object) -> Result<Object> {
  a.get_property_names()
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

export function tsRename(a: { foo: number }): string[]

napi-build@1.1.2

11/25/2021

Bugfix

  • Fix cargo:rerun-if commands #871 @sam3d

napi@2.0.0-alpha.7

11/25/2021

What's Changed

Support export rust mod as JavaScript Object

#[napi]
mod xxh3 {
  use napi::bindgen_prelude::{BigInt, Buffer};

  #[napi]
  pub const ALIGNMENT: u32 = 16;

  #[napi(js_name = "xxh3_64")]
  pub fn xxh64(input: Buffer) -> u64 {
    let mut h: u64 = 0;
    for i in input.as_ref() {
      h = h.wrapping_add(*i as u64);
    }
    h
  }
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

export namespace xxh3 {
  export const ALIGNMENT: number
  export function xxh3_64(input: Buffer): BigInt
  export function xxh128(input: Buffer): BigInt
}

Support return &Self for method chain

#[napi]
pub struct ClassWithFactory {
  pub name: String,
}

#[napi]
impl ClassWithFactory {
  #[napi(factory)]
  pub fn with_name(name: String) -> Self {
    Self { name }
  }

  #[napi]
  pub fn set_name(&mut self, name: String) -> &Self {
    self.name = name;
    self
  }
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

export class ClassWithFactory {
  name: string
  static withName(name: string): ClassWithFactory
  setName(name: string): this
}

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-alpha.6...napi@2.0.0-alpha.7

napi@1.7.11

11/21/2021

Bugfix

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@1.7.10...napi@1.7.11

napi@2.0.0-alpha.6

11/21/2021

Bugfix

Full Changelog: https://github.com/napi-rs/napi-rs/compare/@napi-rs/cli@2.0.0-alpha.10...napi@2.0.0-alpha.6

napi@2.0.0-alpha.5

11/21/2021

Features 🎉

feat(napi-derive): support const export by @Brooooooklyn in https://github.com/napi-rs/napi-rs/pull/863

#[napi]
pub const DEFAULT_COST: u32 = 12;

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

export const DEFAULT_COST: number

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

import { DEFAULT_COST } from './index.js'

console.log(DEFAULT_COST) // 12

feat(napi): implement external value by @Brooooooklyn in https://github.com/napi-rs/napi-rs/pull/868

#[napi]
pub fn create_external(size: u32) -> External<u32> {
  External::new(size)
}

#[napi]
pub fn get_external(external: External<u32>) -> u32 {
  *external.as_ref()
}

#[napi]
pub fn mutate_external(mut external: External<u32>, new_val: u32) {
  *external.as_mut() = new_val;
}

#[napi]
pub fn create_external_string(content: String) -> External<String> {
  External::new(content)
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

export class ExternalObject<T> {
  private readonly __type: unique symbol;
  [val: unique symbol]: T
}

export function createExternal(size: number): ExternalObject<number>
export function getExternal(external: ExternalObject<number>): number
export function mutateExternal(external: ExternalObject<number>, newVal: number): void
export function createExternalString(content: string): ExternalObject<string>

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

import test from 'ava'

import { createExternal, getExternal, mutateExternal } from './index.js'

test('external', (t) => {
  const FX = 42
  const ext = createExternal(FX)
  t.is(getExternal(ext), FX)
  mutateExternal(ext, FX + 1)
  t.is(getExternal(ext), FX + 1)
  // Can not pass non `ExternalObject` type to functions accept `ExternalObject`
  // @ts-expect-error
  t.throws(() => getExternal({}))
  const ext2 = createExternalString('wtf')
  // Can not assign `ExternalObject<string>` to `ExternalObject<number>`
  // @ts-expect-error
  const e = t.throws(() => getExternal(ext2))
  t.is(e.message, 'T on `get_value_external` is not the type of wrapped object')
})

Bugfix

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.0.0-alpha.4...napi@2.0.0-alpha.5

napi@1.7.10

11/20/2021

Bugfix

napi@2.0.0-alpha.4

11/16/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/@napi-rs/cli@2.0.0-alpha.5...napi@2.0.0-alpha.4

napi@2.0.0-alpha.3

11/16/2021

Breaking changes

  • Bigint is renamed into BigInt
  • ValueType::Bigint is renamed into ValueType::BigInt
  • Deprecate creating Error from fields, Error must be created from Error::new/Error::from, Error::from_reason

Highlight features 🚀

await JavaScript Promise in Rust

This feature requires napi4 and tokio_rt features.

#[napi]
pub async fn async_plus_100(p: Promise<u32>) -> Result<u32> {
  let v = p.await?;
  Ok(v + 100)
}

Resolve value

test('await Promise in rust', async (t) => {
  const fx = 20
  const result = await asyncPlus100(
    new Promise((resolve) => {
      setTimeout(() => resolve(fx), 50)
    }),
  )
  t.is(result, fx + 100)
})

Reject error

test('Promise should reject raw error in rust', async (t) => {
  const fxError = new Error('What is Happy Planet')
  const err = await t.throwsAsync(() => asyncPlus100(Promise.reject(fxError)))
  t.is(err, fxError)
})

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0-alpha.3...napi@2.0.0-alpha.3

napi-derive@2.0.0-alpha.6

11/16/2021

What's Changed

  • Generate TypeScript optional types from Rust Option
#[napi]
fn map_option(val: Option<u32>) -> Option<u32> {
  val.map(|v| v + 1)
}
export function mapOption(val?: number | undefined | null): number | undefined | null
#[napi]
pub struct Context {
  data: String,
  pub maybe_need: Option<bool>,
}
export class Context {
  maybeNeed?: boolean | undefined | null
}
#[napi]
fn read_file<T: Fn(Result<()>, Option<String>) -> Result<()>>(callback: T) {
  match read_file_content() {
    Ok(s) => callback(Ok(()), Some(s)),
    Err(e) => callback(Err(e), None),
  }
  .unwrap();
}
export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0-alpha.5...napi-derive@2.0.0-alpha.6

napi-derive@2.0.0-alpha.5

11/16/2021

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.0.0-alpha.4...napi-derive@2.0.0-alpha.5

napi@1.7.9

11/15/2021

Bugfix

napi-derive@2.0.0-alpha.3

11/10/2021

Bugfix

napi@1.7.8

11/6/2021

Features

  • feat(napi): implement Env::throw to throw any JsValue #839 @Brooooooklyn

Throw SyntaxError:

#[js_function(1)]
pub fn throw_syntax_error(ctx: CallContext) -> Result<JsUndefined> {
  let message: JsString = ctx.get(0)?;
  let syntax_error = ctx
    .env
    .get_global()?
    .get_named_property::<JsFunction>("SyntaxError")?;
  ctx.env.throw(syntax_error.new(&[message])?)?;
  ctx.env.get_undefined()
}

napi@2.0.0-alpha.2

11/6/2021

🚧 Breaking Changes

Task

resolve and reject now take &mut self instead of self. Add new fn finally to excute after resolve or reject:

Ref

unref now takes &mut self instead of self.

struct BufferLength(Ref<JsBufferValue>);

impl Task for BufferLength {
  type Output = usize;
  type JsValue = JsNumber;

  fn compute(&mut self) -> Result<Self::Output> {
    Ok(self.0.len() + 1)
  }

-  fn resolve(self, env: Env, output: Self::Output) -> Result<Self::JsValue> {
-    self.0.unref(env)?;
+  fn resolve(&mut self, env: Env, output: Self::Output) -> Result<Self::JsValue> {
    env.create_uint32(output as u32)
   }

-  fn reject(self, err: Error) -> Result<Self::JsValue> {
-    self.0.unref(env)?;
-    Err(err)
-  }

+  fn finally(&mut self, env: Env) -> Result<()> {
+    self.0.unref(env)?;
+    Ok(())
+  }
}

Features

Either type #823 @Brooooooklyn

Either types could be passed in as arguments or as return types:

#[napi]
fn either4(input: Either4<String, u32, bool, Obj>) -> u32 {
  match input {
    Either4::A(s) => s.len() as u32,
    Either4::B(n) => n,
    Either4::C(b) => {
      if b {
        1
      } else {
        0
      }
    }
    Either4::D(f) => match f.v {
      Either::A(s) => s.len() as u32,
      Either::B(n) => n,
    },
  }
}

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

interface Obj {
  v: string | number
}
export function either4(input: string | number | boolean | Obj): number

AsyncTask with AbortSignal support #831 @Brooooooklyn

carbon(5)

carbon(3)

Static Factory function for Class #834 @Brooooooklyn

Env::throw to throw any JavaScript Value e0671fe@Brooooooklyn

Throw SyntaxError:

#[js_function(1)]
pub fn throw_syntax_error(ctx: CallContext) -> Result<JsUndefined> {
  let message: JsString = ctx.get(0)?;
  let syntax_error = ctx
    .env
    .get_global()?
    .get_named_property::<JsFunction>("SyntaxError")?;
  ctx.env.throw(syntax_error.new(&[message])?)?;
  ctx.env.get_undefined()
}