Fluid simulation in JavaScript

#​658 — October 12, 2023

Read on the Web

✍️ Due to being on the road at an event, this is a more compact and bijou issue but I’m back at full pace next week 😅
__
Peter Cooper, your editor

JavaScript Weekly

Speeding Up the JS Ecosystem: The Barrel File Debacle — Marvin continues his tour through the world of JavaScript performance fixes with a look at how some innocent looking code can make tools run slower than they should. Test runners and many import cycle detection tools are most affected.

Marvin Hagemeister

🌊  Building a Water/Fluid Simulation in JavaScript — Hard to explain, but a lot of thought and care has gone into this tutorial of sorts. The live demos are nice, too. Uses p5.js behind the scenes.

Kenichi Yoneda

Strongly Typed and in the ⛅: Meet EdgeDB 4.0 — EdgeDB is an open-source database focused on developer experience. It features a high-level, modern data model, integrated schema migrations, and a TypeScript query builder that makes it easy to write advanced, fast queries, putting ORMs to shame.

EdgeDB sponsor

Angular and Qwik’s Creator on How JS Frameworks Handle Reactivity — A summary of Miško Hevery’s keynote from the International JavaScript Conference looking at reactivity across the major frameworks.

Loraine Lawson (The New Stack)

A Web Server ‘Hello World’ Benchmark: Go vs Node vs Nim vs Bun — The standard disclaimer applies: benchmarks are difficult and don’t always measure what you should care about.

Daniel Lemire

👀 Simon Willison has put together a fantastic live demo (in notebook format) showing off how to do client-side object detection in images using solely JavaScript and a neural network. (Note: Be aware this uses a lot of CPU and may slow your browser down.)

▶️ ViteConf 2023 took place last week and some of the talks are already available on YouTube. 🐦 One key bit of news is about Rolldown, a Rust port of Rollup, meaning Vite will get even faster in the medium term.

⚙️ Stephen Röttger of the V8 team has blogged about efforts to enable control-flow integrity (CFI) in V8, essentially a way to reduce the ability of nefarious third parties to exploit V8’s control flow in order to trigger arbitrary shellcode.

⚠️ A look at the potential dangers of regular expressions in JavaScript.

👾 An interesting post mortem of a game built in just 13KB for the JS13K contest.

🎉 RELEASES:

Electron 27 – The cross-platform desktop app toolkit gains Chromium 118, Node.js 18.17.1, and V8 11.8, but loses macOS 10.13/14 support.

Fresh 1.5 – A Deno-native framework for building full-stack webapps. v1.5 adds support for partials – the ability to update a portion of an existing page.

Parcel 2.10 – The zero-config build tool gets some serious performance improvements (7x faster on large projects). Devon Govett wrote 🐦 a Twitter thread explaining how.

Bun 1.0.5 – Mostly bug fixes and gentle improvements for the performance-oriented JS runtime. No HTTP/2 yet, but it’s just around the corner..

Solid 1.8 – Declarative and performant reactivity for building UIs.

🛠 Code & Tools

Evidence: Reports Synced to Your Data with SQL and Markdown — An open source, code-based alternative to drag-and-drop business intelligence tools. ▶️ This nine minute screencast does a good job at showing off what it can do.

Evidence

Payload 2.0: A Headless CMS Platform Built on Node — A Node-based headless CMS providing an app framework-like experience, including a customizable React-based admin system, GraphQL or REST APIs, flexible auth and file upload systems, etc. v2.0 introduces Postgres support (in addition to MongoDB), Vite support, and a new rich text editor. GitHub repo.

James Mikrut

Add Figma Like Collaborative Features Without Re-Architecting Your App — Create collaborative features, from live cursors to avatar stacks with Spaces, our in-app collaboration SDK.

Ably sponsor

Visual Studio Code Extension Tester v5.10 — A framework for simulating user interactions with VS Code and its extensions via Selenium Webdriver.

Red Hat

audioMotion-analyzer: Real-Time Audio Spectrum Analyzer — A high-resolution real-time audio spectrum analyzer JavaScript module with no dependencies. Gives a single or dual channel view. (Note the AGPL license.) GitHub repo.

