Compare commits

...

211 Commits

Author SHA1 Message Date
Jarred Sumner
fae8dda372 Copy tests from #1693 2023-07-31 06:00:43 -07:00
Jarred Sumner
9c2c62d8e4 Fixes #2935 2023-07-31 05:19:35 -07:00
Jarred Sumner
b366866d61 Update server.zig 2023-07-31 05:08:09 -07:00
Jarred Sumner
1b4c25ff6c Make the tests pass 2023-07-31 05:06:48 -07:00
Jarred Sumner
bca9fedee4 Update tee to match spec closer
Relevant 221bafcd1af8f91209af9effef02b941b69d584d
2023-07-31 05:04:57 -07:00
Jarred Sumner
e1cd128078 Relevant to #3859 2023-07-31 05:04:18 -07:00
Jarred Sumner
4720ae907f Update body.test.ts 2023-07-31 02:30:25 -07:00
Jarred Sumner
2924329ab0 Support ReadableStream when cloning Response & Request 2023-07-31 01:07:12 -07:00
Jarred Sumner
9ecae59bbb Fix memory leak in response.clone(), further reduce memory usage of Request & Response (#3902)
* Atomize respsone.url & response.statusText

* Fix warning

* Atomize Request & Response URLs when possible

* Fix memory leak in response.clone()

bun/bench/snippets on  jarred/atomize
❯ mem bun --smol request-response-clone.mjs
cpu: Apple M1 Max
runtime: bun 0.7.2 (arm64-darwin)

benchmark             time (avg)             (min … max)       p75       p99      p995
-------------------------------------------------------- -----------------------------
req.clone().url     77.3 ns/iter  (40.35 ns … 222.64 ns)  91.53 ns 128.11 ns 172.78 ns
resp.clone().url  162.43 ns/iter    (116 ns … 337.77 ns)  177.4 ns 232.38 ns 262.65 ns

Peak memory usage: 60 MB

bun/bench/snippets on  jarred/atomize
❯ mem bun-0.7.1 --smol request-response-clone.mjs
cpu: Apple M1 Max
runtime: bun 0.7.1 (arm64-darwin)

benchmark             time (avg)             (min … max)       p75       p99      p995
-------------------------------------------------------- -----------------------------
req.clone().url   115.85 ns/iter  (80.35 ns … 247.39 ns) 128.19 ns 181.93 ns 207.23 ns
resp.clone().url  252.32 ns/iter  (202.6 ns … 351.07 ns) 266.56 ns 325.88 ns 334.73 ns

Peak memory usage: 1179 MB

* Update tests

* Update js_ast.zig

* Update test

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-30 23:51:43 -07:00
audothomas
2ea7290172 FIx Uint8Array to a ReadableStream code snippet (#3895) 2023-07-30 17:53:22 -07:00
Jarred Sumner
092ada6d2f Micro-optimize LineOffsetTable.generate
5.00 ms  100.0%	0 s	 	bun (81023)
2.00 ms   40.0%	2.00 ms	 	 WTF::HashTableAddResult<WTF::HashTableIterator<WTF::HashTable<WTF::Packed<WTF::StringImpl*>, WTF::Packed<WTF::StringImpl*>, WTF::IdentityExtractor, WTF::DefaultHash<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>>, WTF::Packed<WTF::StringImpl*>, WTF::Packed<WTF::StringImpl*>, WTF::IdentityExtractor, WTF::DefaultHash<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>>> WTF::HashTable<WTF::Packed<WTF::StringImpl*>, WTF::Packed<WTF::StringImpl*>, WTF::IdentityExtractor, WTF::DefaultHash<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>, WTF::HashTraits<WTF::Packed<WTF::StringImpl*>>>::addPassingHashCode<WTF::HashSetTranslatorAdapter<WTF::BufferFromStaticDataTranslator<unsigned char>>, WTF::HashTranslatorCharBuffer<unsigned char> const&, WTF::HashTranslatorCharBuffer<unsigned char> const&>(WTF::HashTranslatorCharBuffer<unsigned char> const&, WTF::HashTranslatorCharBuffer<unsigned char> const&)
2.00 ms   40.0%	2.00 ms	 	 heap.StackFallbackAllocator(1024).free
2.00 ms   40.0%	0 s	 	  em.Allocator.rawFree
2.00 ms   40.0%	0 s	 	   em.Allocator.log2a
2.00 ms   40.0%	0 s	 	    em.Allocator.free__anon_1330765
2.00 ms   40.0%	0 s	 	     em.Allocator.resize__anon_1069235
2.00 ms   40.0%	0 s	 	      array_list.ArrayListAligned(i32,null).toOwnedSlice
2023-07-30 08:27:31 -07:00
Jarred Sumner
e636f1b026 skip flay test 2023-07-30 08:26:41 -07:00
Jarred Sumner
54a2d89bd2 Support bun . to run the entry point (#3891)
* Support `bun .`

* Fix tests

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-30 07:54:17 -07:00
Tiramify (A.K. Daniel)
0ea59b4c93 Update install.md (#3890) 2023-07-30 06:41:51 -07:00
Jarred Sumner
b0d3ea5a43 Fix issue with file loader (#3889)
* Fix issue with file loader

* Update jest-extended.test.js

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-30 05:59:54 -07:00
Jarred Sumner
a9dc5d51e3 Fixes #3884 2023-07-30 04:04:06 -07:00
Jarred Sumner
749194378a Bump 2023-07-30 04:04:06 -07:00
Jarred Sumner
794e657eb2 remove unnecessary move 2023-07-30 04:04:06 -07:00
Jarred Sumner
1db119ec11 Fix memory leak (#3887)
* Fix memory leak

* Remove an extra copy

* Further fixes

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-30 02:03:32 -07:00
Ai Hoshino
413fd28120 Fix coredump when reading an empty file(node:stream:createReadStream) (#3882)
* Fix coredump when reading an empty file.
Close: #3607

* It seems that the fd is closed when `auto_close` is true.
2023-07-30 01:18:13 -07:00
Tiramify (A.K. Daniel)
40a9ba6340 Improv. (#3885) 2023-07-30 01:17:02 -07:00
Jarred Sumner
681be10294 Make bun:jsc memoryUsage more accurate (#3876)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-29 06:18:51 -07:00
0xflotus
dccf82b1c6 docs: fixed small errors (#3879)
* Update cache.md

* Update index.md

* Update macros.md

* Update writing.md
2023-07-29 03:58:45 -07:00
0xflotus
5563be99d3 fix: small error (#3878) 2023-07-29 03:32:24 -07:00
Jhorman Tito
bcb6dc7806 typo spawn.md (#3875) 2023-07-29 00:35:13 -07:00
Jarred Sumner
dae2928620 Update nodejs-apis.md 2023-07-28 23:58:59 -07:00
Jarred Sumner
05ef9ec141 Update nodejs-apis.md 2023-07-28 23:57:02 -07:00
Jarred Sumner
53cc4df191 Defer task destruction 2023-07-28 20:34:57 -07:00
Jarred Sumner
05716ff39b Stat largefile test (#3870)
* Add test for stat on a large file

* Update fs.test.ts

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-28 18:55:04 -07:00
Jarred Sumner
4f914cbfe8 Ignore when printing to stdout errors (#3869)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-28 18:53:44 -07:00
Jarred Sumner
da7c1d84e9 Fix bug with /path/to/absolute/bun.lockb 2023-07-28 18:52:04 -07:00
Dylan Conway
aebec5b329 markBinding 2023-07-28 18:07:28 -07:00
Dylan Conway
c68d9ae634 optional parameter 2023-07-28 18:04:00 -07:00
Jarred Sumner
bd66a9a94c Fixes #3868
Fixes #3868
Fixes #849
2023-07-28 17:53:12 -07:00
Jarred Sumner
1490cdc4ff Fix assertion failure and possible infinite loop when printing as yarn lock files 2023-07-28 17:40:05 -07:00
Jarred Sumner
97009a49bd Mark broken test as todo 2023-07-28 16:59:46 -07:00
Dylan Conway
d432448ac8 fix types and add message channel/port gc test 2023-07-28 16:55:49 -07:00
Dylan Conway
d614fdfaac MessageChannel and MessagePort (#3860)
* copy and format

* copy

* copy

* cleanup

* some tests

* spellcheck

* add types

* don't lock getting contextId

* array buffer test
2023-07-28 16:44:28 -07:00
Jarred Sumner
0a4e476a7c mark tests as todo 2023-07-28 16:24:22 -07:00
Vlad Sirenko
9078b1286d add fork to child_process (#3851)
* add fork to child_process

* fix export

* add test to child_process method `fork`

* fmt fork

* remove only from test
2023-07-28 16:00:43 -07:00
Tiramify (A.K. Daniel)
242d8655d8 feat(bun/test): Impl. expect().pass() & expect().fail() (#3843)
* Impl. pass & fail

* fix

* fix 2

* smol
2023-07-28 15:46:44 -07:00
Ai Hoshino
9b91e3c1a2 fix the chunk boundary (node:stream:createReadStream) (#3853)
* fix the slice boundary.
Close: #3668

* Add more boundary test case.

* fix end is 0.
2023-07-28 15:44:33 -07:00
Jarred Sumner
7a1ebec26f Support file: URLs in fetch (#3858)
* Support file: URLs in `fetch`

* Update url.zig

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-28 15:44:05 -07:00
Ciro Spaciari
e7c80b90b8 fix(tls) exposes native canonicalizeIP and fix rootCertificates (#3866)
* exposes native canonicalizeIP

* remove unintended duplicate

* add tests

* add tests for debug builds

* add rootCertificates test and fix len

* just randomize test ids on prisma

* remove work around and bump usockets with the actual fix

* fix case

* bump uws
2023-07-28 15:43:15 -07:00
Jarred Sumner
e110ccf84d Fixes #3795 (#3856)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-28 01:33:00 -07:00
Jarred Sumner
c2a744f0cc Add todo
cc @cirospaciari
2023-07-28 00:34:54 -07:00
Jarred Sumner
38168f3c85 Update pull_request_template.md 2023-07-28 00:17:47 -07:00
Jarred Sumner
cbaab23f6d Update pull_request_template.md 2023-07-28 00:17:26 -07:00
Jarred Sumner
3e5beb1279 Fix bug with // @bun annotation in main thread (#3855)
* Uncomment test

* Fix bug with // @bun + async transpiler

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 22:30:10 -07:00
Jarred Sumner
70b9bf743c Add Bun.isMainThread 2023-07-27 22:28:28 -07:00
Jarred Sumner
f3153fbee9 Uncomment test 2023-07-27 20:46:25 -07:00
Ciro Spaciari
7fa71dd032 Resolve watch directories outside main thread + async iterator and symlink fixes (#3846)
* linux working pending tests with FSEvents

* add more tests, fix async iterator

* remove unnecessary check

* fix macos symlink on directories

* remove indirection layer

* todos

* fixes and some permission test

* fix opsie and make prisma test more reliable

* rebase with main

* add comptime check for macOS

* oops

* oops2

* fix symlinks cascade on FSEvents

* use JSC.WorkPool

* use withResolver, createFIFO and fix close event on async iterator

* remove unused events

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2023-07-27 19:23:54 -07:00
Jarred Sumner
52f39d728f Update pull_request_template.md 2023-07-27 18:12:11 -07:00
Jarred Sumner
73eb59019a Update pull_request_template.md 2023-07-27 18:11:28 -07:00
Jarred Sumner
3b24305b7c Update pull_request_template.md 2023-07-27 18:10:49 -07:00
Jarred Sumner
1304779826 Update pull_request_template.md 2023-07-27 18:03:44 -07:00
Jarred Sumner
65d0884361 Update pull_request_template.md 2023-07-27 18:01:01 -07:00
Jarred Sumner
16fdc074ca Update pull_request_template.md 2023-07-27 18:00:03 -07:00
Jarred Sumner
6b35fd847f Create pull_request_template.md 2023-07-27 17:56:11 -07:00
Jarred Sumner
007f357495 Make readFile() async (#3850)
* less leaky

* async readfile

* Update types.zig

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 16:55:49 -07:00
Jarred Sumner
16a7224ce5 Fix hot reloading in canary (#3848)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 15:52:52 -07:00
Jarred Sumner
7c44773f38 Outdated copy 2023-07-27 15:22:53 -07:00
Jarred Sumner
85895bd248 Use putDirectIndex instead of initializeIndex (#3839)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 14:45:32 -07:00
Luigi Pinca
6c2ec2868f Remove no longer needed flag from benchmark documentation (#3845)
`Deno.serve()` was stabilized in version 1.35.0.
2023-07-27 13:27:54 -07:00
Jarred Sumner
704ee13392 Make readdir() async, fix crash in large directory trees (#3838)
* Fix unsafe GC behavior on large arrays returned by fs

* Fix crash in large arrays of strings

* async readdir

* Add tests for large number of files returned by readdir

* Move this down

* Fix encoding edgecase in path.join

* Async stat & lstat

* add test

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 04:27:09 -07:00
Jarred Sumner
d7aebc2222 Remove lstat call in fs.watch (#3836)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-27 03:34:18 -07:00
Jarred Sumner
dc0d767f27 Enable Promise.withResolvers()
https://github.com/tc39/proposal-promise-with-resolvers

Thanks @dcrousso
2023-07-26 23:52:57 -07:00
Jarred Sumner
86633e0af4 Start time performance improvements to build tools (#3797)
* Make os.cpus() faster on Linux

* Fix crash

See https://github.com/ziglang/zig/issues/16540

* Handle watcher_count == 0

* Add assertion

* Clean up lifetimes of fs watcher a little

* ✂️

* Use `errdefer`

* Make the error better

* Make os.cpus() more lazy

* Please don't translate-c on the entire C standard library

* immediately closing works correctly is still bug

* ops

* fmt+fixeup

* add back verbose

* free instead of destroy

* remove destroy option for watcher tasks

* flush verbose and add debug log

* fixup files

* use log for debug

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: cirospaciari <ciro.spaciari@gmail.com>
2023-07-26 21:35:49 -07:00
Jarred Sumner
ec2cf38ad8 [fetch] Ignore invalid Content-Encoding header (#3834)
Fixes #3802

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-26 20:24:36 -07:00
Colin McDonnell
34fd4df646 Fix broken anchors 2023-07-26 17:11:15 -07:00
Jarred Sumner
a6d54e5949 Update macro-test.test.ts 2023-07-26 16:56:26 -07:00
Jarred Sumner
664ccec7d3 Disable concurrent transpiler in macros 2023-07-26 16:54:36 -07:00
Dylan Conway
1a558ef753 fix decorator and declare (#3828)
* return the prop if there are decorators

* test and comment
2023-07-26 16:31:08 -07:00
Jarred Sumner
f3200ac0ca Don't hoist bun plugin in concurrent transpiler 2023-07-26 16:06:04 -07:00
Jarred Sumner
011b50589c Concurrent Transpiler (#3816)
* Concurrent Transpiler

* Fix bug with some improts and add jsc alias

* Some comments

* Fix crash

* Update module_loader.zig

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-26 15:36:05 -07:00
Alex Lam S.L
06503663b1 [install] handle workspace:[alias@]range (#3819) 2023-07-26 15:35:47 -07:00
Colin McDonnell
4c89c60867 Add files (#3826) 2023-07-26 14:59:39 -07:00
Colin McDonnell
6bfee02301 Fix typo 2023-07-25 12:27:27 -07:00
Ai Hoshino
0297cb1527 fix the encoding of dirname's return value. (#3799) 2023-07-25 05:49:48 -07:00
Jarred Sumner
4209703b35 Make this other name better 2023-07-25 02:08:51 -07:00
Jarred Sumner
8edeb617a8 Make this name better 2023-07-25 02:08:23 -07:00
Ai Hoshino
130079b558 fix some cases in the dirname function. (#3785)
Close: #3782
2023-07-25 00:41:22 -07:00
Jarred Sumner
8356830727 Trace printing at runtime 2023-07-24 22:00:43 -07:00
Jarred Sumner
5edb756533 Trace module resolution 2023-07-24 21:59:50 -07:00
Jarred Sumner
e402159df1 test gardening 2023-07-24 19:36:53 -07:00
dave caruso
8a0152e129 Merge import.meta.require and require to be the same thing (#3732)
* Merge import.meta.require and require to be the same thing

* support `require` and BunPlugin (runtime plugin)

* plugins

* unused code

* revert launch.json
2023-07-24 19:32:04 -07:00
Jarred Sumner
1f1d0bfcfb Make this test less flaky 2023-07-24 19:18:07 -07:00
Jarred Sumner
4ebf858f43 Less flaky 2023-07-24 19:14:41 -07:00
Jarred Sumner
90ce74a43e Skip test 2023-07-24 19:13:25 -07:00
Jarred Sumner
e1a59d355a slow test is allowed to be slow 2023-07-24 19:11:53 -07:00
Dylan Conway
e154763e4d fix rope string push (#3796)
* push to next next

* couple more tests

* end
2023-07-24 19:08:56 -07:00
Jarred Sumner
ac10a1b633 move this to troubleshooting 2023-07-24 17:16:34 -07:00
Alex Lam S.L
961312eab0 [install] fix workspace override of aliased npm dependency (#3784) 2023-07-24 17:01:43 -07:00
Jarred Sumner
6ca50526d7 bun:sqlite gets 10% faster (#3780)
* bun:sqlite gets 10% faster

❯ bun-debug bun.js # After
[0.03ms] ".env"
cpu: Apple M1 Max
runtime: bun 0.7.1_debug (arm64-darwin)

benchmark                        time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------------- -----------------------------
SELECT * FROM "Order"         13.65 ms/iter   (12.79 ms … 15.41 ms)  13.69 ms  15.41 ms  15.41 ms
SELECT * FROM "Product"       31.02 µs/iter    (27.08 µs … 1.33 ms)  30.33 µs  42.33 µs  45.25 µs
SELECT * FROM "OrderDetail"   140.2 ms/iter (127.97 ms … 172.31 ms) 144.02 ms 172.31 ms 172.31 ms

bun/bench/sqlite on  jarred/faster-sqlite took 5s
❯ bun bun.js # Before
[0.52ms] ".env"
cpu: Apple M1 Max
runtime: bun 0.7.1 (arm64-darwin)

benchmark                        time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------------- -----------------------------
SELECT * FROM "Order"         15.44 ms/iter   (14.36 ms … 17.94 ms)  15.59 ms  17.94 ms  17.94 ms
SELECT * FROM "Product"       36.89 µs/iter    (31.54 µs … 3.18 ms)  37.25 µs  49.75 µs  54.88 µs
SELECT * FROM "OrderDetail"  156.63 ms/iter (151.68 ms … 175.93 ms) 157.63 ms 175.93 ms 175.93 ms

* Handle empty just incase

* GCDeferral scope is unnecessary

* Make this code more careful

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-24 17:01:21 -07:00
Colin McDonnell
31976f6af1 Update install method order 2023-07-24 14:40:13 -07:00
Jarred Sumner
967ccb5d50 Upgrade WebKit (#3777)
* Upgrade to latest WebKit

* Upgrade WebKit

* hm

* Fix failing tests

* Delete utf8-encoding-fixture.bin.cmp

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-23 22:37:48 -07:00
Alex Lam S.L
d8135e85ca more tests for #3754 (#3774) 2023-07-23 21:19:10 -07:00
Jarred Sumner
b02f097f4d Fix bugs with connecting to localhost (#3758)
* Fix bugs with connecting to localhost

* Update uws

* More logs

* Allow not setting a hostname

* Make server.hostname & server.protocol faster

* Fixup

* normalize listening host

* Fix test

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-23 05:13:48 -07:00
Jarred Sumner
4e852918a3 Raise redirect limit in bundler 2023-07-23 03:59:43 -07:00
Jarred Sumner
c76516fa38 Fixes #3764 2023-07-23 03:58:10 -07:00
Alexander Trefz
ce77266cc5 Update nodejs-apis.md (#3762)
`structuredClone` is implemented as of v0.7
2023-07-23 03:40:46 -07:00
Artur Androsovych
ce9bba9dd5 Update development.md (#3718)
* Update `development.md`

* Update `development.md`
2023-07-22 22:24:59 -07:00
Jarred Sumner
e2e44661c2 Explicitly ref/unref blobs before extracting the value (#3755)
* Explicitly ref/unref blobs before extracting the value

* ✂️

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-22 22:20:10 -07:00
Jarred Sumner
601fd3ead5 in Bun.write(), defer creating the Promise until we're just about to schedule the task 2023-07-22 20:49:35 -07:00
Alex Lam S.L
07e08b086a [install] improve workspace substitution of npm dependencies (#3754)
- respect semver ranges
2023-07-22 20:05:24 -07:00
Jarred Sumner
53eb126898 ref() before creating the JSPromise 2023-07-22 19:56:39 -07:00
Jarred Sumner
6809d08a90 Make zig build obj fail a little later when src/runtime.out.js or src/fallback/out.js doesn't exist 2023-07-22 19:35:00 -07:00
Jarred Sumner
6402967b6d bump! 2023-07-22 17:08:31 -07:00
Jarred Sumner
bfaf095c2e Fixes https://discord.com/channels/876711213126520882/1131175053409656833/1131175053409656833
@tr1ckydev this fixes the issue you ran into, see the diff for an example usage of a Bun.plugin that makes a network request on import.
2023-07-22 16:59:54 -07:00
dave caruso
b17b61b8c6 fix path.format for vite build (#3734)
* fix path.format for vite

* Update path.test.js

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-22 16:45:45 -07:00
Jarred Sumner
27c88c8046 Fixes #3753 2023-07-22 16:42:17 -07:00
Ai Hoshino
04d19d6f6a Fix writeFileSync when the mode is greater than 0o777. (#3747)
Close: #3740
2023-07-22 07:10:36 -07:00
Jarred Sumner
3418feb2e9 Fixes #3744 2023-07-22 04:33:54 -07:00
Jarred Sumner
c6a3467625 Unified event loop (#3741)
* Unified event loop

* Update WebKit, add test for es-module-lexer

* Update README.md

* Use async wasm

* Explicitly set whether concurrenttask should be deinit'd

* Update package.json

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-22 04:31:58 -07:00
Jarred Sumner
636cec03e1 Use WebKit's URL parser in fetch() and bun install (#3730)
* Use WebKit's URL parser in fetch() and `bun install`

* Allocate less memory

* Fix test

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-21 23:27:28 -07:00
Ai Hoshino
1ecd9f8a18 handle latin1 in Bun__encoding__toString. (#3739)
Close: #3738
2023-07-21 22:01:26 -07:00
Dylan Conway
2323f5d08d fix #3716 (#3733)
* don't break on comments for process env variables

* break for `\r` and `\n`

* don't parse process env vars
2023-07-21 20:33:15 -07:00
Alex Lam S.L
311dffc690 improve test (#3731)
- minor build diffs
2023-07-22 02:42:30 +03:00
Ciro Spaciari
c4f062dbf4 clean tables before testing (#3721)
* clean tables before testing

* typo
2023-07-21 16:13:04 -07:00
Vaughan Rouesnel
7ac94e5b4c Typo in loaders.md (#3728) 2023-07-21 15:43:34 -07:00
Dylan Conway
aa1ad7f009 string escape edgecase (#3717)
* fix edgecase when joining rope strings with backtick

* bonus bugfix in ts decorator

* Update transpiler.test.js

* Fix test

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2023-07-21 01:35:06 -07:00
Dylan Conway
21bb3b2bdd fix isFIFO (#3715)
* check poll ref flags

* Update WebCoreJSBuiltins.cpp
2023-07-21 00:18:15 -07:00
Jarred Sumner
cd49615e2c fix flaky test
@paperdave we must always use `bunEnv` in the `env` to ensure that the color settings and other stuff doesn't cause bun to produce extraneous stdout input when using console.log

Additionally, the console.log was left in (which is okay)
2023-07-20 21:45:05 -07:00
Jarred Sumner
eb37794a3b Bump 2023-07-20 21:34:42 -07:00
Jarred Sumner
da298635ef Bump 2023-07-20 21:22:49 -07:00
Dylan Conway
218958dbd1 Update async_hooks.node.test.ts 2023-07-20 21:13:11 -07:00
Jarred Sumner
1c6e464a68 bump 2023-07-20 21:08:42 -07:00
dave caruso
9c85465a58 fix process.exit status code handling (#3714) 2023-07-20 19:16:56 -07:00
Jarred Sumner
2eb79afb2a Update sqlite.md 2023-07-20 18:14:34 -07:00
dave caruso
020cf46346 Fix builtins again (#3713) 2023-07-20 17:33:40 -07:00
dave caruso
134c97a282 fix directory caching with workaround (#3710)
* ok

* test
2023-07-20 16:44:43 -07:00
dave caruso
e2c11c4856 fix process.binding (#3711) 2023-07-20 16:25:02 -07:00
Dylan Conway
9ad330d917 Update process.test.js 2023-07-20 15:32:20 -07:00
Jarred Sumner
ef89f03de6 Update text-decoder.test.js 2023-07-20 15:26:06 -07:00
Julian
c383c6cd81 Pass constructor arguments to TextDecoder (#3692)
* Make TextDecoder constructor use options parameter

The constructor now actually sets TextDecoder properties using the
options parameter.

* Defer decoder allocation to end of constructor

* Verify types of TextDecoder options

* TextDecoder throw TypeError on failure

* Tidying
2023-07-20 14:50:54 -07:00
Dylan Conway
68b4a64569 resolveRopeIfNeeded (#3708) 2023-07-20 14:50:23 -07:00
Dylan Conway
8e12999917 set _preload_modules to empty array (#3709) 2023-07-20 14:50:13 -07:00
Jarred Sumner
73e44e16ea Update Dockerfile 2023-07-20 14:49:57 -07:00
Ciro Spaciari
99da0ae54b fix start delay on Worker (#3707)
* fix start delay on Worker

* fmt

* add delay test
2023-07-20 14:49:10 -07:00
Colin McDonnell
4686f5395e Add number types for FFI (#3706) 2023-07-20 11:52:45 -07:00
Jarred Sumner
2dc90f3908 Update worker.test-d.ts 2023-07-19 23:59:37 -07:00
Colin McDonnell
53ad9b922f Docs & types for 0.7 (#3665)
* Docs & types for 0.7

* Tweak

* Update

* Tweaks

* Tweak

* Tweaks

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2023-07-19 23:59:15 -07:00
Jarred Sumner
0b365781a8 Bump version to Bun v0.7.0 2023-07-19 23:57:41 -07:00
Jarred Sumner
dd46c11273 Support streams in response.formData() & request.formData, introduce Bun.readableStreamToFormData() (#3697)
* codegen

* FormData.from

* Fixes #3225

* Introduce `Bun.readableStreamToFormData`

* Update bun.d.ts

* Add examples

* add

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-19 23:12:06 -07:00
Jarred Sumner
8a13e02473 Fixes #3670 (#3698)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-19 23:04:07 -07:00
Jarred Sumner
ed8be46a7b Inlinebun object from workers 2023-07-19 22:53:28 -07:00
dave caruso
36866c4d79 Fix vite (#3694)
* Fix ServerWebSocket.readyState

* Add create_hash_table to our repo

* Fix #3216
2023-07-19 19:28:53 -07:00
dave caruso
dd58508684 Fix browser bundled string_decoder (#3693)
* Fix #3660

* doc fix
2023-07-19 17:37:20 -07:00
dave caruso
9b6dc49575 Implement AsyncLocalStorage (#3089)
* work to get async local storage working.

* a

* a

* everything but queueMicrotask

* sdfghj

* .

* finish

* tests

* test

* ok

* done

* im so stupid

* Upgrade WebKit

* refactor

* refactor

* changes requested

* oops

* cool

* fix runInAsyncScope
2023-07-19 17:20:00 -07:00
Jarred Sumner
723e9d1ea7 Fix make headers 2023-07-19 16:05:43 -07:00
Ciro Spaciari
f63398ffe4 update root certificates and add tls.rootCertificates (#3688)
* implement tls.rootCertificates

* add test

* bump uws/usockets

* bump uws + .len on certs
2023-07-19 16:02:29 -07:00
Ciro Spaciari
2fbf73535c fix createDecipheriv (#3680)
* fix createDecipheriv

* fix createDecipheriv iv and password validations
2023-07-19 16:01:36 -07:00
dave caruso
ebbbd63ed6 fix #3681 (#3690) 2023-07-19 15:58:07 -07:00
Dylan Conway
bc28ec39cf set did_panic flag (#3687) 2023-07-19 15:39:15 -07:00
Ciro Spaciari
568cadb51e move constants module to cpp (#3683) 2023-07-19 15:39:02 -07:00
Dylan Conway
0dbcb84cbe fix make headers 2023-07-19 15:26:14 -07:00
Jarred Sumner
d74d95d9ab Better error for workspace dependency not found (#3678) 2023-07-20 00:08:52 +03:00
Jarred Sumner
a59ddb131e Fix crash in postMessage that repro'd after ~100,000 messages 2023-07-18 23:09:39 -07:00
Jarred Sumner
8bd2b784a2 more progress on fixing gc issue 2023-07-18 20:49:11 -07:00
Dylan Conway
f494e1b50d add padding bytes 2023-07-18 16:30:58 -07:00
Ciro Spaciari
112f01ca61 feature(constants) add constants/node:constants module and tests(prisma) use prima 5.0.0 + use same connection for postgres, add prisma mssql (disabled for now) (#3672)
* use prima 5.0.0 + use same connection for postgres

* change mongodb test URL

* constants module + mssql prisma test (disabled)
2023-07-18 16:09:18 -07:00
Ciro Spaciari
49231b2cb9 patch checkServerIdentity (#3671) 2023-07-18 16:03:05 -07:00
Jarred Sumner
0179ebcb8c Update workers.md 2023-07-18 05:00:09 -07:00
Alex Lam S.L
1790357021 [jest] execute lifecycle hooks on empty blocks (#3663)
fixes #3494
2023-07-18 04:54:24 -07:00
Jarred Sumner
105919d7ae Clarify 2023-07-18 04:51:29 -07:00
Jarred Sumner
777ee4ecec Fixes #3669 2023-07-18 04:35:04 -07:00
Dylan Conway
661355546a zig upgrade (#3667)
* upgrade

* more fixes

* Bump Zig

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-18 01:20:20 -07:00
Jarred Sumner
71f1aa1802 Enable postgres prisma test 2023-07-17 23:17:06 -07:00
Jarred Sumner
eaff66b098 Emit writeBarrier in napi_module_register 2023-07-17 23:07:09 -07:00
Jarred Sumner
b760d1da30 Fix potential crash in process.dlopen() 2023-07-17 23:02:33 -07:00
Jarred Sumner
728c8fdcdb Implement process.{stdout, stderr}.{columns, rows, getWindowSize} 2023-07-17 21:21:43 -07:00
Ciro Spaciari
13b54fbdb8 [tls] General compatibility improvements (#3596)
* wip

* subjectaltname

* more progress

* bindings

* fmt

* getCert/getPeerCertificate

* fix checkServerIdentity

* fix checkServerIdentity

* add a lot of TLSSocket functions

* getEphemeralKeyInfo fix and comment

* add alternative for getEphemeralKeyInfo

* add get session and set session

* fix isSessionReused

* get back the raw data for MSSQL

* fixeup

* fixup getSession + tests

* fix doc + fmt

* getFinished/getPeerFinished

* codegen

* fixup

* revert webkit

* more fixes

* ssl helper + revert test oops

* asserts
2023-07-17 19:39:09 -07:00
Dylan Conway
9273e29f0e package json main field extension order (#3664) 2023-07-17 19:26:33 -07:00
Alex Lam S.L
9f031b3642 [install] handle duplicated workspace declarations gracefully (#3662)
fixes #3644
2023-07-17 16:06:31 -07:00
Colin McDonnell
ca3b7fa3c9 Clean up worker docs 2023-07-17 13:10:22 -07:00
Colin McDonnell
8a176913d8 Tweak test docs 2023-07-17 11:42:13 -07:00
Alex Lam S.L
570a44d73a workaround readable-stream compatibility (#3626)
- update `bun link` tests
- update `tests/bun.lockb`
- drop unused import in test
2023-07-17 20:05:01 +03:00
Jarred SUmner
5218a33fb6 Fix flaky process test 2023-07-17 04:51:26 -07:00
Jarred Sumner
58824ea743 Fix test with incorrect text 2023-07-17 04:44:56 -07:00
Jarred Sumner
99de971359 Fix incorrect name 2023-07-17 04:21:00 -07:00
Jarred Sumner
55b5aa3571 Fix speculative crashes in console.log(formData) and console.log(headers) 2023-07-17 04:18:43 -07:00
Jarred Sumner
6ca20424d6 Fix crash in console.log(urlSearchParams) on a URLSearchParams object with a lot of keys 2023-07-17 04:18:43 -07:00
Jarred Sumner
36a25c3580 Fix memory leak in await new Response(latin1String).arrayBuffer() and await Response.json(obj).json() (#3656)
❯ mem bun --smol response-arrayBuffer.mjs
cpu: Apple M1 Max
runtime: bun 0.6.15 (arm64-darwin)

benchmark                                                        time (avg)             (min … max)       p75       p99      p995
--------------------------------------------------------------------------------------------------- -----------------------------
new Response().arrayBuffer() (new string each call, latin1)    12.9 µs/iter      (625 ns … 4.18 ms)      1 µs 567.17 µs 711.79 µs
new Response().arrayBuffer() (new string each call, utf16)    12.85 µs/iter     (1.67 µs … 1.56 ms)   2.17 µs 462.75 µs 621.13 µs
new Response().arrayBuffer() (existing string, latin1)         6.53 µs/iter     (6.21 µs … 7.07 µs)   6.64 µs   7.07 µs   7.07 µs

Peak memory usage: 49 MB

bun on  jarred/memory-leak-fix took 2s
❯ mem bun response-arrayBuffer.mjs
cpu: Apple M1 Max
runtime: bun 0.6.15 (arm64-darwin)

benchmark                                                        time (avg)             (min … max)       p75       p99      p995
--------------------------------------------------------------------------------------------------- -----------------------------
new Response().arrayBuffer() (new string each call, latin1)     1.2 µs/iter     (1.04 µs … 1.42 µs)   1.22 µs   1.42 µs   1.42 µs
new Response().arrayBuffer() (new string each call, utf16)     2.74 µs/iter     (2.42 µs … 6.37 µs)   2.68 µs   6.37 µs   6.37 µs
new Response().arrayBuffer() (existing string, latin1)       746.37 ns/iter   (643.82 ns … 1.04 µs) 776.11 ns   1.04 µs   1.04 µs

Peak memory usage: 104 MB

bun on  jarred/memory-leak-fix took 2s
❯ mem ~/.bun/bin/bun response-arrayBuffer.mjs
cpu: Apple M1 Max
runtime: bun 0.6.15 (arm64-darwin)

benchmark                                                        time (avg)             (min … max)       p75       p99      p995
--------------------------------------------------------------------------------------------------- -----------------------------
new Response().arrayBuffer() (new string each call, latin1)    1.69 µs/iter      (1.56 µs … 2.1 µs)   1.73 µs    2.1 µs    2.1 µs
new Response().arrayBuffer() (new string each call, utf16)     2.65 µs/iter     (2.47 µs … 3.17 µs)   2.69 µs   3.17 µs   3.17 µs
new Response().arrayBuffer() (existing string, latin1)       667.67 ns/iter   (547.67 ns … 1.28 µs) 694.21 ns   1.28 µs   1.28 µs

Peak memory usage: 2735 MB

bun on  jarred/memory-leak-fix took 2s
❯ mem ~/.bun/bin/bun --smol response-arrayBuffer.mjs
cpu: Apple M1 Max
runtime: bun 0.6.15 (arm64-darwin)

benchmark                                                        time (avg)             (min … max)       p75       p99      p995
--------------------------------------------------------------------------------------------------- -----------------------------
new Response().arrayBuffer() (new string each call, latin1)   13.51 µs/iter       (541 ns … 3.2 ms)   1.92 µs 553.42 µs 709.92 µs
new Response().arrayBuffer() (new string each call, utf16)    13.07 µs/iter     (1.71 µs … 3.43 ms)   2.13 µs 451.21 µs 651.67 µs
new Response().arrayBuffer() (existing string, latin1)         6.25 µs/iter     (5.79 µs … 6.81 µs)    6.4 µs   6.81 µs   6.81 µs

Peak memory usage: 292 MB

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-17 04:15:13 -07:00
Jarred Sumner
13b5d9d4de 20% faster deserialize (#3655)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-17 02:22:00 -07:00
Jarred Sumner
fa4db1de42 Document --smol 2023-07-16 23:24:00 -07:00
Jarred Sumner
2a02f3d669 Add --smol to bunfig 2023-07-16 23:23:33 -07:00
Jarred Sumner
75213aad37 Document serialize/deserialize 2023-07-16 23:16:54 -07:00
Jarred Sumner
5856639833 Add serialize snippet 2023-07-16 23:16:38 -07:00
Jarred Sumner
edeb3b48e8 Fix test 2023-07-16 22:46:06 -07:00
Jarred Sumner
3613429dc3 Update workers.md 2023-07-16 22:43:38 -07:00
Jarred Sumner
7917ebd58f Fixes base64url encoding for crypto (#3654)
* Fixes base64url encoding for crypto

* 🍏

* Update nodejs-apis.md

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-16 22:42:19 -07:00
Jarred Sumner
a86d00c672 Update nav.ts 2023-07-16 21:43:22 -07:00
Jarred Sumner
d5c51092c8 rename 2023-07-16 21:40:07 -07:00
Jarred Sumner
6a234e6fce Add structuredClone microbenchmark 2023-07-16 21:17:55 -07:00
Jarred Sumner
dc766eb18a Add --smol flag 2023-07-16 21:17:47 -07:00
Jarred Sumner
209dc981c0 Implement Workers (#3645)
* copy files

* format

* options

* Introduce `Worker`, `onmessage`, `onerror`, and `postMessage` globals

* Stub `Worker.prototype.ref` & `Worker.prototype.unref`

* Update web_worker.zig

* Worker works

* Add "mini" mode

* add wakeup

* Partially fix the keep-alive issue

* clean up refer behavior

* Implement `serialize` & `deserialize` in `bun:jsc` & add polyfill for `node:v8`

* Types & docs

* Update globals.d.ts

* Add mutex

* Fixes

---------

Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-16 21:15:24 -07:00
Jarred Sumner
7fc392b182 Support napi_wrap in constructors (#3614)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-16 20:32:33 -07:00
Jarred Sumner
6baa08313c Fixes #3641 (#3643)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-07-16 20:32:18 -07:00
Jiri Spac
131ed06020 docs: add one missing line in typescript.md (#3650) 2023-07-16 20:31:54 -07:00
Dylan Conway
e546e4064c structuredClone types 2023-07-14 19:49:15 -07:00
Dylan Conway
c39c11e101 structured clone (#3637)
* copy `SerializedScriptValue`

* format

* make `SerializedScriptValue` compile

* add `transfer` option

* tests

* serialize/deserialize blobs

* tests for blobs

* serialize/deserialize file blobs

* more tests

* small cleanup

* format

* small changes + serialize offset

* slice helper

* map and set test
2023-07-14 19:37:22 -07:00
Colin McDonnell
2551210426 Update docs 2023-07-14 11:33:07 -07:00
Colin McDonnell
43abf2629f Remove fdatasync from types 2023-07-13 17:48:46 -07:00
Colin McDonnell
325147261f Update docs/types for process (#3631)
* Update docs/types for process

* Tweaks

* Tweaks

* Fix types
2023-07-13 17:40:46 -07:00
Tiramify (A.K. Daniel)
044b09afc2 Impl. fix (#3630) 2023-07-13 14:29:24 -07:00
Ashcon Partovi
9eb8eea2a8 Implement ping(), pong(), terminate() for WebSocket client and server (#3257) 2023-07-13 09:39:43 -07:00
Jarred Sumner
04b4157232 Fixes #3629 2023-07-13 02:57:25 -07:00
Jarred Sumner
a02a79e26c Bump WebKit 2023-07-12 20:48:52 -07:00
dave caruso
ae0a724981 Improve our internal typedefs (#3608)
* types

* some more

* yeah

* i think that fixes it

* oop
2023-07-12 15:21:55 -07:00
Tiramify (A.K. Daniel)
0631f87866 feat(bun/test): Implement "bail" option for "bun test" (#3253)
* Implement bun test --bail

* Fixes

* move printSummary() (more readable)

* Fixes 2

* idk why it got deleted

* Fixes 3

* fmt this better

* Update test_command.zig

* Fix "0 files"

* track number of files so bailing out early prints the right number

---------

Co-authored-by: dave caruso <me@paperdave.net>
2023-07-12 13:41:46 -07:00
Jarred Sumner
4e1a81231c Update build-id 2023-07-12 01:37:08 -07:00
654 changed files with 43526 additions and 14275 deletions

62
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,62 @@
### What does this PR do?
<!-- **Please explain what your changes do**, example: -->
<!--
This adds a new flag --bail to bun test. When set, it will stop running tests after the first failure. This is useful for CI environments where you want to fail fast.
-->
- [ ] Documentation or TypeScript types (it's okay to leave the rest blank in this case)
- [ ] Code changes
### How did you verify your code works?
<!-- **For code changes, please include automated tests**. Feel free to uncomment the line below -->
<!-- I wrote automated tests -->
<!-- If JavaScript/TypeScript modules or builtins changed:
- [ ] I ran `make js` and committed the transpiled changes
- [ ] I or my editor ran Prettier on the changed files (or I ran `bun fmt`)
- [ ] I included a test for the new code, or an existing test covers it
-->
<!-- If Zig files changed:
- [ ] I checked the lifetime of memory allocated to verify it's (1) freed and (2) only freed when it should be
- [ ] I or my editor ran `zig fmt` on the changed files
- [ ] I included a test for the new code, or an existing test covers it
- [ ] JSValue used outside outside of the stack is either wrapped in a JSC.Strong or is JSValueProtect'ed
-->
<!-- If new methods, getters, or setters were added to a publicly exposed class:
- [ ] I added TypeScript types for the new methods, getters, or setters
-->
<!-- If dependencies in tests changed:
- [ ] I made sure that specific versions of dependencies are used instead of ranged or tagged versions
-->
<!-- If functions were added to exports.zig or bindings.zig
- [ ] I ran `make headers` to regenerate the C header file
-->
<!-- If \*.classes.ts files were added or changed:
- [ ] I ran `make codegen` to regenerate the C++ and Zig code
-->
<!-- If a new builtin ESM/CJS module was added:
- [ ] I updated Aliases in `module_loader.zig` to include the new module
- [ ] I added a test that imports the module
- [ ] I added a test that require() the module
-->

View File

@@ -36,7 +36,7 @@ jobs:
arch: aarch64
build_arch: arm64
runner: linux-arm64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-arm64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-linux-arm64-lto.tar.gz"
webkit_basename: "bun-webkit-linux-arm64-lto"
build_machine_arch: aarch64

View File

@@ -46,7 +46,7 @@ jobs:
arch: x86_64
build_arch: amd64
runner: big-ubuntu
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-linux-amd64-lto.tar.gz"
webkit_basename: "bun-webkit-linux-amd64-lto"
build_machine_arch: x86_64
- cpu: nehalem
@@ -54,7 +54,7 @@ jobs:
arch: x86_64
build_arch: amd64
runner: big-ubuntu
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-linux-amd64-lto.tar.gz"
webkit_basename: "bun-webkit-linux-amd64-lto"
build_machine_arch: x86_64
@@ -193,9 +193,8 @@ jobs:
name: Test (node runner)
env:
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
# if: ${{github.event.inputs.use_bun == 'false'}}
run: |
bun install

View File

@@ -117,7 +117,7 @@ jobs:
# obj: bun-obj-darwin-x64-baseline
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: true
# compile_obj: false
# - cpu: haswell
@@ -126,7 +126,7 @@ jobs:
# obj: bun-obj-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: true
# compile_obj: false
# - cpu: nehalem
@@ -135,7 +135,7 @@ jobs:
# obj: bun-obj-darwin-x64-baseline
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: false
# compile_obj: true
# - cpu: haswell
@@ -144,7 +144,7 @@ jobs:
# obj: bun-obj-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: false
# compile_obj: true
- cpu: native
@@ -152,7 +152,7 @@ jobs:
tag: bun-darwin-aarch64
obj: bun-obj-darwin-aarch64
artifact: bun-obj-darwin-aarch64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-arm64-lto.tar.gz"
runner: macos-arm64
dependencies: true
compile_obj: true
@@ -257,7 +257,7 @@ jobs:
# package: bun-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# - cpu: haswell
# arch: x86_64
# tag: bun-darwin-x64
@@ -265,14 +265,14 @@ jobs:
# package: bun-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
- cpu: native
arch: aarch64
tag: bun-darwin-aarch64
obj: bun-obj-darwin-aarch64
package: bun-darwin-aarch64
artifact: bun-obj-darwin-aarch64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-arm64-lto.tar.gz"
runner: macos-arm64
steps:
- uses: actions/checkout@v3
@@ -432,9 +432,8 @@ jobs:
name: Test (node runner)
env:
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
# if: ${{github.event.inputs.use_bun == 'false'}}
run: |
bun install

View File

@@ -117,7 +117,7 @@ jobs:
obj: bun-obj-darwin-x64-baseline
runner: macos-11
artifact: bun-obj-darwin-x64-baseline
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
dependencies: true
compile_obj: false
# - cpu: haswell
@@ -126,7 +126,7 @@ jobs:
# obj: bun-obj-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: true
# compile_obj: false
- cpu: nehalem
@@ -135,7 +135,7 @@ jobs:
obj: bun-obj-darwin-x64-baseline
runner: macos-11
artifact: bun-obj-darwin-x64-baseline
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
dependencies: false
compile_obj: true
# - cpu: haswell
@@ -144,7 +144,7 @@ jobs:
# obj: bun-obj-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: false
# compile_obj: true
# - cpu: native
@@ -152,7 +152,7 @@ jobs:
# tag: bun-darwin-aarch64
# obj: bun-obj-darwin-aarch64
# artifact: bun-obj-darwin-aarch64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# runner: macos-arm64
# dependencies: true
# compile_obj: true
@@ -258,7 +258,7 @@ jobs:
package: bun-darwin-x64
runner: macos-11
artifact: bun-obj-darwin-x64-baseline
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# - cpu: haswell
# arch: x86_64
# tag: bun-darwin-x64
@@ -266,14 +266,14 @@ jobs:
# package: bun-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# - cpu: native
# arch: aarch64
# tag: bun-darwin-aarch64
# obj: bun-obj-darwin-aarch64
# package: bun-darwin-aarch64
# artifact: bun-obj-darwin-aarch64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# runner: macos-arm64
steps:
- uses: actions/checkout@v3
@@ -436,9 +436,8 @@ jobs:
name: Test (node runner)
env:
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
# if: ${{github.event.inputs.use_bun == 'false'}}
run: |
bun install

View File

@@ -117,7 +117,7 @@ jobs:
# obj: bun-obj-darwin-x64-baseline
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: true
# compile_obj: false
- cpu: haswell
@@ -126,7 +126,7 @@ jobs:
obj: bun-obj-darwin-x64
runner: macos-11
artifact: bun-obj-darwin-x64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
dependencies: true
compile_obj: false
# - cpu: nehalem
@@ -135,7 +135,7 @@ jobs:
# obj: bun-obj-darwin-x64-baseline
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# dependencies: false
# compile_obj: true
- cpu: haswell
@@ -144,7 +144,7 @@ jobs:
obj: bun-obj-darwin-x64
runner: macos-11
artifact: bun-obj-darwin-x64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
dependencies: false
compile_obj: true
# - cpu: native
@@ -152,7 +152,7 @@ jobs:
# tag: bun-darwin-aarch64
# obj: bun-obj-darwin-aarch64
# artifact: bun-obj-darwin-aarch64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-arm64-lto.tar.gz"
# runner: macos-arm64
# dependencies: true
# compile_obj: true
@@ -260,7 +260,7 @@ jobs:
# package: bun-darwin-x64
# runner: macos-11
# artifact: bun-obj-darwin-x64-baseline
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
- cpu: haswell
arch: x86_64
tag: bun-darwin-x64
@@ -268,14 +268,14 @@ jobs:
package: bun-darwin-x64
runner: macos-11
artifact: bun-obj-darwin-x64
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-amd64-lto.tar.gz"
# - cpu: native
# arch: aarch64
# tag: bun-darwin-aarch64
# obj: bun-obj-darwin-aarch64
# package: bun-darwin-aarch64
# artifact: bun-obj-darwin-aarch64
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/2023-july23/bun-webkit-macos-arm64-lto.tar.gz"
# runner: macos-arm64
steps:
- uses: actions/checkout@v3
@@ -438,9 +438,8 @@ jobs:
name: Test (node runner)
env:
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
# if: ${{github.event.inputs.use_bun == 'false'}}
run: |
bun install

View File

@@ -1,7 +1,7 @@
name: zig-fmt
env:
ZIG_VERSION: 0.11.0-dev.3737+9eb008717
ZIG_VERSION: 0.11.0-dev.4006+bf827d0b5
on:
pull_request:

2
.gitignore vendored
View File

@@ -123,3 +123,5 @@ cold-jsc-start.d
/test.ts
src/js/out/modules_dev
make-dev-stats.csv

View File

@@ -0,0 +1,21 @@
// I would have made this a bash script but there isn't an easy way to track
// time in bash sub-second cross platform.
import fs from "fs";
const start = Date.now() + 5;
const result = Bun.spawnSync(process.argv.slice(2), {
stdio: ["inherit", "inherit", "inherit"],
});
const end = Date.now();
const diff = (Math.max(Math.round(end - start), 0) / 1000).toFixed(3);
const success = result.exitCode === 0;
try {
const line = `${new Date().toISOString()}, ${success ? "success" : "fail"}, ${diff}\n`;
if (fs.existsSync(".scripts/make-dev-stats.csv")) {
fs.appendFileSync(".scripts/make-dev-stats.csv", line);
} else {
fs.writeFileSync(".scripts/make-dev-stats.csv", line);
}
} catch {
// Ignore
}
process.exit(result.exitCode);

1
.vscode/launch.json generated vendored
View File

@@ -242,7 +242,6 @@
"console": "internalConsole",
"env": {}
},
{
"type": "lldb",
"request": "launch",

View File

@@ -10,9 +10,9 @@ ARG ARCH=x86_64
ARG BUILD_MACHINE_ARCH=x86_64
ARG TRIPLET=${ARCH}-linux-gnu
ARG BUILDARCH=amd64
ARG WEBKIT_TAG=may20-3
ARG WEBKIT_TAG=2023-july23
ARG ZIG_TAG=jul1
ARG ZIG_VERSION="0.11.0-dev.3737+9eb008717"
ARG ZIG_VERSION="0.11.0-dev.4006+bf827d0b5"
ARG WEBKIT_BASENAME="bun-webkit-linux-$BUILDARCH"
ARG ZIG_FOLDERNAME=zig-linux-${BUILD_MACHINE_ARCH}-${ZIG_VERSION}
@@ -20,7 +20,7 @@ ARG ZIG_FILENAME=${ZIG_FOLDERNAME}.tar.xz
ARG WEBKIT_URL="https://github.com/oven-sh/WebKit/releases/download/$WEBKIT_TAG/${WEBKIT_BASENAME}.tar.gz"
ARG ZIG_URL="https://ziglang.org/builds/${ZIG_FILENAME}"
ARG GIT_SHA=""
ARG BUN_BASE_VERSION=0.6
ARG BUN_BASE_VERSION=0.7
FROM bitnami/minideb:bullseye as bun-base

View File

@@ -40,7 +40,7 @@ NATIVE_OR_OLD_MARCH = -march=nehalem
endif
MIN_MACOS_VERSION ?= $(DEFAULT_MIN_MACOS_VERSION)
BUN_BASE_VERSION = 0.6
BUN_BASE_VERSION = 0.7
CI ?= false
@@ -52,6 +52,8 @@ endif
BUN_OR_NODE = $(shell which bun 2>/dev/null || which node 2>/dev/null)
CXX_VERSION=c++2a
TRIPLET = $(OS_NAME)-$(ARCH_NAME)
PACKAGE_NAME = bun-$(TRIPLET)
@@ -684,8 +686,19 @@ require:
@which pkg-config > /dev/null || (echo -e "ERROR: pkg-config is required. Install with:\n\n $(POSIX_PKG_MANAGER) install pkg-config"; exit 1)
@echo "You have the dependencies installed! Woo"
init-submodules:
git submodule update --init --recursive --progress --depth=1 --checkout
# the following allows you to run `make submodule` to update or init submodules. but we will exclude webkit
# unless you explicity clone it yourself (a huge download)
SUBMODULE_NAMES=$(shell cat .gitmodules | grep 'path = ' | awk '{print $$3}')
ifeq ("$(wildcard src/bun.js/WebKit/.git)", "")
SUBMODULE_NAMES := $(filter-out src/bun.js/WebKit, $(SUBMODULE_NAMES))
endif
.PHONY: init-submodules
init-submodules: submodule # (backwards-compatibility alias)
.PHONY: submodule
submodule: ## to init or update all submodules
git submodule update --init --recursive --progress --depth=1 --checkout $(SUBMODULE_NAMES)
.PHONY: build-obj
build-obj:
@@ -1080,16 +1093,32 @@ test/wiptest/run: test/wiptest/run.o
release-bin-dir:
echo $(PACKAGE_DIR)
.PHONY: dev-obj-track
dev-obj-track:
bun .scripts/make-dev-timer.ts $(ZIG) build obj -freference-trace -Dcpu="$(CPU_TARGET)"
.PHONY: dev-obj-notrack
dev-obj-notrack:
$(ZIG) build obj -freference-trace -Dcpu="$(CPU_TARGET)"
.PHONY: dev-obj
dev-obj:
$(ZIG) build obj -freference-trace -Dcpu="$(CPU_TARGET)"
ifeq ($(shell which bun),)
dev-obj : dev-obj-notrack
else
dev-obj : dev-obj-track
endif
.PHONY: dev-obj-linux
dev-obj-linux:
$(ZIG) build obj -Dtarget=x86_64-linux-gnu -Dcpu="$(CPU_TARGET)"
.PHONY: dev
dev: mkdir-dev esm dev-obj link
dev: mkdir-dev esm dev-obj link ## compile zig changes + link bun
mkdir-dev:
mkdir -p $(DEBUG_PACKAGE_DIR)
@@ -1174,7 +1203,7 @@ jsc-build-mac-compile:
-DPORT="JSCOnly" \
-DENABLE_STATIC_JSC=ON \
-DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \
-DCMAKE_BUILD_TYPE=relwithdebuginfo \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_THIN_ARCHIVES=OFF \
-DBUN_FAST_TLS=ON \
-DENABLE_FTL_JIT=ON \
@@ -1241,7 +1270,7 @@ jsc-build-linux-compile-config:
cmake \
-DPORT="JSCOnly" \
-DENABLE_STATIC_JSC=ON \
-DCMAKE_BUILD_TYPE=relwithdebuginfo \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_THIN_ARCHIVES=OFF \
-DENABLE_FTL_JIT=ON \
-DENABLE_REMOTE_INSPECTOR=ON \
@@ -1364,9 +1393,8 @@ mimalloc-wasm:
.PHONY: bun-link-lld-debug
bun-link-lld-debug: link
# link a debug build of bun
.PHONY: link
link:
link: ## link a debug build of bun
$(CXX) $(BUN_LLD_FLAGS_DEBUG) $(DEBUG_FLAGS) $(SYMBOLS) \
-g \
$(DEBUG_BIN)/bun-debug.o \
@@ -1461,7 +1489,7 @@ generate-classes:
generate-sink:
bun src/bun.js/scripts/generate-jssink.js
$(CLANG_FORMAT) -i src/bun.js/bindings/JSSink.cpp src/bun.js/bindings/JSSink.h
$(WEBKIT_DIR)/Source/JavaScriptCore/create_hash_table src/bun.js/bindings/JSSink.cpp > src/bun.js/bindings/JSSinkLookupTable.h
./src/bun.js/scripts/create_hash_table src/bun.js/bindings/JSSink.cpp > src/bun.js/bindings/JSSinkLookupTable.h
$(SED) -i -e 's/#include "Lookup.h"//' src/bun.js/bindings/JSSinkLookupTable.h
$(SED) -i -e 's/namespace JSC {//' src/bun.js/bindings/JSSinkLookupTable.h
$(SED) -i -e 's/} \/\/ namespace JSC//' src/bun.js/bindings/JSSinkLookupTable.h
@@ -1791,7 +1819,7 @@ endif
endif
.PHONY: build-unit
build-unit: ## to build your unit tests
build-unit: # to build your unit tests
@rm -rf zig-out/bin/$(testname)
@mkdir -p zig-out/bin
zig test $(realpath $(testpath)) \
@@ -1809,7 +1837,7 @@ build-unit: ## to build your unit tests
cp zig-out/bin/$(testname) $(testbinpath)
.PHONY: run-all-unit-tests
run-all-unit-tests: ## to run your unit tests
run-all-unit-tests: # to run your unit tests
@rm -rf zig-out/bin/__main_test
@mkdir -p zig-out/bin
zig test src/main.zig \
@@ -1829,15 +1857,11 @@ run-all-unit-tests: ## to run your unit tests
run-unit:
@zig-out/bin/$(testname) $(ZIG)
.PHONY: help
help: ## to print this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {gsub("\\\\n",sprintf("\n%22c",""), $$2);printf "\033[36m%-20s\033[0m \t\t%s\n", $$1, $$2}' $(MAKEFILE_LIST)
.PHONY: test
test: build-unit run-unit
.PHONY: integration-test-dev
integration-test-dev: ## to run integration tests
integration-test-dev: # to run integration tests
USE_EXISTING_PROCESS=true TEST_SERVER_URL=http://localhost:3000 node test/scripts/browser.js
copy-install:
@@ -1880,16 +1904,16 @@ vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimallo
vendor-without-check: npm-install vendor-without-npm
.PHONY: vendor
vendor: require init-submodules vendor-without-check
vendor: require submodule vendor-without-check
.PHONY: vendor-dev
vendor-dev: require init-submodules npm-install-dev vendor-without-npm
vendor-dev: require submodule npm-install-dev vendor-without-npm
.PHONY: bun
bun: vendor identifier-cache build-obj bun-link-lld-release bun-codesign-release-local
.PHONY: regenerate-bindings
regenerate-bindings:
regenerate-bindings: ## compile src/js/builtins + all c++ code, does not link
@make clean-bindings builtins
@make bindings -j$(CPU_COUNT)
@@ -1901,3 +1925,8 @@ setup: vendor-dev identifier-cache clean-bindings
@echo "Development environment setup complete"
@echo "Run \`make dev\` to build \`bun-debug\`"
@echo ""
.PHONY: help
help: ## to print this help
@echo "For detailed build instructions, see https://bun.sh/docs/project/development"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {gsub("\\\\n",sprintf("\n%22c",""), $$2);printf "\033[36m%-20s\033[0m \t\t%s\n", $$1, $$2}' $(MAKEFILE_LIST)

View File

@@ -0,0 +1,30 @@
// https://github.com/nodejs/node/issues/34493
import { AsyncLocalStorage } from "async_hooks";
const asyncLocalStorage = new AsyncLocalStorage();
// let fn = () => Promise.resolve(2).then(() => new Promise(resolve => queueMicrotask(resolve)));
let fn = () => /test/.test("test");
let runWithExpiry = async (expiry, fn) => {
let iterations = 0;
while (Date.now() < expiry) {
await fn();
iterations++;
}
return iterations;
};
console.log(`Performed ${await runWithExpiry(Date.now() + 1000, fn)} iterations to warmup`);
let withAls;
await asyncLocalStorage.run(123, async () => {
withAls = await runWithExpiry(Date.now() + 45000, fn);
console.log(`Performed ${withAls} iterations (with ALS enabled)`);
});
asyncLocalStorage.disable();
let withoutAls = await runWithExpiry(Date.now() + 45000, fn);
console.log(`Performed ${withoutAls} iterations (with ALS disabled)`);
console.log("ALS penalty: " + Math.round((1 - withAls / withoutAls) * 10000) / 100 + "%");

View File

@@ -3,6 +3,6 @@
"module": "index.ts",
"type": "module",
"devDependencies": {
"bun-types": "^0.5.0"
"bun-types": "^0.7.0"
}
}
}

View File

@@ -43,7 +43,7 @@ pub fn main() anyerror!void {
var position = try std.fmt.parseInt(u32, position_str, 10);
const filepath = try std.fs.path.resolve(allocator, &.{basepath});
var file = try std.fs.openFileAbsolute(filepath, .{ .write = true });
var ms = @truncate(u64, (try std.fmt.parseInt(u128, args[args.len - 1], 10)) * std.time.ns_per_ms);
var ms = @as(u64, @truncate((try std.fmt.parseInt(u128, args[args.len - 1], 10)) * std.time.ns_per_ms));
std.debug.assert(ms > 0);
// std.debug.assert(std.math.isFinite(position));
var prng = std.rand.DefaultPrng.init(0);
@@ -125,30 +125,30 @@ pub fn main() anyerror!void {
);
};
counters[counter].timestamp = @truncate(u64, @intCast(u128, std.time.nanoTimestamp()) / (std.time.ns_per_ms / 10));
counters[counter].timestamp = @as(u64, @truncate(@as(u128, @intCast(std.time.nanoTimestamp())) / (std.time.ns_per_ms / 10)));
counters[counter].rotate = rotate % 360;
counters[counter].percent = std.math.mod(f64, std.math.round(((progress_bar + 1.0) / destination_count) * 1000) / 1000, 100) catch 0;
counters[counter].color_values[0] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][0] + 1) % 256)) * 0.8));
counters[counter].color_values[1] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][1] + 1) % 256)) * 0.8));
counters[counter].color_values[2] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][2] + 1) % 256)) * 0.8));
counters[counter].color_values[0] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[1] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[2] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[3] = (colors[0][0] + 1) % 256;
counters[counter].color_values[4] = (colors[0][1] + 1) % 256;
counters[counter].color_values[5] = (colors[0][2] + 1) % 256;
counters[counter].color_values[6] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][0] + 1) % 256)) * 0.8));
counters[counter].color_values[7] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][1] + 1) % 256)) * 0.8));
counters[counter].color_values[8] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][2] + 1) % 256)) * 0.8));
counters[counter].color_values[6] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[7] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[8] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[9] = (colors[1][0] + 1) % 256;
counters[counter].color_values[10] = (colors[1][1] + 1) % 256;
counters[counter].color_values[11] = (colors[1][2] + 1) % 256;
counters[counter].color_values[12] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][0] + 1) % 256)) * 0.8));
counters[counter].color_values[13] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][1] + 1) % 256)) * 0.8));
counters[counter].color_values[14] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][2] + 1) % 256)) * 0.8));
counters[counter].color_values[12] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[13] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[14] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[15] = (colors[2][0] + 1) % 256;
counters[counter].color_values[16] = (colors[2][1] + 1) % 256;
counters[counter].color_values[17] = (colors[2][2] + 1) % 256;
counters[counter].color_values[18] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][0] + 1) % 256)) * 0.8));
counters[counter].color_values[19] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][1] + 1) % 256)) * 0.8));
counters[counter].color_values[20] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][2] + 1) % 256)) * 0.8));
counters[counter].color_values[18] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[19] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[20] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[21] = (colors[3][0] + 1) % 256;
counters[counter].color_values[22] = (colors[3][1] + 1) % 256;
counters[counter].color_values[23] = (colors[3][2] + 1) % 256;

View File

@@ -43,7 +43,7 @@ pub fn main() anyerror!void {
var position = try std.fmt.parseInt(u32, position_str, 10);
const filepath = try std.fs.path.resolve(allocator, &.{basepath});
var file = try std.fs.openFileAbsolute(filepath, .{ .write = true });
var ms = @truncate(u64, (try std.fmt.parseInt(u128, args[args.len - 1], 10)) * std.time.ns_per_ms);
var ms = @as(u64, @truncate((try std.fmt.parseInt(u128, args[args.len - 1], 10)) * std.time.ns_per_ms));
std.debug.assert(ms > 0);
// std.debug.assert(std.math.isFinite(position));
var prng = std.rand.DefaultPrng.init(0);
@@ -112,30 +112,30 @@ pub fn main() anyerror!void {
\\
++ SIMULATE_LONG_FILE;
counters[counter].timestamp = @truncate(u64, @intCast(u128, std.time.nanoTimestamp()) / (std.time.ns_per_ms / 10));
counters[counter].timestamp = @as(u64, @truncate(@as(u128, @intCast(std.time.nanoTimestamp())) / (std.time.ns_per_ms / 10)));
counters[counter].rotate = rotate % 360;
counters[counter].percent = std.math.mod(f64, std.math.round(((progress_bar + 1.0) / destination_count) * 1000) / 1000, 100) catch 0;
counters[counter].color_values[0] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][0] + 1) % 256)) * 0.8));
counters[counter].color_values[1] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][1] + 1) % 256)) * 0.8));
counters[counter].color_values[2] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[0][2] + 1) % 256)) * 0.8));
counters[counter].color_values[0] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[1] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[2] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[0][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[3] = (colors[0][0] + 1) % 256;
counters[counter].color_values[4] = (colors[0][1] + 1) % 256;
counters[counter].color_values[5] = (colors[0][2] + 1) % 256;
counters[counter].color_values[6] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][0] + 1) % 256)) * 0.8));
counters[counter].color_values[7] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][1] + 1) % 256)) * 0.8));
counters[counter].color_values[8] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[1][2] + 1) % 256)) * 0.8));
counters[counter].color_values[6] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[7] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[8] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[1][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[9] = (colors[1][0] + 1) % 256;
counters[counter].color_values[10] = (colors[1][1] + 1) % 256;
counters[counter].color_values[11] = (colors[1][2] + 1) % 256;
counters[counter].color_values[12] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][0] + 1) % 256)) * 0.8));
counters[counter].color_values[13] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][1] + 1) % 256)) * 0.8));
counters[counter].color_values[14] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[2][2] + 1) % 256)) * 0.8));
counters[counter].color_values[12] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[13] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[14] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[2][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[15] = (colors[2][0] + 1) % 256;
counters[counter].color_values[16] = (colors[2][1] + 1) % 256;
counters[counter].color_values[17] = (colors[2][2] + 1) % 256;
counters[counter].color_values[18] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][0] + 1) % 256)) * 0.8));
counters[counter].color_values[19] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][1] + 1) % 256)) * 0.8));
counters[counter].color_values[20] = @intFromFloat(u32, std.math.round(@floatFromInt(f64, ((colors[3][2] + 1) % 256)) * 0.8));
counters[counter].color_values[18] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][0] + 1) % 256))) * 0.8)));
counters[counter].color_values[19] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][1] + 1) % 256))) * 0.8)));
counters[counter].color_values[20] = @as(u32, @intFromFloat(std.math.round(@as(f64, @floatFromInt(((colors[3][2] + 1) % 256))) * 0.8)));
counters[counter].color_values[21] = (colors[3][0] + 1) % 256;
counters[counter].color_values[22] = (colors[3][1] + 1) % 256;
counters[counter].color_values[23] = (colors[3][2] + 1) % 256;

