Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
needs: list-examples
strategy:
matrix:
node-version: ["22", "24"]
node-version: ["22", "24", "26"]
example: ${{ fromJson(needs.list-examples.outputs.examples) }}
fail-fast: false
steps:
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24.19.0
26.8.1
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.5",
"@types/jest": "^29.5.0",
"@types/node": "^24.10.1",
"@types/node": "^26.3.0",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.57.0",
"esbuild": "^0.17.16",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"gypfile": true,
"scripts": {
"build": "rollup -c",
"build-native-addon": "prebuildify --name node --strip --no-napi --target 22.0.0 --target 24.0.0",
"build-native-addon": "prebuildify --name node --strip --no-napi --target 22.0.0 --target 24.0.0 --target 26.0.0",
"build-tracer-client": "openapi --client axios --input ./tracer.spec.json --name MongoTracer --output ./src/generated/openapi",
"test": "jest --passWithNoTests --silent",
"test/integ": "jest --passWithNoTests --silent -c jest.config.integ.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/nodeVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* exact ABI version, so on any other major the addon only loads when it has
* been compiled from source locally.
*/
export const SUPPORTED_NODE_MAJORS = [22, 24];
export const SUPPORTED_NODE_MAJORS = [22, 24, 26];

export function getUnsupportedNodeVersionWarning(
version: string,
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/optimization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
// V8 requires a function to be explicitly marked for manual optimization before
// %OptimizeFunctionOnNextCall is requested on it. Older versions ignored a missing
// marker; since V8 14.6 the mismatch is a fatal CHECK failure that aborts the
// process whenever natives syntax is allowed without --no-opt.
//
// Both natives calls must stay inline: a helper taking `fn` only through an eval
// string looks like it ignores its parameter, and bundlers drop the argument.

export const optimizeFunction = async (fn: CallableFunction) => {
// Source: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#optimization-killers
// a total of 7 calls seems to be the sweet spot
eval("%PrepareFunctionForOptimization(fn)");
await fn();
await fn();
await fn();
Expand All @@ -14,6 +23,7 @@ export const optimizeFunction = async (fn: CallableFunction) => {
export const optimizeFunctionSync = (fn: CallableFunction) => {
// Source: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#optimization-killers
// a total of 7 calls seems to be the sweet spot
eval("%PrepareFunctionForOptimization(fn)");
fn();
fn();
fn();
Expand Down
13 changes: 8 additions & 5 deletions packages/core/tests/nodeVersion.integ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ const { getUnsupportedNodeVersionWarning, warnCi } = require("..") as {
};

describe("getUnsupportedNodeVersionWarning", () => {
it.each(["22.22.2", "24.19.0"])("should not warn on Node %s", (version) => {
expect(getUnsupportedNodeVersionWarning(version)).toBeNull();
});
it.each(["22.22.2", "24.19.0", "26.8.1"])(
"should not warn on Node %s",
(version) => {
expect(getUnsupportedNodeVersionWarning(version)).toBeNull();
},
);

it.each(["20.5.1", "23.11.0", "26.0.0"])(
it.each(["20.5.1", "23.11.0", "27.0.0"])(
"should warn on Node %s",
(version) => {
expect(getUnsupportedNodeVersionWarning(version)).toBe(
`[CodSpeed] Node.js v${version} is not supported: CodSpeed is tested on Node.js 22, 24. Support for other versions is experimental and measurements may be unstable.`,
`[CodSpeed] Node.js v${version} is not supported: CodSpeed is tested on Node.js 22, 24, 26. Support for other versions is experimental and measurements may be unstable.`,
);
},
);
Expand Down
32 changes: 32 additions & 0 deletions packages/core/tests/optimization.integ.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { execFileSync } from "child_process";
import path from "path";

// The optimization helpers reach V8 natives syntax, so their behaviour only shows
// up in a process started with --allow-natives-syntax. A function optimized
// without being marked for manual optimization first aborts the process on
// V8 >= 14.6, which no in-process assertion can observe.
const runWithNatives = (snippet: string): string =>
execFileSync(process.execPath, ["--allow-natives-syntax", "-e", snippet], {
encoding: "utf8",
});

const corePath = JSON.stringify(path.join(__dirname, ".."));

describe("optimization helpers", () => {
it("should optimize a sync function", () => {
const stdout = runWithNatives(
`require(${corePath}).optimizeFunctionSync(() => 1);
console.log("done");`,
);
expect(stdout).toContain("done");
});

it("should optimize an async function", () => {
const stdout = runWithNatives(
`require(${corePath})
.optimizeFunction(async () => 1)
.then(() => console.log("done"));`,
);
expect(stdout).toContain("done");
});
});
2 changes: 1 addition & 1 deletion packages/vitest-plugin/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fromPartial } from "@total-typescript/shoehorn";
import { getV8Flags } from "@codspeed/core";
import { fromPartial } from "@total-typescript/shoehorn";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import codspeedPlugin from "../index";

Expand Down
Loading
Loading