Henrique Avila Vianna

Hotkey 2.1 – Add keyboard shortcuts to pages through HTML attributes (e.g. data-hotkey=”Meta+d”). Built by GitHub and used on github․com itself.

React-Menu 4.1 – Component for building accessible menus and dropdowns.

Ionic 7.5 – Build cross-platform mobile apps with JavaScript.

pnpm 8.9 – The alternative, efficient package manager.

Highlight.js 11.9 – Popular JS syntax highlighting library.

Node.js v18.18.1 (LTS) – To fix a regression in v18.18.0.

💻 Jobs

Apply Now and Work #LikeABosch — Our promise to our associates is rock-solid: we grow together, enjoy our work & inspire each other. Join in & feel the difference.

Bosch

“The art of debugging is figuring out what you really told your program to do rather than what you thought you told it to do.”

___
Andrew Singer

htmx in 100 seconds

#​647 — July 13, 2023

Read on the Web

JavaScript Weekly

Driver.js: Create On-Page Tours, Highlights, and Contextual Help — A no-dependency, vanilla JavaScript library for putting together page tours and contextual help systems. The project is a few years old but has just been entirely rewritten and gained numerous enhancements, plus a huge lick of paint. There are lots of examples to check out.

Kamran Ahmed

Component Party: A Rosetta Stone of UI Library Code Examples — A comparison of different frameworks (like React, Vue, Svelte, Angular, Ember, etc.) by way of simple code snippets covering various tasks.

Mathieu Schimmerling

Test and Validate APIs Effectively and Efficiently — Gain access to several API testing tools and features that help you automate repetitive tasks, stay organized, and build robust workflows to ensure your APIs remain reliable and performant.

Postman sponsor

Prettier 3.0: Now Powered by ES Modules — The popular multi-language code formatter gets a big upgrade with a refactoring to ES modules making up the biggest change (though it can still be used as a library via CommonJS). One side effect is Prettier now supports ESM-based plugins and async parsers which means some necessary changes for Prettier plugin developers.

Sosuke Suzuki

Crockford on Plain Old JavaScript and the DOM — Over the years, Douglas has asked us to only use the good parts of JavaScript, to ▶️ stop using JavaScript, and now he suggests abandoning “the libraries” to instead work with the DOM directly. Lea Verou 🐦 picked up on this story and said this suggestion still isn’t very practical for most web apps as of 2023.

Douglas Crockford

🎉 RELEASES:

Ember 5.1 – The ambitious JS framework that’ll never give up takes a big step into the TypeScript world with stable TypeScript support and types-a-plenty.

p5.js 1.7 – Processing-inspired JavaScript library for creative coding. v1.7 introduces WebGL 2 and frame buffer support.

Prisma 5.0 – A popular ORM for Node.js and TypeScript. 5.0 boasts significant performance improvements.

typescript-eslint 6.0

⚡️ IN BRIEF:

obj?.prop = value; The optional chaining assignment proposal advanced to stage 1 at TC39 this week. (Explanatory slidedeck.)

Popular YouTube channel Fireship explains ▶️ htmx in 100 seconds – well timed, since htmx is seeing a huge amount of fresh interest. And if you’re wondering who the mastermind behind Fireship is, Honeypot has put up ▶️ a short documentary about him.

The folks at Sandworm have shared a look at the state of the npm registry including lots of trivia, history, and stats on how many packages there are, as well as the most commonly used keywords in packages.

Google shares a case study on performance of scroll-driven animations using its new browser based API versus ‘classical JavaScript techniques.’ Unsurprisingly it’s much faster running away from the main thread, and the spec remains in draft for now.

npm will now check the linked source commit and repo when you view a package’s provenance information on npmjs.com and warn you when said provenance cannot be established.

GitHub is rolling out a beta of passwordless, passkey based authentication on GitHub․com.

📒 Articles & Tutorials

Useful Functions for a (Deno) HTTP Server — You could think of HTTP in a functional way with requests going in and responses/results going out. The author explores Deno’s new Deno.serve function and how both it and the /x/http_fns functions can provide a more functional approach to common HTTP tasks.