View File

@@ -5,4 +5,4 @@
"jsx": "react-jsx",
"paths": {}
}
}
}

View File

@@ -1,4 +1,4 @@
import { bench, run } from "../node_modules/mitata/src/cli.mjs";
import { bench, run } from "mitata";
bench("noop", function () {});
bench("async function(){}", async function () {});

View File

@@ -0,0 +1,15 @@
// This mostly exists to check for a memory leak in response.clone()
import { bench, run } from "./runner.mjs";
const req = new Request("http://localhost:3000/");
const resp = await fetch("http://example.com");
bench("req.clone().url", () => {
return req.clone().url;
});
bench("resp.clone().url", () => {
return resp.clone().url;
});
await run();

View File

@@ -0,0 +1,136 @@
// This snippet mostly exists to reproduce a memory leak
//
import { bench, run } from "mitata";
const obj = {
"id": 1296269,
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"owner": {
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false,
},
"private": false,
"html_url": "https://github.com/octocat/Hello-World",
"description": "This your first repo!",
"fork": false,
"url": "https://api.github.com/repos/octocat/Hello-World",
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
"git_url": "git:github.com/octocat/Hello-World.git",
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
"ssh_url": "git@github.com:octocat/Hello-World.git",
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
"clone_url": "https://github.com/octocat/Hello-World.git",
"mirror_url": "git:git.example.com/octocat/Hello-World",
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
"svn_url": "https://svn.github.com/octocat/Hello-World",
"homepage": "https://github.com",
"language": null,
"forks_count": 9,
"stargazers_count": 80,
"watchers_count": 80,
"size": 108,
"default_branch": "master",
"open_issues_count": 0,
"is_template": false,
"topics": ["octocat", "atom", "electron", "api"],
"has_issues": true,
"has_projects": true,
"has_wiki": true,
"has_pages": false,
"has_downloads": true,
"has_discussions": false,
"archived": false,
"disabled": false,
"visibility": "public",
"pushed_at": "2011-01-26T19:06:43Z",
"created_at": "2011-01-26T19:01:12Z",
"updated_at": "2011-01-26T19:14:43Z",
"permissions": {
"admin": false,
"push": false,
"pull": true,
},
"security_and_analysis": {
"advanced_security": {
"status": "enabled",
},
"secret_scanning": {
"status": "enabled",
},
"secret_scanning_push_protection": {
"status": "disabled",
},
},
};
// Force the string to be 8bit
const str = String.fromCharCode(
...JSON.stringify(obj)
.split("")
.map(a => a.charCodeAt(0)),
);
var i = 0;
bench("new Response().arrayBuffer() (new string each call, latin1)", async () => {
return await new Response(str + i++).arrayBuffer();
});
bench("new Response().arrayBuffer() (new string each call, utf16)", async () => {
return await new Response(str + i++ + "😊").arrayBuffer();
});
bench("new Response().arrayBuffer() (existing string, latin1)", async () => {
return await new Response(str).arrayBuffer();
});
await run();

