Compare commits

..

1 Commits

Author SHA1 Message Date
Jarred Sumner
432116f76a [windows] Use fewer system calls to get the file type in the module resolver 2024-01-24 21:50:59 -08:00
514 changed files with 12667 additions and 25693 deletions

View File

@@ -57,7 +57,6 @@ jobs:
timeout-minutes: 60
if: github.repository_owner == 'oven-sh'
steps:
- run: git config --global core.autocrlf false && git config --global core.eol lf
- uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
@@ -117,7 +116,6 @@ jobs:
cpu: [haswell, nehalem]
arch: [x86_64]
steps:
- run: git config --global core.autocrlf false && git config --global core.eol lf
- name: Checkout
uses: actions/checkout@v4
- name: Clone Submodules
@@ -178,11 +176,6 @@ jobs:
path: bun-deps
key: ${{ steps.cache-deps-restore.outputs.cache-primary-key }}
# TODO(@paperdave): stop relying on this and use bun.exe to build itself.
# we cant do that now because there isn't a tagged release to use.
#
# and at the time of writing, the minimum canary required to work is not
# yet released as it is the one *this* commit.
windows-codegen:
name: Codegen
runs-on: ubuntu-latest
@@ -221,7 +214,6 @@ jobs:
cpu: [haswell, nehalem]
arch: [x86_64]
steps:
- run: git config --global core.autocrlf false && git config --global core.eol lf
- uses: actions/checkout@v4
- uses: KyleMayes/install-llvm-action@1a3da29f56261a1e1f937ec88f0856a9b8321d7e
with:
@@ -276,12 +268,11 @@ jobs:
arch: [x86_64]
name: Link
needs: [windows-dependencies, windows-codegen, windows-cpp, windows-zig]
runs-on: windows-small
runs-on: windows-latest
if: github.repository_owner == 'oven-sh'
timeout-minutes: 30
permissions: write-all
steps:
- run: git config --global core.autocrlf false && git config --global core.eol lf
- uses: actions/checkout@v4
- uses: KyleMayes/install-llvm-action@1a3da29f56261a1e1f937ec88f0856a9b8321d7e
with:
@@ -379,7 +370,7 @@ jobs:
**[Build Output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})** | [Commit](https://github.com/oven-sh/bun/commits/${{github.sha}})
windows-test:
name: Test
runs-on: windows-small
runs-on: windows-latest
needs: [windows-link]
if: github.event_name == 'pull_request' && github.repository_owner == 'oven-sh'
permissions:
@@ -395,7 +386,6 @@ jobs:
cpu: [haswell]
arch: [x86_64]
steps:
- run: git config --global core.autocrlf false && git config --global core.eol lf
- id: checkout
name: Checkout
uses: actions/checkout@v3
@@ -439,22 +429,6 @@ jobs:
$null = node packages/bun-internal-test/src/runner.node.mjs ${{runner.temp}}/release/${{env.tag}}-${{ matrix.arch == 'x86_64' && 'x64' || 'aarch64' }}${{ matrix.cpu == 'nehalem' && '-baseline' || '' }}-profile/bun.exe || $true
} catch {}
$ErrorActionPreference = "Stop"
- uses: sarisia/actions-status-discord@v1
if: always() && steps.test.outputs.failing_tests != '' && github.event_name == 'pull_request'
with:
title: ""
webhook: ${{ secrets.DISCORD_WEBHOOK_WINTEST }}
status: "failure"
noprefix: true
nocontext: true
description: |
### ❌🪟 [${{github.event.pull_request.title}}](https://github.com/oven-sh/bun/pull/${{github.event.number}})
@${{ github.actor }}, there are **${{ steps.test.outputs.failing_test_count }} failing tests** on Windows ${{ matrix.arch }}${{ matrix.cpu == 'nehalem' && ' Baseline' || '' }}
${{ steps.test.outputs.failing_tests }}
[Full Test Output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})
- uses: sarisia/actions-status-discord@v1
if: always() && steps.test.outputs.regressing_tests != '' && github.event_name == 'pull_request'
with:

332
.gitignore vendored
View File

@@ -1,168 +1,166 @@
.DS_Store
zig-cache
packages/*/*.wasm
*.o
*.a
profile.json
.env
node_modules
.envrc
.swcrc
yarn.lock
dist
*.tmp
*.log
*.out.js
*.out.refresh.js
**/package-lock.json
build
*.wat
zig-out
pnpm-lock.yaml
README.md.template
src/deps/zig-clap/example
src/deps/zig-clap/README.md
src/deps/zig-clap/.github
src/deps/zig-clap/.gitattributes
out
outdir
.trace
cover
coverage
coverv
*.trace
github
out.*
out
.parcel-cache
esbuilddir
*.bun
parceldist
esbuilddir
outdir/
outcss
.next
txt.js
.idea
.vscode/cpp*
.vscode/clang*
node_modules_*
*.jsb
*.zip
bun-zigld
bun-singlehtreaded
bun-nomimalloc
bun-mimalloc
examples/lotta-modules/bun-yday
examples/lotta-modules/bun-old
examples/lotta-modules/bun-nofscache
src/node-fallbacks/out/*
src/node-fallbacks/node_modules
sign.json
release/
*.dmg
sign.*.json
packages/debug-*
packages/bun-cli/postinstall.js
packages/bun-*/bun
packages/bun-*/bun-profile
packages/bun-*/debug-bun
packages/bun-*/*.o
packages/bun-cli/postinstall.js
packages/bun-cli/bin/*
bun-test-scratch
misctools/fetch
src/deps/libiconv
src/deps/openssl
src/tests.zig
*.blob
src/deps/s2n-tls
.npm
.npm.gz
bun-binary
src/deps/PLCrashReporter/
*.dSYM
*.crash
misctools/sha
packages/bun-wasm/*.mjs
packages/bun-wasm/*.cjs
packages/bun-wasm/*.map
packages/bun-wasm/*.js
packages/bun-wasm/*.d.ts
packages/bun-wasm/*.d.cts
packages/bun-wasm/*.d.mts
*.bc
src/fallback.version
src/runtime.version
*.sqlite
*.database
*.db
misctools/machbench
*.big
.eslintcache
/bun-webkit
src/deps/c-ares/build
src/bun.js/bindings-obj
src/bun.js/debug-bindings-obj
failing-tests.txt
test.txt
myscript.sh
cold-jsc-start
cold-jsc-start.d
/testdir
/test.ts
/test.js
src/js/out/modules*
src/js/out/functions*
src/js/out/tmp
src/js/out/DebugPath.h
make-dev-stats.csv
.uuid
tsconfig.tsbuildinfo
test/js/bun/glob/fixtures
*.lib
*.pdb
CMakeFiles
build.ninja
.ninja_deps
.ninja_log
CMakeCache.txt
cmake_install.cmake
compile_commands.json
*.lib
x64
**/*.vcxproj*
**/*.sln*
**/*.dir
**/*.pdb
/.webkit-cache
/.cache
/src/deps/libuv
/build-*/
.vs
**/.verdaccio-db.json
/test-report.md
.DS_Store
zig-cache
packages/*/*.wasm
*.o
*.a
profile.json
node_modules
.envrc
.swcrc
yarn.lock
dist
*.tmp
*.log
*.out.js
*.out.refresh.js
**/package-lock.json
build
*.wat
zig-out
pnpm-lock.yaml
README.md.template
src/deps/zig-clap/example
src/deps/zig-clap/README.md
src/deps/zig-clap/.github
src/deps/zig-clap/.gitattributes
out
outdir
.trace
cover
coverage
coverv
*.trace
github
out.*
out
.parcel-cache
esbuilddir
*.bun
parceldist
esbuilddir
outdir/
outcss
.next
txt.js
.idea
.vscode/cpp*
.vscode/clang*
node_modules_*
*.jsb
*.zip
bun-zigld
bun-singlehtreaded
bun-nomimalloc
bun-mimalloc
examples/lotta-modules/bun-yday
examples/lotta-modules/bun-old
examples/lotta-modules/bun-nofscache
src/node-fallbacks/out/*
src/node-fallbacks/node_modules
sign.json
release/
*.dmg
sign.*.json
packages/debug-*
packages/bun-cli/postinstall.js
packages/bun-*/bun
packages/bun-*/bun-profile
packages/bun-*/debug-bun
packages/bun-*/*.o
packages/bun-cli/postinstall.js
packages/bun-cli/bin/*
bun-test-scratch
misctools/fetch
src/deps/libiconv
src/deps/openssl
src/tests.zig
*.blob
src/deps/s2n-tls
.npm
.npm.gz
bun-binary
src/deps/PLCrashReporter/
*.dSYM
*.crash
misctools/sha
packages/bun-wasm/*.mjs
packages/bun-wasm/*.cjs
packages/bun-wasm/*.map
packages/bun-wasm/*.js
packages/bun-wasm/*.d.ts
packages/bun-wasm/*.d.cts
packages/bun-wasm/*.d.mts
*.bc
src/fallback.version
src/runtime.version
*.sqlite
*.database
*.db
misctools/machbench
*.big
.eslintcache
/bun-webkit
src/deps/c-ares/build
src/bun.js/bindings-obj
src/bun.js/debug-bindings-obj
failing-tests.txt
test.txt
myscript.sh
cold-jsc-start
cold-jsc-start.d
/test.ts
/test.js
src/js/out/modules*
src/js/out/functions*
src/js/out/tmp
src/js/out/DebugPath.h
make-dev-stats.csv
.uuid
tsconfig.tsbuildinfo
test/js/bun/glob/fixtures
*.lib
*.pdb
CMakeFiles
build.ninja
.ninja_deps
.ninja_log
CMakeCache.txt
cmake_install.cmake
compile_commands.json
*.lib
x64
**/*.vcxproj*
**/*.sln*
**/*.dir
**/*.pdb
/.webkit-cache
/.cache
/src/deps/libuv
/build-*/
.vs
**/.verdaccio-db.json
/test-report.md
/test-report.json

14
.prettierignore Normal file
View File

@@ -0,0 +1,14 @@
src/fallback.html
src/bun.js/WebKit
src/js/out
src/*.out.js
src/*out.*.js
src/deps
src/test/fixtures
src/react-refresh.js
test/snapshots
test/snapshots-no-hmr
test/js/deno/*.test.ts
test/js/deno/**/*.test.ts
bench/react-hello-world/react-hello-world.node.js
test/cli/run/encoding-utf16-le-bom.ts

15
.prettierrc.cjs Normal file
View File

@@ -0,0 +1,15 @@
module.exports = {
arrowParens: "avoid",
printWidth: 120,
trailingComma: "all",
useTabs: false,
quoteProps: "preserve",
overrides: [
{
files: ["*.md"],
options: {
printWidth: 80,
},
},
],
};

View File