Jollytoad

Testing the Dark Scenarios of a Node.js App — Several examples of often overlooked things you should be testing. What happens when a service times out, code is mutating things it shouldn’t, or you have zombie processes milling around? These are some of the ‘dark scenarios’ it’s not too difficult to prepare for.

Yoni Goldberg and Raz Luvaton

The 2023 State of the API Report Is Here — The State of the API is the world’s largest survey and report on APIs, with findings from over 40K developers and API professionals.

Postman sponsor

Creating Randomized Zelda: Tears of the Kingdom Patterns — Nintendo’s new Zelda game uses repeated, geometric patterns as part of its aesthetic. This post looks at how to recreate such motifs with SVG and JavaScript.

Paul Hebert

5 TS Compiler Flags You Should Include in Your Project’s Config

Igor Konovalov

Deploying a Fastify and Vue 3 Static Site to Heroku

Liran Tal

Getting Started with Vector Databases in Node.js

Valeri Karpov

🛠 Code & Tools

MDX Editor: A Rich Markdown Editor React Component — A Lexical-powered Markdown editor for React apps that supports code blocks, tables, and more. The live demo shows off most of what you need to see.

Petyo Ivanov

Meet Your New Favorite Teammate: Cody, the AI Coding Assistant — Code faster with Cody, the only code AI that knows your entire codebase, like the pair programmer you always wanted.

Sourcegraph sponsor

electron-vite: Next Generation Electron Build Tooling — Fish and chips, Bert and Ernie.. some things are just better together, and so it goes with the Electron desktop app framework and the Vite frontend toolkit. There’s also an Electron Vite Boilerplate app to kick off a new app with.

Alex Wei

📊  Vizzu 0.8: A Library for Animated Data Visualizations — Making data visualizations is reasonably easy, but animating them is harder. Vizzu steps in to help you create animated data stories and explorations. There are lots of showcases and examples to peruse.

Vizzu Inc.

🐊  Putout: A Configurable, Babel-Based Linter and Code Transformer — Provides typical linting functionality with ESLint and code transformation with Babel, but distinguishes itself by being prepared to make “more drastic code transformations” than other tools. It’s not the most popular option but it makes a good case for itself in its thorough README.

coderaiser

Standardized Audio Context: Cross-Browser Web Audio API Wrapper — A side effect-free abstraction over a subset of the Web Audio API that works reliably across all mainstream browsers.

Christoph Guttandin

Kanel: Generate TypeScript Types from Postgres — It works by inspecting a live database and outputs code you can add to a TypeScript project and use with something like KnexGitHub repo.

Kristian Dupont

React Authentication — Without Complexity

Userfront sponsor

Boa 0.17 – An experimental Javascript lexer, parser and compiler written in Rust that can be embedded into other projects – it now has a module system.

Octokit.js 3.0
↳ Official GitHub SDK for browsers, Node, and Deno.

Release It! 16.1
↳ Automate npm package publishing and versioning.

zlFetch 6.0
↳ Convenience wrapper around the Fetch API.

Terminalizer 0.10
↳ Record your terminal and generate animated GIFs.

eslint-plugin-prettier 5.0
↳ Prettier, but as an ESLint rule.

Preact 10.16 – 3KB React compatible alternative.

💻 Jobs

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

🧑‍💻 Got a job listing to share? Here’s how.

🍩 Homer would approve

donut.js: donut.c, But in JavaScriptdonut.c, dating from 2006, is a donut-shaped C program that, when run, animates a spinning ASCII text donut on the screen. Here’s a fresh and hot JavaScript variant!

Evan Zhou

Playwright now offers a UI mode

#​631 — March 24, 2023

Read on the Web

JavaScript Weekly

Speeding Up the JavaScript Ecosystem: npm Scripts — The latest in what has been a fascinating series on finding ‘low hanging fruit’ when it comes to performance in the JavaScript world. The author explains it best himself:

“‘npm scripts’ are executed by JavaScript developers … all the time. Despite their high usage they are not particularly well optimized and add about 400ms of overhead. In this article we were able to bring that down to ~22ms.”
What Marvin does here is a valuable skill for all developers to pick up, and you can enjoy more by going back to the start.