View File

@@ -0,0 +1,123 @@
// This snippet mostly exists to reproduce a memory leak
import { bench, run } from "mitata";
const obj = {
"id": 1296269,
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"owner": {
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false,
},
"private": false,
"html_url": "https://github.com/octocat/Hello-World",
"description": "This your first repo!",
"fork": false,
"url": "https://api.github.com/repos/octocat/Hello-World",
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
"git_url": "git:github.com/octocat/Hello-World.git",
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
"ssh_url": "git@github.com:octocat/Hello-World.git",
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
"clone_url": "https://github.com/octocat/Hello-World.git",
"mirror_url": "git:git.example.com/octocat/Hello-World",
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
"svn_url": "https://svn.github.com/octocat/Hello-World",
"homepage": "https://github.com",
"language": null,
"forks_count": 9,
"stargazers_count": 80,
"watchers_count": 80,
"size": 108,
"default_branch": "master",
"open_issues_count": 0,
"is_template": false,
"topics": ["octocat", "atom", "electron", "api"],
"has_issues": true,
"has_projects": true,
"has_wiki": true,
"has_pages": false,
"has_downloads": true,
"has_discussions": false,
"archived": false,
"disabled": false,
"visibility": "public",
"pushed_at": "2011-01-26T19:06:43Z",
"created_at": "2011-01-26T19:01:12Z",
"updated_at": "2011-01-26T19:14:43Z",
"permissions": {
"admin": false,
"push": false,
"pull": true,
},
"security_and_analysis": {
"advanced_security": {
"status": "enabled",
},
"secret_scanning": {
"status": "enabled",
},
"secret_scanning_push_protection": {
"status": "disabled",
},
},
};
bench("Response.json(obj)", async () => {
return Response.json(obj);
});
bench("Response.json(obj).json()", async () => {
return await Response.json(obj).json();
});
await run();