@@ -3,7 +3,6 @@
{
"name": "Debug",
"forcedInclude": ["${workspaceFolder}/src/bun.js/bindings/root.h"],
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"includePath": [
"${workspaceFolder}/build/bun-webkit/include",
"${workspaceFolder}/build/codegen",

View File

@@ -1,33 +1,10 @@
{
"recommendations": [
// Zig
"ziglang.vscode-zig",
// C/C++
"clang.clangd",
"ms-vscode.cmake-tools",
"esbenp.prettier-vscode",
"xaver.clang-format",
"vadimcn.vscode-lldb",
// JavaScript
"oven.bun-vscode",
"biomejs.biome",
// TypeScript
"better-ts-errors.better-ts-errors",
"MylesMurphy.prettify-ts",
// Markdown
"bierner.markdown-preview-github-styles",
"bierner.markdown-emoji",
"bierner.emojisense",
"bierner.markdown-checkbox",
"bierner.jsdoc-markdown-highlighting",
// TOML
"tamasfe.even-better-toml",
// Other
"bierner.comment-tagged-templates",
"ms-vscode.cpptools"
]
}

1183
.vscode/launch.json generated vendored

File diff suppressed because it is too large Load Diff

229
.vscode/settings.json vendored
View File

@@ -1,89 +1,48 @@
{
// Editor
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
// Search
"git.autoRepositoryDetection": "openEditors",
"search.quickOpen.includeSymbols": false,
"search.seedWithNearestWord": true,
"search.smartCase": true,
"search.exclude": {
"node_modules": true,
".git": true,
"src/bun.js/WebKit": true,
".git": true,
"src/deps/*/**": true
},
"search.followSymlinks": false,
"search.useIgnoreFiles": true,
// Git
"git.autoRepositoryDetection": "openEditors",
"git.ignoreSubmodules": true,
"git.ignoreLimitWarning": true,
// Zig
"zig.initialSetupDone": true,
"zig.buildOnSave": false,
"zig.formattingProvider": "zls",
"zig.buildOption": "build",
"zig.buildFilePath": "${workspaceFolder}/build.zig",
"zig.path": "${workspaceFolder}/.cache/zig/zig.exe",
"zig.formattingProvider": "zls",
"zig.zls.enableInlayHints": false,
"zig.initialSetupDone": true,
"editor.formatOnSave": true,
"[zig]": {
"editor.tabSize": 4,
"editor.useTabStops": false,
"editor.defaultFormatter": "ziglang.vscode-zig"
},
// C++
"lldb.verboseLogging": false,
"cmake.configureOnOpen": false,
"C_Cpp.errorSquiggles": "enabled",
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
"[ts]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[c]": {
"editor.defaultFormatter": "xaver.clang-format"
"[js]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[h]": {
"editor.defaultFormatter": "xaver.clang-format"
"zig.zls.enableInlayHints": false,
"zig.path": "${workspaceFolder}/.cache/zig/zig.exe",
"git.ignoreSubmodules": true,
"[jsx]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// JavaScript
"prettier.enable": false,
"eslint.workingDirectories": ["${workspaceFolder}/packages/bun-types"],
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome",
"[tsx]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
// TypeScript
"typescript.tsdk": "${workspaceFolder}/node_modules/typescript/lib",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
// JSON
"[json]": {
"editor.defaultFormatter": "biomejs.biome",
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome",
},
// Markdown
"[yaml]": {},
"[markdown]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.unicodeHighlight.ambiguousCharacters": false,
"editor.unicodeHighlight.invisibleCharacters": false,
"diffEditor.ignoreTrimWhitespace": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.wordWrap": "on",
"editor.quickSuggestions": {
"comments": "off",
@@ -91,18 +50,7 @@
"other": "off"
}
},
// TOML
"[toml]": {
"editor.defaultFormatter": "biomejs.biome",
},
// YAML
"[yaml]": {
"editor.defaultFormatter": "biomejs.biome",
},
// Files
"lldb.verboseLogging": false,
"files.exclude": {
"**/.git": true,
"**/.svn": true,
@@ -112,6 +60,7 @@
"**/Thumbs.db": true,
"**/*.xcworkspacedata": true,
"**/*.xcscheme": true,
"**/*.pem": true,
"**/*.xcodeproj": true,
"src/bun.js/WebKit": true,
"src/deps/libarchive": true,
@@ -126,10 +75,7 @@
"src/deps/tinycc": true,
"src/deps/zstd": true,
"**/*.i": true,
"packages/bun-uws/fuzzing/seed-corpus": true
},
"files.associations": {
"*.idl": "cpp"
"packages/bun-uws/fuzzing/seed-corpus/**/*": true
},
"C_Cpp.files.exclude": {
"**/.vscode": true,
@@ -149,4 +95,137 @@
"WebKit/WebKitBuild": true,
"WebKit/WebInspectorUI": true
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"[h]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"[c]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"files.associations": {
"*.lock": "yarnlock",
"*.idl": "cpp",
"memory": "cpp",
"iostream": "cpp",
"algorithm": "cpp",
"random": "cpp",
"ios": "cpp",
"filesystem": "cpp",
"__locale": "cpp",
"type_traits": "cpp",
"__mutex_base": "cpp",
"__string": "cpp",
"string": "cpp",
"string_view": "cpp",
"typeinfo": "cpp",
"__config": "cpp",
"__nullptr": "cpp",
"exception": "cpp",
"__bit_reference": "cpp",
"atomic": "cpp",
"utility": "cpp",
"sstream": "cpp",
"__functional_base": "cpp",
"new": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__hash_table": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tuple": "cpp",
"array": "cpp",
"bit": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"iterator": "cpp",
"limits": "cpp",
"locale": "cpp",
"mutex": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"stack": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"thread": "cpp",
"tuple": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"__bits": "cpp",
"__tree": "cpp",
"map": "cpp",
"numeric": "cpp",
"set": "cpp",
"__memory": "cpp",
"memory_resource": "cpp",
"*.tcc": "cpp",
"list": "cpp",
"shared_mutex": "cpp",
"cinttypes": "cpp",
"variant": "cpp",
"sysctl.h": "c",
"queue": "cpp",
"compare": "cpp",
"concepts": "cpp",
"typeindex": "cpp",
"__verbose_abort": "cpp",
"__std_stream": "cpp",
"any": "cpp",
"charconv": "cpp",
"csignal": "cpp",
"format": "cpp",
"forward_list": "cpp",
"future": "cpp",
"regex": "cpp",
"span": "cpp",
"valarray": "cpp",
"codecvt": "cpp",
"xtr1common": "cpp",
"stop_token": "cpp",
"xfacet": "cpp",
"xhash": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocbuf": "cpp",
"xlocinfo": "cpp",
"xlocmes": "cpp",
"xlocmon": "cpp",
"xlocnum": "cpp",
"xloctime": "cpp",
"xmemory": "cpp",
"xstring": "cpp",
"xtree": "cpp",
"xutility": "cpp"
},
"C_Cpp.errorSquiggles": "enabled",
"eslint.workingDirectories": ["packages/bun-types"],
"typescript.tsdk": "node_modules/typescript/lib",
"cmake.configureOnOpen": false,
"git.ignoreLimitWarning": true
}

49
.vscode/tasks.json vendored
View File

@@ -2,51 +2,10 @@
"version": "2.0.0",
"tasks": [
{
"label": "Rebuild Debug",
"command": "ninja",
"args": ["-Cbuild"],
"type": "process",
"label": "Install Dependencies",
"command": "scripts/all-dependencies.sh",
"windows": {
"command": "scripts/all-dependencies.ps1"
},
"icon": {
"id": "arrow-down"
},
"options": {
"cwd": "${workspaceFolder}"
},
},
{
"type": "process",
"label": "Setup Environment",
"dependsOn": ["Install Dependencies"],
"command": "scripts/setup.sh",
"windows": {
"command": "scripts/setup.ps1"
},
"icon": {
"id": "check"
},
"options": {
"cwd": "${workspaceFolder}"
},
},
{
"type": "process",
"label": "Build Bun",
"dependsOn": ["Setup Environment"],
"command": "bun",
"args": ["run", "build"],
"icon": {
"id": "gear"
},
"options": {
"cwd": "${workspaceFolder}"
},
"isBuildCommand": true,
"runOptions": {
"instanceLimit": 1,
"reevaluateOnRerun": true,
},
},
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -290,6 +290,7 @@ ENV CCACHE_DIR=/ccache
COPY Makefile ${BUN_DIR}/Makefile
COPY src/deps/zstd ${BUN_DIR}/src/deps/zstd
COPY .prettierrc.cjs ${BUN_DIR}/.prettierrc.cjs
WORKDIR $BUN_DIR
@@ -377,7 +378,7 @@ RUN --mount=type=cache,target=/ccache mkdir ${BUN_DIR}/build \
FROM bun-base-with-zig as bun-codegen-for-zig
COPY package.json bun.lockb Makefile .gitmodules ${BUN_DIR}/
COPY package.json bun.lockb Makefile .gitmodules .prettierrc.cjs ${BUN_DIR}/
COPY src/runtime ${BUN_DIR}/src/runtime
COPY src/runtime.js src/runtime.bun.js ${BUN_DIR}/src/
COPY packages/bun-error ${BUN_DIR}/packages/bun-error

View File

@@ -823,6 +823,7 @@ fmt: fmt-cpp fmt-zig
api:
./node_modules/.bin/peechy --schema src/api/schema.peechy --esm src/api/schema.js --ts src/api/schema.d.ts --zig src/api/schema.zig
$(ZIG) fmt src/api/schema.zig
$(PRETTIER) --config=.prettierrc.cjs --write src/api/schema.js src/api/schema.d.ts
.PHONY: node-fallbacks
node-fallbacks:
@@ -1722,7 +1723,7 @@ sizegen:
# Linux uses bundled SQLite3
ifeq ($(OS_NAME),linux)
sqlite:
$(CC) $(EMIT_LLVM_FOR_RELEASE) $(CFLAGS) $(INCLUDE_DIRS) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 $(SRC_DIR)/sqlite/sqlite3.c -c -o $(SQLITE_OBJECT)
$(CC) $(EMIT_LLVM_FOR_RELEASE) $(CFLAGS) $(INCLUDE_DIRS) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 $(SRC_DIR)/sqlite/sqlite3.c -c -o $(SQLITE_OBJECT)
endif
picohttp:

View File

@@ -7,166 +7,280 @@
"version": "0.0.34"
},
"timestamps": [
16336202536562, 16336202536908, 16336202537294, 16336202537705, 16336202538114, 16336202538534, 16336202538941,
16336202539323, 16336202539742, 16336202540159, 16336202540877, 16336202541310, 16336202541749, 16336202542159,
16336202542565, 16336202542996, 16336202543333, 16336202543761, 16336202544159, 16336202544534, 16336202544944,
16336202545345, 16336202545744, 16336202546159, 16336202546573, 16336202546986, 16336202547399, 16336202547781,
16336202548202, 16336202548564, 16336202548949, 16336202549329, 16336202549762, 16336202550168, 16336202550534,
16336202550887, 16336202551305, 16336202551659, 16336202552060, 16336202552449, 16336202552854, 16336202553270,
16336202553609, 16336202554034, 16336202554437, 16336202554783, 16336202555191, 16336202555623, 16336202556034,
16336202556449, 16336202556890, 16336202557283, 16336202557669, 16336202558084, 16336202558496, 16336202558863,
16336202559271, 16336202559659, 16336202560051, 16336202560452, 16336202560873, 16336202561290, 16336202561659,
16336202562035, 16336202562440, 16336202562862, 16336202563284, 16336202563659, 16336202564034, 16336202564444,
16336202564853, 16336202565245, 16336202565659, 16336202566034, 16336202566455, 16336202566873, 16336202567284,
16336202567659, 16336202568034, 16336202568386, 16336202568790, 16336202569204, 16336202569620, 16336202570384,
16336202570768, 16336202571188, 16336202571551, 16336202572327, 16336202572717, 16336202573116, 16336202573541,
16336202573959, 16336202574319, 16336202574682, 16336202575040, 16336202575375, 16336202577001, 16336202577342,
16336202577680, 16336202578066, 16336202578451, 16336202579166, 16336202579534, 16336202579960, 16336202580370,
16336202580789, 16336202581159, 16336202581576, 16336202581949, 16336202582294, 16336202583087, 16336202583496,
16336202583858, 16336202584203, 16336202584606, 16336202585034, 16336202585386, 16336202585788, 16336202586211,
16336202586604, 16336202587034, 16336202587459, 16336202587869, 16336202588295, 16336202588668, 16336202589092,
16336202589452, 16336202589831, 16336202590197, 16336202590608, 16336202591034, 16336202591460, 16336202591880,
16336202592295, 16336202592727, 16336202593172, 16336202593567, 16336202593994, 16336202594397, 16336202594795,
16336202595224, 16336202595659, 16336202596058, 16336202596463, 16336202596890, 16336202597322, 16336202597732,
16336202598159, 16336202598534, 16336202598951, 16336202599365, 16336202599785, 16336202600159, 16336202600593,
16336202601005, 16336202601402, 16336202601807, 16336202602214, 16336202602556, 16336202602895, 16336202603307,
16336202603661, 16336202604075, 16336202604491, 16336202604853, 16336202605268, 16336202605670, 16336202606034,
16336202606393, 16336202606748, 16336202607170, 16336202607568, 16336202607982, 16336202608411, 16336202608836,
16336202609197, 16336202609596, 16336202609965, 16336202610333, 16336202610740, 16336202611159, 16336202611573,
16336202611975, 16336202612317, 16336202612691, 16336202613060, 16336202613474, 16336202613903, 16336202614341,
16336202614707, 16336202615094, 16336202615534, 16336202615883, 16336202616296, 16336202616671, 16336202617034,
16336202617391, 16336202617727, 16336202618159, 16336202618534, 16336202618937, 16336202619360, 16336202619770,
16336202620179, 16336202620716, 16336202621143, 16336202621534, 16336202622303, 16336202622659, 16336202623085,
16336202623498, 16336202623850, 16336202624220, 16336202624606, 16336202625034, 16336202625387, 16336202625805,
16336202626210, 16336202626599, 16336202627034, 16336202627386, 16336202627748, 16336202628159, 16336202628534,
16336202628954, 16336202629373, 16336202629809, 16336202630197, 16336202630535, 16336202630916, 16336202631290,
16336202631666, 16336202632034, 16336202632369, 16336202633152, 16336202633534, 16336202633883, 16336202634309,
16336202634717, 16336202635106, 16336202635871, 16336202636253, 16336202636671, 16336202637070, 16336202637434,
16336202637798, 16336202638184, 16336202638539, 16336202638938, 16336202639307, 16336202639666, 16336202640095,
16336202640534, 16336202640962, 16336202641307, 16336202641659, 16336202642087, 16336202642521, 16336202642886,
16336202643309, 16336202643662, 16336202644067, 16336202644491, 16336202644853, 16336202645226, 16336202645659,
16336202646074, 16336202646497, 16336202646890, 16336202647311, 16336202647749, 16336202648169, 16336202648976,
16336202649378, 16336202649810, 16336202650165, 16336202650534, 16336202650875, 16336202651250, 16336202651659,
16336202652093, 16336202652516, 16336202652921, 16336202653332, 16336202653722, 16336202654142, 16336202654534,
16336202654880, 16336202655221, 16336202655562, 16336202655997, 16336202656378, 16336202656811, 16336202657161,
16336202657588, 16336202657944, 16336202658360, 16336202658708, 16336202659089, 16336202659428, 16336202659849,
16336202660273, 16336202660685, 16336202661105, 16336202661534, 16336202661873, 16336202662228, 16336202662658,
16336202663438, 16336202663843, 16336202664219, 16336202664646, 16336202665050, 16336202665487, 16336202665838,
16336202666211, 16336202666573, 16336202666927, 16336202667334, 16336202667746, 16336202668158, 16336202668563,
16336202668980, 16336202669406, 16336202669753, 16336202670192, 16336202670554, 16336202670903, 16336202671324,
16336202671734, 16336202672159, 16336202672573, 16336202672982, 16336202673346, 16336202673680, 16336202674087,
16336202674499, 16336202674909, 16336202675260, 16336202676110, 16336202676535, 16336202676913, 16336202677312,
16336202677658, 16336202678044, 16336202678413, 16336202678793, 16336202679208, 16336202679604, 16336202680034,
16336202680385, 16336202680799, 16336202681213, 16336202681595, 16336202682004, 16336202682346, 16336202682726,
16336202683158, 16336202683586, 16336202683990, 16336202684323, 16336202684742, 16336202685175, 16336202685578,
16336202685979, 16336202686805, 16336202687206, 16336202687614, 16336202688038, 16336202688473, 16336202688848,
16336202689221, 16336202689559, 16336202689971, 16336202690368, 16336202690776, 16336202691159, 16336202691585,
16336202692010, 16336202692373, 16336202692780, 16336202693179, 16336202693580, 16336202693991, 16336202694324,
16336202694727, 16336202695159, 16336202695588, 16336202695991, 16336202696335, 16336202697160, 16336202697542,
16336202697929, 16336202698323, 16336202698674, 16336202699060, 16336202699492, 16336202699835, 16336202700238,
16336202700658, 16336202701059, 16336202701420, 16336202701815, 16336202702229, 16336202702659, 16336202703857,
16336202704256, 16336202704659, 16336202705497, 16336202706309, 16336202706660, 16336202707085, 16336202707511,
16336202707866, 16336202708210, 16336202708552, 16336202708925, 16336202709287, 16336202709670, 16336202710045,
16336202710402, 16336202710802, 16336202711167, 16336202711533, 16336202712249, 16336202712660, 16336202713088,
16336202713519, 16336202713936, 16336202714355, 16336202714740, 16336202715160, 16336202715533, 16336202715878,
16336202716290, 16336202716708, 16336202717102, 16336202718290, 16336202718699, 16336202719052, 16336202719388,
16336202719808, 16336202720225, 16336202720659, 16336202721052, 16336202721414, 16336202721828, 16336202722925,
16336202723664, 16336202724063, 16336202724405, 16336202726003, 16336202726736, 16336202727158, 16336202727543,
16336202727930, 16336202728336, 16336202728703, 16336202729061, 16336202729483, 16336202729832, 16336202730222,
16336202730659, 16336202731084, 16336202731500, 16336202731911, 16336202732326, 16336202733158, 16336202733585,
16336202734001, 16336202734691, 16336202735042, 16336202735442, 16336202735863, 16336202736255, 16336202736671,
16336202737043, 16336202737884, 16336202738671, 16336202739110, 16336202739533, 16336202739886, 16336202740283,
16336202740706, 16336202741143, 16336202741534, 16336202741942, 16336202742352, 16336202742697, 16336202743103,
16336202743940, 16336202745172, 16336202745542, 16336202745937, 16336202746339, 16336202746758, 16336202747531,
16336202747877, 16336202748232, 16336202748658, 16336202749055, 16336202749468, 16336202749859, 16336202750416,
16336202750839, 16336202751178, 16336202751572, 16336202752002, 16336202752419, 16336202753269, 16336202753678,
16336202754086, 16336202754432, 16336202754835, 16336202755260, 16336202755683, 16336202756059, 16336202756402,
16336202756837, 16336202758084, 16336202758507, 16336202758879, 16336202759270, 16336202759674, 16336202760044,
16336202760400, 16336202760801, 16336202761659, 16336202762053, 16336202762397, 16336202763199, 16336202763547,
16336202763948, 16336202764714, 16336202765113, 16336202765947, 16336202766329, 16336202766664, 16336202767085,
16336202768233, 16336202769056, 16336202769758, 16336202770178, 16336202770585, 16336202770929, 16336202771325,
16336202772158, 16336202772594, 16336202773033, 16336202773403, 16336202773801, 16336202774179, 16336202774555,
16336202774989, 16336202775393, 16336202775809, 16336202776209, 16336202776618, 16336202777033, 16336202777421,
16336202777845, 16336202778246, 16336202778658, 16336202779055, 16336202779411, 16336202779761, 16336202780175,
16336202780594, 16336202781002, 16336202781848, 16336202782658, 16336202783033, 16336202783857, 16336202784211,
16336202784557, 16336202784972, 16336202785377, 16336202785810, 16336202786172, 16336202786934, 16336202787343,
16336202787765, 16336202788201, 16336202788563, 16336202788970, 16336202789329, 16336202789672, 16336202790055,
16336202790456, 16336202790802, 16336202791580, 16336202791920, 16336202792326, 16336202793158, 16336202793953,
16336202794368, 16336202795187, 16336202795622, 16336202796033, 16336202796393, 16336202796777, 16336202797173,
16336202797540, 16336202797975, 16336202798317, 16336202798739, 16336202799158, 16336202799567, 16336202799966,
16336202800378, 16336202800803, 16336202801232, 16336202801658, 16336202802033, 16336202802374, 16336202802759,
16336202803158, 16336202803533, 16336202803947, 16336202804354, 16336202804729, 16336202805158, 16336202805534,
16336202805950, 16336202806390, 16336202806805, 16336202807219, 16336202807643, 16336202808033, 16336202808377,
16336202808790, 16336202809211, 16336202809560, 16336202809920, 16336202810355, 16336202810758, 16336202811187,
16336202811596, 16336202811943, 16336202812348, 16336202812710, 16336202813060, 16336202813398, 16336202813791,
16336202814158, 16336202814533, 16336202814878, 16336202815246, 16336202815658, 16336202816079, 16336202816851,
16336202817202, 16336202817540, 16336202817905, 16336202818244, 16336202818663, 16336202819068, 16336202819418,
16336202819777, 16336202820193, 16336202820599, 16336202821033, 16336202821395, 16336202821745, 16336202822158,
16336202822590, 16336202822996, 16336202823396, 16336202823804, 16336202824210, 16336202824581, 16336202824991,
16336202825406, 16336202825806, 16336202826210, 16336202826598, 16336202827033, 16336202827446, 16336202827839,
16336202828201, 16336202828577, 16336202828968, 16336202829362, 16336202829709, 16336202830096, 16336202830533,
16336202830917, 16336202831290, 16336202831699, 16336202832035, 16336202832406, 16336202832804, 16336202833200,
16336202833604, 16336202834033, 16336202834386, 16336202834759, 16336202835190, 16336202835621, 16336202836033,
16336202836405, 16336202837191, 16336202837613, 16336202838033, 16336202838374, 16336202838798, 16336202839200,
16336202839603, 16336202840034, 16336202840389, 16336202840783, 16336202841200, 16336202841617, 16336202842034,
16336202842390, 16336202842737, 16336202843158, 16336202843585, 16336202843923, 16336202844313, 16336202844724,
16336202845158, 16336202845576, 16336202845939, 16336202846368, 16336202846728, 16336202847158, 16336202847568,
16336202847911, 16336202848291, 16336202848695, 16336202849103, 16336202849533, 16336202849942, 16336202850368,
16336202850747, 16336202851158, 16336202851549, 16336202851978, 16336202852383, 16336202852725, 16336202853158,
16336202853554, 16336202853961, 16336202854308, 16336202854704, 16336202855060, 16336202855418, 16336202855776,
16336202856203, 16336202856617, 16336202857036, 16336202857455, 16336202857884, 16336202858262, 16336202858658,
16336202859071, 16336202859847, 16336202860237, 16336202860658, 16336202861037, 16336202861452, 16336202861869,
16336202862218, 16336202862590, 16336202863001, 16336202863422, 16336202863857, 16336202864219, 16336202864658,
16336202865047, 16336202865404, 16336202865789, 16336202866210, 16336202866624, 16336202867033, 16336202867380,
16336202867797, 16336202868227, 16336202868658, 16336202869083, 16336202869500, 16336202869906, 16336202870246,
16336202870658, 16336202871086, 16336202871441, 16336202871820, 16336202872204, 16336202872546, 16336202872943,
16336202873380, 16336202873811, 16336202874213, 16336202874566, 16336202874918, 16336202875261, 16336202875655,
16336202876047, 16336202876771, 16336202877202, 16336202877612, 16336202878033, 16336202878412, 16336202878846,
16336202879241, 16336202879658, 16336202880072, 16336202880508, 16336202880901, 16336202881308, 16336202881725,
16336202882158, 16336202882579, 16336202882945, 16336202883286, 16336202883657, 16336202884048, 16336202884404,
16336202884752, 16336202885158, 16336202885533, 16336202885938, 16336202886364, 16336202886759, 16336202887175,
16336202887585, 16336202887929, 16336202888345, 16336202888743, 16336202889157, 16336202889570, 16336202889970,
16336202890382, 16336202890761, 16336202891187, 16336202891600, 16336202892033, 16336202892454, 16336202892794,
16336202893178, 16336202893533, 16336202893903, 16336202894264, 16336202894668, 16336202895049, 16336202895400,
16336202895774, 16336202896157, 16336202896537, 16336202896883, 16336202897232, 16336202897658, 16336202898065,
16336202898493, 16336202898884, 16336202899251, 16336202899673, 16336202900047, 16336202900467, 16336202900883,
16336202901300, 16336202901676, 16336202902068, 16336202902479, 16336202902902, 16336202903260, 16336202903675,
16336202904094, 16336202904476, 16336202904824, 16336202905158, 16336202905533, 16336202905934, 16336202906289,
16336202906717, 16336202907158, 16336202907547, 16336202907904, 16336202908294, 16336202908717, 16336202909157,
16336202909582, 16336202910005, 16336202910399, 16336202910800, 16336202911220, 16336202911657, 16336202912064,
16336202912405, 16336202912779, 16336202913158, 16336202913553, 16336202913966, 16336202914376, 16336202914719,
16336202915091, 16336202915515, 16336202915887, 16336202916293, 16336202916649, 16336202917438, 16336202917869,
16336202918221, 16336202919053, 16336202919425, 16336202919833, 16336202920234, 16336202920658, 16336202921033,
16336202921433, 16336202921801, 16336202922161, 16336202922589, 16336202923017, 16336202923418, 16336202923804,
16336202924199, 16336202924593, 16336202925033, 16336202925449, 16336202925818, 16336202926223, 16336202926662,
16336202927431, 16336202927812, 16336202928227, 16336202928658, 16336202929061, 16336202929473, 16336202929891,
16336202930241, 16336202930657, 16336202931057, 16336202931396, 16336202931811, 16336202932225, 16336202932657,
16336202933058, 16336202933445, 16336202933790, 16336202934157, 16336202934562, 16336202934988, 16336202935391,
16336202935777, 16336202936160, 16336202936562, 16336202936986, 16336202937396, 16336202937751, 16336202938158,
16336202938578, 16336202938985, 16336202939396, 16336202939752, 16336202940157, 16336202940585
16336202536562, 16336202536908, 16336202537294, 16336202537705,
16336202538114, 16336202538534, 16336202538941, 16336202539323,
16336202539742, 16336202540159, 16336202540877, 16336202541310,
16336202541749, 16336202542159, 16336202542565, 16336202542996,
16336202543333, 16336202543761, 16336202544159, 16336202544534,
16336202544944, 16336202545345, 16336202545744, 16336202546159,
16336202546573, 16336202546986, 16336202547399, 16336202547781,
16336202548202, 16336202548564, 16336202548949, 16336202549329,
16336202549762, 16336202550168, 16336202550534, 16336202550887,
16336202551305, 16336202551659, 16336202552060, 16336202552449,
16336202552854, 16336202553270, 16336202553609, 16336202554034,
16336202554437, 16336202554783, 16336202555191, 16336202555623,
16336202556034, 16336202556449, 16336202556890, 16336202557283,
16336202557669, 16336202558084, 16336202558496, 16336202558863,
16336202559271, 16336202559659, 16336202560051, 16336202560452,
16336202560873, 16336202561290, 16336202561659, 16336202562035,
16336202562440, 16336202562862, 16336202563284, 16336202563659,
16336202564034, 16336202564444, 16336202564853, 16336202565245,
16336202565659, 16336202566034, 16336202566455, 16336202566873,
16336202567284, 16336202567659, 16336202568034, 16336202568386,
16336202568790, 16336202569204, 16336202569620, 16336202570384,
16336202570768, 16336202571188, 16336202571551, 16336202572327,
16336202572717, 16336202573116, 16336202573541, 16336202573959,
16336202574319, 16336202574682, 16336202575040, 16336202575375,
16336202577001, 16336202577342, 16336202577680, 16336202578066,
16336202578451, 16336202579166, 16336202579534, 16336202579960,
16336202580370, 16336202580789, 16336202581159, 16336202581576,
16336202581949, 16336202582294, 16336202583087, 16336202583496,
16336202583858, 16336202584203, 16336202584606, 16336202585034,
16336202585386, 16336202585788, 16336202586211, 16336202586604,
16336202587034, 16336202587459, 16336202587869, 16336202588295,
16336202588668, 16336202589092, 16336202589452, 16336202589831,
16336202590197, 16336202590608, 16336202591034, 16336202591460,
16336202591880, 16336202592295, 16336202592727, 16336202593172,
16336202593567, 16336202593994, 16336202594397, 16336202594795,
16336202595224, 16336202595659, 16336202596058, 16336202596463,
16336202596890, 16336202597322, 16336202597732, 16336202598159,
16336202598534, 16336202598951, 16336202599365, 16336202599785,
16336202600159, 16336202600593, 16336202601005, 16336202601402,
16336202601807, 16336202602214, 16336202602556, 16336202602895,
16336202603307, 16336202603661, 16336202604075, 16336202604491,
16336202604853, 16336202605268, 16336202605670, 16336202606034,
16336202606393, 16336202606748, 16336202607170, 16336202607568,
16336202607982, 16336202608411, 16336202608836, 16336202609197,
16336202609596, 16336202609965, 16336202610333, 16336202610740,
16336202611159, 16336202611573, 16336202611975, 16336202612317,
16336202612691, 16336202613060, 16336202613474, 16336202613903,
16336202614341, 16336202614707, 16336202615094, 16336202615534,
16336202615883, 16336202616296, 16336202616671, 16336202617034,
16336202617391, 16336202617727, 16336202618159, 16336202618534,
16336202618937, 16336202619360, 16336202619770, 16336202620179,
16336202620716, 16336202621143, 16336202621534, 16336202622303,
16336202622659, 16336202623085, 16336202623498, 16336202623850,
16336202624220, 16336202624606, 16336202625034, 16336202625387,
16336202625805, 16336202626210, 16336202626599, 16336202627034,
16336202627386, 16336202627748, 16336202628159, 16336202628534,
16336202628954, 16336202629373, 16336202629809, 16336202630197,
16336202630535, 16336202630916, 16336202631290, 16336202631666,
16336202632034, 16336202632369, 16336202633152, 16336202633534,
16336202633883, 16336202634309, 16336202634717, 16336202635106,
16336202635871, 16336202636253, 16336202636671, 16336202637070,
16336202637434, 16336202637798, 16336202638184, 16336202638539,
16336202638938, 16336202639307, 16336202639666, 16336202640095,
16336202640534, 16336202640962, 16336202641307, 16336202641659,
16336202642087, 16336202642521, 16336202642886, 16336202643309,
16336202643662, 16336202644067, 16336202644491, 16336202644853,
16336202645226, 16336202645659, 16336202646074, 16336202646497,
16336202646890, 16336202647311, 16336202647749, 16336202648169,
16336202648976, 16336202649378, 16336202649810, 16336202650165,
16336202650534, 16336202650875, 16336202651250, 16336202651659,
16336202652093, 16336202652516, 16336202652921, 16336202653332,
16336202653722, 16336202654142, 16336202654534, 16336202654880,
16336202655221, 16336202655562, 16336202655997, 16336202656378,
16336202656811, 16336202657161, 16336202657588, 16336202657944,
16336202658360, 16336202658708, 16336202659089, 16336202659428,
16336202659849, 16336202660273, 16336202660685, 16336202661105,
16336202661534, 16336202661873, 16336202662228, 16336202662658,
16336202663438, 16336202663843, 16336202664219, 16336202664646,
16336202665050, 16336202665487, 16336202665838, 16336202666211,
16336202666573, 16336202666927, 16336202667334, 16336202667746,
16336202668158, 16336202668563, 16336202668980, 16336202669406,
16336202669753, 16336202670192, 16336202670554, 16336202670903,
16336202671324, 16336202671734, 16336202672159, 16336202672573,
16336202672982, 16336202673346, 16336202673680, 16336202674087,
16336202674499, 16336202674909, 16336202675260, 16336202676110,
16336202676535, 16336202676913, 16336202677312, 16336202677658,
16336202678044, 16336202678413, 16336202678793, 16336202679208,
16336202679604, 16336202680034, 16336202680385, 16336202680799,
16336202681213, 16336202681595, 16336202682004, 16336202682346,
16336202682726, 16336202683158, 16336202683586, 16336202683990,
16336202684323, 16336202684742, 16336202685175, 16336202685578,
16336202685979, 16336202686805, 16336202687206, 16336202687614,
16336202688038, 16336202688473, 16336202688848, 16336202689221,
16336202689559, 16336202689971, 16336202690368, 16336202690776,
16336202691159, 16336202691585, 16336202692010, 16336202692373,
16336202692780, 16336202693179, 16336202693580, 16336202693991,
16336202694324, 16336202694727, 16336202695159, 16336202695588,
16336202695991, 16336202696335, 16336202697160, 16336202697542,
16336202697929, 16336202698323, 16336202698674, 16336202699060,
16336202699492, 16336202699835, 16336202700238, 16336202700658,
16336202701059, 16336202701420, 16336202701815, 16336202702229,
16336202702659, 16336202703857, 16336202704256, 16336202704659,
16336202705497, 16336202706309, 16336202706660, 16336202707085,
16336202707511, 16336202707866, 16336202708210, 16336202708552,
16336202708925, 16336202709287, 16336202709670, 16336202710045,
16336202710402, 16336202710802, 16336202711167, 16336202711533,
16336202712249, 16336202712660, 16336202713088, 16336202713519,
16336202713936, 16336202714355, 16336202714740, 16336202715160,
16336202715533, 16336202715878, 16336202716290, 16336202716708,
16336202717102, 16336202718290, 16336202718699, 16336202719052,
16336202719388, 16336202719808, 16336202720225, 16336202720659,
16336202721052, 16336202721414, 16336202721828, 16336202722925,
16336202723664, 16336202724063, 16336202724405, 16336202726003,
16336202726736, 16336202727158, 16336202727543, 16336202727930,
16336202728336, 16336202728703, 16336202729061, 16336202729483,
16336202729832, 16336202730222, 16336202730659, 16336202731084,
16336202731500, 16336202731911, 16336202732326, 16336202733158,
16336202733585, 16336202734001, 16336202734691, 16336202735042,
16336202735442, 16336202735863, 16336202736255, 16336202736671,
16336202737043, 16336202737884, 16336202738671, 16336202739110,
16336202739533, 16336202739886, 16336202740283, 16336202740706,
16336202741143, 16336202741534, 16336202741942, 16336202742352,
16336202742697, 16336202743103, 16336202743940, 16336202745172,
16336202745542, 16336202745937, 16336202746339, 16336202746758,
16336202747531, 16336202747877, 16336202748232, 16336202748658,
16336202749055, 16336202749468, 16336202749859, 16336202750416,
16336202750839, 16336202751178, 16336202751572, 16336202752002,
16336202752419, 16336202753269, 16336202753678, 16336202754086,
16336202754432, 16336202754835, 16336202755260, 16336202755683,
16336202756059, 16336202756402, 16336202756837, 16336202758084,
16336202758507, 16336202758879, 16336202759270, 16336202759674,
16336202760044, 16336202760400, 16336202760801, 16336202761659,
16336202762053, 16336202762397, 16336202763199, 16336202763547,
16336202763948, 16336202764714, 16336202765113, 16336202765947,
16336202766329, 16336202766664, 16336202767085, 16336202768233,
16336202769056, 16336202769758, 16336202770178, 16336202770585,
16336202770929, 16336202771325, 16336202772158, 16336202772594,
16336202773033, 16336202773403, 16336202773801, 16336202774179,
16336202774555, 16336202774989, 16336202775393, 16336202775809,
16336202776209, 16336202776618, 16336202777033, 16336202777421,
16336202777845, 16336202778246, 16336202778658, 16336202779055,
16336202779411, 16336202779761, 16336202780175, 16336202780594,
16336202781002, 16336202781848, 16336202782658, 16336202783033,
16336202783857, 16336202784211, 16336202784557, 16336202784972,
16336202785377, 16336202785810, 16336202786172, 16336202786934,
16336202787343, 16336202787765, 16336202788201, 16336202788563,
16336202788970, 16336202789329, 16336202789672, 16336202790055,
16336202790456, 16336202790802, 16336202791580, 16336202791920,
16336202792326, 16336202793158, 16336202793953, 16336202794368,
16336202795187, 16336202795622, 16336202796033, 16336202796393,
16336202796777, 16336202797173, 16336202797540, 16336202797975,
16336202798317, 16336202798739, 16336202799158, 16336202799567,
16336202799966, 16336202800378, 16336202800803, 16336202801232,
16336202801658, 16336202802033, 16336202802374, 16336202802759,
16336202803158, 16336202803533, 16336202803947, 16336202804354,
16336202804729, 16336202805158, 16336202805534, 16336202805950,
16336202806390, 16336202806805, 16336202807219, 16336202807643,
16336202808033, 16336202808377, 16336202808790, 16336202809211,
16336202809560, 16336202809920, 16336202810355, 16336202810758,
16336202811187, 16336202811596, 16336202811943, 16336202812348,
16336202812710, 16336202813060, 16336202813398, 16336202813791,
16336202814158, 16336202814533, 16336202814878, 16336202815246,
16336202815658, 16336202816079, 16336202816851, 16336202817202,
16336202817540, 16336202817905, 16336202818244, 16336202818663,
16336202819068, 16336202819418, 16336202819777, 16336202820193,
16336202820599, 16336202821033, 16336202821395, 16336202821745,
16336202822158, 16336202822590, 16336202822996, 16336202823396,
16336202823804, 16336202824210, 16336202824581, 16336202824991,
16336202825406, 16336202825806, 16336202826210, 16336202826598,
16336202827033, 16336202827446, 16336202827839, 16336202828201,
16336202828577, 16336202828968, 16336202829362, 16336202829709,
16336202830096, 16336202830533, 16336202830917, 16336202831290,
16336202831699, 16336202832035, 16336202832406, 16336202832804,
16336202833200, 16336202833604, 16336202834033, 16336202834386,
16336202834759, 16336202835190, 16336202835621, 16336202836033,
16336202836405, 16336202837191, 16336202837613, 16336202838033,
16336202838374, 16336202838798, 16336202839200, 16336202839603,
16336202840034, 16336202840389, 16336202840783, 16336202841200,
16336202841617, 16336202842034, 16336202842390, 16336202842737,
16336202843158, 16336202843585, 16336202843923, 16336202844313,
16336202844724, 16336202845158, 16336202845576, 16336202845939,
16336202846368, 16336202846728, 16336202847158, 16336202847568,
16336202847911, 16336202848291, 16336202848695, 16336202849103,
16336202849533, 16336202849942, 16336202850368, 16336202850747,
16336202851158, 16336202851549, 16336202851978, 16336202852383,
16336202852725, 16336202853158, 16336202853554, 16336202853961,
16336202854308, 16336202854704, 16336202855060, 16336202855418,
16336202855776, 16336202856203, 16336202856617, 16336202857036,
16336202857455, 16336202857884, 16336202858262, 16336202858658,
16336202859071, 16336202859847, 16336202860237, 16336202860658,
16336202861037, 16336202861452, 16336202861869, 16336202862218,
16336202862590, 16336202863001, 16336202863422, 16336202863857,
16336202864219, 16336202864658, 16336202865047, 16336202865404,
16336202865789, 16336202866210, 16336202866624, 16336202867033,
16336202867380, 16336202867797, 16336202868227, 16336202868658,
16336202869083, 16336202869500, 16336202869906, 16336202870246,
16336202870658, 16336202871086, 16336202871441, 16336202871820,
16336202872204, 16336202872546, 16336202872943, 16336202873380,
16336202873811, 16336202874213, 16336202874566, 16336202874918,
16336202875261, 16336202875655, 16336202876047, 16336202876771,
16336202877202, 16336202877612, 16336202878033, 16336202878412,
16336202878846, 16336202879241, 16336202879658, 16336202880072,
16336202880508, 16336202880901, 16336202881308, 16336202881725,
16336202882158, 16336202882579, 16336202882945, 16336202883286,
16336202883657, 16336202884048, 16336202884404, 16336202884752,
16336202885158, 16336202885533, 16336202885938, 16336202886364,
16336202886759, 16336202887175, 16336202887585, 16336202887929,
16336202888345, 16336202888743, 16336202889157, 16336202889570,
16336202889970, 16336202890382, 16336202890761, 16336202891187,
16336202891600, 16336202892033, 16336202892454, 16336202892794,
16336202893178, 16336202893533, 16336202893903, 16336202894264,
16336202894668, 16336202895049, 16336202895400, 16336202895774,
16336202896157, 16336202896537, 16336202896883, 16336202897232,
16336202897658, 16336202898065, 16336202898493, 16336202898884,
16336202899251, 16336202899673, 16336202900047, 16336202900467,
16336202900883, 16336202901300, 16336202901676, 16336202902068,
16336202902479, 16336202902902, 16336202903260, 16336202903675,
16336202904094, 16336202904476, 16336202904824, 16336202905158,
16336202905533, 16336202905934, 16336202906289, 16336202906717,
16336202907158, 16336202907547, 16336202907904, 16336202908294,
16336202908717, 16336202909157, 16336202909582, 16336202910005,
16336202910399, 16336202910800, 16336202911220, 16336202911657,
16336202912064, 16336202912405, 16336202912779, 16336202913158,
16336202913553, 16336202913966, 16336202914376, 16336202914719,
16336202915091, 16336202915515, 16336202915887, 16336202916293,
16336202916649, 16336202917438, 16336202917869, 16336202918221,
16336202919053, 16336202919425, 16336202919833, 16336202920234,
16336202920658, 16336202921033, 16336202921433, 16336202921801,
16336202922161, 16336202922589, 16336202923017, 16336202923418,
16336202923804, 16336202924199, 16336202924593, 16336202925033,
16336202925449, 16336202925818, 16336202926223, 16336202926662,
16336202927431, 16336202927812, 16336202928227, 16336202928658,
16336202929061, 16336202929473, 16336202929891, 16336202930241,
16336202930657, 16336202931057, 16336202931396, 16336202931811,
16336202932225, 16336202932657, 16336202933058, 16336202933445,
16336202933790, 16336202934157, 16336202934562, 16336202934988,
16336202935391, 16336202935777, 16336202936160, 16336202936562,
16336202936986, 16336202937396, 16336202937751, 16336202938158,
16336202938578, 16336202938985, 16336202939396, 16336202939752,
16336202940157, 16336202940585
],
"frameTimes": [
346, 411, 420, 382, 417, 433, 410, 431, 428, 375, 401, 415, 413, 382, 362, 380, 406, 353, 354, 389, 416, 425, 346,
432, 415, 393, 415, 367, 388, 401, 417, 376, 422, 375, 410, 392, 375, 418, 375, 352, 414, 764, 420, 776, 399, 418,
363, 335, 341, 386, 715, 426, 419, 417, 345, 409, 345, 428, 402, 393, 425, 426, 424, 379, 411, 426, 415, 445, 427,
398, 435, 405, 432, 427, 417, 420, 434, 397, 407, 339, 354, 416, 415, 364, 355, 398, 429, 361, 369, 407, 414, 342,
369, 429, 366, 440, 413, 363, 336, 375, 423, 409, 427, 769, 426, 352, 386, 353, 405, 435, 362, 375, 419, 388, 381,
376, 335, 382, 426, 389, 382, 399, 364, 355, 369, 429, 428, 352, 434, 423, 405, 362, 433, 423, 421, 420, 402, 355,
341, 409, 423, 411, 420, 346, 341, 381, 350, 356, 348, 339, 424, 420, 339, 430, 405, 427, 437, 373, 354, 412, 405,
426, 439, 349, 410, 414, 364, 407, 410, 850, 378, 346, 369, 415, 430, 414, 382, 342, 432, 404, 419, 403, 826, 408,
435, 373, 412, 408, 426, 363, 399, 411, 403, 429, 344, 382, 394, 386, 343, 420, 361, 414, 1198, 403, 812, 425, 355,
342, 362, 375, 400, 366, 411, 431, 419, 420, 345, 418, 1188, 353, 420, 434, 362, 1097, 399, 1598, 422, 387, 367,
422, 390, 425, 411, 832, 416, 351, 421, 416, 841, 439, 353, 423, 391, 410, 406, 1232, 395, 419, 346, 426, 413, 557,
339, 430, 850, 408, 403, 423, 343, 1247, 372, 404, 356, 858, 344, 348, 766, 834, 335, 1148, 702, 407, 396, 436, 370,
378, 434, 416, 409, 388, 401, 397, 350, 419, 846, 375, 354, 415, 433, 762, 422, 362, 359, 383, 346, 340, 832, 415,
435, 360, 396, 435, 422, 409, 412, 429, 375, 385, 375, 407, 429, 416, 415, 424, 344, 421, 360, 403, 409, 405, 350,
393, 375, 368, 421, 351, 365, 419, 350, 416, 434, 350, 432, 400, 406, 410, 400, 388, 413, 362, 391, 347, 437, 373,
336, 398, 404, 353, 431, 412, 786, 420, 424, 403, 355, 417, 417, 347, 427, 390, 434, 363, 360, 410, 380, 408, 409,
379, 391, 405, 433, 407, 396, 358, 427, 419, 429, 396, 776, 421, 415, 349, 411, 435, 439, 357, 421, 409, 417, 431,
417, 340, 428, 379, 342, 437, 402, 352, 394, 724, 410, 379, 395, 414, 393, 417, 421, 341, 391, 348, 375, 426, 416,
344, 398, 413, 412, 426, 433, 340, 355, 361, 381, 374, 380, 349, 407, 391, 422, 420, 417, 392, 423, 415, 382, 334,
401, 428, 389, 390, 440, 423, 401, 437, 341, 379, 413, 343, 424, 406, 789, 352, 372, 401, 375, 368, 428, 401, 395,
440, 369, 439, 381, 431, 412, 350, 400, 415, 432, 387, 367, 426, 386, 402, 410, 407, 407, 356, 428
346, 411, 420, 382, 417, 433, 410, 431, 428, 375, 401, 415, 413, 382, 362,
380, 406, 353, 354, 389, 416, 425, 346, 432, 415, 393, 415, 367, 388, 401,
417, 376, 422, 375, 410, 392, 375, 418, 375, 352, 414, 764, 420, 776, 399,
418, 363, 335, 341, 386, 715, 426, 419, 417, 345, 409, 345, 428, 402, 393,
425, 426, 424, 379, 411, 426, 415, 445, 427, 398, 435, 405, 432, 427, 417,
420, 434, 397, 407, 339, 354, 416, 415, 364, 355, 398, 429, 361, 369, 407,
414, 342, 369, 429, 366, 440, 413, 363, 336, 375, 423, 409, 427, 769, 426,
352, 386, 353, 405, 435, 362, 375, 419, 388, 381, 376, 335, 382, 426, 389,
382, 399, 364, 355, 369, 429, 428, 352, 434, 423, 405, 362, 433, 423, 421,
420, 402, 355, 341, 409, 423, 411, 420, 346, 341, 381, 350, 356, 348, 339,
424, 420, 339, 430, 405, 427, 437, 373, 354, 412, 405, 426, 439, 349, 410,
414, 364, 407, 410, 850, 378, 346, 369, 415, 430, 414, 382, 342, 432, 404,
419, 403, 826, 408, 435, 373, 412, 408, 426, 363, 399, 411, 403, 429, 344,
382, 394, 386, 343, 420, 361, 414, 1198, 403, 812, 425, 355, 342, 362, 375,
400, 366, 411, 431, 419, 420, 345, 418, 1188, 353, 420, 434, 362, 1097, 399,
1598, 422, 387, 367, 422, 390, 425, 411, 832, 416, 351, 421, 416, 841, 439,
353, 423, 391, 410, 406, 1232, 395, 419, 346, 426, 413, 557, 339, 430, 850,
408, 403, 423, 343, 1247, 372, 404, 356, 858, 344, 348, 766, 834, 335, 1148,
702, 407, 396, 436, 370, 378, 434, 416, 409, 388, 401, 397, 350, 419, 846,
375, 354, 415, 433, 762, 422, 362, 359, 383, 346, 340, 832, 415, 435, 360,
396, 435, 422, 409, 412, 429, 375, 385, 375, 407, 429, 416, 415, 424, 344,
421, 360, 403, 409, 405, 350, 393, 375, 368, 421, 351, 365, 419, 350, 416,
434, 350, 432, 400, 406, 410, 400, 388, 413, 362, 391, 347, 437, 373, 336,
398, 404, 353, 431, 412, 786, 420, 424, 403, 355, 417, 417, 347, 427, 390,
434, 363, 360, 410, 380, 408, 409, 379, 391, 405, 433, 407, 396, 358, 427,
419, 429, 396, 776, 421, 415, 349, 411, 435, 439, 357, 421, 409, 417, 431,
417, 340, 428, 379, 342, 437, 402, 352, 394, 724, 410, 379, 395, 414, 393,
417, 421, 341, 391, 348, 375, 426, 416, 344, 398, 413, 412, 426, 433, 340,
355, 361, 381, 374, 380, 349, 407, 391, 422, 420, 417, 392, 423, 415, 382,
334, 401, 428, 389, 390, 440, 423, 401, 437, 341, 379, 413, 343, 424, 406,
789, 352, 372, 401, 375, 368, 428, 401, 395, 440, 369, 439, 381, 431, 412,
350, 400, 415, 432, 387, 367, 426, 386, 402, 410, 407, 407, 356, 428
],
"percentileMs": {
"50": 40.7,

View File

@@ -25,5 +25,6 @@
},
"devDependencies": {
"fast-deep-equal": "^3.1.3"
}
},
"prettier": "../.prettierrc.cjs"
}

View File

@@ -1,70 +0,0 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": false
},
"javascript": {
"parser": {
"unsafeParameterDecoratorsEnabled": true
},
"formatter": {
"arrowParentheses": "asNeeded",
"quoteProperties": "preserve",
"semicolons": "always",
"trailingComma": "all",
"indentStyle": "space",
"quoteStyle": "double"
}
},
"json": {
"formatter": {
"indentStyle": "space"
},
"parser": {
"allowComments": true,
"allowTrailingCommas": true
}
},
"vcs": {
"clientKind": "git",
"enabled": false,
"root": "./"
},
"files": {
"maxSize": 9128312873
},
"formatter": {
"enabled": true,
"indentWidth": 2,
"lineEnding": "lf",
"formatWithErrors": true,
"lineWidth": 120,
"indentStyle": "space",
"ignore": [
"node_modules/**",
"test/snapshots",
"test/fixtures",
".next",
"test/js/deno",
"./src/deps",
"./src/bun.js/WebKit/**",
"packages/bun-polyfills",
"./build-*",
"./build",
".cache",
"out/",
"test/transpiler/property-non-ascii-fixture.js",
"test/transpiler/macro-test.test.ts",
"test/transpiler/decorator-metadata.test.ts",
"src/react-refresh.js",
"bindings-obj/*",
"src/deps/**",
"./bench/react-hello-world/react-hello-world.node.js",
"./test/cli/run/require-cache-bug-leak-fixture-large-ast.js",
"./test/cli/run/esm-leak-fixture-large-ast.mjs"
]
}
}

View File

@@ -591,7 +591,6 @@ pub fn build_(b: *Build) !void {
\\For more info, see https://bun.sh/docs/project/contributing
\\
});
b.default_step.dependOn(&mistake_message.step);
}

BIN
bun.lockb

Binary file not shown.

View File

@@ -65,19 +65,19 @@ Below we create a new `DataView` and set the first byte to 5.
```ts
const buf = new ArrayBuffer(4);
// [0b00000000, 0b00000000, 0b00000000, 0b00000000]
// [0x0, 0x0, 0x0, 0x0]
const dv = new DataView(buf);
dv.setUint8(0, 3); // write value 3 at byte offset 0
dv.getUint8(0); // => 3
// [0b00000011, 0b00000000, 0b00000000, 0b00000000]
// [0x11, 0x0, 0x0, 0x0]
```
Now let's write a `Uint16` at byte offset `1`. This requires two bytes. We're using the value `513`, which is `2 * 256 + 1`; in bytes, that's `00000010 00000001`.
```ts
dv.setUint16(1, 513);
// [0b00000011, 0b00000010, 0b00000001, 0b00000000]
// [0x11, 0x10, 0x1, 0x0]
console.log(dv.getUint16(1)); // => 513
```

View File

@@ -7,7 +7,7 @@ Bun includes a fast native implementation of file globbing.
```ts
import { Glob } from "bun";
const glob = new Glob("**/*.ts");
const glob = new Glob("*.ts");
// Scans the current working directory and each of its sub-directories recursively
for await (const file of glob.scan(".")) {

View File

@@ -56,45 +56,6 @@ const stream = new ReadableStream({
When using a direct `ReadableStream`, all chunk queueing is handled by the destination. The consumer of the stream receives exactly what is passed to `controller.write()`, without any encoding or modification.
## Async generator streams
Bun also supports async generator functions as a source for `Response` and `Request`. This is an easy way to create a `ReadableStream` that fetches data from an asynchronous source.
```ts
const response = new Response(async function* () {
yield "hello";
yield "world";
}());
await response.text(); // "helloworld"
```
You can also use `[Symbol.asyncIterator]` directly.
```ts
const response = new Response({
[Symbol.asyncIterator]: async function* () {
yield "hello";
yield "world";
},
});
await response.text(); // "helloworld"
```
If you need more granular control over the stream, `yield` will return the direct ReadableStream controller.
```ts
const response = new Response({
[Symbol.asyncIterator]: async function* () {
const controller = yield "hello";
await controller.end();
},
});
await response.text(); // "hello"
```
## `Bun.ArrayBufferSink`
The `Bun.ArrayBufferSink` class is a fast incremental writer for constructing an `ArrayBuffer` of unknown size.

View File

@@ -50,7 +50,7 @@ export default jsx(
To override the default loader specified in the `new Bun.Transpiler()` constructor, pass a second argument to `.transformSync()`.
```ts
transpiler.transformSync("<div>hi!</div>", "tsx");
await transpiler.transform("<div>hi!</div>", "tsx");
```
{% details summary="Nitty gritty" %}

View File

@@ -182,12 +182,12 @@ const server = Bun.serve<{ username: string }>({
open(ws) {
const msg = `${ws.data.username} has entered the chat`;
ws.subscribe("the-group-chat");
server.publish("the-group-chat", msg);
ws.publish("the-group-chat", msg);
},
message(ws, message) {
// this is a group chat
// so the server re-broadcasts incoming message to everyone
server.publish("the-group-chat", `${ws.data.username}: ${message}`);
ws.publish("the-group-chat", `${ws.data.username}: ${message}`);
},
close(ws) {
const msg = `${ws.data.username} has left the chat`;

View File

@@ -43,7 +43,7 @@ Let's build our first bundle. You have the following two files, which implement
import * as ReactDOM from 'react-dom/client';
import {Component} from "./Component"
const root = ReactDOM.createRoot(document.getElementById('root')!);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Component message="Sup!" />)
```
@@ -155,7 +155,7 @@ Like the Bun runtime, the bundler supports an array of file types out of the box
---
- `.js` `.jsx`, `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx`
- `.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx`
- Uses Bun's built-in transpiler to parse the file and transpile TypeScript/JSX syntax to vanilla JavaScript. The bundler executes a set of default transforms, including dead code elimination, tree shaking, and environment variable inlining. At the moment Bun does not attempt to down-convert syntax; if you use recently ECMAScript syntax, that will be reflected in the bundled code.
---

View File

@@ -35,6 +35,6 @@ It creates:
If you pass `-y` or `--yes`, it will assume you want to continue without asking questions.
At the end, it runs `bun install` to install `@types/bun`.
At the end, it runs `bun install` to install `bun-types`.
{% /details %}

View File