Marvin Hagemeister

Playwright v1.32 – Now with UI Mode — The popular Web testing and automation framework is taking more steps toward the ground currently served by tools like Cypress by offering a ‘UI mode’ that lets you explore, run and debug tests in a UI environment, complete with watch mode. ▶️ This video provides a good introduction.

Microsoft

A Grid Component with All the Features & Great Performance — Try our powerful JS data grid component which lets you edit, sort, group and filter datasets with fantastic performance. Includes a TreeGrid, API docs and plenty of demos. Seamless integration with React, Angular & Vue apps.

Bryntum sponsor

Why We Added package.json Support to Deno — Deno shares some provenance with Node.js but till recently it hadn’t focused on supporting Node features like npm modules. But with Node and npm compatibility beginning to improve, the team has faced questions about the runtime’s priorities. Ryan Dahl explains more about their thinking here.

Ryan Dahl

???? In other Deno news, Deno 1.32 has been released with… improved package.json support, and more.

How to Start a React Project in 2023 — There are lots of ways, but this well-regarded author explains the pros and cons of a few approaches, and gives you a few options targeting specific use cases you might have.

Robin Wieruch

IN BRIEF:

GitHub had to update its RSA SSH host key today so you may see security related warnings when pushing and cloning. It’s easy to fix, but check the new fingerprint matches – it’s for your own security.

The New Stack caught up with Svelte’s Rich Harris on SvelteKit and what’s coming for Svelte 4.

The React team shared some cutting edge updates on what they’re working on including React Server Components and an optimizing compiler.

If you were experiencing errors on the official Node site last week, here’s the (detailed) post mortem of why. Config errors and inappropriate caching, mostly.

✨ Did you know there’s a market in fake GitHub stars? Some developers analyzed some repos to learn more about it.

???? Congratulations to Lea Verou on her TC39 appointment9. Her efforts to push the Web forward are legendary. Prism is one project you may be aware of.

Make your opinions known on what should be in the next version of Vite.

RELEASES:

Docusaurus 2.4
↳ Easy to maintain documentation site generator.

Puppeteer 19.8
↳ Headless Chrome Node.js API.

Neutralinojs 4.11
↳ Lightweight cross-platform desktop app framework.

Qwik 0.23

???? Articles & Tutorials

Buying a Hard-to-Get Bicycle using Playwright — An unusual use case for JavaScript, Playwright, and GitHub Actions, but Maciek managed to buy his bike.

Maciek Palmowski

Snyk Top 10: JavaScript OSS Vulnerabilities — Dive into the most prevalent critical and high open source vulnerabilities found by Snyk scans of JavaScript apps in 2022.

Snyk sponsor

The ‘End’ of Front-End Development? — A recent narrative doing the rounds suggests that large language models like GPT-4 (or even tools like Copilot X) could soon put some developers out of a job — however, Josh is “optimistic about what these AI advancements mean for the future of software development”.

Josh W. Comeau

In related news, Eric Elliott put ChatGPT through its paces to see if it would make for a good JavaScript tutor. It did well, though with mixed results.

Migrating from ts-node to Bun — A look at adopting performance-oriented Bun when you’re used to using TypeScript with Node.js. John runs us through porting a console app from the ts-node approach over to Bun — “a pretty easy process,” he says.

John Reilly

▶  A Pinia Crash Course for BeginnersPinia is a store / state management solution for Vue that does believe in pineapple on pizza.

Alexander Gekov

A Practical Guide to Getting Started with Astro — An extensive walkthrough of Astro that covers all the topics you’ll need to get you started.

Mojtaba Seyedi

???? Test Website Speed Continuously and Rank Higher In Google — You need a fast website to make users happy and meet Google’s Core Web Vitals metrics. Test and optimize with DebugBear.

DebugBear sponsor

Automatic npm Publishing with GitHub Actions and Granular Tokens

Tim Perry

Make Sure You Do This Before Switching to Signals in Angular

Jordan Powell

Six CSS Snippets Every Developer Should Know

