From 2790cbbbffd63d42cce9ba1fbeaeb0388203f818 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:11:00 -0800 Subject: [PATCH 01/18] docs: move the build docs in readme --- README.md | 278 +++++++++++++++++++++++++-------------------------- src/index.ts | 2 +- 2 files changed, 140 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index 8f193756..4d93fbd5 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,6 @@ - [Useful links](#useful-links) - [Table of contents](#table-of-contents) - [Installation](#installation) - - [Prebuilt binaries](#prebuilt-binaries) - - [Building from source](#building-from-source) - - [Available Build Options](#available-build-options) - - [Curve with Libsodium support](#curve-with-libsodium-support) - - [Draft support](#draft-support) - - [Websocket support](#websocket-support) - - [Secure Websocket support](#secure-websocket-support) - - [Not Synchronous Resolve](#not-synchronous-resolve) - - [MacOS Deployment Target](#macos-deployment-target) - [Examples](#examples) - [Basic Usage](#basic-usage) - [Push/Pull](#pushpull) @@ -50,6 +41,15 @@ - [`server.js`](#serverjs) - [Zeromq 4 and 5 Compatibility layer](#zeromq-4-and-5-compatibility-layer) - [TypeScript](#typescript) + - [Prebuilt binaries](#prebuilt-binaries) + - [Building from source](#building-from-source) + - [Available Build Options](#available-build-options) + - [Curve with Libsodium support](#curve-with-libsodium-support) + - [Draft support](#draft-support) + - [Websocket support](#websocket-support) + - [Secure Websocket support](#secure-websocket-support) + - [Not Synchronous Resolve](#not-synchronous-resolve) + - [MacOS Deployment Target](#macos-deployment-target) - [Contribution](#contribution) - [Dependencies](#dependencies) - [Defining new options](#defining-new-options) @@ -67,139 +67,12 @@ npm install zeromq Supported versions: -- Node.js v12 (requires a [N-API](https://nodejs.org/api/n-api.html)) - -### Prebuilt binaries - -The following platforms have a **prebuilt binary** available: - -- Windows on x86/x86-64 - - Zeromq binaries on Windows 10 or older need - [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version) - to be installed. - -- Linux on x86-64 with libstdc++.so.6.0.21+ (glibc++ 3.4.21+), for example: - - Debian 9+ (Stretch or later) - - Ubuntu 16.04+ (Xenial or later) - - CentOS 8+ -- Linux on x86-64 with musl, for example: - - Alpine 3.3+ -- MacOS 10.9+ on x86-64 - -If a prebuilt binary is not available for your platform, installing will attempt -to start a build from source. - -### Building from source - -If a prebuilt binary is unavailable, or if you want to pass certain options -during build, you can build this package from source. - -Make sure you have the following installed before attempting to build from -source: - -- Node.js 10+ or Electron -- C++17 compiler toolchain (e.g. LLVM, GCC, MSVC) -- Python 3 -- CMake 3.16+ -- vcpkg dependencies (e.g. on Linux it needs curl, unzip, zip, tar, git, - pkg-config) - -For Curve: - -- automake -- autoconf -- libtool - -To install from source, specify `build_from_source=true` in a `.npmrc` file - -``` -build_from_source=true -``` - -When building from source, you can also specify additional build options in a -`.npmrc` file in your project: - -### Available Build Options - -
-👉🏻 Options - -### Curve with Libsodium support - -(Enabled by default) - -Enables CURVE security for encrypted communications. Zeromq uses libsodium for -CURVE security. To enable CURVE support, add the following to your .npmrc: - -```ini -zmq_curve="true" -zmq_sodium="true" -``` - -Building libsodium requires these dependencies on Linux/MacOS: -`autoconf automake libtool`, which can be installed via `apt-get` or `brew`, -etc. - -#### Draft support - -(Enabled by default) - -By default `libzmq` is built with support for `Draft` patterns (e.g. -`server-client`, `radio-dish`, `scatter-gather`). If you want to build `libzmq` -without support for `Draft`, you can specify the following in `.npmrc`: - -```ini -zmq_draft=false -``` - -#### Websocket support - -Enables WebSocket transport, allowing ZeroMQ to communicate over WebSockets. To -enable WebSocket support, add the following to your .npmrc: - -```ini -zmq_websockets="true" -``` - -#### Secure Websocket support - -Enables WebSocket transport with TLS (wss), providing secure WebSocket -communications. To enable secure WebSocket support, add the following to your -.npmrc: - -```ini -zmq_websockets_secure="true" -``` - -#### Not Synchronous Resolve - -Enables immediate send/receive on the socket without synchronous resolution. -This option can improve performance in certain scenarios by allowing operations -to proceed without waiting for synchronous resolution. To enable this feature, -add the following to your `.npmrc`: - -```ini -zmq_no_sync_resolve="true" -``` - -#### MacOS Deployment Target - -Specifies the minimum macOS version that the binary will be compatible with. -This is particularly useful when building for different macOS versions. To set -this, add the following to your .npmrc, replacing 10.15 with your desired -minimum macOS version: - -```ini -macosx_deployment_target="10.15" -``` - -
+- Node.js v10+ (requires a [N-API](https://nodejs.org/api/n-api.html)) ## Examples Here some examples of different features are provided. More examples can be -found in the [examples directory](examples). +found in the [examples directory](https://github.com/zeromq/zeromq.js/tree/master/examples). You can also browse [the API reference documentation](http://zeromq.github.io/zeromq.js/globals.html) @@ -423,6 +296,133 @@ _Requirements_ include their corresponding polyfills if needed): `es2015`, `ESNext.AsyncIterable` +### Prebuilt binaries + +The following platforms have a **prebuilt binary** available: + +- Windows on x86/x86-64 + + Zeromq binaries on Windows 10 or older need + [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version) + to be installed. + +- Linux on x86-64 with libstdc++.so.6.0.21+ (glibc++ 3.4.21+), for example: + - Debian 9+ (Stretch or later) + - Ubuntu 16.04+ (Xenial or later) + - CentOS 8+ +- Linux on x86-64 with musl, for example: + - Alpine 3.3+ +- MacOS 10.9+ on x86-64 + +If a prebuilt binary is not available for your platform, installing will attempt +to start a build from source. + +### Building from source + +If a prebuilt binary is unavailable, or if you want to pass certain options +during build, you can build this package from source. + +Make sure you have the following installed before attempting to build from +source: + +- Node.js 10+ or Electron +- C++17 compiler toolchain (e.g. LLVM, GCC, MSVC) +- Python 3 +- CMake 3.16+ +- vcpkg dependencies (e.g. on Linux it needs curl, unzip, zip, tar, git, + pkg-config) + +For Curve: + +- automake +- autoconf +- libtool + +To install from source, specify `build_from_source=true` in a `.npmrc` file + +``` +build_from_source=true +``` + +When building from source, you can also specify additional build options in a +`.npmrc` file in your project: + +### Available Build Options + +
+👉🏻 Options + +### Curve with Libsodium support + +(Enabled by default) + +Enables CURVE security for encrypted communications. Zeromq uses libsodium for +CURVE security. To enable CURVE support, add the following to your .npmrc: + +```ini +zmq_curve="true" +zmq_sodium="true" +``` + +Building libsodium requires these dependencies on Linux/MacOS: +`autoconf automake libtool`, which can be installed via `apt-get` or `brew`, +etc. + +#### Draft support + +(Enabled by default) + +By default `libzmq` is built with support for `Draft` patterns (e.g. +`server-client`, `radio-dish`, `scatter-gather`). If you want to build `libzmq` +without support for `Draft`, you can specify the following in `.npmrc`: + +```ini +zmq_draft=false +``` + +#### Websocket support + +Enables WebSocket transport, allowing ZeroMQ to communicate over WebSockets. To +enable WebSocket support, add the following to your .npmrc: + +```ini +zmq_websockets="true" +``` + +#### Secure Websocket support + +Enables WebSocket transport with TLS (wss), providing secure WebSocket +communications. To enable secure WebSocket support, add the following to your +.npmrc: + +```ini +zmq_websockets_secure="true" +``` + +#### Not Synchronous Resolve + +Enables immediate send/receive on the socket without synchronous resolution. +This option can improve performance in certain scenarios by allowing operations +to proceed without waiting for synchronous resolution. To enable this feature, +add the following to your `.npmrc`: + +```ini +zmq_no_sync_resolve="true" +``` + +#### MacOS Deployment Target + +Specifies the minimum macOS version that the binary will be compatible with. +This is particularly useful when building for different macOS versions. To set +this, add the following to your .npmrc, replacing 10.15 with your desired +minimum macOS version: + +```ini +macosx_deployment_target="10.15" +``` + +
+ ## Contribution If you are interested in making contributions to this project, please read the @@ -520,4 +520,4 @@ first outlined in [this issue](https://github.com/zeromq/zeromq.js/issues/189). Previous versions of ZeroMQ.js were based on `zmq` and a fork that included prebuilt binaries. -See detailed changes in the [CHANGELOG](CHANGELOG.md). +See detailed changes in the [CHANGELOG](https://github.com/zeromq/zeromq.js/releases). diff --git a/src/index.ts b/src/index.ts index 548f7a41..c6136289 100644 --- a/src/index.ts +++ b/src/index.ts @@ -158,7 +158,7 @@ export interface Writable< * * * If you wish to send on a socket and **messages should be queued before * they are dropped**, you should implement a [simple - * queue](examples/queue/queue.ts) in JavaScript. Such a queue is not + * queue](../examples/queue/queue.ts) in JavaScript. Such a queue is not * provided by this library because most real world applications need to * deal with undeliverable messages in more complex ways - for example, they * might need to reply with a status message; or first retry delivery a From 423b7fe1c5cfc3bf797bf488785580e707943d07 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:18:34 -0800 Subject: [PATCH 02/18] fix: fix the queue example --- README.md | 6 +- examples/pnpm-lock.yaml | 1159 +++++++++++++++++++++++++++++++++++++++ examples/queue/index.ts | 8 +- examples/queue/queue.ts | 17 +- pnpm-lock.yaml | 38 +- 5 files changed, 1195 insertions(+), 33 deletions(-) create mode 100644 examples/pnpm-lock.yaml diff --git a/README.md b/README.md index 4d93fbd5..a72fff81 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ Supported versions: ## Examples Here some examples of different features are provided. More examples can be -found in the [examples directory](https://github.com/zeromq/zeromq.js/tree/master/examples). +found in the +[examples directory](https://github.com/zeromq/zeromq.js/tree/master/examples). You can also browse [the API reference documentation](http://zeromq.github.io/zeromq.js/globals.html) @@ -520,4 +521,5 @@ first outlined in [this issue](https://github.com/zeromq/zeromq.js/issues/189). Previous versions of ZeroMQ.js were based on `zmq` and a fork that included prebuilt binaries. -See detailed changes in the [CHANGELOG](https://github.com/zeromq/zeromq.js/releases). +See detailed changes in the +[CHANGELOG](https://github.com/zeromq/zeromq.js/releases). diff --git a/examples/pnpm-lock.yaml b/examples/pnpm-lock.yaml new file mode 100644 index 00000000..fc10d6d7 --- /dev/null +++ b/examples/pnpm-lock.yaml @@ -0,0 +1,1159 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + zeromq: + specifier: file:.. + version: file:.. + devDependencies: + ts-node: + specifier: '>= 0' + version: 10.9.2(@types/node@22.10.5)(typescript@5.7.2) + +packages: + + '@aminya/cmake-ts@0.3.0-aminya.7': + resolution: {integrity: sha512-y6a2Nq1Pj+3Y0tOLob2q0LbCB4cGIbcXJqDO10W51XpqUdB30OU0Xvl6ZDHFluHm/8nY5Vx/Ua9mxobG975//Q==} + hasBin: true + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@cypress/request@3.0.7': + resolution: {integrity: sha512-LzxlLEMbBOPYB85uXrDqvD4MgcenjRBLIns3zyhx7vTPj/0u2eQhzXvPiGcaJrV38Q9dbkExWp6cOHPJ+EtFYg==} + engines: {node: '>= 6'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/node@22.10.5': + resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.18.0: + resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-signature@1.4.0: + resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} + engines: {node: '>=0.10'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + memory-stream@1.0.0: + resolution: {integrity: sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + node-addon-api@8.3.0: + resolution: {integrity: sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==} + engines: {node: ^18 || ^20 || >= 21} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + qs@6.13.1: + resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + splitargs2@0.1.3: + resolution: {integrity: sha512-7Lt7+Z0YwyhFCbhkXMI3AT5qLcH6rKZgWnmlk0+R4ObjqhTZ3kGB4VMTerMuTmMayJnAuDHYTSomAYtlYq0vbg==} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tldts-core@6.1.70: + resolution: {integrity: sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==} + + tldts@6.1.70: + resolution: {integrity: sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@5.0.0: + resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} + engines: {node: '>=16'} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unzipper@0.12.3: + resolution: {integrity: sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==} + + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + zeromq@file:..: + resolution: {directory: .., type: directory} + engines: {node: '>= 10', pnpm: '>= 9'} + +snapshots: + + '@aminya/cmake-ts@0.3.0-aminya.7': + dependencies: + '@cypress/request': 3.0.7 + fast-glob: 3.3.3 + fs-extra: 10.1.0 + lodash: 4.17.21 + memory-stream: 1.0.0 + minizlib: 2.1.2 + npmlog: 6.0.2 + resolve: 1.22.10 + semver: 7.6.3 + splitargs2: 0.1.3 + tar: 6.2.1 + unzipper: 0.12.3 + url-join: 4.0.1 + which: 2.0.2 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@cypress/request@3.0.7': + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 4.0.1 + http-signature: 1.4.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + performance-now: 2.1.0 + qs: 6.13.1 + safe-buffer: 5.2.1 + tough-cookie: 5.0.0 + tunnel-agent: 0.6.0 + uuid: 8.3.2 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.18.0 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/node@22.10.5': + dependencies: + undici-types: 6.20.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.0 + + acorn@8.14.0: {} + + ansi-regex@5.0.1: {} + + aproba@2.0.0: {} + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + arg@4.1.3: {} + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + + asynckit@0.4.0: {} + + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bluebird@3.7.2: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + call-bind-apply-helpers@1.0.1: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.7 + + caseless@0.12.0: {} + + chownr@2.0.0: {} + + color-support@1.1.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + console-control-strings@1.1.0: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + create-require@1.1.1: {} + + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + + diff@4.0.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + emoji-regex@8.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + extend@3.0.2: {} + + extsprintf@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.18.0: + dependencies: + reusify: 1.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + forever-agent@0.6.1: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + function-bind@1.1.2: {} + + gauge@4.0.4: + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + get-intrinsic@1.2.7: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.0.0 + + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + has-symbols@1.1.0: {} + + has-unicode@2.0.1: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-signature@1.4.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 2.0.2 + sshpk: 1.18.0 + + inherits@2.0.4: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-typedarray@1.0.0: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isstream@0.1.2: {} + + jsbn@0.1.1: {} + + json-schema@0.4.0: {} + + json-stringify-safe@5.0.1: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsprim@2.0.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + lodash@4.17.21: {} + + make-error@1.3.6: {} + + math-intrinsics@1.1.0: {} + + memory-stream@1.0.0: + dependencies: + readable-stream: 3.6.2 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + node-addon-api@8.3.0: {} + + node-int64@0.4.0: {} + + npmlog@6.0.2: + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + + object-inspect@1.13.3: {} + + path-parse@1.0.7: {} + + performance-now@2.1.0: {} + + picomatch@2.3.1: {} + + process-nextick-args@2.0.1: {} + + qs@6.13.1: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + semver@7.6.3: {} + + set-blocking@2.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + splitargs2@0.1.3: {} + + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + supports-preserve-symlinks-flag@1.0.0: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tldts-core@6.1.70: {} + + tldts@6.1.70: + dependencies: + tldts-core: 6.1.70 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tough-cookie@5.0.0: + dependencies: + tldts: 6.1.70 + + ts-node@10.9.2(@types/node@22.10.5)(typescript@5.7.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.10.5 + acorn: 8.14.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.7.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl@0.14.5: {} + + typescript@5.7.2: {} + + undici-types@6.20.0: {} + + universalify@2.0.1: {} + + unzipper@0.12.3: + dependencies: + bluebird: 3.7.2 + duplexer2: 0.1.4 + fs-extra: 11.2.0 + graceful-fs: 4.2.11 + node-int64: 0.4.0 + + url-join@4.0.1: {} + + util-deprecate@1.0.2: {} + + uuid@8.3.2: {} + + v8-compile-cache-lib@3.0.1: {} + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + yallist@4.0.0: {} + + yn@3.1.1: {} + + zeromq@file:..: + dependencies: + '@aminya/cmake-ts': 0.3.0-aminya.7 + node-addon-api: 8.3.0 diff --git a/examples/queue/index.ts b/examples/queue/index.ts index 64b69976..d3e55c3b 100644 --- a/examples/queue/index.ts +++ b/examples/queue/index.ts @@ -1,15 +1,15 @@ import {Dealer} from "zeromq" -import {Queue} from "./queue" +import {Queue} from "./queue.js" async function main() { const sender = new Dealer() await sender.bind("tcp://127.0.0.1:5555") const queue = new Queue(sender) - queue.send("hello") - queue.send("world!") - queue.send(null) + await queue.send("hello") + await queue.send("world!") + await queue.send(null) const receiver = new Dealer() receiver.connect("tcp://127.0.0.1:5555") diff --git a/examples/queue/queue.ts b/examples/queue/queue.ts index d5a2fe0a..30f5d148 100644 --- a/examples/queue/queue.ts +++ b/examples/queue/queue.ts @@ -1,22 +1,22 @@ -import {Socket} from "zeromq" +import {Dealer, type MessageLike} from "zeromq" export class Queue { - queue: any[] = [] - socket: Socket + queue: MessageLike[] = [] + socket: Dealer max: number sending = false - constructor(socket: Socket, max = 100) { + constructor(socket: Dealer, max = 100) { this.socket = socket this.max = max } - send(msg: any) { + send(msg: MessageLike) { if (this.queue.length > this.max) { throw new Error("Queue is full") } this.queue.push(msg) - this.trySend() + return this.trySend() } async trySend() { @@ -25,8 +25,9 @@ export class Queue { } this.sending = true - while (this.queue.length) { - await this.socket.send(this.queue.shift()) + while (this.queue.length > 0) { + const firstMessage = this.queue.shift()! + await this.socket.send(firstMessage) } this.sending = false diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64728bea..6fd97011 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -281,8 +281,8 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@gerrit0/mini-shiki@1.24.4': - resolution: {integrity: sha512-YEHW1QeAg6UmxEmswiQbOVEg1CW22b1XUD/lNTliOsu0LD0wqoyleFMnmbTp697QE0pcadQiR5cVtbbAPncvpw==} + '@gerrit0/mini-shiki@1.26.1': + resolution: {integrity: sha512-gHFUvv9f1fU2Piou/5Y7Sx5moYxcERbC7CXc6rkDLQTUBg5Dgg9L4u29/nHqfoQ3Y9R0h0BcOhd14uOEZIBP7Q==} '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} @@ -354,14 +354,14 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@shikijs/engine-oniguruma@1.24.4': - resolution: {integrity: sha512-Do2ry6flp2HWdvpj2XOwwa0ljZBRy15HKZITzPcNIBOGSeprnA8gOooA/bLsSPuy8aJBa+Q/r34dMmC3KNL/zw==} + '@shikijs/engine-oniguruma@1.26.1': + resolution: {integrity: sha512-F5XuxN1HljLuvfXv7d+mlTkV7XukC1cawdtOo+7pKgPD83CAB1Sf8uHqP3PK0u7njFH0ZhoXE1r+0JzEgAQ+kg==} - '@shikijs/types@1.24.4': - resolution: {integrity: sha512-0r0XU7Eaow0PuDxuWC1bVqmWCgm3XqizIaT7SM42K03vc69LGooT0U8ccSR44xP/hGlNx4FKhtYpV+BU6aaKAA==} + '@shikijs/types@1.26.1': + resolution: {integrity: sha512-d4B00TKKAMaHuFYgRf3L0gwtvqpW4hVdVwKcZYbBfAAQXspgkbWqnFfuFl3MDH6gLbsubOcr+prcnsqah3ny7Q==} - '@shikijs/vscode-textmate@9.3.1': - resolution: {integrity: sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==} + '@shikijs/vscode-textmate@10.0.1': + resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==} '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} @@ -3826,11 +3826,11 @@ snapshots: '@eslint/js@8.57.1': {} - '@gerrit0/mini-shiki@1.24.4': + '@gerrit0/mini-shiki@1.26.1': dependencies: - '@shikijs/engine-oniguruma': 1.24.4 - '@shikijs/types': 1.24.4 - '@shikijs/vscode-textmate': 9.3.1 + '@shikijs/engine-oniguruma': 1.26.1 + '@shikijs/types': 1.26.1 + '@shikijs/vscode-textmate': 10.0.1 '@humanwhocodes/config-array@0.13.0': dependencies: @@ -3905,17 +3905,17 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} - '@shikijs/engine-oniguruma@1.24.4': + '@shikijs/engine-oniguruma@1.26.1': dependencies: - '@shikijs/types': 1.24.4 - '@shikijs/vscode-textmate': 9.3.1 + '@shikijs/types': 1.26.1 + '@shikijs/vscode-textmate': 10.0.1 - '@shikijs/types@1.24.4': + '@shikijs/types@1.26.1': dependencies: - '@shikijs/vscode-textmate': 9.3.1 + '@shikijs/vscode-textmate': 10.0.1 '@types/hast': 3.0.4 - '@shikijs/vscode-textmate@9.3.1': {} + '@shikijs/vscode-textmate@10.0.1': {} '@sindresorhus/is@4.6.0': {} @@ -7447,7 +7447,7 @@ snapshots: typedoc@0.27.6(typescript@4.9.5): dependencies: - '@gerrit0/mini-shiki': 1.24.4 + '@gerrit0/mini-shiki': 1.26.1 lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 From a0199a61b325e2f147eae61d8b0eab31569c1a3c Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:19:26 -0800 Subject: [PATCH 03/18] docs: fix the typeParams in the docs --- src/index.ts | 8 ++++---- src/native.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index c6136289..dd6b4f77 100644 --- a/src/index.ts +++ b/src/index.ts @@ -51,8 +51,8 @@ export type MessageLike = /** * Describes sockets that can send messages. * - * @typeparam M The type of the message or message parts that can be sent. - * @typeparam O Rest type for any options, if applicable to the socket type + * @typeParam M The type of the message or message parts that can be sent. + * @typeParam O Rest type for any options, if applicable to the socket type * (DRAFT only). */ export interface Writable< @@ -176,7 +176,7 @@ type ReceiveType = T extends {receive(): Promise} ? U : never /** * Describes sockets that can receive messages. * - * @typeparam M The type of the message or message parts that can be read. + * @typeParam M The type of the message or message parts that can be read. */ export interface Readable { /** @@ -269,7 +269,7 @@ export interface Readable { * socket type, for example `new Dealer({...})`. Readonly options * for the particular socket will be omitted. * - * @typeparam S The socket type to which the options should be applied. + * @typeParam S The socket type to which the options should be applied. */ export type SocketOptions = Options diff --git a/src/native.ts b/src/native.ts index 83410733..1735870e 100644 --- a/src/native.ts +++ b/src/native.ts @@ -279,7 +279,7 @@ export type EventType = Event["type"] * Represents the event data object given one particular event type, for example * `EventOfType<"accept">`. * - * @typeparam E The specific event type. + * @typeParam E The specific event type. */ export type EventOfType = Expand< Extract> @@ -365,8 +365,8 @@ export declare class Observer { * [Review the ØMQ documentation](http://api.zeromq.org/4-3:zmq-proxy#toc3) for * an overview of some example applications of a proxy. * - * @typeparam F The front-end socket type. - * @typeparam B The back-end socket type. + * @typeParam F The front-end socket type. + * @typeParam B The back-end socket type. */ export declare class Proxy< F extends Socket = Socket, From 367777cb1eb120477d73a8139c8db95030280066 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:22:53 -0800 Subject: [PATCH 04/18] docs: remove unknown writeonly/windows specifiers --- src/index.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index dd6b4f77..c376c8b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -446,8 +446,6 @@ declare module "./native" { * chosen scheduling policy. Details can be found at * http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html. This * option only applies before creating any sockets on the context. - * - * @writeonly */ threadPriority: number @@ -458,8 +456,6 @@ declare module "./native" { * available on Windows. Supported values for this option can be found at * http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html. This * option only applies before creating any sockets on the context. - * - * @writeonly */ threadSchedulingPolicy: number @@ -874,7 +870,6 @@ declare module "./native" { * enable this option to reduce the latency and improve the performance of * loopback operations on a TCP socket on Windows. * - * @windows */ loopbackFastPath: boolean @@ -1160,8 +1155,6 @@ export class Request extends Socket { * * *Warning:** Do not set this option on a socket that talks to any other * socket type except {@link Router}: the results are undefined. - * - * @writeonly */ probeRouter: boolean @@ -1259,8 +1252,6 @@ export class Dealer extends Socket { * * *Warning:** Do not set this option on a socket that talks to any other * socket type except {@link Router}: the results are undefined. - * - * @writeonly */ probeRouter: boolean @@ -1337,8 +1328,6 @@ export class Router extends Socket { * * *Warning:** Do not set this option on a socket that talks to any other * socket type except {@link Router}: the results are undefined. - * - * @writeonly */ probeRouter: boolean From 7bc2e1d179c608f687f9b8fe7072487568ebd9e9 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:47:49 -0800 Subject: [PATCH 05/18] docs: add docs for event/utility types --- .gitignore | 2 +- package.json | 2 +- src/errors.ts | 6 +++ src/native.ts | 118 +++++++++++++++++++++++++++++++++++++------------- src/util.ts | 2 + typedoc.json | 2 - 6 files changed, 99 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 7b3bcd27..6ccdbbf8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /build -/docs +/docs* /lib /tmp node_modules diff --git a/package.json b/package.json index 1d7ea9b0..106e3223 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "clean.temp": "rimraf ./tmp && shx mkdir -p ./tmp", "build.js": "run-s clean.lib && tsc -p ./src/tsconfig.json && run-s build.downlevel", "build.downlevel": "downlevel-dts ./lib ./lib/ts3.7", - "build.doc": "typedoc --options ./typedoc.json && minify-all -s docs-unminified -d docs --jsCompressor terser && rimraf docs-unminified", + "build.doc": "rimraf docs && typedoc --options ./typedoc.json && minify-all -s docs-unminified -d docs --jsCompressor terser && rimraf docs-unminified", "deploy.doc": "run-s build.doc && gh-pages --dist \"./docs\"", "build.native": "cmake-ts nativeonly", "build.native.debug": "cross-env npm_config_zmq_enable_sanitizer_undefined=true cmake-ts dev-os-only", diff --git a/src/errors.ts b/src/errors.ts index de2768e1..c5601341 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,9 +1,15 @@ +/** + * @internal + */ export interface FullError extends Error { code?: string errno?: number address?: string } +/** + * @internal + */ export function isFullError(err: unknown): err is FullError { return err instanceof Error } diff --git a/src/native.ts b/src/native.ts index 1735870e..9da52960 100644 --- a/src/native.ts +++ b/src/native.ts @@ -43,11 +43,11 @@ export declare const capability: Partial<{ * To correctly connect two sockets with this mechanism: * * * Generate a **client** keypair with {@link curveKeyPair}(). - * * Assign the private and public key on the client socket with + * - Assign the private and public key on the client socket with * {@link Socket.curveSecretKey} and {@link Socket.curvePublicKey}. * * Generate a **server** keypair with {@link curveKeyPair}(). - * * Assign the private key on the server socket with {@link Socket.curveSecretKey}. - * * Assign the public key **on the client socket** with + * - Assign the private key on the server socket with {@link Socket.curveSecretKey}. + * - Assign the public key **on the client socket** with * {@link Socket.curveServerKey}. The server does *not* need to know its own * public key. Key distribution is *not* handled by the CURVE security * mechanism. @@ -112,15 +112,24 @@ export declare class Context { */ export declare const context: Context -interface ErrnoError extends Error { +/** + * An error that represents a generic error with an associated error code. + */ +export interface ErrnoError extends Error { code: string errno: number } +/** + * An event that represents an authorization error. + */ export interface AuthError extends Error { status: 300 | 400 | 500 } +/** + * An event that represents a protocol error. + */ export interface ProtoError extends Error { code: | "ERR_ZMTP_UNSPECIFIED" @@ -145,18 +154,39 @@ export interface ProtoError extends Error { | "ERR_ZAP_INVALID_METADATA" } +/** + * An object that contains the address of an event. + */ export interface EventAddress { address: string } +/** + * An object that contains the interval for an event. + */ export interface EventInterval { interval: number } +/** + * An object that contains an error for an event. + */ export interface EventError { error: E } +/** + * Represents a ZeroMQ event type. + * @typeParam T The event type (e.g., "bind", "connect", "close", etc.), which is stored in the `type` property. + * @typeParam D The base event data type (which is unified by the type). + * + * @example + * ```typescript + * type AllEvents = EventFor<"bind", { address: string }> + * // is equivalent to + * type AllEvents = { type: "bind", address: string } + * ``` + */ export type EventFor = Expand<{type: T} & D> /** @@ -176,78 +206,78 @@ export type EventFor = Expand<{type: T} & D> * errors) that correspond to a specific operation are namespaced with a colon * `:`, e.g. `bind:error` or `connect:retry`. * - * * **accept** - ZMQ_EVENT_ACCEPTED The socket has accepted a connection from a + * - **accept** - ZMQ_EVENT_ACCEPTED The socket has accepted a connection from a * remote peer. * - * * **accept:error** - ZMQ_EVENT_ACCEPT_FAILED The socket has rejected a + * - **accept:error** - ZMQ_EVENT_ACCEPT_FAILED The socket has rejected a * connection from a remote peer. * * The following additional details will be included with this event: * - * * `error` - An error object that describes the specific error + * - `error` - An error object that describes the specific error * that occurred. * - * * **bind** - ZMQ_EVENT_LISTENING The socket was successfully bound to a + * - **bind** - ZMQ_EVENT_LISTENING The socket was successfully bound to a * network interface. * - * * **bind:error** - ZMQ_EVENT_BIND_FAILED The socket could not bind to a given + * - **bind:error** - ZMQ_EVENT_BIND_FAILED The socket could not bind to a given * interface. * * The following additional details will be included with this event: * - * * `error` - An error object that describes the specific error + * - `error` - An error object that describes the specific error * that occurred. * - * * **connect** - ZMQ_EVENT_CONNECTED The socket has successfully connected to + * - **connect** - ZMQ_EVENT_CONNECTED The socket has successfully connected to * a remote peer. * - * * **connect:delay** - ZMQ_EVENT_CONNECT_DELAYED A connect request on the + * - **connect:delay** - ZMQ_EVENT_CONNECT_DELAYED A connect request on the * socket is pending. * - * * **connect:retry** - ZMQ_EVENT_CONNECT_RETRIED A connection attempt is being + * - **connect:retry** - ZMQ_EVENT_CONNECT_RETRIED A connection attempt is being * handled by reconnect timer. Note that the reconnect interval is * recalculated at each retry. * * The following additional details will be included with this event: * - * * `interval` - The current reconnect interval. + * - `interval` - The current reconnect interval. * - * * **close** - ZMQ_EVENT_CLOSED The socket was closed. + * - **close** - ZMQ_EVENT_CLOSED The socket was closed. * - * * **close:error** - ZMQ_EVENT_CLOSE_FAILED The socket close failed. Note that + * - **close:error** - ZMQ_EVENT_CLOSE_FAILED The socket close failed. Note that * this event occurs **only on IPC** transports.. * * The following additional details will be included with this event: * - * * `error` - An error object that describes the specific error + * - `error` - An error object that describes the specific error * that occurred. * - * * **disconnect** - ZMQ_EVENT_DISCONNECTED The socket was disconnected + * - **disconnect** - ZMQ_EVENT_DISCONNECTED The socket was disconnected * unexpectedly. * - * * **handshake** - ZMQ_EVENT_HANDSHAKE_SUCCEEDED The ZMTP security mechanism + * - **handshake** - ZMQ_EVENT_HANDSHAKE_SUCCEEDED The ZMTP security mechanism * handshake succeeded. NOTE: This event may still be in DRAFT statea and not * yet available in stable releases. * - * * **handshake:error:protocol** - ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL The ZMTP + * - **handshake:error:protocol** - ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL The ZMTP * security mechanism handshake failed due to some mechanism protocol error, * either between the ZMTP mechanism peers, or between the mechanism server * and the ZAP handler. This indicates a configuration or implementation error * in either peer resp. the ZAP handler. NOTE: This event may still be in * DRAFT state and not yet available in stable releases. * - * * **handshake:error:auth** - ZMQ_EVENT_HANDSHAKE_FAILED_AUTH The ZMTP + * - **handshake:error:auth** - ZMQ_EVENT_HANDSHAKE_FAILED_AUTH The ZMTP * security mechanism handshake failed due to an authentication failure. NOTE: * This event may still be in DRAFT state and not yet available in stable * releases. * - * * **handshake:error:other** - ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL + * - **handshake:error:other** - ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL * Unspecified error during handshake. NOTE: This event may still be in DRAFT * state and not yet available in stable releases. * - * * **end** - ZMQ_EVENT_MONITOR_STOPPED Monitoring on this socket ended. + * - **end** - ZMQ_EVENT_MONITOR_STOPPED Monitoring on this socket ended. * - * * **unknown** An event was generated by ZeroMQ that the Node.js library could + * - **unknown** An event was generated by ZeroMQ that the Node.js library could * not interpret. Please submit a pull request for new event types if they are * not yet included. */ @@ -321,9 +351,9 @@ export declare class Observer { close(): void /** - * Waits for the next event to become availeble on the observer. Reads an + * Waits for the next event to become available on the observer. Reads an * event immediately if possible. If no events are queued, it will wait - * asynchonously. The promise will be resolved with the next event when + * asynchronously. The promise will be resolved with the next event when * available. * * When reading events with {@link receive}() the observer may **not** be in @@ -593,7 +623,7 @@ export declare abstract class Socket { /** * Disconnects a previously connected socket from the given address and - * returns immediately. Disonnection will happen asynchronously in the + * returns immediately. Disconnection will happen asynchronously in the * background. * * ```typescript @@ -656,7 +686,12 @@ export const enum SocketType { type IfEquals = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? A : B -/* https://stackoverflow.com/questions/57683303 */ +/** + * Utility type that expands a type into its keys and values. + * + * https://stackoverflow.com/questions/57683303 + * @internal + */ export type Expand = T extends infer O ? {[K in keyof O]: O[K]} : never /** @internal */ @@ -664,11 +699,36 @@ export type ReadableKeys = { [P in keyof T]-?: T[P] extends Function ? never : P }[keyof T] -/** @internal */ +/** + * Get the writable keys of a type. + * @internal + */ export type WritableKeys = { [P in keyof T]-?: T[P] extends Function ? never : IfEquals<{[Q in P]: T[P]}, {-readonly [Q in P]: T[P]}, P> }[keyof T] +/** + * Utility type for defining options for a given type. + * It allows setting the writable properties of a type. + * + * @typeParam T The type to define options for. + * @typeParam E Additional optional properties. Defaults to an empty object. + * + * @example + * ```typescript + * interface Server { + * port: number + * readonly name: string + * } + * type ServerOptions = Options + * // is equivalent to: + * interface ServerOptions { + * port?: number + * debug?: boolean + * } + * ``` + * @internal + */ export type Options = Expand>>> diff --git a/src/util.ts b/src/util.ts index 2b9d8f6e..18e2d2a1 100644 --- a/src/util.ts +++ b/src/util.ts @@ -6,6 +6,8 @@ type SocketMethods = "send" | "receive" | "join" | "leave" * to make the relevant socket types have only their relevant methods. * @param socketPrototype * @param methods + * + * @internal */ export function allowMethods(socketPrototype: any, methods: SocketMethods[]) { const toDelete = ["send", "receive", "join", "leave"] as SocketMethods[] diff --git a/typedoc.json b/typedoc.json index 195d096c..3828785a 100644 --- a/typedoc.json +++ b/typedoc.json @@ -10,8 +10,6 @@ "script/**/*", "test/**/*", "examples/**/*", - "src/errors.ts", - "src/util.ts", "build/**/*" ], "cleanOutputDir": true, From 703f1e14932e93475208b16f2cb1bb61426c6ab7 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:51:13 -0800 Subject: [PATCH 06/18] docs: highlight ini in the docs --- README.md | 2 +- src/index.ts | 2 +- typedoc.json | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a72fff81..2d122c7e 100644 --- a/README.md +++ b/README.md @@ -341,7 +341,7 @@ For Curve: To install from source, specify `build_from_source=true` in a `.npmrc` file -``` +```ini build_from_source=true ``` diff --git a/src/index.ts b/src/index.ts index c376c8b5..a404273a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1060,7 +1060,7 @@ export class Subscriber extends Socket { } /** - * Establish a new message filter. Newly created {@link Subsriber} sockets + * Establish a new message filter. Newly created {@link Subscriber} sockets * will filtered out all incoming messages. Call this method to subscribe to * messages beginning with the given prefix. * diff --git a/typedoc.json b/typedoc.json index 3828785a..3050ac9c 100644 --- a/typedoc.json +++ b/typedoc.json @@ -12,6 +12,19 @@ "examples/**/*", "build/**/*" ], + "highlightLanguages": [ + "bash", + "console", + "css", + "html", + "javascript", + "json", + "jsonc", + "json5", + "tsx", + "typescript", + "ini" + ], "cleanOutputDir": true, "pretty": false, "githubPages": true From e6c8a4af426ba82681cbe859ce2c2da456890784 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 19:54:12 -0800 Subject: [PATCH 07/18] docs: export SocketType in the compat layer --- src/compat.ts | 24 ++++++++++-------------- src/native.ts | 3 +++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/compat.ts b/src/compat.ts index 7d6ce92c..17951e7f 100644 --- a/src/compat.ts +++ b/src/compat.ts @@ -57,7 +57,7 @@ const shortOptions = { connect_timeout: longOptions.ZMQ_CONNECT_TIMEOUT, } -class Context { +export class Context { static setMaxThreads(value: number) { zmq.context.ioThreads = value } @@ -79,7 +79,10 @@ class Context { } } -type SocketType = +/** + * All the socket types available in the compatibility layer + */ +export type SocketType = | "pair" | "req" | "rep" @@ -97,7 +100,7 @@ type SocketType = type Callback = (err?: Error) => void -class Socket extends EventEmitter { +export class Socket extends EventEmitter { [key: string]: any type: SocketType @@ -729,7 +732,7 @@ for (const key in shortOptions) { }) } -function createSocket(type: SocketType, options: {[key: string]: any} = {}) { +export function createSocket(type: SocketType, options: {[key: string]: any} = {}) { const sock = new Socket(type) for (const key in options) { if (options.hasOwnProperty(key)) { @@ -739,12 +742,12 @@ function createSocket(type: SocketType, options: {[key: string]: any} = {}) { return sock } -function curveKeypair() { +export function curveKeypair() { const {publicKey, secretKey} = zmq.curveKeyPair() return {public: publicKey, secret: secretKey} } -function proxy(frontend: Socket, backend: Socket, capture?: Socket) { +export function proxy(frontend: Socket, backend: Socket, capture?: Socket) { switch (`${frontend.type}/${backend.type}`) { case "push/pull": case "pull/push": @@ -790,17 +793,10 @@ function proxy(frontend: Socket, backend: Socket, capture?: Socket) { } } -const version = zmq.version +export const version = zmq.version export { - version, - Context, - Socket, - SocketType, createSocket as socket, - createSocket, - curveKeypair, - proxy, shortOptions as options, } diff --git a/src/native.ts b/src/native.ts index 9da52960..6d036632 100644 --- a/src/native.ts +++ b/src/native.ts @@ -656,6 +656,9 @@ export declare abstract class Socket { protected setStringOption(option: number, value: string | Buffer | null): void } +/** + * Socket types available for creating sockets. + */ export const enum SocketType { Pair = 0, Publisher = 1, From 8145d55837f230c8a680a8421294f8262e6053f5 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 20:06:00 -0800 Subject: [PATCH 08/18] docs: add plugins to improve documentation --- .github/workflows/docs.yml | 2 +- package.json | 10 +++++++-- pnpm-lock.yaml | 45 ++++++++++++++++++++++++++++++++++++++ typedoc.json | 6 ++++- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 53de9edb..2218e019 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -67,7 +67,7 @@ jobs: - name: Build Documentation run: | pnpm install - pnpm run build.doc + pnpm run docs.build - name: Deploy Documentation uses: Cecilapp/GitHub-Pages-deploy@v3 diff --git a/package.json b/package.json index 106e3223..e91cb787 100644 --- a/package.json +++ b/package.json @@ -54,9 +54,13 @@ "proper-lockfile": "^4.1.2", "rimraf": "^6.0.1", "semver": "^7.6.3", + "servor": "^4.0.2", "shx": "^0.3.4", "ts-node": "~10.9.2", "typedoc": "^0.27.6", + "typedoc-plugin-dt-links": "^1.1.6", + "typedoc-plugin-inline-sources": "^1.2.0", + "typedoc-plugin-mdn-links": "^4.0.7", "typescript": "~4.9.5", "which": "^5.0.0" }, @@ -95,8 +99,10 @@ "clean.temp": "rimraf ./tmp && shx mkdir -p ./tmp", "build.js": "run-s clean.lib && tsc -p ./src/tsconfig.json && run-s build.downlevel", "build.downlevel": "downlevel-dts ./lib ./lib/ts3.7", - "build.doc": "rimraf docs && typedoc --options ./typedoc.json && minify-all -s docs-unminified -d docs --jsCompressor terser && rimraf docs-unminified", - "deploy.doc": "run-s build.doc && gh-pages --dist \"./docs\"", + "docs.build": "rimraf docs && typedoc --options ./typedoc.json && minify-all -s docs-unminified -d docs --jsCompressor terser && rimraf docs-unminified", + "docs.preview": "servor --browse --reload docs", + "docs.dev": "run-s docs.build docs.preview", + "docs.deploy": "run-s docs.build && gh-pages --dist \"./docs\"", "build.native": "cmake-ts nativeonly", "build.native.debug": "cross-env npm_config_zmq_enable_sanitizer_undefined=true cmake-ts dev-os-only", "build": "run-p build.js build.native", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fd97011..0dce2957 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,6 +117,9 @@ importers: semver: specifier: ^7.6.3 version: 7.6.3 + servor: + specifier: ^4.0.2 + version: 4.0.2 shx: specifier: ^0.3.4 version: 0.3.4 @@ -126,6 +129,15 @@ importers: typedoc: specifier: ^0.27.6 version: 0.27.6(typescript@4.9.5) + typedoc-plugin-dt-links: + specifier: ^1.1.6 + version: 1.1.6(typedoc@0.27.6(typescript@4.9.5)) + typedoc-plugin-inline-sources: + specifier: ^1.2.0 + version: 1.2.0(typedoc@0.27.6(typescript@4.9.5)) + typedoc-plugin-mdn-links: + specifier: ^4.0.7 + version: 4.0.7(typedoc@0.27.6(typescript@4.9.5)) typescript: specifier: ~4.9.5 version: 4.9.5 @@ -3021,6 +3033,10 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + servor@4.0.2: + resolution: {integrity: sha512-MlmQ5Ntv4jDYUN060x/KEmN7emvIqKMZ9OkM+nY8Bf2+KkyLmGsTqWLyAN2cZr5oESAcH00UanUyyrlS1LRjFw==} + hasBin: true + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -3378,6 +3394,21 @@ packages: resolution: {integrity: sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==} engines: {node: '>= 0.4'} + typedoc-plugin-dt-links@1.1.6: + resolution: {integrity: sha512-1t4eH4m2nIPCaG2V2tg5MpfZskbpxUCABQK6nAMlaYvZniDohQ7EOXBiW3kDrsHNXaEIMV38nXAJgP3dfptJDg==} + peerDependencies: + typedoc: '>= 0.23.14 || 0.24.x || 0.25.x || 0.26.x || 0.27.x' + + typedoc-plugin-inline-sources@1.2.0: + resolution: {integrity: sha512-gCjief4B71vRJw25Lwl7J69DuxzDjjG6pvUUPmjxY3uePyzcFGiw4eqbq+tmIPLXlnKAQujmglX/G+ZDnLUzug==} + peerDependencies: + typedoc: 0.25.x || 0.26.x + + typedoc-plugin-mdn-links@4.0.7: + resolution: {integrity: sha512-S9nUdZShdu+8HyWygmxjqyYIviZVdL36OjPWvxuLVMrS21lqxnVYLqInPYHXalmvitVEqWmrJJk8Al0x6d8wEA==} + peerDependencies: + typedoc: 0.26.x || 0.27.x + typedoc@0.27.6: resolution: {integrity: sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==} engines: {node: '>= 18'} @@ -7027,6 +7058,8 @@ snapshots: dependencies: randombytes: 2.1.0 + servor@4.0.2: {} + set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -7445,6 +7478,18 @@ snapshots: typed-array-buffer: 1.0.2 typed-array-byte-offset: 1.0.2 + typedoc-plugin-dt-links@1.1.6(typedoc@0.27.6(typescript@4.9.5)): + dependencies: + typedoc: 0.27.6(typescript@4.9.5) + + typedoc-plugin-inline-sources@1.2.0(typedoc@0.27.6(typescript@4.9.5)): + dependencies: + typedoc: 0.27.6(typescript@4.9.5) + + typedoc-plugin-mdn-links@4.0.7(typedoc@0.27.6(typescript@4.9.5)): + dependencies: + typedoc: 0.27.6(typescript@4.9.5) + typedoc@0.27.6(typescript@4.9.5): dependencies: '@gerrit0/mini-shiki': 1.26.1 diff --git a/typedoc.json b/typedoc.json index 3050ac9c..15843eba 100644 --- a/typedoc.json +++ b/typedoc.json @@ -27,5 +27,9 @@ ], "cleanOutputDir": true, "pretty": false, - "githubPages": true + "githubPages": true, + "plugin": [ + "typedoc-plugin-dt-links", + "typedoc-plugin-mdn-links", + ] } From b095b7380b03a715c1c4a0e91a75de3f1b4a0e66 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 20:15:51 -0800 Subject: [PATCH 09/18] docs: include examples for the types in the docs --- examples/threaded-worker/processor.ts | 6 +++--- package.json | 1 + pnpm-lock.yaml | 12 ++++++++++++ src/compat.ts | 10 ++++++++++ src/index.ts | 15 +++++++++++++++ typedoc.json | 1 + 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/examples/threaded-worker/processor.ts b/examples/threaded-worker/processor.ts index 156218b8..e609fa86 100644 --- a/examples/threaded-worker/processor.ts +++ b/examples/threaded-worker/processor.ts @@ -10,8 +10,8 @@ export class Processor { output = new Pull() signal = new Publisher() - init: Promise - exit: Promise + init: Promise + exit: Promise constructor(threads: number = cpus().length) { console.log(`starting ${threads} worker threads`) @@ -22,7 +22,7 @@ export class Processor { this.input.bind("inproc://input"), this.output.bind("inproc://output"), this.signal.bind("inproc://signal"), - new Promise(resolve => { + new Promise(resolve => { setTimeout(resolve, 100) }), ]) diff --git a/package.json b/package.json index e91cb787..f9906821 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "ts-node": "~10.9.2", "typedoc": "^0.27.6", "typedoc-plugin-dt-links": "^1.1.6", + "typedoc-plugin-include-example": "^2.0.2", "typedoc-plugin-inline-sources": "^1.2.0", "typedoc-plugin-mdn-links": "^4.0.7", "typescript": "~4.9.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0dce2957..35d76d7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: typedoc-plugin-dt-links: specifier: ^1.1.6 version: 1.1.6(typedoc@0.27.6(typescript@4.9.5)) + typedoc-plugin-include-example: + specifier: ^2.0.2 + version: 2.0.2(typedoc@0.27.6(typescript@4.9.5)) typedoc-plugin-inline-sources: specifier: ^1.2.0 version: 1.2.0(typedoc@0.27.6(typescript@4.9.5)) @@ -3399,6 +3402,11 @@ packages: peerDependencies: typedoc: '>= 0.23.14 || 0.24.x || 0.25.x || 0.26.x || 0.27.x' + typedoc-plugin-include-example@2.0.2: + resolution: {integrity: sha512-5TTfmUR4dzz68K6RJMVQJ6db0MNK+86n0BFuxYeEJ1+MRV546pE7y+vdUfSjc7spVOZhzNp+vxH76+9bTmSHyQ==} + peerDependencies: + typedoc: 0.26.x || 0.27.x + typedoc-plugin-inline-sources@1.2.0: resolution: {integrity: sha512-gCjief4B71vRJw25Lwl7J69DuxzDjjG6pvUUPmjxY3uePyzcFGiw4eqbq+tmIPLXlnKAQujmglX/G+ZDnLUzug==} peerDependencies: @@ -7482,6 +7490,10 @@ snapshots: dependencies: typedoc: 0.27.6(typescript@4.9.5) + typedoc-plugin-include-example@2.0.2(typedoc@0.27.6(typescript@4.9.5)): + dependencies: + typedoc: 0.27.6(typescript@4.9.5) + typedoc-plugin-inline-sources@1.2.0(typedoc@0.27.6(typescript@4.9.5)): dependencies: typedoc: 0.27.6(typescript@4.9.5) diff --git a/src/compat.ts b/src/compat.ts index 17951e7f..3e6dd567 100644 --- a/src/compat.ts +++ b/src/compat.ts @@ -732,6 +732,16 @@ for (const key in shortOptions) { }) } +/** + * Create a new socket. + * + * @param type Type of socket to create. + * @param options Options for the socket. + * + * @returns A new socket. + * + * @includeExample examples/v5-compat/index.js + */ export function createSocket(type: SocketType, options: {[key: string]: any} = {}) { const sock = new Socket(type) for (const key in options) { diff --git a/src/index.ts b/src/index.ts index a404273a..99557317 100644 --- a/src/index.ts +++ b/src/index.ts @@ -982,6 +982,8 @@ allowMethods(Pair.prototype, ["send", "receive"]) * water mark for a connected {@link Subscriber}, then any messages that would * be sent to the subscriber in question shall instead be dropped until the mute * state ends. The {@link Writable.send}() method will never block. + * + * @includeExample examples/pub-sub/publisher.ts */ export class Publisher extends Socket { /** @@ -1030,6 +1032,8 @@ allowMethods(Publisher.prototype, ["send"]) * {@link Publisher}. Initially a {@link Subscriber} is not subscribed to any * messages. Use {@link Subscriber.subscribe}() to specify which messages to * subscribe to. This socket cannot send messages. + * + * @includeExample examples/pub-sub/subscriber.ts */ export class Subscriber extends Socket { /** @@ -1135,6 +1139,8 @@ allowMethods(Subscriber.prototype, ["receive"]) * If no services are available, then any send operation on the socket shall * block until at least one service becomes available. The REQ socket shall not * discard messages. + * + * @includeExample examples/req-rep/client.ts */ export class Request extends Socket { /** @@ -1201,6 +1207,8 @@ allowMethods(Request.prototype, ["send", "receive"]) * among all clients, and each reply sent is routed to the client that issued * the last request. If the original requester does not exist any more the reply * is silently discarded. + * + * @includeExample examples/req-rep/server.ts */ export class Reply extends Socket { /** @@ -1232,6 +1240,9 @@ allowMethods(Reply.prototype, ["send", "receive"]) * When a {@link Dealer} is connected to a {@link Reply} socket, each message * sent must consist of an empty message part, the delimiter, followed by one or * more body parts. + * + * @includeExample examples/queue/index.ts + * @includeExample examples/queue/queue.ts */ export class Dealer extends Socket { /** @@ -1375,6 +1386,8 @@ allowMethods(Router.prototype, ["send", "receive"]) * A {@link Pull} socket is used by a pipeline node to receive messages from * upstream pipeline nodes. Messages are fair-queued from among all connected * upstream nodes. This socket cannot send messages. + * + * @includeExample examples/push-pull/worker.ts */ export class Pull extends Socket { constructor(options?: SocketOptions) { @@ -1406,6 +1419,8 @@ allowMethods(Pull.prototype, ["receive"]) * at all, then {@link Writable.send}() will block until the mute state ends or * at least one downstream node becomes available for sending; messages are not * discarded. + * + * @includeExample examples/push-pull/producer.ts */ export class Push extends Socket { constructor(options?: SocketOptions) { diff --git a/typedoc.json b/typedoc.json index 15843eba..c3bf497e 100644 --- a/typedoc.json +++ b/typedoc.json @@ -31,5 +31,6 @@ "plugin": [ "typedoc-plugin-dt-links", "typedoc-plugin-mdn-links", + "typedoc-plugin-include-example" ] } From 38a6948c8561a914d9bd32e2c7bfef54b9f4a85f Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 21:30:59 -0800 Subject: [PATCH 10/18] docs: include non-exported types in the docs --- package.json | 1 + pnpm-lock.yaml | 12 ++++++++++++ src/compat.ts | 16 ++++++++-------- src/index.ts | 14 +++++++------- src/native.ts | 7 +++++-- src/util.ts | 2 +- typedoc.json | 10 +++------- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index f9906821..c57863f8 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "typedoc-plugin-include-example": "^2.0.2", "typedoc-plugin-inline-sources": "^1.2.0", "typedoc-plugin-mdn-links": "^4.0.7", + "typedoc-plugin-missing-exports": "^3.1.0", "typescript": "~4.9.5", "which": "^5.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 35d76d7c..552ae022 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -141,6 +141,9 @@ importers: typedoc-plugin-mdn-links: specifier: ^4.0.7 version: 4.0.7(typedoc@0.27.6(typescript@4.9.5)) + typedoc-plugin-missing-exports: + specifier: ^3.1.0 + version: 3.1.0(typedoc@0.27.6(typescript@4.9.5)) typescript: specifier: ~4.9.5 version: 4.9.5 @@ -3417,6 +3420,11 @@ packages: peerDependencies: typedoc: 0.26.x || 0.27.x + typedoc-plugin-missing-exports@3.1.0: + resolution: {integrity: sha512-Sogbaj+qDa21NjB3SlIw4JXSwmcl/WOjwiPNaVEcPhpNG/MiRTtpwV81cT7h1cbu9StpONFPbddYWR0KV/fTWA==} + peerDependencies: + typedoc: 0.26.x || 0.27.x + typedoc@0.27.6: resolution: {integrity: sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==} engines: {node: '>= 18'} @@ -7502,6 +7510,10 @@ snapshots: dependencies: typedoc: 0.27.6(typescript@4.9.5) + typedoc-plugin-missing-exports@3.1.0(typedoc@0.27.6(typescript@4.9.5)): + dependencies: + typedoc: 0.27.6(typescript@4.9.5) + typedoc@0.27.6(typescript@4.9.5): dependencies: '@gerrit0/mini-shiki': 1.26.1 diff --git a/src/compat.ts b/src/compat.ts index 3e6dd567..cfdf3a93 100644 --- a/src/compat.ts +++ b/src/compat.ts @@ -734,15 +734,18 @@ for (const key in shortOptions) { /** * Create a new socket. - * + * * @param type Type of socket to create. * @param options Options for the socket. - * + * * @returns A new socket. - * + * * @includeExample examples/v5-compat/index.js */ -export function createSocket(type: SocketType, options: {[key: string]: any} = {}) { +export function createSocket( + type: SocketType, + options: {[key: string]: any} = {}, +) { const sock = new Socket(type) for (const key in options) { if (options.hasOwnProperty(key)) { @@ -805,10 +808,7 @@ export function proxy(frontend: Socket, backend: Socket, capture?: Socket) { export const version = zmq.version -export { - createSocket as socket, - shortOptions as options, -} +export {createSocket as socket, shortOptions as options} export * from "./compat/long-options" export * from "./compat/types" diff --git a/src/index.ts b/src/index.ts index 99557317..0fb7379b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -982,7 +982,7 @@ allowMethods(Pair.prototype, ["send", "receive"]) * water mark for a connected {@link Subscriber}, then any messages that would * be sent to the subscriber in question shall instead be dropped until the mute * state ends. The {@link Writable.send}() method will never block. - * + * * @includeExample examples/pub-sub/publisher.ts */ export class Publisher extends Socket { @@ -1032,7 +1032,7 @@ allowMethods(Publisher.prototype, ["send"]) * {@link Publisher}. Initially a {@link Subscriber} is not subscribed to any * messages. Use {@link Subscriber.subscribe}() to specify which messages to * subscribe to. This socket cannot send messages. - * + * * @includeExample examples/pub-sub/subscriber.ts */ export class Subscriber extends Socket { @@ -1139,7 +1139,7 @@ allowMethods(Subscriber.prototype, ["receive"]) * If no services are available, then any send operation on the socket shall * block until at least one service becomes available. The REQ socket shall not * discard messages. - * + * * @includeExample examples/req-rep/client.ts */ export class Request extends Socket { @@ -1207,7 +1207,7 @@ allowMethods(Request.prototype, ["send", "receive"]) * among all clients, and each reply sent is routed to the client that issued * the last request. If the original requester does not exist any more the reply * is silently discarded. - * + * * @includeExample examples/req-rep/server.ts */ export class Reply extends Socket { @@ -1240,7 +1240,7 @@ allowMethods(Reply.prototype, ["send", "receive"]) * When a {@link Dealer} is connected to a {@link Reply} socket, each message * sent must consist of an empty message part, the delimiter, followed by one or * more body parts. - * + * * @includeExample examples/queue/index.ts * @includeExample examples/queue/queue.ts */ @@ -1386,7 +1386,7 @@ allowMethods(Router.prototype, ["send", "receive"]) * A {@link Pull} socket is used by a pipeline node to receive messages from * upstream pipeline nodes. Messages are fair-queued from among all connected * upstream nodes. This socket cannot send messages. - * + * * @includeExample examples/push-pull/worker.ts */ export class Pull extends Socket { @@ -1419,7 +1419,7 @@ allowMethods(Pull.prototype, ["receive"]) * at all, then {@link Writable.send}() will block until the mute state ends or * at least one downstream node becomes available for sending; messages are not * discarded. - * + * * @includeExample examples/push-pull/producer.ts */ export class Push extends Socket { diff --git a/src/native.ts b/src/native.ts index 6d036632..d56dce94 100644 --- a/src/native.ts +++ b/src/native.ts @@ -685,8 +685,11 @@ export const enum SocketType { /* Utility types. */ -/* https://stackoverflow.com/questions/49579094 */ -type IfEquals = +/** + * @internal + * https://stackoverflow.com/questions/49579094 + */ +export type IfEquals = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? A : B /** diff --git a/src/util.ts b/src/util.ts index 18e2d2a1..eb6c4b32 100644 --- a/src/util.ts +++ b/src/util.ts @@ -6,7 +6,7 @@ type SocketMethods = "send" | "receive" | "join" | "leave" * to make the relevant socket types have only their relevant methods. * @param socketPrototype * @param methods - * + * * @internal */ export function allowMethods(socketPrototype: any, methods: SocketMethods[]) { diff --git a/typedoc.json b/typedoc.json index c3bf497e..64d60da0 100644 --- a/typedoc.json +++ b/typedoc.json @@ -6,12 +6,7 @@ "out": "docs-unminified", "excludePrivate": true, "excludeExternals": false, - "exclude": [ - "script/**/*", - "test/**/*", - "examples/**/*", - "build/**/*" - ], + "exclude": ["script/**/*", "test/**/*", "examples/**/*", "build/**/*"], "highlightLanguages": [ "bash", "console", @@ -31,6 +26,7 @@ "plugin": [ "typedoc-plugin-dt-links", "typedoc-plugin-mdn-links", - "typedoc-plugin-include-example" + "typedoc-plugin-include-example", + "typedoc-plugin-missing-exports" ] } From 58438fa6876b8584403c11c4dfb49ae96f2039d3 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 21:39:54 -0800 Subject: [PATCH 11/18] fix: fix eslint errors for {} --- .eslintrc | 7 +------ package.json | 2 +- src/native.ts | 3 +++ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.eslintrc b/.eslintrc index 1254442e..2ccc83ea 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,15 +13,10 @@ "ignorePatterns": [ "node_modules/", "build/", - "lib/", + "lib/**/*", "tmp/", - "v5-compat.d.ts", - "draft.d.ts", - "script/*.js", - "script/*.d.ts", "docs/", "doc-unminified/", - "test/unit/compat/", "test/bench/" ] } diff --git a/package.json b/package.json index c57863f8..15ffdbf1 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "format": "run-s format.prettier format.clang-format", "format.prettier": "prettier -l --cache --cache-location ./.cache/prettier --write .", "format.clang-format": "clang-format -i -style=file ./src/*.cc ./src/*.h ./src/util/*.h", - "lint-test.eslint": "eslint ./**/*.{ts,tsx,js,jsx,cjs,mjs,json,yaml} --no-error-on-unmatched-pattern --cache --cache-location ./.cache/eslint/", + "lint-test.eslint": "eslint './**/*.{ts,tsx,js,jsx,cjs,mjs,json,yaml}' --no-error-on-unmatched-pattern --cache --cache-location ./.cache/eslint/", "lint.eslint": "pnpm run lint-test.eslint --fix", "lint.tsc": "tsc --noEmit -p ./src/tsconfig.json", "lint.tsc-test": "tsc --noEmit -p ./test/tsconfig.json", diff --git a/src/native.ts b/src/native.ts index d56dce94..d235a36d 100644 --- a/src/native.ts +++ b/src/native.ts @@ -187,6 +187,7 @@ export interface EventError { * type AllEvents = { type: "bind", address: string } * ``` */ +// eslint-disable-next-line @typescript-eslint/ban-types export type EventFor = Expand<{type: T} & D> /** @@ -530,6 +531,7 @@ export declare abstract class Socket { * @param type The socket type. * @param options Any options to set during construction. */ + // eslint-disable-next-line @typescript-eslint/ban-types protected constructor(type: SocketType, options?: {}) /** @@ -737,4 +739,5 @@ export type WritableKeys = { * ``` * @internal */ +// eslint-disable-next-line @typescript-eslint/ban-types export type Options = Expand>>> From f4526f6c244e4e26b6725b45d03c7fe7104fe28a Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:07:46 -0800 Subject: [PATCH 12/18] fix: fix the majordomo example --- examples/majordomo/README.md | 62 ++++++++++++++++++++---------------- examples/majordomo/broker.ts | 41 ++++++++++-------------- examples/majordomo/index.ts | 30 +++++++++++------ examples/majordomo/worker.ts | 42 +++++++++++------------- examples/package.json | 6 ++-- 5 files changed, 92 insertions(+), 89 deletions(-) diff --git a/examples/majordomo/README.md b/examples/majordomo/README.md index 05b47fdf..f6280f9f 100644 --- a/examples/majordomo/README.md +++ b/examples/majordomo/README.md @@ -6,12 +6,12 @@ not send or listen to heartbeats. ## Running this example -To run this example, install the example project depedencies and run the -majordomo example script with `yarn`: +To run this example, install the example project dependencies and run the +majordomo example script with `pnpm`: ``` -> yarn install -> yarn majordomo +> pnpm install +> pnpm run majordomo ``` ## Expected behaviour @@ -20,7 +20,13 @@ The example will start a broker and some workers, then do some requests. The output will be similar to this: ``` + starting broker on tcp://127.0.0.1:5555 +starting worker on tcp://127.0.0.1:5555 +starting worker on tcp://127.0.0.1:5555 +starting worker on tcp://127.0.0.1:5555 +---------- Started ----------- +requesting 'cola' from 'soda' requesting 'oolong' from 'tea' requesting 'sencha' from 'tea' requesting 'earl grey, with milk' from 'tea' @@ -29,33 +35,33 @@ requesting 'cappuccino' from 'coffee' requesting 'latte, with soy milk' from 'coffee' requesting 'espresso' from 'coffee' requesting 'irish coffee' from 'coffee' -registered worker 00800041af for 'coffee' -dispatching 'coffee' 00800041ab req -> 00800041af -registered worker 00800041b0 for 'tea' -dispatching 'tea' 00800041a7 req -> 00800041b0 -registered worker 00800041b1 for 'tea' -dispatching 'tea' 00800041a8 req -> 00800041b1 -dispatching 'tea' 00800041a7 <- rep 00800041b0 -dispatching 'tea' 00800041a9 req -> 00800041b0 -received 'oolong' from 'tea' -dispatching 'coffee' 00800041ab <- rep 00800041af -dispatching 'coffee' 00800041ac req -> 00800041af -received 'cappuccino' from 'coffee' -dispatching 'tea' 00800041a9 <- rep 00800041b0 -dispatching 'tea' 00800041aa req -> 00800041b0 -received 'earl grey, with milk' from 'tea' -dispatching 'tea' 00800041a8 <- rep 00800041b1 +registered worker 00800041a7 for 'tea' +registered worker 00800041a8 for 'coffee' +registered worker 00800041a9 for 'tea' +dispatching 'tea' 00800041ab req -> 00800041a7 +dispatching 'tea' 00800041ac req -> 00800041a9 +dispatching 'coffee' 00800041af req -> 00800041a8 +dispatching 'tea' 00800041ac <- rep 00800041a9 +dispatching 'tea' 00800041ad req -> 00800041a9 received 'sencha' from 'tea' -dispatching 'tea' 00800041aa <- rep 00800041b0 -received 'jasmine' from 'tea' -dispatching 'coffee' 00800041ac <- rep 00800041af -dispatching 'coffee' 00800041ad req -> 00800041af +dispatching 'tea' 00800041ad <- rep 00800041a9 +dispatching 'tea' 00800041ae req -> 00800041a9 +received 'earl grey, with milk' from 'tea' +dispatching 'coffee' 00800041af <- rep 00800041a8 +dispatching 'coffee' 00800041b0 req -> 00800041a8 +received 'cappuccino' from 'coffee' +dispatching 'coffee' 00800041b0 <- rep 00800041a8 +dispatching 'coffee' 00800041b1 req -> 00800041a8 received 'latte, with soy milk' from 'coffee' -dispatching 'coffee' 00800041ad <- rep 00800041af -dispatching 'coffee' 00800041ae req -> 00800041af +dispatching 'coffee' 00800041b1 <- rep 00800041a8 +dispatching 'coffee' 00800041b2 req -> 00800041a8 received 'espresso' from 'coffee' -dispatching 'coffee' 00800041ae <- rep 00800041af +dispatching 'tea' 00800041ae <- rep 00800041a9 +received 'jasmine' from 'tea' +dispatching 'coffee' 00800041b2 <- rep 00800041a8 received 'irish coffee' from 'coffee' +dispatching 'tea' 00800041ab <- rep 00800041a7 +received 'oolong' from 'tea' timeout expired waiting for 'soda' -deregistered worker 00800041b1 for 'tea' +---------- Stopping ----------- ``` diff --git a/examples/majordomo/broker.ts b/examples/majordomo/broker.ts index 3380a7bb..41e20a7d 100644 --- a/examples/majordomo/broker.ts +++ b/examples/majordomo/broker.ts @@ -17,22 +17,18 @@ export class Broker { console.log(`starting broker on ${this.address}`) await this.socket.bind(this.address) - const loop = async () => { - for await (const [sender, _blank, header, ...rest] of this.socket) { - switch (header.toString()) { - case Header.Client: - this.handleClient(sender, ...rest) - break - case Header.Worker: - this.handleWorker(sender, ...rest) - break - default: - console.error(`invalid message header: ${header}`) - } + for await (const [sender, _blank, header, ...rest] of this.socket) { + switch (header.toString()) { + case Header.Client: + await this.handleClient(sender as Buffer, ...(rest as Buffer[])) + break + case Header.Worker: + await this.handleWorker(sender as Buffer, ...(rest as Buffer[])) + break + default: + console.error(`invalid message header: ${header}`) } } - - return loop() } async stop() { @@ -43,7 +39,7 @@ export class Broker { handleClient(client: Buffer, service?: Buffer, ...req: Buffer[]) { if (service) { - this.dispatchRequest(client, service, ...req) + return this.dispatchRequest(client, service, ...req) } } @@ -51,16 +47,14 @@ export class Broker { switch (type?.toString()) { case Message.Ready: { const [service] = rest - this.register(worker, service) - break + return this.register(worker, service) } case Message.Reply: { const [client, _blank, ...rep] = rest - this.dispatchReply(worker, client, ...rep).catch(err => { + return this.dispatchReply(worker, client, ...rep).catch(err => { console.error(err) }) - break } case Message.Heartbeat: @@ -68,8 +62,7 @@ export class Broker { break case Message.Disconnect: - this.deregister(worker) - break + return this.deregister(worker) default: console.error(`invalid worker message type: ${type}`) @@ -78,11 +71,11 @@ export class Broker { register(worker: Buffer, service: Buffer) { this.setWorkerService(worker, service) - this.getService(service).register(worker) + return this.getService(service).register(worker) } dispatchRequest(client: Buffer, service: Buffer, ...req: Buffer[]) { - this.getService(service).dispatchRequest(client, ...req) + return this.getService(service).dispatchRequest(client, ...req) } dispatchReply(worker: Buffer, client: Buffer, ...rep: Buffer[]) { @@ -92,7 +85,7 @@ export class Broker { deregister(worker: Buffer) { const service = this.getWorkerService(worker) - this.getService(service).deregister(worker) + return this.getService(service).deregister(worker) } getService(name: Buffer): Service { diff --git a/examples/majordomo/index.ts b/examples/majordomo/index.ts index 1d1e4874..6735c1ac 100644 --- a/examples/majordomo/index.ts +++ b/examples/majordomo/index.ts @@ -12,7 +12,7 @@ async function sleep(msec: number) { class TeaWorker extends Worker { service = "tea" - async process(...msgs: Buffer[]): Promise { + override async process(...msgs: Buffer[]): Promise { await sleep(Math.random() * 500) return msgs } @@ -21,7 +21,7 @@ class TeaWorker extends Worker { class CoffeeWorker extends Worker { service = "coffee" - async process(...msgs: Buffer[]): Promise { + override async process(...msgs: Buffer[]): Promise { await sleep(Math.random() * 200) return msgs } @@ -51,10 +51,14 @@ async function request( } async function main() { - for (const worker of workers) { - await worker.start() - } - await broker.start() + const started = Promise.all([ + // start the broker + broker.start(), + // start the workers + ...workers.map(worker => worker.start()), + ]) + + console.log("---------- Started -----------") /* Requests are issued in parallel. */ await Promise.all([ @@ -69,10 +73,16 @@ async function main() { request("coffee", "irish coffee"), ]) - for (const worker of workers) { - await worker.stop() - } - await broker.stop() + console.log("---------- Stopping -----------") + + await Promise.all([ + // stop the broker + broker.stop(), + // stop the workers + ...workers.map(worker => worker.stop()), + ]) + // await outstanding promises + await started } main().catch(err => { diff --git a/examples/majordomo/worker.ts b/examples/majordomo/worker.ts index 12efb755..9d5bd818 100644 --- a/examples/majordomo/worker.ts +++ b/examples/majordomo/worker.ts @@ -13,34 +13,25 @@ export class Worker { } async start() { + console.log(`starting worker on ${this.address}`) await this.socket.send([null, Header.Worker, Message.Ready, this.service]) - const loop = async () => { - for await (const [ - _blank1, - _header, - _type, - client, - _blank2, - ...req - ] of this.socket) { - const rep = await this.process(...req) - try { - await this.socket.send([ - null, - Header.Worker, - Message.Reply, - client, - null, - ...rep, - ]) - } catch (err) { - console.error(`unable to send reply for ${this.address}`) - } + for await (const [_blank1, _header, _type, client, _blank2, ...req] of this + .socket) { + const rep = await this.process(...req) + try { + await this.socket.send([ + null, + Header.Worker, + Message.Reply, + client, + null, + ...rep, + ]) + } catch (err) { + console.error(`unable to send reply for ${this.address}`) } } - - return loop() } async stop() { @@ -55,6 +46,9 @@ export class Worker { } } + /** + * @virtual + */ async process(...req: Buffer[]): Promise { return req } diff --git a/examples/package.json b/examples/package.json index a43cd93d..880e7d69 100644 --- a/examples/package.json +++ b/examples/package.json @@ -8,8 +8,8 @@ "ts-node": ">= 0" }, "scripts": { - "majordomo": "ts-node majordomo", - "queue": "ts-node queue", - "threaded-worker": "ts-node threaded-worker" + "majordomo": "ts-node ./majordomo/index.ts", + "queue": "ts-node ./queue/index.ts", + "threaded-worker": "ts-node ./threaded-worker/index.ts" } } From ef16f2169df6fa3603919b721442ad242a8687b5 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:11:37 -0800 Subject: [PATCH 13/18] fix: fix the queue example --- examples/package.json | 6 +++++- examples/queue/index.ts | 15 +++++++++++---- examples/queue/queue.ts | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/examples/package.json b/examples/package.json index 880e7d69..a91eb481 100644 --- a/examples/package.json +++ b/examples/package.json @@ -10,6 +10,10 @@ "scripts": { "majordomo": "ts-node ./majordomo/index.ts", "queue": "ts-node ./queue/index.ts", - "threaded-worker": "ts-node ./threaded-worker/index.ts" + "threaded-worker": "ts-node ./threaded-worker/index.ts", + "pub-sub": "ts-node ./pub-sub/index.ts", + "push-pull": "ts-node ./push-pull/index.ts", + "req-rep": "ts-node ./req-rep/index.ts", + "v5-compat": "node ./v5-compat/index.js" } } diff --git a/examples/queue/index.ts b/examples/queue/index.ts index d3e55c3b..06fc9c53 100644 --- a/examples/queue/index.ts +++ b/examples/queue/index.ts @@ -1,18 +1,23 @@ import {Dealer} from "zeromq" -import {Queue} from "./queue.js" +import {Queue} from "./queue" async function main() { const sender = new Dealer() await sender.bind("tcp://127.0.0.1:5555") + console.log("sender bound to port 5555") const queue = new Queue(sender) - await queue.send("hello") - await queue.send("world!") - await queue.send(null) + + const sent = Promise.all([ + queue.send("hello"), + queue.send("world!"), + queue.send(null), + ]) const receiver = new Dealer() receiver.connect("tcp://127.0.0.1:5555") + console.log("receiver connected to port 5555") for await (const [msg] of receiver) { if (msg.length === 0) { @@ -22,6 +27,8 @@ async function main() { console.log(`received: ${msg}`) } } + + await sent } main().catch(err => { diff --git a/examples/queue/queue.ts b/examples/queue/queue.ts index 30f5d148..109500c0 100644 --- a/examples/queue/queue.ts +++ b/examples/queue/queue.ts @@ -12,6 +12,7 @@ export class Queue { } send(msg: MessageLike) { + console.log(`Sending message: ${msg}`) if (this.queue.length > this.max) { throw new Error("Queue is full") } From 1c43975f4ab239df79006bb7abccb54d3d3714f1 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:13:11 -0800 Subject: [PATCH 14/18] fix: fix the output lint error in threaded-worker --- examples/threaded-worker/processor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/threaded-worker/processor.ts b/examples/threaded-worker/processor.ts index e609fa86..5335a6bb 100644 --- a/examples/threaded-worker/processor.ts +++ b/examples/threaded-worker/processor.ts @@ -38,7 +38,7 @@ export class Processor { await this.input.send(req.map(pt => pt.toString())) } - const output: string[] = Array.from({length: input.length}) + const output: (string | undefined)[] = Array.from({length: input.length}) for await (const [pos, res] of this.output) { output[parseInt(pos.toString(), 10)] = res.toString() if (output.every(el => el !== undefined)) { @@ -46,7 +46,7 @@ export class Processor { } } - return output.join("") + return (output as string[]).join("") } async stop() { From ce7d050bb9d6cbeb7727ff2a23f11d9a8a5d2852 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:26:04 -0800 Subject: [PATCH 15/18] fix: allow running pub-sub, push-pull, req-rep examples --- examples/pub-sub/index.ts | 10 ++++++++++ examples/pub-sub/publisher.ts | 3 ++- examples/pub-sub/subscriber.ts | 2 +- examples/push-pull/index.ts | 10 ++++++++++ examples/push-pull/producer.ts | 3 ++- examples/push-pull/worker.ts | 2 +- examples/req-rep/client.ts | 9 +++++---- examples/req-rep/index.ts | 10 ++++++++++ examples/req-rep/server.ts | 9 +++++++-- 9 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 examples/pub-sub/index.ts create mode 100644 examples/push-pull/index.ts create mode 100644 examples/req-rep/index.ts diff --git a/examples/pub-sub/index.ts b/examples/pub-sub/index.ts new file mode 100644 index 00000000..1bf626dc --- /dev/null +++ b/examples/pub-sub/index.ts @@ -0,0 +1,10 @@ +if (process.env.CI) { + // exit after 1 second in CI environment + setTimeout(() => { + process.exit(0) + }, 1000) +} + +/* eslint-disable import/no-unassigned-import */ +import "./publisher" +import "./subscriber" diff --git a/examples/pub-sub/publisher.ts b/examples/pub-sub/publisher.ts index 7b4943dc..83f4cd87 100644 --- a/examples/pub-sub/publisher.ts +++ b/examples/pub-sub/publisher.ts @@ -6,6 +6,7 @@ async function run() { await sock.bind("tcp://127.0.0.1:3000") console.log("Publisher bound to port 3000") + // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition while (true) { console.log("sending a multipart message envelope") await sock.send(["kitty cats", "meow!"]) @@ -15,4 +16,4 @@ async function run() { } } -run() +run().catch(console.error) diff --git a/examples/pub-sub/subscriber.ts b/examples/pub-sub/subscriber.ts index fdf48165..c32ee486 100644 --- a/examples/pub-sub/subscriber.ts +++ b/examples/pub-sub/subscriber.ts @@ -17,4 +17,4 @@ async function run() { } } -run() +run().catch(console.error) diff --git a/examples/push-pull/index.ts b/examples/push-pull/index.ts new file mode 100644 index 00000000..933e8ad7 --- /dev/null +++ b/examples/push-pull/index.ts @@ -0,0 +1,10 @@ +if (process.env.CI) { + // exit after 1 second in CI environment + setTimeout(() => { + process.exit(0) + }, 1000) +} + +/* eslint-disable import/no-unassigned-import */ +import "./producer" +import "./worker" diff --git a/examples/push-pull/producer.ts b/examples/push-pull/producer.ts index ff4441b5..8847ce1e 100644 --- a/examples/push-pull/producer.ts +++ b/examples/push-pull/producer.ts @@ -6,6 +6,7 @@ async function run() { await sock.bind("tcp://127.0.0.1:3000") console.log("Producer bound to port 3000") + // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition while (true) { await sock.send("some work") await new Promise(resolve => { @@ -14,4 +15,4 @@ async function run() { } } -run() +run().catch(console.error) diff --git a/examples/push-pull/worker.ts b/examples/push-pull/worker.ts index 7cd9644b..4b822978 100644 --- a/examples/push-pull/worker.ts +++ b/examples/push-pull/worker.ts @@ -11,4 +11,4 @@ async function run() { } } -run() +run().catch(console.error) diff --git a/examples/req-rep/client.ts b/examples/req-rep/client.ts index 242437e6..cc4d08bc 100644 --- a/examples/req-rep/client.ts +++ b/examples/req-rep/client.ts @@ -6,10 +6,11 @@ async function run() { sock.connect("tcp://127.0.0.1:3000") console.log("Producer bound to port 3000") - await sock.send("4") - const [result] = await sock.receive() + await sock.send(4) + console.log("Request a calculation for 4") - console.log(result) + const [result] = await sock.receive() + console.log(`Received result: ${result}`) } -run() +run().catch(console.error) diff --git a/examples/req-rep/index.ts b/examples/req-rep/index.ts new file mode 100644 index 00000000..15238c2a --- /dev/null +++ b/examples/req-rep/index.ts @@ -0,0 +1,10 @@ +if (process.env.CI) { + // exit after 1 second in CI environment + setTimeout(() => { + process.exit(0) + }, 1000) +} + +/* eslint-disable import/no-unassigned-import */ +import "./client" +import "./server" diff --git a/examples/req-rep/server.ts b/examples/req-rep/server.ts index 708ead90..62680d56 100644 --- a/examples/req-rep/server.ts +++ b/examples/req-rep/server.ts @@ -6,8 +6,13 @@ async function run() { await sock.bind("tcp://127.0.0.1:3000") for await (const [msg] of sock) { - await sock.send((2 * parseInt(msg.toString(), 10)).toString()) + // parse the message as a number + const value = parseInt(msg.toString(), 10) + + // calculate the result and send it back to the client + const result = 2 * value + await sock.send(result) } } -run() +run().catch(console.error) From 7b553eb07a2e7df6bde8a0d306dde3463d7db7c6 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:53:01 -0800 Subject: [PATCH 16/18] docs: update the compat example --- examples/package.json | 1 + examples/v5-compat/index.js | 40 +++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/examples/package.json b/examples/package.json index a91eb481..9d7b9c11 100644 --- a/examples/package.json +++ b/examples/package.json @@ -8,6 +8,7 @@ "ts-node": ">= 0" }, "scripts": { + "build": "cd .. && pnpm build && cd ./examples && pnpm install", "majordomo": "ts-node ./majordomo/index.ts", "queue": "ts-node ./queue/index.ts", "threaded-worker": "ts-node ./threaded-worker/index.ts", diff --git a/examples/v5-compat/index.js b/examples/v5-compat/index.js index 5a5f2cbb..6817f3d4 100644 --- a/examples/v5-compat/index.js +++ b/examples/v5-compat/index.js @@ -1,18 +1,36 @@ +/* eslint-disable */ const zmq = require("zeromq/v5-compat") -const pub = zmq.socket("pub") -const sub = zmq.socket("sub") +function main() { + const pub = zmq.socket("pub") + const sub = zmq.socket("sub") -pub.bind("tcp://*:3456", err => { - if (err) { - throw err - } + pub.on("bind", address => { + console.log(`Bound to ${address}`) + }) + + pub.bind("tcp://127.0.0.1:3456", err => { + if (err) { + throw err + } - sub.connect("tcp://127.0.0.1:3456") + sub.connect("tcp://127.0.0.1:3456") + console.log("Subscriber connected to tcp://127.0.0.1:3456") - pub.send("message") + sub.on("message", msg => { + // Handle received message... + console.log(`Received message: ${msg.toString()}`) + }) - sub.on("message", msg => { - // Handle received message... + pub.send("message") }) -}) + + if (process.env.CI) { + // exit after 1 second in CI environment + setTimeout(() => { + process.exit(0) + }, 2000) + } +} + +main() From 586fe8d31fb3e4047ec4b5d06ad568ef2954781a Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 22:59:04 -0800 Subject: [PATCH 17/18] test: run examples as part of the tests --- .github/workflows/CI.yml | 2 +- examples/package.json | 7 +- examples/pnpm-lock.yaml | 144 ++++++++++++++++++++++++++++++++++++++- package.json | 5 +- 4 files changed, 152 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a9c86ae6..b34f929a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -212,7 +212,7 @@ jobs: max_attempts: 3 shell: bash command: | - pnpm run test.unit || (rm -rf ./tmp && mkdir -p ./tmp && exit 1) + pnpm run test || (rm -rf ./tmp && mkdir -p ./tmp && exit 1) rm -rf ./tmp && mkdir -p ./tmp - name: Test Electron Windows/MacOS diff --git a/examples/package.json b/examples/package.json index 9d7b9c11..26f9ca20 100644 --- a/examples/package.json +++ b/examples/package.json @@ -5,7 +5,9 @@ "zeromq": "file:.." }, "devDependencies": { - "ts-node": ">= 0" + "cross-env": "^7.0.3", + "npm-run-all2": "^7.0.2", + "ts-node": "10.9.2" }, "scripts": { "build": "cd .. && pnpm build && cd ./examples && pnpm install", @@ -15,6 +17,7 @@ "pub-sub": "ts-node ./pub-sub/index.ts", "push-pull": "ts-node ./push-pull/index.ts", "req-rep": "ts-node ./req-rep/index.ts", - "v5-compat": "node ./v5-compat/index.js" + "v5-compat": "node ./v5-compat/index.js", + "test": "cross-env CI=true run-s majordomo queue threaded-worker pub-sub push-pull req-rep" } } diff --git a/examples/pnpm-lock.yaml b/examples/pnpm-lock.yaml index fc10d6d7..2792b52e 100644 --- a/examples/pnpm-lock.yaml +++ b/examples/pnpm-lock.yaml @@ -12,8 +12,14 @@ importers: specifier: file:.. version: file:.. devDependencies: + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + npm-run-all2: + specifier: ^7.0.2 + version: 7.0.2 ts-node: - specifier: '>= 0' + specifier: 10.9.2 version: 10.9.2(@types/node@22.10.5)(typescript@5.7.2) packages: @@ -80,6 +86,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} @@ -107,12 +117,18 @@ packages: aws4@1.13.2: resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -152,6 +168,15 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} @@ -306,12 +331,20 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + json-parse-even-better-errors@4.0.0: + resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} + engines: {node: ^18.17.0 || >=20.5.0} + json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} @@ -338,6 +371,10 @@ packages: memory-stream@1.0.0: resolution: {integrity: sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==} + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -354,6 +391,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} @@ -378,6 +419,15 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + npm-normalize-package-bin@4.0.0: + resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} + engines: {node: ^18.17.0 || >=20.5.0} + + npm-run-all2@7.0.2: + resolution: {integrity: sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==} + engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'} + hasBin: true + npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -387,6 +437,10 @@ packages: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -397,6 +451,11 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -407,6 +466,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + read-package-json-fast@4.0.0: + resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} + engines: {node: ^18.17.0 || >=20.5.0} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -443,6 +506,18 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -564,6 +639,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -663,6 +743,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-styles@6.2.1: {} + aproba@2.0.0: {} are-we-there-yet@3.0.1: @@ -684,12 +766,18 @@ snapshots: aws4@1.13.2: {} + balanced-match@1.0.2: {} + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 bluebird@3.7.2: {} + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -722,6 +810,16 @@ snapshots: create-require@1.1.1: {} + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.6 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dashdash@1.14.1: dependencies: assert-plus: 1.0.0 @@ -880,10 +978,14 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.1: {} + isstream@0.1.2: {} jsbn@0.1.1: {} + json-parse-even-better-errors@4.0.0: {} + json-schema@0.4.0: {} json-stringify-safe@5.0.1: {} @@ -911,6 +1013,8 @@ snapshots: dependencies: readable-stream: 3.6.2 + memorystream@0.3.1: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -924,6 +1028,10 @@ snapshots: dependencies: mime-db: 1.52.0 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + minipass@3.3.6: dependencies: yallist: 4.0.0 @@ -941,6 +1049,19 @@ snapshots: node-int64@0.4.0: {} + npm-normalize-package-bin@4.0.0: {} + + npm-run-all2@7.0.2: + dependencies: + ansi-styles: 6.2.1 + cross-spawn: 7.0.6 + memorystream: 0.3.1 + minimatch: 9.0.5 + pidtree: 0.6.0 + read-package-json-fast: 4.0.0 + shell-quote: 1.8.2 + which: 5.0.0 + npmlog@6.0.2: dependencies: are-we-there-yet: 3.0.1 @@ -950,12 +1071,16 @@ snapshots: object-inspect@1.13.3: {} + path-key@3.1.1: {} + path-parse@1.0.7: {} performance-now@2.1.0: {} picomatch@2.3.1: {} + pidtree@0.6.0: {} + process-nextick-args@2.0.1: {} qs@6.13.1: @@ -964,6 +1089,11 @@ snapshots: queue-microtask@1.2.3: {} + read-package-json-fast@4.0.0: + dependencies: + json-parse-even-better-errors: 4.0.0 + npm-normalize-package-bin: 4.0.0 + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -1002,6 +1132,14 @@ snapshots: set-blocking@2.0.0: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.2: {} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -1145,6 +1283,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@5.0.0: + dependencies: + isexe: 3.1.1 + wide-align@1.1.5: dependencies: string-width: 4.2.3 diff --git a/package.json b/package.json index 15ffdbf1..ee490cf1 100644 --- a/package.json +++ b/package.json @@ -109,11 +109,12 @@ "build.native.debug": "cross-env npm_config_zmq_enable_sanitizer_undefined=true cmake-ts dev-os-only", "build": "run-p build.js build.native", "build.debug": "run-s build.js build.native.debug", - "test": "run-s test.unit", - "test.debug": "run-s test.unit.debug", + "test": "run-s test.unit test.examples", + "test.debug": "run-s test.unit.debug test.examples", "test.unit": "run-s clean.temp build && cross-env INCLUDE_COMPAT_TESTS=true mocha ./test/unit/*-test.ts ./test/unit/compat/*-test.ts", "test.unit.debug": "run-s clean.temp build.debug && cross-env INCLUDE_COMPAT_TESTS=true mocha ./test/unit/*-test.ts ./test/unit/compat/*-test.ts", "test.unit.nogc": "run-s clean.temp build && cross-env SKIP_GC_TESTS=true mocha", + "test.examples": "cd examples && pnpm install && pnpm run test", "test.electron.main": "run-s clean.temp build && cross-env INCLUDE_COMPAT_TESTS=true SKIP_GC_TESTS=true electron-mocha ./test/unit/*-test.ts ./test/unit/compat/*-test.ts", "test.electron.renderer": "run-s build && cross-env INCLUDE_COMPAT_TESTS=true SKIP_GC_TESTS=true electron-mocha --renderer ./test/unit/*-test.ts ./test/unit/compat/*-test.ts", "test.smoke": "bash ./script/smoke-test.bash", From 133135fefc4a301136b71badc65e26e39e7adf9a Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sun, 5 Jan 2025 23:21:52 -0800 Subject: [PATCH 18/18] test: add a soda worker for majordomo --- examples/majordomo/README.md | 30 +++++++++++++++++------------- examples/majordomo/index.ts | 29 ++++++++++++++++++++++++----- examples/majordomo/worker.ts | 2 +- examples/queue/index.ts | 8 ++++---- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/examples/majordomo/README.md b/examples/majordomo/README.md index f6280f9f..4f0d8be3 100644 --- a/examples/majordomo/README.md +++ b/examples/majordomo/README.md @@ -20,11 +20,12 @@ The example will start a broker and some workers, then do some requests. The output will be similar to this: ``` - starting broker on tcp://127.0.0.1:5555 -starting worker on tcp://127.0.0.1:5555 -starting worker on tcp://127.0.0.1:5555 -starting worker on tcp://127.0.0.1:5555 +starting broker on tcp://127.0.0.1:5555 +starting worker soda on tcp://127.0.0.1:5555 +starting worker tea on tcp://127.0.0.1:5555 +starting worker coffee on tcp://127.0.0.1:5555 +starting worker tea on tcp://127.0.0.1:5555 ---------- Started ----------- requesting 'cola' from 'soda' requesting 'oolong' from 'tea' @@ -41,27 +42,30 @@ registered worker 00800041a9 for 'tea' dispatching 'tea' 00800041ab req -> 00800041a7 dispatching 'tea' 00800041ac req -> 00800041a9 dispatching 'coffee' 00800041af req -> 00800041a8 -dispatching 'tea' 00800041ac <- rep 00800041a9 -dispatching 'tea' 00800041ad req -> 00800041a9 -received 'sencha' from 'tea' -dispatching 'tea' 00800041ad <- rep 00800041a9 -dispatching 'tea' 00800041ae req -> 00800041a9 -received 'earl grey, with milk' from 'tea' dispatching 'coffee' 00800041af <- rep 00800041a8 dispatching 'coffee' 00800041b0 req -> 00800041a8 received 'cappuccino' from 'coffee' +dispatching 'tea' 00800041ab <- rep 00800041a7 +dispatching 'tea' 00800041ad req -> 00800041a7 +received 'oolong' from 'tea' dispatching 'coffee' 00800041b0 <- rep 00800041a8 dispatching 'coffee' 00800041b1 req -> 00800041a8 received 'latte, with soy milk' from 'coffee' dispatching 'coffee' 00800041b1 <- rep 00800041a8 dispatching 'coffee' 00800041b2 req -> 00800041a8 received 'espresso' from 'coffee' +registered worker 00800041b3 for 'soda' +dispatching 'soda' 00800041aa req -> 00800041b3 +dispatching 'soda' 00800041aa <- rep 00800041b3 +received 'cola' from 'soda' +dispatching 'tea' 00800041ac <- rep 00800041a9 +dispatching 'tea' 00800041ae req -> 00800041a9 +received 'sencha' from 'tea' dispatching 'tea' 00800041ae <- rep 00800041a9 received 'jasmine' from 'tea' dispatching 'coffee' 00800041b2 <- rep 00800041a8 received 'irish coffee' from 'coffee' -dispatching 'tea' 00800041ab <- rep 00800041a7 -received 'oolong' from 'tea' -timeout expired waiting for 'soda' +dispatching 'tea' 00800041ad <- rep 00800041a7 +received 'earl grey, with milk' from 'tea' ---------- Stopping ----------- ``` diff --git a/examples/majordomo/index.ts b/examples/majordomo/index.ts index 6735c1ac..13d95571 100644 --- a/examples/majordomo/index.ts +++ b/examples/majordomo/index.ts @@ -9,6 +9,15 @@ async function sleep(msec: number) { }) } +class SodaWorker extends Worker { + service = "soda" + + override async process(...msgs: Buffer[]): Promise { + await sleep(Math.random() * 300) + return msgs + } +} + class TeaWorker extends Worker { service = "tea" @@ -29,7 +38,12 @@ class CoffeeWorker extends Worker { const broker = new Broker() -const workers = [new TeaWorker(), new CoffeeWorker(), new TeaWorker()] +const workers = [ + new SodaWorker(), + new TeaWorker(), + new CoffeeWorker(), + new TeaWorker(), +] async function request( service: string, @@ -46,12 +60,12 @@ async function request( console.log(`received '${res.join(", ")}' from '${service}'`) return res } catch (err) { - console.log(`timeout expired waiting for '${service}'`) + console.log(`timeout expired waiting for '${service}'`, err) } } async function main() { - const started = Promise.all([ + const _started = Promise.all([ // start the broker broker.start(), // start the workers @@ -81,11 +95,16 @@ async function main() { // stop the workers ...workers.map(worker => worker.stop()), ]) - // await outstanding promises - await started } main().catch(err => { console.error(err) process.exit(1) }) + +if (process.env.CI) { + // exit after 1 second in CI environment + setTimeout(() => { + process.exit(0) + }, 2000) +} diff --git a/examples/majordomo/worker.ts b/examples/majordomo/worker.ts index 9d5bd818..a4eb6e48 100644 --- a/examples/majordomo/worker.ts +++ b/examples/majordomo/worker.ts @@ -13,7 +13,7 @@ export class Worker { } async start() { - console.log(`starting worker on ${this.address}`) + console.log(`starting worker ${this.service} on ${this.address}`) await this.socket.send([null, Header.Worker, Message.Ready, this.service]) for await (const [_blank1, _header, _type, client, _blank2, ...req] of this diff --git a/examples/queue/index.ts b/examples/queue/index.ts index 06fc9c53..231ecc46 100644 --- a/examples/queue/index.ts +++ b/examples/queue/index.ts @@ -4,8 +4,8 @@ import {Queue} from "./queue" async function main() { const sender = new Dealer() - await sender.bind("tcp://127.0.0.1:5555") - console.log("sender bound to port 5555") + await sender.bind("tcp://127.0.0.1:4444") + console.log("sender bound to port 4444") const queue = new Queue(sender) @@ -16,8 +16,8 @@ async function main() { ]) const receiver = new Dealer() - receiver.connect("tcp://127.0.0.1:5555") - console.log("receiver connected to port 5555") + receiver.connect("tcp://127.0.0.1:4444") + console.log("receiver connected to port 4444") for await (const [msg] of receiver) { if (msg.length === 0) {