Compare commits

..

4 Commits

Author SHA1 Message Date
David Herman
f75368a2d2 cargo fmt 2021-05-15 13:38:07 -07:00
David Herman
6221ee21a8 Update doc examples to use Channel. 2021-05-15 13:21:34 -07:00
David Herman
280fdbd42a Add EventQueue and EventQueueError back to the prelude for backwards compatibility.
I think this will result in fewer deprecation warnings for users than ideal, but it seems better to optimize for compatibility than warnings.
2021-05-15 12:58:41 -07:00
David Herman
f2d3703ab9 Rename EventQueue and EventQueueError to Channel and SendError.
The previous types are preserved for backwards compatibility.
2021-05-15 12:45:11 -07:00
23 changed files with 147 additions and 197 deletions

View File

@ -1,18 +1,18 @@
[package]
name = "neon"
version = "0.8.2"
version = "0.8.1"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "A safe abstraction layer for Node.js."
readme = "README.md"
homepage = "https://www.neon-bindings.com"
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
exclude = ["neon.jpg", "doc/**/*"]
exclude = ["neon.jpg"]
build = "build.rs"
edition = "2018"
[build-dependencies]
neon-build = { version = "=0.8.2", path = "crates/neon-build" }
neon-build = { version = "=0.8.1", path = "crates/neon-build" }
[dev-dependencies]
lazy_static = "1.4.0"
@ -25,8 +25,8 @@ failure = "0.1.5" # used for a doc example
cslice = "0.2"
semver = "0.9.0"
smallvec = "1.4.2"
neon-runtime = { version = "=0.8.2", path = "crates/neon-runtime" }
neon-macros = { version = "=0.8.2", path = "crates/neon-macros", optional = true }
neon-runtime = { version = "=0.8.1", path = "crates/neon-runtime" }
neon-macros = { version = "=0.8.1", path = "crates/neon-macros", optional = true }
[features]
default = ["legacy-runtime"]

View File