Adam Argyle (Google)

???? Code & Tools

trace.cafe: Easy Webperf Trace Sharing — A quick way to share a performance profile saved from your DevTools, available for up to 90 days with the DevTools perf panel embedded (see example).

paul irish

VueUse: A Collection of Vue Composition Utilities — With over 200 functions targeting both Vue 2 and 3, there’ll be something in this suite of Composition API-based utility functions for you, whether it’s working with state, browser capabilities, animations, Electron, Firebase, and more.

Anthony Fu

Don’t Let Your Issue Tracker Be a Four-Letter Word. Use Shortcut

Shortcut (formerly Clubhouse.io) sponsor

OTPAuth: One Time Password (HOTP/TOTP) Library — When you log in to a site that uses 2FA and you’re asked for some digits from an authentication app, that’s probably a Time-based One-Time Password (or TOTP). This library for Node, Deno, Bun and the browser lets you work with TOTPs and HOTPs from JS.

Héctor Molinero Fernández

Recharts 2.5: Chart Library Built with React and D3 — Easy to deploy with declarative components, native SVG support, and lightweight dependency on D3. Line, bar, scatter, composed, pie, and radar charts are offered. There are lots of examples, complete with code.

recharts

DOCX 8.0: Generate Word .docx Files from JavaScript — The code to lay out documents is verbose but there’s a lot of functionality. Here’s a CodePen example and release notesGitHub repo.

Dolan Miu

SvHighlight: Code Syntax Highlighter for Svelte — Powered by Highlight.js, it includes a blurring feature to focus attention on specific areas of code and you an customize it with Tailwind. Try the interactive examples to see the effect.

SvHighlight

eslint-formatter-pretty 5.0: Pretty ESLint Formatter — Nicer output than the default. Sort results by severity. Get stylized inline code blocks, and more.

Sindre Sorhus

AWS JWT Verify: Verify JWTs Signed by Amazon Cognito — In both Node.js and the browser.

Amazon Web Services

???? Jobs

Software Engineer (Backend) — Join our “kick ass” team. Our software team operates from 17 countries and we’re always looking for more exceptional engineers.

Sticker Mule

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

????‍???? Got a job listing to share? Here’s how.

melonJS 15.0
↳ Mature HTML5 game engine.

Marked 4.3
↳ Markdown parser and compiler. (Demo.)

v8go 0.9
↳ Execute JavaScript from Go(lang).

Million 2.1
↳ Fast Virtual DOM to make React faster.

Partytown 0.7.6
↳ Take third-party scripts off the main thread.

???? Bonus Item

Make Bookmarklets — Create and test bookmarklets directly in the browser. Makes an irritating task slightly easier if you need to do it.

Cullan Luther

Introducing nsuv

Introducing nsuv

nsuv is a C++ wrapper around libuv with the main goal of supporting compile-time type safety when propagating data.

You can find the open source package here: https://github.com/nodesource/nsuv

Here at NodeSource we are focused on fixing issues for the enterprise. This includes adding functionality and features to Node.js that are useful for enterprise-level deployments but would be difficult to upstream. One is the ability to execute commands remotely on Worker threads without the addition of running the inspector, such as capturing CPU profiles or heap snapshots. Another feature necessary to make Node.js more reliable in production is the ability to record and send metrics without being at the mercy of a busy event loop.

To achieve these, we run a separate thread that receives commands and gathers metrics from each Node.js thread. The locks and data queues in the separate thread are managed by libuv. As the codebase grew, usability issues began to come up, such as remembering the correct type of each void pointer and keeping track of the lifetime of the many shared locks and resources. Our solution was to write a wrapper for libuv to alleviate these problems.

We had a lot of existing libuv code and didn’t want to rewrite everything from scratch. So we wrote a template class library that inherits from each libuv handle or request type and uses the curiously recurring template pattern (CRTP) for inheritance. Doing so made it possible to write a wrapper that serves as a drop-in replacement, allowing for incremental improvements while supplementing the wrapper’s API with what was needed.

N|Solid has a zero-failure tolerance, so none of our code can accidentally terminate your process. One way we do this is to try our best not to perform additional allocations. If an allocation is necessary, it always does with a strong exception guarantee, which is then caught and returned as a libuv error code.

