diff --git a/desktop/package-lock.json b/desktop/package-lock.json index be2f2c483d3d..f454d28091c6 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -1590,6 +1590,12 @@ "node": ">=8" } }, + "node_modules/@neon-rs/load": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.1.81.tgz", + "integrity": "sha512-A6w26BOWkFNXw04nfmcC75mLiPd3HPYC/PAuNDlXswvNb/rf55qXpTqGSz2txJmc7V8UDfIE1CAq5FUjL9wOmQ==", + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -10173,6 +10179,10 @@ "node": ">= 0.10" } }, + "node_modules/nseventforwarder": { + "resolved": "packages/nseventforwarder", + "link": true + }, "node_modules/nseventmonitor": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nseventmonitor/-/nseventmonitor-1.0.5.tgz", @@ -14670,6 +14680,13 @@ "grpc-tools": "^1.12.4", "nseventmonitor": "^1.0.5" } + }, + "packages/nseventforwarder": { + "version": "0.0.0", + "license": "GPL-3.0", + "dependencies": { + "@neon-rs/load": "^0.1.73" + } } }, "dependencies": { @@ -15847,6 +15864,11 @@ } } }, + "@neon-rs/load": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.1.81.tgz", + "integrity": "sha512-A6w26BOWkFNXw04nfmcC75mLiPd3HPYC/PAuNDlXswvNb/rf55qXpTqGSz2txJmc7V8UDfIE1CAq5FUjL9wOmQ==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -22679,6 +22701,12 @@ "once": "^1.3.2" } }, + "nseventforwarder": { + "version": "file:packages/nseventforwarder", + "requires": { + "@neon-rs/load": "^0.1.73" + } + }, "nseventmonitor": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nseventmonitor/-/nseventmonitor-1.0.5.tgz", diff --git a/desktop/packages/nseventforwarder/.gitignore b/desktop/packages/nseventforwarder/.gitignore new file mode 100644 index 000000000000..1444c8f490e5 --- /dev/null +++ b/desktop/packages/nseventforwarder/.gitignore @@ -0,0 +1,8 @@ +target +index.node +**/node_modules +**/.DS_Store +npm-debug.log* +lib +*.log +dist/ diff --git a/desktop/packages/nseventforwarder/Cargo.lock b/desktop/packages/nseventforwarder/Cargo.lock new file mode 100644 index 000000000000..c334d14c6d01 --- /dev/null +++ b/desktop/packages/nseventforwarder/Cargo.lock @@ -0,0 +1,325 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "neon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d75440242411c87dc39847b0e33e961ec1f10326a9d8ecf9c1ea64a3b3c13dc" +dependencies = [ + "getrandom", + "libloading", + "neon-macros", + "once_cell", + "semver", + "send_wrapper", + "smallvec", +] + +[[package]] +name = "neon-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6813fde79b646e47e7ad75f480aa80ef76a5d9599e2717407961531169ee38b" +dependencies = [ + "quote", + "syn", + "syn-mid", +] + +[[package]] +name = "nseventforwarder" +version = "0.1.0" +dependencies = [ + "block2", + "neon", + "objc2-app-kit", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-mid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5dc35bb08dd1ca3dfb09dce91fd2d13294d6711c88897d9a9d60acf39bce049" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/desktop/packages/nseventforwarder/Cargo.toml b/desktop/packages/nseventforwarder/Cargo.toml new file mode 100644 index 000000000000..af92e12b9fb1 --- /dev/null +++ b/desktop/packages/nseventforwarder/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +members = ["crates/nseventforwarder"] +resolver = "2" + +[profile.release] +strip = true # Automatically strip symbols from the binary. +opt-level = "z" # Optimize for size. diff --git a/desktop/packages/nseventforwarder/README.md b/desktop/packages/nseventforwarder/README.md new file mode 100644 index 000000000000..4d758b62dbbc --- /dev/null +++ b/desktop/packages/nseventforwarder/README.md @@ -0,0 +1,19 @@ +# nseventforwarder + +## Building nseventforwarder + +Building nseventforwarder requires a [supported version of Node and Rust](https://github.com/neon-bindings/neon#platform-support). + +To run the build, run: + +```sh +$ npm run build-debug +``` + +## Learn More + +Learn more about: + +- [Neon](https://neon-bindings.com). +- [Rust](https://www.rust-lang.org). +- [Node](https://nodejs.org). diff --git a/desktop/packages/nseventforwarder/build.sh b/desktop/packages/nseventforwarder/build.sh new file mode 100644 index 000000000000..53d39c762f58 --- /dev/null +++ b/desktop/packages/nseventforwarder/build.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -eu + +# Parse arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --target) + TARGET_TRIPLE="$2" + shift + shift + ;; + *) + echo "Unknown parameter: $1" + exit 1 + ;; + esac +done + +# Fail if TARGET_TRIPLE is not set +if [[ -z ${TARGET_TRIPLE-} ]]; then + echo "The variable TARGET_TRIPLE is not set." + echo "Set it using the --target flag" + echo "Available targets: aarch64-apple-darwin, x86_64-apple-darwin" + exit 1 +fi + +# Map the target to an output folder (where the dylib / node binary will end up). +# This is neon-convention. +case "$TARGET_TRIPLE" in + aarch64-apple-darwin) PLATFORM_DIR_NAME=darwin-arm64;; + x86_64-apple-darwin) PLATFORM_DIR_NAME=darwin-x64;; + *) + echo "Unknown target: $TARGET_TRIPLE" + echo "Available targets: aarch64-apple-darwin, x86_64-apple-darwin" + exit 1 + ;; +esac + +if [[ "$(uname -s)" == "Darwin" ]]; then + npm run cargo-build -- --release --target "$TARGET_TRIPLE" + # Copy the neon library to the correct dists folder, which is what node will + # pick up when loading the library at runtime. + PLATFORM_DIR="dist/$PLATFORM_DIR_NAME" + mkdir -p $PLATFORM_DIR + cp "target/$TARGET_TRIPLE/release/libnseventforwarder.dylib" "$PLATFORM_DIR/index.node" +fi diff --git a/desktop/packages/nseventforwarder/crates/nseventforwarder/Cargo.toml b/desktop/packages/nseventforwarder/crates/nseventforwarder/Cargo.toml new file mode 100644 index 000000000000..2243cbeae689 --- /dev/null +++ b/desktop/packages/nseventforwarder/crates/nseventforwarder/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "nseventforwarder" +version = "0.1.0" +license = "GPL-3.0" +edition = "2021" +exclude = ["index.node"] + +[lib] +crate-type = ["cdylib"] + +[target.'cfg(target_os = "macos")'.dependencies] +neon = "1" +block2 = "0.5.1" +objc2-app-kit = { version = "0.2.2", features = ["NSEvent", "block2"] } diff --git a/desktop/packages/nseventforwarder/crates/nseventforwarder/src/lib.rs b/desktop/packages/nseventforwarder/crates/nseventforwarder/src/lib.rs new file mode 100644 index 000000000000..c07fac279c1d --- /dev/null +++ b/desktop/packages/nseventforwarder/crates/nseventforwarder/src/lib.rs @@ -0,0 +1,113 @@ +//! Forward [NSEvent]s from macOS to node. +#![cfg(target_os = "macos")] +#![warn(clippy::undocumented_unsafe_blocks)] + +use std::sync::{mpsc, Arc, Mutex}; +use std::thread::JoinHandle; + +use block2::RcBlock; +use neon::prelude::{ + Context, FunctionContext, Handle, JsFunction, JsNull, JsResult, JsUndefined, ModuleContext, + NeonResult, Object, Root, +}; +use neon::result::Throw; +use objc2_app_kit::{NSEvent, NSEventMask}; + +#[neon::main] +fn main(mut cx: ModuleContext) -> NeonResult<()> { + cx.export_function("start", start)?; + Ok(()) +} + +/// NSEventForwarder instance. It must be initialized by `start` and cleaned up by the callback +/// function returned from `start`. +static NSEVENTFORWARDER: Mutex> = Mutex::new(None); + +struct NSEventForwarder { + /// The thread listening for incoming [NSEvent]s. + thread: JoinHandle<()>, + /// Signal for the current execution context to stop. + stop: mpsc::Sender<()>, +} + +impl NSEventForwarder { + fn stop(self) { + // Tell the thread to stop running + let _ = self.stop.send(()); + // Wait for the thread to shutdown + self.thread + .join() + .expect("Couldn't join the NSEventForwarder thread"); + } +} + +/// Register a callback to fire every time a [NSEventMask::LeftMouseDown] or [NSEventMask::RightMouseDown] event occur. +/// +/// Returns a stop function to call when the original callback shouldn't be called anymore. +fn start(mut cx: FunctionContext) -> JsResult { + // Set up neon stuff + let callback = cx.argument::(0)?.root(&mut cx); + let callback: Arc> = Arc::new(callback); + let channel = cx.channel(); + + // Start a long-running thread which handles incoming NS events + // When a new event is received, call the callback passed to us from the JavaScript caller + let (stop_tx, stop_rx) = mpsc::channel(); + let join_handle = std::thread::spawn(move || { + // Scaffolding for calling the JavaScript callback function + let call_callback = move || { + let cb = Arc::clone(&callback); + channel.send(move |mut cx| { + let this = JsNull::new(&mut cx); + let _ = cb.to_inner(&mut cx).call(&mut cx, this, []); + Ok(()) + }) + }; + // Start monitoring incoming NS events + let block = RcBlock::new(move |_event| { + call_callback(); + }); + // SAFETY: This function is trivially safe to call. + // Note: Make sure to cancel this handler with [NSEvent::removeMonitor] to unregister the + // listener. + let mut handler = unsafe { + NSEvent::addGlobalMonitorForEventsMatchingMask_handler( + NSEventMask::LeftMouseDown | NSEventMask::RightMouseDown, + &block, + ) + }; + + // Listen for stop signal + let _ = stop_rx.recv(); + if let Some(handler) = handler.take() { + // SAFETY: handler is removed only once. + // See https://developer.apple.com/documentation/appkit/nsevent/1533709-removemonitor#discussion + unsafe { NSEvent::removeMonitor(&handler) } + } + // The thread's execution will stop when this function returns + }); + + let new_context = NSEventForwarder { + thread: join_handle, + stop: stop_tx, + }; + + // Update the global NSEventForwarder state + let mut nseventmonitor_context = NSEVENTFORWARDER.lock().unwrap(); + // Stop any old NSEventForwarder + if let Some(context) = nseventmonitor_context.take() { + context.stop(); + } + let _ = nseventmonitor_context.insert(new_context); + drop(nseventmonitor_context); + + JsFunction::new(&mut cx, stop) +} + +fn stop(mut cx: FunctionContext<'_>) -> Result, Throw> { + if let Some(context) = NSEVENTFORWARDER.lock().unwrap().take() { + context.stop(); + } + + Ok(JsUndefined::new(&mut cx)) +} diff --git a/desktop/packages/nseventforwarder/eslint.config.mjs b/desktop/packages/nseventforwarder/eslint.config.mjs new file mode 100644 index 000000000000..9e16ad57ea10 --- /dev/null +++ b/desktop/packages/nseventforwarder/eslint.config.mjs @@ -0,0 +1,3 @@ +import workspaceConfig from '../../eslint.config.mjs'; + +export default [...workspaceConfig, { ignores: ['lib/'] }]; diff --git a/desktop/packages/nseventforwarder/package.json b/desktop/packages/nseventforwarder/package.json new file mode 100644 index 000000000000..1cd99857479e --- /dev/null +++ b/desktop/packages/nseventforwarder/package.json @@ -0,0 +1,41 @@ +{ + "name": "nseventforwarder", + "version": "0.0.0", + "author": "Mullvad VPN", + "license": "GPL-3.0", + "description": "", + "main": "./lib/index.cjs", + "scripts": { + "cargo-build": "tsc && cargo build", + "build-debug": "npm run cargo-build && cp target/debug/libnseventforwarder.dylib target/debug/index.node", + "build-arm": "bash ./build.sh --target aarch64-apple-darwin", + "build-x86": "bash ./build.sh --target x86_64-apple-darwin", + "lint": "eslint .", + "lint-fix": "eslint --fix ." + }, + "exports": { + ".": { + "import": { + "types": "./lib/index.d.mts", + "default": "./lib/index.mjs" + }, + "require": { + "types": "./lib/index.d.cts", + "default": "./lib/index.cjs" + } + } + }, + "types": "./lib/index.d.cts", + "files": [ + "lib/**/*.?({c,m}){t,j}s" + ], + "neon": { + "type": "library", + "org": "mullvad-vpn", + "platforms": "common", + "load": "./src/load.cts" + }, + "dependencies": { + "@neon-rs/load": "^0.1.73" + } +} diff --git a/desktop/packages/nseventforwarder/src/index.cts b/desktop/packages/nseventforwarder/src/index.cts new file mode 100644 index 000000000000..bee20624aeba --- /dev/null +++ b/desktop/packages/nseventforwarder/src/index.cts @@ -0,0 +1,14 @@ +// This module is the CJS entry point for the library. + +// The Rust addon. +import * as addon from './load.cjs'; + +// Use this declaration to assign types to the addon's exports, +// which otherwise by default are `any`. +declare module './load.cjs' { + function start(cb: () => void): () => void; +} + +export function start(cb: () => void): () => void { + return addon.start(cb); +} diff --git a/desktop/packages/nseventforwarder/src/index.mts b/desktop/packages/nseventforwarder/src/index.mts new file mode 100644 index 000000000000..5e1ab260f603 --- /dev/null +++ b/desktop/packages/nseventforwarder/src/index.mts @@ -0,0 +1,3 @@ +// This module is the ESM entry point for the library. + +export * from './index.cjs'; diff --git a/desktop/packages/nseventforwarder/src/load.cts b/desktop/packages/nseventforwarder/src/load.cts new file mode 100644 index 000000000000..c82a2a9e481e --- /dev/null +++ b/desktop/packages/nseventforwarder/src/load.cts @@ -0,0 +1,11 @@ +// This module loads the platform-specific build of the addon on +// the current system. + +/* eslint-disable @typescript-eslint/no-require-imports */ +module.exports = require('@neon-rs/load').proxy({ + platforms: { + 'darwin-x64': () => require('../dist/darwin-x64'), + 'darwin-arm64': () => require('../dist/darwin-arm64'), + }, + debug: () => require('../target/debug/index.node'), +}); diff --git a/desktop/packages/nseventforwarder/tsconfig.json b/desktop/packages/nseventforwarder/tsconfig.json new file mode 100644 index 000000000000..31e66037718c --- /dev/null +++ b/desktop/packages/nseventforwarder/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "node16", + "declaration": true, + "outDir": "lib" + }, + "exclude": ["lib"] +}