View File

@@ -0,0 +1 @@
for (let i = 0; i < 9999999; i++) new Request("http://aaaaaaaaaaaaaaaaaaaaa");

View File

@@ -0,0 +1,128 @@
import { serialize, deserialize } from "node:v8";
import { bench, run } from "./runner.mjs";
const obj = {
"id": 1296269,
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"owner": {
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false,
},
"private": false,
"html_url": "https://github.com/octocat/Hello-World",
"description": "This your first repo!",
"fork": false,
"url": "https://api.github.com/repos/octocat/Hello-World",
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
"git_url": "git:github.com/octocat/Hello-World.git",
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
"ssh_url": "git@github.com:octocat/Hello-World.git",
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
"clone_url": "https://github.com/octocat/Hello-World.git",
"mirror_url": "git:git.example.com/octocat/Hello-World",
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
"svn_url": "https://svn.github.com/octocat/Hello-World",
"homepage": "https://github.com",
"language": null,
"forks_count": 9,
"stargazers_count": 80,
"watchers_count": 80,
"size": 108,
"default_branch": "master",
"open_issues_count": 0,
"is_template": false,
"topics": ["octocat", "atom", "electron", "api"],
"has_issues": true,
"has_projects": true,
"has_wiki": true,
"has_pages": false,
"has_downloads": true,
"has_discussions": false,
"archived": false,
"disabled": false,
"visibility": "public",
"pushed_at": "2011-01-26T19:06:43Z",
"created_at": "2011-01-26T19:01:12Z",
"updated_at": "2011-01-26T19:14:43Z",
"permissions": {
"admin": false,
"push": false,
"pull": true,
},
"security_and_analysis": {
"advanced_security": {
"status": "enabled",
},
"secret_scanning": {
"status": "enabled",
},
"secret_scanning_push_protection": {
"status": "disabled",
},
},
};
bench("serialize", () => {
serialize(obj);
});
const serialized = serialize(obj);
bench("deserialize", () => {
deserialize(serialized);
});
if (typeof Bun !== "undefined") {
if (!Bun.deepEquals(obj, deserialize(serialized))) {
throw new Error("not equal");
}
}
await run();