We have also enabled compile time warnings when returned error codes aren’t handled. While developing nsuv, we analyzed many existing C++ projects that use libuv and discovered that most of them assume the state of the application and lack sufficient error handling in case something unexpected occurs. This can be especially painful when working with asynchronous code, but we understand that not everyone requires the same level of caution. It can be disabled by defining NSUV_DISABLE_WUR in your flags.

Getting Started

The following code example shows the execution of a simple libuv timer, and the only change was to turn the uv_timer_t to a nsuv::ns_timer instance while still being able to use the original libuv APIs:

static void timer_cb(uv_timer_t* handle) {
Foo* foo = static_cast<Foo*>(handle->data);
delete foo;
uv_close(reinterpret_cast<uv_handle_t*>(handle), nullptr);
}

static void call_timer() {
ns_timer timer;
Foo* foo = new Foo();

timer.data = foo;
uv_timer_init(uv_default_loop(), &timer);
uv_timer_start(&timer, timer_cb, 1000, 0);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

As you can see, there’s no need to cast timer before being passed to libuv’s timer function since ns_timer is a derived class of uv_timer_t and upcasting is implicit. It offers the first step in converting code to be more type-safe and improve overall usability. Improvements can be made incrementally from here. Below we take advantage of the CRTP and use it to downcast the uv_timer_t to the nsuv counterpart after using libuv’s timer API:

static void timer_cb(uv_timer_t* handle) {
// Downcast the libuv handle to its nsuv counterpart.
ns_timer* timer = ns_timer::cast(handle);
// Convenience method to retrieve and cast data.
Foo* foo = timer->get_data<Foo>();

delete foo;
timer->close();
}

While this is a good first step, it still requires we know what the data value should be cast to. The call to get_data() only serves as a convenience method for easier casting.

Passing Data

One of the most painful parts of working with libuv was ensuring we didn’t accidentally cast a void pointer to the wrong type from a specific queue. While this could be verified by hand, having the compiler tell us if we did it wrong would have been more reassuring.

To accomplish this, we wrapped libuv in a way that allows any function that takes a callback to be passed an arbitrary pointer. That pointer is then passed along as an argument in the callback’s parameters. Preventing us from needing to use the uv_handle_t::data property and ensuring the callback always has the correct pointer type.

Below we have fully converted the previous code to use nsuv. As you can see, the pointer that would have been stored in the data parameter can now be passed to the method, making it available as an argument in the callback.

static void call_timer() {
ns_timer timer;
Foo* foo = new Foo();
int r;

r = timer.init(uv_default_loop());
//check r
r = timer.start(+[](ns_timer* handle, Foo* foo) {
delete foo;
handle->close();
}, 1000, 0, foo);
// check r

uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

For the sake of the example, a C++ lambda function was used. Remember that when passing a lambda function, it needs to be converted to a plain old function pointer using the + operator.

Also notice that we are assigning and handling all return values from each call. As mentioned above, the compiler will warn us if we do not check each call’s return codes. For simplicity of future examples, the return value will be assigned but not include a comment that it needs to be checked.

Locks

Because of all the communication between threads, mutexes were heavily used. To make things simpler, we added a couple of APIs for convenience. The first API of note is that init() accepts an optional boolean value. If true is passed in, the mutex is automatically destroyed when the destructor is called. The other was to add an API for scoped locking.

static void try_mutex() {
ns_mutex mutex;
// The optional boolean argument sets if the mutex should be
// automatically destroyed in the destructor.
int r = mutex.init(true);
// Convenience class to create scoped locks. Accepts either a
// pointer or reference.
{
ns_mutex::scoped_lock lock(mutex);
}
}

Having a mutex call destroy() in the destructor was kept false by default to maintain parity with the libuv API and prevent surprises while migrating to nsuv.

Example Usage

At first, we only implemented the libuv APIs that were necessary for us to use internally, but since deciding to open source the library we have begun to add as much of the remaining libuv APIs as possible. But despite not having yet ported the entire libuv API, it’s still possible to take advantage of what has been done. The following is an example from a test that includes the checks to demonstrate how class instances are being passed around.

#include “nsuv-inl.h”

using namespace nsuv;

ns_tcp client;
ns_tcp incoming;
ns_tcp server;
ns_connect<ns_tcp> connect_req;
ns_write<ns_tcp> write_req;

static void alloc_cb(ns_tcp* handle, size_t, uv_buf_t* buf) {
static char slab[1024];
assert(handle == &incoming);

buf->base = slab;
buf->len = sizeof(slab);
}

static void read_cb(ns_tcp* handle, ssize_t, const uv_buf_t*) {
assert(handle == &incoming);

handle->close();
client.close();
server.close();
}

static void write_cb(ns_write<ns_tcp>* req, int) {
assert(req == &write_req);
// Retrieve a reference to the uv_buf_t array as a std::vector.
assert(req->bufs().size() == 2);
}

static void connection_cb(ns_tcp* server, int) {
int r;
r = incoming.init(server->get_loop());
r = server->accept(&incoming);
r = incoming.read_start(alloc_cb, read_cb);
}

static void connect_cb(ns_connect<ns_tcp>* req, int, char* data) {
static char bye_ctr[] = “BYE”;
uv_buf_t buf1 = uv_buf_init(data, strlen(data));
uv_buf_t buf2 = uv_buf_init(bye_ctr, strlen(bye_ctr));
// Write to the handle attached to this request and pass along data
// by constructing a std::vector.
int r = req->handle()->write(&write_req, { buf1, buf2 }, write_cb);
}

static void do_listen() {
static char hello_cstr[] = “HELLO”;
struct sockaddr_in addr_in;
struct sockaddr* addr;
int r;

r = uv_ip4_addr(“127.0.0.1”, 9999, &addr_in);
addr = reinterpret_cast<struct sockaddr*>(&addr_in);

// Server setup.
r = server.init(uv_default_loop());
r = server.bind(addr, 0);
r = server.listen(1, connection_cb);

// Client connection.
r = client.init(uv_default_loop());
r = client.connect(&connect_req, addr, connect_cb, hello_cstr);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

The request types ns_write and ns_connect are also used in the above example. They inherit from uv_write_t and uv_connect_t respectively, and can be upcast and downcast the same way as handles. Each request type API is templated to identify which handle is being used and can return the correct handle type.

While the write() method does accept a uv_buf_t[] array, we’ve also added the ability to pass in a std::vector of buffers for ease of use. Once the request is complete, the list of written buffers can be retrieved via the ns_write::buf() API as a reference to the std::vector that’s stored internally.

Conclusion

One goal when creating nsuv was to reduce cognitive load by mimicking the libuv API naming and structure while adding safety features offered by C++. We’ve made it easy to transition existing projects to nsuv. By open-sourcing nsuv, we hope to give developers more confidence that their code will behave as expected when expected.

There is near zero runtime overhead using nsuv. The template function proxy pattern used can be completely optimized out by modern compilers. Combining that with the ability to enforce type checks at compile time, I won’t be using libuv in C++ without nsuv going forward.

Using nsuv is as simple as including the two header files from the project repository. We are still working on getting complete coverage of the libuv API and hope the community can help us decide what to work on next. We are also working on porting all applicable tests from libuv to nsuv, which can serve as usage examples. We hope that you’ll find nsuv as useful as we have.

NodeSource has delivered Node.js fresh to your Linux system via your package manager within hours, minutes, days, or weeks. For NodeSource, sustaining the community is essential because we want to support more people using Linux to have Node.js in production.

Also, we are looking for more community involvement in the project. Help will be appreciated! So if you have ideas or solutions or want to help us continue supporting open source, you can contribute to this GitHub Repo.

Continue the conversation with NodeSource here:
Twitter
LinkedIn
Github
As always, the best place to contact us is via our website or [email protected]

Ready for more?

If you are looking for NodeSource’s Enterprise-grade Node.js platform, N|Solid, please visit https://downloads.nodesource.com/. For detailed information on installing and using N|Solid, please refer to the N|Solid User Guide.