Skip to content

Commit d0f50db

Browse files
committed
feat: Officially support bun and add it to CI
1 parent b231761 commit d0f50db

9 files changed

Lines changed: 105 additions & 28 deletions

File tree

.github/workflows/ci.yml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
echo "rust_toolchain=$PARTIAL_RUST_TOOLCHAINS" >> $GITHUB_OUTPUT
4141
fi
4242
43-
build:
43+
node:
4444
needs: matrix
4545
runs-on: ${{ matrix.os }}
4646
strategy:
@@ -120,3 +120,33 @@ jobs:
120120
token: ${{ secrets.CODECOV_TOKEN }}
121121
slug: neon-bindings/neon
122122
files: target/codecov.json
123+
124+
bun:
125+
needs: matrix
126+
runs-on: ${{ matrix.os }}
127+
strategy:
128+
matrix:
129+
os: [ubuntu-latest, windows-latest, macos-latest]
130+
rust-toolchain: ${{fromJson(needs.matrix.outputs.rust_toolchain)}}
131+
steps:
132+
- name: Checkout Code
133+
uses: actions/checkout@v4
134+
135+
- name: Use Rust ${{ matrix.rust-toolchain }}
136+
uses: dtolnay/rust-toolchain@v1
137+
with:
138+
toolchain: ${{ matrix.rust-toolchain }}
139+
140+
- uses: oven-sh/setup-bun@v2
141+
with:
142+
bun-version: latest
143+
144+
- name: convert lockfile
145+
run: bun install --lockfile-only
146+
147+
- name: bun install
148+
run: bun ci
149+
150+
- name: test
151+
working-directory: ./test/napi
152+
run: bun run test:bun

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ wip
99
# Node
1010
**/node_modules
1111
npm-debug.log
12+
bun.lock
1213

1314
# JS build
1415
**/build

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ using a different version of Node and believe it should be supported, let us kno
4545

