mirror of
https://github.com/oven-sh/bun
synced 2026-02-07 01:18:51 +00:00
Compare commits
4 Commits
dylan/pyth
...
ciro/bench
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a90a4adb3 | ||
|
|
f78995f232 | ||
|
|
5dd9ccb50e | ||
|
|
305df47a2c |
175
bench/mysql/.gitignore
vendored
Normal file
175
bench/mysql/.gitignore
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
27
bench/mysql/README.md
Normal file
27
bench/mysql/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Postgres table load benchmark
|
||||
|
||||
To install dependencies:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
To run in Bun:
|
||||
|
||||
```bash
|
||||
bun ./index.mjs
|
||||
```
|
||||
|
||||
To run in Node.js:
|
||||
|
||||
```bash
|
||||
node index.mjs
|
||||
```
|
||||
|
||||
To run in Deno:
|
||||
|
||||
```bash
|
||||
deno run -A index.mjs
|
||||
```
|
||||
|
||||
You will need a localhost Postgres server running.
|
||||
58
bench/mysql/bun.lock
Normal file
58
bench/mysql/bun.lock
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "mysql",
|
||||
"dependencies": {
|
||||
"mysql2": "^3.14.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
|
||||
|
||||
"@types/node": ["@types/node@24.3.0", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow=="],
|
||||
|
||||
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
|
||||
|
||||
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
||||
|
||||
"generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
|
||||
|
||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||
|
||||
"lru.min": ["lru.min@1.1.2", "", {}, "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg=="],
|
||||
|
||||
"mysql2": ["mysql2@3.14.3", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-fD6MLV8XJ1KiNFIF0bS7Msl8eZyhlTDCDl75ajU5SJtpdx9ZPEACulJcqJWr1Y8OYyxsFc4j3+nflpmhxCU5aQ=="],
|
||||
|
||||
"named-placeholders": ["named-placeholders@1.1.3", "", { "dependencies": { "lru-cache": "^7.14.1" } }, "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
|
||||
|
||||
"sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
|
||||
"undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
|
||||
}
|
||||
}
|
||||
8
bench/mysql/go-mysql/go.mod
Normal file
8
bench/mysql/go-mysql/go.mod
Normal file
@@ -0,0 +1,8 @@
|
||||
module bench
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
||||
)
|
||||
4
bench/mysql/go-mysql/go.sum
Normal file
4
bench/mysql/go-mysql/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
111
bench/mysql/go-mysql/main.go
Normal file
111
bench/mysql/go-mysql/main.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
type UserRow struct {
|
||||
ID uint64
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string
|
||||
DOB time.Time // MySQL DATE -> time.Time (use parseTime=true)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Rust DSN: mysql://root:bun@localhost:55034/mysql
|
||||
// Go DSN (mysql driver): user:pass@tcp(host:port)/db?params
|
||||
dsn := "root:bun@tcp(localhost:55034)/mysql?parseTime=true&interpolateParams=true"
|
||||
|
||||
db, err := sql.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// --- Pool settings (cap at 10, like Rust .max_size(10)) ---
|
||||
db.SetMaxOpenConns(10)
|
||||
db.SetMaxIdleConns(10)
|
||||
db.SetConnMaxLifetime(60 * time.Minute)
|
||||
|
||||
// Make sure we can connect
|
||||
if err := db.Ping(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Prepare once (Stmt is safe for concurrent use by multiple goroutines)
|
||||
stmt, err := db.PrepareContext(ctx, "SELECT * FROM users_bun_bench LIMIT 100")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
// Workload config
|
||||
const totalJobs = 1_000_000
|
||||
// choose a reasonable worker count; you can tweak this
|
||||
workers := 10
|
||||
|
||||
start := time.Now()
|
||||
|
||||
// Worker pool
|
||||
jobs := make(chan struct{}, workers)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
runOne := func() {
|
||||
defer wg.Done()
|
||||
|
||||
for range jobs {
|
||||
// Run the query and scan rows (discarding results to avoid huge memory use)
|
||||
rows, err := stmt.QueryContext(ctx)
|
||||
if err != nil {
|
||||
// Match Rust's "unwrap()" behavior by failing loudly
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var u UserRow
|
||||
if err := rows.Scan(&u.ID, &u.FirstName, &u.LastName, &u.Email, &u.DOB); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Start workers
|
||||
wg.Add(workers)
|
||||
for i := 0; i < workers; i++ {
|
||||
go runOne()
|
||||
}
|
||||
|
||||
// Enqueue jobs
|
||||
for i := 0; i < totalJobs; i++ {
|
||||
jobs <- struct{}{}
|
||||
}
|
||||
close(jobs)
|
||||
|
||||
// Wait for completion
|
||||
wg.Wait()
|
||||
|
||||
dur := time.Since(start)
|
||||
fmt.Printf("go-sql: %v\n", dur)
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
36
bench/mysql/index.mjs
Normal file
36
bench/mysql/index.mjs
Normal file
@@ -0,0 +1,36 @@
|
||||
const sql = new Bun.SQL("mysql://root:bun@localhost:55034");
|
||||
|
||||
// Create the table if it doesn't exist
|
||||
await sql`CREATE TABLE IF NOT EXISTS users_bun_bench (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
first_name VARCHAR(255) NOT NULL,
|
||||
last_name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
dob DATE NOT NULL
|
||||
)`;
|
||||
|
||||
// Check if users already exist
|
||||
const existingUsers = await sql`SELECT COUNT(*) as count FROM users_bun_bench`;
|
||||
|
||||
if (+(existingUsers?.[0]?.count ?? existingUsers?.count) < 100) {
|
||||
// Generate 100 users if none exist
|
||||
const users = Array.from({ length: 100 }, (_, i) => ({
|
||||
first_name: `FirstName${i}`,
|
||||
last_name: `LastName${i}`,
|
||||
email: `user${i}@example.com`,
|
||||
dob: new Date(1970 + Math.floor(Math.random() * 30), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28))
|
||||
.toISOString()
|
||||
.split("T")[0],
|
||||
}));
|
||||
|
||||
// Insert all users
|
||||
await sql`INSERT INTO users_bun_bench ${sql(users)}`;
|
||||
}
|
||||
|
||||
console.time("Bun.sql");
|
||||
let promises = [];
|
||||
for (let i = 0; i < 1_000_000; i++) {
|
||||
promises.push(sql`SELECT * FROM users_bun_bench LIMIT 100`);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
console.timeEnd("Bun.sql");
|
||||
29
bench/mysql/mariadb.mjs
Normal file
29
bench/mysql/mariadb.mjs
Normal file
@@ -0,0 +1,29 @@
|
||||
import mariadb from "mariadb";
|
||||
const pool = mariadb.createPool({
|
||||
host: "localhost",
|
||||
user: "root",
|
||||
password: "bun",
|
||||
database: "mysql",
|
||||
port: 55034,
|
||||
connectionLimit: 10,
|
||||
acquireTimeout: 600000,
|
||||
});
|
||||
|
||||
async function executeQuery() {
|
||||
let conn;
|
||||
try {
|
||||
conn = await pool.getConnection();
|
||||
return await conn.query("SELECT * FROM users_bun_bench LIMIT 100");
|
||||
} finally {
|
||||
if (conn) conn.release(); //release to pool
|
||||
}
|
||||
}
|
||||
|
||||
console.time("mariadb");
|
||||
let promises = [];
|
||||
for (let i = 0; i < 1_000_000; i++) {
|
||||
promises.push(executeQuery());
|
||||
}
|
||||
await Promise.all(promises);
|
||||
console.timeEnd("mariadb");
|
||||
await pool.end();
|
||||
57
bench/mysql/mysql2.mjs
Normal file
57
bench/mysql/mysql2.mjs
Normal file
@@ -0,0 +1,57 @@
|
||||
import { createPool } from "mysql2/promise";
|
||||
const pool = createPool({
|
||||
host: "localhost",
|
||||
user: "root",
|
||||
password: "bun",
|
||||
database: "mysql",
|
||||
port: 55034,
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
idleTimeout: 60000,
|
||||
queueLimit: 0,
|
||||
enableKeepAlive: true,
|
||||
keepAliveInitialDelay: 0,
|
||||
});
|
||||
|
||||
// Create the table if it doesn't exist
|
||||
await pool.execute(`CREATE TABLE IF NOT EXISTS users_bun_bench (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
first_name VARCHAR(255) NOT NULL,
|
||||
last_name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
dob DATE NOT NULL
|
||||
)`);
|
||||
|
||||
// Check if users already exist
|
||||
const existingUsers = await pool.execute(`SELECT COUNT(*) as count FROM users_bun_bench`);
|
||||
|
||||
if (+(existingUsers?.[0]?.count ?? existingUsers?.count) < 100) {
|
||||
// Generate 100 users if none exist
|
||||
const users = Array.from({ length: 100 }, (_, i) => ({
|
||||
first_name: `FirstName${i}`,
|
||||
last_name: `LastName${i}`,
|
||||
email: `user${i}@example.com`,
|
||||
dob: new Date(1970 + Math.floor(Math.random() * 30), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28))
|
||||
.toISOString()
|
||||
.split("T")[0],
|
||||
}));
|
||||
|
||||
for (let user of users) {
|
||||
await pool.execute(
|
||||
`INSERT INTO users_bun_bench (first_name, last_name, email, dob) VALUES (?, ?, ?, ?)`,
|
||||
user.first_name,
|
||||
user.last_name,
|
||||
user.email,
|
||||
user.dbo,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.time("mysql2");
|
||||
let promises = [];
|
||||
for (let i = 0; i < 1_000_000; i++) {
|
||||
promises.push(pool.execute(`SELECT * FROM users_bun_bench LIMIT 100`));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
console.timeEnd("mysql2");
|
||||
await pool.end();
|
||||
14
bench/mysql/package.json
Normal file
14
bench/mysql/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "mysql",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mysql2": "^3.14.3"
|
||||
}
|
||||
}
|
||||
1668
bench/mysql/rust-diesel-async/Cargo.lock
generated
Normal file
1668
bench/mysql/rust-diesel-async/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
bench/mysql/rust-diesel-async/Cargo.toml
Normal file
11
bench/mysql/rust-diesel-async/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "rust-mysql"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
diesel = { version = "2", features = ["mysql", "chrono"] }
|
||||
diesel-async = { version = "0.6.1", features = ["mysql", "tokio", "bb8"] }
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
futures = "0.3"
|
||||
chrono = { version = "0.4", features = ["serde"] } # remove `serde` if you don't need it
|
||||
60
bench/mysql/rust-diesel-async/src/main.rs
Normal file
60
bench/mysql/rust-diesel-async/src/main.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
use diesel_async::pooled_connection::bb8::{Pool, RunError};
|
||||
use diesel_async::pooled_connection::AsyncDieselConnectionManager;
|
||||
use diesel_async::{AsyncMysqlConnection, RunQueryDsl};
|
||||
use futures::future::join_all;
|
||||
use diesel::sql_query;
|
||||
use std::time::Instant;
|
||||
use diesel::sql_types::*;
|
||||
use std::time::Duration;
|
||||
|
||||
|
||||
#[derive(Debug, diesel::QueryableByName)]
|
||||
struct UserRow {
|
||||
#[diesel(sql_type = Unsigned<BigInt>)]
|
||||
id: u64,
|
||||
#[diesel(sql_type = Varchar)]
|
||||
first_name: String,
|
||||
#[diesel(sql_type = Varchar)]
|
||||
last_name: String,
|
||||
#[diesel(sql_type = Varchar)]
|
||||
email: String,
|
||||
#[diesel(sql_type = Date)]
|
||||
dob: chrono::NaiveDate,
|
||||
}
|
||||
#[tokio::main(flavor = "multi_thread")]
|
||||
async fn main() -> Result<(), RunError> {
|
||||
let config = AsyncDieselConnectionManager::<AsyncMysqlConnection>::new(
|
||||
"mysql://root:bun@localhost:55034/mysql",
|
||||
|
||||
);
|
||||
let pool = Pool::builder().connection_timeout(Duration::from_secs(36000)).max_size(10).build(config).await?;
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// for i in 0..10usize {
|
||||
let tasks: Vec<_> = (0..1_000_000usize).map(|_| {
|
||||
let pool = pool.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut conn = pool.get().await.unwrap();
|
||||
let rows: Vec<UserRow> = sql_query("SELECT * FROM users_bun_bench LIMIT 100")
|
||||
.get_results(&mut conn)
|
||||
.await.unwrap();
|
||||
Ok::<Vec<UserRow>, diesel::result::Error>(rows)
|
||||
})
|
||||
}).collect();
|
||||
|
||||
// Wait for all the concurrent tasks to finish
|
||||
// let _ = join_all(tasks).await;
|
||||
for task in tasks {
|
||||
let _ = task.await;
|
||||
}
|
||||
// }
|
||||
let duration = start.elapsed();
|
||||
println!(
|
||||
"diesel-async: {:.2?}",
|
||||
duration
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
2070
bench/mysql/rust-sqlx/Cargo.lock
generated
Normal file
2070
bench/mysql/rust-sqlx/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
bench/mysql/rust-sqlx/Cargo.toml
Normal file
10
bench/mysql/rust-sqlx/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "tokio-mysql-pool"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
sqlx = { version = "0.7", features = ["mysql", "runtime-tokio-rustls"] }
|
||||
anyhow = "1"
|
||||
futures = "0.3"
|
||||
38
bench/mysql/rust-sqlx/src/main.rs
Normal file
38
bench/mysql/rust-sqlx/src/main.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use futures::future::join_all;
|
||||
use sqlx::{mysql::MySqlPoolOptions, Row};
|
||||
use std::time::Instant;
|
||||
|
||||
#[tokio::main(flavor = "multi_thread")]
|
||||
async fn main() -> Result<(), sqlx::Error> {
|
||||
let db_url = "mysql://root:bun@localhost:55034/mysql";
|
||||
|
||||
// Create a Tokio-backed SQLx pool with a hard cap of 10 connections.
|
||||
let pool = MySqlPoolOptions::new()
|
||||
.max_connections(10)
|
||||
.connect(&db_url)
|
||||
.await?;
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
let tasks: Vec<_> = (0..1_000_000usize).map(|_| {
|
||||
let pool = pool.clone();
|
||||
tokio::spawn(async move {
|
||||
sqlx::query("SELECT * FROM users_bun_bench LIMIT 100")
|
||||
.fetch_all(&pool).await
|
||||
})
|
||||
}).collect();
|
||||
|
||||
for task in tasks {
|
||||
let _ = task.await;
|
||||
}
|
||||
|
||||
let duration = start.elapsed();
|
||||
|
||||
println!(
|
||||
"sqlx: {:.2?}",
|
||||
duration
|
||||
);
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
27
bench/mysql/tsconfig.json
Normal file
27
bench/mysql/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "Preserve",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
||||
31
bun.lock
31
bun.lock
@@ -3,6 +3,9 @@
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "bun",
|
||||
"dependencies": {
|
||||
"mysql2": "^3.14.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/common": "^1.2.3",
|
||||
"@lezer/cpp": "^1.1.3",
|
||||
@@ -166,6 +169,8 @@
|
||||
|
||||
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
|
||||
|
||||
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
||||
|
||||
"before-after-hook": ["before-after-hook@2.2.3", "", {}, "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="],
|
||||
|
||||
"bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="],
|
||||
@@ -194,6 +199,8 @@
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
||||
|
||||
"deprecation": ["deprecation@2.3.1", "", {}, "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="],
|
||||
|
||||
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
||||
@@ -204,14 +211,20 @@
|
||||
|
||||
"esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
|
||||
|
||||
"generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],
|
||||
|
||||
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
|
||||
|
||||
"header-case": ["header-case@2.0.4", "", { "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" } }, "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q=="],
|
||||
|
||||
"html-minifier": ["html-minifier@4.0.0", "", { "dependencies": { "camel-case": "^3.0.0", "clean-css": "^4.2.1", "commander": "^2.19.0", "he": "^1.2.0", "param-case": "^2.1.1", "relateurl": "^0.2.7", "uglify-js": "^3.5.1" }, "bin": { "html-minifier": "./cli.js" } }, "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
|
||||
|
||||
"is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
|
||||
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="],
|
||||
@@ -256,11 +269,15 @@
|
||||
|
||||
"lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="],
|
||||
|
||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||
|
||||
"lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="],
|
||||
|
||||
"lru-cache": ["@wolfy1339/lru-cache@11.0.2-patch.1", "", {}, "sha512-BgYZfL2ADCXKOw2wJtkM3slhHotawWkgIRRxq4wEybnZQPjvAp71SPX35xepMykTw8gXlzWcWPTY31hlbnRsDA=="],
|
||||
"lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||
|
||||
"lru.min": ["lru.min@1.1.2", "", {}, "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg=="],
|
||||
|
||||
"marked": ["marked@12.0.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="],
|
||||
|
||||
@@ -268,6 +285,10 @@
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"mysql2": ["mysql2@3.14.3", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-fD6MLV8XJ1KiNFIF0bS7Msl8eZyhlTDCDl75ajU5SJtpdx9ZPEACulJcqJWr1Y8OYyxsFc4j3+nflpmhxCU5aQ=="],
|
||||
|
||||
"named-placeholders": ["named-placeholders@1.1.3", "", { "dependencies": { "lru-cache": "^7.14.1" } }, "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w=="],
|
||||
|
||||
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
|
||||
|
||||
"octokit": ["octokit@3.2.2", "", { "dependencies": { "@octokit/app": "^14.0.2", "@octokit/core": "^5.0.0", "@octokit/oauth-app": "^6.0.0", "@octokit/plugin-paginate-graphql": "^4.0.0", "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1", "@octokit/plugin-retry": "^6.0.0", "@octokit/plugin-throttling": "^8.0.0", "@octokit/request-error": "^5.0.0", "@octokit/types": "^13.0.0", "@octokit/webhooks": "^12.3.1" } }, "sha512-7Abo3nADdja8l/aglU6Y3lpnHSfv0tw7gFPiqzry/yCU+2gTAX7R1roJ8hJrxIK+S1j+7iqRJXtmuHJ/UDsBhQ=="],
|
||||
@@ -294,18 +315,24 @@
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
|
||||
|
||||
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||
|
||||
"sentence-case": ["sentence-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg=="],
|
||||
|
||||
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
|
||||
|
||||
"snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
@@ -328,6 +355,8 @@
|
||||
|
||||
"@octokit/app/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="],
|
||||
|
||||
"@octokit/auth-app/lru-cache": ["@wolfy1339/lru-cache@11.0.2-patch.1", "", {}, "sha512-BgYZfL2ADCXKOw2wJtkM3slhHotawWkgIRRxq4wEybnZQPjvAp71SPX35xepMykTw8gXlzWcWPTY31hlbnRsDA=="],
|
||||
|
||||
"@octokit/auth-unauthenticated/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="],
|
||||
|
||||
"@octokit/plugin-throttling/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="],
|
||||
|
||||
@@ -85,5 +85,8 @@
|
||||
"node:test:cp": "bun ./scripts/fetch-node-test.ts ",
|
||||
"clean:zig": "rm -rf build/debug/cache/zig build/debug/CMakeCache.txt 'build/debug/*.o' .zig-cache zig-out || true",
|
||||
"sync-webkit-source": "bun ./scripts/sync-webkit-source.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"mysql2": "^3.14.3"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user