Compare commits

...

109 Commits

Author SHA1 Message Date
Don Isaac
a634127dca fix(napi): memory leak when creating strings 2025-02-13 13:23:41 -08:00
Jarred Sumner
baee1c10d3 Fix flaky patch test (#17301) 2025-02-13 00:22:05 -08:00
Meghan Denny
6353fa4806 node:buffer: fix read (#17299) 2025-02-12 23:37:36 -08:00
chloe caruso
f17ce2b756 hmr fixes (#17239)
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-02-12 23:14:02 -08:00
Meghan Denny
c445cdaf13 cpp: fix asan error in process.setuid/setgid (#17300) 2025-02-12 23:13:07 -08:00
190n
ea65a2ad48 Bump WebKit (#17095)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-02-12 22:08:53 -08:00
pfg
eb145870cb Remove @intFromPtr(...) == 0 (#17276) 2025-02-12 20:18:03 -08:00
Jarred Sumner
2ea879e29b Add a couple guides 2025-02-12 17:32:16 -08:00
Jarred Sumner
a127f1ab59 Add v8 heap snapshot guide 2025-02-12 17:22:30 -08:00
Shlomo
506ea28b36 feat: load full certificate bundles from NODE_EXTRA_CA_CERTS (#16782) 2025-02-12 11:42:31 -08:00
Jarred Sumner
23ba9af43c Remove two usages of cppFn() (#17278) 2025-02-11 21:33:43 -08:00
Ciro Spaciari
1bb1f59b9e fix(sql) fix fragments containing fragments + concat syntax for parameters (#17273) 2025-02-11 20:08:58 -08:00
Ciro Spaciari
7403088c3b fix(sql) fix ready for query state (#17272) 2025-02-11 20:08:10 -08:00
chloe caruso
2b97d61deb chore: remove some trivial usage of usingnamespace (#17268) 2025-02-11 19:38:52 -08:00
chloe caruso
e22c6c5dbe fix a crash when trying to throw the error for onEnd ($notImplementedIssueFn) (#17271) 2025-02-11 19:38:10 -08:00
Meghan Denny
bdccbbc828 node: fix Buffer.from(arrayBuffer) (#17267) 2025-02-11 18:10:43 -08:00
Zack Radisic
0b6d468b74 CSS fix parsing of @-webkit-keyframes (#17266) 2025-02-11 16:19:33 -08:00
Meghan Denny
251c2b7d06 node:fs: windows: fix integer cast truncating bits when using too large of a mode (#17249) 2025-02-11 00:12:28 -08:00
Zack Radisic
321500c625 CSS stress tests, some fixes (#17131) 2025-02-10 20:56:30 -08:00
Ciro Spaciari
3a231a62b4 fix(sql) fix support for binary numeric values (#17245) 2025-02-10 19:25:52 -08:00
Meghan Denny
7adb2b9502 fix memory leak in ERR_INVALID_ARG_TYPE (#17169) 2025-02-10 18:50:49 -08:00
Vinícius Jardim
c2edbe848f docs(shell): fix incorrect output on "awaiting" example (#17152) 2025-02-10 17:20:18 -08:00
Jarred Sumner
02d4534561 Add =<val> to --help flags that accept values (#17237) 2025-02-10 17:19:09 -08:00
Snoep
cfebfe7731 Added Windows-specific instructions for Bun PATH setup (#17186) 2025-02-10 15:45:14 -08:00
Jarred Sumner
14b93e2ab9 Display CLI usage in docs 2025-02-10 06:48:07 -08:00
Jarred Sumner
9755e02e17 Update bun outdateddocs 2025-02-10 03:53:59 -08:00
Jarred Sumner
a23c11e381 Support BUN_PUBLIC_* and other env options in HTML imports (#17227)
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-02-10 02:09:48 -08:00
Meghan Denny
d814f3e6d8 meta: fix disabling of clangd auto header insertion (#17172) 2025-02-10 02:04:21 -08:00
Minsoo Choo
4a7e56b532 Fix latest version display from update-sqlite (#17209) 2025-02-10 02:02:38 -08:00
Jarred Sumner
fb0f28aab9 Remove a .vscode/launch.json config that is rarely used 2025-02-09 22:55:13 -08:00
Jarred Sumner
ba8573494a Add shadcn, tailwind and react detection & templates to bun create. Also: bun install --analyze <files...> (#17035) 2025-02-09 09:36:57 -08:00
github-actions[bot]
14164920b5 deps: update sqlite to 3.490.0 (#17201)
Co-authored-by: Jarred-Sumner <Jarred-Sumner@users.noreply.github.com>
2025-02-09 00:36:36 -08:00
Dylan Conway
2644bad5d4 Fix lexing out of bounds by one (#17168) 2025-02-08 05:23:41 -08:00
Michael H
584db03a74 bun pm pack support "files" starting with ./ (#17135)
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2025-02-08 01:27:15 -08:00
chloe caruso
f912e0abc4 hot module reloading for HTML import development mode (#16955) 2025-02-08 00:31:30 -08:00
Ciro Spaciari
6e887c8e45 fix(sql) fix TLS verify modes (#17129) 2025-02-07 23:23:05 -08:00
Meghan Denny
374195ea30 node: fix test-buffer-backing-arraybuffer.js (#17161) 2025-02-07 23:22:03 -08:00
Ciro Spaciari
0da7025fb0 fix(sql) decode options from URI properly (#17156) 2025-02-07 15:43:23 -08:00
Meghan Denny
180500181f js: fix Buffer constructor and Buffer.from (#16731) 2025-02-07 15:13:21 -08:00
Ciro Spaciari
c970922456 fix(sql) expose alias in SQLOption type (#17122) 2025-02-06 19:14:34 -08:00
Jarred Sumner
93af28751f Update CMakeLists.txt 2025-02-06 18:07:55 -08:00
190n
4d2a8650e5 test: bump pglite version (#17117) 2025-02-06 14:33:44 -08:00
Don Isaac
146ec7791b fix(node/assert): port more test cases from node (#16895)
Co-authored-by: DonIsaac <22823424+DonIsaac@users.noreply.github.com>
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2025-02-06 14:29:59 -08:00
Ciro Spaciari
253faed1cf fix(sql) types (#17118) 2025-02-06 13:37:58 -08:00
Ciro Spaciari
1fe2c3b426 feat(sql) support retrieving array values (#17094) 2025-02-06 02:45:05 -08:00
Jarred Sumner
fad856c03c Support fs.stat, fs.existsSync, fs.readFile, fs.promises.stat, fs.promises.readFile in bun build --compile (#17102)
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2025-02-06 00:06:52 -08:00
Jarred Sumner
2770ecad5c Fixes #16995 (#17101) 2025-02-05 22:35:53 -08:00
Michael H
1684c6246d fix bunx on windows with postinstall scripts (#17076) 2025-02-05 22:31:42 -08:00
Jarred Sumner
d2cdb5031d Fix potential crash when printing errors in bun install (#17027) 2025-02-05 22:17:02 -08:00
pfg
0c8658b350 Fix test-fs-promises-writefile.js on windows (#17053) 2025-02-05 22:12:52 -08:00
pfg
fc7bd569f5 Fix UAF in throwCommandNotFound (#17097) 2025-02-05 21:22:52 -08:00
pfg
5620a7dfac Enable asan on debug macos aarch64 builds (#17058) 2025-02-05 17:24:32 -08:00
Bartłomiej Kalemba
1ccc13ecf7 docs(bunfig): update test runner options (#17040) 2025-02-04 23:56:12 -08:00
Dylan Conway
4d004b90ca Fix bun.lock formatting of bin (#17041) 2025-02-04 23:55:57 -08:00
Zack Radisic
dcf0b719a5 CSS Fixes: light dark, color down-leveling bugs, implement minify for box-shadow (#17055) 2025-02-04 22:50:41 -08:00
Meghan Denny
8634ee3065 fix test-buffer-copy.js (#16640) 2025-02-04 20:19:22 -08:00
Meghan Denny
1819b01932 node: fix test-buffer-fill.js (#16738) 2025-02-04 19:52:11 -08:00
Meghan Denny
b39d84690c implement process.binding('buffer') (#16741)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-02-04 17:59:48 -08:00
Kai Tamkun
d63fe71a6d Fix node:dgram addMembership/dropMembership segfault (#17049) 2025-02-04 15:22:44 -08:00
Dylan Conway
fa55ca31e1 Fix occasional crash on FilePoll deinit (#17050) 2025-02-04 15:22:28 -08:00
190n
a8d159da22 Fix napi_is_buffer/napi_is_typedarray to match Node.js (#17034) 2025-02-03 21:49:27 -08:00
Jarred Sumner
0861c03b37 Fix memory leak in the SQL query string (#17026)
Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
2025-02-03 17:38:17 -08:00
Jarred Sumner
7a918d24a7 Fix loading react-jsxdev instead of react-jsx (#17013)
Co-authored-by: chloe caruso <git@paperclover.net>
2025-02-03 14:10:09 -08:00
Bkh
7bef462257 Fix typo in html.ts (#17023) 2025-02-03 12:28:19 -08:00
Jarred Sumner
9cfa3a558b Bump 2025-02-03 07:15:33 -08:00
Jarred Sumner
97ae35dfde Update html.md 2025-02-03 04:08:46 -08:00
Jarred Sumner
1ea14f483c Introduce bun ./index.html (#16993) 2025-02-03 04:06:12 -08:00
Jarred Sumner
ec751159c6 Update typescript.md 2025-02-03 02:40:20 -08:00
Minsoo Choo
fa502506e5 Fix formatting for extern "c" (#16983) 2025-02-02 21:34:58 -08:00
Dylan Conway
06b16fc11e fix 16939 (#16991) 2025-02-02 21:31:40 -08:00
Ciro Spaciari
00a5c4af5a fix(sql) disable idle timeout when still processing data (#16984) 2025-02-02 21:27:22 -08:00
Dylan Conway
cc68f4f025 Fix occasional crash starting debugger thread (#16989) 2025-02-02 05:11:15 -08:00
Jarred Sumner
aac951bd47 Move semver-related structs into their own files (#16987) 2025-02-02 00:20:45 -08:00
Meghan Denny
34419c5f0d zig: only call strlen/wcslen in indexOfSentinel if libc is linked (#16986) 2025-02-01 23:59:45 -08:00
Jarred Sumner
1595b1cc2b Disable stop if necessary timer (#16962) 2025-02-01 22:56:34 -08:00
Michael H
5366c9db33 hopefully auto pr to DT (#16956) 2025-02-01 22:55:19 -08:00
Okinea Dev
87281b6d48 fix: add file association for *.mdc files (#16963) 2025-02-01 22:18:17 -08:00
Jarred Sumner
43fd9326ba Use a more reliable zig download url 2025-02-01 22:12:22 -08:00
Meghan Denny
26d3688e53 zig: update to 0.14.0-dev (#16862)
Co-authored-by: nektro <5464072+nektro@users.noreply.github.com>
2025-02-01 01:11:02 -08:00
pfg
1ddf3fc097 Fix fetch with formdata on some servers (#16947) 2025-01-31 22:39:43 -08:00
Dylan Conway
73bcff9d01 fix 16842 (#16952) 2025-01-31 22:39:30 -08:00
Jarred Sumner
c1708ea6ab Try bringing release/acquire heap access back (#16865)
Co-authored-by: Ben Grant <ben@bun.sh>
2025-01-31 16:13:03 -08:00
Meghan Denny
447121235c node:vm: this error was super confusing without the period 2025-01-31 15:54:06 -08:00
Jarred Sumner
1fa42d81af Bump 2025-01-31 07:08:40 -08:00
Jarred Sumner
22a23add8d Fix import("bun") in Vite (#16938) 2025-01-31 06:34:14 -08:00
Dylan Conway
d4ce421982 Fix node:fs memory leak with AbortSignal (#16788)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:25:53 -08:00
chloe caruso
322098fa54 allow resolution to work when the source file does not exist (#16851)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:24:57 -08:00
Jarred Sumner
9acb72d2ad Correctly handle __esModule for loader: "object" (#16885)
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-01-31 05:24:33 -08:00
Ciro Spaciari
25f6cbd471 fix(s3) fix queue and multipart flow (#16890)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:19:23 -08:00
Dylan Conway
b098c9ed89 fix(fs): WriteStream pending write fastpath (#16856)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-01-31 05:14:41 -08:00
Jarred Sumner
212944a5b6 Reduce memory usage of fs.readdir withFileTypes (#16897) 2025-01-31 04:25:58 -08:00
Jarred Sumner
61bf221510 Get pnpm to run inside bun (#16934) 2025-01-31 04:22:03 -08:00
Michael H
891057cd20 fix bun init -h (#16896) 2025-01-31 04:15:44 -08:00
Don Isaac
c51196a8dc fix(install): crash from invalid SemVer with extra wildcard (#16489) 2025-01-31 04:14:53 -08:00
Zack Radisic
f6ec0da125 Various CSS fixing and stability stuff (#16889) 2025-01-31 03:47:49 -08:00
Jarred Sumner
b59b793a32 Fix lifetime issue in BunString (#16930) 2025-01-30 20:46:19 -08:00
Matt Sutkowski
3a4df79a64 chore(docs): remove await from migrate cmd in drizzle.md (#16919) 2025-01-30 17:09:16 -08:00
190n
91f2be57b5 fix(node:os): loadavg() return values on Darwin (#16922) 2025-01-30 17:08:44 -08:00
Don Isaac
b612bc4f47 feat(node/fs): add fs.glob, fs.globSync, and fs.promises.glob (#16676) 2025-01-30 13:20:19 -08:00
Don Isaac
f454c27365 fix: Bun.deepEquals on empty objects with the same prototype (#16894)
Co-authored-by: DonIsaac <22823424+DonIsaac@users.noreply.github.com>
2025-01-30 12:12:51 -08:00
Ciro Spaciari
892764ec43 fix(sql) fix execution queue (#16854) 2025-01-29 23:52:19 -08:00
190n
574a41b03f chore: bump to v1.2.1 (#16891) 2025-01-29 20:19:12 -08:00
Don Isaac
c8f8d2c0bb fix(node/http): re-export WebSocket, CloseEvent, and MessageEvent (#16888) 2025-01-29 18:52:02 -08:00
Meghan Denny
29839737df cpp: synchronize on JSC::getVM since its more likely to be forward compatible (#16688) 2025-01-29 15:50:57 -08:00
Jarred Sumner
4d5ece3f63 Run stopIfNecessary GC timer more (#16871) 2025-01-29 14:40:51 -08:00
Meghan Denny
93a89e5866 meta: update bun.locks with bun 1.2 (#16867)
Co-authored-by: nektro <5464072+nektro@users.noreply.github.com>
2025-01-29 01:47:43 -08:00
Meghan Denny
676e8d1632 zig: delete is_bindgen (#16858) 2025-01-28 23:51:24 -08:00
Meghan Denny
5633ec4334 docker: fix distroless build (#16820) 2025-01-28 18:08:40 -08:00
Meghan Denny
160bf9d563 zig: make install.Resolution.init() not use anytype (#16852) 2025-01-28 18:08:10 -08:00
970 changed files with 54864 additions and 18412 deletions

View File

@@ -391,6 +391,8 @@ function getBuildEnv(target, options) {
ENABLE_ASSERTIONS: release ? "OFF" : "ON",
ENABLE_LOGS: release ? "OFF" : "ON",
ABI: abi === "musl" ? "musl" : undefined,
CMAKE_TLS_VERIFY: "0",
};
}

View File

@@ -6,6 +6,3 @@ CompileFlags:
Diagnostics:
UnusedIncludes: None
HeaderInsertion:
IncludeBlocks: Preserve # Do not auto-include headers.

View File

@@ -0,0 +1,378 @@
---
description: JavaScript class implemented in C++
globs: *.cpp
---
# Implementing JavaScript classes in C++
If there is a publicly accessible Constructor and Prototype, then there are 3 classes:
- IF there are C++ class members we need a destructor, so `class Foo : public JSC::DestructibleObject`, if no C++ class fields (only JS properties) then we don't need a class at all usually. We can instead use JSC::constructEmptyObject(vm, structure) and `putDirectOffset` like in [NodeFSBinding.cpp](mdc:src/bun.js/bindings/NodeFSBinding.cpp).
- class FooPrototype : public JSC::JSNonFinalObject
- class FooConstructor : public JSC::InternalFunction
If there is no publicly accessible Constructor, just the Prototype and the class is necessary. In some cases, we can avoid the prototype entirely (but that's rare).
If there are C++ fields on the Foo class, the Foo class will need an iso subspace added to [DOMClientIsoSubspaces.h](mdc:src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h) and [DOMIsoSubspaces.h](mdc:src/bun.js/bindings/webcore/DOMIsoSubspaces.h). Prototype and Constructor do not need subspaces.
Usually you'll need to #include "root.h" at the top of C++ files or you'll get lint errors.
Generally, defining the subspace looks like this:
```c++
class Foo : public JSC::DestructibleObject {
// ...
template<typename MyClassT, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return WebCore::subspaceForImpl<MyClassT, WebCore::UseCustomHeapCellType::No>(
vm,
[](auto& spaces) { return spaces.m_clientSubspaceFor${MyClassT}.get(); },
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceFor${MyClassT} = std::forward<decltype(space)>(space); },
[](auto& spaces) { return spaces.m_subspaceFo${MyClassT}.get(); },
[](auto& spaces, auto&& space) { spaces.m_subspaceFor${MyClassT} = std::forward<decltype(space)>(space); });
}
```
It's better to put it in the .cpp file instead of the .h file, when possible.
## Defining properties
Define properties on the prototype. Use a const HashTableValues like this:
```C++
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckEmail);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckHost);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckIP);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckIssued);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckPrivateKey);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToJSON);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToLegacyObject);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncToString);
static JSC_DECLARE_HOST_FUNCTION(jsX509CertificateProtoFuncVerify);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_ca);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint256);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_fingerprint512);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_subject);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_subjectAltName);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_infoAccess);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_keyUsage);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_issuer);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_issuerCertificate);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_publicKey);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_raw);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_serialNumber);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validFrom);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validTo);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validFromDate);
static JSC_DECLARE_CUSTOM_GETTER(jsX509CertificateGetter_validToDate);
static const HashTableValue JSX509CertificatePrototypeTableValues[] = {
{ "ca"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_ca, 0 } },
{ "checkEmail"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckEmail, 2 } },
{ "checkHost"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckHost, 2 } },
{ "checkIP"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckIP, 1 } },
{ "checkIssued"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckIssued, 1 } },
{ "checkPrivateKey"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncCheckPrivateKey, 1 } },
{ "fingerprint"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint, 0 } },
{ "fingerprint256"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint256, 0 } },
{ "fingerprint512"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_fingerprint512, 0 } },
{ "infoAccess"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_infoAccess, 0 } },
{ "issuer"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_issuer, 0 } },
{ "issuerCertificate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_issuerCertificate, 0 } },
{ "keyUsage"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_keyUsage, 0 } },
{ "publicKey"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_publicKey, 0 } },
{ "raw"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_raw, 0 } },
{ "serialNumber"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_serialNumber, 0 } },
{ "subject"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_subject, 0 } },
{ "subjectAltName"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_subjectAltName, 0 } },
{ "toJSON"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToJSON, 0 } },
{ "toLegacyObject"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToLegacyObject, 0 } },
{ "toString"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncToString, 0 } },
{ "validFrom"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validFrom, 0 } },
{ "validFromDate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validFromDate, 0 } },
{ "validTo"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validTo, 0 } },
{ "validToDate"_s, static_cast<unsigned>(PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessorOrValue), NoIntrinsic, { HashTableValue::GetterSetterType, jsX509CertificateGetter_validToDate, 0 } },
{ "verify"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsX509CertificateProtoFuncVerify, 1 } },
};
```
### Creating a prototype class
Follow a pattern like this:
```c++
class JSX509CertificatePrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSX509CertificatePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
{
JSX509CertificatePrototype* prototype = new (NotNull, allocateCell<JSX509CertificatePrototype>(vm)) JSX509CertificatePrototype(vm, structure);
prototype->finishCreation(vm);
return prototype;
}
template<typename, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.plainObjectSpace();
}
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
auto* structure = JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
structure->setMayBePrototype(true);
return structure;
}
private:
JSX509CertificatePrototype(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure)
{
}
void finishCreation(JSC::VM& vm);
};
const ClassInfo JSX509CertificatePrototype::s_info = { "X509Certificate"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSX509CertificatePrototype) };
void JSX509CertificatePrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSX509Certificate::info(), JSX509CertificatePrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
} // namespace Bun
```
### Getter definition:
```C++
JSC_DEFINE_CUSTOM_GETTER(jsX509CertificateGetter_ca, (JSGlobalObject * globalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSX509Certificate* thisObject = jsDynamicCast<JSX509Certificate*>(JSValue::decode(thisValue));
if (UNLIKELY(!thisObject)) {
Bun::throwThisTypeError(*globalObject, scope, "JSX509Certificate"_s, "ca"_s);
return {};
}
return JSValue::encode(jsBoolean(thisObject->view().isCA()));
}
```
### Setter definition
```C++
JSC_DEFINE_CUSTOM_SETTER(jsImportMetaObjectSetter_require, (JSGlobalObject * jsGlobalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, PropertyName propertyName))
{
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
if (UNLIKELY(!thisObject))
return false;
JSValue value = JSValue::decode(encodedValue);
if (!value.isCell()) {
// TODO:
return true;
}
thisObject->requireProperty.set(thisObject->vm(), thisObject, value.asCell());
return true;
}
```
### Function definition
```C++
JSC_DEFINE_HOST_FUNCTION(jsX509CertificateProtoFuncToJSON, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto *thisObject = jsDynamicCast<MyClassT*>(callFrame->thisValue());
if (UNLIKELY(!thisObject)) {
Bun::throwThisTypeError(*globalObject, scope, "MyClass"_s, "myFunctionName"_s);
return {};
}
return JSValue::encode(functionThatReturnsJSValue(vm, globalObject, thisObject));
}
```
### Constructor definition
```C++
JSC_DECLARE_HOST_FUNCTION(callStats);
JSC_DECLARE_HOST_FUNCTION(constructStats);
class JSStatsConstructor final : public JSC::InternalFunction {
public:
using Base = JSC::InternalFunction;
static constexpr unsigned StructureFlags = Base::StructureFlags;
static JSStatsConstructor* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* prototype)
{
JSStatsConstructor* constructor = new (NotNull, JSC::allocateCell<JSStatsConstructor>(vm)) JSStatsConstructor(vm, structure);
constructor->finishCreation(vm, prototype);
return constructor;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
return &vm.internalFunctionSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
}
private:
JSStatsConstructor(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, callStats, constructStats)
{
}
void finishCreation(JSC::VM& vm, JSC::JSObject* prototype)
{
Base::finishCreation(vm, 0, "Stats"_s);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
}
};
```
### Structure caching
If there's a class, prototype, and constructor:
1. Add the `JSC::LazyClassStructure` to [ZigGlobalObject.h](mdc:src/bun.js/bindings/ZigGlobalObject.h)
2. Initialize the class structure in [ZigGlobalObject.cpp](mdc:src/bun.js/bindings/ZigGlobalObject.cpp) in `void GlobalObject::finishCreation(VM& vm)`
3. Visit the class structure in visitChildren in [ZigGlobalObject.cpp](mdc:src/bun.js/bindings/ZigGlobalObject.cpp) in `void GlobalObject::visitChildrenImpl`
```c++
m_JSStatsBigIntClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
Bun::initJSBigIntStatsClassStructure(init);
});
```
If there's only a class, use `JSC::LazyProperty<JSGlobalObject, Structure>` instead of `JSC::LazyClassStructure`.
Then, implement the function that creates the structure:
```c++
void setupX509CertificateClassStructure(LazyClassStructure::Initializer& init)
{
auto* prototypeStructure = JSX509CertificatePrototype::createStructure(init.vm, init.global, init.global->objectPrototype());
auto* prototype = JSX509CertificatePrototype::create(init.vm, init.global, prototypeStructure);
auto* constructorStructure = JSX509CertificateConstructor::createStructure(init.vm, init.global, init.global->functionPrototype());
auto* constructor = JSX509CertificateConstructor::create(init.vm, init.global, constructorStructure, prototype);
auto* structure = JSX509Certificate::createStructure(init.vm, init.global, prototype);
init.setPrototype(prototype);
init.setStructure(structure);
init.setConstructor(constructor);
}
```
Then, use the structure by calling `globalObject.m_myStructureName.get(globalObject)`
```C++
JSC_DEFINE_HOST_FUNCTION(x509CertificateConstructorConstruct, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (!callFrame->argumentCount()) {
Bun::throwError(globalObject, scope, ErrorCode::ERR_MISSING_ARGS, "X509Certificate constructor requires at least one argument"_s);
return {};
}
JSValue arg = callFrame->uncheckedArgument(0);
if (!arg.isCell()) {
Bun::throwError(globalObject, scope, ErrorCode::ERR_INVALID_ARG_TYPE, "X509Certificate constructor argument must be a Buffer, TypedArray, or string"_s);
return {};
}
auto* zigGlobalObject = defaultGlobalObject(globalObject);
Structure* structure = zigGlobalObject->m_JSX509CertificateClassStructure.get(zigGlobalObject);
JSValue newTarget = callFrame->newTarget();
if (UNLIKELY(zigGlobalObject->m_JSX509CertificateClassStructure.constructor(zigGlobalObject) != newTarget)) {
auto scope = DECLARE_THROW_SCOPE(vm);
if (!newTarget) {
throwTypeError(globalObject, scope, "Class constructor X509Certificate cannot be invoked without 'new'"_s);
return {};
}
auto* functionGlobalObject = defaultGlobalObject(getFunctionRealm(globalObject, newTarget.getObject()));
RETURN_IF_EXCEPTION(scope, {});
structure = InternalFunction::createSubclassStructure(
globalObject, newTarget.getObject(), functionGlobalObject->NodeVMScriptStructure());
scope.release();
}
return JSValue::encode(createX509Certificate(vm, globalObject, structure, arg));
}
```
### Expose to Zig
To expose the constructor to zig:
```c++
extern "C" JSC::EncodedJSValue Bun__JSBigIntStatsObjectConstructor(Zig::GlobalObject* globalobject)
{
return JSValue::encode(globalobject->m_JSStatsBigIntClassStructure.constructor(globalobject));
}
```
Zig:
```zig
extern "c" fn Bun__JSBigIntStatsObjectConstructor(*JSC.JSGlobalObject) JSC.JSValue;
pub const getBigIntStatsConstructor = Bun__JSBigIntStatsObjectConstructor;
```
To create an object (instance) of a JS class defined in C++ from Zig, follow the __toJS convention like this:
```c++
// X509* is whatever we need to create the object
extern "C" EncodedJSValue Bun__X509__toJS(Zig::GlobalObject* globalObject, X509* cert)
{
// ... implementation details
auto* structure = globalObject->m_JSX509CertificateClassStructure.get(globalObject);
return JSValue::encode(JSX509Certificate::create(globalObject->vm(), structure, globalObject, WTFMove(cert)));
}
```
And from Zig:
```zig
const X509 = opaque {
// ... class
extern fn Bun__X509__toJS(*JSC.JSGlobalObject, *X509) JSC.JSValue;
pub fn toJS(this: *X509, globalObject: *JSC.JSGlobalObject) JSC.JSValue {
return Bun__X509__toJS(globalObject, this);
}
};
```

1
.gitattributes vendored
View File

@@ -15,6 +15,7 @@
*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mdc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mjs text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.mts text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

View File

@@ -4,7 +4,7 @@ description: An internal version of the 'oven-sh/setup-bun' action.
inputs:
bun-version:
type: string
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.0.0', etc."
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.2.0', etc."
default: latest
required: false
baseline:

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
LLVM_VERSION: "18.1.8"
LLVM_VERSION_MAJOR: "18"

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
LLVM_VERSION: "18.1.8"
LLVM_VERSION_MAJOR: "18"

View File

@@ -5,7 +5,7 @@ on:
workflow_dispatch:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
OXLINT_VERSION: "0.15.0"
jobs:

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
prettier-format:

View File

@@ -44,6 +44,10 @@ on:
description: Should types be released to npm?
type: boolean
default: false
use-definitelytyped:
description: "Should types be PR'd to DefinitelyTyped?"
type: boolean
default: false
jobs:
sign:
@@ -66,7 +70,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Sign Release
@@ -94,7 +98,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Release
@@ -123,7 +127,7 @@ jobs:
if: ${{ env.BUN_VERSION != 'canary' }}
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Setup Bun
if: ${{ env.BUN_VERSION == 'canary' }}
uses: ./.github/actions/setup-bun
@@ -155,6 +159,48 @@ jobs:
with:
package: packages/bun-types/package.json
token: ${{ secrets.NPM_TOKEN }}
definitelytyped:
name: Make pr to DefinitelyTyped to update `bun-types` version
runs-on: ubuntu-latest
needs: npm-types
if: ${{ github.event_name == 'release' || github.event.inputs.use-definitelytyped == 'true' }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: DefinitelyTyped/DefinitelyTyped
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.2.0"
- id: bun-version
run: echo "BUN_VERSION=${BUN_VERSION#bun-v}" >> "$GITHUB_OUTPUT"
- name: Update bun-types version in package.json
run: |
bun -e '
const file = Bun.file("./types/bun/package.json");
const json = await file.json();
const version = "${{ steps.bun-version.outputs.BUN_VERSION }}";
json.dependencies["bun-types"] = version;
json.version = version.slice(0, version.lastIndexOf(".")) + ".9999";
await file.write(JSON.stringify(json, null, 4) + "\n");
'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
if: ${{ env.BUN_LATEST == 'true' && env.BUN_VERSION != 'canary'}}
with:
token: ${{ secrets.ROBOBUN_TOKEN }}
add-paths: ./types/bun/package.json
title: "[bun] update to ${{ steps.bun-version.outputs.BUN_VERSION }}"
commit-message: "[bun] update to ${{ steps.bun-version.outputs.BUN_VERSION }}"
body: |
Update `bun-types` version to ${{ steps.bun-version.outputs.BUN_VERSION }}
https://bun.sh/blog/${{ env.BUN_VERSION }}
push-to-fork: oven-sh/DefinitelyTyped
branch: ${{env.BUN_VERSION}}
docker:
name: Release to Dockerhub
runs-on: ubuntu-latest
@@ -265,7 +311,7 @@ jobs:
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Install Dependencies
run: bun install
- name: Release
@@ -309,7 +355,7 @@ jobs:
uses: ./.github/actions/setup-bun
if: ${{ env.BUN_LATEST == 'true' }}
with:
bun-version: "1.1.44"
bun-version: "1.2.0"
- name: Bump version
uses: ./.github/actions/bump
if: ${{ env.BUN_LATEST == 'true' }}

View File

@@ -4,7 +4,7 @@ permissions:
contents: read
env:
LLVM_VERSION: 16
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
on:
workflow_call:

View File

@@ -9,7 +9,7 @@ on:
required: true
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
bump:

View File

@@ -55,7 +55,7 @@ jobs:
# Convert numeric version to semantic version for display
LATEST_MAJOR=$((10#$LATEST_VERSION_NUM / 1000000))
LATEST_MINOR=$((($LATEST_VERSION_NUM / 1000) % 1000))
LATEST_MINOR=$((($LATEST_VERSION_NUM / 10000) % 100))
LATEST_PATCH=$((10#$LATEST_VERSION_NUM % 1000))
LATEST_VERSION="$LATEST_MAJOR.$LATEST_MINOR.$LATEST_PATCH"

View File

@@ -10,7 +10,7 @@ on:
merge_group:
env:
BUN_VERSION: "1.1.44"
BUN_VERSION: "1.2.0"
jobs:
zig-format:

4
.gitignore vendored
View File

@@ -16,6 +16,7 @@
.vscode/clang*
.vscode/cpp*
.zig-cache
.bake-debug
*.a
*.bc
*.big
@@ -151,6 +152,7 @@ src/bake/generated.ts
test/cli/install/registry/packages/publish-pkg-*
test/cli/install/registry/packages/@secret/publish-pkg-8
test/js/third_party/prisma/prisma/sqlite/dev.db-journal
tmp
# Dependencies
/vendor
@@ -178,4 +180,4 @@ test/js/third_party/prisma/prisma/sqlite/dev.db-journal
.buildkite/ci.yml
*.sock
scratch*.{js,ts,tsx,cjs,mjs}
scratch*.{js,ts,tsx,cjs,mjs}

View File

@@ -7,3 +7,4 @@ src/react-refresh.js
*.min.js
test/snippets
test/js/node/test
bun.lock

View File

@@ -63,6 +63,7 @@
"editor.tabSize": 4,
"editor.defaultFormatter": "xaver.clang-format",
},
"clangd.arguments": ["--header-insertion=never"],
// JavaScript
"prettier.enable": true,
@@ -140,6 +141,7 @@
},
"files.associations": {
"*.idl": "cpp",
"*.mdc": "markdown",
"array": "cpp",
},
"C_Cpp.files.exclude": {

View File

@@ -12,6 +12,12 @@ list(APPEND CMAKE_MODULE_PATH
include(Policies)
include(Globals)
if (CMAKE_HOST_WIN32)
# Workaround for TLS certificate verification issue on Windows when downloading from GitHub
# Remove this once we've bumped the CI machines build image
set(CMAKE_TLS_VERIFY 0)
endif()
# --- Compilers ---
if(CMAKE_HOST_APPLE)

2
LATEST
View File

@@ -1 +1 @@
1.2.0
1.2.2

View File

@@ -1301,6 +1301,7 @@ jsc-build-mac-compile-lto:
.PHONY: jsc-build-mac-compile-debug
jsc-build-mac-compile-debug:
mkdir -p $(WEBKIT_DEBUG_DIR) $(WEBKIT_DIR);
# to disable asan, remove -DENABLE_SANITIZERS=address and add -DENABLE_MALLOC_HEAP_BREAKDOWN=ON
cd $(WEBKIT_DEBUG_DIR) && \
ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \
cmake \
@@ -1309,7 +1310,6 @@ jsc-build-mac-compile-debug:
-DCMAKE_BUILD_TYPE=Debug \
-DUSE_THIN_ARCHIVES=OFF \
-DENABLE_FTL_JIT=ON \
-DENABLE_MALLOC_HEAP_BREAKDOWN=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DUSE_BUN_JSC_ADDITIONS=ON \
-DUSE_BUN_EVENT_LOOP=ON \
@@ -1321,6 +1321,7 @@ jsc-build-mac-compile-debug:
-DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \
-DENABLE_REMOTE_INSPECTOR=ON \
-DUSE_VISIBILITY_ATTRIBUTE=1 \
-DENABLE_SANITIZERS=address \
$(WEBKIT_DIR) \
$(WEBKIT_DEBUG_DIR) && \
CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "expect-to-equal",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "simple-react",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "react-hello-world",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "scan",

View File

@@ -39,24 +39,24 @@ bench("Buffer.from(ArrayBuffer(100))", () => {
return Buffer.from(hundred);
});
bench("new Buffer(ArrayBuffer(100))", () => {
return new Buffer(hundred);
});
var hundredArray = new Uint8Array(100);
bench("Buffer.from(Uint8Array(100))", () => {
return Buffer.from(hundredArray);
});
bench("new Buffer(Uint8Array(100))", () => {
return new Buffer(hundredArray);
});
var empty = new Uint8Array(0);
bench("Buffer.from(Uint8Array(0))", () => {
return Buffer.from(empty);
});
bench("new Buffer(ArrayBuffer(100))", () => {
return new Buffer(hundred);
});
bench("new Buffer(Uint8Array(100))", () => {
return new Buffer(hundredArray);
});
bench("new Buffer(Uint8Array(0))", () => {
return new Buffer(empty);
});

View File

@@ -1,7 +1,7 @@
// import { Buffer } from "buffer";
var buf = new Buffer(1024);
var view = new DataView(buf.buffer);
var INTERVAL = 9999999;
var INTERVAL = 9_999_999;
var time = (name, fn) => {
for (let i = 0; i < INTERVAL; i++) fn();

View File

@@ -0,0 +1,25 @@
import { posix } from "path";
import { bench, run } from "../runner.mjs";
const pathConfigurations = [
["", ""],
[".", "."],
["/foo/bar", "/foo/bar"],
["/foo/bar/baz", "/foo/bar"],
["/foo/bar", "/foo/bar/baz"],
["/foo/bar/baz", "/foo/bar/qux"],
["/foo/bar/baz", "/foo/bar/baz/qux"],
["/foo/bar/baz", "/foo/bar/baz/qux/quux"],
["/", "/foo"],
["/foo", "/"],
["foo/bar/baz", "foo/bar/qux"],
["../foo/bar", "../foo/baz"],
];
pathConfigurations.forEach(([from, to]) => {
bench(`relative(${JSON.stringify(from)}, ${JSON.stringify(to)})`, () => {
globalThis.abc = posix.relative(from, to);
});
});
await run();

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "websocket-server",

View File

@@ -19,7 +19,7 @@ const OperatingSystem = @import("src/env.zig").OperatingSystem;
const pathRel = fs.path.relative;
/// Do not rename this constant. It is scanned by some scripts to determine which zig version to install.
const recommended_zig_version = "0.13.0";
const recommended_zig_version = "0.14.0-dev.2987+183bb8b08";
comptime {
if (!std.mem.eql(u8, builtin.zig_version_string, recommended_zig_version)) {
@@ -46,6 +46,7 @@ const BunBuildOptions = struct {
sha: []const u8,
/// enable debug logs in release builds
enable_logs: bool = false,
enable_asan: bool,
tracy_callstack_depth: u16,
reported_nodejs_version: Version,
/// To make iterating on some '@embedFile's faster, we load them at runtime
@@ -81,10 +82,7 @@ const BunBuildOptions = struct {
var opts = b.addOptions();
opts.addOption([]const u8, "base_path", b.pathFromRoot("."));
opts.addOption([]const u8, "codegen_path", std.fs.path.resolve(b.graph.arena, &.{
b.build_root.path.?,
this.codegen_path,
}) catch @panic("OOM"));
opts.addOption([]const u8, "codegen_path", std.fs.path.resolve(b.graph.arena, &.{ b.build_root.path.?, this.codegen_path }) catch @panic("OOM"));
opts.addOption(bool, "codegen_embed", this.shouldEmbedCode());
opts.addOption(u32, "canary_revision", this.canary_revision orelse 0);
@@ -154,8 +152,6 @@ pub fn build(b: *Build) !void {
std.log.info("zig compiler v{s}", .{builtin.zig_version_string});
checked_file_exists = std.AutoHashMap(u64, void).init(b.allocator);
b.zig_lib_dir = b.zig_lib_dir orelse b.path("vendor/zig/lib");
// TODO: Upgrade path for 0.14.0
// b.graph.zig_lib_directory = brk: {
// const sub_path = "vendor/zig/lib";
@@ -209,7 +205,7 @@ pub fn build(b: *Build) !void {
const bun_version = b.option([]const u8, "version", "Value of `Bun.version`") orelse "0.0.0";
b.reference_trace = ref_trace: {
const trace = b.option(u32, "reference-trace", "Set the reference trace") orelse 16;
const trace = b.option(u32, "reference-trace", "Set the reference trace") orelse 24;
break :ref_trace if (trace == 0) null else trace;
};
@@ -277,6 +273,7 @@ pub fn build(b: *Build) !void {
.tracy_callstack_depth = b.option(u16, "tracy_callstack_depth", "") orelse 10,
.enable_logs = b.option(bool, "enable_logs", "Enable logs in release") orelse false,
.enable_asan = b.option(bool, "enable_asan", "Enable asan") orelse false,
};
// zig build obj
@@ -331,11 +328,25 @@ pub fn build(b: *Build) !void {
.{ .os = .windows, .arch = .x86_64 },
});
}
{
const step = b.step("check-macos", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
});
}
{
const step = b.step("check-linux", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .linux, .arch = .x86_64 },
.{ .os = .linux, .arch = .aarch64 },
});
}
// zig build translate-c-headers
{
const step = b.step("translate-c", "Copy generated translated-c-headers.zig to zig-out");
step.dependOn(&b.addInstallFile(getTranslateC(b, b.host, .Debug).getOutput(), "translated-c-headers.zig").step);
step.dependOn(&b.addInstallFile(getTranslateC(b, b.graph.host, .Debug).getOutput(), "translated-c-headers.zig").step);
}
// zig build enum-extractor
@@ -363,7 +374,7 @@ pub fn addMultiCheck(
const check_target = b.resolveTargetQuery(.{
.os_tag = OperatingSystem.stdOSTag(check.os),
.cpu_arch = check.arch,
.cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_cpu_arch,
.cpu_model = getCpuModel(check.os, check.arch) orelse .determined_by_arch_os,
.os_version_min = getOSVersionMin(check.os),
.glibc_version = if (check.musl) null else getOSGlibCVersion(check.os),
});
@@ -381,6 +392,7 @@ pub fn addMultiCheck(
.reported_nodejs_version = root_build_options.reported_nodejs_version,
.codegen_path = root_build_options.codegen_path,
.no_llvm = root_build_options.no_llvm,
.enable_asan = root_build_options.enable_asan,
};
var obj = addBunObject(b, &options);
@@ -414,7 +426,7 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
.name = if (opts.optimize == .Debug) "bun-debug" else "bun",
.root_source_file = switch (opts.os) {
.wasm => b.path("root_wasm.zig"),
else => b.path("root.zig"),
else => b.path("src/main.zig"),
// else => b.path("root_css.zig"),
},
.target = opts.target,
@@ -428,8 +440,15 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
.omit_frame_pointer = false,
.strip = false, // stripped at the end
});
if (opts.enable_asan) {
if (@hasField(Build.Module, "sanitize_address")) {
obj.root_module.sanitize_address = true;
} else {
const fail_step = b.addFail("asan is not supported on this platform");
obj.step.dependOn(&fail_step.step);
}
}
obj.bundle_compiler_rt = false;
obj.formatted_panics = true;
obj.root_module.omit_frame_pointer = false;
// Link libc
@@ -497,16 +516,6 @@ fn exists(path: []const u8) bool {
fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
const os = opts.os;
const io_path = switch (os) {
.mac => "src/io/io_darwin.zig",
.linux => "src/io/io_linux.zig",
.windows => "src/io/io_windows.zig",
else => "src/io/io_stub.zig",
};
obj.root_module.addAnonymousImport("async_io", .{
.root_source_file = b.path(io_path),
});
const zlib_internal_path = switch (os) {
.windows => "src/deps/zlib.win32.zig",
.linux, .mac => "src/deps/zlib.posix.zig",
@@ -539,6 +548,7 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
.{ .file = "bun-error/index.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bun-error/bun-error.css", .enable = opts.shouldEmbedCode() },
.{ .file = "fallback-decoder.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/react-refresh.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/assert.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/buffer.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/console.js", .enable = opts.shouldEmbedCode() },
@@ -575,6 +585,15 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
});
}
}
inline for (.{
.{ .import = "completions-bash", .file = b.path("completions/bun.bash") },
.{ .import = "completions-zsh", .file = b.path("completions/bun.zsh") },
.{ .import = "completions-fish", .file = b.path("completions/bun.fish") },
}) |entry| {
obj.root_module.addAnonymousImport(entry.import, .{
.root_source_file = entry.file,
});
}
if (os == .windows) {
obj.root_module.addAnonymousImport("bun_shim_impl.exe", .{
@@ -614,7 +633,7 @@ const WindowsShim = struct {
.optimize = .ReleaseFast,
.use_llvm = true,
.use_lld = true,
.unwind_tables = false,
.unwind_tables = .none,
.omit_frame_pointer = true,
.strip = true,
.linkage = .static,

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun",
@@ -45,21 +45,21 @@
"packages": {
"@biomejs/biome": ["@biomejs/biome@1.8.3", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.8.3", "@biomejs/cli-darwin-x64": "1.8.3", "@biomejs/cli-linux-arm64": "1.8.3", "@biomejs/cli-linux-arm64-musl": "1.8.3", "@biomejs/cli-linux-x64": "1.8.3", "@biomejs/cli-linux-x64-musl": "1.8.3", "@biomejs/cli-win32-arm64": "1.8.3", "@biomejs/cli-win32-x64": "1.8.3" }, "bin": { "biome": "bin/biome" } }, "sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.8.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.8.3", "", { "os":"darwin", "cpu":"arm64" }, "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.8.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.8.3", "", { "os":"darwin", "cpu":"x64" }, "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.8.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.8.3", "", { "os":"linux", "cpu":"arm64" }, "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.8.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.8.3", "", { "os":"linux", "cpu":"arm64" }, "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.8.3", "", { "os": "linux", "cpu": "x64" }, "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.8.3", "", { "os":"linux", "cpu":"x64" }, "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.8.3", "", { "os": "linux", "cpu": "x64" }, "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.8.3", "", { "os":"linux", "cpu":"x64" }, "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.8.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.8.3", "", { "os":"win32", "cpu":"arm64" }, "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.8.3", "", { "os": "win32", "cpu": "x64" }, "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.8.3", "", { "os":"win32", "cpu":"x64" }, "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg=="],
"@definitelytyped/dts-critic": ["@definitelytyped/dts-critic@0.0.191", "", { "dependencies": { "@definitelytyped/header-parser": "0.0.190", "command-exists": "^1.2.9", "semver": "^7.5.4", "tmp": "^0.2.1", "typescript": "^5.2.2", "yargs": "^17.7.2" } }, "sha512-j5HK3pQYiQwSXRLJzyhXJ6KxdzLl4gXXhz3ysCtLnRQkj+zsEfloDkEZ3x2bZMWS0OsKLXmR91JeQ2/c9DFEjg=="],
@@ -75,51 +75,51 @@
"@es-joy/jsdoccomment": ["@es-joy/jsdoccomment@0.39.4", "", { "dependencies": { "comment-parser": "1.3.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" } }, "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os":"aix", "cpu":"ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os":"android", "cpu":"arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os":"android", "cpu":"arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os":"android", "cpu":"x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os":"darwin", "cpu":"arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os":"darwin", "cpu":"x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os":"freebsd", "cpu":"arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os":"freebsd", "cpu":"x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os":"linux", "cpu":"arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os":"linux", "cpu":"arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os":"linux", "cpu":"ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os":"linux", "cpu":"ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os":"linux", "cpu":"s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os":"linux", "cpu":"x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os":"none", "cpu":"x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os":"openbsd", "cpu":"x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os":"sunos", "cpu":"x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os":"win32", "cpu":"arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os":"win32", "cpu":"ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os":"win32", "cpu":"x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.0", "", { "dependencies": { "eslint-visitor-keys": "^3.3.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA=="],
@@ -257,7 +257,7 @@
"builtins": ["builtins@1.0.3", "", {}, "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ=="],
"bun-types": ["bun-types@workspace:packages/bun-types", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" }, "devDependencies": { "@biomejs/biome": "^1.5.3", "@definitelytyped/dtslint": "^0.0.199", "@definitelytyped/eslint-plugin": "^0.0.197", "typescript": "^5.0.2" } }],
"bun-types": ["bun-types@workspace:packages/bun-types"],
"call-bind": ["call-bind@1.0.7", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.1" } }, "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w=="],
@@ -265,7 +265,7 @@
"camel-case": ["camel-case@4.1.2", "", { "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw=="],
"caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"caniuse-lite": ["caniuse-lite@1.0.30001695", "", {}, "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw=="],
"capital-case": ["capital-case@1.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A=="],
@@ -923,10 +923,14 @@
"are-we-there-yet/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"babel-code-frame/chalk": ["chalk@1.1.3", "", { "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="],
"babel-code-frame/js-tokens": ["js-tokens@3.0.2", "", {}, "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg=="],
"browserslist/caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="],
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],

View File

@@ -44,6 +44,13 @@ if(WIN32)
)
endif()
if(ENABLE_ASAN)
register_compiler_flags(
DESCRIPTION "Enable AddressSanitizer"
-fsanitize=address
)
endif()
# --- Optimization level ---
if(DEBUG)
register_compiler_flags(

View File

@@ -86,6 +86,11 @@ optionx(ENABLE_LTO BOOL "If LTO (link-time optimization) should be used" DEFAULT
if(LINUX)
optionx(ENABLE_VALGRIND BOOL "If Valgrind support should be enabled" DEFAULT OFF)
endif()
if(DEBUG AND APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
optionx(ENABLE_ASAN BOOL "If ASAN support should be enabled" DEFAULT ON)
else()
optionx(ENABLE_ASAN BOOL "If ASAN support should be enabled" DEFAULT OFF)
endif()
optionx(ENABLE_PRETTIER BOOL "If prettier should be ran" DEFAULT OFF)

View File

@@ -28,7 +28,12 @@ else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
endif()
set(ZIG_NAME zig-${ZIG_OS}-${ZIG_ARCH}-${ZIG_VERSION})
set(ZIG_ASAN "")
if(ENABLE_ASAN)
set(ZIG_ASAN "+asan")
endif()
set(ZIG_NAME zig-${ZIG_OS}-${ZIG_ARCH}-${ZIG_VERSION}${ZIG_ASAN})
if(CMAKE_HOST_WIN32)
set(ZIG_EXE "zig.exe")
@@ -38,7 +43,7 @@ else()
set(ZIG_FILENAME ${ZIG_NAME}.tar.xz)
endif()
set(ZIG_DOWNLOAD_URL https://ziglang.org/download/${ZIG_VERSION}/${ZIG_FILENAME})
set(ZIG_DOWNLOAD_URL https://bun-ci-assets.bun.sh/${ZIG_FILENAME})
execute_process(
COMMAND

View File

@@ -179,6 +179,32 @@ register_command(
${BUN_NODE_FALLBACKS_OUTPUTS}
)
# An embedded copy of react-refresh is used when the user forgets to install it.
# The library is not versioned alongside React.
set(BUN_REACT_REFRESH_OUTPUT ${BUN_NODE_FALLBACKS_OUTPUT}/react-refresh.js)
register_command(
TARGET
bun-node-fallbacks-react-refresh
COMMENT
"Building node-fallbacks/react-refresh.js"
CWD
${BUN_NODE_FALLBACKS_SOURCE}
COMMAND
${BUN_EXECUTABLE} build
${BUN_NODE_FALLBACKS_SOURCE}/node_modules/react-refresh/cjs/react-refresh-runtime.development.js
--outfile=${BUN_REACT_REFRESH_OUTPUT}
--target=browser
--format=cjs
--minify
--define:process.env.NODE_ENV=\"'development'\"
SOURCES
${BUN_NODE_FALLBACKS_SOURCE}/package.json
${BUN_NODE_FALLBACKS_SOURCE}/bun.lock
${BUN_NODE_FALLBACKS_NODE_MODULES}
OUTPUTS
${BUN_REACT_REFRESH_OUTPUT}
)
set(BUN_ERROR_CODE_SCRIPT ${CWD}/src/codegen/generate-node-errors.ts)
set(BUN_ERROR_CODE_SOURCES
@@ -404,6 +430,7 @@ set(BUN_OBJECT_LUT_SOURCES
${CWD}/src/bun.js/bindings/ZigGlobalObject.lut.txt
${CWD}/src/bun.js/bindings/JSBuffer.cpp
${CWD}/src/bun.js/bindings/BunProcess.cpp
${CWD}/src/bun.js/bindings/ProcessBindingBuffer.cpp
${CWD}/src/bun.js/bindings/ProcessBindingConstants.cpp
${CWD}/src/bun.js/bindings/ProcessBindingNatives.cpp
${CWD}/src/bun.js/modules/NodeModuleModule.cpp
@@ -415,6 +442,7 @@ set(BUN_OBJECT_LUT_OUTPUTS
${CODEGEN_PATH}/ZigGlobalObject.lut.h
${CODEGEN_PATH}/JSBuffer.lut.h
${CODEGEN_PATH}/BunProcess.lut.h
${CODEGEN_PATH}/ProcessBindingBuffer.lut.h
${CODEGEN_PATH}/ProcessBindingConstants.lut.h
${CODEGEN_PATH}/ProcessBindingNatives.lut.h
${CODEGEN_PATH}/NodeModuleModule.lut.h
@@ -498,8 +526,7 @@ file(GLOB_RECURSE BUN_ZIG_SOURCES ${CONFIGURE_DEPENDS}
list(APPEND BUN_ZIG_SOURCES
${CWD}/build.zig
${CWD}/root.zig
${CWD}/root_wasm.zig
${CWD}/src/main.zig
${BUN_BINDGEN_ZIG_OUTPUTS}
)
@@ -508,6 +535,7 @@ set(BUN_ZIG_GENERATED_SOURCES
${BUN_FALLBACK_DECODER_OUTPUT}
${BUN_RUNTIME_JS_OUTPUT}
${BUN_NODE_FALLBACKS_OUTPUTS}
${BUN_REACT_REFRESH_OUTPUT}
${BUN_ERROR_CODE_OUTPUTS}
${BUN_ZIG_GENERATED_CLASSES_OUTPUTS}
${BUN_JAVASCRIPT_OUTPUTS}
@@ -827,6 +855,15 @@ if(NOT WIN32)
)
endif()
if (ENABLE_ASAN)
target_compile_options(${bun} PUBLIC
-fsanitize=address
)
target_link_libraries(${bun} PUBLIC
-fsanitize=address
)
endif()
target_compile_options(${bun} PUBLIC
-Werror=return-type
-Werror=return-stack-address
@@ -1052,6 +1089,7 @@ add_custom_target(dependencies DEPENDS ${BUN_TARGETS})
if(APPLE)
target_link_libraries(${bun} PRIVATE icucore resolv)
target_compile_definitions(${bun} PRIVATE U_DISABLE_RENAMING=1)
endif()
if(USE_STATIC_SQLITE)

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/mimalloc
COMMIT
82b2c2277a4d570187c07b376557dc5bde81d848
1beadf9651a7bfdec6b5367c380ecc3fe1c40d1a
)
set(MIMALLOC_CMAKE_ARGS
@@ -19,6 +19,10 @@ set(MIMALLOC_CMAKE_ARGS
-DMI_SKIP_COLLECT_ON_EXIT=ON
)
if(ENABLE_ASAN)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_TRACK_ASAN=ON)
endif()
if(DEBUG)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_DEBUG_FULL=ON)
endif()

View File

@@ -9,6 +9,14 @@ find_command(
>=1.1.26
)
if (NOT CI)
# If node.js is not installed, it is extremely easy to make this path point to
# a tempdir such as /private/tmp/bun-node-ce532901c/bun, which may cause this
# CMake configuration break after tempdir is cleaned up (ex. after reboot).
get_filename_component(BUN_EXECUTABLE ${BUN_EXECUTABLE} REALPATH)
set(BUN_EXECUTABLE ${BUN_EXECUTABLE} CACHE FILEPATH "Bun executable" FORCE)
endif()
# If this is not set, some advanced features are not checked.
# https://github.com/oven-sh/bun/blob/cd7f6a1589db7f1e39dc4e3f4a17234afbe7826c/src/bun.js/javascript.zig#L1069-L1072
setenv(BUN_GARBAGE_COLLECTOR_LEVEL 1)

View File

@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION e6cb36cabed465c28c7bcbb28d86e8466ea36e8d)
set(WEBKIT_VERSION 57004f91903936881b3301594d9d67708f1ff64c)
endif()
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
@@ -79,6 +79,10 @@ else()
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}")
endif()
if(ENABLE_ASAN)
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-asan")
endif()
set(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX})
set(WEBKIT_FILENAME ${WEBKIT_NAME}.tar.gz)
setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/autobuild-${WEBKIT_VERSION}/${WEBKIT_FILENAME})

View File

@@ -20,8 +20,8 @@ else()
unsupported(CMAKE_SYSTEM_NAME)
endif()
optionx(ZIG_VERSION STRING "The zig version of the compiler to download" DEFAULT "0.13.0")
optionx(ZIG_COMMIT STRING "The zig commit to use in oven-sh/zig" DEFAULT "131a009ba2eb127a3447d05b9e12f710429aa5ee")
optionx(ZIG_VERSION STRING "The zig version of the compiler to download" DEFAULT "0.14.0-dev.2987+183bb8b08")
optionx(ZIG_COMMIT STRING "The zig commit to use in oven-sh/zig" DEFAULT "02c57c7ee3b8fde7528c74dd06490834d2d6fae9")
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
if(CMAKE_BUILD_TYPE STREQUAL "Release")
@@ -79,6 +79,7 @@ register_command(
-DZIG_PATH=${ZIG_PATH}
-DZIG_VERSION=${ZIG_VERSION}
-DZIG_COMMIT=${ZIG_COMMIT}
-DENABLE_ASAN=${ENABLE_ASAN}
-P ${CWD}/cmake/scripts/DownloadZig.cmake
SOURCES
${CWD}/cmake/scripts/DownloadZig.cmake

View File

@@ -67,14 +67,18 @@ ARG BUN_INSTALL_BIN=/usr/local/bin
ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN}
COPY --from=build /usr/local/bin/bun /usr/local/bin/
RUN mkdir -p /usr/local/bun-node-fallback-bin && ln -s /usr/local/bin/bun /usr/local/bun-node-fallback-bin/node
ENV PATH "${PATH}:/usr/local/bun-node-fallback-bin"
# Temporarily use the `build`-stage image binaries to create a symlink:
RUN --mount=type=bind,from=build,source=/usr/bin,target=/usr/bin \
--mount=type=bind,from=build,source=/bin,target=/bin <<EOF
--mount=type=bind,from=build,source=/bin,target=/bin \
--mount=type=bind,from=build,source=/usr/lib,target=/usr/lib \
--mount=type=bind,from=build,source=/lib,target=/lib \
<<EOF
ln -s /usr/local/bin/bun /usr/local/bin/bunx
which bunx
mkdir -p /usr/local/bun-node-fallback-bin
ln -s /usr/local/bin/bun /usr/local/bun-node-fallback-bin/nodebun
EOF
ENTRYPOINT ["/usr/local/bin/bun"]

View File

@@ -196,6 +196,8 @@ import icon from "./icon.png" with { type: "file" };
import { file } from "bun";
const bytes = await file(icon).arrayBuffer();
// await fs.promises.readFile(icon)
// fs.readFileSync(icon)
```
### Embed SQLite databases

View File

@@ -1,6 +1,6 @@
As of Bun v1.1.44, we've added initial support for bundling frontend apps directly in Bun's HTTP server: `Bun.serve()`. Run your frontend and backend in the same app with no extra steps.
Using `Bun.serve()`'s `static` option, you can run your frontend and backend in the same app with no extra steps.
To get started, import your HTML files and pass them to the `static` option in `Bun.serve()`.
To get started, import HTML files and pass them to the `static` option in `Bun.serve()`.
```ts
import dashboard from "./dashboard.html";
@@ -33,7 +33,7 @@ const server = Bun.serve({
},
});
console.log(`Listening on ${server.url}`)
console.log(`Listening on ${server.url}`);
```
```bash
@@ -211,6 +211,7 @@ For example, enable TailwindCSS on your routes by installing and adding the `bun
```sh
$ bun add bun-plugin-tailwind
```
```toml#bunfig.toml
[serve.static]
plugins = ["bun-plugin-tailwind"]

View File

@@ -1,4 +1,4 @@
As of Bun v1.1.43, Bun's bundler now has first-class support for HTML. Build static sites, landing pages, and web applications with zero configuration. Just point Bun at your HTML file and it handles everything else.
Bun's bundler has first-class support for HTML. Build static sites, landing pages, and web applications with zero configuration. Just point Bun at your HTML file and it handles everything else.
```html#index.html
<!doctype html>
@@ -13,45 +13,228 @@ As of Bun v1.1.43, Bun's bundler now has first-class support for HTML. Build sta
</html>
```
One command is all you need (won't be experimental after Bun v1.2):
To get started, pass HTML files to `bun`.
{% bunDevServerTerminal alt="bun ./index.html" path="./index.html" routes="" /%}
Bun's development server provides powerful features with zero configuration:
- **Automatic Bundling** - Bundles and serves your HTML, JavaScript, and CSS
- **Multi-Entry Support** - Handles multiple HTML entry points and glob entry points
- **Modern JavaScript** - TypeScript & JSX support out of the box
- **Smart Configuration** - Reads `tsconfig.json` for paths, JSX options, experimental decorators, and more
- **Plugins** - Plugins for TailwindCSS and more
- **ESM & CommonJS** - Use ESM and CommonJS in your JavaScript, TypeScript, and JSX files
- **CSS Bundling & Minification** - Bundles CSS from `<link>` tags and `@import` statements
- **Asset Management**
- Automatic copying & hashing of images and assets
- Rewrites asset paths in JavaScript, CSS, and HTML
## Single Page Apps (SPA)
When you pass a single .html file to Bun, Bun will use it as a fallback route for all paths. This makes it perfect for single page apps that use client-side routing:
{% bunDevServerTerminal alt="bun index.html" path="index.html" routes="" /%}
Your React or other SPA will work out of the box — no configuration needed. All routes like `/about`, `/users/123`, etc. will serve the same HTML file, letting your client-side router handle the navigation.
```html#index.html
<!doctype html>
<html>
<head>
<title>My SPA</title>
<script src="./app.tsx" type="module"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
```
## Multi-page apps (MPA)
Some projects have several separate routes or HTML files as entry points. To support multiple entry points, pass them all to `bun`
{% bunDevServerTerminal alt="bun ./index.html ./about.html" path="./index.html ./about.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about.html\"}]" /%}
This will serve:
- `index.html` at `/`
- `about.html` at `/about`
### Glob patterns
To specify multiple files, you can use glob patterns that end in `.html`:
{% bunDevServerTerminal alt="bun ./**/*.html" path="./**/*.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about.html\"}]" /%}
### Path normalization
The base path is chosen from the longest common prefix among all the files.
{% bunDevServerTerminal alt="bun ./index.html ./about/index.html ./about/foo/index.html" path="./index.html ./about/index.html ./about/foo/index.html" routes="[{\"path\": \"/\", \"file\": \"./index.html\"}, {\"path\": \"/about\", \"file\": \"./about/index.html\"}, {\"path\": \"/about/foo\", \"file\": \"./about/foo/index.html\"}]" /%}
## JavaScript, TypeScript, and JSX
Bun's transpiler natively implements JavaScript, TypeScript, and JSX support. [Learn more about loaders in Bun](/docs/bundler/loaders).
Bun's transpiler is also used at runtime.
### ES Modules & CommonJS
You can use ESM and CJS in your JavaScript, TypeScript, and JSX files. Bun will handle the transpilation and bundling automatically.
There is no pre-build or separate optimization step. It's all done at the same time.
Learn more about [module resolution in Bun](/docs/runtime/modules).
## CSS
Bun's CSS parser is also natively implemented (clocking in around 58,000 lines of Zig).
It's also a CSS bundler. You can use `@import` in your CSS files to import other CSS files.
For example:
```css#styles.css
@import "./abc.css";
.container {
background-color: blue;
}
```
```css#abc.css
body {
background-color: red;
}
```
This outputs:
```css#styles.css
body {
background-color: red;
}
.container {
background-color: blue;
}
```
### Referencing local assets in CSS
You can reference local assets in your CSS files.
```css#styles.css
body {
background-image: url("./logo.png");
}
```
This will copy `./logo.png` to the output directory and rewrite the path in the CSS file to include a content hash.
```css#styles.css
body {
background-image: url("./logo-[ABC123].png");
}
```
### Importing CSS in JavaScript
To associate a CSS file with a JavaScript file, you can import it in your JavaScript file.
```ts#app.ts
import "./styles.css";
import "./more-styles.css";
```
This generates `./app.css` and `./app.js` in the output directory. All CSS files imported from JavaScript will be bundled into a single CSS file per entry point. If you import the same CSS file from multiple JavaScript files, it will only be included once in the output CSS file.
## Plugins
The dev server supports plugins.
### Tailwind CSS
To use TailwindCSS, install the `bun-plugin-tailwind` plugin:
```bash
# Or any npm client
$ bun install --dev bun-plugin-tailwind
```
Then, add the plugin to your `bunfig.toml`:
```toml
[serve.static]
plugins = ["bun-plugin-tailwind"]
```
Then, reference TailwindCSS in your HTML via `<link>` tag, `@import` in CSS, or `import` in JavaScript.
{% codetabs %}
```html#index.html
<!-- Reference TailwindCSS in your HTML -->
<link rel="stylesheet" href="tailwindcss" />
```
```css#styles.css
/* Import TailwindCSS in your CSS */
@import "tailwindcss";
```
```ts#app.ts
/* Import TailwindCSS in your JavaScript */
import "tailwindcss";
```
{% /codetabs %}
Only one of those are necessary, not all three.
## Keyboard Shortcuts
While the server is running:
- `o + Enter` - Open in browser
- `c + Enter` - Clear console
- `q + Enter` (or Ctrl+C) - Quit server
## Build for Production
When you're ready to deploy, use `bun build` to create optimized production bundles:
{% codetabs %}
```bash#CLI
$ bun build ./index.html --outdir=dist
$ bun build ./index.html --minify --outdir=dist
```
```ts#API
Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
minify: {
whitespace: true,
identifiers: true,
syntax: true,
}
});
```
{% /codetabs %}
Bun automatically:
Currently, plugins are only supported through `Bun.build`'s API or through `bunfig.toml` with the frontend dev server - not yet supported in `bun build`'s CLI.
- Bundles, tree-shakes, and optimizes your JavaScript, JSX and TypeScript
- Bundles and optimizes your CSS
- Copies & hashes images and other assets
- Updates all references to local files or packages in your HTML
### Watch Mode
## Zero Config, Maximum Performance
The HTML bundler is enabled by default after Bun v1.2+. Drop in your existing HTML files and Bun will handle:
- **TypeScript & JSX** - Write modern JavaScript for browsers without the setup
- **CSS** - Bundle CSS stylesheets directly from `<link rel="stylesheet">` or `@import`
- **Images & Assets** - Automatic copying & hashing & rewriting of assets in JavaScript, CSS, and HTML
## Watch mode
You can run `bun build --watch` to watch for changes and rebuild automatically.
You can run `bun build --watch` to watch for changes and rebuild automatically. This works nicely for library development.
You've never seen a watch mode this fast.
## Plugin API
### Plugin API
Need more control? Configure the bundler through the JavaScript API and use Bun's builtin `HTMLRewriter` to preprocess HTML.
@@ -102,3 +285,22 @@ Bun automatically handles all common web assets:
- Any `<link>` tag with an `href` attribute pointing to a local file is rewritten to the new path, and hashed
All paths are resolved relative to your HTML file, making it easy to organize your project however you want.
## This is a work in progress
- No HMR support yet
- Need more plugins
- Need more configuration options for things like asset handling
- Need a way to configure CORS, headers, etc.
If you want to submit a PR, most of the [code is here](https://github.com/oven-sh/bun/blob/main/src/js/internal/html.ts). You could even copy paste that file into your project and use it as a starting point.
## How this works
This is a small wrapper around Bun's support for HTML imports in JavaScript.
### Adding a backend to your frontend
To add a backend to your frontend, you can use the `"static"` option in `Bun.serve`.
Learn more in [the full-stack docs](/docs/bundler/fullstack).

View File

@@ -1629,3 +1629,5 @@ declare class ResolveMessage {
toString(): string;
}
```
{% bunCLIUsage command="build" /%}

View File

@@ -192,8 +192,6 @@ Otherwise, the database to embed is copied into the `outdir` with a hashed filen
### `html`
**HTML loader**. Default for `.html` after Bun v1.2.0.
The html loader processes HTML files and bundles any referenced assets. It will:
- Bundle and hash referenced JavaScript files (`<script src="...">`)

View File

@@ -169,3 +169,5 @@ This will add the following line to your `package.json`:
}
}
```
{% bunCLIUsage command="add" /%}

View File

@@ -2,10 +2,97 @@
**Note** You dont need `bun create` to use Bun. You dont need any configuration at all. This command exists to make getting started a bit quicker and easier.
{% /callout %}
Template a new Bun project with `bun create`. This is a flexible command that can be used to create a new project with a `create-<template>` npm package, a GitHub repo, or a local template.
Template a new Bun project with `bun create`. This is a flexible command that can be used to create a new project from a React component, a `create-<template>` npm package, a GitHub repo, or a local template.
If you're looking to create a brand new empty project, use [`bun init`](https://bun.sh/docs/cli/init).
## From a React component
`bun create ./MyComponent.tsx` turns an existing React component into a complete dev environment with hot reload and production builds in one command.
```bash
$ bun create ./MyComponent.jsx # .tsx also supported
```
{% raw %}
<video style="aspect-ratio: 2062 / 1344; width: 100%; height: 100%; object-fit: contain;" loop autoplay muted playsinline>
<source src="/bun-create-shadcn.mp4" style="width: 100%; height: 100%; object-fit: contain;" type="video/mp4">
</video>
{% /raw %}
{% callout %}
🚀 **Create React App Successor**`bun create <component>` provides everything developers loved about Create React App, but with modern tooling, faster builds, and backend support.
{% /callout %}
#### How this works
When you run `bun create <component>`, Bun:
1. Uses [Bun's JavaScript bundler](https://bun.sh/docs/bundler) to analyze your module graph.
2. Collects all the dependencies needed to run the component.
3. Scans the exports of the entry point for a React component.
4. Generates a `package.json` file with the dependencies and scripts needed to run the component.
5. Installs any missing dependencies using [`bun install --only-missing`](https://bun.sh/docs/cli/install).
6. Generates the following files:
- `${component}.html`
- `${component}.client.tsx` (entry point for the frontend)
- `${component}.css` (css file)
7. Starts a frontend dev server automatically.
### Using TailwindCSS with Bun
[TailwindCSS](https://tailwindcss.com/) is an extremely popular utility-first CSS framework used to style web applications.
When you run `bun create <component>`, Bun scans your JSX/TSX file for TailwindCSS class names (and any files it imports). If it detects TailwindCSS class names, it will add the following dependencies to your `package.json`:
```json#package.json
{
"dependencies": {
"tailwindcss": "^4",
"bun-plugin-tailwind": "latest"
}
}
```
We also configure `bunfig.toml` to use Bun's TailwindCSS plugin with `Bun.serve()`
```toml#bunfig.toml
[serve.static]
plugins = ["bun-plugin-tailwind"]
```
And a `${component}.css` file with `@import "tailwindcss";` at the top:
```css#MyComponent.css
@import "tailwindcss";
```
### Using `shadcn/ui` with Bun
[`shadcn/ui`](https://ui.shadcn.com/) is an extremely popular component library tool for building web applications.
`bun create <component>` scans for any shadcn/ui components imported from `@/components/ui`.
If it finds any, it runs:
```bash
# Assuming bun detected imports to @/components/ui/accordion and @/components/ui/button
$ bunx shadcn@canary add accordion button # and any other components
```
Since `shadcn/ui` itself uses TailwindCSS, `bun create` also adds the necessary TailwindCSS dependencies to your `package.json` and configures `bunfig.toml` to use Bun's TailwindCSS plugin with `Bun.serve()` as described above.
Additionally, we setup the following:
- `tsconfig.json` to alias `"@/*"` to `"src/*"` or `.` (depending on if there is a `src/` directory)
- `components.json` so that shadcn/ui knows its a shadcn/ui project
- `styles/globals.css` file that configures Tailwind v4 in the way that shadcn/ui expects
- `${component}.build.ts` file that builds the component for production with `bun-plugin-tailwind` configured
`bun create ./MyComponent.jsx` is one of the easiest ways to run code generated from LLMs like [Claude](https://claude.ai) or ChatGPT locally.
## From `npm`
```sh

View File

@@ -1,21 +0,0 @@
In your project folder root (where `package.json` is):
```bash
$ bun bun ./entry-point-1.js ./entry-point-2.jsx
$ bun dev
```
By default, `bun dev` will look for any HTML files in the `public` directory and serve that. For browsers navigating to the page, the `.html` file extension is optional in the URL, and `index.html` will automatically rewrite for the directory.
Here are examples of routing from `public/` and how theyre matched:
| Dev Server URL | File Path |
|----------------|-----------|
| /dir | public/dir/index.html |
| / | public/index.html |
| /index | public/index.html |
| /hi | public/hi.html |
| /file | public/file.html |
| /font/Inter.woff2 | public/font/Inter.woff2 |
| /hello | public/index.html |
If `public/index.html` exists, it becomes the default page instead of a 404 page, unless that pathname has a file extension.

View File

@@ -38,3 +38,5 @@ If you pass `-y` or `--yes`, it will assume you want to continue without asking
At the end, it runs `bun install` to install `@types/bun`.
{% /details %}
{% bunCLIUsage command="init" /%}

View File

@@ -235,3 +235,5 @@ jobs:
- name: Build app
run: bun run build
```
{% bunCLIUsage command="install" /%}

View File

@@ -36,3 +36,5 @@ In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencie
}
}
```
{% bunCLIUsage command="link" /%}

View File

@@ -1,63 +1,47 @@
Use `bun outdated` to display a table of outdated dependencies with their latest versions for the current workspace:
Use `bun outdated` to check for outdated dependencies in your project. This command displays a table of dependencies that have newer versions available.
```sh
$ bun outdated
{% bunOutdatedTerminal displayGlob="" filter="" glob="" /%}
|--------------------------------------------------------------------|
| Package | Current | Update | Latest |
|----------------------------------------|---------|--------|--------|
| @types/bun (dev) | 1.1.6 | 1.1.7 | 1.1.7 |
|----------------------------------------|---------|--------|--------|
| @types/react (dev) | 18.3.3 | 18.3.4 | 18.3.4 |
|----------------------------------------|---------|--------|--------|
| @typescript-eslint/eslint-plugin (dev) | 7.16.1 | 7.18.0 | 8.2.0 |
|----------------------------------------|---------|--------|--------|
| @typescript-eslint/parser (dev) | 7.16.1 | 7.18.0 | 8.2.0 |
|----------------------------------------|---------|--------|--------|
| esbuild (dev) | 0.21.5 | 0.21.5 | 0.23.1 |
|----------------------------------------|---------|--------|--------|
| eslint (dev) | 9.7.0 | 9.9.1 | 9.9.1 |
|----------------------------------------|---------|--------|--------|
| typescript (dev) | 5.5.3 | 5.5.4 | 5.5.4 |
|--------------------------------------------------------------------|
```
## Version Information
The `Update` column shows the version that would be installed if you ran `bun update [package]`. This version is the latest version that satisfies the version range specified in your `package.json`.
The output table shows three version columns:
The `Latest` column shows the latest version available from the registry. `bun update --latest [package]` will update to this version.
- **Current**: The version currently installed
- **Update**: The latest version that satisfies your package.json version range
- **Latest**: The latest version published to the registry
Dependency names can be provided to filter the output (pattern matching is supported):
### Dependency Filters
```sh
$ bun outdated "@types/*"
`bun outdated` supports searching for outdated dependencies by package names and glob patterns.
|------------------------------------------------|
| Package | Current | Update | Latest |
|--------------------|---------|--------|--------|
| @types/bun (dev) | 1.1.6 | 1.1.8 | 1.1.8 |
|--------------------|---------|--------|--------|
| @types/react (dev) | 18.3.3 | 18.3.4 | 18.3.4 |
|------------------------------------------------|
```
To check if specific dependencies are outdated, pass the package names as positional arguments:
## `--filter`
{% bunOutdatedTerminal displayGlob="eslint-plugin-security eslint-plugin-sonarjs" glob="eslint-plugin-*" /%}
The `--filter` flag can be used to select workspaces to include in the output. Workspace names or paths can be used as patterns.
You can also pass glob patterns to check for outdated packages:
```sh
$ bun outdated --filter <pattern>
```
{% bunOutdatedTerminal displayGlob="'eslint*'" glob="eslint*" /%}
For example, to only show outdated dependencies for workspaces in the `./apps` directory:
For example, to check for outdated `@types/*` packages:
```sh
$ bun outdated --filter './apps/*'
```
{% bunOutdatedTerminal displayGlob="'@types/*'" glob="@types/*" /%}
If you want to do the same, but exclude the `./apps/api` workspace:
Or to exclude all `@types/*` packages:
```sh
$ bun outdated --filter './apps/*' --filter '!./apps/api'
```
{% bunOutdatedTerminal displayGlob="'!@types/*'" glob="!@types/*" /%}
Refer to [Package Manager > Filtering](https://bun.sh/docs/cli/filter#bun-install-and-bun-outdated) for more information on `--filter`.
### Workspace Filters
Use the `--filter` flag to check for outdated dependencies in a different workspace package:
{% bunOutdatedTerminal glob="t*" filter="@monorepo/types" /%}
You can pass multiple `--filter` flags to check multiple workspaces:
{% bunOutdatedTerminal glob="{e,t}*" displayGlob="--filter @monorepo/types --filter @monorepo/cli" /%}
You can also pass glob patterns to filter by workspace names:
{% bunOutdatedTerminal glob="{e,t}*" displayGlob="--filter='@monorepo/{types,cli}'" /%}
{% bunCLIUsage command="outdated" /%}

View File

@@ -7,3 +7,5 @@ To get started with patch, first prepare the package for patching with [`bun pat
By default, `bun patch-commit` will use the `patches` directory in the temporary directory.
You can specify a different directory with the `--patches-dir` flag.
{% bunCLIUsage command="patch-commit" /%}

View File

@@ -105,3 +105,4 @@ $ bun publish --otp 123456
### `--gzip-level`
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
{% bunCLIUsage command="publish" /%}

View File

@@ -3,3 +3,5 @@ To remove a dependency:
```bash
$ bun remove ts-node
```
{% bunCLIUsage command="remove" /%}

View File

@@ -205,3 +205,5 @@ When there is a package.json script and a file with the same name, `bun run` pri
2. Source files, eg `bun run src/main.js`
3. Binaries from project packages, eg `bun add eslint && bun run eslint`
4. (`bun run` only) System commands, eg `bun run ls`
{% bunCLIUsage command="run" /%}

View File

@@ -247,3 +247,5 @@ $ bun test foo
```
Any test file in the directory with an _absolute path_ that contains one of the targets will run. Glob patterns are not yet supported. -->
{% bunCLIUsage command="test" /%}

View File

@@ -5,3 +5,5 @@ $ cd /path/to/cool-pkg
$ bun unlink
bun unlink v1.x (7416672e)
```
{% bunCLIUsage command="unlink" /%}

View File

@@ -32,3 +32,5 @@ For example, with the following `package.json`:
- `bun update` would update to a version that matches `17.x`.
- `bun update --latest` would update to a version that matches `18.x` or later.
{% bunCLIUsage command="update" /%}

View File

@@ -98,7 +98,7 @@ import { Database } from "bun:sqlite";
const sqlite = new Database("sqlite.db");
const db = drizzle(sqlite);
await migrate(db, { migrationsFolder: "./drizzle" });
migrate(db, { migrationsFolder: "./drizzle" });
```
---

View File

@@ -35,7 +35,7 @@ jobs:
# ...
- uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: 1.0.11 # or "latest", "canary", <sha>
+ bun-version: 1.2.0 # or "latest", "canary", <sha>
```
---

View File

@@ -0,0 +1,37 @@
---
name: Delete directories
---
To recursively delete a directory and all its contents, use `rm` from `node:fs/promises`. This is like running `rm -rf` in JavaScript.
```ts
import { rm } from "node:fs/promises";
// Delete a directory and all its contents
await rm("path/to/directory", { recursive: true, force: true });
```
---
These options configure the deletion behavior:
- `recursive: true` - Delete subdirectories and their contents
- `force: true` - Don't throw errors if the directory doesn't exist
You can also use it without `force` to ensure the directory exists:
```ts
try {
await rm("path/to/directory", { recursive: true });
} catch (error) {
if (error.code === "ENOENT") {
console.log("Directory doesn't exist");
} else {
throw error;
}
}
```
---
See [Docs > API > FileSystem](https://bun.sh/docs/api/file-io) for more filesystem operations.

View File

@@ -0,0 +1,19 @@
---
name: Delete files
---
To delete a file, use `Bun.file(path).delete()`.
```ts
// Delete a file
const file = Bun.file("path/to/file.txt");
await file.delete();
// Now the file doesn't exist
const exists = await file.exists();
// => false
```
---
See [Docs > API > FileSystem](https://bun.sh/docs/api/file-io) for more filesystem operations.

View File

@@ -0,0 +1,26 @@
---
name: Inspect memory usage using V8 heap snapshots
---
Bun implements V8's heap snapshot API, which allows you to create snapshots of the heap at runtime. This helps debug memory leaks in your JavaScript/TypeScript application.
```ts#snapshot.ts
import v8 from "node:v8";
// Creates a heap snapshot file with an auto-generated name
const snapshotPath = v8.writeHeapSnapshot();
console.log(`Heap snapshot written to: ${snapshotPath}`);
```
---
## Inspect memory in Chrome DevTools
To view V8 heap snapshots in Chrome DevTools:
1. Open Chrome DevTools (F12 or right-click and select "Inspect")
2. Go to the "Memory" tab
3. Click the "Load" button (folder icon)
4. Select your `.heapsnapshot` file
{% image src="/images/chrome-devtools-memory.png" alt="Chrome DevTools Memory Tab" width="100%" /%}

View File

@@ -55,3 +55,5 @@ $ bun patch --commit react --patches-dir=mypatches
# `patch-commit` is available for compatibility with pnpm
$ bun patch-commit react
```
{% bunCLIUsage command="patch" /%}

View File

@@ -94,7 +94,9 @@ $ bun --revision
If you've installed Bun but are seeing a `command not found` error, you may have to manually add the installation directory (`~/.bun/bin`) to your `PATH`.
{% details summary="How to add to your `PATH`" %}
### How to add your `PATH`
{% details summary="Linux / Mac" %}
First, determine what shell you're using:
```sh
@@ -129,6 +131,26 @@ Save the file. You'll need to open a new shell/terminal window for the changes t
{% /details %}
{% details summary="Windows" %}
First, determine if the bun binary is properly installed on your system:
```pwsh
& "$env:USERPROFILE\.bun\bin\bun" --version
```
If the command runs successfully but `bun --version` is not recognized, it means that bun is not in your system's `PATH`. To fix this, open a Powershell terminal and run the following command:
```pwsh
[System.Environment]::SetEnvironmentVariable(
"Path",
[System.Environment]::GetEnvironmentVariable("Path", "User") + ";$env:USERPROFILE\.bun\bin",
[System.EnvironmentVariableTarget]::User
)
```
After running the command, restart your terminal and test with `bun --version`
{% /details %}
## Upgrading
Once installed, the binary can upgrade itself.

View File

@@ -27,7 +27,7 @@ export default {
divider("Intro"),
page("index", "What is Bun?", {
description:
"Bun is an all-in-one runtime for JavaScript and TypeScript apps. Run, bundle, and test apps with one fast tool.",
"Bun is an all-in-one runtime for JavaScript and TypeScript apps. Build, run, and test apps with one fast tool.",
}),
page("installation", "Installation", {
description: "Install Bun with npm, Homebrew, Docker, or the official install script.",
@@ -181,7 +181,7 @@ export default {
"Bun's package manager installs all packages into a shared global cache to avoid redundant re-downloads.",
}),
page("install/workspaces", "Workspaces", {
description: "Bun's package manager supports workspaces and mono-repo development workflows.",
description: "Bun's package manager supports workspaces and monorepo development workflows.",
}),
page("install/lifecycle", "Lifecycle scripts", {
description: "How Bun handles package lifecycle scripts with trustedDependencies",
@@ -194,7 +194,8 @@ export default {
"Bun's lockfile `bun.lock` tracks your resolved dependency tree, making future installs fast and repeatable.",
}),
page("install/registries", "Scopes and registries", {
description: "How to configure private scopes and custom package registries.",
description:
"How to configure private scopes, custom package registries, authenticating with npm token, and more.",
}),
page("install/overrides", "Overrides and resolutions", {
description: "Specify version ranges for nested dependencies",
@@ -214,8 +215,8 @@ export default {
page("bundler", "`Bun.build`", {
description: "Bundle code for consumption in the browser with Bun's native bundler.",
}),
page("bundler/html", "HTML", {
description: `Bundle html files with Bun's native bundler.`,
page("bundler/html", "Bundle frontend & static sites", {
description: `Zero-config HTML bundler for single-page apps and multi-page apps. Automatic bundling, TailwindCSS plugins, TypeScript, JSX, React support, and incredibly fast builds`,
}),
page("bundler/fullstack", "Fullstack Dev Server", {
description: "Serve your frontend and backend from the same app with Bun's dev server.",

View File

@@ -180,6 +180,25 @@ Whether to skip test files when computing coverage statistics. Default `false`.
coverageSkipTestFiles = false
```
### `test.coverageReporter`
By default, coverage reports will be printed to the console. For persistent code coverage reports in CI environments and for other tools use `lcov`.
```toml
[test]
coverageReporter = ["text", "lcov"] # default ["text"]
```
### `test.coverageDir`
Set path where coverage reports will be saved. Please notice, that it works only for persistent `coverageReporter` like `lcov`.
```toml
[test]
coverageDir = "path/to/somewhere" # default "coverage"
```
## Package manager
Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured under the `[install]` section.

View File

@@ -56,9 +56,9 @@ By default, `await`ing will return stdout and stderr as `Buffer`s.
```js
import { $ } from "bun";
const { stdout, stderr } = await $`echo "Hello World!"`.quiet();
const { stdout, stderr } = await $`echo "Hello!"`.quiet();
console.log(stdout); // Buffer(6) [ 72, 101, 108, 108, 111, 32 ]
console.log(stdout); // Buffer(7) [ 72, 101, 108, 108, 111, 33, 10 ]
console.log(stderr); // Buffer(0) []
```

View File

@@ -58,3 +58,82 @@ export const foo = "Hello world!"
```
{% /codetabs %}
## Experimental Decorators
Bun supports the pre-TypeScript 5.0 experimental decorators syntax.
```ts#hello.ts
// Simple logging decorator
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with:`, args);
return originalMethod.apply(this, args);
};
}
class Example {
@log
greet(name: string) {
return `Hello ${name}!`;
}
}
// Usage
const example = new Example();
example.greet("world"); // Logs: "Calling greet with: ['world']"
```
To enable it, add `"experimentalDecorators": true` to your `tsconfig.json`:
```jsonc#tsconfig.json
{
"compilerOptions": {
// ... rest of your config
"experimentalDecorators": true,
},
}
```
We generally don't recommend using this in new codebases, but plenty of existing codebases have come to rely on it.
### emitDecoratorMetadata
Bun supports `emitDecoratorMetadata` in your `tsconfig.json`. This enables emitting design-time type metadata for decorated declarations in source files.
```ts#emit-decorator-metadata.ts
import "reflect-metadata";
class User {
id: number;
name: string;
}
function Injectable(target: Function) {
// Get metadata about constructor parameters
const params = Reflect.getMetadata("design:paramtypes", target);
console.log("Dependencies:", params); // [User]
}
@Injectable
class UserService {
constructor(private user: User) {}
}
// Creates new UserService instance with dependencies
const container = new UserService(new User());
```
To enable it, add `"emitDecoratorMetadata": true` to your `tsconfig.json`:
```jsonc#tsconfig.json
{
"compilerOptions": {
// ... rest of your config
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
},
}
```

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "macros",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "simple-react",
@@ -1659,7 +1659,7 @@
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@7.5.9", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="],
"ws": ["ws@7.5.9", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="],
"xml-name-validator": ["xml-name-validator@3.0.0", "", {}, "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="],

View File

@@ -1,4 +1,10 @@
process handle -p true -s false -n false SIGUSR1
# Tell LLDB what to do when the debugged process receives SIGPWR: pass it through to the process
# (-p), but do not stop the process (-s) or notify the user (-n).
#
# JSC's garbage collector sends this signal (as configured by Bun WebKit in
# Thread::initializePlatformThreading() in ThreadingPOSIX.cpp) to the JS thread to suspend or resume
# it. So stopping the process would just create noise when debugging any long-running script.
process handle -p true -s false -n false SIGPWR
command script import misctools/lldb/lldb_pretty_printers.py
type category enable zig.lang

View File

@@ -35,7 +35,7 @@ fn spamMe(count: usize) void {
while (i < count) : (i += 1) {
waker.wake() catch unreachable;
}
Output.prettyErrorln("[EVFILT_MACHPORT] Sent {any}", .{bun.fmt.fmtDuration(timer.read())});
Output.prettyErrorln("[EVFILT_MACHPORT] Sent {any}", .{std.fmt.fmtDuration(timer.read())});
}
const thread_count = 1;
pub fn machMain(runs: usize) anyerror!void {
@@ -67,7 +67,7 @@ pub fn machMain(runs: usize) anyerror!void {
elapsed += timer.read();
}
Output.prettyErrorln("[EVFILT_MACHPORT] Recv {any}", .{bun.fmt.fmtDuration(elapsed)});
Output.prettyErrorln("[EVFILT_MACHPORT] Recv {any}", .{std.fmt.fmtDuration(elapsed)});
}
var user_waker: bun.Async.UserFilterWaker = undefined;
@@ -80,7 +80,7 @@ fn spamMeUserFilter(count: usize) void {
user_waker.wake() catch unreachable;
}
Output.prettyErrorln("[EVFILT_USER] Sent {any}", .{bun.fmt.fmtDuration(timer.read())});
Output.prettyErrorln("[EVFILT_USER] Sent {any}", .{std.fmt.fmtDuration(timer.read())});
}
pub fn userMain(runs: usize) anyerror!void {
defer Output.flush();
@@ -111,7 +111,7 @@ pub fn userMain(runs: usize) anyerror!void {
elapsed += timer.read();
}
Output.prettyErrorln("[EVFILT_USER] Recv {any}", .{bun.fmt.fmtDuration(elapsed)});
Output.prettyErrorln("[EVFILT_USER] Recv {any}", .{std.fmt.fmtDuration(elapsed)});
Output.flush();
}

View File

@@ -20,6 +20,7 @@
"build",
"test/snapshots/**",
"bench/react-hello-world/*.js",
"bun.lock",
"test/js/node/**/parallel/**",
"test/js/node/test/fixtures", // full of JS with intentional syntax errors

View File

@@ -1,16 +1,19 @@
{
"private": true,
"name": "bun",
"version": "1.2.1",
"version": "1.2.3",
"workspaces": [
"./packages/bun-types"
],
"devDependencies": {
"@mdn/browser-compat-data": "~5.5.28",
"@types/bun": "*",
"@types/react": "^18.3.3",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"@vscode/debugadapter": "^1.65.0",
"autoprefixer": "^10.4.19",
"caniuse-lite": "^1.0.30001620",
"esbuild": "^0.21.4",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
@@ -21,10 +24,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"source-map-js": "^1.2.0",
"typescript": "^5.7.2",
"caniuse-lite": "^1.0.30001620",
"autoprefixer": "^10.4.19",
"@mdn/browser-compat-data": "~5.5.28"
"typescript": "^5.7.2"
},
"resolutions": {
"bun-types": "workspace:packages/bun-types"

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-debug-adapter-protocol",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "web-inspector-bun",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-inspector-protocol",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
@@ -26,7 +26,7 @@
"@types/p-queue": ["@types/p-queue@3.2.1", "", { "dependencies": { "p-queue": "*" } }, "sha512-tgAdn5zEs05NuHzOyRM34cMO0rczStphR/kLo/ZJwwwJ5S2+QVxwA6gST3vDHWPB1oDfUuT6wOouhJvJkBCA0w=="],
"bun": ["bun@workspace:runners/bun", {}],
"bun": ["bun@workspace:runners/bun"],
"bun-types": ["bun-types@1.0.4-canary.20230929T233451", "", {}, "sha512-Ke/y3GX0T2ZYKx0UKKCnFRRP9bXzVRcRZCrIlF5/aRNEpgbfrMBw+s5imPqrV2CqJ7q6kIbMikCahzMr4N9PTg=="],
@@ -38,7 +38,7 @@
"prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="],
"qunit": ["qunit@workspace:runners/qunit", {}],
"qunit": ["qunit@workspace:runners/qunit"],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -2,16 +2,12 @@
name = "bun-native-plugin"
description = "Rustified wrapper for writing native plugins for Bun."
license = "MIT"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
[dependencies]
anyhow = "1.0.94"
# use local path in dev and publish to crates.io in prod
bun-macro = { path = "./bun-macro", version = "0.1.0" }
napi = { version = "2.14.1", default-features = false, features = ["napi4"] }
[features]
default = ["napi"]
napi = []

View File

@@ -473,6 +473,10 @@ impl<'a> OnBeforeParse<'a> {
}
}
/// # Safety
/// This is unsafe as you must ensure that no other invocation of the plugin (or JS!)
/// simultaneously holds a mutable reference to the external.
///
/// Get the external object from the `OnBeforeParse` arguments.
///
/// The external object is set by the plugin definition inside of JS:
@@ -521,42 +525,35 @@ impl<'a> OnBeforeParse<'a> {
/// },
/// };
/// ```
pub unsafe fn external<T: 'static + Sync>(&self) -> PluginResult<Option<&'static T>> {
pub unsafe fn external<'b, T: 'static + Sync>(
&self,
from_raw: unsafe fn(*mut c_void) -> Option<&'b T>,
) -> PluginResult<Option<&'b T>> {
if unsafe { (*self.args_raw).external.is_null() } {
return Ok(None);
}
let external: *mut TaggedObject<T> =
unsafe { (*self.args_raw).external as *mut TaggedObject<T> };
let external = unsafe { from_raw((*self.args_raw).external as *mut _) };
unsafe {
if (*external).type_id != TypeId::of::<T>() {
return Err(Error::ExternalTypeMismatch);
}
Ok((*external).object.as_ref())
}
Ok(external)
}
/// The same as [`crate::bun_native_plugin::OnBeforeParse::external`], but returns a mutable reference.
///
/// This is unsafe as you must ensure that no other invocation of the plugin
/// # Safety
/// This is unsafe as you must ensure that no other invocation of the plugin (or JS!)
/// simultaneously holds a mutable reference to the external.
pub unsafe fn external_mut<T: 'static + Sync>(&mut self) -> PluginResult<Option<&mut T>> {
pub unsafe fn external_mut<'b, T: 'static + Sync>(
&mut self,
from_raw: unsafe fn(*mut c_void) -> Option<&'b mut T>,
) -> PluginResult<Option<&'b mut T>> {
if unsafe { (*self.args_raw).external.is_null() } {
return Ok(None);
}
let external: *mut TaggedObject<T> =
unsafe { (*self.args_raw).external as *mut TaggedObject<T> };
let external = unsafe { from_raw((*self.args_raw).external as *mut _) };
unsafe {
if (*external).type_id != TypeId::of::<T>() {
return Err(Error::ExternalTypeMismatch);
}
Ok((*external).object.as_mut())
}
Ok(external)
}
/// Get the input source code for the current file.

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-plugin",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-polyfills",

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -2009,35 +2009,51 @@ declare module "bun" {
*/
type SQLOptions = {
/** Connection URL (can be string or URL object) */
url: URL | string;
url?: URL | string;
/** Database server hostname */
host: string;
host?: string;
/** Database server hostname (alias for host) */
hostname?: string;
/** Database server port number */
port: number | string;
port?: number | string;
/** Database user for authentication */
username: string;
username?: string;
/** Database user for authentication (alias for username) */
user?: string;
/** Database password for authentication */
password: string;
password?: string;
/** Database password for authentication (alias for password) */
pass?: string;
/** Name of the database to connect to */
database: string;
database?: string;
/** Name of the database to connect to (alias for database) */
db?: string;
/** Database adapter/driver to use */
adapter: string;
/** Maximum time in milliseconds to wait for connection to become available */
idleTimeout: number;
/** Maximum time in milliseconds to wait when establishing a connection */
connectionTimeout: number;
/** Maximum lifetime in milliseconds of a connection */
maxLifetime: number;
adapter?: string;
/** Maximum time in seconds to wait for connection to become available */
idleTimeout?: number;
/** Maximum time in seconds to wait for connection to become available (alias for idleTimeout) */
idle_timeout?: number;
/** Maximum time in seconds to wait when establishing a connection */
connectionTimeout?: number;
/** Maximum time in seconds to wait when establishing a connection (alias for connectionTimeout) */
connection_timeout?: number;
/** Maximum lifetime in seconds of a connection */
maxLifetime?: number;
/** Maximum lifetime in seconds of a connection (alias for maxLifetime) */
max_lifetime?: number;
/** Whether to use TLS/SSL for the connection */
tls: boolean;
tls?: TLSOptions | boolean;
/** Whether to use TLS/SSL for the connection (alias for tls) */
ssl?: TLSOptions | boolean;
/** Callback function executed when a connection is established */
onconnect: (client: SQL) => void;
onconnect?: (client: SQL) => void;
/** Callback function executed when a connection is closed */
onclose: (client: SQL) => void;
onclose?: (client: SQL) => void;
/** Maximum number of connections in the pool */
max: number;
max?: number;
/** By default values outside i32 range are returned as strings. If this is true, values outside i32 range are returned as BigInts. */
bigint: boolean;
bigint?: boolean;
};
/**
@@ -3686,7 +3702,17 @@ declare module "bun" {
* Render contextual errors? This enables bun's error page
* @default process.env.NODE_ENV !== 'production'
*/
development?: boolean;
development?:
| boolean
| {
/**
* Enable Hot Module Replacement for routes (including React Fast Refresh, if React is in use)
*
* @default true if process.env.NODE_ENV !== 'production'
*
*/
hmr?: boolean;
};
error?: (this: Server, error: ErrorLike) => Response | Promise<Response> | undefined | Promise<undefined>;
@@ -5309,7 +5335,10 @@ declare module "bun" {
interface PluginBuilder {
/**
* Register a callback which will be invoked when bundling starts.
* Register a callback which will be invoked when bundling starts. When
* using hot module reloading, this is called at the start of each
* incremental rebuild.
*
* @example
* ```ts
* Bun.plugin({
@@ -5406,9 +5435,9 @@ declare module "bun" {
* - `browser`: The plugin will be applied to browser builds
* - `node`: The plugin will be applied to Node.js builds
*
* If in Bun's runtime, the default target is `bun`.
* If unspecified, it is assumed that the plugin is compatible with all targets.
*
* If unspecified, it is assumed that the plugin is compatible with the default target.
* This field is not read by Bun.plugin
*/
target?: Target;
/**

View File

@@ -27,7 +27,7 @@
},
"scripts": {
"prebuild": "echo $(pwd)",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION:-1.0.0}\"'/g' ./docs/**/*.md",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v:-1.0.0}\"'/g' {} +",
"build": "bun run copy-docs && bun scripts/build.ts && bun run fmt",
"test": "tsc",
"fmt": "echo $(which biome) && biome format --write ."

View File

@@ -387,8 +387,15 @@ int bsd_socket_multicast_interface(LIBUS_SOCKET_DESCRIPTOR fd, const struct sock
static int bsd_socket_set_membership4(LIBUS_SOCKET_DESCRIPTOR fd, const struct sockaddr_in *addr, const struct sockaddr_in *iface, int drop) {
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = iface->sin_addr.s_addr;
if (iface != NULL) {
mreq.imr_interface.s_addr = iface->sin_addr.s_addr;
} else {
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
int option = drop ? IP_DROP_MEMBERSHIP : IP_ADD_MEMBERSHIP;
return setsockopt(fd, IPPROTO_IP, option, &mreq, sizeof(mreq));
}
@@ -397,13 +404,15 @@ static int bsd_socket_set_membership6(LIBUS_SOCKET_DESCRIPTOR fd, const struct s
struct ipv6_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.ipv6mr_multiaddr = addr->sin6_addr;
mreq.ipv6mr_interface = iface->sin6_scope_id;
if (iface != NULL) {
mreq.ipv6mr_interface = iface->sin6_scope_id;
}
int option = drop ? IPV6_LEAVE_GROUP : IPV6_JOIN_GROUP;
return setsockopt(fd, IPPROTO_IP, option, &mreq, sizeof(mreq));
}
int bsd_socket_set_membership(LIBUS_SOCKET_DESCRIPTOR fd, const struct sockaddr_storage *addr, const struct sockaddr_storage *iface, int drop) {
if (addr->ss_family != iface->ss_family) {
if (iface != NULL && addr->ss_family != iface->ss_family) {
errno = EINVAL;
return -1;
}

View File

@@ -1589,22 +1589,40 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(
socket_ext_size, error);
}
// https://github.com/oven-sh/bun/issues/16995
static void us_internal_zero_ssl_data_for_connected_socket_before_onopen(struct us_internal_ssl_socket_t *s) {
s->ssl = NULL;
s->ssl_write_wants_read = 0;
s->ssl_read_wants_write = 0;
s->fatal_error = 0;
s->handshake_state = HANDSHAKE_PENDING;
}
// TODO does this need more changes?
struct us_connecting_socket_t *us_internal_ssl_socket_context_connect(
struct us_socket_t *us_internal_ssl_socket_context_connect(
struct us_internal_ssl_socket_context_t *context, const char *host,
int port, int options, int socket_ext_size, int* is_connected) {
return us_socket_context_connect(
int port, int options, int socket_ext_size, int* is_connecting) {
struct us_internal_ssl_socket_t *s = (struct us_internal_ssl_socket_t *)us_socket_context_connect(
2, &context->sc, host, port, options,
sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) +
socket_ext_size, is_connected);
socket_ext_size, is_connecting);
if (*is_connecting) {
us_internal_zero_ssl_data_for_connected_socket_before_onopen(s);
}
return (struct us_socket_t*)s;
}
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_internal_ssl_socket_context_t *context, const char *server_path,
size_t pathlen, int options, int socket_ext_size) {
return (struct us_internal_ssl_socket_t *)us_socket_context_connect_unix(
struct us_socket_t *s = (struct us_socket_t *)us_socket_context_connect_unix(
0, &context->sc, server_path, pathlen, options,
sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) +
socket_ext_size);
if (s) {
us_internal_zero_ssl_data_for_connected_socket_before_onopen((struct us_internal_ssl_socket_t*) s);
}
return s;
}
static void ssl_on_open_without_sni(struct us_internal_ssl_socket_t *s, int is_client, char *ip, int ip_length) {

View File

@@ -8,6 +8,8 @@
#include <string.h>
static const int root_certs_size = sizeof(root_certs) / sizeof(root_certs[0]);
extern "C" void BUN__warn__extra_ca_load_failed(const char* filename, const char* error_msg);
// This callback is used to avoid the default passphrase callback in OpenSSL
// which will typically prompt for the passphrase. The prompting is designed
// for the OpenSSL CLI, but works poorly for this case because it involves
@@ -27,57 +29,82 @@ us_ssl_ctx_get_X509_without_callback_from(struct us_cert_string_t content) {
in = BIO_new_mem_buf(content.str, content.len);
if (in == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto end;
}
} else {
x = PEM_read_bio_X509(in, NULL, us_no_password_callback, NULL);
if (x == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
}
x = PEM_read_bio_X509(in, NULL, us_no_password_callback, NULL);
if (x == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
goto end;
// NOTE: PEM_read_bio_X509 allocates, so input BIO must be freed.
BIO_free(in);
}
// NOTE: PEM_read_bio_X509 allocates, so input BIO must be freed.
BIO_free(in);
return x;
end:
X509_free(x);
BIO_free(in);
return NULL;
}
static X509 *
us_ssl_ctx_get_X509_without_callback_from_file(const char *filename) {
static STACK_OF(X509) *us_ssl_ctx_load_all_certs_from_file(const char *filename) {
BIO *in = NULL;
STACK_OF(X509) *certs = NULL;
X509 *x = NULL;
BIO *in;
unsigned long last_err;
ERR_clear_error(); // clear error stack for SSL_CTX_use_certificate()
in = BIO_new(BIO_s_file());
in = BIO_new_file(filename, "r");
if (in == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, filename) <= 0) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
goto end;
}
x = PEM_read_bio_X509(in, NULL, us_no_password_callback, NULL);
if (x == NULL) {
certs = sk_X509_new_null();
if (certs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto end;
}
while ((x = PEM_read_bio_X509(in, NULL, us_no_password_callback, NULL))) {
if (!sk_X509_push(certs, x)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
X509_free(x);
goto end;
}
}
last_err = ERR_peek_last_error();
// Ignore error if its EOF/no start line found.
if (ERR_GET_LIB(last_err) == ERR_LIB_PEM && ERR_GET_REASON(last_err) == PEM_R_NO_START_LINE) {
ERR_clear_error();
} else {
goto end;
}
if (sk_X509_num(certs) == 0) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
goto end;
}
return x;
end:
X509_free(x);
BIO_free(in);
return certs;
end:
BIO_free(in);
if (certs) {
sk_X509_pop_free(certs, X509_free);
}
char error_msg[256];
ERR_error_string_n(ERR_peek_last_error(), error_msg, sizeof(error_msg));
BUN__warn__extra_ca_load_failed(filename, error_msg);
ERR_clear_error();
return NULL;
}
static void us_internal_init_root_certs(X509 *root_cert_instances[sizeof(root_certs) / sizeof(root_certs[0])], X509 *&root_extra_cert_instances) {
static void us_internal_init_root_certs(
X509 *root_cert_instances[root_certs_size],
STACK_OF(X509) *&root_extra_cert_instances) {
static std::atomic_flag root_cert_instances_lock = ATOMIC_FLAG_INIT;
static std::atomic_bool root_cert_instances_initialized = 0;
if (std::atomic_load(&root_cert_instances_initialized) == 1)
return;
@@ -92,13 +119,9 @@ static void us_internal_init_root_certs(X509 *root_cert_instances[sizeof(root_ce
}
// get extra cert option from environment variable
const char *extra_cert = getenv("NODE_EXTRA_CA_CERTS");
if (extra_cert) {
size_t length = strlen(extra_cert);
if (length > 0) {
root_extra_cert_instances =
us_ssl_ctx_get_X509_without_callback_from_file(extra_cert);
}
const char *extra_certs = getenv("NODE_EXTRA_CA_CERTS");
if (extra_certs && extra_certs[0]) {
root_extra_cert_instances = us_ssl_ctx_load_all_certs_from_file(extra_certs);
}
}
@@ -122,9 +145,8 @@ extern "C" X509_STORE *us_get_default_ca_store() {
return NULL;
}
static X509 *root_cert_instances[sizeof(root_certs) / sizeof(root_certs[0])] = {
NULL};
static X509 *root_extra_cert_instances = NULL;
static X509 *root_cert_instances[root_certs_size] = {NULL};
static STACK_OF(X509) *root_extra_cert_instances = NULL;
us_internal_init_root_certs(root_cert_instances, root_extra_cert_instances);
@@ -138,8 +160,11 @@ extern "C" X509_STORE *us_get_default_ca_store() {
}
if (root_extra_cert_instances) {
X509_up_ref(root_extra_cert_instances);
X509_STORE_add_cert(store, root_extra_cert_instances);
for (int i = 0; i < sk_X509_num(root_extra_cert_instances); i++) {
X509 *cert = sk_X509_value(root_extra_cert_instances, i);
X509_up_ref(cert);
X509_STORE_add_cert(store, cert);
}
}
return store;

View File

@@ -247,7 +247,7 @@ void us_loop_run(struct us_loop_t *loop) {
}
}
extern int Bun__JSC_onBeforeWait(void*);
extern void Bun__JSC_onBeforeWait(void*);
extern void Bun__JSC_onAfterWait(void*);
void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout) {
@@ -265,10 +265,8 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
/* Emit pre callback */
us_internal_loop_pre(loop);
int needs_after_wait = 0;
if (loop->data.jsc_vm) {
needs_after_wait = Bun__JSC_onBeforeWait(loop->data.jsc_vm);
}
/* Safe if jsc_vm is NULL */
Bun__JSC_onBeforeWait(loop->data.jsc_vm);
/* Fetch ready polls */
#ifdef LIBUS_USE_EPOLL
@@ -280,9 +278,7 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
} while (IS_EINTR(loop->num_ready_polls));
#endif
if (needs_after_wait) {
Bun__JSC_onAfterWait(loop->data.jsc_vm);
}
Bun__JSC_onAfterWait(loop->data.jsc_vm);
/* 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++) {

View File

@@ -400,11 +400,11 @@ struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(
us_internal_ssl_socket_context_r context, const char *path,
size_t pathlen, int options, int socket_ext_size, int* error);
struct us_connecting_socket_t *us_internal_ssl_socket_context_connect(
struct us_socket_t *us_internal_ssl_socket_context_connect(
us_internal_ssl_socket_context_r context, const char *host,
int port, int options, int socket_ext_size, int* is_resolved);
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(
struct us_socket_t *us_internal_ssl_socket_context_connect_unix(
us_internal_ssl_socket_context_r context, const char *server_path,
size_t pathlen, int options, int socket_ext_size);

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "mock-debug",
@@ -148,9 +148,9 @@
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
"bun-debug-adapter-protocol": ["bun-debug-adapter-protocol@workspace:../bun-debug-adapter-protocol", { "dependencies": { "semver": "^7.5.4", "source-map-js": "^1.0.2" } }],
"bun-debug-adapter-protocol": ["bun-debug-adapter-protocol@workspace:../bun-debug-adapter-protocol"],
"bun-inspector-protocol": ["bun-inspector-protocol@workspace:../bun-inspector-protocol", { "dependencies": { "ws": "^8.13.0" } }],
"bun-inspector-protocol": ["bun-inspector-protocol@workspace:../bun-inspector-protocol"],
"bun-types": ["bun-types@1.1.29", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-En3/TzSPMPyl5UlUB1MHzHpcrZDakTm7mS203eLoX1fBoEa3PW+aSS8GAqVJ7Is/m34Z5ogL+ECniLY0uDaCPw=="],

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {

View File

@@ -1,5 +1,5 @@
{
"lockfileVersion": 0,
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-wasm",

View File

@@ -1,13 +0,0 @@
pub usingnamespace @import("./src/main.zig");
/// These functions are used throughout Bun's codebase.
pub const bun = @import("./src/bun.zig");
pub const completions = struct {
pub const bash = @embedFile("./completions/bun.bash");
pub const zsh = @embedFile("./completions/bun.zsh");
pub const fish = @embedFile("./completions/bun.fish");
};
pub const JavaScriptCore = @import("./src/jsc.zig");
pub const C = @import("./src/c.zig");

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