4646
Older Node version support (minimum v10) may require lower Node-API versions. See the Node [version support matrix](https://nodejs.org/api/n-api.html#node-api-version-matrix) for more details.
4747

48-
### Bun (experimental)
48+
### Bun
4949

50-
[Bun](https://bun.sh/) is an alternate JavaScript runtime that targets Node compatibility. In many cases Neon modules will work in bun; however, at the time of this writing, some Node-API functions are [not implemented](https://github.com/oven-sh/bun/issues/158).
50+
[Bun](https://bun.sh/) is an alternate JavaScript runtime that targets Node compatibility. Bun is supported and tested in CI. For details on compatibility see the [Bun support tracking issue](https://github.com/neon-bindings/neon/issues/1128).
5151

5252
### Rust
5353

test/electron/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"author": "The Neon Community",
77
"license": "MIT",
88
"scripts": {
9-
"install": "cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics",
9+
"install": "cargo-cp-artifact -ac electron-tests index.node -- cargo build --message-format=json-render-diagnostics",
1010
"start": "electron .",
1111
"test": "playwright test"
1212
},

test/napi/lib/functions.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ describe("JsFunction", function () {
104104
});
105105

106106
it("bind a strict JsFunction to a number", function () {
107+
// https://github.com/neon-bindings/neon/issues/1128#usestrict
108+
if (process.versions.bun) {
109+
return this.skip();
110+
}
111+
107112
assert.isTrue(isStrict(STRICT));
108113

109114
// strict mode functions are allowed to have a primitive this binding
@@ -154,13 +159,23 @@ describe("JsFunction", function () {
154159
});
155160

156161
it("call a JsFunction with the default this", function () {
162+
// https://github.com/neon-bindings/neon/issues/1128#usestrict
163+
if (process.versions.bun) {
164+
return this.skip();
165+
}
166+
157167
addon.call_js_function_with_implicit_this(function () {
158168
"use strict"; // ensure the undefined this isn't replaced with the global object
159169
assert.strictEqual(this, undefined);
160170
});
161171
});
162172

163173
it("exec a JsFunction with the default this", function () {
174+
// https://github.com/neon-bindings/neon/issues/1128#usestrict
175+
if (process.versions.bun) {
176+
return this.skip();
177+
}
178+
164179
addon.exec_js_function_with_implicit_this(function () {
165180
"use strict"; // ensure the undefined this isn't replaced with the global object
166181
assert.strictEqual(this, undefined);
@@ -349,19 +364,20 @@ describe("JsFunction", function () {
349364
assert.strictEqual(addon.count_called() + 1, addon.count_called());
350365
});
351366

352-
(global.gc ? it : it.skip)(
353-
"should drop function when going out of scope",
354-
function (cb) {
355-
// Run from an `IIFE` to ensure that `f` is out of scope and eligible for garbage
356-
// collection when `global.gc()` is executed.
357-
(() => {
358-
const msg = "Hello, World!";
359-
const f = addon.caller_with_drop_callback(() => msg, cb);
367+
it("should drop function when going out of scope", function (cb) {
368+
if (!global.gc) {
369+
return this.skip();
370+
}
360371

361-
assert.strictEqual(f(), msg);
362-
})();
372+
// Run from an `IIFE` to ensure that `f` is out of scope and eligible for garbage
373+
// collection when `global.gc()` is executed.
374+
(() => {
375+
const msg = "Hello, World!";
376+
const f = addon.caller_with_drop_callback(() => msg, cb);
363377

364-
global.gc();
365-
}
366-
);
378+
assert.strictEqual(f(), msg);
379+
})();
380+
381+
global.gc();
382+
});
367383
});

test/napi/lib/threads.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
const addon = require("..");
22
const assert = require("chai").assert;
33

4-
(function () {
5-
// These tests require GC exposed to shutdown properly; skip if it is not
6-
return typeof global.gc === "function" ? describe : describe.skip;
7-
})()("sync", function () {
4+
describe("sync", function () {
5+
before(function () {
6+
if (!global.gc) {
7+
this.skip();
8+
}
9+
});
10+
811
let unhandledRejectionListeners = [];
912

1013
beforeEach(() => {

test/napi/lib/typedarrays.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@ describe("Typed arrays", function () {
314314
});
315315

316316
it("correctly constructs a view over a slice of a buffer", function () {
317+
// https://github.com/neon-bindings/neon/issues/1128#byteoffset
318+
if (process.versions.bun) {
319+
return this.skip();
320+
}
321+
317322
var buf = new ArrayBuffer(128);
318323

319324
var a = addon.return_uint32array_from_arraybuffer_region(buf, 16, 4);
@@ -457,6 +462,11 @@ describe("Typed arrays", function () {
457462
}
458463

459464
it("provides correct metadata when detaching a typed array's buffer", function () {
465+
// https://github.com/neon-bindings/neon/issues/1128#detach
466+
if (process.versions.bun) {
467+
return this.skip();
468+
}
469+
460470
var buf = new ArrayBuffer(16);
461471
var arr = new Uint32Array(buf, 4, 2);
462472
var buf = arr.buffer;
@@ -492,16 +502,31 @@ describe("Typed arrays", function () {
492502
});
493503

494504
it("provides correct metadata when detaching an escaped typed array's buffer", function () {
505+
// https://github.com/neon-bindings/neon/issues/1128#detach
506+
if (process.versions.bun) {
507+
return this.skip();
508+
}
509+
495510
var buf = new ArrayBuffer(16);
496511
testDetach(new Uint32Array(buf, 4, 2), addon.detach_and_escape, 8, 2, 4);
497512
});
498513

499514
it("provides correct metadata when detaching a casted typed array's buffer", function () {
515+
// https://github.com/neon-bindings/neon/issues/1128#detach
516+
if (process.versions.bun) {
517+
return this.skip();
518+
}
519+
500520
var buf = new ArrayBuffer(16);
501521
testDetach(new Uint32Array(buf, 4, 2), addon.detach_and_cast, 8, 2, 4);
502522
});
503523

504524
it("provides correct metadata when detaching an un-rooted typed array's buffer", function () {
525+
// https://github.com/neon-bindings/neon/issues/1128#detach
526+
if (process.versions.bun) {
527+
return this.skip();
528+
}
529+
505530
var buf = new ArrayBuffer(16);
506531
testDetach(new Uint32Array(buf, 4, 2), addon.detach_and_unroot, 8, 2, 4);
507532
});

test/napi/lib/workers.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe("Worker / Root Tagging Tests", () => {
105105
describe("Multi-Threaded", () => {
106106
it("should fail to use `get_and_replace`", (cb) => {
107107
const worker = new Worker(__filename);
108-
after(() => worker.terminate());
108+
worker.unref();
109109

110110
worker.once("message", (message) => {
111111
assert.ok(/wrong module/.test(message));
@@ -117,7 +117,7 @@ describe("Worker / Root Tagging Tests", () => {
117117

118118
it("should fail to use `get_or_init`", (cb) => {
119119
const worker = new Worker(__filename);
120-
after(() => worker.terminate());
120+
worker.unref();
121121

122122
worker.once("message", (message) => {
123123
assert.ok(/wrong module/.test(message));
@@ -129,7 +129,7 @@ describe("Worker / Root Tagging Tests", () => {
129129

130130
it("should fail to use `get_or_init`", (cb) => {
131131
const worker = new Worker(__filename);
132-
after(() => worker.terminate());
132+
worker.unref();
133133

134134
worker.once("message", (message) => {
135135
assert.ok(/wrong module/.test(message));
@@ -192,7 +192,7 @@ describe("Instance-local storage", () => {
192192
assert(!Number.isNaN(mainThreadId));
193193

194194
const worker = new Worker(__filename);
195-
after(() => worker.terminate());
195+
worker.unref();
196196

197197
worker.once("message", (message) => {
198198
assert.strictEqual(typeof message, "number");
@@ -211,8 +211,9 @@ describe("Instance-local storage", () => {
211211
workerData: "notify_when_startup_complete",
212212
});
213213

214+
worker.unref();
215+
214216
worker.once("message", async () => {
215-
await worker.terminate();
216217
setTimeout(cb, 200);
217218
});
218219
});

test/napi/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"author": "The Neon Community",
66
"license": "MIT",
77
"scripts": {
8-
"install": "cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics",
8+
"install": "cargo-cp-artifact -ac napi-tests index.node -- cargo build --message-format=json-render-diagnostics",
99
"mocha": "mocha",
10-
"test": "mocha --v8-expose-gc --timeout 5000 --recursive lib"
10+
"test": "mocha --expose-gc --timeout 5000 --recursive lib",
11+
"test:bun": "bun ../../node_modules/mocha/bin/mocha.js --v8-expose-gc --timeout 5000 --recursive lib"
1112
},
1213
"devDependencies": {
1314
"cargo-cp-artifact": "^0.1.9",

0 commit comments

Comments
 (0)