View File

@@ -0,0 +1,39 @@
var testArray = [
{
description: "Random description.",
testNumber: 123456789,
testBoolean: true,
testObject: {
testString: "test string",
testNumber: 12345,
},
testArray: [
{
myName: "test name",
myNumber: 123245,
},
],
},
{
description: "Random description.",
testNumber: 123456789,
testBoolean: true,
testObject: {
testString: "test string",
testNumber: 12345,
},
testArray: [
{
myName: "test name",
myNumber: 123245,
},
],
},
];
import { bench, run } from "./runner.mjs";
bench("structuredClone(array)", () => structuredClone(testArray));
bench("structuredClone(123)", () => structuredClone(123));
bench("structuredClone({a: 123})", () => structuredClone({ a: 123 }));
await run();

View File

@@ -0,0 +1,20 @@
import { group } from "mitata";
import { bench, run } from "./runner.mjs";
const sizes = [
["small (63 bytes)", 63],
["medium (4096 bytes)", 4096],
["large (64 MB)", 64 * 1024 * 1024],
];
for (let [name, size] of sizes) {
group(name, () => {
var buf = new Uint8Array(size);
for (let algorithm of ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]) {
bench(algorithm, async () => {
await crypto.subtle.digest(algorithm, buf);
});
}
});
}
await run();

Binary file not shown.

View File