@ -33,15 +33,14 @@ The N-API backend of Neon requires a minimum Node version of 10.0.
To enable the N-API backend, you need to:
1. Remove `build.rs` from the project directory and `build = "build.rs"` from the `Cargo.toml`. The N-API backend does not require a Cargo build script.
2. Disable the default features (for now, the default features select the legacy backend) by setting `default-features = false`; and
3. Enable the appropriate feature flag in your `Cargo.toml` to select the N-API version you need support for (each N-API version N uses the feature flag `"napi-N"`, for example `"napi-4"` for N-API version 4).
1. Disable the default features (for now, the default features select the legacy backend) by setting `default-features = false`; and
2. Enable the appropriate feature flag in your `Cargo.toml` to select the N-API version you need support for (each N-API version N uses the feature flag `"napi-N"`, for example `"napi-4"` for N-API version 4).
As a rule, you should choose the **oldest version of N-API that has the APIs you need.** (We will be adding N-API version requirements to the Neon API docs to make this clearer in the future.) You can consult the [official N-API feature matrix](https://nodejs.org/api/n-api.html#n_api_node_api_version_matrix) to see which N-API versions come with various versions of Node.
```toml
[dependencies.neon]
version = "0.8.2"
version = "0.8.1"
default-features = false
features = ["napi-4"]
```

View File

@ -1,8 +1,3 @@
# Version 0.8.2
* More docs improvements
* Added a deprecation warning to `neon new` (https://github.com/neon-bindings/neon/pull/722)
# Version 0.8.1
* Fix `legacy-backend` for Node 16 (https://github.com/neon-bindings/neon/pull/715)

20
cli/package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "neon-cli",
"version": "0.8.2",
"version": "0.8.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -616,9 +616,9 @@
"dev": true
},
"handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
"version": "4.7.6",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
"integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
"requires": {
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
@ -849,9 +849,9 @@
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
},
"lodash.camelcase": {
"version": "4.3.0",
@ -1365,9 +1365,9 @@
"integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="
},
"uglify-js": {
"version": "3.13.5",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz",
"integrity": "sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz",
"integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==",
"optional": true
},
"validate-npm-package-license": {

View File

@ -1,6 +1,6 @@
{
"name": "neon-cli",
"version": "0.8.2",
"version": "0.8.1",
"description": "Build and load native Rust/Neon modules.",
"author": "Dave Herman <david.herman@gmail.com>",
"repository": {

View File

@ -1,6 +1,6 @@
[package]
name = "neon-build"
version = "0.8.2"
version = "0.8.1"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Build logic required for Neon projects."
repository = "https://github.com/neon-bindings/neon"
@ -9,4 +9,4 @@ edition = "2018"
build = "build.rs"
[dependencies]
neon-sys = { version = "=0.8.2", path = "../neon-sys", optional = true }
neon-sys = { version = "=0.8.1", path = "../neon-sys", optional = true }

View File

@ -1,6 +1,6 @@
[package]
name = "neon-macros"
version = "0.8.2"
version = "0.8.1"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Procedural macros supporting Neon"
repository = "https://github.com/neon-bindings/neon"

View File

@ -1,6 +1,6 @@
[package]
name = "neon-runtime"
version = "0.8.2"
version = "0.8.1"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Bindings to the Node.js native addon API, used by the Neon implementation."
repository = "https://github.com/neon-bindings/neon"
@ -10,7 +10,7 @@ edition = "2018"
[dependencies]
cfg-if = "1.0.0"
libloading = { version = "0.6.5", optional = true }
neon-sys = { version = "=0.8.2", path = "../neon-sys", optional = true }
neon-sys = { version = "=0.8.1", path = "../neon-sys", optional = true }
smallvec = "1.4.2"
[dev-dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "neon-sys"
version = "0.8.2"
version = "0.8.1"
authors = ["David Herman <david.herman@gmail.com>"]
description = "Exposes the low-level V8/NAN C/C++ APIs. Will be superseded by N-API."
edition = "2018"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

View File

@ -152,7 +152,7 @@ use crate::borrow::internal::Ledger;
use crate::borrow::{Borrow, BorrowMut, Ref, RefMut};
use crate::context::internal::Env;
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
use crate::event::EventQueue;
use crate::event::Channel;
use crate::handle::{Handle, Managed};
#[cfg(feature = "legacy-runtime")]
use crate::object::class::Class;
@ -550,9 +550,16 @@ pub trait Context<'a>: ContextInternal<'a> {
}
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
/// Creates an unbounded queue of events to be executed on a JavaScript thread
fn queue(&mut self) -> EventQueue {
EventQueue::new(self)
/// Creates an unbounded channel for scheduling events to be executed on the JavaScript thread.
fn channel(&mut self) -> Channel {
Channel::new(self)
}
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
#[deprecated(since = "0.9.0", note = "Please use the channel() method instead")]
#[doc(hidden)]
fn queue(&mut self) -> Channel {
self.channel()
}
}

View File

@ -6,7 +6,7 @@ use crate::result::NeonResult;
type Callback = Box<dyn FnOnce(Env) + Send + 'static>;
/// Queue for scheduling Rust closures to execute on the JavaScript main thread.
/// Channel for scheduling Rust closures to execute on the JavaScript main thread.
///
/// # Example
///
@ -17,11 +17,11 @@ type Callback = Box<dyn FnOnce(Env) + Send + 'static>;
/// # use neon::prelude::*;
/// # fn fibonacci(_: f64) -> f64 { todo!() }
/// fn async_fibonacci(mut cx: FunctionContext) -> JsResult<JsUndefined> {
/// // These types (`f64`, `Root<JsFunction>`, `EventQueue`) may all be sent
/// // These types (`f64`, `Root<JsFunction>`, `Channel`) may all be sent
/// // across threads.
/// let n = cx.argument::<JsNumber>(0)?.value(&mut cx);
/// let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
/// let queue = cx.queue();
/// let channel = cx.channel();
///
/// // Spawn a thread to complete the execution. This will _not_ block the
/// // JavaScript event loop.
@ -29,8 +29,8 @@ type Callback = Box<dyn FnOnce(Env) + Send + 'static>;
/// let result = fibonacci(n);
///
/// // Send a closure as a task to be executed by the JavaScript event
/// // queue. This _will_ block the event queue while executing.
/// queue.send(move |mut cx| {
/// // loop. This _will_ block the event loop while executing.
/// channel.send(move |mut cx| {
/// let callback = callback.into_inner(&mut cx);
/// let this = cx.undefined();
/// let null = cx.null();
@ -49,19 +49,19 @@ type Callback = Box<dyn FnOnce(Env) + Send + 'static>;
/// }
/// ```
pub struct EventQueue {
pub struct Channel {
tsfn: ThreadsafeFunction<Callback>,
has_ref: bool,
}
impl std::fmt::Debug for EventQueue {
impl std::fmt::Debug for Channel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("EventQueue")
f.write_str("Channel")
}
}
impl EventQueue {
/// Creates an unbounded queue for scheduling closures on the JavaScript
impl Channel {
/// Creates an unbounded channel for scheduling closures on the JavaScript
/// main thread
pub fn new<'a, C: Context<'a>>(cx: &mut C) -> Self {
let tsfn = unsafe { ThreadsafeFunction::new(cx.env().to_raw(), Self::callback) };
@ -72,7 +72,7 @@ impl EventQueue {
}
}
/// Allow the Node event loop to exit while this `EventQueue` exists.
/// Allow the Node event loop to exit while this `Channel` exists.
/// _Idempotent_
pub fn unref<'a, C: Context<'a>>(&mut self, cx: &mut C) -> &mut Self {
self.has_ref = false;
@ -82,7 +82,7 @@ impl EventQueue {
self
}
/// Prevent the Node event loop from exiting while this `EventQueue` exists. (Default)
/// Prevent the Node event loop from exiting while this `Channel` exists. (Default)
/// _Idempotent_
pub fn reference<'a, C: Context<'a>>(&mut self, cx: &mut C) -> &mut Self {
self.has_ref = true;
@ -92,7 +92,7 @@ impl EventQueue {
self
}
/// Schedules a closure to execute on the JavaScript thread that created this EventQueue
/// Schedules a closure to execute on the JavaScript thread that created this Channel
/// Panics if there is a libuv error
pub fn send<F>(&self, f: F)
where
@ -101,9 +101,9 @@ impl EventQueue {
self.try_send(f).unwrap()
}
/// Schedules a closure to execute on the JavaScript thread that created this EventQueue
/// Schedules a closure to execute on the JavaScript thread that created this Channel
/// Returns an `Error` if the task could not be scheduled.
pub fn try_send<F>(&self, f: F) -> Result<(), EventQueueError>
pub fn try_send<F>(&self, f: F) -> Result<(), SendError>
where
F: FnOnce(TaskContext) -> NeonResult<()> + Send + 'static,
{
@ -117,11 +117,11 @@ impl EventQueue {
});
});
self.tsfn.call(callback, None).map_err(|_| EventQueueError)
self.tsfn.call(callback, None).map_err(|_| SendError)
}
/// Returns a boolean indicating if this `EventQueue` will prevent the Node event
/// queue from exiting.
/// Returns a boolean indicating if this `Channel` will prevent the Node event
/// loop from exiting.
pub fn has_ref(&self) -> bool {
self.has_ref
}
@ -138,19 +138,19 @@ impl EventQueue {
}
}
/// Error indicating that a closure was unable to be scheduled to execute on the event queue
pub struct EventQueueError;
/// Error indicating that a closure was unable to be scheduled to execute on the event loop.
pub struct SendError;
impl std::fmt::Display for EventQueueError {
impl std::fmt::Display for SendError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "EventQueueError")
write!(f, "SendError")
}
}
impl std::fmt::Debug for EventQueueError {
impl std::fmt::Debug for SendError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl std::error::Error for EventQueueError {}
impl std::error::Error for SendError {}

View File

@ -32,20 +32,20 @@
//! # #[cfg(feature = "napi-1")] {
//! # use neon::prelude::*;
//! #
//! # fn parse(filename: String, callback: Root<JsFunction>, queue: EventQueue) { }
//! # fn parse(filename: String, callback: Root<JsFunction>, channel: Channel) { }
//! #
//! fn parse_async(mut cx: FunctionContext) -> JsResult<JsUndefined> {
//! // The types `String`, `Root<JsFunction>`, and `EventQueue` can all be
//! // The types `String`, `Root<JsFunction>`, and `Channel` can all be
//! // sent across threads.
//! let filename = cx.argument::<JsString>(0)?.value(&mut cx);
//! let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
//! let queue = cx.queue();
//! let channel = cx.channel();
//!
//! // Spawn a thread to complete the execution. This will _not_ block the
//! // JavaScript event loop.
//! // Spawn a background thread to complete the execution. The background
//! // execution will _not_ block the JavaScript event loop.
//! std::thread::spawn(move || {
//! // Do the heavy lifting inside the background thread.
//! parse(filename, callback, queue);
//! parse(filename, callback, channel);
//! });
//!
//! Ok(cx.undefined())
@ -58,7 +58,7 @@
//! thread.)
//!
//! Upon completion of its task, the background thread can use the JavaScript
//! callback and the event queue to notify the main thread of the result:
//! callback and the channel to notify the main thread of the result:
//!
//! ```
//! # #[cfg(feature = "napi-1")] {
@ -70,12 +70,12 @@
//! Psd::from_bytes(&std::fs::read(&filename)?)
//! }
//!
//! fn parse(filename: String, callback: Root<JsFunction>, queue: EventQueue) {
//! fn parse(filename: String, callback: Root<JsFunction>, channel: Channel) {
//! let result = psd_from_filename(filename);
//!
//! // Send a closure as a task to be executed by the JavaScript event
//! // queue. This _will_ block the event queue while executing.
//! queue.send(move |mut cx| {
//! // loop. This _will_ block the event loop while executing.
//! channel.send(move |mut cx| {
//! let callback = callback.into_inner(&mut cx);
//! let this = cx.undefined();
//! let null = cx.null();
@ -127,7 +127,17 @@
mod event_queue;
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
pub use self::event_queue::{EventQueue, EventQueueError};
pub use self::event_queue::{Channel, SendError};
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
#[deprecated(since = "0.9.0", note = "Please use the Channel type instead")]
#[doc(hidden)]
pub type EventQueue = self::event_queue::Channel;
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
#[deprecated(since = "0.9.0", note = "Please use the SendError type instead")]
#[doc(hidden)]
pub type EventQueueError = self::event_queue::SendError;
#[cfg(all(not(feature = "napi-1"), feature = "event-handler-api"))]
mod event_handler;
@ -138,5 +148,5 @@ pub use self::event_handler::EventHandler;
#[cfg(all(feature = "napi-1", feature = "event-handler-api"))]
compile_error!(
"The `EventHandler` API is not supported with the N-API \
backend. Use `EventQueue` instead."
backend. Use `Channel` instead."
);

View File

@ -10,6 +10,9 @@ pub use crate::declare_types;
#[cfg(all(not(feature = "napi-1"), feature = "event-handler-api"))]
pub use crate::event::EventHandler;
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
pub use crate::event::{Channel, SendError};
#[cfg(all(feature = "napi-4", feature = "event-queue-api"))]
#[allow(deprecated)]
pub use crate::event::{EventQueue, EventQueueError};
pub use crate::handle::Handle;
#[cfg(feature = "legacy-runtime")]

View File

@ -1,76 +1,4 @@
//! Representations of JavaScript's core builtin types.
//!
//! ## Modeling JavaScript Types
//!
//! All JavaScript values in Neon implement the abstract [`Value`] trait, which
//! is the most generic way to work with JavaScript values. Neon provides a
//! number of types that implement this trait, each representing a particular
//! type of JavaScript value.
//!
//! By convention, JavaScript types in Neon have the prefix `Js` in their name,
//! such as [`JsNumber`](crate::types::JsNumber) (for the JavaScript `number`
//! type) or [`JsFunction`](crate::types::JsFunction) (for the JavaScript
//! `function` type).
//!
//! ### Handles and Casts
//!
//! Access to JavaScript values in Neon works through [handles](crate::handle),
//! which ensure the safe interoperation between Rust and the JavaScript garbage
//! collector. This means, for example, a Rust variable that stores a JavaScript string
//! will have the type `Handle<JsString>` rather than [`JsString`](crate::types::JsString).
//!
//! Neon types model the JavaScript type hierarchy through the use of *casts*.
//! The [`Handle::upcast()`](crate::handle::Handle::upcast) method safely converts
//! a handle to a JavaScript value of one type into a handle to a value of its
//! supertype. For example, it's safe to treat a [`JsArray`](crate::types::JsArray)
//! as a [`JsObject`](crate::types::JsObject), so you can do an "upcast" and it will
//! never fail:
//!
//! ```
//! # use neon::prelude::*;
//! fn as_object(array: Handle<JsArray>) -> Handle<JsObject> {
//! let object: Handle<JsObject> = array.upcast();
//! object
//! }
//! ```
//!
//! Unlike upcasts, the [`Handle::downcast()`](crate::handle::Handle::downcast) method
//! requires a runtime check to test a value's type at runtime, so it can fail with
//! a [`DowncastError`](crate::handle::DowncastError):
//!
//! ```
//! # use neon::prelude::*;
//! fn as_array<'a>(
//! cx: &mut impl Context<'a>,
//! object: Handle<'a, JsObject>
//! ) -> JsResult<'a, JsArray> {
//! object.downcast(cx).or_throw(cx)
//! }
//! ```
//!
//! ### The JavaScript Type Hierarchy
//!
//! ![The Neon type hierarchy, described in detail below.][types]
//!
//! The JavaScript type hierarchy includes:
//!
//! - [`JsValue`](JsValue): This is the top of the type hierarchy, and can refer to
//! any JavaScript value. (For TypeScript programmers, this can be thought of as
//! similar to TypeScript's [`unknown`][unknown] type.)
//! - [`JsObject`](JsObject): This is the top of the object type hierarchy. Object
//! types all implement the [`Object`](crate::object::Object) trait, which allows
//! getting and setting properties.
//! - **Standard object types:** [`JsFunction`](JsFunction), [`JsArray`](JsArray),
//! [`JsDate`](JsDate), and [`JsError`](JsError).
//! - **Typed arrays:** [`JsBuffer`](JsBuffer) and [`JsArrayBuffer`](JsArrayBuffer).
//! - **Custom types:** [`JsBox`](JsBox), a special Neon type that allows the creation
//! of custom objects that own Rust data structures.
//! - **Primitive types:** These are the built-in JavaScript datatypes that are not
//! object types: [`JsNumber`](JsNumber), [`JsBoolean`](JsBoolean),
//! [`JsString`](JsString), [`JsNull`](JsNull), and [`JsUndefined`](JsUndefined).
//!
//! [types]: https://raw.githubusercontent.com/neon-bindings/neon/main/doc/types.jpg
//! [unknown]: https://mariusschulz.com/blog/the-unknown-type-in-typescript#the-unknown-type
pub(crate) mod binary;
#[cfg(feature = "napi-1")]

View File

@ -687,15 +687,14 @@
"dev": true
},
"handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
"requires": {
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"optimist": "^0.6.1",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4",
"wordwrap": "^1.0.0"
"uglify-js": "^3.1.4"
}
},
"has-flag": {
@ -838,9 +837,9 @@
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
},
"lodash.padend": {
"version": "4.6.1",
@ -927,9 +926,9 @@
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
},
"mkdirp": {
"version": "0.5.1",
@ -1072,6 +1071,15 @@
"mimic-fn": "^1.0.0"
}
},
"optimist": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"requires": {
"minimist": "~0.0.1",
"wordwrap": "~0.0.2"
}
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -1489,9 +1497,9 @@
"integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
},
"uglify-js": {
"version": "3.13.5",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz",
"integrity": "sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw==",
"version": "3.10.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz",
"integrity": "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g==",
"optional": true
},
"v8flags": {
@ -1545,9 +1553,9 @@
}
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
},
"wordwrapjs": {
"version": "3.0.0",

View File

@ -14,7 +14,7 @@
"command-line-commands": "^2.0.0",
"command-line-usage": "^4.0.0",
"git-config": "0.0.7",
"handlebars": "^4.7.7",
"handlebars": "^4.5.3",
"inquirer": "^3.0.6",
"mkdirp": "^0.5.1",
"quickly-copy-file": "^1.0.0",

View File

@ -810,9 +810,9 @@
"dev": true
},
"electron": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-11.1.0.tgz",
"integrity": "sha512-RFAhR/852VMaRd9NSe7jprwSoG9dLc6u1GwnqRWg+/3cy/8Zrwt1Betw1lXiZH7hGuB9K2cqju83Xv5Pq5ZSGA==",
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-11.0.4.tgz",
"integrity": "sha512-ipfQ28Km52iuDSe9VK0G5uuyxi8qy8szg+01kQTRXZFCLlpgsgU+vQxWkld2tkhXWdu+H3dmgYHvWtoijOvhjw==",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@ -1342,9 +1342,9 @@
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true,
"optional": true
},
@ -2085,9 +2085,9 @@
"dev": true
},
"ua-parser-js": {
"version": "0.7.28",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz",
"integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==",
"version": "0.7.22",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz",
"integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==",
"dev": true
},
"unbzip2-stream": {

View File

@ -13,7 +13,7 @@
"repository": "https://github.com/electron/electron-quick-start",
"devDependencies": {
"cargo-cp-artifact": "^0.1.0 ",
"electron": "^11.1.0",
"electron": "^11.0.3",
"spectron": "^13.0.0"
}
}