@@ -113,6 +113,10 @@ See [Test > Lifecycle](/docs/test/lifecycle) for complete documentation.
## Mocks
{% callout %}
Module mocking (`jest.mock()`) is not yet supported. Track support for it [here](https://github.com/oven-sh/bun/issues/5394).
{% /callout %}
Create mock functions with the `mock` function. Mocks are automatically reset between tests.
```ts

View File

@@ -1,46 +0,0 @@
---
name: Common HTTP server usage
---
This starts an HTTP server listening on port `3000`. It demonstates basic routing with a number of common responses and also handles POST data from standard forms or as JSON.
See [`Bun.serve`](/docs/api/http) for details.
```ts
const server = Bun.serve({
async fetch (req) {
const path = new URL(req.url).pathname;
// respond with text/html
if (path === "/") return new Response("Welcome to Bun!");
// redirect
if (path === "/abc") return Response.redirect("/source", 301);
// send back a file (in this case, *this* file)
if (path === "/source") return new Response(Bun.file(import.meta.file));
// respond with JSON
if (path === "/api") return Response.json({ some: "buns", for: "you" });
// receive JSON data to a POST request
if (req.method === "POST" && path === "/api/post") {
const data = await req.json();
console.log("Received JSON:", data);
return Response.json({ success: true, data });
}
// receive POST data from a form
if (req.method === "POST" && path === "/form") {
const data = await req.formData();
console.log(data.get("someField"));
return new Response("Success");
}
// 404s
return new Response("Page not found", { status: 404 });
}
})
console.log(`Listening on ${server.url}`);
```

View File

@@ -15,13 +15,13 @@ Below is the full set of recommended `compilerOptions` for a Bun project. With t
```jsonc
{
"compilerOptions": {
// Enable latest features
// enable latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"jsx": "react-jsx", // support JSX
"allowJs": true, // allow importing `.js` from `.ts`
// Bundler mode
"moduleResolution": "bundler",
@@ -32,11 +32,12 @@ Below is the full set of recommended `compilerOptions` for a Bun project. With t
// Best practices
"strict": true,
"skipLibCheck": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags
"noUnusedLocals": true,
"noUnusedParameters": true,
"useUnknownInCatchVariables": true,
"noPropertyAccessFromIndexSignature": true
}
}

View File

@@ -93,7 +93,7 @@ $ bun test --timeout 10000
Many other flags become irrelevant or obsolete when using `bun test`.
- `transform` — Bun supports TypeScript & JSX. Other file types can be configured with [Plugins](/docs/runtime/plugins).
- `transform` — Buns supports TypeScript & JSX. Other file types can be configured with [Plugins](/docs/runtime/plugins).
- `extensionsToTreatAsEsm`
- `haste` — Bun uses it's own internal source maps
- `watchman`, `watchPlugins`, `watchPathIgnorePatterns` — use `--watch` to run tests in watch mode

View File

@@ -20,11 +20,11 @@ const server = Bun.serve<{ username: string }>({
open(ws) {
const msg = `${ws.data.username} has entered the chat`;
ws.subscribe("the-group-chat");
server.publish("the-group-chat", msg);
ws.publish("the-group-chat", msg);
},
message(ws, message) {
// the server re-broadcasts incoming messages to everyone
server.publish("the-group-chat", `${ws.data.username}: ${message}`);
ws.publish("the-group-chat", `${ws.data.username}: ${message}`);
},
close(ws) {
const msg = `${ws.data.username} has left the chat`;

View File

@@ -233,10 +233,6 @@ If you need to remove Bun from your system, use the following commands.
$ rm -rf ~/.bun # for macOS, Linux, and WSL
```
```bash#Windows
$ Remove-Item ~\.bun -Recurse
```
```bash#NPM
$ npm uninstall -g bun
```

View File

@@ -369,9 +369,6 @@ export default {
page("project/contributing", "Contributing", {
description: "Learn how to contribute to Bun and get your local development environment up and running.",
}),
page("project/building-windows", "Building Windows", {
description: "Learn how to setup a development environment for contributing to the Windows build of Bun.",
}),
page("project/licensing", "License", {
description: `Bun is a MIT-licensed project with a large number of statically-linked dependencies with various licenses.`,
}),

View File

@@ -1,10 +1,7 @@
This document describes the build process for Windows. If you run into problems, please join the [#windows channel on our Discord](http://bun.sh/discord) for help.
It is strongly recommended to use [PowerShell 7 (`pwsh.exe`)](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4) instead of the default `powershell.exe`.
The following document is not yet complete, please join the [#windows channel on our Discord](http://bun.sh/discord) for help.
## Prerequisites
<!--
{% details summary="Extra notes for Bun Core Team Members" %}
Here are the extra steps I ran on my fresh windows machine (some of these are a little opiniated)
@@ -32,11 +29,17 @@ Here are the extra steps I ran on my fresh windows machine (some of these are a
I recommend using VSCode through SSH instead of Tunnels or the Tailscale extension, it seems to be more reliable.
{% /details %} -->
{% /details %}
Make sure to use powershell with the proper shell environment loaded. To do so, you can run:
```ps1
.\scripts\env.ps1
```
### Enable Scripts
By default, running unverified scripts are blocked.
By default, scripts are blocked.
```ps1
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
@@ -44,14 +47,8 @@ Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
### System Dependencies
- Bun 1.1 or later. We use Bun to run it's own code generators.
```ps1
irm bun.sh/install.ps1 | iex
```
- [Visual Studio](https://visualstudio.microsoft.com) with the "Desktop Development with C++" workload.
- Install Git and CMake from this installer, if not already installed.
- Install Git and CMake from here, if not already installed.
After Visual Studio, you need the following:
@@ -61,31 +58,25 @@ After Visual Studio, you need the following:
- NASM
- Perl
- Ruby
- Node.js
- Node.js (until bun is stable enough on windows)
{% callout %}
The Zig compiler is automatically downloaded, installed, and updated by the building process.
{% /callout %}
[Scoop](https://scoop.sh) can be used to install these remaining tools easily:
```ps1
irm https://get.scoop.sh | iex
[Scoop](https://scoop.sh) can be used to install these easily.
```bash
scoop install nodejs-lts go rust nasm ruby perl
scoop llvm@16.0.4 # scoop bug if you install llvm and the rest at the same time
```
If you intend on building WebKit locally (optional), you should install these packages:
If you intend on building WebKit locally (optional), you should install some more packages:
```ps1
```bash
scoop install make cygwin python
```
From here on out, it is **expected you use a PowerShell Terminal with `.\scripts\env.ps1` sourced**. This script is available in the Bun repository and can be loaded by executing it:
From here on out, it is **expected you use a Developer PowerShell Terminal with `.\scripts\env.ps1 sourced**. This script is available in the Bun repository and can be loaded by executing it.
```ps1
.\scripts\env.ps1
$ .\scripts\env.ps1
```
To verify, you can check for an MSVC-only command line such as `mt.exe`
@@ -94,55 +85,43 @@ To verify, you can check for an MSVC-only command line such as `mt.exe`
Get-Command mt
```
{% callout %}
It is not recommended to install `ninja` / `cmake` into your global path, because you may run into a situation where you try to build bun without .\scripts\env.ps1 sourced.
{% /callout %}
### Codegen
On Unix platforms, we depend on an existing build of Bun to generate code for itself. Since the Windows build is not stable enough for this to run the code generators, you currently need to use another computer or WSL to generate this:
```bash
$ wsl --install # run twice if it doesnt install
# in the linux environment
$ sudo apt install unzip
$ curl -fsSL https://bun.sh/install | bash
```
Whenever codegen-related things are updated, please re-run
```ps1
$ .\scripts\codegen.ps1
```
## Building
```ps1
bun install
npm install
.\scripts\env.ps1
.\scripts\update-submodules.ps1 # this syncs git submodule state
.\scripts\all-dependencies.ps1 # this builds all dependencies
.\scripts\make-old-js.ps1 # runs some old code generators
.\scripts\update-submodules.ps1
.\scripts\all-dependencies.ps1
.\scripts\codegen.ps1
# Configure build environment
cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Debug
cd build # this was created by the codegen.ps1 script in the prerequisites
# Build bun
ninja -Cbuild
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug
ninja
```
If this was successful, you should have a `bun-debug.exe` in the `build` folder.
```ps1
.\build\bun-debug.exe --revision
```
You should add this to `$Env:PATH`. The simplest way to do so is to open the start menu, type "Path", and then navigate the environment variables menu to add `C:\.....\bun\build` to the user environment variable `PATH`. You should then restart your editor (if it does not update still, log out and log back in).
## Extra paths
- WebKit is extracted to `build/bun-webkit`
- Zig is extracted to `.cache/zig/zig.exe`
## Tests
You can run the test suite either using `bun test`, or by using the wrapper script `packages\bun-internal-test`. The internal test package is a wrapper cli to run every test file in a separate instance of bun.exe, to prevent a crash in the test runner from stopping the entire suite.
```ps1
# Setup
bun i --cwd packages\bun-internal-test
# Run the entire test suite with reporter
# the package.json script "test" uses "build/bun-debug.exe" by default
bun run test
# Run an individual test file:
bun-debug test node\fs
bun-debug test "C:\bun\test\js\bun\resolve\import-meta.test.js"
.\bun-debug.exe --version
```
## Troubleshooting

View File

@@ -105,8 +105,6 @@ $ export PATH="$PATH:/usr/lib/llvm16/bin"
{% /codetabs %}
> ⚠️ Ubuntu distributions may require installation of the C++ standard library independently. See the [troubleshooting section](#span-file-not-found-on-ubuntu) for more information.
## Building Bun
After cloning the repository, run the following command to run the first build. This may take a while as it will clone submodules and build dependencies.
@@ -254,16 +252,6 @@ fatal error: 'span' file not found
^~~~~~
```
The issue may manifest when initially running `bun setup` as Clang being unable to compile a simple program:
```
The C++ compiler
"/usr/bin/clang++-16"
is not able to compile a simple test program.
```
To fix the error, we need to update the GCC version to 11. To do this, we'll need to check if the latest version is available in the distribution's official repositories or use a third-party repository that provides GCC 11 packages. Here are general steps:
```bash

View File

@@ -45,25 +45,18 @@ console.log(`Listening on http://localhost:${server.port} ...`);
{% details summary="Seeing TypeScript errors on `Bun`?" %}
If you used `bun init`, Bun will have automatically installed Bun's TypeScript declarations and configured your `tsconfig.json`. If you're trying out Bun in an existing project, you may see a type error on the `Bun` global.
To fix this, first install `@types/bun` as a dev dependency.
To fix this, first install `bun-types` as a dev dependency.
```sh
$ bun add -d @types/bun
$ bun add -d bun-types
```
Then add the following to your `compilerOptions` in `tsconfig.json`:
Then add the following line to your `compilerOptions` in `tsconfig.json`.
```json#tsconfig.json
```json-diff#tsconfig.json
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
+ "types": ["bun-types"]
}
}
```
@@ -124,12 +117,12 @@ Update `index.ts` to use `figlet` in the `fetch` handler.
+ import figlet from "figlet";
const server = Bun.serve({
port: 3000,
fetch(req) {
fetch() {
+ const body = figlet.textSync("Bun!");
+ return new Response(body);
- return new Response("Bun!");
},
port: 3000,
});
```

View File

@@ -298,7 +298,7 @@ Valid values are:
---
- `"fallback"`
- Check local `node_modules` first, then auto-install any packages that aren't found. You can enable this from the CLI with `bun -i`.
- Check local `node_modules` first, the auto-install any packages that aren't found. You can enable this from the CLI with `bun -i`.
{% /table %}

View File

@@ -116,7 +116,7 @@ Some methods are not optimized yet.
### [`node:stream`](https://nodejs.org/api/stream.html)
🟡 Missing `getDefaultHighWaterMark` `setDefaultHighWaterMark` `toWeb`
🟡 Missing `getDefaultHighWaterMark` `setDefaultHighWaterMark`
### [`node:string_decoder`](https://nodejs.org/api/string_decoder.html)
@@ -312,23 +312,23 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`PerformanceEntry`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry)
🟢 Fully implemented.
🔴 Not implemented.
### [`PerformanceMark`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMark)
🟢 Fully implemented.
🔴 Not implemented.
### [`PerformanceMeasure`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMeasure)
🟢 Fully implemented.
🔴 Not implemented.
### [`PerformanceObserver`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver)
🟢 Fully implemented.
🔴 Not implemented.
### [`PerformanceObserverEntryList`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserverEntryList)
🟢 Fully implemented.
🔴 Not implemented.
### [`PerformanceResourceTiming`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming)
@@ -356,11 +356,11 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`ReadableStreamBYOBReader`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader)
🟢 Fully implemented.
🔴 Not implemented.
### [`ReadableStreamBYOBRequest`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBRequest)
🟢 Fully implemented.
🔴 Not implemented.
### [`ReadableStreamDefaultController`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultController)

View File

@@ -214,7 +214,7 @@ With this plugin, Svelte components can now be directly imported and consumed.
import "./sveltePlugin.ts";
import MySvelteComponent from "./component.svelte";
console.log(MySvelteComponent.render());
console.log(mySvelteComponent.render());
```
## Virtual Modules

View File

@@ -269,7 +269,7 @@ import { $ } from "bun";
const search = "bun";
for await (let line of $`cat list.txt | grep ${search}`.lines()) {
for await (let line of await $`cat list.txt | grep ${search}`.lines()) {
console.log(line);
}
```
@@ -322,26 +322,15 @@ await $.braces(`echo {1,2,3}`);
// => ["echo 1", "echo 2", "echo 3"]
```
### `$.escape` (escape strings)
### `$.escape` (unescaped strings)
Exposes Bun Shell's escaping logic as a function:
For security purposes, Bun Shell escapes input by default. If you need to disable that, this function returns a string that is not escaped by Bun Shell:
```js
import { $ } from "bun";
console.log($.escape('$(foo) `bar` "baz"'))
// => \$(foo) \`bar\` \"baz\"
```
If you do not want your string to be escaped, wrap it in a `{ raw: 'str' }` object:
```js
import { $ } from "bun";
await $`echo ${{ raw: '$(foo) `bar` "baz"' }}`
// => bun: command not found: foo
// => bun: command not found: bar
// => baz
await $`echo ${$.escape("Hello World!")}`;
// => Hello World!
```
## .bun.sh file loader

View File

@@ -52,7 +52,7 @@ It is possible to specify a coverage threshold in `bunfig.toml`. If your test su
coverageThreshold = 0.9
# to set different thresholds for lines and functions
coverageThreshold = { lines = 0.9, functions = 0.9 }
coverageThreshold = { line = 0.9, function = 0.9 }
```
### Sourcemaps

View File

@@ -109,7 +109,7 @@ $ bun test --todo
## `test.only`
To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --only` will only execute tests/suites that have been marked with `.only()`. Running `bun test` without the `--only` option with `test.only()` declared will result in all tests in the given suite being executed _up to_ the test with `.only()`. `describe.only()` functions the same in both execution scenarios.
To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --only` will only execute tests/suites that have been marked with `.only()`.
```ts
import { test, describe } from "bun:test";
@@ -135,12 +135,6 @@ The following command will only execute tests #2 and #3.
$ bun test --only
```
The following command will only execute tests #1, #2 and #3.
```sh
$ bun test
```
## `test.if`
To run a test conditionally, use `test.if()`. The test will run if the condition is truthy. This is particularly useful for tests that should only run on specific architectures or operating systems.
@@ -307,7 +301,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
-
-
- [`.extend`](https://jestjs.io/docs/expect#expectextendmatchers)
---

View File

@@ -17,13 +17,13 @@ Bun supports things like top-level await, JSX, and extensioned `.ts` imports, wh
```jsonc
{
"compilerOptions": {
// Enable latest features
// enable latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"jsx": "react-jsx", // support JSX
"allowJs": true, // allow importing `.js` from `.ts`
// Bundler mode
"moduleResolution": "bundler",
@@ -34,17 +34,18 @@ Bun supports things like top-level await, JSX, and extensioned `.ts` imports, wh
// Best practices
"strict": true,
"skipLibCheck": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags
"noUnusedLocals": true,
"noUnusedParameters": true,
"useUnknownInCatchVariables": true,
"noPropertyAccessFromIndexSignature": true
}
}
```
If you run `bun init` in a new directory, this `tsconfig.json` will be generated for you. (The stricter flags are disabled by default.)
If you run `bun init` in a new directory, this `tsconfig.json` will be generated for you.
```sh
$ bun init

View File

@@ -1,8 +1,6 @@
{
"private": true,
"name": "bun",
"dependencies": {
"@biomejs/biome": "1.5.3",
"@vscode/debugadapter": "^1.61.0",
"esbuild": "^0.17.15",
"eslint": "^8.20.0",
@@ -15,11 +13,7 @@
"source-map-js": "^1.0.2",
"typescript": "^5.0.2"
},
"devDependencies": {
"@types/react": "^18.0.25",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0"
},
"private": true,
"scripts": {
"setup": "./scripts/setup.sh",
"build": "if [ ! -e build ]; then bun setup; fi && ninja -C build",
@@ -27,12 +21,19 @@
"build:release": "cmake . -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-release && ninja -Cbuild-release",
"build:safe": "cmake . -DZIG_OPTIMIZE=ReleaseSafe -DUSE_DEBUG_JSC=ON -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-safe && ninja -Cbuild-safe",
"typecheck": "tsc --noEmit && cd test && bun run typecheck",
"fmt": "biome format --write {.vscode,src,test,bench,packages/{bun-types,bun-inspector-*,bun-vscode,bun-debug-adapter-protocol}}",
"fmt:zig": "zig fmt src/*.zig src/*/*.zig src/*/*/*.zig src/*/*/*/*.zig",
"fmt": "prettier --write --cache \"./{src,test,bench,packages/{bun-types,bun-inspector-*,bun-vscode,bun-debug-adapter-protocol}}/**/*.{mjs,ts,tsx,js,jsx}\"",
"fmt:zig": "zig fmt src/*.zig src/**/*.zig",
"lint": "eslint './**/*.d.ts' --cache",
"lint:fix": "eslint './**/*.d.ts' --cache --fix",
"test": "node packages/bun-internal-test/src/runner.node.mjs ./build/bun-debug",
"test:release": "node packages/bun-internal-test/src/runner.node.mjs ./build-release/bun",
"update-known-failures": "node packages/bun-internal-test/src/update-known-windows-failures.mjs"
}
},
"devDependencies": {
"@types/react": "^18.0.25",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0"
},
"version": "0.0.0",
"prettier": "./.prettierrc.cjs"
}

View File

@@ -11,7 +11,11 @@ import type {
StackFrame,
WebsocketMessageBuildFailure,
} from "../../src/api/schema";
import { messagesToMarkdown, problemsToMarkdown, withBunInfo } from "./markdown";
import {
messagesToMarkdown,
problemsToMarkdown,
withBunInfo,
} from "./markdown";
import { fetchAllMappings, remapPosition, sourceMappings } from "./sourcemap";
export enum StackFrameScope {
@@ -78,7 +82,9 @@ enum ErrorTagType {
}
const ErrorTag = ({ type }: { type: ErrorTagType }) => (
<div className={`BunError-ErrorTag BunError-ErrorTag--${ErrorTagType[type]}`}>{ErrorTagType[type]}</div>
<div className={`BunError-ErrorTag BunError-ErrorTag--${ErrorTagType[type]}`}>
{ErrorTagType[type]}
</div>
);
const errorTags = [
@@ -127,7 +133,11 @@ function hasColumnOrLine(filename: string) {
return /:\d+/.test(filename);
}
function appendLineColumnIfNeeded(base: string, line?: number, column?: number) {
function appendLineColumnIfNeeded(
base: string,
line?: number,
column?: number,
) {
if (hasColumnOrLine(base)) return base;
return appendLineColumn(base, line, column);
@@ -145,7 +155,11 @@ function appendLineColumn(base: string, line?: number, column?: number) {
return base;
}
const blobFileURL = (filename: string, line?: number, column?: number): string => {
const blobFileURL = (
filename: string,
line?: number,
column?: number,
): string => {
var base = `/blob:${filename}`;
base = appendLineColumnIfNeeded(base, line, column);
@@ -153,7 +167,11 @@ const blobFileURL = (filename: string, line?: number, column?: number): string =
return new URL(base, globalThis.location.href).href;
};
const maybeBlobFileURL = (filename: string, line?: number, column?: number): string => {
const maybeBlobFileURL = (
filename: string,
line?: number,
column?: number,
): string => {
if (filename.includes(".bun")) {
return blobFileURL(filename, line, column);
}
@@ -165,7 +183,9 @@ const maybeBlobFileURL = (filename: string, line?: number, column?: number): str
return srcFileURL(filename, line, column);
};
const openWithoutFlashOfNewTab: React.MouseEventHandler<HTMLAnchorElement> = event => {
const openWithoutFlashOfNewTab: React.MouseEventHandler<HTMLAnchorElement> = (
event,
) => {
const target = event.currentTarget;
const href = target.getAttribute("href");
if (!href || event.button !== 0) {
@@ -196,13 +216,18 @@ const openWithoutFlashOfNewTab: React.MouseEventHandler<HTMLAnchorElement> = eve
})
.then(
() => {},
er => {},
(er) => {},
);
return false;
};
const srcFileURL = (filename: string, line?: number, column?: number): string => {
if (filename.startsWith("http://") || filename.startsWith("https://")) return appendLineColumnIfNeeded(filename);
const srcFileURL = (
filename: string,
line?: number,
column?: number,
): string => {
if (filename.startsWith("http://") || filename.startsWith("https://"))
return appendLineColumnIfNeeded(filename);
if (filename.endsWith(".bun")) {
return new URL("/" + filename, globalThis.location.href).href;
@@ -247,7 +272,10 @@ class FancyTypeError {
const nextWord = /(["a-zA-Z0-9_\.]+)\)$/.exec(partial);
if (nextWord && nextWord[0]) {
this.runtimeTypeName = nextWord[0];
this.runtimeTypeName = this.runtimeTypeName.substring(0, this.runtimeTypeName.length - 1);
this.runtimeTypeName = this.runtimeTypeName.substring(
0,
this.runtimeTypeName.length - 1,
);
switch (this.runtimeTypeName.toLowerCase()) {
case "undefined": {
this.runtimeType = RuntimeType.Undefined;
@@ -284,12 +312,15 @@ class FancyTypeError {
}
}
this.message = exception.message.substring(0, i);
this.message = this.message.substring(0, this.message.lastIndexOf("(In "));
this.message = this.message.substring(
0,
this.message.lastIndexOf("(In "),
);
}
}
}
export const clientURL = filename => {
export const clientURL = (filename) => {
if (filename.includes(".bun")) {
return `/${filename.replace(/^(\/)?/g, "")}`;
}
@@ -337,17 +368,22 @@ const AsyncSourceLines = ({
Accept: "text/plain",
},
})
.then(resp => {
.then((resp) => {
return resp.text();
})
.then(text => {
.then((text) => {
if (cancelled) return;
// TODO: make this faster
const lines = text.split("\n");
const startLineNumber = Math.max(Math.min(Math.max(highlight - 4, 0), lines.length - 1), 0);
const startLineNumber = Math.max(
Math.min(Math.max(highlight - 4, 0), lines.length - 1),
0,
);
const endLineNumber = Math.min(startLineNumber + 8, lines.length);
const sourceLines: SourceLine[] = new Array(endLineNumber - startLineNumber);
const sourceLines: SourceLine[] = new Array(
endLineNumber - startLineNumber,
);
var index = 0;
for (let i = startLineNumber; i < endLineNumber; i++) {
const currentLine = lines[i - 1];
@@ -358,10 +394,14 @@ const AsyncSourceLines = ({
};
}
setSourceLines(index !== sourceLines.length ? sourceLines.slice(0, index) : sourceLines);
setSourceLines(
index !== sourceLines.length
? sourceLines.slice(0, index)
: sourceLines,
);
setLoadState(LoadState.loaded);
})
.catch(err => {
.catch((err) => {
if (!cancelled) {
console.error(err);
setLoadState(LoadState.failed);
@@ -459,7 +499,8 @@ const SourceLines = ({
}
}
const leftPad = maxLineNumber.toString(10).length - minLineNumber.toString(10).length;
const leftPad =
maxLineNumber.toString(10).length - minLineNumber.toString(10).length;
const _sourceLines = sourceLines.slice(start, end);
const lines = new Array(_sourceLines.length + React.Children.count(children));
@@ -479,10 +520,15 @@ const SourceLines = ({
data-line={line}
data-column={classes.highlight ? highlightColumnStart : dedent}
title={`Open line ${line} in editor`}
href={buildURL(line, classes.highlight ? highlightColumnStart : dedent)}
href={buildURL(
line,
classes.highlight ? highlightColumnStart : dedent,
)}
onClickCapture={openWithoutFlashOfNewTab}
key={"highlight-number-" + line}
className={`BunError-SourceLine-number ${classes.empty ? "BunError-SourceLine-number--empty" : ""} ${
className={`BunError-SourceLine-number ${
classes.empty ? "BunError-SourceLine-number--empty" : ""
} ${
classes.highlight ? "BunError-SourceLine-number--highlight" : ""
}`}
>
@@ -490,9 +536,9 @@ const SourceLines = ({
</a>
<div
tabIndex={i}
className={`BunError-SourceLine-text ${classes.empty ? "BunError-SourceLine-text--empty" : ""} ${
classes.highlight ? "BunError-SourceLine-text--highlight" : ""
}`}
className={`BunError-SourceLine-text ${
classes.empty ? "BunError-SourceLine-text--empty" : ""
} ${classes.highlight ? "BunError-SourceLine-text--highlight" : ""}`}
>
{_text}
</div>
@@ -503,7 +549,9 @@ const SourceLines = ({
return (
<IndentationContext.Provider value={dedent}>
<div className="BunError-SourceLines">
<div className={`BunError-SourceLines-highlighter--${highlightI}`}></div>
<div
className={`BunError-SourceLines-highlighter--${highlightI}`}
></div>
{lines}
</div>
@@ -520,7 +568,10 @@ const BuildErrorSourceLines = ({
}) => {
const { line, line_text, column } = location;
const sourceLines: SourceLine[] = [{ line, text: line_text }];
const buildURL = React.useCallback((line, column) => srcFileURL(filename, line, column), [srcFileURL, filename]);
const buildURL = React.useCallback(
(line, column) => srcFileURL(filename, line, column),
[srcFileURL, filename],
);
return (
<SourceLines
sourceLines={sourceLines}
@@ -562,7 +613,8 @@ export const StackFrameIdentifier = ({
}) => {
switch (scope) {
case StackFrameScope.Constructor: {
functionName = markdown && functionName ? "`" + functionName + "`" : functionName;
functionName =
markdown && functionName ? "`" + functionName + "`" : functionName;
return functionName ? `new ${functionName}` : "new (anonymous)";
}
@@ -584,12 +636,16 @@ export const StackFrameIdentifier = ({
case StackFrameScope.Function:
default: {
return functionName ? (markdown ? "`" + functionName + "`" : functionName) : "λ()";
return functionName
? markdown
? "`" + functionName + "`"
: functionName
: "λ()";
}
}
};
const getNativeStackFrameIdentifier = frame => {
const getNativeStackFrameIdentifier = (frame) => {
const { file, function_name: functionName, scope } = frame;
return StackFrameIdentifier({
@@ -617,7 +673,11 @@ const NativeStackFrame = ({
} = frame;
const fileName = normalizedFilename(file, cwd);
return (
<div className={`BunError-StackFrame ${fileName.endsWith(".bun") ? "BunError-StackFrame--muted" : ""}`}>
<div
className={`BunError-StackFrame ${
fileName.endsWith(".bun") ? "BunError-StackFrame--muted" : ""
}`}
>
<div
title={StackFrameScope[scope]}
className="BunError-StackFrame-identifier"
@@ -640,7 +700,9 @@ const NativeStackFrame = ({
<div className="BunError-StackFrame-link-content">
<div className={`BunError-StackFrame-file`}>{fileName}</div>
{line > -1 && <div className="BunError-StackFrame-line">:{line}</div>}
{column > -1 && <div className="BunError-StackFrame-column">:{column}</div>}
{column > -1 && (
<div className="BunError-StackFrame-column">:{column}</div>
)}
</div>
</a>
</div>
@@ -652,11 +714,21 @@ const NativeStackFrames = ({ frames, urlBuilder }) => {
var maxLength = 0;
for (let i = 0; i < frames.length; i++) {
maxLength = Math.max(getNativeStackFrameIdentifier(frames[i]).length, maxLength);
maxLength = Math.max(
getNativeStackFrameIdentifier(frames[i]).length,
maxLength,
);
}
for (let i = 0; i < frames.length; i++) {
items[i] = <NativeStackFrame maxLength={maxLength} urlBuilder={urlBuilder} key={i} frame={frames[i]} />;
items[i] = (
<NativeStackFrame
maxLength={maxLength}
urlBuilder={urlBuilder}
key={i}
frame={frames[i]}
/>
);
}
return (
@@ -684,7 +756,10 @@ const NativeStackTrace = ({
const filename = normalizedFilename(file, cwd);
const urlBuilder = isClient ? clientURL : maybeBlobFileURL;
const ref = React.useRef<HTMLDivElement>(null);
const buildURL = React.useCallback((line, column) => urlBuilder(file, line, column), [file, urlBuilder]);
const buildURL = React.useCallback(
(line, column) => urlBuilder(file, line, column),
[file, urlBuilder],
);
return (
<div ref={ref} className={`BunError-NativeStackTrace`}>
@@ -722,7 +797,9 @@ const NativeStackTrace = ({
{children}
</AsyncSourceLines>
)}
{frames.length > 1 && <NativeStackFrames urlBuilder={urlBuilder} frames={frames} />}
{frames.length > 1 && (
<NativeStackFrames urlBuilder={urlBuilder} frames={frames} />
)}
</div>
);
};
@@ -745,7 +822,9 @@ const JSException = ({
isClient: boolean;
}) => {
const tag = isClient ? ErrorTagType.client : ErrorTagType.server;
const [sourceLines, _setSourceLines] = React.useState(value?.stack?.source_lines ?? []);
const [sourceLines, _setSourceLines] = React.useState(
value?.stack?.source_lines ?? [],
);
var message = value.message || "";
var name = value.name || "";
if (!name && !message) {
@@ -770,17 +849,25 @@ const JSException = ({
if (fancyTypeError.runtimeType !== RuntimeType.Nothing) {
return (
<div className={`BunError-JSException BunError-JSException--TypeError`}>
<div
className={`BunError-JSException BunError-JSException--TypeError`}
>
<div className="BunError-error-header">
<div className={`BunError-error-code`}>TypeError</div>
{errorTags[tag]}
</div>
<div className={`BunError-error-message`}>{fancyTypeError.message}</div>
<div className={`BunError-error-message`}>
{fancyTypeError.message}
</div>
{fancyTypeError.runtimeTypeName.length && (
<div className={`BunError-error-subtitle`}>
It's <span className="BunError-error-typename">{fancyTypeError.runtimeTypeName}</span>.
It's{" "}
<span className="BunError-error-typename">
{fancyTypeError.runtimeTypeName}
</span>
.
</div>
)}
@@ -792,7 +879,9 @@ const JSException = ({
setSourceLines={setSourceLines}
>
<Indent by={value.stack.frames[0].position.column_start}>
<span className="BunError-error-typename">{fancyTypeError.runtimeTypeName}</span>
<span className="BunError-error-typename">
{fancyTypeError.runtimeTypeName}
</span>
</Indent>
</NativeStackTrace>
)}
@@ -867,8 +956,17 @@ const Summary = ({
{errorCount}&nbsp;error{errorCount > 1 ? "s" : ""}&nbsp;on this page
</div>
<a href="https://bun.sh/discord" target="_blank" className="BunError-Summary-help">
<svg width="18" viewBox="0 0 71 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<a
href="https://bun.sh/discord"
target="_blank"
className="BunError-Summary-help"
>
<svg
width="18"
viewBox="0 0 71 55"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)">
<path
d="M60.1045 4.8978C55.5792 2.8214 50.7265 1.2916 45.6527 0.41542C45.5603 0.39851 45.468 0.440769 45.4204 0.525289C44.7963 1.6353 44.105 3.0834 43.6209 4.2216C38.1637 3.4046 32.7345 3.4046 27.3892 4.2216C26.905 3.0581 26.1886 1.6353 25.5617 0.525289C25.5141 0.443589 25.4218 0.40133 25.3294 0.41542C20.2584 1.2888 15.4057 2.8186 10.8776 4.8978C10.8384 4.9147 10.8048 4.9429 10.7825 4.9795C1.57795 18.7309 -0.943561 32.1443 0.293408 45.3914C0.299005 45.4562 0.335386 45.5182 0.385761 45.5576C6.45866 50.0174 12.3413 52.7249 18.1147 54.5195C18.2071 54.5477 18.305 54.5139 18.3638 54.4378C19.7295 52.5728 20.9469 50.6063 21.9907 48.5383C22.0523 48.4172 21.9935 48.2735 21.8676 48.2256C19.9366 47.4931 18.0979 46.6 16.3292 45.5858C16.1893 45.5041 16.1781 45.304 16.3068 45.2082C16.679 44.9293 17.0513 44.6391 17.4067 44.3461C17.471 44.2926 17.5606 44.2813 17.6362 44.3151C29.2558 49.6202 41.8354 49.6202 53.3179 44.3151C53.3935 44.2785 53.4831 44.2898 53.5502 44.3433C53.9057 44.6363 54.2779 44.9293 54.6529 45.2082C54.7816 45.304 54.7732 45.5041 54.6333 45.5858C52.8646 46.6197 51.0259 47.4931 49.0921 48.2228C48.9662 48.2707 48.9102 48.4172 48.9718 48.5383C50.038 50.6034 51.2554 52.5699 52.5959 54.435C52.6519 54.5139 52.7526 54.5477 52.845 54.5195C58.6464 52.7249 64.529 50.0174 70.6019 45.5576C70.6551 45.5182 70.6887 45.459 70.6943 45.3942C72.1747 30.0791 68.2147 16.7757 60.1968 4.9823C60.1772 4.9429 60.1437 4.9147 60.1045 4.8978ZM23.7259 37.3253C20.2276 37.3253 17.3451 34.1136 17.3451 30.1693C17.3451 26.225 20.1717 23.0133 23.7259 23.0133C27.308 23.0133 30.1626 26.2532 30.1066 30.1693C30.1066 34.1136 27.28 37.3253 23.7259 37.3253ZM47.3178 37.3253C43.8196 37.3253 40.9371 34.1136 40.9371 30.1693C40.9371 26.225 43.7636 23.0133 47.3178 23.0133C50.9 23.0133 53.7545 26.2532 53.6986 30.1693C53.6986 34.1136 50.9 37.3253 47.3178 37.3253Z"
@@ -907,9 +1005,13 @@ const BuildError = ({ message }: { message: Message }) => {
<div className={`BunError-error-message`}>{title}</div>
{subtitle.length > 0 && <div className={`BunError-error-subtitle`}>{subtitle}</div>}
{subtitle.length > 0 && (
<div className={`BunError-error-subtitle`}>{subtitle}</div>
)}
{message.data.location && <BuildErrorStackTrace location={message.data.location} />}
{message.data.location && (
<BuildErrorStackTrace location={message.data.location} />
)}
</div>
);
};
@@ -932,12 +1034,16 @@ const ResolveError = ({ message }: { message: Message }) => {
<div className={`BunError-error-message`}>
Can't import{" "}
<span className="BunError-error-message--mono BunError-error-message--quoted">"{message.on.resolve}"</span>
<span className="BunError-error-message--mono BunError-error-message--quoted">
"{message.on.resolve}"
</span>
</div>
{subtitle && <div className={`BunError-error-subtitle`}>{subtitle}</div>}
{message.data.location && <BuildErrorStackTrace location={message.data.location} />}
{message.data.location && (
<BuildErrorStackTrace location={message.data.location} />
)}
</div>
);
};
@@ -946,7 +1052,9 @@ const OverlayMessageContainer = ({
reason,
isClient = false,
}: FallbackMessageContainer & { isClient: boolean }) => {
const errorCount = problems ? problems.exceptions.length + problems.build.errors : 0;
const errorCount = problems
? problems.exceptions.length + problems.build.errors
: 0;
return (
<div id="BunErrorOverlay-container">
<div className="BunError-content">
@@ -978,7 +1086,7 @@ function copyToClipboard(input: string | Promise<string>) {
if (!input) return;
if (typeof input === "object" && "then" in input) {
return input.then(str => copyToClipboard(str));
return input.then((str) => copyToClipboard(str));
}
return navigator.clipboard.writeText(input).then(() => {});
@@ -1040,7 +1148,9 @@ function renderWithFunc(func) {
reactRoot = document.createElement("div");
reactRoot.id = BUN_ERROR_CONTAINER_ID;
const fallbackStyleSheet = document.querySelector("style[data-has-bun-fallback-style]");
const fallbackStyleSheet = document.querySelector(
"style[data-has-bun-fallback-style]",
);
if (!fallbackStyleSheet) {
reactRoot.style.visibility = "hidden";
}
@@ -1094,7 +1204,7 @@ import { parse as getStackTrace } from "./stack-trace-parser";
var runtimeErrorController: AbortController | null = null;
var pending: { stopped: boolean }[] = [];
var onIdle = globalThis.requestIdleCallback || (cb => setTimeout(cb, 32));
var onIdle = globalThis.requestIdleCallback || ((cb) => setTimeout(cb, 32));
function clearSourceMappings() {
sourceMappings.clear();
}
@@ -1160,7 +1270,8 @@ export function renderRuntimeError(error: Error) {
exception.stack.frames[0].position.line = error[lineNumberProperty];
if (Number.isFinite(error[columnNumberProperty])) {
exception.stack.frames[0].position.column_start = error[columnNumberProperty];
exception.stack.frames[0].position.column_start =
error[columnNumberProperty];
}
}
}
@@ -1197,18 +1308,20 @@ export function renderRuntimeError(error: Error) {
// Rely on the cached ones
// and don't fetch them again
const framePromises = fetchAllMappings(
exception.stack.frames.map(frame => normalizedFilename(frame.file, thisCwd)),
exception.stack.frames.map((frame) =>
normalizedFilename(frame.file, thisCwd),
),
signal,
)
.map((frame, i) => {
if (stopThis.stopped) return null;
return [frame, i];
})
.map(result => {
.map((result) => {
if (!result) return;
const [mappings, frameIndex] = result;
if (mappings?.then) {
return mappings.then(mappings => {
return mappings.then((mappings) => {
if (!mappings || stopThis.stopped) {
return null;
}
@@ -1278,7 +1391,10 @@ export function dismissError() {
}
}
export const renderBuildFailure = (failure: WebsocketMessageBuildFailure, cwd: string) => {
export const renderBuildFailure = (
failure: WebsocketMessageBuildFailure,
cwd: string,
) => {
thisCwd = cwd;
renderWithFunc(() => (
<ErrorGroupContext.Provider value={{ cwd }}>

View File

@@ -1,5 +1,15 @@
import { normalizedFilename, StackFrameIdentifier, thisCwd, StackFrameScope } from "./index";
import type { JSException, JSException as JSExceptionType, Message, Problems } from "../../src/api/schema";
import {
normalizedFilename,
StackFrameIdentifier,
thisCwd,
StackFrameScope,
} from "./index";
import type {
JSException,
JSException as JSExceptionType,
Message,
Problems,
} from "../../src/api/schema";
export function problemsToMarkdown(problems: Problems) {
var markdown = "";
@@ -17,14 +27,14 @@ export function problemsToMarkdown(problems: Problems) {
export function messagesToMarkdown(messages: Message[]): string {
return messages
.map(messageToMarkdown)
.map(a => a.trim())
.map((a) => a.trim())
.join("\n");
}
export function exceptionsToMarkdown(exceptions: JSExceptionType[]): string {
return exceptions
.map(exceptionToMarkdown)
.map(a => a.trim())
.map((a) => a.trim())
.join("\n");
}
@@ -63,7 +73,11 @@ function exceptionToMarkdown(exception: JSException): string {
const {
file: _file = "",
function_name = "",
position: { line = -1, column_start: column = -1, column_stop: columnEnd = column } = {
position: {
line = -1,
column_start: column = -1,
column_stop: columnEnd = column,
} = {
line: -1,
column_start: -1,
column_stop: -1,
@@ -100,17 +114,23 @@ function exceptionToMarkdown(exception: JSException): string {
markdown += "\n```";
markdown += extname;
markdown += "\n";
stack.source_lines.forEach(sourceLine => {
stack.source_lines.forEach((sourceLine) => {
const lineText = sourceLine.text.trimEnd();
markdown += lineText + "\n";
if (sourceLine.line === line && stack.source_lines.length > 1) {
// the comment should start at the first non-whitespace character
// ideally it should be length the original line
// but it may not be
var prefix = "".padStart(lineText.length - lineText.trimStart().length, " ");
var prefix = "".padStart(
lineText.length - lineText.trimStart().length,
" ",
);
prefix += "/* ".padEnd(column - 1 - prefix.length, " ") + "^ happened here ";
markdown += prefix.padEnd(Math.max(lineText.length, 1) - 1, " ") + "*/\n";
prefix +=
"/* ".padEnd(column - 1 - prefix.length, " ") +
"^ happened here ";
markdown +=
prefix.padEnd(Math.max(lineText.length, 1) - 1, " ") + "*/\n";
}
});
markdown = markdown.trimEnd() + "\n```";
@@ -220,9 +240,11 @@ function messageToMarkdown(message: Message): string {
if (message.data.location.line_text.length) {
const extnameI = message.data.location.file.lastIndexOf(".");
const extname = extnameI > -1 ? message.data.location.file.slice(extnameI + 1) : "";
const extname =
extnameI > -1 ? message.data.location.file.slice(extnameI + 1) : "";
markdown += "\n```" + extname + "\n" + message.data.location.line_text + "\n```\n";
markdown +=
"\n```" + extname + "\n" + message.data.location.line_text + "\n```\n";
} else {
markdown += "\n";
}
@@ -235,14 +257,14 @@ function messageToMarkdown(message: Message): string {
return markdown;
}
export const withBunInfo = text => {
export const withBunInfo = (text) => {
const bunInfo = getBunInfo();
const trimmed = text.trim();
if (bunInfo && "then" in bunInfo) {
return bunInfo.then(
info => {
(info) => {
const markdown = bunInfoToMarkdown(info).trim();
return trimmed + "\n" + markdown + "\n";
},
@@ -357,8 +379,8 @@ function getBunInfo() {
Accept: "application/json",
},
})
.then(resp => resp.json())
.then(bunInfo => {
.then((resp) => resp.json())
.then((bunInfo) => {
clearTimeout(id);
bunInfoMemoized = bunInfo;
if ("sessionStorage" in globalThis) {

View File

@@ -1,6 +1,10 @@
// Based on https://github.com/stacktracejs/error-stack-parser/blob/master/error-stack-parser.js
import type { StackFrame as StackFrameType, StackFramePosition, StackFrameScope } from "../../src/api/schema";
import type {
StackFrame as StackFrameType,
StackFramePosition,
StackFrameScope,
} from "../../src/api/schema";
export class StackFrame implements StackFrameType {
function_name: string;
@@ -85,7 +89,9 @@ export default class RuntimeError {
return filtered.map(function (line) {
if (line.indexOf("(eval ") > -1) {
// Throw away eval information until we implement stacktrace.js/stackframe#8
line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(\),.*$)/g, "");
line = line
.replace(/eval code/g, "eval")
.replace(/(\(eval at [^()]*)|(\),.*$)/g, "");
}
var sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(");
@@ -94,13 +100,20 @@ export default class RuntimeError {
var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
// remove the parenthesized location from the line, if it was matched
sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
sanitizedLine = location
? sanitizedLine.replace(location[0], "")
: sanitizedLine;
var tokens = sanitizedLine.split(/\s+/).slice(1);
// if a location was matched, pass it to extractLocation() otherwise pop the last token
var locationParts = this.extractLocation(location ? location[1] : tokens.pop());
var locationParts = this.extractLocation(
location ? location[1] : tokens.pop(),
);
var functionName = tokens.join(" ") || undefined;
var fileName = ["eval", "<anonymous>"].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0];
var fileName =
["eval", "<anonymous>"].indexOf(locationParts[0]) > -1
? undefined
: locationParts[0];
return new StackFrame({
functionName: functionName,
@@ -120,7 +133,10 @@ export default class RuntimeError {
return filtered.map(function (line) {
// Throw away eval information until we implement stacktrace.js/stackframe#8
if (line.indexOf(" > eval") > -1) {
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
line = line.replace(
/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
":$1",
);
}
if (line.indexOf("@") === -1 && line.indexOf(":") === -1) {
@@ -132,7 +148,9 @@ export default class RuntimeError {
var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/;
var matches = line.match(functionNameRegex);
var functionName = matches && matches[1] ? matches[1] : undefined;
var locationParts = this.extractLocation(line.replace(functionNameRegex, ""));
var locationParts = this.extractLocation(
line.replace(functionNameRegex, ""),
);
return new StackFrame({
functionName: functionName,

View File

@@ -1,6 +1,7 @@
// Accelerate VLQ decoding with a lookup table
const vlqTable = new Uint8Array(128);
const vlqChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const vlqChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
vlqTable.fill(0xff);
for (let i = 0; i < vlqChars.length; i++) vlqTable[vlqChars.charCodeAt(i)] = i;
@@ -9,7 +10,10 @@ export function parseSourceMap(json) {
throw new Error("Invalid source map");
}
if (!(json.sources instanceof Array) || json.sources.some(x => typeof x !== "string")) {
if (
!(json.sources instanceof Array) ||
json.sources.some((x) => typeof x !== "string")
) {
throw new Error("Invalid source map");
}
@@ -143,7 +147,8 @@ export function decodeMappings(mappings, sourcesCount) {
// Read the original source
const originalSourceDelta = decodeVLQ();
originalSource += originalSourceDelta;
if (originalSource < 0 || originalSource >= sourcesCount) decodeError("Invalid original source");
if (originalSource < 0 || originalSource >= sourcesCount)
decodeError("Invalid original source");
// Read the original line
const originalLineDelta = decodeVLQ();
@@ -206,7 +211,11 @@ export function decodeMappings(mappings, sourcesCount) {
return data.subarray(0, dataLength);
}
export function remapPosition(decodedMappings: Int32Array, line: number, column: number) {
export function remapPosition(
decodedMappings: Int32Array,
line: number,
column: number,
) {
if (!(decodedMappings instanceof Int32Array)) {
throw new Error("decodedMappings must be an Int32Array");
}
@@ -251,7 +260,7 @@ export function fetchMappings(file, signal) {
return sourceMappings.get(file);
}
return fetchRemoteSourceMap(file, signal).then(json => {
return fetchRemoteSourceMap(file, signal).then((json) => {
if (!json) return null;
const { data } = parseSourceMap(json);
sourceMappings.set(file, data);
@@ -276,11 +285,11 @@ export function fetchAllMappings(files, signal) {
var resolvers = [];
for (let i = 0; i < indices.length; i++) {
results[indices[i]] = new Promise((resolve, reject) => {
resolvers[i] = res => resolve(res ? [res, i] : null);
resolvers[i] = (res) => resolve(res ? [res, i] : null);
});
}
mapped.finally(a => {
mapped.finally((a) => {
for (let resolve of resolvers) {
try {
resolve(a);
@@ -311,7 +320,10 @@ function indexOfMapping(mappings: Int32Array, line: number, column: number) {
var i = index + step;
// this multiply is slow but it's okay for now
var j = i * 6;
if (mappings[j] < line || (mappings[j] == line && mappings[j + 1] <= column)) {
if (
mappings[j] < line ||
(mappings[j] == line && mappings[j + 1] <= column)
) {
index = i + 1;
count -= step + 1;
} else {

View File

@@ -17,7 +17,12 @@ export function parse(stackString): StackFrame[] {
const lines = stackString.split("\n");
return lines.reduce((stack, line) => {
const parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
const parseResult =
parseChrome(line) ||
parseWinjs(line) ||
parseGecko(line) ||
parseNode(line) ||
parseJSC(line);
if (parseResult) {
stack.push(parseResult);
@@ -27,14 +32,15 @@ export function parse(stackString): StackFrame[] {
}, []);
}
const formatFile = file => {
const formatFile = (file) => {
if (!file) {
return "";
}
if (file.startsWith("blob:")) {
if (globalThis["__BUN"]?.client) {
const replacement = globalThis["__BUN"]?.client.dependencies.getFilePathFromBlob(file);
const replacement =
globalThis["__BUN"]?.client.dependencies.getFilePathFromBlob(file);
if (replacement) {
file = replacement;
}
@@ -140,7 +146,8 @@ function parseGecko(line) {
};
}
const javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
const javaScriptCoreRe =
/^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
function parseJSC(line) {
const parts = javaScriptCoreRe.exec(line);
@@ -159,7 +166,8 @@ function parseJSC(line) {
};
}
const nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
const nodeRe =
/^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
function parseNode(line) {
const parts = nodeRe.exec(line);

View File

@@ -48,7 +48,10 @@
"id": "Channel",
"description": "Logging channel.",
"type": "object",
"properties": [{ "name": "source", "$ref": "ChannelSource" }, { "name": "level", "$ref": "ChannelLevel" }]
"properties": [
{ "name": "source", "$ref": "ChannelSource" },
{ "name": "level", "$ref": "ChannelLevel" }
]
},
{
"id": "ConsoleMessage",
@@ -1139,7 +1142,10 @@
{
"name": "snapshot",
"description": "Take a heap snapshot.",
"returns": [{ "name": "timestamp", "type": "number" }, { "name": "snapshotData", "$ref": "HeapSnapshotData" }]
"returns": [
{ "name": "timestamp", "type": "number" },
{ "name": "snapshotData", "$ref": "HeapSnapshotData" }
]
},
{
"name": "startTracking",
@@ -1229,7 +1235,10 @@
{ "name": "evaluateForTestInFrontend", "parameters": [{ "name": "script", "type": "string" }] },
{
"name": "inspect",
"parameters": [{ "name": "object", "$ref": "Runtime.RemoteObject" }, { "name": "hints", "type": "object" }]
"parameters": [
{ "name": "object", "$ref": "Runtime.RemoteObject" },
{ "name": "hints", "type": "object" }
]
}
]
},

View File

@@ -1518,7 +1518,10 @@
"id": "EventMetadata",
"description": "A key-value pair for additional event information to pass along.",
"type": "object",
"properties": [{ "name": "key", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "key", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "BackgroundServiceEvent",
@@ -1570,7 +1573,10 @@
{
"name": "setRecording",
"description": "Set the recording state for the service.",
"parameters": [{ "name": "shouldRecord", "type": "boolean" }, { "name": "service", "$ref": "ServiceName" }]
"parameters": [
{ "name": "shouldRecord", "type": "boolean" },
{ "name": "service", "$ref": "ServiceName" }
]
},
{
"name": "clearEvents",
@@ -1582,7 +1588,10 @@
{
"name": "recordingStateChanged",
"description": "Called when the recording state for the service has been updated.",
"parameters": [{ "name": "isRecording", "type": "boolean" }, { "name": "service", "$ref": "ServiceName" }]
"parameters": [
{ "name": "isRecording", "type": "boolean" },
{ "name": "service", "$ref": "ServiceName" }
]
},
{
"name": "backgroundServiceEventReceived",
@@ -2072,7 +2081,10 @@
{
"id": "Header",
"type": "object",
"properties": [{ "name": "name", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "name", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "CachedResponse",
@@ -3442,7 +3454,10 @@
{
"name": "setStyleSheetText",
"description": "Sets the new stylesheet text.",
"parameters": [{ "name": "styleSheetId", "$ref": "StyleSheetId" }, { "name": "text", "type": "string" }],
"parameters": [
{ "name": "styleSheetId", "$ref": "StyleSheetId" },
{ "name": "text", "type": "string" }
],
"returns": [
{
"name": "sourceMapURL",
@@ -3567,7 +3582,10 @@
},
{
"name": "executeSQL",
"parameters": [{ "name": "databaseId", "$ref": "DatabaseId" }, { "name": "query", "type": "string" }],
"parameters": [
{ "name": "databaseId", "$ref": "DatabaseId" },
{ "name": "query", "type": "string" }
],
"returns": [
{ "name": "columnNames", "optional": true, "type": "array", "items": { "type": "string" } },
{ "name": "values", "optional": true, "type": "array", "items": { "type": "any" } },
@@ -3608,7 +3626,10 @@
{
"name": "selectPrompt",
"description": "Select a device in response to a DeviceAccess.deviceRequestPrompted event.",
"parameters": [{ "name": "id", "$ref": "RequestId" }, { "name": "deviceId", "$ref": "DeviceId" }]
"parameters": [
{ "name": "id", "$ref": "RequestId" },
{ "name": "deviceId", "$ref": "DeviceId" }
]
},
{
"name": "cancelPrompt",
@@ -5656,7 +5677,10 @@
},
{
"name": "removeDOMStorageItem",
"parameters": [{ "name": "storageId", "$ref": "StorageId" }, { "name": "key", "type": "string" }]
"parameters": [
{ "name": "storageId", "$ref": "StorageId" },
{ "name": "key", "type": "string" }
]
},
{
"name": "setDOMStorageItem",
@@ -5678,7 +5702,10 @@
},
{
"name": "domStorageItemRemoved",
"parameters": [{ "name": "storageId", "$ref": "StorageId" }, { "name": "key", "type": "string" }]
"parameters": [
{ "name": "storageId", "$ref": "StorageId" },
{ "name": "key", "type": "string" }
]
},
{
"name": "domStorageItemUpdated",
@@ -5748,7 +5775,10 @@
{
"id": "MediaFeature",
"type": "object",
"properties": [{ "name": "name", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "name", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "VirtualTimePolicy",
@@ -5762,7 +5792,10 @@
"description": "Used to specify User Agent Cient Hints to emulate. See https://wicg.github.io/ua-client-hints",
"experimental": true,
"type": "object",
"properties": [{ "name": "brand", "type": "string" }, { "name": "version", "type": "string" }]
"properties": [
{ "name": "brand", "type": "string" },
{ "name": "version", "type": "string" }
]
},
{
"id": "UserAgentMetadata",
@@ -6120,7 +6153,10 @@
"name": "setSensorOverrideReadings",
"description": "Updates the sensor readings reported by a sensor type previously overriden\nby setSensorOverrideEnabled.",
"experimental": true,
"parameters": [{ "name": "type", "$ref": "SensorType" }, { "name": "reading", "$ref": "SensorReading" }]
"parameters": [
{ "name": "type", "$ref": "SensorType" },
{ "name": "reading", "$ref": "SensorReading" }
]
},
{
"name": "setIdleOverride",
@@ -6405,11 +6441,17 @@
{ "name": "disable" },
{
"name": "selectAccount",
"parameters": [{ "name": "dialogId", "type": "string" }, { "name": "accountIndex", "type": "integer" }]
"parameters": [
{ "name": "dialogId", "type": "string" },
{ "name": "accountIndex", "type": "integer" }
]
},
{
"name": "clickDialogButton",
"parameters": [{ "name": "dialogId", "type": "string" }, { "name": "dialogButton", "$ref": "DialogButton" }]
"parameters": [
{ "name": "dialogId", "type": "string" },
{ "name": "dialogButton", "$ref": "DialogButton" }
]
},
{
"name": "dismissDialog",
@@ -6464,7 +6506,10 @@
"id": "HeaderEntry",
"description": "Response HTTP header entry",
"type": "object",
"properties": [{ "name": "name", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "name", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "AuthChallenge",
@@ -8301,19 +8346,28 @@
"id": "PlayerProperty",
"description": "Corresponds to kMediaPropertyChange",
"type": "object",
"properties": [{ "name": "name", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "name", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "PlayerEvent",
"description": "Corresponds to kMediaEventTriggered",
"type": "object",
"properties": [{ "name": "timestamp", "$ref": "Timestamp" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "timestamp", "$ref": "Timestamp" },
{ "name": "value", "type": "string" }
]
},
{
"id": "PlayerErrorSourceLocation",
"description": "Represents logged source line numbers reported in an error.\nNOTE: file and line are from chromium c++ implementation code, not js.",
"type": "object",
"properties": [{ "name": "file", "type": "string" }, { "name": "line", "type": "integer" }]
"properties": [
{ "name": "file", "type": "string" },
{ "name": "line", "type": "integer" }
]
},
{
"id": "PlayerError",
@@ -12357,7 +12411,10 @@
"description": "Pair of issuer origin and number of available (signed, but not used) Trust\nTokens from that issuer.",
"experimental": true,
"type": "object",
"properties": [{ "name": "issuerOrigin", "type": "string" }, { "name": "count", "type": "number" }]
"properties": [
{ "name": "issuerOrigin", "type": "string" },
{ "name": "count", "type": "number" }
]
},
{
"id": "InterestGroupAccessType",
@@ -12420,7 +12477,10 @@
"id": "SharedStorageEntry",
"description": "Struct for a single key-value pair in an origin's shared storage.",
"type": "object",
"properties": [{ "name": "key", "type": "string" }, { "name": "value", "type": "string" }]
"properties": [
{ "name": "key", "type": "string" },
{ "name": "value", "type": "string" }
]
},
{
"id": "SharedStorageMetadata",
@@ -12436,7 +12496,10 @@
"id": "SharedStorageReportingMetadata",
"description": "Pair of reporting metadata details for a candidate URL for `selectURL()`.",
"type": "object",
"properties": [{ "name": "eventType", "type": "string" }, { "name": "reportingUrl", "type": "string" }]
"properties": [
{ "name": "eventType", "type": "string" },
{ "name": "reportingUrl", "type": "string" }
]
},
{
"id": "SharedStorageUrlWithMetadata",
@@ -12568,7 +12631,10 @@
"id": "AttributionReportingAggregationKeysEntry",
"experimental": true,
"type": "object",
"properties": [{ "name": "key", "type": "string" }, { "name": "value", "$ref": "UnsignedInt128AsBase16" }]
"properties": [
{ "name": "key", "type": "string" },
{ "name": "value", "$ref": "UnsignedInt128AsBase16" }
]
},
{
"id": "AttributionReportingEventReportWindows",
@@ -12943,7 +13009,10 @@
"name": "getInterestGroupDetails",
"description": "Gets details for a named interest group.",
"experimental": true,
"parameters": [{ "name": "ownerOrigin", "type": "string" }, { "name": "name", "type": "string" }],
"parameters": [
{ "name": "ownerOrigin", "type": "string" },
{ "name": "name", "type": "string" }
],
"returns": [{ "name": "details", "$ref": "InterestGroupDetails" }]
},
{
@@ -12986,7 +13055,10 @@
"name": "deleteSharedStorageEntry",
"description": "Deletes entry for `key` (if it exists) for a given origin's shared storage.",
"experimental": true,
"parameters": [{ "name": "ownerOrigin", "type": "string" }, { "name": "key", "type": "string" }]
"parameters": [
{ "name": "ownerOrigin", "type": "string" },
{ "name": "key", "type": "string" }
]
},
{
"name": "clearSharedStorageEntries",
@@ -13010,7 +13082,10 @@
"name": "setStorageBucketTracking",
"description": "Set tracking for a storage key's buckets.",
"experimental": true,
"parameters": [{ "name": "storageKey", "type": "string" }, { "name": "enable", "type": "boolean" }]
"parameters": [
{ "name": "storageKey", "type": "string" },
{ "name": "enable", "type": "boolean" }
]
},
{
"name": "deleteStorageBucket",
@@ -13456,7 +13531,10 @@
"id": "RemoteLocation",
"experimental": true,
"type": "object",
"properties": [{ "name": "host", "type": "string" }, { "name": "port", "type": "integer" }]
"properties": [
{ "name": "host", "type": "string" },
{ "name": "port", "type": "integer" }
]
}
],
"commands": [

View File

@@ -79,7 +79,10 @@
"env": {
"NAME": "Bun"
},
"args": ["--jsx-import-source", "src/middleware/jsx/jsx-dev-runtime"],
"args": [
"--jsx-import-source",
"src/middleware/jsx/jsx-dev-runtime"
],
"path": "runtime_tests/bun/index.test.tsx"
}
},

View File

@@ -107,9 +107,9 @@ async function runTest(path) {
const expected_crash_reason = windows
? await readFile(resolve(path), "utf-8").then(data => {
const match = data.match(/@known-failing-on-windows:(.*)\n/);
return match ? match[1].trim() : null;
})
const match = data.match(/@known-failing-on-windows:(.*)\n/);
return match ? match[1].trim() : null;
})
: null;
const start = Date.now();
@@ -195,7 +195,8 @@ async function runTest(path) {
}
console.log(
`\x1b[2m${formatTime(duration).padStart(6, " ")}\x1b[0m ${passed ? "\x1b[32m✔" : expected_crash_reason ? "\x1b[33m⚠" : "\x1b[31m✖"
`\x1b[2m${formatTime(duration).padStart(6, " ")}\x1b[0m ${
passed ? "\x1b[32m✔" : expected_crash_reason ? "\x1b[33m⚠" : "\x1b[31m✖"
} ${name}\x1b[0m${reason ? ` (${reason})` : ""}`,
);
@@ -319,9 +320,10 @@ console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n"
console.log(header);
console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n");
let report = `# bun test on ${process.env["GITHUB_REF"] ??
let report = `# bun test on ${
process.env["GITHUB_REF"] ??
spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf-8" }).stdout.trim()
}
}
\`\`\`
${header}
@@ -345,7 +347,8 @@ if (regressions.length > 0) {
report += regressions
.map(
({ path, reason, expected_crash_reason }) =>
`- [\`${path}\`](${sectionLink(path)}) ${reason}${expected_crash_reason ? ` (expected: ${expected_crash_reason})` : ""
`- [\`${path}\`](${sectionLink(path)}) ${reason}${
expected_crash_reason ? ` (expected: ${expected_crash_reason})` : ""
}`,
)
.join("\n");
@@ -378,9 +381,8 @@ if (failing_tests.length) {
report += `${reason}\n\n`;
}
report += "```\n";
report += output
.replace(/\x1b\[[0-9;]*m/g, "")
.replace(/^::(group|endgroup|error|warning|set-output|add-matcher|remove-matcher).*$/gm, "");
report += output.replace(/\x1b\[[0-9;]*m/g, "")
.replace(/^::(group|endgroup|error|warning|set-output|add-matcher|remove-matcher).*$/gm, "")
report += "```\n\n";
}
}
@@ -400,14 +402,21 @@ console.log("-> test-report.md, test-report.json");
if (ci) {
if (windows) {
action.setOutput("regressing_tests", regressions.map(({ path }) => `- \`${path}\``).join("\n"));
if (regressions.length > 0) {
action.setFailed(`${regressions.length} regressing tests`);
}
action.setOutput(
"regressing_tests",
regressions.map(({ path }) => `- \`${path}\``).join("\n"),
);
action.setOutput("regressing_test_count", regressions.length);
} else {
if (failing_tests.length > 0) {
action.setFailed(`${failing_tests.length} files with failing tests`);
}
action.setOutput("failing_tests", failingTestDisplay);
action.setOutput("failing_tests_count", failing_tests.length);
}
if (failing_tests.length > 0) {
action.setFailed(`${failing_tests.length} files with failing tests`);
}
action.setOutput("failing_tests", failingTestDisplay);
action.setOutput("failing_tests_count", failing_tests.length);
let truncated_report = report;
if (truncated_report.length > 512 * 1000) {
truncated_report = truncated_report.slice(0, 512 * 1000) + "\n\n...truncated...";

View File

@@ -279,7 +279,7 @@ async function sendResponse(response: unknown): Promise<void> {
}
await fetch(`runtime/invocation/${requestId}/response`, {
method: "POST",
body: response === null ? null : typeof response === "string" ? response : JSON.stringify(response),
body: response === null ? null : (typeof response === 'string' ? response : JSON.stringify(response)),
});
}
@@ -594,8 +594,8 @@ class LambdaServer implements Server {
typeof options.port === "number"
? options.port
: typeof options.port === "string"
? parseInt(options.port)
: this.port;
? parseInt(options.port)
: this.port;
this.hostname = options.hostname ?? this.hostname;
this.development = options.development ?? this.development;
}

View File

@@ -87,13 +87,12 @@ export class BuildCommand extends Command {
this.log("Saving...", output);
const archiveBuffer = await archive
.generateAsync({
type: "blob",
type: 'blob',
compression: "DEFLATE",
compressionOptions: {
level: 9,
},
})
.then(blob => blob.arrayBuffer());
}).then(blob => blob.arrayBuffer());
writeFileSync(output, archiveBuffer);
this.log("Saved");
}

View File

@@ -32,60 +32,54 @@ export class PublishCommand extends BuildCommand {
}
const { layer, region, arch, output, public: isPublic } = flags;
if (region.includes("*")) {
// biome-ignore: format ignore
const result = this.#aws(["ec2", "describe-regions", "--query", "Regions[].RegionName", "--output", "json"]);
// prettier-ignore
const result = this.#aws([
"ec2",
"describe-regions",
"--query", "Regions[].RegionName",
"--output", "json"
]);
region.length = 0;
for (const name of JSON.parse(result)) {
region.push(name);
}
} else if (!region.length) {
// biome-ignore: format ignore
region.push(this.#aws(["configure", "get", "region"]));
// prettier-ignore
region.push(this.#aws([
"configure",
"get",
"region"
]));
}
this.log("Publishing...");
for (const regionName of region) {
for (const layerName of layer) {
// biome-ignore: format ignore
// prettier-ignore
const result = this.#aws([
"lambda",
"publish-layer-version",
"--layer-name",
layerName,
"--region",
regionName,
"--description",
"Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager.",
"--license-info",
"MIT",
"--compatible-architectures",
arch === "x64" ? "x86_64" : "arm64",
"--compatible-runtimes",
"provided.al2",
"provided",
"--zip-file",
`fileb://${output}`,
"--output",
"json",
"--layer-name", layerName,
"--region", regionName,
"--description", "Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager.",
"--license-info", "MIT",
"--compatible-architectures", arch === "x64" ? "x86_64" : "arm64",
"--compatible-runtimes", "provided.al2", "provided",
"--zip-file", `fileb://${output}`,
"--output", "json",
]);
const { LayerVersionArn } = JSON.parse(result);
this.log("Published", LayerVersionArn);
if (isPublic) {
// biome-ignore: format ignore
// prettier-ignore
this.#aws([
"lambda",
"add-layer-version-permission",
"--layer-name",
layerName,
"--region",
regionName,
"--version-number",
LayerVersionArn.split(":").pop(),
"--statement-id",
`${layerName}-public`,
"--action",
"lambda:GetLayerVersion",
"--principal",
"*",
"--layer-name", layerName,
"--region", regionName,
"--version-number", LayerVersionArn.split(":").pop(),
"--statement-id", `${layerName}-public`,
"--action", "lambda:GetLayerVersion",
"--principal", "*",
]);
}
}

View File

@@ -32,7 +32,9 @@ for (const asset of release.assets) {
const url = asset.browser_download_url;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to download asset: ${response.status} ${url}`);
throw new Error(
`Failed to download asset: ${response.status} ${url}`
);
}
const name = asset.name;
let contentType: string;
@@ -84,7 +86,9 @@ async function uploadToS3({
headers,
});
if (!response.ok) {
throw new Error(`Failed to upload to S3: ${response.status} ${response.statusText}`);
throw new Error(
`Failed to upload to S3: ${response.status} ${response.statusText}`
);
}
}

View File

@@ -0,0 +1,6 @@
{
"arrowParens": "avoid",
"printWidth": 80,
"trailingComma": "all",
"useTabs": false
}

View File

@@ -45,13 +45,14 @@ declare module "bun" {
* @param {string} options.PATH Overrides the PATH environment variable
* @param {string} options.cwd Limits the search to a particular directory in which to searc
*/
function which(command: string, options?: { PATH?: string; cwd?: string }): string | null;
function which(
command: string,
options?: { PATH?: string; cwd?: string },
): string | null;
export type ShellFunction = (input: Uint8Array) => Uint8Array;
export type ShellExpression =
| { toString(): string }
| Array<ShellExpression>
| string
| { raw: string }
| Subprocess
@@ -59,75 +60,6 @@ declare module "bun" {
| SpawnOptions.Writable
| ReadableStream;
class ShellError extends Error implements ShellOutput {
readonly stdout: Buffer;
readonly stderr: Buffer;
readonly exitCode: number;
/**
* Read from stdout as a string
*
* @param encoding - The encoding to use when decoding the output
* @returns Stdout as a string with the given encoding
* @example
*
* ## Read as UTF-8 string
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.text()); // "hello\n"
* ```
*
* ## Read as base64 string
*
* ```ts
* const output = await $`echo ${atob("hello")}`;
* console.log(output.text("base64")); // "hello\n"
* ```
*
*/
text(encoding?: BufferEncoding): string;
/**
* Read from stdout as a JSON object
*
* @returns Stdout as a JSON object
* @example
*
* ```ts
* const output = await $`echo '{"hello": 123}'`;
* console.log(output.json()); // { hello: 123 }
* ```
*
*/
json(): any;
/**
* Read from stdout as an ArrayBuffer
*
* @returns Stdout as an ArrayBuffer
* @example
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
* ```
*/
arrayBuffer(): ArrayBuffer;
/**
* Read from stdout as a Blob
*
* @returns Stdout as a blob
* @example
* ```ts
* const output = await $`echo hello`;
* console.log(output.blob()); // Blob { size: 6, type: "" }
* ```
*/
blob(): Blob;
}
class ShellPromise extends Promise<ShellOutput> {
get stdin(): WritableStream;
/**
@@ -227,16 +159,6 @@ declare module "bun" {
* ```
*/
blob(): Promise<Blob>;
/**
* Configure the shell to not throw an exception on non-zero exit codes.
*/
nothrow(): this;
/**
* Configure whether or not the shell should throw an exception on non-zero exit codes.
*/
throws(shouldThrow: boolean): this;
}
interface ShellConstructor {
@@ -244,7 +166,10 @@ declare module "bun" {
}
export interface Shell {
(strings: TemplateStringsArray, ...expressions: ShellExpression[]): ShellPromise;
(
strings: TemplateStringsArray,
...expressions: ShellExpression[]
): ShellPromise;
/**
* Perform bash-like brace expansion on the given pattern.
@@ -288,16 +213,6 @@ declare module "bun" {
*/
cwd(newCwd?: string): this;
/**
* Configure the shell to not throw an exception on non-zero exit codes.
*/
nothrow(): this;
/**
* Configure whether or not the shell should throw an exception on non-zero exit codes.
*/
throws(shouldThrow: boolean): this;
readonly ShellPromise: typeof ShellPromise;
readonly Shell: ShellConstructor;
}
@@ -306,69 +221,6 @@ declare module "bun" {
readonly stdout: Buffer;
readonly stderr: Buffer;
readonly exitCode: number;
/**
* Read from stdout as a string
*
* @param encoding - The encoding to use when decoding the output
* @returns Stdout as a string with the given encoding
* @example
*
* ## Read as UTF-8 string
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.text()); // "hello\n"
* ```
*
* ## Read as base64 string
*
* ```ts
* const output = await $`echo ${atob("hello")}`;
* console.log(output.text("base64")); // "hello\n"
* ```
*
*/
text(encoding?: BufferEncoding): string;
/**
* Read from stdout as a JSON object
*
* @returns Stdout as a JSON object
* @example
*
* ```ts
* const output = await $`echo '{"hello": 123}'`;
* console.log(output.json()); // { hello: 123 }
* ```
*
*/
json(): any;
/**
* Read from stdout as an ArrayBuffer
*
* @returns Stdout as an ArrayBuffer
* @example
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
* ```
*/
arrayBuffer(): ArrayBuffer;
/**
* Read from stdout as a Blob
*
* @returns Stdout as a blob
* @example
* ```ts
* const output = await $`echo hello`;
* console.log(output.blob()); // Blob { size: 6, type: "" }
* ```
*/
blob(): Blob;
}
export const $: Shell;
@@ -636,7 +488,9 @@ declare module "bun" {
* This function is faster because it uses uninitialized memory when copying. Since the entire
* length of the buffer is known, it is safe to use uninitialized memory.
*/
function concatArrayBuffers(buffers: Array<ArrayBufferView | ArrayBufferLike>): ArrayBuffer;
function concatArrayBuffers(
buffers: Array<ArrayBufferView | ArrayBufferLike>,
): ArrayBuffer;
/**
* Consume all data from a {@link ReadableStream} until it closes or errors.
@@ -692,7 +546,10 @@ declare module "bun" {
*/
function readableStreamToFormData(
stream: ReadableStream<string | NodeJS.TypedArray | ArrayBufferView>,
multipartBoundaryExcludingDashes?: string | NodeJS.TypedArray | ArrayBufferView,
multipartBoundaryExcludingDashes?:
| string
| NodeJS.TypedArray
| ArrayBufferView,
): Promise<FormData>;
/**
@@ -721,7 +578,9 @@ declare module "bun" {
* @param stream The stream to consume
* @returns A promise that resolves with the chunks as an array
*/
function readableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]> | T[];
function readableStreamToArray<T>(
stream: ReadableStream<T>,
): Promise<T[]> | T[];
/**
* Escape the following characters in a string:
@@ -759,7 +618,9 @@ declare module "bun" {
interface Peek {
<T = undefined>(promise: T | Promise<T>): Promise<T> | T;
status<T = undefined>(promise: T | Promise<T>): "pending" | "fulfilled" | "rejected";
status<T = undefined>(
promise: T | Promise<T>,
): "pending" | "fulfilled" | "rejected";
}
/**
* Extract the value from the Promise in the same tick of the event loop
@@ -799,7 +660,9 @@ declare module "bun" {
stream?: boolean;
}): void;
write(chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer): number;
write(
chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
): number;
/**
* Flush the internal buffer
*
@@ -941,7 +804,9 @@ declare module "bun" {
*
* If the file descriptor is not writable yet, the data is buffered.
*/
write(chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer): number;
write(
chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
): number;
/**
* Flush the internal buffer, committing the data to disk or the pipe.
*/
@@ -1113,14 +978,35 @@ declare module "bun" {
Hash;
interface Hash {
wyhash: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: bigint) => bigint;
adler32: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer) => number;
crc32: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer) => number;
cityHash32: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer) => number;
cityHash64: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: bigint) => bigint;
murmur32v3: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: number) => number;
murmur32v2: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: number) => number;
murmur64v2: (data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: bigint) => bigint;
wyhash: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
seed?: bigint,
) => bigint;
adler32: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
) => number;
crc32: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
) => number;
cityHash32: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
) => number;
cityHash64: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
seed?: bigint,
) => bigint;
murmur32v3: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
seed?: number,
) => number;
murmur32v2: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
seed?: number,
) => number;
murmur64v2: (
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
seed?: bigint,
) => bigint;
}
type JavaScriptLoader = "jsx" | "js" | "ts" | "tsx";
@@ -1301,13 +1187,20 @@ declare module "bun" {
* This function does not resolve imports.
* @param code The code to transpile
*/
transform(code: Bun.StringOrBuffer, loader?: JavaScriptLoader): Promise<string>;
transform(
code: Bun.StringOrBuffer,
loader?: JavaScriptLoader,
): Promise<string>;
/**
* Transpile code from TypeScript or JSX into valid JavaScript.
* This function does not resolve imports.
* @param code The code to transpile
*/
transformSync(code: Bun.StringOrBuffer, loader: JavaScriptLoader, ctx: object): string;
transformSync(
code: Bun.StringOrBuffer,
loader: JavaScriptLoader,
ctx: object,
): string;
/**
* Transpile code from TypeScript or JSX into valid JavaScript.
* This function does not resolve imports.
@@ -1544,7 +1437,10 @@ declare module "bun" {
*
* When using bcrypt, passwords exceeding 72 characters will be SHA512'd before
*/
algorithm?: Password.AlgorithmLabel | Password.Argon2Algorithm | Password.BCryptAlgorithm,
algorithm?:
| Password.AlgorithmLabel
| Password.Argon2Algorithm
| Password.BCryptAlgorithm,
): Promise<string>;
/**
@@ -1629,7 +1525,10 @@ declare module "bun" {
*
* When using bcrypt, passwords exceeding 72 characters will be SHA256'd before
*/
algorithm?: Password.AlgorithmLabel | Password.Argon2Algorithm | Password.BCryptAlgorithm,
algorithm?:
| Password.AlgorithmLabel
| Password.Argon2Algorithm
| Password.BCryptAlgorithm,
): string;
};
@@ -1724,7 +1623,10 @@ declare module "bun" {
* ws.send("Compress this.", true);
* ws.send(new Uint8Array([1, 2, 3, 4]));
*/
send(data: string | Bun.BufferSource, compress?: boolean): ServerWebSocketSendStatus;
send(
data: string | Bun.BufferSource,
compress?: boolean,
): ServerWebSocketSendStatus;
/**
* Sends a text message to the client.
@@ -1746,7 +1648,10 @@ declare module "bun" {
* ws.send(new TextEncoder().encode("Hello!"));
* ws.send(new Uint8Array([1, 2, 3, 4]), true);
*/
sendBinary(data: Bun.BufferSource, compress?: boolean): ServerWebSocketSendStatus;
sendBinary(
data: Bun.BufferSource,
compress?: boolean,
): ServerWebSocketSendStatus;
/**
* Closes the connection.
@@ -1798,7 +1703,11 @@ declare module "bun" {
* ws.publish("chat", "Compress this.", true);
* ws.publish("chat", new Uint8Array([1, 2, 3, 4]));
*/
publish(topic: string, data: string | Bun.BufferSource, compress?: boolean): ServerWebSocketSendStatus;
publish(
topic: string,
data: string | Bun.BufferSource,
compress?: boolean,
): ServerWebSocketSendStatus;
/**
* Sends a text message to subscribers of the topic.
@@ -1810,7 +1719,11 @@ declare module "bun" {
* ws.publish("chat", "Hello!");
* ws.publish("chat", "Compress this.", true);
*/
publishText(topic: string, data: string, compress?: boolean): ServerWebSocketSendStatus;
publishText(
topic: string,
data: string,
compress?: boolean,
): ServerWebSocketSendStatus;
/**
* Sends a binary message to subscribers of the topic.
@@ -1822,7 +1735,11 @@ declare module "bun" {
* ws.publish("chat", new TextEncoder().encode("Hello!"));
* ws.publish("chat", new Uint8Array([1, 2, 3, 4]), true);
*/
publishBinary(topic: string, data: Bun.BufferSource, compress?: boolean): ServerWebSocketSendStatus;
publishBinary(
topic: string,
data: Bun.BufferSource,
compress?: boolean,
): ServerWebSocketSendStatus;
/**
* Subscribes a client to the topic.
@@ -1985,7 +1902,6 @@ declare module "bun" {
* return new Response("Hello World");
* },
* });
* ```
*/
interface WebSocketHandler<T = undefined> {
/**
@@ -1999,7 +1915,10 @@ declare module "bun" {
* @param ws The websocket that sent the message
* @param message The message received
*/
message(ws: ServerWebSocket<T>, message: string | Buffer): void | Promise<void>;
message(
ws: ServerWebSocket<T>,
message: string | Buffer,
): void | Promise<void>;
/**
* Called when a connection is opened.
@@ -2023,7 +1942,11 @@ declare module "bun" {
* @param code The close code
* @param message The close message
*/
close?(ws: ServerWebSocket<T>, code: number, reason: string): void | Promise<void>;
close?(
ws: ServerWebSocket<T>,
code: number,
reason: string,
): void | Promise<void>;
/**
* Called when a ping is sent.
@@ -2138,7 +2061,10 @@ declare module "bun" {
*/
development?: boolean;
error?: (this: Server, request: ErrorLike) => Response | Promise<Response> | undefined | Promise<undefined>;
error?: (
this: Server,
request: ErrorLike,
) => Response | Promise<Response> | undefined | Promise<undefined>;
/**
* Uniquely identify a server instance with an ID
@@ -2203,7 +2129,11 @@ declare module "bun" {
*
* Respond to {@link Request} objects with a {@link Response} object.
*/
fetch(this: Server, request: Request, server: Server): Response | Promise<Response>;
fetch(
this: Server,
request: Request,
server: Server,
): Response | Promise<Response>;
}
interface UnixServeOptions extends GenericServeOptions {
@@ -2217,10 +2147,15 @@ declare module "bun" {
*
* Respond to {@link Request} objects with a {@link Response} object.
*/
fetch(this: Server, request: Request, server: Server): Response | Promise<Response>;
fetch(
this: Server,
request: Request,
server: Server,
): Response | Promise<Response>;
}
interface WebSocketServeOptions<WebSocketDataType = undefined> extends GenericServeOptions {
interface WebSocketServeOptions<WebSocketDataType = undefined>
extends GenericServeOptions {
/**
* What port should the server listen on?
* @default process.env.PORT || "3000"
@@ -2297,7 +2232,8 @@ declare module "bun" {
): Response | undefined | void | Promise<Response | undefined | void>;
}
interface UnixWebSocketServeOptions<WebSocketDataType = undefined> extends GenericServeOptions {
interface UnixWebSocketServeOptions<WebSocketDataType = undefined>
extends GenericServeOptions {
/**
* If set, the HTTP server will listen on a unix socket instead of a port.
* (Cannot be used with hostname+port)
@@ -2347,7 +2283,11 @@ declare module "bun" {
*
* Respond to {@link Request} objects with a {@link Response} object.
*/
fetch(this: Server, request: Request, server: Server): Response | undefined | Promise<Response | undefined>;
fetch(
this: Server,
request: Request,
server: Server,
): Response | undefined | Promise<Response | undefined>;
}
interface TLSWebSocketServeOptions<WebSocketDataType = undefined>
@@ -2400,7 +2340,12 @@ declare module "bun" {
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
* replaced when CAs are explicitly specified using this option.
*/
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
ca?:
| string
| Buffer
| BunFile
| Array<string | Buffer | BunFile>
| undefined;
/**
* Cert chains in PEM format. One cert chain should be provided per
* private key. Each cert chain should consist of the PEM formatted
@@ -2412,7 +2357,12 @@ declare module "bun" {
* intermediate certificates are not provided, the peer will not be
* able to validate the certificate, and the handshake will fail.
*/
cert?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
cert?:
| string
| Buffer
| BunFile
| Array<string | Buffer | BunFile>
| undefined;
/**
* Private keys in PEM format. PEM allows the option of private keys
* being encrypted. Encrypted keys will be decrypted with
@@ -2423,7 +2373,12 @@ declare module "bun" {
* object.passphrase is optional. Encrypted keys will be decrypted with
* object.passphrase if provided, or options.passphrase if it is not.
*/
key?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
key?:
| string
| Buffer
| BunFile
| Array<string | Buffer | BunFile>
| undefined;
/**
* Optionally affect the OpenSSL protocol behavior, which is not
* usually necessary. This should be used carefully if at all! Value is
@@ -2628,25 +2583,6 @@ declare module "bun" {
*/
requestIP(request: Request): SocketAddress | null;
/**
* Undo a call to {@link Server.unref}
*
* If the Server has already been stopped, this does nothing.
*
* If {@link Server.ref} is called multiple times, this does nothing. Think of it as a boolean toggle.
*/
ref(): void;
/**
* Don't keep the process alive if this server is the only thing left.
* Active connections may continue to keep the process alive.
*
* By default, the server is ref'd.
*
* To prevent new connections from being accepted, use {@link Server.stop}
*/
unref(): void;
/**
* How many requests are in-flight right now?
*/
@@ -2732,7 +2668,10 @@ declare module "bun" {
* @param path The path to the file as a byte buffer (the buffer is copied)
*/
// tslint:disable-next-line:unified-signatures
function file(path: ArrayBufferLike | Uint8Array, options?: BlobPropertyBag): BunFile;
function file(
path: ArrayBufferLike | Uint8Array,
options?: BlobPropertyBag,
): BunFile;
/**
* [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) powered by the fastest system calls available for operating on files.
@@ -2996,7 +2935,10 @@ declare module "bun" {
*
* @param hashInto `TypedArray` to write the hash into. Faster than creating a new one each time
*/
static hash(input: Bun.BlobOrStringOrBuffer, hashInto?: NodeJS.TypedArray): NodeJS.TypedArray;
static hash(
input: Bun.BlobOrStringOrBuffer,
hashInto?: NodeJS.TypedArray,
): NodeJS.TypedArray;
/**
* Run the hash over the given data
@@ -3005,7 +2947,10 @@ declare module "bun" {
*
* @param encoding `DigestEncoding` to return the hash in
*/
static hash(input: Bun.BlobOrStringOrBuffer, encoding: DigestEncoding): string;
static hash(
input: Bun.BlobOrStringOrBuffer,
encoding: DigestEncoding,
): string;
}
type SupportedCryptoAlgorithms =
@@ -3047,7 +2992,10 @@ declare module "bun" {
*
* @param input
*/
update(input: Bun.BlobOrStringOrBuffer, inputEncoding?: CryptoEncoding): CryptoHasher;
update(
input: Bun.BlobOrStringOrBuffer,
inputEncoding?: CryptoEncoding,
): CryptoHasher;
/**
* Perform a deep copy of the hasher
@@ -3162,7 +3110,10 @@ declare module "bun" {
* openssl sha512-256 /path/to/file
* ```
*/
function sha(input: Bun.StringOrBuffer, hashInto?: NodeJS.TypedArray): NodeJS.TypedArray;
function sha(
input: Bun.StringOrBuffer,
hashInto?: NodeJS.TypedArray,
): NodeJS.TypedArray;
/**
* Hash `input` using [SHA-2 512/256](https://en.wikipedia.org/wiki/SHA-2#Comparison_of_SHA_functions)
@@ -3332,26 +3283,32 @@ declare module "bun" {
* @param options Compression options to use
* @returns The output buffer with the compressed data
*/
function deflateSync(data: Uint8Array | string | ArrayBuffer, options?: ZlibCompressionOptions): Uint8Array;
function deflateSync(
data: Uint8Array,
options?: ZlibCompressionOptions,
): Uint8Array;
/**
* Compresses a chunk of data with `zlib` GZIP algorithm.
* @param data The buffer of data to compress
* @param options Compression options to use
* @returns The output buffer with the compressed data
*/
function gzipSync(data: Uint8Array | string | ArrayBuffer, options?: ZlibCompressionOptions): Uint8Array;
function gzipSync(
data: Uint8Array,
options?: ZlibCompressionOptions,
): Uint8Array;
/**
* Decompresses a chunk of data with `zlib` INFLATE algorithm.
* @param data The buffer of data to decompress
* @returns The output buffer with the decompressed data
*/
function inflateSync(data: Uint8Array | string | ArrayBuffer): Uint8Array;
function inflateSync(data: Uint8Array): Uint8Array;
/**
* Decompresses a chunk of data with `zlib` GUNZIP algorithm.
* @param data The buffer of data to decompress
* @returns The output buffer with the decompressed data
*/
function gunzipSync(data: Uint8Array | string | ArrayBuffer): Uint8Array;
function gunzipSync(data: Uint8Array): Uint8Array;
type Target =
/**
@@ -3374,7 +3331,17 @@ declare module "bun" {
| "browser";
/** https://bun.sh/docs/bundler/loaders */
type Loader = "js" | "jsx" | "ts" | "tsx" | "json" | "toml" | "file" | "napi" | "wasm" | "text";
type Loader =
| "js"
| "jsx"
| "ts"
| "tsx"
| "json"
| "toml"
| "file"
| "napi"
| "wasm"
| "text";
interface PluginConstraints {
/**
@@ -3465,7 +3432,9 @@ declare module "bun" {
}
type OnLoadResult = OnLoadResultSourceCode | OnLoadResultObject | undefined;
type OnLoadCallback = (args: OnLoadArgs) => OnLoadResult | Promise<OnLoadResult>;
type OnLoadCallback = (
args: OnLoadArgs,
) => OnLoadResult | Promise<OnLoadResult>;
interface OnResolveArgs {
/**
@@ -3507,7 +3476,11 @@ declare module "bun" {
type OnResolveCallback = (
args: OnResolveArgs,
) => OnResolveResult | Promise<OnResolveResult | undefined | null> | undefined | null;
) =>
| OnResolveResult
| Promise<OnResolveResult | undefined | null>
| undefined
| null;
interface PluginBuilder {
/**
@@ -3541,7 +3514,10 @@ declare module "bun" {
* });
* ```
*/
onResolve(constraints: PluginConstraints, callback: OnResolveCallback): void;
onResolve(
constraints: PluginConstraints,
callback: OnResolveCallback,
): void;
/**
* The config object passed to `Bun.build` as is. Can be mutated.
*/
@@ -3573,7 +3549,10 @@ declare module "bun" {
* console.log(foo); // "bar"
* ```
*/
module(specifier: string, callback: () => OnLoadResult | Promise<OnLoadResult>): void;
module(
specifier: string,
callback: () => OnLoadResult | Promise<OnLoadResult>,
): void;
}
interface BunPlugin {
@@ -3685,7 +3664,11 @@ declare module "bun" {
* will be slow. In the future, Bun will buffer writes and flush them at the
* end of the tick, when the event loop is idle, or sooner if the buffer is full.
*/
write(data: string | Bun.BufferSource, byteOffset?: number, byteLength?: number): number;
write(
data: string | Bun.BufferSource,
byteOffset?: number,
byteLength?: number,
): number;
/**
* The data context for the socket.
@@ -3697,7 +3680,11 @@ declare module "bun" {
*
* Use it to send your last message and close the connection.
*/
end(data?: string | Bun.BufferSource, byteOffset?: number, byteLength?: number): number;
end(
data?: string | Bun.BufferSource,
byteOffset?: number,
byteLength?: number,
): number;
/**
* Close the socket immediately
@@ -3796,7 +3783,10 @@ declare module "bun" {
}
type BinaryType = keyof BinaryTypeList;
interface SocketHandler<Data = unknown, DataBinaryType extends BinaryType = "buffer"> {
interface SocketHandler<
Data = unknown,
DataBinaryType extends BinaryType = "buffer",
> {
/**
* Is called when the socket connects, or in case of TLS if no handshake is provided
* this will be called only after handshake
@@ -3805,7 +3795,10 @@ declare module "bun" {
open?(socket: Socket<Data>): void | Promise<void>;
close?(socket: Socket<Data>): void | Promise<void>;
error?(socket: Socket<Data>, error: Error): void | Promise<void>;
data?(socket: Socket<Data>, data: BinaryTypeList[DataBinaryType]): void | Promise<void>;
data?(
socket: Socket<Data>,
data: BinaryTypeList[DataBinaryType],
): void | Promise<void>;
drain?(socket: Socket<Data>): void | Promise<void>;
/**
@@ -3814,7 +3807,11 @@ declare module "bun" {
* @param success Indicates if the server authorized despite the authorizationError.
* @param authorizationError Certificate Authorization Error or null.
*/
handshake?(socket: Socket<Data>, success: boolean, authorizationError: Error | null): void;
handshake?(
socket: Socket<Data>,
success: boolean,
authorizationError: Error | null,
): void;
/**
* When the socket has been shutdown from the other end, this function is
@@ -3867,13 +3864,15 @@ declare module "bun" {
// port: number;
// }
interface TCPSocketListenOptions<Data = undefined> extends SocketOptions<Data> {
interface TCPSocketListenOptions<Data = undefined>
extends SocketOptions<Data> {
hostname: string;
port: number;
tls?: TLSOptions;
}
interface TCPSocketConnectOptions<Data = undefined> extends SocketOptions<Data> {
interface TCPSocketConnectOptions<Data = undefined>
extends SocketOptions<Data> {
hostname: string;
port: number;
tls?: boolean;
@@ -3894,8 +3893,12 @@ declare module "bun" {
* @param options.tls The TLS configuration object
* @param options.unix The unix socket to connect to
*/
function connect<Data = undefined>(options: TCPSocketConnectOptions<Data>): Promise<Socket<Data>>;
function connect<Data = undefined>(options: UnixSocketOptions<Data>): Promise<Socket<Data>>;
function connect<Data = undefined>(
options: TCPSocketConnectOptions<Data>,
): Promise<Socket<Data>>;
function connect<Data = undefined>(
options: UnixSocketOptions<Data>,
): Promise<Socket<Data>>;
/**
* Create a TCP server that listens on a port
@@ -3908,8 +3911,12 @@ declare module "bun" {
* @param options.tls The TLS configuration object
* @param options.unix The unix socket to connect to
*/
function listen<Data = undefined>(options: TCPSocketListenOptions<Data>): TCPSocketListener<Data>;
function listen<Data = undefined>(options: UnixSocketOptions<Data>): UnixSocketListener<Data>;
function listen<Data = undefined>(
options: TCPSocketListenOptions<Data>,
): TCPSocketListener<Data>;
function listen<Data = undefined>(
options: UnixSocketOptions<Data>,
): UnixSocketListener<Data>;
namespace SpawnOptions {
/**
@@ -4079,19 +4086,24 @@ declare module "bun" {
// windowsHide?: boolean;
}
type OptionsToSubprocess<Opts extends OptionsObject> = Opts extends OptionsObject<infer In, infer Out, infer Err>
? Subprocess<
// "Writable extends In" means "if In === Writable",
// aka if true that means the user didn't specify anything
Writable extends In ? "ignore" : In,
Readable extends Out ? "pipe" : Out,
Readable extends Err ? "inherit" : Err
>
: Subprocess<Writable, Readable, Readable>;
type OptionsToSubprocess<Opts extends OptionsObject> =
Opts extends OptionsObject<infer In, infer Out, infer Err>
? Subprocess<
// "Writable extends In" means "if In === Writable",
// aka if true that means the user didn't specify anything
Writable extends In ? "ignore" : In,
Readable extends Out ? "pipe" : Out,
Readable extends Err ? "inherit" : Err
>
: Subprocess<Writable, Readable, Readable>;
type OptionsToSyncSubprocess<Opts extends OptionsObject> = Opts extends OptionsObject<any, infer Out, infer Err>
? SyncSubprocess<Readable extends Out ? "pipe" : Out, Readable extends Err ? "pipe" : Err>
: SyncSubprocess<Readable, Readable>;
type OptionsToSyncSubprocess<Opts extends OptionsObject> =
Opts extends OptionsObject<any, infer Out, infer Err>
? SyncSubprocess<
Readable extends Out ? "pipe" : Out,
Readable extends Err ? "pipe" : Err
>
: SyncSubprocess<Readable, Readable>;
type ReadableIO = ReadableStream<Uint8Array> | number | undefined;
@@ -4101,7 +4113,9 @@ declare module "bun" {
? number
: undefined;
type ReadableToSyncIO<X extends Readable> = X extends "pipe" | undefined ? Buffer : undefined;
type ReadableToSyncIO<X extends Readable> = X extends "pipe" | undefined
? Buffer
: undefined;
type WritableIO = FileSink | number | undefined;
@@ -4586,7 +4600,10 @@ declare module "bun" {
*
* This is sort of like readline() except without the IO.
*/
function indexOfLine(buffer: ArrayBufferView | ArrayBufferLike, offset?: number): number;
function indexOfLine(
buffer: ArrayBufferView | ArrayBufferLike,
offset?: number,
): number;
/**
* Provides a higher level API for command-line argument parsing than interacting
@@ -4714,7 +4731,9 @@ declare module "bun" {
* }
* ```
*/
scan(optionsOrCwd?: string | GlobScanOptions): AsyncIterableIterator<string>;
scan(
optionsOrCwd?: string | GlobScanOptions,
): AsyncIterableIterator<string>;
/**
* Synchronously scan a root directory recursively for files that match this glob pattern. Returns an iterator.

Binary file not shown.

View File

@@ -55,7 +55,12 @@ declare namespace Bun {
interface CustomEvent<T = any> {
/** @deprecated */
initCustomEvent(type: string, bubbles?: boolean, cancelable?: boolean, detail?: T): void;
initCustomEvent(
type: string,
bubbles?: boolean,
cancelable?: boolean,
detail?: T,
): void;
}
interface DOMException {

View File

@@ -1,8 +1,13 @@
type _Response = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Response;
type _Response = typeof globalThis extends { onmessage: any }
? {}
: import("undici-types").Response;
export interface Response extends _Response {}
export declare class Response {
constructor(body?: Bun.BodyInit | null | undefined, init?: Bun.ResponseInit | undefined);
constructor(
body?: Bun.BodyInit | null | undefined,
init?: Bun.ResponseInit | undefined,
);
/**
* Create a new {@link Response} with a JSON body

View File

@@ -551,7 +551,11 @@ declare module "bun:ffi" {
close(): void;
}
type ToFFIType<T extends FFITypeOrString> = T extends FFIType ? T : T extends string ? FFITypeStringToType[T] : never;
type ToFFIType<T extends FFITypeOrString> = T extends FFIType
? T
: T extends string
? FFITypeStringToType[T]
: never;
type ConvertFns<Fns extends Symbols> = {
[K in keyof Fns]: (
@@ -561,7 +565,8 @@ declare module "bun:ffi" {
[unknown] extends [Fns[K]["args"]]
? []
: never
) => [unknown] extends [Fns[K]["returns"]] // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
) => // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
[unknown] extends [Fns[K]["returns"]]
? undefined
: FFITypeToReturnsType[ToFFIType<NonNullable<Fns[K]["returns"]>>];
};
@@ -592,7 +597,10 @@ declare module "bun:ffi" {
* bun uses [tinycc](https://github.com/TinyCC/tinycc), so a big thanks
* goes to Fabrice Bellard and TinyCC maintainers for making this possible.
*/
function dlopen<Fns extends Record<string, FFIFunction>>(name: string, symbols: Fns): Library<Fns>;
function dlopen<Fns extends Record<string, FFIFunction>>(
name: string,
symbols: Fns,
): Library<Fns>;
/**
* Turn a native library's function pointer into a JavaScript function
@@ -678,7 +686,9 @@ declare module "bun:ffi" {
* bun uses [tinycc](https://github.com/TinyCC/tinycc), so a big thanks
* goes to Fabrice Bellard and TinyCC maintainers for making this possible.
*/
function linkSymbols<Fns extends Record<string, FFIFunction>>(symbols: Fns): Library<Fns>;
function linkSymbols<Fns extends Record<string, FFIFunction>>(
symbols: Fns,
): Library<Fns>;
/**
* Read a pointer as a {@link Buffer}
@@ -694,7 +704,11 @@ declare module "bun:ffi" {
* reading beyond the bounds of the pointer will crash the program or cause
* undefined behavior. Use with care!
*/
function toBuffer(ptr: Pointer, byteOffset?: number, byteLength?: number): Buffer;
function toBuffer(
ptr: Pointer,
byteOffset?: number,
byteLength?: number,
): Buffer;
/**
* Read a pointer as an {@link ArrayBuffer}
@@ -710,7 +724,11 @@ declare module "bun:ffi" {
* reading beyond the bounds of the pointer will crash the program or cause
* undefined behavior. Use with care!
*/
function toArrayBuffer(ptr: Pointer, byteOffset?: number, byteLength?: number): ArrayBuffer;
function toArrayBuffer(
ptr: Pointer,
byteOffset?: number,
byteLength?: number,
): ArrayBuffer;
namespace read {
/**
@@ -897,7 +915,10 @@ declare module "bun:ffi" {
* }
* ```
*/
function ptr(view: NodeJS.TypedArray | ArrayBufferLike | DataView, byteOffset?: number): Pointer;
function ptr(
view: NodeJS.TypedArray | ArrayBufferLike | DataView,
byteOffset?: number,
): Pointer;
/**
* Get a string from a UTF-8 encoded C string

View File

@@ -33,7 +33,9 @@ type _Performance = typeof globalThis extends {
? {}
: import("perf_hooks").Performance;
type _Worker = typeof globalThis extends { onerror: any; Worker: infer T } ? T : Bun.Worker;
type _Worker = typeof globalThis extends { onerror: any; Worker: infer T }
? T
: Bun.Worker;
type _Event = typeof globalThis extends { onerror: any; Event: any }
? {}
@@ -138,7 +140,10 @@ type _Body = typeof globalThis extends { onerror: any }
};
import type { MessagePort } from "worker_threads";
import type { TextEncoder as NodeTextEncoder, TextDecoder as NodeTextDecoder } from "util";
import type {
TextEncoder as NodeTextEncoder,
TextDecoder as NodeTextDecoder,
} from "util";
import type { WebSocket as _WebSocket } from "ws";
declare module "*.txt" {
@@ -196,9 +201,15 @@ declare global {
type TimerHandler = (...args: any[]) => void;
type BufferSource = NodeJS.TypedArray | DataView | ArrayBufferLike;
type DOMHighResTimeStamp = number;
type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
type EventListenerOrEventListenerObject =
| EventListener
| EventListenerObject;
type BlobOrStringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike | Blob;
type BlobOrStringOrBuffer =
| string
| NodeJS.TypedArray
| ArrayBufferLike
| Blob;
type Platform =
| "aix"
@@ -212,23 +223,56 @@ declare global {
| "win32"
| "cygwin"
| "netbsd";
type Architecture = "arm" | "arm64" | "ia32" | "mips" | "mipsel" | "ppc" | "ppc64" | "s390" | "s390x" | "x64";
type Architecture =
| "arm"
| "arm64"
| "ia32"
| "mips"
| "mipsel"
| "ppc"
| "ppc64"
| "s390"
| "s390x"
| "x64";
type UncaughtExceptionListener = (error: Error, origin: UncaughtExceptionOrigin) => void;
type UncaughtExceptionListener = (
error: Error,
origin: UncaughtExceptionOrigin,
) => void;
/**
* Most of the time the unhandledRejection will be an Error, but this should not be relied upon
* as *anything* can be thrown/rejected, it is therefore unsafe to assume that the value is an Error.
*/
type UnhandledRejectionListener = (reason: unknown, promise: Promise<unknown>) => void;
type UnhandledRejectionListener = (
reason: unknown,
promise: Promise<unknown>,
) => void;
type MultipleResolveListener = (type: MultipleResolveType, promise: Promise<unknown>, value: unknown) => void;
type MultipleResolveListener = (
type: MultipleResolveType,
promise: Promise<unknown>,
value: unknown,
) => void;
type HeadersInit = Headers | Record<string, string> | Array<[string, string]> | IterableIterator<[string, string]>;
type HeadersInit =
| Headers
| Record<string, string>
| Array<[string, string]>
| IterableIterator<[string, string]>;
type ResponseType = "basic" | "cors" | "default" | "error" | "opaque" | "opaqueredirect";
type ResponseType =
| "basic"
| "cors"
| "default"
| "error"
| "opaque"
| "opaqueredirect";
interface TextEncoder extends NodeTextEncoder {
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextEncoder;
new (
encoding?: Bun.Encoding,
options?: { fatal?: boolean; ignoreBOM?: boolean },
): TextEncoder;
/**
* UTF-8 encodes the `src` string to the `dest` Uint8Array and returns an object
* containing the read Unicode code units and written UTF-8 bytes.
@@ -242,11 +286,17 @@ declare global {
* @param src The text to encode.
* @param dest The array to hold the encode result.
*/
encodeInto(src?: string, dest?: Bun.BufferSource): import("util").EncodeIntoResult;
encodeInto(
src?: string,
dest?: Bun.BufferSource,
): import("util").EncodeIntoResult;
}
interface TextDecoder extends NodeTextDecoder {
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextDecoder;
new (
encoding?: Bun.Encoding,
options?: { fatal?: boolean; ignoreBOM?: boolean },
): TextDecoder;
}
interface ErrorEventInit extends EventInit {
@@ -366,7 +416,10 @@ declare global {
}
interface EventSource extends EventTarget {
new (url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource;
new (
url: string | URL,
eventSourceInitDict?: EventSourceInit,
): EventSource;
onerror: ((this: EventSource, ev: Event) => any) | null;
onmessage: ((this: EventSource, ev: MessageEvent) => any) | null;
@@ -432,7 +485,9 @@ declare global {
}
interface TransformerFlushCallback<O> {
(controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;
(
controller: TransformStreamDefaultController<O>,
): void | PromiseLike<void>;
}
interface TransformerStartCallback<O> {
@@ -440,7 +495,10 @@ declare global {
}
interface TransformerTransformCallback<I, O> {
(chunk: I, controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;
(
chunk: I,
controller: TransformStreamDefaultController<O>,
): void | PromiseLike<void>;
}
interface UnderlyingSinkAbortCallback {
@@ -456,7 +514,10 @@ declare global {
}
interface UnderlyingSinkWriteCallback<W> {
(chunk: W, controller: WritableStreamDefaultController): void | PromiseLike<void>;
(
chunk: W,
controller: WritableStreamDefaultController,
): void | PromiseLike<void>;
}
interface UnderlyingSourceCancelCallback {
@@ -484,7 +545,9 @@ declare global {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface DirectUnderlyingSource<R = any> {
cancel?: UnderlyingSourceCancelCallback;
pull: (controller: ReadableStreamDirectController) => void | PromiseLike<void>;
pull: (
controller: ReadableStreamDirectController,
) => void | PromiseLike<void>;
type: "direct";
}
@@ -584,7 +647,10 @@ declare global {
/**
* If set, specifies the initial value of process.env inside the Worker thread. As a special value, worker.SHARE_ENV may be used to specify that the parent thread and the child thread should share their environment variables; in that case, changes to one thread's process.env object affect the other thread as well. Default: process.env.
*/
env?: Record<string, string> | typeof import("node:worker_threads")["SHARE_ENV"] | undefined;
env?:
| Record<string, string>
| (typeof import("node:worker_threads"))["SHARE_ENV"]
| undefined;
/**
* In Bun, this does nothing.
@@ -670,7 +736,10 @@ declare global {
? T
: {
prototype: ReadableStream;
new <R = any>(underlyingSource?: Bun.UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
new <R = any>(
underlyingSource?: Bun.UnderlyingSource<R>,
strategy?: QueuingStrategy<R>,
): ReadableStream<R>;
new <R = any>(
underlyingSource?: Bun.DirectUnderlyingSource<R>,
strategy?: QueuingStrategy<R>,
@@ -685,7 +754,10 @@ declare global {
? T
: {
prototype: WritableStream;
new <W = any>(underlyingSink?: Bun.UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;
new <W = any>(
underlyingSink?: Bun.UnderlyingSink<W>,
strategy?: QueuingStrategy<W>,
): WritableStream<W>;
};
interface Worker extends _Worker {}
@@ -696,7 +768,10 @@ declare global {
? T
: {
prototype: Worker;
new (scriptURL: string | URL, options?: Bun.WorkerOptions | undefined): Worker;
new (
scriptURL: string | URL,
options?: Bun.WorkerOptions | undefined,
): Worker;
/**
* This is the cloned value of the `data` property passed to `new Worker()`
*
@@ -792,11 +867,17 @@ declare global {
* @param `name` - The name of the file
* @param `options` - An object containing properties to be added to the [File](https://developer.mozilla.org/en-US/docs/Web/API/File)
*/
new (parts: Bun.BlobPart[], name: string, options?: BlobPropertyBag & { lastModified?: Date | number }): File;
new (
parts: Bun.BlobPart[],
name: string,
options?: BlobPropertyBag & { lastModified?: Date | number },
): File;
readonly lastModified: number;
readonly name: string;
}
var File: typeof globalThis extends { onerror: any; File: infer T } ? T : typeof File;
var File: typeof globalThis extends { onerror: any; File: infer T }
? T
: typeof File;
interface FetchRequestInit extends RequestInit {
/**
@@ -926,7 +1007,10 @@ declare global {
*
* @returns A promise that resolves to {@link Response} object.
*/
function fetch(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>;
function fetch(
url: string | URL | Request,
init?: FetchRequestInit,
): Promise<Response>;
function queueMicrotask(callback: (...args: any[]) => void): void;
/**
@@ -968,13 +1052,21 @@ declare global {
* @param handler function to call
* @param interval milliseconds to wait between calls
*/
function setInterval(handler: Bun.TimerHandler, interval?: number, ...arguments: any[]): Timer;
function setInterval(
handler: Bun.TimerHandler,
interval?: number,
...arguments: any[]
): Timer;
/**
* Run a function after `timeout` (milliseconds)
* @param handler function to call
* @param timeout milliseconds to wait between calls
*/
function setTimeout(handler: Bun.TimerHandler, timeout?: number, ...arguments: any[]): Timer;
function setTimeout(
handler: Bun.TimerHandler,
timeout?: number,
...arguments: any[]
): Timer;
function addEventListener<K extends keyof EventMap>(
type: K,
@@ -1036,7 +1128,10 @@ declare global {
? T
: {
prototype: MessageEvent;
new <T>(type: string, eventInitDict?: Bun.MessageEventInit<T>): MessageEvent<T>;
new <T>(
type: string,
eventInitDict?: Bun.MessageEventInit<T>,
): MessageEvent<T>;
};
interface CustomEvent<T = any> extends Event {
@@ -1046,7 +1141,10 @@ declare global {
var CustomEvent: {
prototype: CustomEvent;
new <T>(type: string, eventInitDict?: Bun.CustomEventInit<T>): CustomEvent<T>;
new <T>(
type: string,
eventInitDict?: Bun.CustomEventInit<T>,
): CustomEvent<T>;
};
/**
@@ -1076,7 +1174,14 @@ declare global {
: typeof URL;
interface URLSearchParams {
new (init?: string | string[][] | Record<string, string> | URLSearchParams | undefined): URLSearchParams;
new (
init?:
| string
| string[][]
| Record<string, string>
| URLSearchParams
| undefined,
): URLSearchParams;
toString(): string;
}
var URLSearchParams: typeof globalThis extends {
@@ -1165,7 +1270,9 @@ declare global {
fetch: Promise<any>;
instantiate: Promise<any>;
satisfy: Promise<any>;
dependencies: Array<(typeof Loader)["registry"] extends Map<any, infer V> ? V : any>;
dependencies: Array<
(typeof Loader)["registry"] extends Map<any, infer V> ? V : any
>;
/**
* Your application will probably crash if you mess with this.
*/
@@ -1253,7 +1360,9 @@ declare global {
interface ReadableStreamDirectController {
close(error?: Error): void;
write(data: Bun.BufferSource | ArrayBuffer | string): number | Promise<number>;
write(
data: Bun.BufferSource | ArrayBuffer | string,
): number | Promise<number>;
end(): number | Promise<number>;
flush(): number | Promise<number>;
start(): void;
@@ -1264,13 +1373,16 @@ declare global {
new (): ReadableStreamDefaultController;
};
interface ReadableStreamDefaultReader<R = any> extends ReadableStreamGenericReader {
interface ReadableStreamDefaultReader<R = any>
extends ReadableStreamGenericReader {
read(): Promise<Bun.ReadableStreamDefaultReadResult<R>>;
/**
* Only available in Bun. If there are multiple chunks in the queue, this will return all of them at the same time.
* Will only return a promise if the data is not immediately available.
*/
readMany(): Promise<Bun.ReadableStreamDefaultReadManyResult<R>> | Bun.ReadableStreamDefaultReadManyResult<R>;
readMany():
| Promise<Bun.ReadableStreamDefaultReadManyResult<R>>
| Bun.ReadableStreamDefaultReadManyResult<R>;
releaseLock(): void;
}
@@ -1529,7 +1641,9 @@ declare global {
*
* @see https://v8.dev/docs/stack-trace-api#customizing-stack-traces
*/
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
prepareStackTrace?:
| ((err: Error, stackTraces: NodeJS.CallSite[]) => any)
| undefined;
stackTraceLimit: number;
}
@@ -1563,43 +1677,11 @@ declare global {
}
interface ArrayConstructor {
/**
* Create an array from an iterable or async iterable object.
* Values from the iterable are awaited.
*
* ```ts
* await Array.fromAsync([1]); // [1]
* await Array.fromAsync([Promise.resolve(1)]); // [1]
* await Array.fromAsync((async function*() { yield 1 })()); // [1]
* ```
*
* @param arrayLike - The iterable or async iterable to convert to an array.
* @returns A {@link Promise} whose fulfillment is a new {@link Array} instance containing the values from the iterator.
*/
fromAsync<T>(arrayLike: AsyncIterable<T> | Iterable<T> | ArrayLike<T>): Promise<Awaited<T>[]>;
/**
* Create an array from an iterable or async iterable object.
* Values from the iterable are awaited. Results of the map function are also awaited.
*
* ```ts
* await Array.fromAsync([1]); // [1]
* await Array.fromAsync([Promise.resolve(1)]); // [1]
* await Array.fromAsync((async function*() { yield 1 })()); // [1]
* await Array.fromAsync([1], (n) => n + 1); // [2]
* await Array.fromAsync([1], (n) => Promise.resolve(n + 1)); // [2]
* ```
*
* @param arrayLike - The iterable or async iterable to convert to an array.
* @param mapFn - A mapper function that transforms each element of `arrayLike` after awaiting them.
* @param thisArg - The `this` to which `mapFn` is bound.
* @returns A {@link Promise} whose fulfillment is a new {@link Array} instance containing the values from the iterator.
*/
fromAsync<T, U>(
arrayLike: AsyncIterable<T> | Iterable<T> | ArrayLike<T>,
mapFn?: (value: T, index: number) => U,
fromAsync<T>(
asyncItems: AsyncIterable<T> | Iterable<T> | ArrayLike<T>,
mapfn?: (value: any, index: number) => any,
thisArg?: any,
): Promise<Awaited<U>[]>;
): Promise<T[]>;
}
interface ConsoleOptions {
@@ -1843,7 +1925,10 @@ declare global {
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/structuredClone)
*/
function structuredClone<T>(value: T, options?: Bun.StructuredSerializeOptions): T;
function structuredClone<T>(
value: T,
options?: Bun.StructuredSerializeOptions,
): T;
/**
* Post a message to the parent thread.

View File

@@ -106,8 +106,13 @@ declare namespace HTMLRewriterTypes {
*/
declare class HTMLRewriter {
constructor();
on(selector: string, handlers: HTMLRewriterTypes.HTMLRewriterElementContentHandlers): HTMLRewriter;
onDocument(handlers: HTMLRewriterTypes.HTMLRewriterDocumentContentHandlers): HTMLRewriter;
on(
selector: string,
handlers: HTMLRewriterTypes.HTMLRewriterElementContentHandlers,
): HTMLRewriter;
onDocument(
handlers: HTMLRewriterTypes.HTMLRewriterDocumentContentHandlers,
): HTMLRewriter;
/**
* @param input - The HTML to transform
* @returns A new {@link Response} with the transformed HTML

View File

@@ -7,12 +7,10 @@
/// <reference types="ws" />
// contributors: uncomment this to detect conflicts with lib.dom.d.ts
//// <reference lib="dom" />
/// <reference lib="dom" />
/// <reference path="./globals.d.ts" />
/// <reference path="./bun.d.ts" />
/// <reference path="./overrides.d.ts" />
/// <reference path="./fetch.d.ts" />
/// <reference path="./ffi.d.ts" />
/// <reference path="./test.d.ts" />
/// <reference path="./html-rewriter.d.ts" />

View File

@@ -31,7 +31,9 @@ declare module "bun:jsc" {
function isRope(input: string): boolean;
function callerSourceOrigin(): string;
function noFTL(func: (...args: any[]) => any): (...args: any[]) => any;
function noOSRExitFuzzing(func: (...args: any[]) => any): (...args: any[]) => any;
function noOSRExitFuzzing(
func: (...args: any[]) => any,
): (...args: any[]) => any;
function optimizeNextInvocation(func: (...args: any[]) => any): void;
function numberOfDFGCompiles(func: (...args: any[]) => any): number;
function releaseWeakRefs(): void;
@@ -47,7 +49,10 @@ declare module "bun:jsc" {
* @param value A JavaScript value, usually an object or array, to be converted.
* @returns A SharedArrayBuffer that can be sent to another Bun instance.
*/
function serialize(value: any, options?: { binaryType?: "arraybuffer" }): SharedArrayBuffer;
function serialize(
value: any,
options?: { binaryType?: "arraybuffer" },
): SharedArrayBuffer;
/**
* Convert a JavaScript value to a binary representation that can be sent to another Bun instance.
@@ -57,14 +62,19 @@ declare module "bun:jsc" {
* @param value A JavaScript value, usually an object or array, to be converted.
* @returns A Buffer that can be sent to another Bun instance.
*/
function serialize(value: any, options?: { binaryType: "nodebuffer" }): Buffer;
function serialize(
value: any,
options?: { binaryType: "nodebuffer" },
): Buffer;
/**
* Convert an ArrayBuffer or Buffer to a JavaScript value compatible with the HTML Structured Clone Algorithm.
*
* @param value A serialized value, usually an ArrayBuffer or Buffer, to be converted.
*/
function deserialize(value: ArrayBufferLike | NodeJS.TypedArray | Buffer): any;
function deserialize(
value: ArrayBufferLike | NodeJS.TypedArray | Buffer,
): any;
/**
* Set the timezone used by Intl, Date, etc.

View File

@@ -16,13 +16,20 @@ declare module "fs/promises" {
}
declare module "tls" {
interface BunConnectionOptions extends Omit<ConnectionOptions, "key" | "ca" | "tls" | "cert"> {
interface BunConnectionOptions
extends Omit<ConnectionOptions, "key" | "ca" | "tls" | "cert"> {
/**
* Optionally override the trusted CA certificates. Default is to trust
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
* replaced when CAs are explicitly specified using this option.
*/
ca?: string | Buffer | NodeJS.TypedArray | BunFile | Array<string | Buffer | BunFile> | undefined;
ca?:
| string
| Buffer
| NodeJS.TypedArray
| BunFile
| Array<string | Buffer | BunFile>
| undefined;
/**
* Cert chains in PEM format. One cert chain should be provided per
* private key. Each cert chain should consist of the PEM formatted
@@ -60,5 +67,8 @@ declare module "tls" {
| undefined;
}
function connect(options: BunConnectionOptions, secureConnectListener?: () => void): TLSSocket;
function connect(
options: BunConnectionOptions,
secureConnectListener?: () => void,
): TLSSocket;
}

View File

@@ -18,16 +18,16 @@
"@types/ws": "~8.5.10"
},
"devDependencies": {
"@biomejs/biome": "^1.5.3",
"@definitelytyped/dtslint": "^0.0.199",
"@definitelytyped/eslint-plugin": "^0.0.197",
"prettier": "^2.4.1",
"typescript": "^5.0.2"
},
"scripts": {
"prebuild": "echo $(pwd)",
"build": "bun scripts/build.ts && bun run fmt",
"test": "tsc",
"fmt": "echo $(which biome) && biome format --write ."
"fmt": "echo $(which prettier) && prettier --write './**/*.{ts,tsx,js,jsx}'"
},
"keywords": [
"bun",

View File

@@ -2,6 +2,13 @@ import { join } from "node:path";
import pkg from "../package.json";
const BUN_VERSION = (process.env.BUN_VERSION || Bun.version || process.versions.bun).replace(/^.*v/, "");
const BUN_VERSION = (
process.env.BUN_VERSION ||
Bun.version ||
process.versions.bun
).replace(/^.*v/, "");
Bun.write(join(import.meta.dir, "..", "package.json"), JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2));
Bun.write(
join(import.meta.dir, "..", "package.json"),
JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2),
);

View File

@@ -165,11 +165,17 @@ declare module "bun:sqlite" {
* | `bigint` | `INTEGER` |
* | `null` | `NULL` |
*/
run<ParamsType extends SQLQueryBindings[]>(sqlQuery: string, ...bindings: ParamsType[]): void;
run<ParamsType extends SQLQueryBindings[]>(
sqlQuery: string,
...bindings: ParamsType[]
): void;
/**
This is an alias of {@link Database.prototype.run}
*/
exec<ParamsType extends SQLQueryBindings[]>(sqlQuery: string, ...bindings: ParamsType[]): void;
exec<ParamsType extends SQLQueryBindings[]>(
sqlQuery: string,
...bindings: ParamsType[]
): void;
/**
* Compile a SQL query and return a {@link Statement} object. This is the
@@ -220,7 +226,10 @@ declare module "bun:sqlite" {
*
* Under the hood, this calls `sqlite3_prepare_v3`.
*/
prepare<ReturnType, ParamsType extends SQLQueryBindings | SQLQueryBindings[]>(
prepare<
ReturnType,
ParamsType extends SQLQueryBindings | SQLQueryBindings[],
>(
sqlQuery: string,
params?: ParamsType,
): // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
@@ -426,7 +435,10 @@ declare module "bun:sqlite" {
* });
* ```
*/
static deserialize(serialized: NodeJS.TypedArray | ArrayBufferLike, isReadOnly?: boolean): Database;
static deserialize(
serialized: NodeJS.TypedArray | ArrayBufferLike,
isReadOnly?: boolean,
): Database;
}
/**
@@ -455,7 +467,10 @@ declare module "bun:sqlite" {
* // => undefined
* ```
*/
export class Statement<ReturnType = unknown, ParamsType extends SQLQueryBindings[] = any[]> {
export class Statement<
ReturnType = unknown,
ParamsType extends SQLQueryBindings[] = any[],
> {
/**
* Creates a new prepared statement from native code.
*
@@ -589,7 +604,9 @@ declare module "bun:sqlite" {
* | `bigint` | `INTEGER` |
* | `null` | `NULL` |
*/
values(...params: ParamsType): Array<Array<string | bigint | number | boolean | Uint8Array>>;
values(
...params: ParamsType
): Array<Array<string | bigint | number | boolean | Uint8Array>>;
/**
* The names of the columns returned by the prepared statement.
@@ -789,7 +806,10 @@ declare module "bun:sqlite" {
| number
| boolean
| null
| Record<string, string | bigint | NodeJS.TypedArray | number | boolean | null>;
| Record<
string,
string | bigint | NodeJS.TypedArray | number | boolean | null
>;
export default Database;

View File

@@ -20,7 +20,7 @@ declare module "bun:test" {
export type Mock<T extends (...args: any[]) => any> = JestMock.Mock<T>;
export const mock: {
<T extends (...args: any[]) => any>(Function?: T): Mock<T>;
<T extends (...args: any[]) => any>(Function: T): Mock<T>;
/**
* Replace the module `id` with the return value of `factory`.
@@ -92,14 +92,14 @@ declare module "bun:test" {
interface Jest {
restoreAllMocks(): void;
fn<T extends (...args: any[]) => any>(func?: T): Mock<T>;
setSystemTime(now?: number | Date): void;
}
export const jest: Jest;
export namespace jest {
/**
* Constructs the type of a mock function, e.g. the return type of `jest.fn()`.
*/
type Mock<T extends (...args: any[]) => any = (...args: any[]) => any> = JestMock.Mock<T>;
type Mock<T extends (...args: any[]) => any = (...args: any[]) => any> =
JestMock.Mock<T>;
/**
* Wraps a class, function or object type with Jest mock type definitions.
*/
@@ -123,7 +123,8 @@ declare module "bun:test" {
/**
* Constructs the type of a spied class or function.
*/
type Spied<T extends JestMock.ClassLike | ((...args: any[]) => any)> = JestMock.Spied<T>;
type Spied<T extends JestMock.ClassLike | ((...args: any[]) => any)> =
JestMock.Spied<T>;
/**
* Constructs the type of a spied class.
*/
@@ -131,7 +132,8 @@ declare module "bun:test" {
/**
* Constructs the type of a spied function.
*/
type SpiedFunction<T extends (...args: any[]) => any> = JestMock.SpiedFunction<T>;
type SpiedFunction<T extends (...args: any[]) => any> =
JestMock.SpiedFunction<T>;
/**
* Constructs the type of a spied getter.
*/
@@ -186,12 +188,6 @@ declare module "bun:test" {
* @param fn the function that defines the tests
*/
todo(label: string, fn?: () => void): void;
/**
* Marks this group of tests as broken and in need of fixing.
* @param label the label for the tests
* @param fn the function that defines the tests
*/
fixme(label: string, fn?: () => void): void;
/**
* Runs this group of tests, only if `condition` is true.
*
@@ -214,13 +210,25 @@ declare module "bun:test" {
each<T extends Readonly<[any, ...any[]]>>(
table: readonly T[],
): (label: string, fn: (...args: [...T]) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: [...T]) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
each<T extends any[]>(
table: readonly T[],
): (label: string, fn: (...args: Readonly<T>) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: Readonly<T>) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
each<T>(
table: T[],
): (label: string, fn: (...args: T[]) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: T[]) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
}
/**
* Describes a group of related tests.
@@ -255,7 +263,11 @@ declare module "bun:test" {
*
* @param fn the function to run
*/
export function beforeAll(fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void)): void;
export function beforeAll(
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
): void;
/**
* Runs a function before each test.
*
@@ -266,7 +278,11 @@ declare module "bun:test" {
*
* @param fn the function to run
*/
export function beforeEach(fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void)): void;
export function beforeEach(
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
): void;
/**
* Runs a function, once, after all the tests.
*
@@ -283,7 +299,11 @@ declare module "bun:test" {
*
* @param fn the function to run
*/
export function afterAll(fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void)): void;
export function afterAll(
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
): void;
/**
* Runs a function after each test.
*
@@ -292,7 +312,11 @@ declare module "bun:test" {
*
* @param fn the function to run
*/
export function afterEach(fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void)): void;
export function afterEach(
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
): void;
export interface TestOptions {
/**
* Sets the timeout for the test in milliseconds.
@@ -342,7 +366,9 @@ declare module "bun:test" {
export interface Test {
(
label: string,
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
/**
* - If a `number`, sets the timeout for the test in milliseconds.
* - If an `object`, sets the options for the test.
@@ -353,7 +379,7 @@ declare module "bun:test" {
options?: number | TestOptions,
): void;
/**
* Skips all other tests, except this test when run with the `--only` option.
* Skips all other tests, except this test.
*
* @param label the label for the test
* @param fn the test function
@@ -361,7 +387,9 @@ declare module "bun:test" {
*/
only(
label: string,
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
): void;
/**
@@ -373,7 +401,9 @@ declare module "bun:test" {
*/
skip(
label: string,
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
): void;
/**
@@ -390,22 +420,9 @@ declare module "bun:test" {
*/
todo(
label: string,
fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
): void;
/**
* Marks this test as broken and in need of fixing.
*
* If the test function fails, it will be marked as `fixme` in the test results
* instead of `fail`. This is useful for marking tests that are known to be broken.
*
* @param label the label for the test
* @param fn the test function
* @param options the test timeout or options
*/
fixme(
label: string,
fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn?:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
): void;
/**
@@ -419,7 +436,9 @@ declare module "bun:test" {
condition: boolean,
): (
label: string,
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
) => void;
/**
@@ -431,31 +450,9 @@ declare module "bun:test" {
condition: boolean,
): (
label: string,
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
) => void;
/**
* Marks this test as `todo`, if `condition` is true.
*
* @param condition if the test should be marked as `todo`
*/
todoIf(
condition: boolean,
): (
label: string,
fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
) => void;
/**
* Marks this test as `fixme`, if `condition` is true.
*
* @param condition if the test should be marked as `fixme`
*/
fixmeIf(
condition: boolean,
): (
label: string,
fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
fn:
| (() => void | Promise<unknown>)
| ((done: (err?: unknown) => void) => void),
options?: number | TestOptions,
) => void;
/**
@@ -465,13 +462,25 @@ declare module "bun:test" {
*/
each<T extends Readonly<[any, ...any[]]>>(
table: readonly T[],
): (label: string, fn: (...args: [...T]) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: [...T]) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
each<T extends any[]>(
table: readonly T[],
): (label: string, fn: (...args: Readonly<T>) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: Readonly<T>) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
each<T>(
table: T[],
): (label: string, fn: (...args: T[]) => void | Promise<unknown>, options?: number | TestOptions) => void;
): (
label: string,
fn: (...args: T[]) => void | Promise<unknown>,
options?: number | TestOptions,
) => void;
}
/**
* Runs a test.
@@ -505,7 +514,8 @@ declare module "bun:test" {
*/
export const expect: Expect;
type ExpectNot = Omit<AsymmetricMatchers, keyof AsymmetricMatchersBuiltin> & AsymmetricMatchersBuiltinNegated;
type ExpectNot = Omit<AsymmetricMatchers, keyof AsymmetricMatchersBuiltin> &
AsymmetricMatchersBuiltinNegated;
export interface Expect extends AsymmetricMatchers {
// the `expect()` callable signature
@@ -662,7 +672,9 @@ declare module "bun:test" {
* expect(mock).toBeCalledWith(expect.any(Number));
* });
*/
any(constructor: ((...args: any[]) => any) | { new (...args: any[]): any }): AsymmetricMatcher;
any(
constructor: ((...args: any[]) => any) | { new (...args: any[]): any },
): AsymmetricMatcher;
/**
* Matches anything but null or undefined. You can use it inside `toEqual` or `toBeCalledWith` instead
* of a literal value. For example, if you want to check that a mock function is called with a
@@ -1008,7 +1020,10 @@ declare module "bun:test" {
* @param keyPath the expected property name or path, or an index
* @param value the expected property value, if provided
*/
toHaveProperty(keyPath: string | number | Array<string | number>, value?: unknown): void;
toHaveProperty(
keyPath: string | number | Array<string | number>,
value?: unknown,
): void;
/**
* Asserts that a value is "truthy".
*
@@ -1263,7 +1278,17 @@ declare module "bun:test" {
* expect("hello").toBeTypeOf("string");
* expect([]).not.toBeTypeOf("boolean");
*/
toBeTypeOf(type: "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"): void;
toBeTypeOf(
type:
| "bigint"
| "boolean"
| "function"
| "number"
| "object"
| "string"
| "symbol"
| "undefined",
): void;
/**
* Asserts that a value is `false`.
*
@@ -1467,7 +1492,10 @@ declare module "bun:test" {
) => MatcherResult | Promise<MatcherResult>;
/** All non-builtin matchers and asymmetric matchers that have been type-registered through declaration merging */
export type CustomMatchersDetected = Omit<Matchers<unknown>, keyof MatchersBuiltin<unknown>> &
export type CustomMatchersDetected = Omit<
Matchers<unknown>,
keyof MatchersBuiltin<unknown>
> &
Omit<AsymmetricMatchers, keyof AsymmetricMatchersBuiltin>;
/**
@@ -1481,7 +1509,12 @@ declare module "bun:test" {
};
/** Custom equality tester */
export type Tester = (this: TesterContext, a: any, b: any, customTesters: Tester[]) => boolean | undefined;
export type Tester = (
this: TesterContext,
a: any,
b: any,
customTesters: Tester[],
) => boolean | undefined;
export type EqualsFunction = (
a: unknown,
@@ -1574,7 +1607,8 @@ declare namespace JestMock {
[K in keyof T as Required<T>[K] extends FunctionLike ? K : never]: T[K];
};
export interface Mock<T extends (...args: any[]) => any> extends MockInstance<T> {
export interface Mock<T extends (...args: any[]) => any>
extends MockInstance<T> {
(...args: Parameters<T>): ReturnType<T>;
}
@@ -1855,9 +1889,13 @@ declare namespace JestMock {
// ): MockedShallow<T>;
// }
export type PropertyLikeKeys<T> = Exclude<keyof T, ConstructorLikeKeys<T> | MethodLikeKeys<T>>;
export type PropertyLikeKeys<T> = Exclude<
keyof T,
ConstructorLikeKeys<T> | MethodLikeKeys<T>
>;
export type RejectType<T extends FunctionLike> = ReturnType<T> extends PromiseLike<any> ? unknown : never;
export type RejectType<T extends FunctionLike> =
ReturnType<T> extends PromiseLike<any> ? unknown : never;
export interface Replaced<T = unknown> {
/**
@@ -1878,13 +1916,16 @@ declare namespace JestMock {
[K in keyof T as Required<T>[K] extends ClassLike ? K : never]: T[K];
}
| keyof {
[K_1 in keyof T as Required<T>[K_1] extends FunctionLike ? K_1 : never]: T[K_1];
[K_1 in keyof T as Required<T>[K_1] extends FunctionLike
? K_1
: never]: T[K_1];
}
>,
V extends T[K_2],
>(object: T, propertyKey: K_2, value: V): Replaced<T[K_2]>;
export type ResolveType<T extends FunctionLike> = ReturnType<T> extends PromiseLike<infer U> ? U : never;
export type ResolveType<T extends FunctionLike> =
ReturnType<T> extends PromiseLike<infer U> ? U : never;
export type Spied<T extends ClassLike | FunctionLike> = T extends ClassLike
? SpiedClass<T>
@@ -1896,15 +1937,15 @@ declare namespace JestMock {
(...args: ConstructorParameters<T>) => InstanceType<T>
>;
export type SpiedFunction<T extends FunctionLike = UnknownFunction> = MockInstance<
(...args: Parameters<T>) => ReturnType<T>
>;
export type SpiedFunction<T extends FunctionLike = UnknownFunction> =
MockInstance<(...args: Parameters<T>) => ReturnType<T>>;
export type SpiedGetter<T> = MockInstance<() => T>;
export type SpiedSetter<T> = MockInstance<(arg: T) => void>;
export interface SpyInstance<T extends FunctionLike = UnknownFunction> extends MockInstance<T> {}
export interface SpyInstance<T extends FunctionLike = UnknownFunction>
extends MockInstance<T> {}
export const spyOn: {
<
@@ -1912,10 +1953,14 @@ declare namespace JestMock {
K_2 extends Exclude<
keyof T,
| keyof {
[K in keyof T as Required<T>[K] extends ClassLike ? K : never]: T[K];
[K in keyof T as Required<T>[K] extends ClassLike
? K
: never]: T[K];
}
| keyof {
[K_1 in keyof T as Required<T>[K_1] extends FunctionLike ? K_1 : never]: T[K_1];
[K_1 in keyof T as Required<T>[K_1] extends FunctionLike
? K_1
: never]: T[K_1];
}
>,
V extends Required<T>[K_2],
@@ -1924,15 +1969,23 @@ declare namespace JestMock {
object: T,
methodKey: K_2,
accessType: A,
): A extends "get" ? SpiedGetter<V> : A extends "set" ? SpiedSetter<V> : never;
): A extends "get"
? SpiedGetter<V>
: A extends "set"
? SpiedSetter<V>
: never;
<
T_1 extends object,
K_5 extends
| keyof {
[K_3 in keyof T_1 as Required<T_1>[K_3] extends ClassLike ? K_3 : never]: T_1[K_3];
[K_3 in keyof T_1 as Required<T_1>[K_3] extends ClassLike
? K_3
: never]: T_1[K_3];
}
| keyof {
[K_4 in keyof T_1 as Required<T_1>[K_4] extends FunctionLike ? K_4 : never]: T_1[K_4];
[K_4 in keyof T_1 as Required<T_1>[K_4] extends FunctionLike
? K_4
: never]: T_1[K_4];
},
V_1 extends Required<T_1>[K_5],
>(

View File

@@ -1,8 +1,8 @@
import { expectType } from "./utilities.test";
async function* listReleases() {
for (let page = 1; ; page++) {
const response = await fetch(`https://api.github.com/repos/oven-sh/bun/releases?page=${page}`);
const response = await fetch(
`https://api.github.com/repos/oven-sh/bun/releases?page=${page}`,
);
const releases = (await response.json()) as Array<{ data: string }>;
if (!releases.length) {
break;
@@ -15,18 +15,4 @@ async function* listReleases() {
await Array.fromAsync(listReleases());
// Tests from issue #8484
// https://github.com/oven-sh/bun/issues/8484
async function* naturals() {
for (let i = 0; i < 10; i++) {
yield i;
}
}
const test1 = await Array.fromAsync(naturals(), n => Promise.resolve(`${n}`));
expectType<string[]>(test1);
const test2 = await Array.fromAsync([Promise.resolve(1), Promise.resolve(2)]);
expectType<number[]>(test2);
export {};

View File

@@ -163,7 +163,10 @@ tsd.expectType<CString>(lib2.symbols.sqlite3_libversion());
// tslint:disable-next-line:no-void-expression
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
tsd.expectType<void>(lib2.symbols.multi_args(1, 2));
tsd.expectTypeEquals<ReturnType<(typeof lib2)["symbols"]["no_returns"]>, undefined>(true);
tsd.expectTypeEquals<
ReturnType<(typeof lib2)["symbols"]["no_returns"]>,
undefined
>(true);
tsd.expectTypeEquals<Parameters<(typeof lib2)["symbols"]["no_args"]>, []>(true);
tsd.expectType<number>(read.u8(0));

View File

@@ -32,7 +32,9 @@ expectType<Uint8Array>(
windowBits: 15,
}),
);
expectType<Uint8Array>(Bun.gzipSync(new Uint8Array(128), { level: 9, memLevel: 6, windowBits: 27 }));
expectType<Uint8Array>(
Bun.gzipSync(new Uint8Array(128), { level: 9, memLevel: 6, windowBits: 27 }),
);
expectType<Uint8Array>(Bun.inflateSync(new Uint8Array(64))); // Pretend this is DEFLATE compressed data
expectType<Uint8Array>(Bun.gunzipSync(new Uint8Array(64))); // Pretend this is GZIP compressed data
expectAssignable<ZlibCompressionOptions>({ windowBits: -11 });
@@ -44,7 +46,9 @@ expectType<URL>(Bun.pathToFileURL("/foo/bar.txt"));
expectType<string>(Bun.fileURLToPath(new URL("file:///foo/bar.txt")));
// Testing ../fs.d.ts
expectType<string>(fs.readFileSync("./index.d.ts", { encoding: "utf-8" }).toString());
expectType<string>(
fs.readFileSync("./index.d.ts", { encoding: "utf-8" }).toString(),
);
expectType<boolean>(fs.existsSync("./index.d.ts"));
// tslint:disable-next-line:no-void-expression
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
@@ -57,7 +61,9 @@ expectType<void>(fs.appendFileSync("./index.d.ts", "test"));
expectType<void>(fs.mkdirSync("./index.d.ts"));
// Testing ^promises.d.ts
expectType<string>((await fsPromises.readFile("./index.d.ts", { encoding: "utf-8" })).toString());
expectType<string>(
(await fsPromises.readFile("./index.d.ts", { encoding: "utf-8" })).toString(),
);
expectType<Promise<void>>(fsPromises.access("./index.d.ts"));
expectType<Promise<void>>(fsPromises.appendFile("./index.d.ts", "test"));
expectType<Promise<void>>(fsPromises.mkdir("./index.d.ts"));

View File

@@ -1,4 +1,11 @@
import { FileSink, NullSubprocess, PipedSubprocess, ReadableSubprocess, SyncSubprocess, WritableSubprocess } from "bun";
import {
FileSink,
NullSubprocess,
PipedSubprocess,
ReadableSubprocess,
SyncSubprocess,
WritableSubprocess,
} from "bun";
import * as tsd from "./utilities.test";
Bun.spawn(["echo", "hello"]);
@@ -25,7 +32,11 @@ function depromise<T>(_promise: Promise<T>): T {
{
const proc = Bun.spawn(["cat"], {
stdin: depromise(fetch("https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js")),
stdin: depromise(
fetch(
"https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js",
),
),
});
const text = depromise(new Response(proc.stdout).text());
@@ -130,16 +141,36 @@ function depromise<T>(_promise: Promise<T>): T {
});
tsd.expectType<number>(proc.stdin);
}
tsd.expectAssignable<PipedSubprocess>(Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }));
tsd.expectNotAssignable<PipedSubprocess>(Bun.spawn([], { stdio: ["inherit", "inherit", "inherit"] }));
tsd.expectAssignable<ReadableSubprocess>(Bun.spawn([], { stdio: ["ignore", "pipe", "pipe"] }));
tsd.expectAssignable<ReadableSubprocess>(Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }));
tsd.expectNotAssignable<ReadableSubprocess>(Bun.spawn([], { stdio: ["pipe", "ignore", "pipe"] }));
tsd.expectAssignable<WritableSubprocess>(Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }));
tsd.expectAssignable<WritableSubprocess>(Bun.spawn([], { stdio: ["pipe", "ignore", "inherit"] }));
tsd.expectNotAssignable<WritableSubprocess>(Bun.spawn([], { stdio: ["ignore", "pipe", "pipe"] }));
tsd.expectAssignable<NullSubprocess>(Bun.spawn([], { stdio: ["ignore", "inherit", "ignore"] }));
tsd.expectAssignable<NullSubprocess>(Bun.spawn([], { stdio: [null, null, null] }));
tsd.expectAssignable<PipedSubprocess>(
Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }),
);
tsd.expectNotAssignable<PipedSubprocess>(
Bun.spawn([], { stdio: ["inherit", "inherit", "inherit"] }),
);
tsd.expectAssignable<ReadableSubprocess>(
Bun.spawn([], { stdio: ["ignore", "pipe", "pipe"] }),
);
tsd.expectAssignable<ReadableSubprocess>(
Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }),
);
tsd.expectNotAssignable<ReadableSubprocess>(
Bun.spawn([], { stdio: ["pipe", "ignore", "pipe"] }),
);
tsd.expectAssignable<WritableSubprocess>(
Bun.spawn([], { stdio: ["pipe", "pipe", "pipe"] }),
);
tsd.expectAssignable<WritableSubprocess>(
Bun.spawn([], { stdio: ["pipe", "ignore", "inherit"] }),
);
tsd.expectNotAssignable<WritableSubprocess>(
Bun.spawn([], { stdio: ["ignore", "pipe", "pipe"] }),
);
tsd.expectAssignable<NullSubprocess>(
Bun.spawn([], { stdio: ["ignore", "inherit", "ignore"] }),
);
tsd.expectAssignable<NullSubprocess>(
Bun.spawn([], { stdio: [null, null, null] }),
);
tsd.expectNotAssignable<ReadableSubprocess>(Bun.spawn([], {}));
tsd.expectNotAssignable<PipedSubprocess>(Bun.spawn([], {}));

View File

@@ -1,4 +1,13 @@
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, spyOn, test } from "bun:test";
import {
afterAll,
afterEach,
beforeAll,
beforeEach,
describe,
expect,
spyOn,
test,
} from "bun:test";
import { expectType } from "./utilities.test";
const spy = spyOn(console, "log");

View File

@@ -5,4 +5,6 @@ export declare const expectAssignable: <T>(expression: T) => void;
// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
export declare const expectNotAssignable: <T>(expression: any) => void;
// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
export declare const expectTypeEquals: <T, S>(expression: T extends S ? (S extends T ? true : false) : false) => void;
export declare const expectTypeEquals: <T, S>(
expression: T extends S ? (S extends T ? true : false) : false,
) => void;

View File

@@ -1,11 +1,12 @@
export {};
type _Global<T extends Bun.WebAssembly.ValueType = Bun.WebAssembly.ValueType> = typeof globalThis extends {
onerror: any;
WebAssembly: { Global: infer T };
}
? T
: Bun.WebAssembly.Global<T>;
type _Global<T extends Bun.WebAssembly.ValueType = Bun.WebAssembly.ValueType> =
typeof globalThis extends {
onerror: any;
WebAssembly: { Global: infer T };
}
? T
: Bun.WebAssembly.Global<T>;
type _CompileError = typeof globalThis extends {
onerror: any;
@@ -62,7 +63,11 @@ declare global {
type ImportExportKind = "function" | "global" | "memory" | "table";
type TableKind = "anyfunc" | "externref";
// eslint-disable-next-line @typescript-eslint/ban-types
type ExportValue = Function | Global | WebAssembly.Memory | WebAssembly.Table;
type ExportValue =
| Function
| Global
| WebAssembly.Memory
| WebAssembly.Table;
type Exports = Record<string, ExportValue>;
type ImportValue = ExportValue | number;
type Imports = Record<string, ModuleImports>;
@@ -161,13 +166,17 @@ declare global {
namespace WebAssembly {
interface ValueTypeMap extends Bun.WebAssembly.ValueTypeMap {}
interface GlobalDescriptor<T extends keyof ValueTypeMap = keyof ValueTypeMap>
extends Bun.WebAssembly.GlobalDescriptor<T> {}
interface GlobalDescriptor<
T extends keyof ValueTypeMap = keyof ValueTypeMap,
> extends Bun.WebAssembly.GlobalDescriptor<T> {}
interface MemoryDescriptor extends Bun.WebAssembly.MemoryDescriptor {}
interface ModuleExportDescriptor extends Bun.WebAssembly.ModuleExportDescriptor {}
interface ModuleImportDescriptor extends Bun.WebAssembly.ModuleImportDescriptor {}
interface ModuleExportDescriptor
extends Bun.WebAssembly.ModuleExportDescriptor {}
interface ModuleImportDescriptor
extends Bun.WebAssembly.ModuleImportDescriptor {}
interface TableDescriptor extends Bun.WebAssembly.TableDescriptor {}
interface WebAssemblyInstantiatedSource extends Bun.WebAssembly.WebAssemblyInstantiatedSource {}
interface WebAssemblyInstantiatedSource
extends Bun.WebAssembly.WebAssemblyInstantiatedSource {}
interface LinkError extends _LinkError {}
var LinkError: {
@@ -195,7 +204,8 @@ declare global {
(message?: string): RuntimeError;
};
interface Global<T extends keyof ValueTypeMap = keyof ValueTypeMap> extends _Global<T> {}
interface Global<T extends keyof ValueTypeMap = keyof ValueTypeMap>
extends _Global<T> {}
var Global: typeof globalThis extends {
onerror: any;
WebAssembly: { Global: infer T };
@@ -217,7 +227,10 @@ declare global {
? T
: {
prototype: Instance;
new (module: Module, importObject?: Bun.WebAssembly.Imports): Instance;
new (
module: Module,
importObject?: Bun.WebAssembly.Imports,
): Instance;
};
interface Memory extends _Memory {}
@@ -236,7 +249,10 @@ declare global {
prototype: Module;
new (bytes: Bun.BufferSource): Module;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/customSections) */
customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];
customSections(
moduleObject: Module,
sectionName: string,
): ArrayBuffer[];
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/exports) */
exports(moduleObject: Module): ModuleExportDescriptor[];
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/imports) */
@@ -252,13 +268,18 @@ declare global {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile) */
function compile(bytes: Bun.BufferSource): Promise<Module>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming) */
function compileStreaming(source: Response | PromiseLike<Response>): Promise<Module>;
function compileStreaming(
source: Response | PromiseLike<Response>,
): Promise<Module>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) */
function instantiate(
bytes: Bun.BufferSource,
importObject?: Bun.WebAssembly.Imports,
): Promise<WebAssemblyInstantiatedSource>;
function instantiate(moduleObject: Module, importObject?: Bun.WebAssembly.Imports): Promise<Instance>;
function instantiate(
moduleObject: Module,
importObject?: Bun.WebAssembly.Imports,
): Promise<Instance>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming) */
function instantiateStreaming(
source: Response | PromiseLike<Response>,

View File

@@ -1,38 +1,38 @@
// Script to update certdata.txt from NSS.
import { execFileSync } from "node:child_process";
import { randomUUID } from "node:crypto";
import { createWriteStream } from "node:fs";
import { basename, dirname, join, relative } from "node:path";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";
import { fileURLToPath } from "node:url";
import { parseArgs } from "node:util";
import { execFileSync } from 'node:child_process';
import { randomUUID } from 'node:crypto';
import { createWriteStream } from 'node:fs';
import { basename, dirname, join, relative } from 'node:path';
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';
import { fileURLToPath } from 'node:url';
import { parseArgs } from 'node:util';
// Constants for NSS release metadata.
const kNSSVersion = "version";
const kNSSDate = "date";
const kFirefoxVersion = "firefoxVersion";
const kFirefoxDate = "firefoxDate";
const kNSSVersion = 'version';
const kNSSDate = 'date';
const kFirefoxVersion = 'firefoxVersion';
const kFirefoxDate = 'firefoxDate';
const __filename = fileURLToPath(import.meta.url);
const now = new Date();
const formatDate = d => {
const formatDate = (d) => {
const iso = d.toISOString();
return iso.substring(0, iso.indexOf("T"));
return iso.substring(0, iso.indexOf('T'));
};
const getCertdataURL = version => {
const tag = `NSS_${version.replaceAll(".", "_")}_RTM`;
const getCertdataURL = (version) => {
const tag = `NSS_${version.replaceAll('.', '_')}_RTM`;
const certdataURL = `https://hg.mozilla.org/projects/nss/raw-file/${tag}/lib/ckfw/builtins/certdata.txt`;
return certdataURL;
};
const normalizeTD = text => {
const normalizeTD = (text) => {
// Remove whitespace and any HTML tags.
return text?.trim().replace(/<.*?>/g, "");
return text?.trim().replace(/<.*?>/g, '');
};
const getReleases = text => {
const getReleases = (text) => {
const releases = [];
const tableRE = /<table [^>]+>([\S\s]*?)<\/table>/g;
const tableRowRE = /<tr ?[^>]*>([\S\s]*?)<\/tr>/g;
@@ -46,7 +46,7 @@ const getReleases = text => {
if (row.done) {
continue;
}
const headers = Array.from(row.value[1].matchAll(tableHeaderRE), m => m[1]);
const headers = Array.from(row.value[1].matchAll(tableHeaderRE), (m) => m[1]);
if (headers.length > 0) {
for (let i = 0; i < headers.length; i++) {
if (/NSS version/i.test(headers[i])) {
@@ -67,7 +67,7 @@ const getReleases = text => {
// Scrape releases.
row = matches.next();
while (!row.done) {
const cells = Array.from(row.value[1].matchAll(tableDataRE), m => m[1]);
const cells = Array.from(row.value[1].matchAll(tableDataRE), (m) => m[1]);
const release = {};
release[kNSSVersion] = normalizeTD(cells[columns[kNSSVersion]]);
release[kNSSDate] = new Date(normalizeTD(cells[columns[kNSSDate]]));
@@ -80,7 +80,7 @@ const getReleases = text => {
return releases;
};
const getLatestVersion = async releases => {
const getLatestVersion = async (releases) => {
const arrayNumberSortDescending = (x, y, i) => {
if (x[i] === undefined && y[i] === undefined) {
return 0;
@@ -89,8 +89,8 @@ const getLatestVersion = async releases => {
}
return (y[i] ?? 0) - (x[i] ?? 0);
};
const extractVersion = t => {
return t[kNSSVersion].split(".").map(n => parseInt(n));
const extractVersion = (t) => {
return t[kNSSVersion].split('.').map((n) => parseInt(n));
};
const releaseSorter = (x, y) => {
return arrayNumberSortDescending(extractVersion(x), extractVersion(y), 0);
@@ -102,31 +102,34 @@ const getLatestVersion = async releases => {
if (values.verbose) {
console.log(`Trying ${candidateURL}`);
}
const response = await fetch(candidateURL, { method: "HEAD" });
const response = await fetch(candidateURL, { method: 'HEAD' });
if (response.ok) {
return candidate[kNSSVersion];
}
}
};
const pastRelease = r => {
const pastRelease = (r) => {
return r[kNSSDate] < now;
};
const options = {
help: {
type: "boolean",
type: 'boolean',
},
file: {
short: "f",
type: "string",
short: 'f',
type: 'string',
},
verbose: {
short: "v",
type: "boolean",
short: 'v',
type: 'boolean',
},
};
const { positionals, values } = parseArgs({
const {
positionals,
values,
} = parseArgs({
allowPositionals: true,
options,
});
@@ -134,16 +137,16 @@ const { positionals, values } = parseArgs({
if (values.help) {
console.log(`Usage: ${basename(__filename)} [OPTION]... [VERSION]...`);
console.log();
console.log("Updates certdata.txt to NSS VERSION (most recent release by default).");
console.log("");
console.log(" -f, --file=FILE writes a commit message reflecting the change to the");
console.log(" specified FILE");
console.log(" -v, --verbose writes progress to stdout");
console.log(" --help display this help and exit");
console.log('Updates certdata.txt to NSS VERSION (most recent release by default).');
console.log('');
console.log(' -f, --file=FILE writes a commit message reflecting the change to the');
console.log(' specified FILE');
console.log(' -v, --verbose writes progress to stdout');
console.log(' --help display this help and exit');
process.exit(0);
}
const scheduleURL = "https://wiki.mozilla.org/NSS:Release_Versions";
const scheduleURL = 'https://wiki.mozilla.org/NSS:Release_Versions';
if (values.verbose) {
console.log(`Fetching NSS release schedule from ${scheduleURL}`);
}
@@ -156,15 +159,15 @@ const scheduleText = await schedule.text();
const nssReleases = getReleases(scheduleText);
// Retrieve metadata for the NSS release being updated to.
const version = positionals[0] ?? (await getLatestVersion(nssReleases));
const release = nssReleases.find(r => {
return new RegExp(`^${version.replace(".", "\\.")}\\b`).test(r[kNSSVersion]);
const version = positionals[0] ?? await getLatestVersion(nssReleases);
const release = nssReleases.find((r) => {
return new RegExp(`^${version.replace('.', '\\.')}\\b`).test(r[kNSSVersion]);
});
if (!pastRelease(release)) {
console.warn(`Warning: NSS ${version} is not due to be released until ${formatDate(release[kNSSDate])}`);
}
if (values.verbose) {
console.log("Found NSS version:");
console.log('Found NSS version:');
console.log(release);
}
@@ -176,7 +179,7 @@ if (values.verbose) {
const checkoutDir = dirname(__filename);
const certdata = await fetch(certdataURL);
const certdataFile = join(checkoutDir, "certdata.txt");
const certdataFile = join(checkoutDir, 'certdata.txt');
if (!certdata.ok) {
console.error(`Failed to fetch ${certdataURL}: ${certdata.status}: ${certdata.statusText}`);
process.exit(-1);
@@ -188,46 +191,46 @@ await pipeline(certdata.body, createWriteStream(certdataFile));
// Run generate-root-certs.pl to generate src/crypto/root_certs.h.
if (values.verbose) {
console.log("Running generate-root-certs.pl");
console.log('Running generate-root-certs.pl');
}
const opts = { encoding: "utf8" };
const mkCABundleTool = join(checkoutDir, "generate-root-certs.pl");
const mkCABundleOut = execFileSync(mkCABundleTool, values.verbose ? ["-v"] : [], opts);
const opts = { encoding: 'utf8' };
const mkCABundleTool = join(checkoutDir, 'generate-root-certs.pl');
const mkCABundleOut = execFileSync(mkCABundleTool,
values.verbose ? [ '-v' ] : [],
opts);
if (values.verbose) {
console.log(mkCABundleOut);
}
// Determine certificates added and/or removed.
const certHeaderFile = relative(process.cwd(), join(checkoutDir, "src", "crypto", "root_certs.h"));
const diff = execFileSync("git", ["diff-files", "-u", "--", certHeaderFile], opts);
const certHeaderFile = relative(process.cwd(), join(checkoutDir, 'src', 'crypto', 'root_certs.h'));
const diff = execFileSync('git', [ 'diff-files', '-u', '--', certHeaderFile ], opts);
if (values.verbose) {
console.log(diff);
}
const certsAddedRE = /^\+\/\* (.*) \*\//gm;
const certsRemovedRE = /^-\/\* (.*) \*\//gm;
const added = [...diff.matchAll(certsAddedRE)].map(m => m[1]);
const removed = [...diff.matchAll(certsRemovedRE)].map(m => m[1]);
const added = [ ...diff.matchAll(certsAddedRE) ].map((m) => m[1]);
const removed = [ ...diff.matchAll(certsRemovedRE) ].map((m) => m[1]);
const commitMsg = [
`crypto: update root certificates to NSS ${release[kNSSVersion]}`,
"",
'',
`This is the certdata.txt[0] from NSS ${release[kNSSVersion]}, released on ${formatDate(release[kNSSDate])}.`,
"",
`This is the version of NSS that ${release[kFirefoxDate] < now ? "shipped" : "will ship"} in Firefox ${
release[kFirefoxVersion]
} on`,
'',
`This is the version of NSS that ${release[kFirefoxDate] < now ? 'shipped' : 'will ship'} in Firefox ${release[kFirefoxVersion]} on`,
`${formatDate(release[kFirefoxDate])}.`,
"",
'',
];
if (added.length > 0) {
commitMsg.push("Certificates added:");
commitMsg.push(...added.map(cert => `- ${cert}`));
commitMsg.push("");
commitMsg.push('Certificates added:');
commitMsg.push(...added.map((cert) => `- ${cert}`));
commitMsg.push('');
}
if (removed.length > 0) {
commitMsg.push("Certificates removed:");
commitMsg.push(...removed.map(cert => `- ${cert}`));
commitMsg.push("");
commitMsg.push('Certificates removed:');
commitMsg.push(...removed.map((cert) => `- ${cert}`));
commitMsg.push('');
}
commitMsg.push(`[0] ${certdataURL}`);
const delimiter = randomUUID();
@@ -236,8 +239,8 @@ const properties = [
`COMMIT_MSG<<${delimiter}`,
...commitMsg,
delimiter,
"",
].join("\n");
'',
].join('\n');
if (values.verbose) {
console.log(properties);
}

View File

@@ -269,8 +269,6 @@ LIBUS_SOCKET_DESCRIPTOR apple_no_sigpipe(LIBUS_SOCKET_DESCRIPTOR fd) {
LIBUS_SOCKET_DESCRIPTOR bsd_set_nonblocking(LIBUS_SOCKET_DESCRIPTOR fd) {
#ifdef _WIN32
/* Libuv will set windows sockets as non-blocking */
#elif defined(__APPLE__)
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK | O_CLOEXEC);
#else
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
#endif
@@ -752,64 +750,6 @@ static int bsd_do_connect(struct addrinfo *rp, int *fd)
}
LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket(const char *host, int port, const char *source_host, int options) {
#ifdef _WIN32
// The caller (sometimes) uses NULL to indicate localhost. This works fine with getaddrinfo, but not with WSAConnectByName
if (!host) {
host = "localhost";
} else if (strcmp(host, "0.0.0.0") == 0 || strcmp(host, "::") == 0 || strcmp(host, "[::]") == 0) {
// windows disallows connecting to 0.0.0.0. To emulate POSIX behavior, we connect to localhost instead
// Also see https://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_connect
host = "localhost";
}
// On windows we use WSAConnectByName to speed up connecting to localhost
// The other implementation also works on windows, but is slower
char port_string[16];
snprintf(port_string, 16, "%d", port);
SOCKET s = socket(AF_INET6, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
return LIBUS_SOCKET_ERROR;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaconnectbynamea#remarks
DWORD zero = 0;
if (SOCKET_ERROR == setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&zero, sizeof(DWORD))) {
closesocket(s);
return LIBUS_SOCKET_ERROR;
}
if (source_host) {
struct addrinfo *interface_result;
if (!getaddrinfo(source_host, NULL, NULL, &interface_result)) {
int ret = bind(s, interface_result->ai_addr, (socklen_t) interface_result->ai_addrlen);
freeaddrinfo(interface_result);
if (ret == SOCKET_ERROR) {
closesocket(s);
return LIBUS_SOCKET_ERROR;
}
}
}
SOCKADDR_STORAGE local;
SOCKADDR_STORAGE remote;
DWORD local_len = sizeof(local);
DWORD remote_len = sizeof(remote);
if (FALSE == WSAConnectByNameA(s, host, port_string, &local_len, (SOCKADDR*)&local, &remote_len, (SOCKADDR*)&remote, NULL, NULL)) {
closesocket(s);
return LIBUS_SOCKET_ERROR;
}
// See
// - https://stackoverflow.com/questions/60591081/getpeername-always-fails-with-error-code-wsaenotconn
// - https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaconnectbynamea#remarks
//
// When the WSAConnectByName function returns TRUE, the socket s is in the default state for a connected socket.
// The socket s does not enable previously set properties or options until SO_UPDATE_CONNECT_CONTEXT is set on the socket.
// Use the setsockopt function to set the SO_UPDATE_CONNECT_CONTEXT option.
//
if (SOCKET_ERROR == setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 )) {
closesocket(s);
return LIBUS_SOCKET_ERROR;
}
return s;
#else
struct addrinfo hints, *result;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
@@ -855,7 +795,6 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket(const char *host, int port, co
freeaddrinfo(result);
return fd;
#endif
}
LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket_unix(const char *server_path, int options) {

View File

@@ -31,7 +31,7 @@ void Bun__internal_dispatch_ready_poll(void* loop, void* poll);
#include <errno.h>
#endif
void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs);
void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs, void*);
/* Pointer tags are used to indicate a Bun pointer versus a uSockets pointer */
#define UNSET_BITS_49_UNTIL_64 0x0000FFFFFFFFFFFF
@@ -175,7 +175,11 @@ void us_loop_run(struct us_loop_t *loop) {
}
}
void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs) {
void bun_on_tick_before(void* ctx);
void bun_on_tick_after(void* ctx);
void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs, void* tickCallbackContext) {
if (loop->num_polls == 0)
return;
@@ -187,6 +191,10 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs) {
us_loop_integrate(loop);
}
if (tickCallbackContext) {
bun_on_tick_before(tickCallbackContext);
}
/* Emit pre callback */
us_internal_loop_pre(loop);
@@ -213,6 +221,10 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, int64_t timeoutMs) {
}
#endif
if (tickCallbackContext) {
bun_on_tick_after(tickCallbackContext);
}
/* Iterate ready polls, dispatching them by type */
for (loop->current_ready_poll = 0; loop->current_ready_poll < loop->num_ready_polls; loop->current_ready_poll++) {
struct us_poll_t *poll = GET_READY_POLL(loop, loop->current_ready_poll);

View File

@@ -198,7 +198,7 @@ void us_loop_free(struct us_loop_t *loop) {
void us_loop_run(struct us_loop_t *loop) {
us_loop_integrate(loop);
uv_run(loop->uv_loop, UV_RUN_ONCE);
uv_run(loop->uv_loop, UV_RUN_NOWAIT);
}
struct us_poll_t *us_create_poll(struct us_loop_t *loop, int fallthrough,
@@ -327,11 +327,11 @@ void us_internal_async_wakeup(struct us_internal_async *a) {
uv_async_send(uv_async);
}
int us_socket_get_error(int ssl, struct us_socket_t *s) {
int us_socket_get_error(int ssl, struct us_socket_t* s)
{
int error = 0;
socklen_t len = sizeof(error);
if (getsockopt(us_poll_fd((struct us_poll_t *)s), SOL_SOCKET, SO_ERROR,
(char *)&error, &len) == -1) {
if (getsockopt(us_poll_fd((struct us_poll_t*)s), SOL_SOCKET, SO_ERROR, (char*)&error, &len) == -1) {
return errno;
}
return error;

View File

@@ -46,7 +46,6 @@
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#define LIBUS_SOCKET_DESCRIPTOR SOCKET
#else
@@ -400,9 +399,6 @@ int us_raw_root_certs(struct us_cert_string_t**out);
unsigned int us_get_remote_address_info(char *buf, struct us_socket_t *s, const char **dest, int *port, int *is_ipv6);
int us_socket_get_error(int ssl, struct us_socket_t *s);
void us_socket_ref(struct us_socket_t *s);
void us_socket_unref(struct us_socket_t *s);
#ifdef __cplusplus
}
#endif

View File

@@ -387,17 +387,3 @@ unsigned int us_get_remote_address_info(char *buf, struct us_socket_t *s, const
return length;
}
void us_socket_ref(struct us_socket_t *s) {
#ifdef LIBUS_USE_LIBUV
uv_ref((uv_handle_t*)s->p.uv_p);
#endif
// do nothing if not using libuv
}
void us_socket_unref(struct us_socket_t *s) {
#ifdef LIBUS_USE_LIBUV
uv_unref((uv_handle_t*)s->p.uv_p);
#endif
// do nothing if not using libuv
}

View File

@@ -134,8 +134,6 @@ private:
/* Handle HTTP data streams */
us_socket_context_on_data(SSL, getSocketContext(), [](us_socket_t *s, char *data, int length) {
// ref the socket to make sure we process it entirely before it is closed
us_socket_ref(s);
// total overhead is about 210k down to 180k
// ~210k req/sec is the original perf with write in data
@@ -295,10 +293,6 @@ private:
/* We need to uncork in all cases, except for nullptr (closed socket, or upgraded socket) */
if (returnedSocket != nullptr) {
us_socket_t* returnedSocketPtr = (us_socket_t*) returnedSocket;
/* We don't want open sockets to keep the event loop alive between HTTP requests */
us_socket_unref(returnedSocketPtr);
/* Timeout on uncork failure */
auto [written, failed] = ((AsyncSocket<SSL> *) returnedSocket)->uncork();
if (failed) {
@@ -318,7 +312,8 @@ private:
}
}
}
return returnedSocketPtr;
return (us_socket_t *) returnedSocket;
}
/* If we upgraded, check here (differ between nullptr close and nullptr upgrade) */

View File

@@ -227,15 +227,16 @@ namespace uWS
return unsignedIntegerValue;
}
/* RFC 9110 5.6.2. Tokens */
static inline bool isFieldNameByte(unsigned char c)
/* RFC 9110 16.3.1 Field Name Registry (TLDR; alnum + hyphen is allowed)
* [...] It MUST conform to the field-name syntax defined in Section 5.1,
* and it SHOULD be restricted to just letters, digits,
* and hyphen ('-') characters, with the first character being a letter. */
static inline bool isFieldNameByte(unsigned char x)
{
return (c > 32) & (c < 127) & (c != '(') &
(c != ')') & (c != ',') & (c != '/') &
(c != ':') & (c != ';') & (c != '<') &
(c != '=') & (c != '>') & (c != '?') &
(c != '@') & (c != '[') & (c != '\\') &
(c != ']') & (c != '{') & (c != '}');
return (x == '-') |
((x > '/') & (x < ':')) |
((x > '@') & (x < '[')) |
((x > 96) & (x < '{'));
}
static inline uint64_t hasLess(uint64_t x, uint64_t n)
@@ -262,19 +263,23 @@ namespace uWS
hasMore(x, 'z');
}
static inline void *consumeFieldName(char *p) {
//for (; true; p += 8) {
//uint64_t word;
//memcpy(&word, p, sizeof(uint64_t));
//if (notFieldNameWord(word)) {
while (isFieldNameByte(*(unsigned char *)p)) {
*(p++) |= 0x20;
static inline void *consumeFieldName(char *p)
{
for (; true; p += 8)
{
uint64_t word;
memcpy(&word, p, sizeof(uint64_t));
if (notFieldNameWord(word))
{
while (isFieldNameByte(*(unsigned char *)p))
{
*(p++) |= 0x20;
}
return (void *)p;
}
return (void *)p;
//}
//word |= 0x2020202020202020ull;
//memcpy(p, &word, sizeof(uint64_t));
//}
word |= 0x2020202020202020ull;
memcpy(p, &word, sizeof(uint64_t));
}
}
/* Puts method as key, target as value and returns non-null (or nullptr on error). */

View File

@@ -1,91 +1,86 @@
/* This smoke test runs against the Crc32 example program for now, but this example will be extended for more tests */
var crc32 = (function () {
var table = new Uint32Array(256);
for (var i = 256; i--; ) {
var tmp = i;
for (var k = 8; k--; ) {
tmp = tmp & 1 ? 3988292384 ^ (tmp >>> 1) : tmp >>> 1;
var table = new Uint32Array(256);
for (var i = 256; i--;) {
var tmp = i;
for (var k = 8; k--;) {
tmp = tmp & 1 ? 3988292384 ^ tmp >>> 1 : tmp >>> 1;
}
table[i] = tmp;
}
table[i] = tmp;
}
return function (data) {
var crc = -1; // Begin with all bits set ( 0xffffffff )
for (var i = 0, l = data.length; i < l; i++) {
crc = (crc >>> 8) ^ table[(crc & 255) ^ data[i]];
}
return (crc ^ -1) >>> 0; // Apply binary NOT
};
return function (data) {
var crc = -1; // Begin with all bits set ( 0xffffffff )
for (var i = 0, l = data.length; i < l; i++) {
crc = crc >>> 8 ^ table[crc & 255 ^ data[i]];
}
return (crc ^ -1) >>> 0; // Apply binary NOT
};
})();
async function chunkedCrc32Test(array) {
console.log("Making chunked request with body size: " + array.length);
const stream = new ReadableStream(
/*{type: "bytes"}, */ {
async start(controller) {
await 1;
controller.enqueue(array);
controller.close();
},
},
);
console.log("Making chunked request with body size: " + array.length);
const r = await fetch("http://localhost:3000", {
method: "POST",
headers: { "Content-Type": "application/octet-stream" },
body: stream,
duplex: "half",
});
const stream = new ReadableStream(/*{type: "bytes"}, */{
async start(controller) {
await 1;
controller.enqueue(array);
controller.close();
},
});
/* Download the response body (it's a crc32 hash plus newline) */
const body = await r.body.getReader().read();
const r = await fetch("http://localhost:3000", {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: stream,
duplex: 'half',
});
/* Make a crc32 comparison of the two (mind the newline in one!) */
const got = new TextDecoder().decode(body.value);
/* Download the response body (it's a crc32 hash plus newline) */
const body = await r.body.getReader().read();
const want = crc32(array).toString(16);
if (got.toString().slice(0, -1) !== want.toString()) {
throw new Error("failed chunked test");
}
/* Make a crc32 comparison of the two (mind the newline in one!) */
const got = new TextDecoder().decode(body.value);
const want = crc32(array).toString(16);
if (got.toString().slice(0, -1) !== want.toString()) {
throw new Error("failed chunked test");
}
}
async function fixedCrc32Test(array) {
console.log("Making request with body size: " + array.length);
console.log("Making request with body size: " + array.length);
/* Send it with content-length */
const res = await fetch("http://localhost:3000", {
keepalive: true,
headers: { "Content-Type": "text/plain" },
method: "POST",
body: array,
});
/* Send it with content-length */
const res = await fetch("http://localhost:3000", { keepalive: true, headers: { 'Content-Type': 'text/plain' }, method: "POST", body: array });
/* Download the response body (it's a crc32 hash plus newline) */
const body = await res.body.getReader().read();
/* Download the response body (it's a crc32 hash plus newline) */
const body = await res.body.getReader().read();
/* Make a crc32 comparison of the two (mind the newline in one!) */
const got = new TextDecoder().decode(body.value);
const want = crc32(array).toString(16);
if (got.toString().slice(0, -1) !== want.toString()) {
throw new Error("failed test");
}
/* Make a crc32 comparison of the two (mind the newline in one!) */
const got = new TextDecoder().decode(body.value);
const want = crc32(array).toString(16);
if (got.toString().slice(0, -1) !== want.toString()) {
throw new Error("failed test");
}
}
/* Maximum chunk size is less than 256mb */
const sizes = [0, 0, 32, 32, 128, 256, 1024, 65536, 1024 * 1024, 1024 * 1024 * 128, 0, 0, 32, 32];
for (let i = 0; i < sizes.length; i++) {
/* Create buffer with random data */
const array = new Uint8Array(sizes[i]);
//if (sizes[i] <= 65536) {
//self.crypto.getRandomValues(array);
//} else {
array.fill(Math.random() * 255);
//}
/* Do this for all methods */
await fixedCrc32Test(array);
await chunkedCrc32Test(array);
/* Create buffer with random data */
const array = new Uint8Array(sizes[i]);
//if (sizes[i] <= 65536) {
//self.crypto.getRandomValues(array);
//} else {
array.fill(Math.random() * 255);
//}
/* Do this for all methods */
await fixedCrc32Test(array);
await chunkedCrc32Test(array);
}
console.log("Done!");
console.log("Done!");

View File

@@ -796,6 +796,9 @@
"eslintConfig": {
"$ref": "https://json.schemastore.org/eslintrc.json"
},
"prettier": {
"$ref": "https://json.schemastore.org/prettierrc.json"
},
"stylelint": {
"$ref": "https://json.schemastore.org/stylelintrc.json"
},

View File

@@ -19,9 +19,9 @@ export enum Loader {
ts = BunLoader.ts,
}
export interface TestReference {
name: string;
byteOffset: number;
kind: "test" | "describe";
name: string,
byteOffset: number,
kind: 'test' | 'describe',
}
export type { ScanResult, TransformResponse };
@@ -221,7 +221,7 @@ export class Bun {
} else {
const fs = await import("fs");
if (typeof url === "string" && url.startsWith("file://")) {
if (typeof url === 'string' && url.startsWith('file://')) {
url = new URL(url); // fs.readFileSync cannot consume URL strings, only URL objects
}
@@ -300,7 +300,7 @@ export class Bun {
),
),
byteOffset: response.tests[i].byteOffset,
kind: testKindMap[response.tests[i].kind] as "test" | "describe",
kind: testKindMap[response.tests[i].kind] as 'test' | 'describe',
};
}
@@ -309,11 +309,7 @@ export class Bun {
return tests;
}
static transformSync(
content: Uint8Array | string,
file_name: string,
loader?: keyof typeof Loader,
): TransformResponse {
static transformSync(content: Uint8Array | string, file_name: string, loader?: keyof typeof Loader): TransformResponse {
const bb = new ByteBuffer(Bun.scratch);
bb.length = 0;
bb.index = 0;

View File

@@ -1,2 +1,2 @@
.\scripts\env.ps1
.\scripts\env.sh
ninja -Cbuild

17
scripts/codegen.ps1 Normal file
View File

@@ -0,0 +1,17 @@
$Script1=(Join-Path $PSScriptRoot "./cross-compile-codegen.sh")
$CrossCompileCodegen=(Get-Content $Script1 -Raw)
$CrossCompileCodegen.Replace("`r`n","`n") | Set-Content $Script1 -Force -NoNewline
$Script2=(Join-Path $PSScriptRoot "../src/codegen/create_hash_table")
$CreateHashTable=(Get-Content $Script2 -Raw)
$CreateHashTable.Replace("`r`n","`n") | Set-Content $Script2 -Force -NoNewline
& 'C:\Program Files\WSL\wsl.exe' ./scripts/cross-compile-codegen.sh win32 x64 "build"
Set-Content $Script1 -Force -NoNewline -Value $CrossCompileCodegen
Set-Content $Script2 -Force -NoNewline -Value $CreateHashTable
# copy into build-release as well
Remove-Item -Path "build-release/codegen" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "build-release/js" -Recurse -Force -ErrorAction SilentlyContinue
Copy-Item -Path "build/codegen" -Destination "build-release/codegen" -Recurse -Force
Copy-Item -Path "build/js" -Destination "build-release/js" -Recurse -Force

View File

@@ -59,11 +59,13 @@ update_repo_if_needed() {
done
printf "Zig was updated to ${zig_version}. Please commit new files."
# symlink extracted zig to extracted zig.exe
# TODO: Workaround for https://github.com/ziglang/vscode-zig/issues/164
ln -sf "${extract_at}/zig" "${extract_at}/zig.exe"
chmod +x "${extract_at}/zig.exe"
fi
# symlink extracted zig to extracted zig.exe
# TODO: Workaround for https://github.com/ziglang/vscode-zig/issues/164
ln -sf "${extract_at}/zig" "${extract_at}/zig.exe"
chmod +x "${extract_at}/zig.exe"
}
if [ -e "${extract_at}/.version" ]; then

View File

@@ -1,32 +1,32 @@
$npm_client = "npm"
# & ${npm_client} i
$root = Join-Path (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) "..\"
$esbuild = Join-Path $root "node_modules\.bin\esbuild.cmd"
$env:NODE_ENV = "production"
# runtime.js
echo $esbuild
& ${esbuild} `
"--target=esnext" "--bundle" `
"src/runtime.bun.js" `
"--format=esm" "--platform=node" "--minify" "--external:/bun:*" `
"--outfile=src/runtime.out.js"
if ($LASTEXITCODE -ne 0) { throw "esbuild failed with exit code $LASTEXITCODE" }
# fallback_decoder
& ${esbuild} --target=esnext --bundle src/fallback.ts --format=iife --platform=browser --minify > src/fallback.out.js
# bun-error
Push-Location packages\bun-error
& ${npm_client} install
& ${npm_client} run build
Pop-Location
# node-fallbacks
Push-Location src\node-fallbacks
& ${npm_client} install
& ${esbuild} --bundle @(Get-Item .\*.js) --outdir=out --format=esm --minify --platform=browser
Pop-Location
$npm_client = "npm"
# & ${npm_client} i
$root = Join-Path (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) "..\"
$esbuild = Join-Path $root "node_modules\.bin\esbuild.cmd"
$env:NODE_ENV = "production"
# runtime.js
echo $esbuild
& ${esbuild} `
"--target=esnext" "--bundle" `
"src/runtime.bun.js" `
"--format=esm" "--platform=node" "--minify" "--external:/bun:*" `
"--outfile=src/runtime.out.js"
if ($LASTEXITCODE -ne 0) { throw "esbuild failed with exit code $LASTEXITCODE" }
# fallback_decoder
& ${esbuild} --target=esnext --bundle src/fallback.ts --format=iife --platform=browser --minify > src/fallback.out.js
# bun-error
Push-Location packages\bun-error
& ${npm_client} install
& ${npm_client} run build
Pop-Location
# node-fallbacks
Push-Location src\node-fallbacks
& ${npm_client} install
& ${esbuild} --bundle @(Get-Item .\*.js) --outdir=out --format=esm --minify --platform=browser
Pop-Location

View File

@@ -1,22 +0,0 @@
# Navigate to the parent directory of the script
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
Push-Location $scriptPath\..
try {
# Get the WEBKIT_TAG value from CMakeLists.txt
$WEBKIT_TAG = Select-String -Path 'CMakeLists.txt' -Pattern 'set\(WEBKIT_TAG (.*?)\)' | ForEach-Object { $_.Matches.Groups[1].Value }
if (-not $WEBKIT_TAG) {
Write-Host "Could not find WEBKIT_TAG in CMakeLists.txt"
exit 1
}
Write-Host "Setting WebKit submodule to $WEBKIT_TAG"
# Navigate to the WebKit submodule directory
Set-Location src/bun.js/WebKit
# Fetch and reset the submodule to the specified tag
git fetch origin "$WEBKIT_TAG"
git reset --hard "$WEBKIT_TAG"
} finally {
Pop-Location
}

View File

@@ -69,8 +69,6 @@ pub fn setThreadName(name: StringTypes.stringZ) void {
_ = std.os.prctl(.SET_NAME, .{@intFromPtr(name.ptr)}) catch 0;
} else if (Environment.isMac) {
_ = std.c.pthread_setname_np(name);
} else if (Environment.isWindows) {
// _ = std.os.SetThreadDescription(std.os.GetCurrentThread(), name);
}
}
@@ -92,14 +90,10 @@ pub fn runExitCallbacks() void {
/// Flushes stdout and stderr and exits with the given code.
pub fn exit(code: u8) noreturn {
exitWide(@as(u32, code));
}
pub fn exitWide(code: u32) noreturn {
runExitCallbacks();
Output.flush();
std.mem.doNotOptimizeAway(&Bun__atexit);
std.c.exit(@bitCast(code));
std.c.exit(code);
}
pub fn raiseIgnoringPanicHandler(sig: anytype) noreturn {

View File

@@ -4,11 +4,8 @@ const FeatureFlags = @import("./feature_flags.zig");
const Environment = @import("./env.zig");
const FixedBufferAllocator = std.heap.FixedBufferAllocator;
const bun = @import("root").bun;
/// Checks if a slice's pointer is contained within another slice.
pub inline fn isSliceInBuffer(comptime T: type, slice: []const T, buffer: []const T) bool {
return (@intFromPtr(buffer.ptr) <= @intFromPtr(slice.ptr) and
(@intFromPtr(slice.ptr) + slice.len) <= (@intFromPtr(buffer.ptr) + buffer.len));
pub fn isSliceInBuffer(slice: anytype, buffer: anytype) bool {
return (@intFromPtr(&buffer) <= @intFromPtr(slice.ptr) and (@intFromPtr(slice.ptr) + slice.len) <= (@intFromPtr(buffer) + buffer.len));
}
pub fn sliceRange(slice: []const u8, buffer: []const u8) ?[2]u32 {
@@ -308,8 +305,8 @@ pub fn BSSStringList(comptime _count: usize, comptime _item_length: usize) type
return instance.slice_buf_used >= @as(u16, count);
}
pub fn exists(self: *const Self, value: ValueType) bool {
return isSliceInBuffer(u8, value, &self.backing_buf);
pub fn exists(_: *const Self, value: ValueType) bool {
return isSliceInBuffer(value, &instance.backing_buf);
}
pub fn editableSlice(slice: []const u8) []u8 {
@@ -317,7 +314,7 @@ pub fn BSSStringList(comptime _count: usize, comptime _item_length: usize) type
}
pub fn appendMutable(self: *Self, comptime AppendType: type, _value: AppendType) ![]u8 {
const appended = try @call(bun.callmod_inline, append, .{ self, AppendType, _value });
const appended = try @call(.always_inline, append, .{ self, AppendType, _value });
return @constCast(appended);
}
@@ -569,18 +566,14 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, comptime store_
}
}
/// Returns true if the entry was removed
pub fn remove(self: *Self, denormalized_key: []const u8) bool {
pub fn remove(self: *Self, denormalized_key: []const u8) void {
self.mutex.lock();
defer self.mutex.unlock();
const key = if (comptime remove_trailing_slashes)
std.mem.trimRight(u8, denormalized_key, "/")
else
denormalized_key;
const key = if (comptime remove_trailing_slashes) std.mem.trimRight(u8, denormalized_key, "/") else denormalized_key;
const _key = bun.hash(key);
return self.index.remove(_key);
_ = self.index.remove(_key);
// const index = self.index.get(_key) orelse return;
// switch (index) {
// Unassigned.index, NotFound.index => {
@@ -637,11 +630,11 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, comptime store_
return try self.map.getOrPut(key);
}
pub fn get(self: *Self, key: []const u8) ?*ValueType {
return @call(bun.callmod_inline, BSSMapType.get, .{ self.map, key });
return @call(.always_inline, BSSMapType.get, .{ self.map, key });
}
pub fn atIndex(self: *Self, index: IndexType) ?*ValueType {
return @call(bun.callmod_inline, BSSMapType.atIndex, .{ self.map, index });
return @call(.always_inline, BSSMapType.atIndex, .{ self.map, index });
}
pub fn keyAtIndex(_: *Self, index: IndexType) ?[]const u8 {
@@ -713,9 +706,8 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, comptime store_
self.map.markNotFound(result);
}
/// This does not free the keys.
/// Returns `true` if an entry had previously existed.
pub fn remove(self: *Self, key: []const u8) bool {
// For now, don't free the keys.
pub fn remove(self: *Self, key: []const u8) void {
return self.map.remove(key);
}
};

View File

@@ -309,59 +309,59 @@ pub const FilePoll = struct {
var ptr = poll.owner;
switch (ptr.tag()) {
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(FIFO))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) FIFO", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) FIFO", .{poll.fd});
ptr.as(FIFO).ready(size_or_offset, poll.flags.contains(.hup));
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellBufferedInput))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellBufferedInput", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellBufferedInput", .{poll.fd});
ptr.as(ShellBufferedInput).onPoll(size_or_offset, 0);
},
@field(Owner.Tag, "Subprocess") => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) Subprocess", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) Subprocess", .{poll.fd});
var loader = ptr.as(JSC.Subprocess);
loader.onExitNotificationTask();
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellBufferedWriter))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellBufferedWriter", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellBufferedWriter", .{poll.fd});
var loader = ptr.as(ShellBufferedWriter);
loader.onPoll(size_or_offset, 0);
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellBufferedWriterMini))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellBufferedWriterMini", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellBufferedWriterMini", .{poll.fd});
var loader = ptr.as(ShellBufferedWriterMini);
loader.onPoll(size_or_offset, 0);
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellSubprocessCapturedBufferedWriter))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellSubprocessCapturedBufferedWriter", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellSubprocessCapturedBufferedWriter", .{poll.fd});
var loader = ptr.as(ShellSubprocessCapturedBufferedWriter);
loader.onPoll(size_or_offset, 0);
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellSubprocessCapturedBufferedWriterMini))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellSubprocessCapturedBufferedWriterMini", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellSubprocessCapturedBufferedWriterMini", .{poll.fd});
var loader = ptr.as(ShellSubprocessCapturedBufferedWriterMini);
loader.onPoll(size_or_offset, 0);
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellSubprocess))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellSubprocess", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellSubprocess", .{poll.fd});
var loader = ptr.as(ShellSubprocess);
loader.onExitNotificationTask();
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(ShellSubprocessMini))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) ShellSubprocessMini", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) ShellSubprocessMini", .{poll.fd});
var loader = ptr.as(ShellSubprocessMini);
loader.onExitNotificationTask();
},
@field(Owner.Tag, bun.meta.typeBaseName(@typeName(JSC.WebCore.FileSink))) => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) FileSink", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) FileSink", .{poll.fd});
var loader = ptr.as(JSC.WebCore.FileSink);
loader.onPoll(size_or_offset, 0);
},
@field(Owner.Tag, "DNSResolver") => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) DNSResolver", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) DNSResolver", .{poll.fd});
var loader: *DNSResolver = ptr.as(DNSResolver);
loader.onDNSPoll(poll);
},
@@ -371,25 +371,25 @@ pub const FilePoll = struct {
unreachable;
}
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) GetAddrInfoRequest", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) GetAddrInfoRequest", .{poll.fd});
var loader: *GetAddrInfoRequest = ptr.as(GetAddrInfoRequest);
loader.onMachportChange();
},
@field(Owner.Tag, "OutputReader") => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) OutputReader", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) OutputReader", .{poll.fd});
var output: *LifecycleScriptSubprocessOutputReader = ptr.as(LifecycleScriptSubprocessOutputReader);
output.onPoll(size_or_offset);
},
@field(Owner.Tag, "PidPollData") => {
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) LifecycleScriptSubprocess Pid", .{poll.fd});
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) LifecycleScriptSubprocess Pid", .{poll.fd});
var loader: *bun.install.LifecycleScriptSubprocess = @ptrCast(ptr.as(LifecycleScriptSubprocessPid));
loader.onProcessUpdate(size_or_offset);
},
else => {
const possible_name = Owner.typeNameFromTag(@intFromEnum(ptr.tag()));
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {}) disconnected? (maybe: {s})", .{ poll.fd, possible_name orelse "<unknown>" });
log("onUpdate " ++ kqueue_or_epoll ++ " (fd: {d}) disconnected? (maybe: {s})", .{ poll.fd, possible_name orelse "<unknown>" });
},
}
}
@@ -731,7 +731,7 @@ pub const FilePoll = struct {
pub fn registerWithFd(this: *FilePoll, loop: *Loop, flag: Flags, one_shot: bool, fd: bun.FileDescriptor) JSC.Maybe(void) {
const watcher_fd = loop.fd;
log("register: {s} ({})", .{ @tagName(flag), fd });
log("register: {s} ({d})", .{ @tagName(flag), fd });
std.debug.assert(fd != invalid_fd);
@@ -908,7 +908,7 @@ pub const FilePoll = struct {
};
if (this.flags.contains(.needs_rearm) and !force_unregister) {
log("unregister: {s} ({}) skipped due to needs_rearm", .{ @tagName(flag), fd });
log("unregister: {s} ({d}) skipped due to needs_rearm", .{ @tagName(flag), fd });
this.flags.remove(.poll_process);
this.flags.remove(.poll_readable);
this.flags.remove(.poll_process);
@@ -916,7 +916,7 @@ pub const FilePoll = struct {
return JSC.Maybe(void).success;
}
log("unregister: {s} ({})", .{ @tagName(flag), fd });
log("unregister: {s} ({d})", .{ @tagName(flag), fd });
if (comptime Environment.isLinux) {
const ctl = linux.epoll_ctl(

View File

@@ -8,6 +8,9 @@ const uv = bun.windows.libuv;
pub const Loop = uv.Loop;
pub const KeepAlive = struct {
// handle.init zeroes the memory
handle: uv.uv_async_t = undefined,
status: Status = .inactive,
const log = Output.scoped(.KeepAlive, false);
@@ -15,6 +18,11 @@ pub const KeepAlive = struct {
const Status = enum { active, inactive, done };
pub inline fn isActive(this: KeepAlive) bool {
if (comptime Environment.allow_assert) {
if (this.status == .active) {
std.debug.assert(this.handle.isActive());
}
}
return this.status == .active;
}
@@ -22,6 +30,7 @@ pub const KeepAlive = struct {
pub fn disable(this: *KeepAlive) void {
if (this.status == .active) {
this.unref(JSC.VirtualMachine.get());
this.handle.close(null);
}
this.status = .done;
@@ -29,11 +38,12 @@ pub const KeepAlive = struct {
/// Only intended to be used from EventLoop.Pollable
pub fn deactivate(this: *KeepAlive, loop: *Loop) void {
_ = loop;
if (this.status != .active)
return;
this.status = .inactive;
loop.dec();
this.handle.close(null);
}
/// Only intended to be used from EventLoop.Pollable
@@ -42,7 +52,7 @@ pub const KeepAlive = struct {
return;
this.status = .active;
loop.inc();
this.handle.init(loop, null);
}
pub fn init() KeepAlive {
@@ -51,39 +61,42 @@ pub const KeepAlive = struct {
/// Prevent a poll from keeping the process alive.
pub fn unref(this: *KeepAlive, event_loop_ctx_: anytype) void {
const event_loop_ctx = JSC.AbstractVM(event_loop_ctx_);
_ = event_loop_ctx_;
// const event_loop_ctx = JSC.AbstractVM(event_loop_ctx_);
if (this.status != .active)
return;
this.status = .inactive;
event_loop_ctx.platformEventLoop().dec();
this.handle.unref();
}
/// From another thread, Prevent a poll from keeping the process alive.
pub fn unrefConcurrently(this: *KeepAlive, vm: *JSC.VirtualMachine) void {
// _ = vm;
_ = vm;
if (this.status != .active)
return;
this.status = .inactive;
// TODO: https://github.com/oven-sh/bun/pull/4410#discussion_r1317326194
vm.event_loop_handle.?.dec();
this.handle.unref();
}
/// Prevent a poll from keeping the process alive on the next tick.
pub fn unrefOnNextTick(this: *KeepAlive, vm: *JSC.VirtualMachine) void {
_ = vm;
if (this.status != .active)
return;
this.status = .inactive;
vm.event_loop_handle.?.dec();
this.handle.unref();
}
/// From another thread, prevent a poll from keeping the process alive on the next tick.
pub fn unrefOnNextTickConcurrently(this: *KeepAlive, vm: *JSC.VirtualMachine) void {
_ = vm;
if (this.status != .active)
return;
this.status = .inactive;
// TODO: https://github.com/oven-sh/bun/pull/4410#discussion_r1317326194
vm.event_loop_handle.?.dec();
this.handle.unref();
}
/// Allow a poll to keep the process alive.
@@ -92,7 +105,8 @@ pub const KeepAlive = struct {
if (this.status != .inactive)
return;
this.status = .active;
event_loop_ctx.platformEventLoop().inc();
this.handle.init(event_loop_ctx.platformEventLoop(), null);
this.handle.ref();
}
/// Allow a poll to keep the process alive.
@@ -101,7 +115,8 @@ pub const KeepAlive = struct {
return;
this.status = .active;
// TODO: https://github.com/oven-sh/bun/pull/4410#discussion_r1317326194
vm.event_loop_handle.?.inc();
this.handle.init(vm.event_loop_handle.?, null);
this.handle.ref();
}
pub fn refConcurrentlyFromEventLoop(this: *KeepAlive, loop: *JSC.EventLoop) void {

View File

@@ -143,9 +143,6 @@ pub const BrotliReaderArrayList = struct {
},
.needs_more_input => {
if (in_remaining > 0) {
@panic("Brotli wants more data");
}
this.state = .Inflating;
if (is_done) {
this.state = .Error;

View File

@@ -920,8 +920,7 @@ pub const Formatter = struct {
JSX,
Event,
GetterSetter,
CustomGetterSetter,
Getter,
pub fn isPrimitive(this: Tag) bool {
return switch (this) {
@@ -974,8 +973,7 @@ pub const Formatter = struct {
ArrayBuffer: void,
JSX: void,
Event: void,
GetterSetter: void,
CustomGetterSetter: void,
Getter: void,
pub fn isPrimitive(this: @This()) bool {
return @as(Tag, this).isPrimitive();
@@ -1109,24 +1107,22 @@ pub const Formatter = struct {
return .{
.tag = switch (js_type) {
.ErrorInstance => .Error,
.NumberObject => .Double,
.DerivedArray, JSValue.JSType.Array => .Array,
.DerivedStringObject, JSValue.JSType.String, JSValue.JSType.StringObject => .String,
.RegExpObject => .String,
.Symbol => .Symbol,
.BooleanObject => .Boolean,
.JSFunction => .Function,
.JSWeakMap, JSValue.JSType.JSMap => .Map,
.JSMapIterator => .MapIterator,
.JSSetIterator => .SetIterator,
.JSWeakSet, JSValue.JSType.JSSet => .Set,
.JSDate => .JSON,
.JSPromise => .Promise,
.Object,
.FinalObject,
.ProxyObject,
JSValue.JSType.ErrorInstance => .Error,
JSValue.JSType.NumberObject => .Double,
JSValue.JSType.DerivedArray, JSValue.JSType.Array => .Array,
JSValue.JSType.DerivedStringObject, JSValue.JSType.String, JSValue.JSType.StringObject => .String,
JSValue.JSType.RegExpObject => .String,
JSValue.JSType.Symbol => .Symbol,
JSValue.JSType.BooleanObject => .Boolean,
JSValue.JSType.JSFunction => .Function,
JSValue.JSType.JSWeakMap, JSValue.JSType.JSMap => .Map,
JSValue.JSType.JSMapIterator => .MapIterator,
JSValue.JSType.JSSetIterator => .SetIterator,
JSValue.JSType.JSWeakSet, JSValue.JSType.JSSet => .Set,
JSValue.JSType.JSDate => .JSON,
JSValue.JSType.JSPromise => .Promise,
JSValue.JSType.Object,
JSValue.JSType.FinalObject,
.ModuleNamespaceObject,
=> .Object,
@@ -1136,17 +1132,17 @@ pub const Formatter = struct {
.GlobalObject,
.ArrayBuffer,
.Int8Array,
.Uint8Array,
.Uint8ClampedArray,
.Int16Array,
.Uint16Array,
.Int32Array,
.Uint32Array,
.Float32Array,
.Float64Array,
.BigInt64Array,
.BigUint64Array,
JSValue.JSType.Int8Array,
JSValue.JSType.Uint8Array,
JSValue.JSType.Uint8ClampedArray,
JSValue.JSType.Int16Array,
JSValue.JSType.Uint16Array,
JSValue.JSType.Int32Array,
JSValue.JSType.Uint32Array,
JSValue.JSType.Float32Array,
JSValue.JSType.Float64Array,
JSValue.JSType.BigInt64Array,
JSValue.JSType.BigUint64Array,
.DataView,
=> .TypedArray,
@@ -1180,8 +1176,7 @@ pub const Formatter = struct {
.Event => .Event,
.GetterSetter => .GetterSetter,
.CustomGetterSetter => .CustomGetterSetter,
.GetterSetter, .CustomGetterSetter => .Getter,
.JSAsJSONType => .toJSON,
@@ -1891,31 +1886,8 @@ pub const Formatter = struct {
writer.print(comptime Output.prettyFmt("<cyan>[Function: {}]<r>", enable_ansi_colors), .{printable});
}
},
.GetterSetter => {
const cell = value.asCell();
const getterSetter = cell.getGetterSetter();
const hasGetter = !getterSetter.isGetterNull();
const hasSetter = !getterSetter.isSetterNull();
if (hasGetter and hasSetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Getter/Setter]<r>", enable_ansi_colors), .{});
} else if (hasGetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Getter]<r>", enable_ansi_colors), .{});
} else if (hasSetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Setter]<r>", enable_ansi_colors), .{});
}
},
.CustomGetterSetter => {
const cell = value.asCell();
const getterSetter = cell.getCustomGetterSetter();
const hasGetter = !getterSetter.isGetterNull();
const hasSetter = !getterSetter.isSetterNull();
if (hasGetter and hasSetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Getter/Setter]<r>", enable_ansi_colors), .{});
} else if (hasGetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Getter]<r>", enable_ansi_colors), .{});
} else if (hasSetter) {
writer.print(comptime Output.prettyFmt("<cyan>[Setter]<r>", enable_ansi_colors), .{});
}
.Getter => {
writer.print(comptime Output.prettyFmt("<cyan>[Getter]<r>", enable_ansi_colors), .{});
},
.Array => {
const len = @as(u32, @truncate(value.getLength(this.globalThis)));
@@ -2952,8 +2924,7 @@ pub const Formatter = struct {
.NativeCode => this.printAs(.NativeCode, Writer, writer, value, result.cell, enable_ansi_colors),
.JSX => this.printAs(.JSX, Writer, writer, value, result.cell, enable_ansi_colors),
.Event => this.printAs(.Event, Writer, writer, value, result.cell, enable_ansi_colors),
.GetterSetter => this.printAs(.GetterSetter, Writer, writer, value, result.cell, enable_ansi_colors),
.CustomGetterSetter => this.printAs(.CustomGetterSetter, Writer, writer, value, result.cell, enable_ansi_colors),
.Getter => this.printAs(.Getter, Writer, writer, value, result.cell, enable_ansi_colors),
.CustomFormattedObject => |callback| {
this.custom_formatted_object = callback;

View File

@@ -210,16 +210,16 @@ pub const RuntimeTranspilerCache = struct {
break :brk metadata_buf[0..metadata_stream.pos];
};
const vecs: []const bun.PlatformIOVecConst = if (output_bytes.len > 0)
const vecs: []const std.os.iovec_const = if (output_bytes.len > 0)
&.{
bun.platformIOVecConstCreate(metadata_bytes),
bun.platformIOVecConstCreate(output_bytes),
bun.platformIOVecConstCreate(sourcemap),
.{ .iov_base = metadata_bytes.ptr, .iov_len = metadata_bytes.len },
.{ .iov_base = output_bytes.ptr, .iov_len = output_bytes.len },
.{ .iov_base = sourcemap.ptr, .iov_len = sourcemap.len },
}
else
&.{
bun.platformIOVecConstCreate(metadata_bytes),
bun.platformIOVecConstCreate(sourcemap),
.{ .iov_base = metadata_bytes.ptr, .iov_len = metadata_bytes.len },
.{ .iov_base = sourcemap.ptr, .iov_len = sourcemap.len },
};
var position: isize = 0;
@@ -228,13 +228,8 @@ pub const RuntimeTranspilerCache = struct {
if (bun.Environment.allow_assert) {
var total: usize = 0;
for (vecs) |v| {
if (comptime bun.Environment.isWindows) {
std.debug.assert(v.len > 0);
total += v.len;
} else {
std.debug.assert(v.iov_len > 0);
total += v.iov_len;
}
std.debug.assert(v.iov_len > 0);
total += v.iov_len;
}
std.debug.assert(end_position == total);
}
@@ -251,7 +246,7 @@ pub const RuntimeTranspilerCache = struct {
}
}
try tmpfile.finish(@ptrCast(std.fs.path.basename(destination_path.slice())));
try tmpfile.finish(destination_path.sliceAssumeZ());
}
pub fn load(
@@ -486,7 +481,6 @@ pub const RuntimeTranspilerCache = struct {
const file = cache_fd.asFile();
const metadata_bytes = try file.preadAll(&metadata_bytes_buf, 0);
if (comptime bun.Environment.isWindows) try file.seekTo(0);
var metadata_stream = std.io.fixedBufferStream(metadata_bytes_buf[0..metadata_bytes]);
var entry = Entry{
@@ -545,7 +539,7 @@ pub const RuntimeTranspilerCache = struct {
const cache_dir_fd = brk: {
if (std.fs.path.dirname(cache_file_path)) |dirname| {
const dir = try std.fs.cwd().makeOpenPath(dirname, .{ .access_sub_paths = true });
break :brk bun.toLibUVOwnedFD(dir.fd);
break :brk bun.toFD(dir.fd);
}
break :brk bun.toFD(std.fs.cwd().fd);

Some files were not shown because too many files have changed in this diff Show More