@@ -1,7 +1,7 @@
{
"name": "bench",
"dependencies": {
"better-sqlite3": "^8.0.1"
"better-sqlite3": "8.5.0"
},
"scripts": {
"build": "exit 0",

View File

@@ -2,7 +2,7 @@
This benchmarks a websocket server intended as a simple but very active chat room.
First, start the server. By default, it will wait for 16 clients which the client script will handle.
First, start the server. By default, it will wait for 32 clients which the client script will handle.
Run in Bun (`Bun.serve`):
@@ -19,10 +19,10 @@ node ./chat-server.node.mjs
Run in Deno (`Deno.serve`):
```bash
deno run -A --unstable ./chat-server.deno.mjs
deno run -A ./chat-server.deno.mjs
```
Then, run the client script. By default, it will connect 16 clients. This client script can run in Bun, Node, or Deno
Then, run the client script. By default, it will connect 32 clients. This client script can run in Bun, Node, or Deno
```bash
node ./chat-client.mjs
@@ -34,6 +34,4 @@ For example, when the client sends `"foo"`, the server sends back `"John: foo"`
The client script waits until it receives all the messages for each client before sending the next batch of messages.
TODO: once Deno lands their performance improvements, increase the client count (it was originally going to be 32 or 64, but that would've exluded Deno from the benchmark)
This project was created using `bun init` in bun v0.2.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.

Binary file not shown.

View File

@@ -3,7 +3,7 @@ const env = "process" in globalThis ? process.env : "Deno" in globalThis ? Deno.
const SERVER = env.SERVER || "ws://0.0.0.0:4001";
const WebSocket = globalThis.WebSocket || (await import("ws")).WebSocket;
const LOG_MESSAGES = env.LOG_MESSAGES === "1";
const CLIENTS_TO_WAIT_FOR = parseInt(env.CLIENTS_COUNT || "", 10) || 16;
const CLIENTS_TO_WAIT_FOR = parseInt(env.CLIENTS_COUNT || "", 10) || 32;
const DELAY = 64;
const MESSAGES_TO_SEND = Array.from({ length: 32 }, () => [
"Hello World!",

View File

@@ -1,5 +1,5 @@
// See ./README.md for instructions on how to run this benchmark.
const CLIENTS_TO_WAIT_FOR = parseInt(process.env.CLIENTS_COUNT || "", 10) || 16;
const CLIENTS_TO_WAIT_FOR = parseInt(process.env.CLIENTS_COUNT || "", 10) || 32;
var remainingClients = CLIENTS_TO_WAIT_FOR;
const COMPRESS = process.env.COMPRESS === "1";
const port = process.PORT || 4001;

View File

@@ -1,6 +1,6 @@
// See ./README.md for instructions on how to run this benchmark.
const port = Deno.env.get("PORT") || 4001;
const CLIENTS_TO_WAIT_FOR = parseInt(Deno.env.get("CLIENTS_COUNT") || "", 10) || 16;
const CLIENTS_TO_WAIT_FOR = parseInt(Deno.env.get("CLIENTS_COUNT") || "", 10) || 32;
var clients = [];
async function reqHandler(req) {

View File

@@ -1,6 +1,6 @@
// See ./README.md for instructions on how to run this benchmark.
const port = process.env.PORT || 4001;
const CLIENTS_TO_WAIT_FOR = parseInt(process.env.CLIENTS_COUNT || "", 10) || 16;
const CLIENTS_TO_WAIT_FOR = parseInt(process.env.CLIENTS_COUNT || "", 10) || 32;
import { createRequire } from "module";
const require = createRequire(import.meta.url);

View File

@@ -3,8 +3,8 @@
"module": "index.ts",
"type": "module",
"dependencies": {
"bufferutil": "^4.0.7",
"utf-8-validate": "^5.0.10",
"ws": "^8.9.0"
"bufferutil": "4.0.7",
"utf-8-validate": "6.0.3",
"ws": "8.13.0"
}
}

View File

@@ -1,6 +1,6 @@
const std = @import("std");
const Wyhash = @import("./src/wyhash.zig").Wyhash;
var is_debug_build = false;
fn moduleSource(comptime out: []const u8) FileSource {
if (comptime std.fs.path.dirname(@src().file)) |base| {
const outpath = comptime base ++ std.fs.path.sep_str ++ out;
@@ -9,27 +9,6 @@ fn moduleSource(comptime out: []const u8) FileSource {
return FileSource.relative(out);
}
}
pub fn addPicoHTTP(step: *CompileStep, comptime with_obj: bool) void {
step.addIncludePath("src/deps");
if (with_obj) {
step.addObjectFile("src/deps/picohttpparser.o");
}
step.addIncludePath("src/deps");
if (with_obj) {
step.addObjectFile(panicIfNotFound("src/deps/picohttpparser.o"));
step.addObjectFile(panicIfNotFound("src/deps/libssl.a"));
step.addObjectFile(panicIfNotFound("src/deps/libcrypto.a"));
}
// step.add("/Users/jarred/Code/WebKit/WebKitBuild/Release/lib/libWTF.a");
// ./Tools/Scripts/build-jsc --jsc-only --cmakeargs="-DENABLE_STATIC_JSC=ON"
// set -gx ICU_INCLUDE_DIRS "/usr/local/opt/icu4c/include"
// homebrew-provided icu4c
}
const color_map = std.ComptimeStringMap([]const u8, .{
&.{ "black", "30m" },
@@ -76,18 +55,31 @@ const BunBuildOptions = struct {
fallback_html_version: u64 = 0,
pub fn updateRuntime(this: *BunBuildOptions) anyerror!void {
var runtime_out_file = try std.fs.cwd().openFile("src/runtime.out.js", .{ .mode = .read_only });
const runtime_hash = Wyhash.hash(
0,
try runtime_out_file.readToEndAlloc(std.heap.page_allocator, try runtime_out_file.getEndPos()),
);
this.runtime_js_version = runtime_hash;
var fallback_out_file = try std.fs.cwd().openFile("src/fallback.out.js", .{ .mode = .read_only });
const fallback_hash = Wyhash.hash(
0,
try fallback_out_file.readToEndAlloc(std.heap.page_allocator, try fallback_out_file.getEndPos()),
);
this.fallback_html_version = fallback_hash;
if (std.fs.cwd().openFile("src/runtime.out.js", .{ .mode = .read_only })) |file| {
defer file.close();
const runtime_hash = Wyhash.hash(
0,
try file.readToEndAlloc(std.heap.page_allocator, try file.getEndPos()),
);
this.runtime_js_version = runtime_hash;
} else |_| {
if (!is_debug_build) {
@panic("Runtime file was not read successfully. Please run `make setup`");
}
}
if (std.fs.cwd().openFile("src/fallback.out.js", .{ .mode = .read_only })) |file| {
defer file.close();
const fallback_hash = Wyhash.hash(
0,
try file.readToEndAlloc(std.heap.page_allocator, try file.getEndPos()),
);
this.fallback_html_version = fallback_hash;
} else |_| {
if (!is_debug_build) {
@panic("Fallback file was not read successfully. Please run `make setup`");
}
}
}
pub fn step(this: BunBuildOptions, b: anytype) *std.build.OptionsStep {
@@ -187,6 +179,7 @@ pub fn build(b: *Build) !void {
}
std.fs.cwd().makePath(output_dir) catch {};
is_debug_build = optimize == OptimizeMode.Debug;
const bun_executable_name = if (optimize == std.builtin.OptimizeMode.Debug) "bun-debug" else "bun";
const root_src = if (target.getOsTag() == std.Target.Os.Tag.freestanding)
"src/main_wasm.zig"
@@ -247,7 +240,6 @@ pub fn build(b: *Build) !void {
};
{
addPicoHTTP(obj, false);
obj.setMainPkgPath(b.pathFromRoot("."));
try addInternalPackages(
@@ -468,8 +460,6 @@ pub fn configureObjectStep(b: *std.build.Builder, obj: *CompileStep, comptime Ta
// obj.setTarget(target);
try addInternalPackages(b, obj, std.heap.page_allocator, b.zig_exe, target);
if (target.getOsTag() != .freestanding)
addPicoHTTP(obj, false);
obj.strip = false;

BIN
bun.lockb

Binary file not shown.

View File

@@ -12,7 +12,7 @@ The second argument to `Bun.spawn` is a parameters object that can be used to co
```ts
const proc = Bun.spawn(["echo", "hello"], {
cwd: "./path/to/subdir", // specify a working direcory
cwd: "./path/to/subdir", // specify a working directory
env: { ...process.env, FOO: "bar" }, // specify environment variables
onExit(proc, exitCode, signalCode, error) {
// exit handler

View File

@@ -75,7 +75,7 @@ Note: `close()` is called automatically when the database is garbage collected.
```ts
const olddb = new Database("mydb.sqlite");
const contents = olddb.serialize(); // => Uint8Array
const newdb = new Database(contents);
const newdb = Database.deserialize(contents);
```
Internally, `.serialize()` calls [`sqlite3_serialize`](https://www.sqlite.org/c3ref/serialize.html).
@@ -250,7 +250,7 @@ Transactions are a mechanism for executing multiple queries in an _atomic_ way;
```ts
const insertCat = db.prepare("INSERT INTO cats (name) VALUES ($name)");
const insertCats = db.transaction((cats) => {
const insertCats = db.transaction(cats => {
for (const cat of cats) insertCat.run(cat);
});
```
@@ -261,7 +261,7 @@ To execute the transaction, call this function. All arguments will be passed thr
```ts
const insert = db.prepare("INSERT INTO cats (name) VALUES ($name)");
const insertCats = db.transaction((cats) => {
const insertCats = db.transaction(cats => {
for (const cat of cats) insert.run(cat);
return cats.length;
});
@@ -296,11 +296,11 @@ const insertExpense = db.prepare(
"INSERT INTO expenses (note, dollars) VALUES (?, ?)",
);
const insert = db.prepare("INSERT INTO cats (name, age) VALUES ($name, $age)");
const insertCats = db.transaction((cats) => {
const insertCats = db.transaction(cats => {
for (const cat of cats) insert.run(cat);
});
const adopt = db.transaction((cats) => {
const adopt = db.transaction(cats => {
insertExpense.run("adoption fees", 20);
insertCats(cats); // nested transaction
});

View File

@@ -149,7 +149,9 @@ test("peek", () => {
// If we peek a rejected promise, it:
// - returns the error
// - does not mark the promise as handled
const rejected = Promise.reject(new Error("Successfully tested promise rejection"));
const rejected = Promise.reject(
new Error("Successfully tested promise rejection"),
);
expect(peek(rejected).message).toBe("Successfully tested promise rejection");
});
```
@@ -245,7 +247,7 @@ Bun.deepEquals(new Foo(), { a: 1 }, true); // false
## `Bun.escapeHTML()`
`Bun.escapeHTML(value: string | object | number | boolean): boolean`
`Bun.escapeHTML(value: string | object | number | boolean): string`
Escapes the following characters from an input string:
@@ -283,7 +285,7 @@ console.log(url); // "file:///foo/bar.txt"
## `Bun.gzipSync()`
Compresses a `Uint8Array` using zlib's DEFLATE algorithm.
Compresses a `Uint8Array` using zlib's GZIP algorithm.
```ts
const buf = Buffer.from("hello".repeat(100)); // Buffer extends Uint8Array
@@ -372,7 +374,7 @@ export type ZlibCompressionOptions = {
## `Bun.gunzipSync()`
Uncompresses a `Uint8Array` using zlib's INFLATE algorithm.
Decompresses a `Uint8Array` using zlib's GUNZIP algorithm.
```ts
const buf = Buffer.from("hello".repeat(100)); // Buffer extends Uint8Array
@@ -400,15 +402,15 @@ The second argument supports the same set of configuration options as [`Bun.gzip
## `Bun.inflateSync()`
Uncompresses a `Uint8Array` using zlib's INFLATE algorithm.
Decompresses a `Uint8Array` using zlib's INFLATE algorithm.
```ts
const buf = Buffer.from("hello".repeat(100));
const compressed = Bun.deflateSync(buf);
const dec = new TextDecoder();
const uncompressed = Bun.inflateSync(compressed);
dec.decode(uncompressed);
const decompressed = Bun.inflateSync(compressed);
dec.decode(decompressed);
// => "hellohellohello..."
```
@@ -458,6 +460,12 @@ await Bun.readableStreamToText(stream);
// returns all chunks as an array
await Bun.readableStreamToArray(stream);
// => unknown[]
// returns all chunks as a FormData object (encoded as x-www-form-urlencoded)
await Bun.readableStreamToFormData(stream);
// returns all chunks as a FormData object (encoded as multipart/form-data)
await Bun.readableStreamToFormData(stream, multipartFormBoundary);
```
## `Bun.resolveSync()`
@@ -484,3 +492,17 @@ To resolve relative to the directory containing the current file, pass `import.m
```ts
Bun.resolveSync("./foo.ts", import.meta.dir);
```
## `serialize` & `deserialize` in `bun:jsc`
To save a JavaScript value into an ArrayBuffer & back, use `serialize` and `deserialize` from the `"bun:jsc"` module.
```js
import { serialize, deserialize } from "bun:jsc";
const buf = serialize({ foo: "bar" });
const obj = deserialize(buf);
console.log(obj); // => { foo: "bar" }
```
Internally, [`structuredClone`](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) and [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) serialize and deserialize the same way. This exposes the underlying [HTML Structured Clone Algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) to JavaScript as an ArrayBuffer.

164
docs/api/workers.md Normal file
View File

@@ -0,0 +1,164 @@
{% callout %}
`Worker` support was added in Bun v0.7.0.
{% /callout %}
[`Worker`](https://developer.mozilla.org/en-US/docs/Web/API/Worker) lets you start and communicate with a new JavaScript instance running on a separate thread while sharing I/O resources with the main thread.
Bun implements a minimal version of the [Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) with extensions that make it work better for server-side use cases. Like the rest of Bun, `Worker` in Bun support CommonJS, ES Modules, TypeScript, JSX, TSX and more out of the box. No extra build steps are necessary.
## Creating a `Worker`
Like in browsers, [`Worker`](https://developer.mozilla.org/en-US/docs/Web/API/Worker) is a global. Use it to create a new worker thread.
From the main thread:
```js#Main_thread
const workerURL = new URL("worker.ts", import.meta.url).href;
const worker = new Worker(workerURL);
worker.postMessage("hello");
worker.onmessage = event => {
console.log(event.data);
};
```
Worker thread:
```ts#worker.ts_(Worker_thread)
self.onmessage = (event: MessageEvent) => {
console.log(event.data);
postMessage("world");
};
```
You can use `import`/`export` syntax in your worker code. Unlike in browsers, there's no need to specify `{type: "module"}` to use ES Modules.
To simplify error handling, the initial script to load is resolved at the time `new Worker(url)` is called.
```js
const worker = new Worker("/not-found.js");
// throws an error immediately
```
The specifier passed to `Worker` is resolved relative to the project root (like typing `bun ./path/to/file.js`).
### `"open"`
The `"open"` event is emitted when a worker is created and ready to receive messages. This can be used to send an initial message to a worker once it's ready. (This event does not exist in browsers.)
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);
worker.addEventListener("open", () => {
console.log("worker is ready");
});
```
Messages are automatically enqueued until the worker is ready, so there is no need to wait for the `"open"` event to send messages.
## Messages with `postMessage`
To send messages, use [`worker.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) and [`self.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). This leverages the [HTML Structured Clone Algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm).
```js
// On the worker thread, `postMessage` is automatically "routed" to the parent thread.
postMessage({ hello: "world" });
// On the main thread
worker.postMessage({ hello: "world" });
```
To receive messages, use the [`message` event handler](https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event) on the worker and main thread.
```js
// Worker thread:
self.addEventListener("message", event => {
console.log(event.data);
});
// or use the setter:
// self.onmessage = fn
// if on the main thread
worker.addEventListener("message", event => {
console.log(event.data);
});
// or use the setter:
// worker.onmessage = fn
```
## Terminating a worker
A `Worker` instance terminate automatically when Bun's process exits. To terminate a `Worker` sooner, call `worker.terminate()`.
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);
// ...some time later
worker.terminate();
```
### `process.exit()`
A worker can terminate itself with `process.exit()`. This does not terminate the main process. Like in Node.js, `process.on('beforeExit', callback)` and `process.on('exit', callback)` are emitted on the worker thread (and not on the main thread).
### `"close"`
The `"close"` event is emitted when a worker has been terminated. It can take some time for the worker to actually terminate, so this event is emitted when the worker has been marked as terminated.
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);
worker.addEventListener("close", () => {
console.log("worker is being closed");
});
```
This event does not exist in browsers.
## Managing lifetime
By default, an active `Worker` will _not_ keep the main (spawning) process alive. Once the main script finishes, the main thread will terminate, shutting down any workers it created.
### `worker.ref`
To keep the process alive until the `Worker` terminates, call `worker.ref()`. This couples the lifetime of the worker to the lifetime of the main process.
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);
worker.ref();
```
Alternatively, you can also pass an `options` object to `Worker`:
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href, {
ref: true,
});
```
### `worker.unref`
To stop keeping the process alive, call `worker.unref()`.
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);
worker.ref();
// ...later on
worker.unref();
```
Note: `worker.ref()` and `worker.unref()` do not exist in browsers.
## Memory usage with `smol`
JavaScript instances can use a lot of memory. Bun's `Worker` supports a `smol` mode that reduces memory usage, at a cost of performance. To enable `smol` mode, pass `smol: true` to the `options` object in the `Worker` constructor.
```js
const worker = new Worker("./i-am-smol.ts", {
smol: true,
});
```
{% details summary="What does `smol` mode actually do?" %}
Setting `smol: true` sets `JSC::HeapSize` to be `Small` instead of the default `Large`.
{% /details %}

View File

@@ -307,7 +307,7 @@ Depending on the target, Bun will apply different module resolution rules and op
---
- `browser`
- _Default._ For generating bundles that are intended for execution by a browser. Prioritizes the `"browser"` export condition when resolving imports. An error will be thrown if any Node.js or Bun built-ins are imported or used, e.g. `node:fs` or `Bun.serve`.
- _Default._ For generating bundles that are intended for execution by a browser. Prioritizes the `"browser"` export condition when resolving imports. Importing any built-in modules, like `node:events` or `node:path` will work, but calling some functions, like `fs.readFile` will not work.
---
@@ -482,7 +482,7 @@ n/a
{% /codetabs %}
Bun implements a univeral plugin system for both Bun's runtime and bundler. Refer to the [plugin documentation](/docs/bundler/plugins) for complete documentation.
Bun implements a universal plugin system for both Bun's runtime and bundler. Refer to the [plugin documentation](/docs/bundler/plugins) for complete documentation.
<!-- ### `manifest`
@@ -1272,7 +1272,17 @@ interface BuildArtifact extends Blob {
sourcemap?: BuildArtifact;
}
type Loader = "js" | "jsx" | "ts" | "tsx" | "json" | "toml" | "file" | "napi" | "wasm" | "text";
type Loader =
| "js"
| "jsx"
| "ts"
| "tsx"
| "json"
| "toml"
| "file"
| "napi"
| "wasm"
| "text";
interface BuildOutput {
outputs: BuildArtifact[];

View File

@@ -10,7 +10,7 @@ Bun uses the file extension to determine which built-in _loader_ should be used
**JavaScript**. Default for `.cjs` and `.mjs`.
Parses the code and applies a set if default transforms, like dead-code elimination, tree shaking, and environment variable inlining. Note that Bun does not attempt to down-convert syntax at the moment.
Parses the code and applies a set of default transforms, like dead-code elimination, tree shaking, and environment variable inlining. Note that Bun does not attempt to down-convert syntax at the moment.
### `jsx`

View File

@@ -33,7 +33,7 @@ As you can see, the source code of the `random` function occurs nowhere in the b
## When to use macros
If you have several build scripts for small things where you would otherwise have a one-off build script, bundle-time code execution can be easier to maintain. It lives with the rest of your code, it runs with the rest of the build, it is automatically paralellized, and if it fails, the build fails too.
If you have several build scripts for small things where you would otherwise have a one-off build script, bundle-time code execution can be easier to maintain. It lives with the rest of your code, it runs with the rest of the build, it is automatically parallelized, and if it fails, the build fails too.
If you find yourself running a lot of code at bundle-time though, consider running a server instead.

View File

@@ -276,7 +276,7 @@ import MySvelteComponent from "./component.svelte";
console.log(mySvelteComponent.render());
```
## Reading `Bun.build`'s config
## Reading the config
Plugins can read and write to the [build config](/docs/bundler#api) with `build.config`.
@@ -305,7 +305,10 @@ Bun.build({
```ts
namespace Bun {
function plugin(plugin: { name: string; setup: (build: PluginBuilder) => void }): void;
function plugin(plugin: {
name: string;
setup: (build: PluginBuilder) => void;
}): void;
}
type PluginBuilder = {

View File

@@ -897,7 +897,7 @@ const myPlugin: BunPlugin = {
};
```
The `builder` object provides some methods for hooking into parts of the bundling process. Bun implements `onResolve` and `onLoad`; it does not yet implement the esbuild hooks `onStart`, `onEnd`, and `onDispose`, and `resolve` utilities. `initialOptions` is partially implemented, being read-only and only having a subset of esbuild's options; use [`config`](/docs/bundler/plugins#reading-bunbuilds-config) (same thing but with Bun's `BuildConfig` format) instead.
The `builder` object provides some methods for hooking into parts of the bundling process. Bun implements `onResolve` and `onLoad`; it does not yet implement the esbuild hooks `onStart`, `onEnd`, and `onDispose`, and `resolve` utilities. `initialOptions` is partially implemented, being read-only and only having a subset of esbuild's options; use [`config`](/docs/bundler/plugins#reading-the-config) (same thing but with Bun's `BuildConfig` format) instead.
```ts
import type { BunPlugin } from "bun";

View File

@@ -40,7 +40,7 @@ On Linux, `bun install` tends to install packages 20-100x faster than `npm insta
Running `bun install` will:
- **Install** all `dependencies`, `devDependencies`, and `optionalDependencies`. Bun does not install `peerDependencies` by default.
- **Run** your project's `{pre|post}install` scripts at the appropriate time. For security reasons Bun _does not execute_ lifecycle scripts of installed dependencies.
- **Run** your project's `{pre|post}install` and `{pre|post}prepare` scripts at the appropriate time. For security reasons Bun _does not execute_ lifecycle scripts of installed dependencies.
- **Write** a `bun.lockb` lockfile to the project root.
To install in production mode (i.e. without `devDependencies`):

View File

@@ -32,6 +32,26 @@ The "naked" `bun` command is equivalent to `bun run`.
$ bun index.tsx
```
### `--watch`
To run a file in watch mode, use the `--watch` flag.
```bash
$ bun --watch run index.tsx
```
### `--smol`
{% callout %}
Added in Bun v0.7.0.
{% /callout %}
In memory-constrained environments, use the `--smol` flag to reduce memory usage at a cost to performance.
```bash
$ bun --smol run index.tsx
```
## Run a `package.json` script
{% note %}
@@ -106,4 +126,4 @@ Under the hood Bun uses the [JavaScriptCore engine](https://developer.apple.com/
{% image src="/images/bun-run-speed.jpeg" caption="Bun vs Node.js vs Deno running Hello World" /%}
<!-- If no `node_modules` directory is found in the working directory or above, Bun will abandon Node.js-style module resolution in favor of the `Bun module resolution algorithm`. Under Bun-style module resolution, all packages are _auto-installed_ on the fly into a [global module cache](/docs/cli/install#global-cache). For full details on this algorithm, refer to [Runtime > Modules](/docs/runtime/modules). -->
<!-- If no `node_modules` directory is found in the working directory or above, Bun will abandon Node.js-style module resolution in favor of the `Bun module resolution algorithm`. Under Bun-style module resolution, all packages are _auto-installed_ on the fly into a [global module cache](/docs/install/cache). For full details on this algorithm, refer to [Runtime > Modules](/docs/runtime/modules). -->

View File

@@ -69,7 +69,7 @@ See [Test > Lifecycle](/docs/test/lifecycle) for complete documentation.
Create mocks with the `mock` function. Mocks are automatically reset between tests.
```
```ts
import { test, expect, mock } from "bun:test";
const random = mock(() => Math.random());

View File

@@ -0,0 +1,27 @@
---
name: Convert an ArrayBuffer to an array of numbers
---
To retrieve the contents of an `ArrayBuffer` as an array of numbers, create a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) over of the buffer. and use the [`Array.from()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method to convert it to an array.
```ts
const buf = new ArrayBuffer(64);
const arr = new Uint8Array(buf);
arr.length; // 64
arr[0]; // 0 (instantiated with all zeros)
```
---
The `Uint8Array` class supports array indexing and iteration. However if you wish to convert the instance to a regular `Array`, use `Array.from()`. (This will likely be slower than using the `Uint8Array` directly.)
```ts
const buf = new ArrayBuffer(64);
const uintArr = new Uint8Array(buf);
const regularArr = Array.from(uintArr);
// number[]
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,24 @@
---
name: Convert an ArrayBuffer to a Blob
---
A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure, or another `Blob`.
```ts
const buf = new ArrayBuffer(64);
const blob = new Blob([buf]);
```
---
By default the `type` of the resulting `Blob` will be unset. This can be set manually.
```ts
const buf = new ArrayBuffer(64);
const blob = new Blob([buf], { type: "application/octet-stream" });
blob.type; // => "application/octet-stream"
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,25 @@
---
name: Convert an ArrayBuffer to a Uint8Array
---
The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) API predates the introduction of `ArrayBuffer` into the JavaScript language. Bun implements both.
Use the static `Buffer.from()` method to create a `Buffer` from an `ArrayBuffer`.
```ts
const arrBuffer = new ArrayBuffer(64);
const nodeBuffer = Buffer.from(arrBuffer);
```
---
To create a `Buffer` that only views a portion of the underlying buffer, pass the offset and length to the constructor.
```ts
const arrBuffer = new ArrayBuffer(64);
const nodeBuffer = Buffer.from(arrBuffer, 0, 16); // view first 16 bytes
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,15 @@
---
name: Convert an ArrayBuffer to a string
---
Bun implements the Web-standard [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class for converting between binary data types and strings.
```ts
const buf = new ArrayBuffer(64);
const decoder = new TextDecoder();
const str = decoder.decode(buf);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,39 @@
---
name: Convert an ArrayBuffer to a Uint8Array
---
A `Uint8Array` is a _typed array_, meaning it is a mechanism for viewing the data in an underlying `ArrayBuffer`.
```ts
const buffer = new ArrayBuffer(64);
const arr = new Uint8Array(buffer);
```
---
Instances of other typed arrays can be created similarly.
```ts
const buffer = new ArrayBuffer(64);
const arr1 = new Uint8Array(buffer);
const arr2 = new Uint16Array(buffer);
const arr3 = new Uint32Array(buffer);
const arr4 = new Float32Array(buffer);
const arr5 = new Float64Array(buffer);
const arr6 = new BigInt64Array(buffer);
const arr7 = new BigUint64Array(buffer);
```
---
To create a typed array that only views a portion of the underlying buffer, pass the offset and length to the constructor.
```ts
const buffer = new ArrayBuffer(64);
const arr = new Uint8Array(buffer, 0, 16); // view first 16 bytes
```
---
See [Docs > API > Utils](/docs/api/utils) for more useful utilities.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Blob to an ArrayBuffer
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, including `.arrayBuffer()`.
```ts
const blob = new Blob(["hello world"]);
const buf = await blob.arrayBuffer();
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Blob to a DataView
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats. This snippets reads the contents to an `ArrayBuffer`, then creates a `DataView` from the buffer.
```ts
const blob = new Blob(["hello world"]);
const arr = new DataView(await blob.arrayBuffer());
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Blob to a ReadableStream
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.stream()`. This returns `Promise<ReadableStream>`.
```ts
const blob = new Blob(["hello world"]);
const stream = await blob.stream();
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,15 @@
---
name: Convert a Blob to a string
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.text()`.
```ts
const blob = new Blob(["hello world"]);
const str = await blob.text();
// => "hello world"
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Blob to a Uint8Array
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats. This snippets reads the contents to an `ArrayBuffer`, then creates a `Uint8Array` from the buffer.
```ts
const blob = new Blob(["hello world"]);
const arr = new Uint8Array(await blob.arrayBuffer());
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Buffer to an ArrayBuffer
---
The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) class provides a way to view and manipulate data in an underlying `ArrayBuffer`, which is available via the `buffer` property.
```ts
const nodeBuf = Buffer.alloc(64);
const arrBuf = nodeBuf.buffer;
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Buffer to a blob
---
A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure (including `Buffer`), or another `Blob`.
```ts
const buf = Buffer.from("hello");
const blob = new Blob([buf]);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,41 @@
---
name: Convert a Buffer to a ReadableStream
---
The naive approach to creating a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) from a [`Buffer`](https://nodejs.org/api/buffer.html) is to use the `ReadableStream` constructor and enqueue the entire array as a single chunk. For a large buffer, this may be undesirable as this approach does not "streaming" the data in smaller chunks.
```ts
const buf = Buffer.from("hello world");
const stream = new ReadableStream({
start(controller) {
controller.enqueue(buf);
controller.close();
},
});
```
---
To stream the data in smaller chunks, first create a `Blob` instance from the `Buffer`. Then use the [`Blob.stream()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) method to create a `ReadableStream` that streams the data in chunks of a specified size.
```ts
const buf = Buffer.from("hello world");
const blob = new Blob([buf]);
const stream = blob.stream();
```
---
The chunk size can be set by passing a number to the `.stream()` method.
```ts
const buf = Buffer.from("hello world");
const blob = new Blob([buf]);
// set chunk size of 1024 bytes
const stream = blob.stream(1024);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,25 @@
---
name: Convert a Buffer to a string
---
The [`Buffer`](https://nodejs.org/api/buffer.html) class provides a built-in `.toString()` method that converts a `Buffer` to a string.
```ts
const buf = Buffer.from("hello");
const str = buf.toString();
// => "hello"
```
---
You can optionally specify an encoding and byte range.
```ts
const buf = Buffer.from("hello world!");
const str = buf.toString("utf8", 0, 5);
// => "hello"
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Buffer to a Uint8Array
---
The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) class extends [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array), so no conversion is needed. All properties and methods on `Uint8Array` are available on `Buffer`.
```ts
const buf = Buffer.alloc(64);
buf instanceof Uint8Array; // => true
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,15 @@
---
name: Convert a Uint8Array to a string
---
If a [`DataView`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) contains ASCII-encoded text, you can convert it to a string using the [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class.
```ts
const dv: DataView = ...;
const decoder = new TextDecoder();
const str = decoder.decode(dv);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,4 @@
{
"name": "Binary data",
"description": "A collection of guides for converting between binary data formats with Bun"
}

View File

@@ -0,0 +1,25 @@
---
name: Convert a Uint8Array to an ArrayBuffer
---
A [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is a _typed array_ class, meaning it is a mechanism for viewing data in an underlying `ArrayBuffer`. The underlying `ArrayBuffer` is accessible via the `buffer` property.
```ts
const arr = new Uint8Array(64);
arr.buffer; // => ArrayBuffer(64)
```
---
The `Uint8Array` may be a view over a _subset_ of the data in the underlying `ArrayBuffer`. In this case, the `buffer` property will return the entire buffer, and the `byteOffset` and `byteLength` properties will indicate the subset.
```ts
const arr = new Uint8Array(64, 16, 32);
arr.buffer; // => ArrayBuffer(64)
arr.byteOffset; // => 16
arr.byteLength; // => 32
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,16 @@
---
name: Convert a Uint8Array to a Blob
---
A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure (including `Uint8Array`), or another `Blob`.
```ts
const arr = new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
const blob = new Blob([arr]);
console.log(await blob.text());
// => "hello"
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Uint8Array to a Buffer
---
The [`Buffer`](https://nodejs.org/api/buffer.html) class extends [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) with a number of additional methods. Use `Buffer.from()` to create a `Buffer` instance from a `Uint8Array`.
```ts
const arr: Uint8Array = ...
const buf = Buffer.from(arr);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,14 @@
---
name: Convert a Uint8Array to a DataView
---
A [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is a _typed array_ class, meaning it is a mechanism for viewing data in an underlying `ArrayBuffer`. The following snippet creates a [`DataView`] instance over the same range of data as the `Uint8Array`.
```ts
const arr: Uint8Array = ...
const dv = new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,41 @@
---
name: Convert a Uint8Array to a ReadableStream
---
The naive approach to creating a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) from a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is to use the [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) constructor and enqueue the entire array as a single chunk. For larger chunks, this may be undesirable as it isn't actually "streaming" the data.
```ts
const arr = new Uint8Array(64);
const stream = new ReadableStream({
start(controller) {
controller.enqueue(arr);
controller.close();
},
});
```
---
To stream the data in smaller chunks, first create a `Blob` instance from the `Uint8Array`. Then use the [`Blob.stream()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) method to create a `ReadableStream` that streams the data in chunks of a specified size.
```ts
const arr = new Uint8Array(64);
const blob = new Blob([arr]);
const stream = blob.stream();
```
---
The chunk size can be set by passing a number to the `.stream()` method.
```ts
const arr = new Uint8Array(64);
const blob = new Blob([arr]);
// set chunk size of 1024 bytes
const stream = blob.stream(1024);
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,16 @@
---
name: Convert a Uint8Array to a string
---
Bun implements the Web-standard [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class for converting from binary data types like `Uint8Array` and strings.
```ts
const arr = new Uint8Array([104, 101, 108, 108, 111]);
const decoder = new TextDecoder();
const str = decoder.decode(buf);
// => "hello"
```
---
See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -0,0 +1,77 @@
---
name: Create a Discord bot
---
Discord.js works [out of the box](https://bun.sh/blog/bun-v0.6.7) with Bun. Let's write a simple bot. First create a directory and initialize it with `bun init`.
```bash
mkdir my-bot
cd my-bot
bun init
```
---
Now install Discord.js.
```bash
bun add discord.js
```
---
Before we go further, we need to go to the [Discord developer portal](https://discord.com/developers/applications), login/signup, create a new _Application_, then create a new _Bot_ within that application. Follow the [official guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot) for step-by-step instructions.
---
Once complete, you'll be presented with your bot's _private key_. Let's add this to a file called `.env.local`. Bun automatically reads this file and loads it into `process.env`.
{% callout %}
This is an example token that has already been invalidated.
{% /callout %}
```txt#.env.local
DISCORD_TOKEN=NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I
```
---
Be sure to add `.env.local` to your `.gitignore`! It is dangerous to check your bot's private key into version control.
```txt#.gitignore
node_modules
.env.local
```
---
Now let's actually write our bot in a new file called `bot.ts`.
```ts#bot.ts
// import discord.js
import {Client, Events, GatewayIntentBits} from 'discord.js';
// create a new Client instance
const client = new Client({intents: [GatewayIntentBits.Guilds]});
// listen for the client to be ready
client.once(Events.ClientReady, (c) => {
console.log(`Ready! Logged in as ${c.user.tag}`);
});
// login with the token from .env.local
client.login(process.env.DISCORD_TOKEN);
```
---
Now we can run our bot with `bun run`. It may take a several seconds for the client to initialize the first time you run the file.
```bash
$ bun run bot.ts
Ready! Logged in as my-bot#1234
```
---
You're up and running with a bare-bones Discord.js bot! This is a basic guide to setting up your bot with Bun; we recommend the [official Discord docs](https://discordjs.guide/) for complete information on the `discord.js` API.

View File

@@ -0,0 +1,4 @@
{
"name": "Ecosystem",
"description": "A collection of guides for using various tools and frameworks with Bun"
}

View File

@@ -0,0 +1,80 @@
---
name: Use MongoDB and Mongoose
---
MongoDB and Mongoose work out of the box with Bun. This guide assumes you've already installed MongoDB and are running it as background process/service on your development machine. Follow [this guide](https://www.mongodb.com/docs/manual/installation/) for details.
---
Once MongoDB is running, create a directory and initialize it with `bun init`.
```bash
mkdir mongoose-app
cd mongoose-app
bun init
```
---
Then add Mongoose as a dependency.
```bash
bun add mongoose
```
---
In `schema.ts` we'll declare and export a simple `Animal` model.
```ts#schema.ts
import * as mongoose from 'mongoose';
const animalSchema = new mongoose.Schema(
{
name: {type: String, required: true},
sound: {type: String, required: true},
}
);
export type Animal = mongoose.InferSchemaType<typeof animalSchema>;
export const Animal = mongoose.model('Kitten', animalSchema);
```
---
Now from `index.ts` we can import `Animal`, connect to MongoDB, and add some data to our database.
```ts#index.ts
import * as mongoose from 'mongoose';
import {Animal} from './schema';
// connect to database
await mongoose.connect('mongodb://127.0.0.1:27017/mongoose-app');
// create new Animal
const cow = new Animal({
name: 'Cow',
sound: 'Moo',
});
await cow.save(); // saves to the database
// read all Animals
const animals = await Animal.find();
animals[0].speak(); // logs "Moo!"
// disconect
await mongoose.disconnect();
```
---
Lets run this with `bun run`.
```bash
$ bun run index.ts
Moo!
```
---
This is a simple introduction to using Mongoose with TypeScript and Bun. As you build your application, refer to the official [MongoDB](https://docs.mongodb.com/) and [Mongoose](https://mongoosejs.com/docs/) sites for complete documentation.

View File

@@ -0,0 +1,110 @@
---
name: Use Prisma
---
Prisma works our of the box with Bun. First, create a directory and initialize it with `bun init`.
```bash
mkdir prisma-app
cd prisma-app
bun init
```
---
Then add Prisma as a dependency.
```bash
bun add prisma
```
---
We'll use the Prisma CLI with `bunx` to initialize our schema and migration directory. For simplicity we'll be using an in-memory SQLite database.
```bash
bunx prisma init --datasource-provider sqlite
```
---
Open `prisma/schema.prisma` and add a simple `User` model.
```prisma-diff#prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
+ model User {
+ id Int @id @default(autoincrement())
+ email String @unique
+ name String?
+ }
```
---
Then generate and run initial migration.
This will generate a `.sql` migration file in `prisma/migrations`, create a new SQLite instance, and execute the migration against the new instance.
```bash
bunx prisma migrate dev --name init
```
---
Prisma automatically generates our _Prisma client_ whenever we execute a new migration. The client provides a fully typed API for reading and writing from our database.
It can be imported from `@prisma/client`.
```ts#src/index.ts
import {PrismaClient} from "@prisma/client";
```
---
Let's write a simple script to create a new user, then count the number of users in the database.
```ts#index.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// create a new user
await prisma.user.create({
data: {
name: "John Dough",
email: `john-${Math.random()}@example.com`,
},
});
// count the number of users
const count = await prisma.user.count();
console.log(`There are ${count} users in the database.`);
```
---
Let's run this script with `bun run`. Each time we run it, a new user is created.
```bash
$ bun run index.ts
Created john-0.12802932895402364@example.com
There are 1 users in the database.
$ bun run index.ts
Created john-0.8671308799782803@example.com
There are 2 users in the database.
$ bun run index.ts
Created john-0.4465968383115295@example.com
There are 3 users in the database.
```
---
That's it! Now that you've set up Prisma using Bun, we recommend referring to the [official Prisma docs](https://www.prisma.io/docs/concepts/components/prisma-client) as you continue to develop your application.

View File

@@ -0,0 +1,71 @@
---
name: Use Vite
---
{% callout %}
While Vite currently works with Bun, it has not been heavily optimized, nor has Vite been adapted to use Bun's bundler, module resolver, or transpiler.
{% /callout %}
---
Vite works out of the box with Bun (v0.7 and later). Get started with one of Vite's templates.
```bash
$ bunx create-vite my-app
✔ Select a framework: React
✔ Select a variant: TypeScript + SWC
Scaffolding project in /path/to/my-app...
```
---
Then `cd` into the project directory and install dependencies.
```bash
cd my-app
bun install
```
---
Start the development server with the `vite` CLI using `bunx`.
The `--bun` flag tells Bun to run Vite's CLI using `bun` instead of `node`; by default Bun respects Vite's `#!/usr/bin/env node` [shebang line](<https://en.wikipedia.org/wiki/Shebang_(Unix)>). After Bun 1.0 this flag will no longer be necessary.
```bash
bunx --bun vite
```
---
To simplify this command, update the `"dev"` script in `package.json` to the following.
```json-diff#package.json
"scripts": {
- "dev": "vite",
+ "dev": "bunx --bun vite",
"build": "vite build",
"serve": "vite preview"
},
// ...
```
---
Now you can start the development server with `bun run dev`.
```bash
bun run dev
```
---
The following command will build your app for production.
```sh
$ bunx --bun vite build
```
---
This is a stripped down guide to get you started with Vite + Bun. For more information, see the [Vite documentation](https://vitejs.dev/guide/).

55
docs/guides/http/hot.md Normal file
View File

@@ -0,0 +1,55 @@
---
name: Hot reload an HTTP server
---
Bun supports the [`--hot`](/docs/runtime/hot#hot-mode) flag to run a file with hot reloading enabled. When any module or file changes, Bun re-runs the file.
```sh
bun --hot run index.ts
```
---
To avoid re-running `Bun.serve()` during `--hot` reloads, you should assign the `Server` instance as a property of `globalThis`. The `globalThis` object survives hot reloads.
```ts
import { type Serve, type Server } from "bun";
// make TypeScript happy
declare global {
var server: Server;
}
// define server parameters
const serveOptions: Serve = {
port: 3000,
fetch(req) {
return new Response(`Hello world`);
},
};
if (!globalThis.server) {
globalThis.server = Bun.serve(serveOptions);
} else {
globalThis.server.reload(serveOptions);
}
```
---
To avoid manually calling `server.reload()`, you can use start a server with Bun's [object syntax](/docs/runtime/hot#http-servers). If you `export default` a plain object with a `fetch` handler defined, then run this file with Bun, Bun will start an HTTP server as if you'd passed this object into `Bun.serve()`.
With this approach, Bun automatically reloads the server when reloads happen.
See [HTTP > Hot Reloading](<[/docs/api/http](https://bun.sh/docs/api/http#hot-reloading)>) for full docs.
```ts
import { type Serve } from "bun";
export default {
port: 3000,
fetch(req) {
return new Response(`Hello world`);
},
} satisfies Serve;
```

View File

@@ -0,0 +1,4 @@
{
"name": "HTTP",
"description": "A collection of guides for building HTTP servers with Bun"
}

View File

@@ -0,0 +1,18 @@
---
name: Write a simple HTTP server
---
This starts an HTTP server listening on port `3000`. It responds to all requests with a `Response` with status `200` and body `"Welcome to Bun!"`.
See [`Bun.serve`](/docs/api/http) for details.
```ts
const server = Bun.serve({
port: 3000,
fetch(request) {
return new Response("Welcome to Bun!");
},
});
console.log(`Listening on localhost:\${server.port}`);
```

View File

@@ -0,0 +1,48 @@
---
name: Stream a file as an HTTP Response
---
This snippet reads a file from disk using [`Bun.file()`](/docs/api/file-io#reading-files-bun-file). This returns a `BunFile` instance, which can be passed directly into the `new Response` constructor.
```ts
const path = "/path/to/file.txt";
const file = Bun.file(path);
const resp = new Response(file);
```
---
The `Content-Type` is read from the file and automatically set on the `Response`.
```ts
new Response(Bun.file("./package.json")).headers.get("Content-Type");
// => application/json;charset=utf-8
new Response(Bun.file("./test.txt")).headers.get("Content-Type");
// => text/plain;charset=utf-8
new Response(Bun.file("./index.tsx")).headers.get("Content-Type");
// => text/javascript;charset=utf-8
new Response(Bun.file("./img.png")).headers.get("Content-Type");
// => image/png
```
---
Putting it all together with [`Bun.serve()`](/docs/api/http#bun-serve).
```ts
// static file server
Bun.serve({
async fetch(req) {
const path = new URL(req.url).pathname;
const file = Bun.file(path);
return new Response(file);
},
});
```
---
See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`.

30
docs/guides/http/tls.md Normal file
View File

@@ -0,0 +1,30 @@
---
name: Configure TLS on an HTTP server
---
Set the `tls` key to configure TLS. Both `key` and `cert` are required. The `key` should be the contents of your private key; `cert` should be the contents of your issued certificate. Use [`Bun.file()`](/docs/api/file-io#reading-files-bun-file) to read the contents.
```ts
const server = Bun.serve({
fetch: (request) => new Response("Welcome to Bun!"),
tls: {
cert: Bun.file("cert.pem"),
key: Bun.file("key.pem"),
},
});
```
---
By default Bun trusts the default Mozilla-curated list of well-known root CAs. To override this list, pass an array of certificates as `ca`.
```ts
const server = Bun.serve({
fetch: (request) => new Response("Welcome to Bun!"),
tls: {
cert: Bun.file("cert.pem"),
key: Bun.file("key.pem"),
ca: [Bun.file("ca1.pem"), Bun.file("ca2.pem")],
},
});
```

View File

@@ -0,0 +1,22 @@
---
name: Parse command-line arguments
---
The _argument vector_ is the list of arguments passed to the program when it is run. It is available as `Bun.argv`.
```ts#cli.ts
console.log(Bun.argv);
```
---
Running this file with arguments results in the following:
```sh
$ bun run cli.tsx --flag1 --flag2 value
[ '/path/to/bun', '/path/to/cli.ts', '--flag1', '--flag2', 'value' ]
```
---
To parse `argv` into a more useful format, consider using [minimist](https://github.com/minimistjs/minimist) or [commander](https://github.com/tj/commander.js).

View File

@@ -0,0 +1,16 @@
---
name: Listen for CTRL+C
---
The `ctrl+c` shortcut sends an _interrupt signal_ to the running process. This signal can be intercepted by listening for the `SIGINT` event. If you want to close the process, you must explicitly call `process.exit()`.
```ts
process.on("SIGINT", () => {
console.log("Ctrl-C was pressed");
process.exit();
});
```
---
See [Docs > API > Utils](/docs/api/utils) for more useful utilities.

View File

@@ -0,0 +1,4 @@
{
"name": "Processes",
"description": "A collection of guides for inspecting the current process and creating child processes with Bun"
}

View File

@@ -0,0 +1,13 @@
---
name: Get the process uptime in nanoseconds
---
Use `Bun.nanoseconds()` to get the total number of nanoseconds the `bun` process has been alive.
```ts
Bun.nanoseconds();
```
---
See [Docs > API > Utils](/docs/api/utils) for more useful utilities.

View File

@@ -0,0 +1,39 @@
---
name: Listen to OS signals
---
Bun supports the Node.js `process` global, including the `process.on()` method for listening to OS signals.
```ts
process.on("SIGINT", () => {
console.log("Received SIGINT");
});
```
---
If you don't know which signal to listen for, you listen to the umbrella `"exit"` event.
```ts
process.on("exit", (code) => {
console.log(`Process exited with code ${code}`);
});
```
---
If you don't know which signal to listen for, you listen to the [`"beforeExit"`](https://nodejs.org/api/process.html#event-beforeexit) and [`"exit"`](https://nodejs.org/api/process.html#event-exit) events.
```ts
process.on("beforeExit", (code) => {
console.log(`Event loop is empty!`);
});
process.on("exit", (code) => {
console.log(`Process is exiting with code ${code}`);
});
```
---
See [Docs > API > Utils](/docs/api/utils) for more useful utilities.

View File

@@ -0,0 +1,31 @@
---
name: Read stderr from a child process
---
When using [`Bun.spawn()`](/docs/api/spawn), the child process inherits the `stderr` of the spawning process. If instead you'd prefer to read and handle `stderr`, set the `stderr` option to `"pipe"`.
```ts
const proc = Bun.spawn(["echo", "hello"], {
stderr: "pipe",
});
proc.stderr; // => ReadableStream
```
---
To read `stderr` until the child process exits, use the [`Bun.readableStreamToText()`](/docs/api/utils#bun-readablestreamto) convenience function.
```ts
const proc = Bun.spawn(["echo", "hello"], {
stderr: "pipe",
});
const errors: string = await Bun.readableStreamToText(proc.stderr);
if (errors) {
// handle errors
}
```
---
See [Docs > API > Child processes](/docs/api/spawn) for complete documentation..

View File

@@ -0,0 +1,26 @@
---
name: Read stdout from a child process
---
When using [`Bun.spawn()`](/docs/api/spawn), the `stdout` of the child process can be consumed as a `ReadableStream` via `proc.stdout`.
```ts
const proc = Bun.spawn(["echo", "hello"]);
const output = await new Response(proc.stdout).text();
output; // => "hello"
```
---
To instead pipe the `stdout` of the child process to `stdout` of the parent process, set "inherit".
```ts
const proc = Bun.spawn(["echo", "hello"], {
stdout: "inherit",
});
```
---
See [Docs > API > Child processes](/docs/api/spawn) for complete documentation..

View File

@@ -0,0 +1,41 @@
---
name: Spawn a child process
---
Use [`Bun.spawn()`](/docs/api/spawn) to spawn a child process.
```ts
const proc = Bun.spawn(["echo", "hello"]);
// await completion
await proc.exited;
```
---
The second argument accepts a configuration object.
```ts
const proc = Bun.spawn("echo", ["Hello, world!"], {
cwd: "/tmp",
env: { FOO: "bar" },
onExit(proc, exitCode, signalCode, error) {
// exit handler
},
});
```
---
By default, the `stdout` of the child process can be consumed as a `ReadableStream` using `proc.stdout`.
```ts
const proc = Bun.spawn(["echo", "hello"]);
const output = await new Response(proc.stdout).text();
output; // => "hello"
```
---
See [Docs > API > Child processes](/docs/api/spawn) for complete documentation..

View File

@@ -0,0 +1,54 @@
---
name: Read from stdin
---
For CLI tools, it's often useful to read from `stdin`. In Bun, the `console` object is an `AsyncIterable` that yields lines from `stdin`.
```ts#index.ts
const prompt = "Type something: ";
process.stdout.write(prompt);
for await (const line of console) {
console.log(`You typed: ${line}`);
process.stdout.write(prompt);
}
```
---
Running this file results in a never-ending interactive prompt that echoes whatever the user types.
```sh
$ bun run index.tsx
Type something: hello
You typed: hello
Type something: hello again
You typed: hello again
```
---
Bun also exposes stdin as a `BunFile` via `Bun.stdin`. This is useful for incrementally reading large inputs that are piped into the `bun` process.
There is no guarantee that the chunks will be split line-by-line.
```ts#stdin.ts
for await (const chunk of Bun.stdin.stream()) {
// chunk is Uint8Array
// this converts it to text (assumes ASCII encoding)
const chunkText = Buffer.from(chunk).toString();
console.log(`Chunk: ${chunkText}`);
}
```
---
This will print the input that is piped into the `bun` process.
```sh
$ echo "hello" | bun run stdin.ts
Chunk: hello
```
---
See [Docs > API > Utils](/docs/api/utils) for more useful utilities.

View File

@@ -0,0 +1,28 @@
---
name: Read a file to an ArrayBuffer
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.arrayBuffer()` to read the file as an `ArrayBuffer`.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
const buffer = await file.arrayBuffer();
```
---
The binary content in the `ArrayBuffer` can then be read as a typed array, such as `Uint8Array`.
```ts
const buffer = await file.arrayBuffer();
const bytes = new Uint8Array(buffer);
bytes[0];
bytes.length;
```
---
Refer to the [Typed arrays](/docs/api/binary-data#typedarray) docs for more information on working with typed arrays in Bun.

View File

@@ -0,0 +1,19 @@
---
name: Read a file to a Buffer
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats.
To read the file into a `Buffer` instance, first use `.arrayBuffer()` to consume the file as an `ArrayBuffer`, then use `Buffer.from()` to create a `Buffer` from the `ArrayBuffer`.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
const arrbuf = await file.arrayBuffer();
const buffer = Buffer.from(arrbuf);
```
---
Refer to [Binary data > Buffer](/docs/api/binary-data#buffer) for more information on working with `Buffer` and other binary data formats in Bun.

View File

@@ -0,0 +1,16 @@
---
name: Check if a file exists
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. Use the `.exists()` method to check if a file exists at the given path.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
file.exists(); // boolean;
```
---
Refer to [API > File I/O](/docs/api/file-io) for more information on working with `BunFile`.

View File

@@ -0,0 +1,4 @@
{
"name": "Reading files",
"description": "A collection of guides for reading files with Bun"
}

View File

@@ -0,0 +1,34 @@
---
name: Read a JSON file
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.json()` to read and parse the contents of a `.json` file as a plain object.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
const contents = await file.json();
// { name: "my-package" }
```
---
The MIME type of the `BunFile` will be set accordingly.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
file.type; // => "application/json;charset=utf-8";
```
---
If the path to the `.json` file is static, it can be directly imported as a module.
```ts
import pkg from "./package.json";
pkg.name; // => "my-package"
```

View File

@@ -0,0 +1,20 @@
---
name: Get the MIME type of a file
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob`, so use the `.type` property to read the MIME type.
```ts
const file = Bun.file("./package.json");
file.type; // application/json
const file = Bun.file("./index.html");
file.type; // text/html
const file = Bun.file("./image.png");
file.type; // image/png
```
---
Refer to [API > File I/O](/docs/api/file-io) for more information on working with `BunFile`.

View File

@@ -0,0 +1,26 @@
---
name: Read a file as a ReadableStream
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.stream()` to consume the file incrementally as a `ReadableStream`.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
const stream = await file.stream();
```
---
The chunks of the stream can be consumed with `for await`.
```ts
for await (const chunk of stream.values()) {
chunk; // => Uint8Array
}
```
---
Refer to the [Streams](/docs/api/streams) documentation for more information on working with streams in Bun.

View File

@@ -0,0 +1,22 @@
---
name: Read a file as a string
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.text()` to read the contents as a string.
```ts
const path = "/path/to/file.txt";
const file = Bun.file(path);
const text = await file.text();
// string
```
---
Any relative paths will be resolved relative to the project root (the nearest directory containing a `package.json` file).
```ts
const path = "./file.txt";
const file = Bun.file(path);
```

View File

@@ -0,0 +1,22 @@
---
name: Read a file to a Uint8Array
---
The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats.
To read the file into a `Uint8Array` instance, retrieve the contents of the `BunFile` as an `ArrayBuffer` with `.arrayBuffer()`, then pass it into the `Uint8Array` constructor.
```ts
const path = "/path/to/package.json";
const file = Bun.file(path);
const arrBuffer = await file.arrayBuffer();
const byteArray = new Uint8Array(arrBuffer);
byteArray[0]; // first byteArray
byteArray.length; // length of byteArray
```
---
Refer to [API > Binary data > Typed arrays](/docs/api/binary-data#typedarray) for more information on working with `Uint8Array` and other binary data formats in Bun.

View File

@@ -0,0 +1,68 @@
---
name: Watch a directory for changes
---
Bun implements the `node:fs` module, including the `fs.watch` function for listening for file system changes.
This code block listens for changes to files in the current directory. By default this operation is _shallow_, meaning that changes to files in subdirectories will not be detected.
```ts
import { watch } from "fs";
const watcher = watch(import.meta.dir, (event, filename) => {
console.log(`Detected ${event} in ${filename}`);
});
```
---
To listen to changes in subdirectories, pass the `recursive: true` option to `fs.watch`.
```ts
import { watch } from "fs";
const watcher = watch(
import.meta.dir,
{ recursive: true },
(event, filename) => {
console.log(`Detected ${event} in ${filename}`);
},
);
```
---
Using the `node:fs/promises` module, you can listen for changes using `for await...of` instead of a callback.
```ts
import { watch } from "fs/promises";
const watcher = watch(import.meta.dir);
for await (const event of watcher) {
console.log(`Detected ${event.eventType} in ${event.filename}`);
}
```
---
To stop listening for changes, call `watcher.close()`. It's common to do this when the process receives a `SIGINT` signal, such as when the user presses Ctrl-C.
```ts
import { watch } from "fs";
const watcher = watch(import.meta.dir, (event, filename) => {
console.log(`Detected ${event} in ${filename}`);
});
process.on("SIGINT", () => {
// close watcher when Ctrl-C is pressed
console.log("Closing watcher...");
watcher.close();
process.exit(0);
});
```
---
Refer to [API > Binary data > Typed arrays](/docs/api/binary-data#typedarray) for more information on working with `Uint8Array` and other binary data formats in Bun.

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