mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 02:18:47 +00:00
Compare commits
211 Commits
jarred/fas
...
jarred/sup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fae8dda372 | ||
|
|
9c2c62d8e4 | ||
|
|
b366866d61 | ||
|
|
1b4c25ff6c | ||
|
|
bca9fedee4 | ||
|
|
e1cd128078 | ||
|
|
4720ae907f | ||
|
|
2924329ab0 | ||
|
|
9ecae59bbb | ||
|
|
2ea7290172 | ||
|
|
092ada6d2f | ||
|
|
e636f1b026 | ||
|
|
54a2d89bd2 | ||
|
|
0ea59b4c93 | ||
|
|
b0d3ea5a43 | ||
|
|
a9dc5d51e3 | ||
|
|
749194378a | ||
|
|
794e657eb2 | ||
|
|
1db119ec11 | ||
|
|
413fd28120 | ||
|
|
40a9ba6340 | ||
|
|
681be10294 | ||
|
|
dccf82b1c6 | ||
|
|
5563be99d3 | ||
|
|
bcb6dc7806 | ||
|
|
dae2928620 | ||
|
|
05ef9ec141 | ||
|
|
53cc4df191 | ||
|
|
05716ff39b | ||
|
|
4f914cbfe8 | ||
|
|
da7c1d84e9 | ||
|
|
aebec5b329 | ||
|
|
c68d9ae634 | ||
|
|
bd66a9a94c | ||
|
|
1490cdc4ff | ||
|
|
97009a49bd | ||
|
|
d432448ac8 | ||
|
|
d614fdfaac | ||
|
|
0a4e476a7c | ||
|
|
9078b1286d | ||
|
|
242d8655d8 | ||
|
|
9b91e3c1a2 | ||
|
|
7a1ebec26f | ||
|
|
e7c80b90b8 | ||
|
|
e110ccf84d | ||
|
|
c2a744f0cc | ||
|
|
38168f3c85 | ||
|
|
cbaab23f6d | ||
|
|
3e5beb1279 | ||
|
|
70b9bf743c | ||
|
|
f3153fbee9 | ||
|
|
7fa71dd032 | ||
|
|
52f39d728f | ||
|
|
73eb59019a | ||
|
|
3b24305b7c | ||
|
|
1304779826 | ||
|
|
65d0884361 | ||
|
|
16fdc074ca | ||
|
|
6b35fd847f | ||
|
|
007f357495 | ||
|
|
16a7224ce5 | ||
|
|
7c44773f38 | ||
|
|
85895bd248 | ||
|
|
6c2ec2868f | ||
|
|
704ee13392 | ||
|
|
d7aebc2222 | ||
|
|
dc0d767f27 | ||
|
|
86633e0af4 | ||
|
|
ec2cf38ad8 | ||
|
|
34fd4df646 | ||
|
|
a6d54e5949 | ||
|
|
664ccec7d3 | ||
|
|
1a558ef753 | ||
|
|
f3200ac0ca | ||
|
|
011b50589c | ||
|
|
06503663b1 | ||
|
|
4c89c60867 | ||
|
|
6bfee02301 | ||
|
|
0297cb1527 | ||
|
|
4209703b35 | ||
|
|
8edeb617a8 | ||
|
|
130079b558 | ||
|
|
8356830727 | ||
|
|
5edb756533 | ||
|
|
e402159df1 | ||
|
|
8a0152e129 | ||
|
|
1f1d0bfcfb | ||
|
|
4ebf858f43 | ||
|
|
90ce74a43e | ||
|
|
e1a59d355a | ||
|
|
e154763e4d | ||
|
|
ac10a1b633 | ||
|
|
961312eab0 | ||
|
|
6ca50526d7 | ||
|
|
31976f6af1 | ||
|
|
967ccb5d50 | ||
|
|
d8135e85ca | ||
|
|
b02f097f4d | ||
|
|
4e852918a3 | ||
|
|
c76516fa38 | ||
|
|
ce77266cc5 | ||
|
|
ce9bba9dd5 | ||
|
|
e2e44661c2 | ||
|
|
601fd3ead5 | ||
|
|
07e08b086a | ||
|
|
53eb126898 | ||
|
|
6809d08a90 | ||
|
|
6402967b6d | ||
|
|
bfaf095c2e | ||
|
|
b17b61b8c6 | ||
|
|
27c88c8046 | ||
|
|
04d19d6f6a | ||
|
|
3418feb2e9 | ||
|
|
c6a3467625 | ||
|
|
636cec03e1 | ||
|
|
1ecd9f8a18 | ||
|
|
2323f5d08d | ||
|
|
311dffc690 | ||
|
|
c4f062dbf4 | ||
|
|
7ac94e5b4c | ||
|
|
aa1ad7f009 | ||
|
|
21bb3b2bdd | ||
|
|
cd49615e2c | ||
|
|
eb37794a3b | ||
|
|
da298635ef | ||
|
|
218958dbd1 | ||
|
|
1c6e464a68 | ||
|
|
9c85465a58 | ||
|
|
2eb79afb2a | ||
|
|
020cf46346 | ||
|
|
134c97a282 | ||
|
|
e2c11c4856 | ||
|
|
9ad330d917 | ||
|
|
ef89f03de6 | ||
|
|
c383c6cd81 | ||
|
|
68b4a64569 | ||
|
|
8e12999917 | ||
|
|
73e44e16ea | ||
|
|
99da0ae54b | ||
|
|
4686f5395e | ||
|
|
2dc90f3908 | ||
|
|
53ad9b922f | ||
|
|
0b365781a8 | ||
|
|
dd46c11273 | ||
|
|
8a13e02473 | ||
|
|
ed8be46a7b | ||
|
|
36866c4d79 | ||
|
|
dd58508684 | ||
|
|
9b6dc49575 | ||
|
|
723e9d1ea7 | ||
|
|
f63398ffe4 | ||
|
|
2fbf73535c | ||
|
|
ebbbd63ed6 | ||
|
|
bc28ec39cf | ||
|
|
568cadb51e | ||
|
|
0dbcb84cbe | ||
|
|
d74d95d9ab | ||
|
|
a59ddb131e | ||
|
|
8bd2b784a2 | ||
|
|
f494e1b50d | ||
|
|
112f01ca61 | ||
|
|
49231b2cb9 | ||
|
|
0179ebcb8c | ||
|
|
1790357021 | ||
|
|
105919d7ae | ||
|
|
777ee4ecec | ||
|
|
661355546a | ||
|
|
71f1aa1802 | ||
|
|
eaff66b098 | ||
|
|
b760d1da30 | ||
|
|
728c8fdcdb | ||
|
|
13b54fbdb8 | ||
|
|
9273e29f0e | ||
|
|
9f031b3642 | ||
|
|
ca3b7fa3c9 | ||
|
|
8a176913d8 | ||
|
|
570a44d73a | ||
|
|
5218a33fb6 | ||
|
|
58824ea743 | ||
|
|
99de971359 | ||
|
|
55b5aa3571 | ||
|
|
6ca20424d6 | ||
|
|
36a25c3580 | ||
|
|
13b5d9d4de | ||
|
|
fa4db1de42 | ||
|
|
2a02f3d669 | ||
|
|
75213aad37 | ||
|
|
5856639833 | ||
|
|
edeb3b48e8 | ||
|
|
3613429dc3 | ||
|
|
7917ebd58f | ||
|
|
a86d00c672 | ||
|
|
d5c51092c8 | ||
|
|
6a234e6fce | ||
|
|
dc766eb18a | ||
|
|
209dc981c0 | ||
|
|
7fc392b182 | ||
|
|
6baa08313c | ||
|
|
131ed06020 | ||
|
|
e546e4064c | ||
|
|
c39c11e101 | ||
|
|
2551210426 | ||
|
|
43abf2629f | ||
|
|
325147261f | ||
|
|
044b09afc2 | ||
|
|
9eb8eea2a8 | ||
|
|
04b4157232 | ||
|
|
a02a79e26c | ||
|
|
ae0a724981 | ||
|
|
0631f87866 | ||
|
|
4e1a81231c |
62
.github/pull_request_template.md
vendored
Normal file
62
.github/pull_request_template.md
vendored
Normal 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
|
||||
-->
|
||||
2
.github/workflows/bun-linux-aarch64.yml
vendored
2
.github/workflows/bun-linux-aarch64.yml
vendored
@@ -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
|
||||
|
||||
|
||||
7
.github/workflows/bun-linux-build.yml
vendored
7
.github/workflows/bun-linux-build.yml
vendored
@@ -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
|
||||
|
||||
19
.github/workflows/bun-mac-aarch64.yml
vendored
19
.github/workflows/bun-mac-aarch64.yml
vendored
@@ -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
|
||||
|
||||
19
.github/workflows/bun-mac-x64-baseline.yml
vendored
19
.github/workflows/bun-mac-x64-baseline.yml
vendored
@@ -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
|
||||
|
||||
19
.github/workflows/bun-mac-x64.yml
vendored
19
.github/workflows/bun-mac-x64.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/zig-fmt.yml
vendored
2
.github/workflows/zig-fmt.yml
vendored
@@ -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
2
.gitignore
vendored
@@ -123,3 +123,5 @@ cold-jsc-start.d
|
||||
/test.ts
|
||||
|
||||
src/js/out/modules_dev
|
||||
|
||||
make-dev-stats.csv
|
||||
|
||||
21
.scripts/make-dev-timer.ts
Normal file
21
.scripts/make-dev-timer.ts
Normal 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
1
.vscode/launch.json
generated
vendored
@@ -242,7 +242,6 @@
|
||||
"console": "internalConsole",
|
||||
"env": {}
|
||||
},
|
||||
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
69
Makefile
69
Makefile
@@ -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)
|
||||
|
||||
30
bench/async/AsyncLocalStorage.mjs
Normal file
30
bench/async/AsyncLocalStorage.mjs
Normal 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 + "%");
|
||||
@@ -3,6 +3,6 @@
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"bun-types": "^0.5.0"
|
||||
"bun-types": "^0.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
"jsx": "react-jsx",
|
||||
"paths": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 () {});
|
||||
|
||||
15
bench/snippets/request-response-clone.mjs
Normal file
15
bench/snippets/request-response-clone.mjs
Normal 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();
|
||||
136
bench/snippets/response-arrayBuffer.mjs
Normal file
136
bench/snippets/response-arrayBuffer.mjs
Normal 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();
|
||||
123
bench/snippets/response-json.mjs
Normal file
123
bench/snippets/response-json.mjs
Normal 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();
|
||||
1
bench/snippets/resposne-constructor.mjs
Normal file
1
bench/snippets/resposne-constructor.mjs
Normal file
@@ -0,0 +1 @@
|
||||
for (let i = 0; i < 9999999; i++) new Request("http://aaaaaaaaaaaaaaaaaaaaa");
|
||||
128
bench/snippets/serialize.mjs
Normal file
128
bench/snippets/serialize.mjs
Normal 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();
|
||||
39
bench/snippets/structuredClone.mjs
Normal file
39
bench/snippets/structuredClone.mjs
Normal 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();
|
||||
20
bench/snippets/webcrypto.mjs
Normal file
20
bench/snippets/webcrypto.mjs
Normal 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.
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "bench",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^8.0.1"
|
||||
"better-sqlite3": "8.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "exit 0",
|
||||
|
||||
@@ -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.
@@ -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!",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
64
build.zig
64
build.zig
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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
164
docs/api/workers.md
Normal 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 %}
|
||||
@@ -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[];
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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`):
|
||||
|
||||
@@ -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). -->
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
27
docs/guides/binary/arraybuffer-to-array.md
Normal file
27
docs/guides/binary/arraybuffer-to-array.md
Normal 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.
|
||||
24
docs/guides/binary/arraybuffer-to-blob.md
Normal file
24
docs/guides/binary/arraybuffer-to-blob.md
Normal 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.
|
||||
25
docs/guides/binary/arraybuffer-to-buffer.md
Normal file
25
docs/guides/binary/arraybuffer-to-buffer.md
Normal 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.
|
||||
15
docs/guides/binary/arraybuffer-to-string.md
Normal file
15
docs/guides/binary/arraybuffer-to-string.md
Normal 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.
|
||||
39
docs/guides/binary/arraybuffer-to-typedarray.md
Normal file
39
docs/guides/binary/arraybuffer-to-typedarray.md
Normal 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.
|
||||
14
docs/guides/binary/blob-to-arraybuffer.md
Normal file
14
docs/guides/binary/blob-to-arraybuffer.md
Normal 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.
|
||||
14
docs/guides/binary/blob-to-dataview.md
Normal file
14
docs/guides/binary/blob-to-dataview.md
Normal 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.
|
||||
14
docs/guides/binary/blob-to-stream.md
Normal file
14
docs/guides/binary/blob-to-stream.md
Normal 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.
|
||||
15
docs/guides/binary/blob-to-string.md
Normal file
15
docs/guides/binary/blob-to-string.md
Normal 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.
|
||||
14
docs/guides/binary/blob-to-typedarray.md
Normal file
14
docs/guides/binary/blob-to-typedarray.md
Normal 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.
|
||||
14
docs/guides/binary/buffer-to-arraybuffer.md
Normal file
14
docs/guides/binary/buffer-to-arraybuffer.md
Normal 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.
|
||||
14
docs/guides/binary/buffer-to-blob.md
Normal file
14
docs/guides/binary/buffer-to-blob.md
Normal 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.
|
||||
41
docs/guides/binary/buffer-to-readablestream.md
Normal file
41
docs/guides/binary/buffer-to-readablestream.md
Normal 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.
|
||||
25
docs/guides/binary/buffer-to-string.md
Normal file
25
docs/guides/binary/buffer-to-string.md
Normal 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.
|
||||
14
docs/guides/binary/buffer-to-typedarray.md
Normal file
14
docs/guides/binary/buffer-to-typedarray.md
Normal 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.
|
||||
15
docs/guides/binary/dataview-to-string.md
Normal file
15
docs/guides/binary/dataview-to-string.md
Normal 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.
|
||||
4
docs/guides/binary/index.json
Normal file
4
docs/guides/binary/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Binary data",
|
||||
"description": "A collection of guides for converting between binary data formats with Bun"
|
||||
}
|
||||
25
docs/guides/binary/typedarray-to-arraybuffer.md
Normal file
25
docs/guides/binary/typedarray-to-arraybuffer.md
Normal 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.
|
||||
16
docs/guides/binary/typedarray-to-blob.md
Normal file
16
docs/guides/binary/typedarray-to-blob.md
Normal 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.
|
||||
14
docs/guides/binary/typedarray-to-buffer.md
Normal file
14
docs/guides/binary/typedarray-to-buffer.md
Normal 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.
|
||||
14
docs/guides/binary/typedarray-to-dataview.md
Normal file
14
docs/guides/binary/typedarray-to-dataview.md
Normal 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.
|
||||
41
docs/guides/binary/typedarray-to-readablestream.md
Normal file
41
docs/guides/binary/typedarray-to-readablestream.md
Normal 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.
|
||||
16
docs/guides/binary/typedarray-to-string.md
Normal file
16
docs/guides/binary/typedarray-to-string.md
Normal 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.
|
||||
77
docs/guides/ecosystem/discordjs.md
Normal file
77
docs/guides/ecosystem/discordjs.md
Normal 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.
|
||||
4
docs/guides/ecosystem/index.json
Normal file
4
docs/guides/ecosystem/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Ecosystem",
|
||||
"description": "A collection of guides for using various tools and frameworks with Bun"
|
||||
}
|
||||
80
docs/guides/ecosystem/mongoose.md
Normal file
80
docs/guides/ecosystem/mongoose.md
Normal 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.
|
||||
110
docs/guides/ecosystem/prisma.md
Normal file
110
docs/guides/ecosystem/prisma.md
Normal 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.
|
||||
71
docs/guides/ecosystem/vite.md
Normal file
71
docs/guides/ecosystem/vite.md
Normal 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
55
docs/guides/http/hot.md
Normal 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;
|
||||
```
|
||||
4
docs/guides/http/index.json
Normal file
4
docs/guides/http/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "HTTP",
|
||||
"description": "A collection of guides for building HTTP servers with Bun"
|
||||
}
|
||||
18
docs/guides/http/simple.md
Normal file
18
docs/guides/http/simple.md
Normal 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}`);
|
||||
```
|
||||
48
docs/guides/http/stream-file.md
Normal file
48
docs/guides/http/stream-file.md
Normal 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
30
docs/guides/http/tls.md
Normal 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")],
|
||||
},
|
||||
});
|
||||
```
|
||||
22
docs/guides/process/argv.md
Normal file
22
docs/guides/process/argv.md
Normal 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).
|
||||
16
docs/guides/process/ctrl-c.md
Normal file
16
docs/guides/process/ctrl-c.md
Normal 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.
|
||||
4
docs/guides/process/index.json
Normal file
4
docs/guides/process/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Processes",
|
||||
"description": "A collection of guides for inspecting the current process and creating child processes with Bun"
|
||||
}
|
||||
13
docs/guides/process/nanoseconds.md
Normal file
13
docs/guides/process/nanoseconds.md
Normal 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.
|
||||
39
docs/guides/process/os-signals.md
Normal file
39
docs/guides/process/os-signals.md
Normal 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.
|
||||
31
docs/guides/process/spawn-stderr.md
Normal file
31
docs/guides/process/spawn-stderr.md
Normal 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..
|
||||
26
docs/guides/process/spawn-stdout.md
Normal file
26
docs/guides/process/spawn-stdout.md
Normal 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..
|
||||
41
docs/guides/process/spawn.md
Normal file
41
docs/guides/process/spawn.md
Normal 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..
|
||||
54
docs/guides/process/stdin.md
Normal file
54
docs/guides/process/stdin.md
Normal 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.
|
||||
28
docs/guides/read-file/arraybuffer.md
Normal file
28
docs/guides/read-file/arraybuffer.md
Normal 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.
|
||||
19
docs/guides/read-file/buffer.md
Normal file
19
docs/guides/read-file/buffer.md
Normal 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.
|
||||
16
docs/guides/read-file/exists.md
Normal file
16
docs/guides/read-file/exists.md
Normal 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`.
|
||||
4
docs/guides/read-file/index.json
Normal file
4
docs/guides/read-file/index.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Reading files",
|
||||
"description": "A collection of guides for reading files with Bun"
|
||||
}
|
||||
34
docs/guides/read-file/json.md
Normal file
34
docs/guides/read-file/json.md
Normal 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"
|
||||
```
|
||||
20
docs/guides/read-file/mime.md
Normal file
20
docs/guides/read-file/mime.md
Normal 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`.
|
||||
26
docs/guides/read-file/stream.md
Normal file
26
docs/guides/read-file/stream.md
Normal 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.
|
||||
22
docs/guides/read-file/string.md
Normal file
22
docs/guides/read-file/string.md
Normal 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);
|
||||
```
|
||||
22
docs/guides/read-file/uint8array.md
Normal file
22
docs/guides/read-file/uint8array.md
Normal 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.
|
||||
68
docs/guides/read-file/watch.md
Normal file
68
docs/guides/read-file/watch.md
Normal 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
Reference in New Issue
Block a user