View File

@ -6,7 +6,7 @@ const assert = require('chai').assert;
return typeof global.gc === 'function' ? describe : describe.skip;
})()('sync', function() {
afterEach(() => {
// Force garbage collection to shutdown `EventQueue`
// Force garbage collection to shutdown `Channel`
global.gc();
});
@ -60,9 +60,9 @@ const assert = require('chai').assert;
global.gc();
});
it('should be able to unref event queue', function () {
// If the EventQueue is not unreferenced, the test runner will not cleanly exit
addon.leak_event_queue();
it('should be able to unref channel', function () {
// If the Channel is not unreferenced, the test runner will not cleanly exit
addon.leak_channel();
});
it('should drop leaked Root from the global queue', function (cb) {

View File

@ -13,10 +13,10 @@ pub fn useless_root(mut cx: FunctionContext) -> JsResult<JsObject> {
pub fn thread_callback(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let callback = cx.argument::<JsFunction>(0)?.root(&mut cx);
let queue = cx.queue();
let channel = cx.channel();
std::thread::spawn(move || {
queue.send(move |mut cx| {
channel.send(move |mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = Vec::<Handle<JsValue>>::new();
@ -33,14 +33,14 @@ pub fn thread_callback(mut cx: FunctionContext) -> JsResult<JsUndefined> {
pub fn multi_threaded_callback(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let n = cx.argument::<JsNumber>(0)?.value(&mut cx);
let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
let queue = Arc::new(cx.queue());
let channel = Arc::new(cx.channel());
for i in 0..(n as usize) {
let callback = callback.clone(&mut cx);
let queue = Arc::clone(&queue);
let channel = Arc::clone(&channel);
std::thread::spawn(move || {
queue.send(move |mut cx| {
channel.send(move |mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = vec![cx.number(i as f64)];
@ -63,17 +63,17 @@ pub struct AsyncGreeter {
greeting: String,
callback: Root<JsFunction>,
shutdown: Option<Root<JsFunction>>,
queue: Arc<EventQueue>,
channel: Arc<Channel>,
}
impl AsyncGreeter {
fn greet<'a, C: Context<'a>>(&self, mut cx: C) -> JsResult<'a, JsUndefined> {
let greeting = self.greeting.clone();
let callback = self.callback.clone(&mut cx);
let queue = Arc::clone(&self.queue);
let channel = Arc::clone(&self.channel);
std::thread::spawn(move || {
queue.send(|mut cx| {
channel.send(|mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = vec![cx.string(greeting)];
@ -110,7 +110,7 @@ pub fn greeter_new(mut cx: FunctionContext) -> JsResult<BoxedGreeter> {
let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
let shutdown = cx.argument_opt(2);
let queue = cx.queue();
let channel = cx.channel();
let shutdown = shutdown
.map(|v| v.downcast_or_throw::<JsFunction, _>(&mut cx))
.transpose()?
@ -120,7 +120,7 @@ pub fn greeter_new(mut cx: FunctionContext) -> JsResult<BoxedGreeter> {
greeting,
callback,
shutdown,
queue: Arc::new(queue),
channel: Arc::new(channel),
}));
Ok(greeter)
@ -133,14 +133,14 @@ pub fn greeter_greet(mut cx: FunctionContext) -> JsResult<JsUndefined> {
greeter.greet(cx)
}
pub fn leak_event_queue(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let queue = Box::new({
let mut queue = cx.queue();
queue.unref(&mut cx);
queue
pub fn leak_channel(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let channel = Box::new({
let mut channel = cx.channel();
channel.unref(&mut cx);
channel
});
Box::leak(queue);
Box::leak(channel);
Ok(cx.undefined())
}
@ -148,7 +148,7 @@ pub fn leak_event_queue(mut cx: FunctionContext) -> JsResult<JsUndefined> {
pub fn drop_global_queue(mut cx: FunctionContext) -> JsResult<JsUndefined> {
struct Wrapper {
callback: Option<Root<JsFunction>>,
queue: EventQueue,
channel: Channel,
}
impl Finalize for Wrapper {}
@ -158,7 +158,7 @@ pub fn drop_global_queue(mut cx: FunctionContext) -> JsResult<JsUndefined> {
impl Drop for Wrapper {
fn drop(&mut self) {
if let Some(callback) = self.callback.take() {
self.queue.send(|mut cx| {
self.channel.send(|mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = vec![cx.undefined()];
@ -172,11 +172,11 @@ pub fn drop_global_queue(mut cx: FunctionContext) -> JsResult<JsUndefined> {
}
let callback = cx.argument::<JsFunction>(0)?.root(&mut cx);
let queue = cx.queue();
let channel = cx.channel();
let wrapper = cx.boxed(Wrapper {
callback: Some(callback),
queue,
channel,
});
// Put the `Wrapper` instance in a `Root` and drop it

View File

@ -255,7 +255,7 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("multi_threaded_callback", multi_threaded_callback)?;
cx.export_function("greeter_new", greeter_new)?;
cx.export_function("greeter_greet", greeter_greet)?;
cx.export_function("leak_event_queue", leak_event_queue)?;
cx.export_function("leak_channel", leak_channel)?;
cx.export_function("drop_global_queue", drop_global_queue)?;
Ok(())