mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Compare commits
495 Commits
claude/imp
...
ali/react
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e3ee654f2 | ||
|
|
f8dce87f24 | ||
|
|
359f04d81f | ||
|
|
9ce2504554 | ||
|
|
5d76a0b2f8 | ||
|
|
8a9249c216 | ||
|
|
aad4d800ff | ||
|
|
528620e9ae | ||
|
|
7197fb1f04 | ||
|
|
946470dcd7 | ||
|
|
d76fad3618 | ||
|
|
bdaab89253 | ||
|
|
797847639a | ||
|
|
39c43170e6 | ||
|
|
f770b1b1c7 | ||
|
|
42543fb544 | ||
|
|
60c0fd7786 | ||
|
|
219b9c6cfc | ||
|
|
a912eca96a | ||
|
|
8058d78b6a | ||
|
|
8b98746808 | ||
|
|
f50b44e35b | ||
|
|
b02d46498e | ||
|
|
28be8a9915 | ||
|
|
5aeef40479 | ||
|
|
9953d78a66 | ||
|
|
0564b81e64 | ||
|
|
7c9e8a2b10 | ||
|
|
c5def80191 | ||
|
|
fb6384160d | ||
|
|
759018caf9 | ||
|
|
b3b465937f | ||
|
|
570b0a03a4 | ||
|
|
358596afbd | ||
|
|
5b5b02dee6 | ||
|
|
8f0f06ba52 | ||
|
|
90ce355ef0 | ||
|
|
476e1cfe69 | ||
|
|
646aede0d4 | ||
|
|
1d728bb778 | ||
|
|
a7fc6eb354 | ||
|
|
ddd4018bda | ||
|
|
1de4448425 | ||
|
|
9d4a04cff9 | ||
|
|
9d0ef94557 | ||
|
|
a5f8b0e8dd | ||
|
|
fe1bc56637 | ||
|
|
98c04e37ec | ||
|
|
4f1b90ad1d | ||
|
|
51431b6e65 | ||
|
|
eb77bdd286 | ||
|
|
523fc14d76 | ||
|
|
a0a69ee146 | ||
|
|
668eba0eb8 | ||
|
|
6580b563b0 | ||
|
|
f3ed784a6b | ||
|
|
64bfd8b938 | ||
|
|
2afafbfa23 | ||
|
|
1e849b905a | ||
|
|
b280e8d326 | ||
|
|
b7ae21d0bc | ||
|
|
a75cef5079 | ||
|
|
4c00d8f016 | ||
|
|
f58a066236 | ||
|
|
3367fa6ae3 | ||
|
|
a2b262ed69 | ||
|
|
fb1fbe62e6 | ||
|
|
d2c2842420 | ||
|
|
0fba69d50c | ||
|
|
f4b6396eac | ||
|
|
cfe561a083 | ||
|
|
5a7b824091 | ||
|
|
a3f18b9e0e | ||
|
|
afd125fc12 | ||
|
|
0dd6aa47ea | ||
|
|
ab1395d38e | ||
|
|
e76570f452 | ||
|
|
d648547942 | ||
|
|
787a46d110 | ||
|
|
29028bbabe | ||
|
|
5a82e85876 | ||
|
|
7bf67e78d7 | ||
|
|
fb75e077a2 | ||
|
|
24d9d642de | ||
|
|
b278c85753 | ||
|
|
066f706a99 | ||
|
|
0ad4e6af2d | ||
|
|
b90abdda08 | ||
|
|
89fa0f3439 | ||
|
|
72f1ffdaf7 | ||
|
|
bb5f0f5d69 | ||
|
|
a3c43dc8b9 | ||
|
|
45841d6630 | ||
|
|
d846e9a1e7 | ||
|
|
06eea5213a | ||
|
|
1aaabcf4de | ||
|
|
3bc78598c6 | ||
|
|
12e22af382 | ||
|
|
88fa296dcd | ||
|
|
cd8043b76e | ||
|
|
840c6ca471 | ||
|
|
150338faab | ||
|
|
7662de9632 | ||
|
|
789a5f4078 | ||
|
|
965051fd1f | ||
|
|
7750afa29b | ||
|
|
2c86fdb818 | ||
|
|
07317193fe | ||
|
|
3e53ada574 | ||
|
|
25a8dea38b | ||
|
|
3520393b25 | ||
|
|
8b8e98d0fb | ||
|
|
b1f83d0bb2 | ||
|
|
32a28385dd | ||
|
|
881514a18a | ||
|
|
6dffd32d52 | ||
|
|
5971bf67ef | ||
|
|
686998ed3d | ||
|
|
b3c69e5a4e | ||
|
|
1e3e693f4a | ||
|
|
2557b1cc2a | ||
|
|
e306ac831e | ||
|
|
ebc0cfeacd | ||
|
|
abb85018df | ||
|
|
1c4d8b1c1c | ||
|
|
3921f76ff8 | ||
|
|
74fa49963c | ||
|
|
fb2bf3fe83 | ||
|
|
4539d241a1 | ||
|
|
6f3dfa79bb | ||
|
|
767c61d355 | ||
|
|
e63a897c66 | ||
|
|
576b21f2ff | ||
|
|
ed1eb21093 | ||
|
|
4a4a37796b | ||
|
|
7aef153f5d | ||
|
|
3cb64478d7 | ||
|
|
7dfed6b986 | ||
|
|
5972cf24cb | ||
|
|
329c79364d | ||
|
|
da5bf73494 | ||
|
|
fbd58db004 | ||
|
|
81999c26e6 | ||
|
|
dde1f9e610 | ||
|
|
c9b5ba1c96 | ||
|
|
74f4fcf2a6 | ||
|
|
031f12442d | ||
|
|
a20a718e48 | ||
|
|
33537b6ec1 | ||
|
|
952436fc4c | ||
|
|
31352bc646 | ||
|
|
ff84564c11 | ||
|
|
cc78a1bca1 | ||
|
|
3ca89abacf | ||
|
|
2f02e4e31d | ||
|
|
efb508e2ae | ||
|
|
86af3dd034 | ||
|
|
a6d3808ad8 | ||
|
|
2153fe4163 | ||
|
|
6977b36215 | ||
|
|
ceaab9eda3 | ||
|
|
f262e32368 | ||
|
|
69a76d44f9 | ||
|
|
fc9538baf1 | ||
|
|
72b7956385 | ||
|
|
62b296bb43 | ||
|
|
cb14f70a43 | ||
|
|
38511375f8 | ||
|
|
06cfe2ead1 | ||
|
|
4f219503fe | ||
|
|
b2353d687e | ||
|
|
65e66099f7 | ||
|
|
c534f0caa0 | ||
|
|
a873152aeb | ||
|
|
a17eb07d48 | ||
|
|
1381de4d18 | ||
|
|
8d8b037e94 | ||
|
|
f43a175f72 | ||
|
|
e1ad16f857 | ||
|
|
661a246039 | ||
|
|
d0fed20c89 | ||
|
|
1c6165e68a | ||
|
|
daefbfb453 | ||
|
|
971e4679cf | ||
|
|
49a9dc7ddf | ||
|
|
b5a5fea9ae | ||
|
|
243a237a62 | ||
|
|
49cfda12a8 | ||
|
|
ab579a3cc3 | ||
|
|
8cd9b4eae6 | ||
|
|
dd9860f501 | ||
|
|
756e590782 | ||
|
|
c62613e765 | ||
|
|
7f96bf8f13 | ||
|
|
cd800b02f5 | ||
|
|
de999f78ab | ||
|
|
24748104ce | ||
|
|
3fca3b97d9 | ||
|
|
4cec2ecdc6 | ||
|
|
cdeb7bfb00 | ||
|
|
98b24f5797 | ||
|
|
678843fb59 | ||
|
|
7227745249 | ||
|
|
472e2d379f | ||
|
|
16360c9432 | ||
|
|
1b3d0d5c40 | ||
|
|
799248bfb4 | ||
|
|
a2689c03e9 | ||
|
|
2a7e2c9cf3 | ||
|
|
4f0d2a5624 | ||
|
|
23230112b0 | ||
|
|
c2c2a1685a | ||
|
|
09716704bb | ||
|
|
2d3223c5a6 | ||
|
|
891ea726d6 | ||
|
|
11eddb2cf1 | ||
|
|
0cc63255b1 | ||
|
|
71a5f9fb26 | ||
|
|
b257967189 | ||
|
|
4e629753cc | ||
|
|
7204820f19 | ||
|
|
af3a1ffd46 | ||
|
|
2ff068dad2 | ||
|
|
927065238b | ||
|
|
fa727b22de | ||
|
|
f20b0ced8e | ||
|
|
17fdb5bcdf | ||
|
|
f65d89ff8b | ||
|
|
c1931c11fe | ||
|
|
67d27499c3 | ||
|
|
85db75611b | ||
|
|
61519b320d | ||
|
|
c129d683cd | ||
|
|
0b0ffbf250 | ||
|
|
c64dd684c8 | ||
|
|
5aa5906ccf | ||
|
|
c93d8cf12b | ||
|
|
1a1091fd2c | ||
|
|
bdf77f968c | ||
|
|
457b4a46b3 | ||
|
|
3b2bea9820 | ||
|
|
5b4b99e2c4 | ||
|
|
da2be3f582 | ||
|
|
7282e92e48 | ||
|
|
80c28b6280 | ||
|
|
e40238fdc2 | ||
|
|
166e961202 | ||
|
|
58ecff4e0c | ||
|
|
a548ae7038 | ||
|
|
bbaabedce6 | ||
|
|
f84f90c09f | ||
|
|
43a7b6518a | ||
|
|
c85ab5218e | ||
|
|
bade403361 | ||
|
|
047eecc90c | ||
|
|
f03a1ab1c9 | ||
|
|
1e3057045c | ||
|
|
e92fd08930 | ||
|
|
deb3e94948 | ||
|
|
1b01f7c0da | ||
|
|
5e256e4b1f | ||
|
|
fc6fdbe300 | ||
|
|
247629aded | ||
|
|
2894e8d309 | ||
|
|
cc84e271ff | ||
|
|
c07150d5b1 | ||
|
|
b0d3815cf9 | ||
|
|
f145d8c30c | ||
|
|
3a23965581 | ||
|
|
0b45b9c29e | ||
|
|
9d679811cd | ||
|
|
cda3eb5396 | ||
|
|
b17dccc6e0 | ||
|
|
99a80a6fe6 | ||
|
|
8b7bc0fe59 | ||
|
|
7e89ca3d2f | ||
|
|
d8fa01ed41 | ||
|
|
361cd05676 | ||
|
|
dbe15d3020 | ||
|
|
3a200e8097 | ||
|
|
2701292a9f | ||
|
|
61b1aded3e | ||
|
|
36a414c087 | ||
|
|
ac02036879 | ||
|
|
612d41185b | ||
|
|
59b34efea8 | ||
|
|
243f3652f1 | ||
|
|
11dc2fae56 | ||
|
|
0919f237a5 | ||
|
|
691e731404 | ||
|
|
1a19be07ee | ||
|
|
903ac7bdd5 | ||
|
|
0ac6b17d4a | ||
|
|
921e3578b1 | ||
|
|
101bcb1ea0 | ||
|
|
f691ea1e96 | ||
|
|
53208e2538 | ||
|
|
53299d78b1 | ||
|
|
363c4a5c06 | ||
|
|
6e6120640e | ||
|
|
6556138c7b | ||
|
|
aea7b196e6 | ||
|
|
b3f92b0889 | ||
|
|
dab797b834 | ||
|
|
a8ff3f8ac3 | ||
|
|
b516eedc67 | ||
|
|
bcea163fd2 | ||
|
|
a47cbef4ca | ||
|
|
90e68fa095 | ||
|
|
da0b090834 | ||
|
|
e6aced6637 | ||
|
|
ce560cd318 | ||
|
|
e554c4e1ca | ||
|
|
731f42ca72 | ||
|
|
f33a852a80 | ||
|
|
f5122bdbf1 | ||
|
|
c29c69b9b5 | ||
|
|
916d44fc45 | ||
|
|
421a4f37cd | ||
|
|
d0da7076e6 | ||
|
|
ea78d564da | ||
|
|
6338d55f70 | ||
|
|
d3bdc77274 | ||
|
|
ecd2fed665 | ||
|
|
28447ab578 | ||
|
|
3e798f1787 | ||
|
|
a64f073ad3 | ||
|
|
bb19610f0d | ||
|
|
ed4a887047 | ||
|
|
894a654e26 | ||
|
|
99dd08bccb | ||
|
|
7339d1841b | ||
|
|
1217e87379 | ||
|
|
704661e96f | ||
|
|
8e659b2dc8 | ||
|
|
93007de396 | ||
|
|
2166f0c200 | ||
|
|
1a0a081e75 | ||
|
|
2eb33628d1 | ||
|
|
56e9c92b4a | ||
|
|
34cfdf039a | ||
|
|
d4a9c7a161 | ||
|
|
b5c16dcc1b | ||
|
|
0ba166eea3 | ||
|
|
1920a7c63c | ||
|
|
d56005b520 | ||
|
|
2bd5d68047 | ||
|
|
9c5c4edac4 | ||
|
|
cae0673dc4 | ||
|
|
51e18d379f | ||
|
|
199781bf4f | ||
|
|
ffeb21c49b | ||
|
|
d54ffd8012 | ||
|
|
dca34819b6 | ||
|
|
b4add533e6 | ||
|
|
7afcc8416f | ||
|
|
1ef578a0b4 | ||
|
|
8be4fb61d0 | ||
|
|
208ac7fb60 | ||
|
|
29b6faadf8 | ||
|
|
99df2e071f | ||
|
|
a3d91477a8 | ||
|
|
52c3e2e3f8 | ||
|
|
a7e95718ac | ||
|
|
db2960d27b | ||
|
|
bbfac709cc | ||
|
|
41fbeacee1 | ||
|
|
24b2929c9a | ||
|
|
bf992731c6 | ||
|
|
eafc04cc5d | ||
|
|
95cacdc6be | ||
|
|
6cf46e67f6 | ||
|
|
f28670ac68 | ||
|
|
0df21d7f30 | ||
|
|
39e7e55802 | ||
|
|
a63888ed6d | ||
|
|
e50385879b | ||
|
|
20d2f3805e | ||
|
|
d984f8f5ad | ||
|
|
9ea2ec876e | ||
|
|
0919e45c23 | ||
|
|
fd41a41ab9 | ||
|
|
fc06e1cf14 | ||
|
|
1778713cbf | ||
|
|
02d9da73bd | ||
|
|
6562275d15 | ||
|
|
cccae0cc79 | ||
|
|
c10d184448 | ||
|
|
0f8a232466 | ||
|
|
f47df15c18 | ||
|
|
f2d3141767 | ||
|
|
c8b21f207d | ||
|
|
6357978b90 | ||
|
|
151d8bb413 | ||
|
|
42bfccee3c | ||
|
|
f219a29248 | ||
|
|
b588512237 | ||
|
|
3a42ad8b1f | ||
|
|
cc1fff363d | ||
|
|
ba5e4784aa | ||
|
|
3e747886aa | ||
|
|
9504d14b7a | ||
|
|
911b670621 | ||
|
|
679282b8c6 | ||
|
|
1f79bc15a3 | ||
|
|
80a945f03f | ||
|
|
43054c9a7f | ||
|
|
2fad71dd45 | ||
|
|
6b2c3e61ea | ||
|
|
43d447f9fe | ||
|
|
8b35b5634a | ||
|
|
811f0888c8 | ||
|
|
a5d7830862 | ||
|
|
ef17dc57e4 | ||
|
|
e58cb4511e | ||
|
|
d44b3db1cb | ||
|
|
857e25d88c | ||
|
|
6eee2eeaf6 | ||
|
|
cc3e4d8319 | ||
|
|
278c2e7fb6 | ||
|
|
e296928ab9 | ||
|
|
39c1bf38f5 | ||
|
|
91d30b4da0 | ||
|
|
c2812fff79 | ||
|
|
e0337f5649 | ||
|
|
d05768cc18 | ||
|
|
1ad67908fc | ||
|
|
f55e320f41 | ||
|
|
8e0cf4c5e0 | ||
|
|
5dcf8a8076 | ||
|
|
d6b155f056 | ||
|
|
5f8393cc99 | ||
|
|
ee7dfefbe0 | ||
|
|
6d132e628f | ||
|
|
ae9ecc99c9 | ||
|
|
eeecbfa790 | ||
|
|
862f7378e4 | ||
|
|
636e597b60 | ||
|
|
6abb9f81eb | ||
|
|
aa33b11a7a | ||
|
|
21266f5263 | ||
|
|
c5fc729fde | ||
|
|
03d1e48004 | ||
|
|
19b9c4a850 | ||
|
|
842503ecb1 | ||
|
|
cb9c45c26c | ||
|
|
917dcc846f | ||
|
|
0fb277a56e | ||
|
|
c343aca21e | ||
|
|
e89a0f3807 | ||
|
|
59f12d30b3 | ||
|
|
f0d4fa8b63 | ||
|
|
3fb0a824cb | ||
|
|
ab3566627d | ||
|
|
3906407e5d | ||
|
|
33447ef2db | ||
|
|
3760407908 | ||
|
|
c1f0ce277d | ||
|
|
bfe3041179 | ||
|
|
5b6344cf3c | ||
|
|
b4fdf41ea5 | ||
|
|
b9da6b71f9 | ||
|
|
87487468f3 | ||
|
|
cfdeb42023 | ||
|
|
20e4c094ac | ||
|
|
17be416250 | ||
|
|
9745f01041 | ||
|
|
16131f92e1 | ||
|
|
59a4d0697b | ||
|
|
78a2ae44aa | ||
|
|
7f295919a9 | ||
|
|
1d0984b5c4 | ||
|
|
dfa93a8ede | ||
|
|
c8773c5e30 | ||
|
|
0f74fafc59 | ||
|
|
47d6e161fe | ||
|
|
160625c37c | ||
|
|
1b9b686772 | ||
|
|
6f3e098bac | ||
|
|
4c6b296a7c | ||
|
|
2ab962bf6b | ||
|
|
f556fc987c | ||
|
|
3a1b12ee61 | ||
|
|
a952b4200e | ||
|
|
24485fb432 | ||
|
|
b10fda0487 | ||
|
|
740cdaba3d | ||
|
|
68be15361a | ||
|
|
c57be8dcdb | ||
|
|
5115a88126 | ||
|
|
e992b804c8 | ||
|
|
b92555e099 | ||
|
|
381848cd69 | ||
|
|
61f9845f80 | ||
|
|
abc52da7bb |
@@ -108,9 +108,9 @@ const buildPlatforms = [
|
||||
{ os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", profile: "asan", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.22" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.22" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22" },
|
||||
{ os: "windows", arch: "x64", release: "2019" },
|
||||
{ os: "windows", arch: "x64", baseline: true, release: "2019" },
|
||||
];
|
||||
@@ -133,9 +133,9 @@ const testPlatforms = [
|
||||
{ os: "linux", arch: "x64", distro: "ubuntu", release: "24.04", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "25.04", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "24.04", tier: "latest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22", tier: "latest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", tier: "oldest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", baseline: true, tier: "oldest" },
|
||||
];
|
||||
@@ -343,7 +343,7 @@ function getZigPlatform() {
|
||||
arch: "aarch64",
|
||||
abi: "musl",
|
||||
distro: "alpine",
|
||||
release: "3.21",
|
||||
release: "3.22",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
43
.claude/commands/dedupe.md
Normal file
43
.claude/commands/dedupe.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)
|
||||
description: Find duplicate GitHub issues
|
||||
---
|
||||
|
||||
# Issue deduplication command
|
||||
|
||||
Find up to 3 likely duplicate issues for a given GitHub issue.
|
||||
|
||||
To do this, follow these steps precisely:
|
||||
|
||||
1. Use an agent to check if the GitHub issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicate detection comment (check for the exact HTML marker `<!-- dedupe-bot:marker -->` in the issue comments - ignore other bot comments). If so, do not proceed.
|
||||
2. Use an agent to view a GitHub issue, and ask the agent to return a summary of the issue
|
||||
3. Then, launch 5 parallel agents to search GitHub for duplicates of this issue, using diverse keywords and search approaches, using the summary from Step 2. **IMPORTANT**: Always scope searches with `repo:owner/repo` to constrain results to the current repository only.
|
||||
4. Next, feed the results from Steps 2 and 3 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.
|
||||
5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)
|
||||
|
||||
Notes (be sure to tell this to your agents, too):
|
||||
|
||||
- Use `gh` to interact with GitHub, rather than web fetch
|
||||
- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)
|
||||
- Make a todo list first
|
||||
- Always scope searches with `repo:owner/repo` to prevent cross-repo false positives
|
||||
- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):
|
||||
|
||||
---
|
||||
|
||||
Found 3 possible duplicate issues:
|
||||
|
||||
1. <link to issue>
|
||||
2. <link to issue>
|
||||
3. <link to issue>
|
||||
|
||||
This issue will be automatically closed as a duplicate in 3 days.
|
||||
|
||||
- If your issue is a duplicate, please close it and 👍 the existing issue instead
|
||||
- To prevent auto-closure, add a comment or 👎 this comment
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
||||
|
||||
<!-- dedupe-bot:marker -->
|
||||
|
||||
---
|
||||
143
.coderabbit.yaml
Normal file
143
.coderabbit.yaml
Normal file
@@ -0,0 +1,143 @@
|
||||
language: en-US
|
||||
|
||||
reviews:
|
||||
profile: assertive
|
||||
request_changes_workflow: false
|
||||
high_level_summary: false
|
||||
high_level_summary_placeholder: "@coderabbitai summary"
|
||||
high_level_summary_in_walkthrough: true
|
||||
auto_title_placeholder: "@coderabbitai"
|
||||
review_status: false
|
||||
commit_status: false
|
||||
fail_commit_status: false
|
||||
collapse_walkthrough: false
|
||||
changed_files_summary: true
|
||||
sequence_diagrams: false
|
||||
estimate_code_review_effort: false
|
||||
assess_linked_issues: true
|
||||
related_issues: true
|
||||
related_prs: true
|
||||
suggested_labels: false
|
||||
suggested_reviewers: true
|
||||
in_progress_fortune: false
|
||||
poem: false
|
||||
abort_on_close: true
|
||||
|
||||
path_filters:
|
||||
- "!test/js/node/test/"
|
||||
|
||||
auto_review:
|
||||
enabled: true
|
||||
auto_incremental_review: true
|
||||
drafts: false
|
||||
|
||||
finishing_touches:
|
||||
docstrings:
|
||||
enabled: false
|
||||
unit_tests:
|
||||
enabled: false
|
||||
|
||||
pre_merge_checks:
|
||||
docstrings:
|
||||
mode: off
|
||||
title:
|
||||
mode: warning
|
||||
description:
|
||||
mode: warning
|
||||
issue_assessment:
|
||||
mode: warning
|
||||
|
||||
tools:
|
||||
shellcheck:
|
||||
enabled: true
|
||||
ruff:
|
||||
enabled: true
|
||||
markdownlint:
|
||||
enabled: true
|
||||
github-checks:
|
||||
enabled: true
|
||||
timeout_ms: 90000
|
||||
languagetool:
|
||||
enabled: true
|
||||
enabled_only: false
|
||||
level: default
|
||||
biome:
|
||||
enabled: true
|
||||
hadolint:
|
||||
enabled: true
|
||||
swiftlint:
|
||||
enabled: true
|
||||
phpstan:
|
||||
enabled: true
|
||||
level: default
|
||||
phpmd:
|
||||
enabled: true
|
||||
phpcs:
|
||||
enabled: true
|
||||
golangci-lint:
|
||||
enabled: true
|
||||
yamllint:
|
||||
enabled: true
|
||||
gitleaks:
|
||||
enabled: true
|
||||
checkov:
|
||||
enabled: true
|
||||
detekt:
|
||||
enabled: true
|
||||
eslint:
|
||||
enabled: true
|
||||
flake8:
|
||||
enabled: true
|
||||
rubocop:
|
||||
enabled: true
|
||||
buf:
|
||||
enabled: true
|
||||
regal:
|
||||
enabled: true
|
||||
actionlint:
|
||||
enabled: true
|
||||
pmd:
|
||||
enabled: true
|
||||
clang:
|
||||
enabled: true
|
||||
cppcheck:
|
||||
enabled: true
|
||||
semgrep:
|
||||
enabled: true
|
||||
circleci:
|
||||
enabled: true
|
||||
clippy:
|
||||
enabled: true
|
||||
sqlfluff:
|
||||
enabled: true
|
||||
prismaLint:
|
||||
enabled: true
|
||||
pylint:
|
||||
enabled: true
|
||||
oxc:
|
||||
enabled: true
|
||||
shopifyThemeCheck:
|
||||
enabled: true
|
||||
luacheck:
|
||||
enabled: true
|
||||
brakeman:
|
||||
enabled: true
|
||||
dotenvLint:
|
||||
enabled: true
|
||||
htmlhint:
|
||||
enabled: true
|
||||
checkmake:
|
||||
enabled: true
|
||||
osvScanner:
|
||||
enabled: true
|
||||
|
||||
chat:
|
||||
auto_reply: true
|
||||
|
||||
knowledge_base:
|
||||
opt_out: false
|
||||
code_guidelines:
|
||||
enabled: true
|
||||
filePatterns:
|
||||
- "**/.cursor/rules/*.mdc"
|
||||
- "**/CLAUDE.md"
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -47,6 +47,7 @@ examples/**/* linguist-documentation
|
||||
|
||||
vendor/*.c linguist-vendored
|
||||
vendor/brotli/** linguist-vendored
|
||||
packages/bun-framework-react/vendor/** linguist-vendored -diff -merge
|
||||
|
||||
test/js/node/test/fixtures linguist-vendored
|
||||
test/js/node/test/common linguist-vendored
|
||||
|
||||
29
.github/workflows/auto-close-duplicates.yml
vendored
Normal file
29
.github/workflows/auto-close-duplicates.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Auto-close duplicate issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 9 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
auto-close-duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
concurrency:
|
||||
group: auto-close-duplicates-${{ github.repository }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
|
||||
- name: Auto-close duplicate issues
|
||||
run: bun run scripts/auto-close-duplicates.ts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
34
.github/workflows/claude-dedupe-issues.yml
vendored
Normal file
34
.github/workflows/claude-dedupe-issues.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Claude Issue Dedupe
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: 'Issue number to process for duplicate detection'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
claude-dedupe-issues:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
concurrency:
|
||||
group: claude-dedupe-issues-${{ github.event.issue.number || inputs.issue_number }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Claude Code slash command
|
||||
uses: anthropics/claude-code-base-action@beta
|
||||
with:
|
||||
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
claude_args: "--model claude-sonnet-4-5-20250929"
|
||||
claude_env: |
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -76,7 +76,8 @@ test("my feature", async () => {
|
||||
- Use `normalizeBunSnapshot` to normalize snapshot output of the test.
|
||||
- NEVER write tests that check for no "panic" or "uncaught exception" or similar in the test output. That is NOT a valid test.
|
||||
- Use `tempDir` from `"harness"` to create a temporary directory. **Do not** use `tmpdirSync` or `fs.mkdtempSync` to create temporary directories.
|
||||
- When spawning processes, tests should assert the output BEFORE asserting the exit code. This gives you a more useful error message on test failure.
|
||||
- When spawning processes, tests should expect(stdout).toBe(...) BEFORE expect(exitCode).toBe(0). This gives you a more useful error message on test failure.
|
||||
- **CRITICAL**: Do not write flaky tests. Do not use `setTimeout` in tests. Instead, `await` the condition to be met. You are not testing the TIME PASSING, you are testing the CONDITION.
|
||||
- **CRITICAL**: Verify your test fails with `USE_SYSTEM_BUN=1 bun test <file>` and passes with `bun bd test <file>`. Your test is NOT VALID if it passes with `USE_SYSTEM_BUN=1`.
|
||||
|
||||
## Code Architecture
|
||||
|
||||
@@ -1,40 +1,29 @@
|
||||
# `install` benchmark
|
||||
# Create T3 App
|
||||
|
||||
Requires [`hyperfine`](https://github.com/sharkdp/hyperfine). The goal of this benchmark is to compare installation performance of Bun with other package managers _when caches are hot_.
|
||||
This is a [T3 Stack](https://create.t3.gg/) project bootstrapped with `create-t3-app`.
|
||||
|
||||
### With lockfile, online mode
|
||||
## What's next? How do I make an app with this?
|
||||
|
||||
To run the benchmark with the standard "install" command for each package manager:
|
||||
We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary.
|
||||
|
||||
```sh
|
||||
$ hyperfine --prepare 'rm -rf node_modules' --warmup 1 --runs 3 'bun install' 'pnpm install' 'yarn' 'npm install'
|
||||
```
|
||||
If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help.
|
||||
|
||||
### With lockfile, offline mode
|
||||
- [Next.js](https://nextjs.org)
|
||||
- [NextAuth.js](https://next-auth.js.org)
|
||||
- [Prisma](https://prisma.io)
|
||||
- [Drizzle](https://orm.drizzle.team)
|
||||
- [Tailwind CSS](https://tailwindcss.com)
|
||||
- [tRPC](https://trpc.io)
|
||||
|
||||
Even though all packages are cached, some tools may hit the npm API during the version resolution step. (This is not the same as re-downloading a package.) To entirely avoid network calls, the other package managers require `--prefer-offline/--offline` flag. To run the benchmark using "offline" mode:
|
||||
## Learn More
|
||||
|
||||
```sh
|
||||
$ hyperfine --prepare 'rm -rf node_modules' --runs 1 'bun install' 'pnpm install --prefer-offline' 'yarn --offline' 'npm install --prefer-offline'
|
||||
```
|
||||
To learn more about the [T3 Stack](https://create.t3.gg/), take a look at the following resources:
|
||||
|
||||
### Without lockfile, offline mode
|
||||
- [Documentation](https://create.t3.gg/)
|
||||
- [Learn the T3 Stack](https://create.t3.gg/en/faq#what-learning-resources-are-currently-available) — Check out these awesome tutorials
|
||||
|
||||
To run the benchmark with offline mode but without lockfiles:
|
||||
You can check out the [create-t3-app GitHub repository](https://github.com/t3-oss/create-t3-app) — your feedback and contributions are welcome!
|
||||
|
||||
```sh
|
||||
$ hyperfine --prepare 'rm -rf node_modules' --warmup 1 'rm bun.lock && bun install' 'rm pnpm-lock.yaml && pnpm install --prefer-offline' 'rm yarn.lock && yarn --offline' 'rm package-lock.json && npm install --prefer-offline'
|
||||
```
|
||||
## How do I deploy this?
|
||||
|
||||
##
|
||||
|
||||
To check that the app is working as expected:
|
||||
|
||||
```
|
||||
$ bun run dev
|
||||
$ npm run dev
|
||||
$ yarn dev
|
||||
$ pnpm dev
|
||||
```
|
||||
|
||||
Then visit [http://localhost:3000](http://localhost:3000).
|
||||
Follow our deployment guides for [Vercel](https://create.t3.gg/en/deployment/vercel), [Netlify](https://create.t3.gg/en/deployment/netlify) and [Docker](https://create.t3.gg/en/deployment/docker) for more information.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* By default, Remix will handle hydrating your app on the client for you.
|
||||
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
|
||||
* For more information, see https://remix.run/docs/en/main/file-conventions/entry.client
|
||||
*/
|
||||
|
||||
import { RemixBrowser } from "@remix-run/react";
|
||||
import { startTransition, StrictMode } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
|
||||
startTransition(() => {
|
||||
hydrateRoot(
|
||||
document,
|
||||
<StrictMode>
|
||||
<RemixBrowser />
|
||||
</StrictMode>,
|
||||
);
|
||||
});
|
||||
@@ -1,101 +0,0 @@
|
||||
/**
|
||||
* By default, Remix will handle generating the HTTP Response for you.
|
||||
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
|
||||
* For more information, see https://remix.run/docs/en/main/file-conventions/entry.server
|
||||
*/
|
||||
|
||||
import type { EntryContext } from "@remix-run/node";
|
||||
import { Response } from "@remix-run/node";
|
||||
import { RemixServer } from "@remix-run/react";
|
||||
import isbot from "isbot";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { renderToPipeableStream } from "react-dom/server";
|
||||
|
||||
const ABORT_DELAY = 5_000;
|
||||
|
||||
export default function handleRequest(
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext,
|
||||
) {
|
||||
return isbot(request.headers.get("user-agent"))
|
||||
? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext)
|
||||
: handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext);
|
||||
}
|
||||
|
||||
function handleBotRequest(
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext,
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { pipe, abort } = renderToPipeableStream(
|
||||
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />,
|
||||
{
|
||||
onAllReady() {
|
||||
const body = new PassThrough();
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
|
||||
resolve(
|
||||
new Response(body, {
|
||||
headers: responseHeaders,
|
||||
status: responseStatusCode,
|
||||
}),
|
||||
);
|
||||
|
||||
pipe(body);
|
||||
},
|
||||
onShellError(error: unknown) {
|
||||
reject(error);
|
||||
},
|
||||
onError(error: unknown) {
|
||||
responseStatusCode = 500;
|
||||
console.error(error);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
setTimeout(abort, ABORT_DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
function handleBrowserRequest(
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext,
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { pipe, abort } = renderToPipeableStream(
|
||||
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />,
|
||||
{
|
||||
onShellReady() {
|
||||
const body = new PassThrough();
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
|
||||
resolve(
|
||||
new Response(body, {
|
||||
headers: responseHeaders,
|
||||
status: responseStatusCode,
|
||||
}),
|
||||
);
|
||||
|
||||
pipe(body);
|
||||
},
|
||||
onShellError(error: unknown) {
|
||||
reject(error);
|
||||
},
|
||||
onError(error: unknown) {
|
||||
console.error(error);
|
||||
responseStatusCode = 500;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
setTimeout(abort, ABORT_DELAY);
|
||||
});
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<Meta />
|
||||
<Links />
|
||||
</head>
|
||||
<body>
|
||||
<Outlet />
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
<LiveReload />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import type { V2_MetaFunction } from "@remix-run/node";
|
||||
|
||||
export const meta: V2_MetaFunction = () => {
|
||||
return [{ title: "New Remix App" }];
|
||||
};
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
|
||||
<h1>Welcome to Remix</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a target="_blank" href="https://remix.run/tutorials/blog" rel="noreferrer">
|
||||
15m Quickstart Blog Tutorial
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://remix.run/tutorials/jokes" rel="noreferrer">
|
||||
Deep Dive Jokes App Tutorial
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a target="_blank" href="https://remix.run/docs" rel="noreferrer">
|
||||
Remix Docs
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
488
bench/install/bun.lock
Normal file
488
bench/install/bun.lock
Normal file
@@ -0,0 +1,488 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "installbench",
|
||||
"dependencies": {
|
||||
"@auth/drizzle-adapter": "^1.7.2",
|
||||
"@t3-oss/env-nextjs": "^0.12.0",
|
||||
"@tanstack/react-query": "^5.69.0",
|
||||
"@trpc/client": "^11.0.0",
|
||||
"@trpc/react-query": "^11.0.0",
|
||||
"@trpc/server": "^11.0.0",
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"esbuild": "^0.25.11",
|
||||
"next": "^15.2.3",
|
||||
"next-auth": "5.0.0-beta.25",
|
||||
"postgres": "^3.4.4",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"server-only": "^0.0.1",
|
||||
"superjson": "^2.2.1",
|
||||
"zod": "^3.24.2",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@tailwindcss/postcss": "^4.0.15",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^4.0.15",
|
||||
"typescript": "^5.8.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||
|
||||
"@auth/core": ["@auth/core@0.41.1", "", { "dependencies": { "@panva/hkdf": "1.2.1", "jose": "6.1.0", "oauth4webapi": "3.8.2", "preact": "10.24.3", "preact-render-to-string": "6.5.11" } }, "sha512-t9cJ2zNYAdWMacGRMT6+r4xr1uybIdmYa49calBPeTqwgAFPV/88ac9TEvCR85pvATiSPt8VaNf+Gt24JIT/uw=="],
|
||||
|
||||
"@auth/drizzle-adapter": ["@auth/drizzle-adapter@1.11.1", "", { "dependencies": { "@auth/core": "0.41.1" } }, "sha512-cQTvDZqsyF7RPhDm/B6SvqdVP9EzQhy3oM4Muu7fjjmSYFLbSR203E6dH631ZHSKDn2b4WZkfMnjPDzRsPSAeA=="],
|
||||
|
||||
"@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
|
||||
|
||||
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="],
|
||||
|
||||
"@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "0.18.20", "source-map-support": "0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
|
||||
|
||||
"@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "3.3.2", "get-tsconfig": "4.13.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.11", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.11", "", { "os": "android", "cpu": "arm" }, "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.11", "", { "os": "android", "cpu": "arm64" }, "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.11", "", { "os": "android", "cpu": "x64" }, "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.11", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.11", "", { "os": "linux", "cpu": "arm" }, "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.11", "", { "os": "linux", "cpu": "ia32" }, "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.11", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.11", "", { "os": "linux", "cpu": "s390x" }, "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.11", "", { "os": "linux", "cpu": "x64" }, "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ=="],
|
||||
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.11", "", { "os": "none", "cpu": "x64" }, "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A=="],
|
||||
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.11", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.11", "", { "os": "openbsd", "cpu": "x64" }, "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw=="],
|
||||
|
||||
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.11", "", { "os": "sunos", "cpu": "x64" }, "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.11", "", { "os": "win32", "cpu": "x64" }, "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA=="],
|
||||
|
||||
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
|
||||
|
||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="],
|
||||
|
||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.3", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="],
|
||||
|
||||
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="],
|
||||
|
||||
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="],
|
||||
|
||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="],
|
||||
|
||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="],
|
||||
|
||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="],
|
||||
|
||||
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="],
|
||||
|
||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="],
|
||||
|
||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="],
|
||||
|
||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="],
|
||||
|
||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="],
|
||||
|
||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.4", "", { "dependencies": { "@emnapi/runtime": "1.6.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="],
|
||||
|
||||
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="],
|
||||
|
||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="],
|
||||
|
||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.4", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||
|
||||
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@next/env": ["@next/env@15.5.6", "", {}, "sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q=="],
|
||||
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg=="],
|
||||
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA=="],
|
||||
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg=="],
|
||||
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w=="],
|
||||
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA=="],
|
||||
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ=="],
|
||||
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg=="],
|
||||
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ=="],
|
||||
|
||||
"@panva/hkdf": ["@panva/hkdf@1.2.1", "", {}, "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw=="],
|
||||
|
||||
"@petamoriken/float16": ["@petamoriken/float16@3.9.3", "", {}, "sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g=="],
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||
|
||||
"@t3-oss/env-core": ["@t3-oss/env-core@0.12.0", "", { "optionalDependencies": { "typescript": "5.9.3", "zod": "3.25.76" } }, "sha512-lOPj8d9nJJTt81mMuN9GMk8x5veOt7q9m11OSnCBJhwp1QrL/qR+M8Y467ULBSm9SunosryWNbmQQbgoiMgcdw=="],
|
||||
|
||||
"@t3-oss/env-nextjs": ["@t3-oss/env-nextjs@0.12.0", "", { "dependencies": { "@t3-oss/env-core": "0.12.0" }, "optionalDependencies": { "typescript": "5.9.3", "zod": "3.25.76" } }, "sha512-rFnvYk1049RnNVUPvY8iQ55AuQh1Rr+qZzQBh3t++RttCGK4COpXGNxS4+45afuQq02lu+QAOy/5955aU8hRKw=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.16", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "enhanced-resolve": "5.18.3", "jiti": "2.6.1", "lightningcss": "1.30.2", "magic-string": "0.30.21", "source-map-js": "1.2.1", "tailwindcss": "4.1.16" } }, "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.16", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.16", "@tailwindcss/oxide-darwin-arm64": "4.1.16", "@tailwindcss/oxide-darwin-x64": "4.1.16", "@tailwindcss/oxide-freebsd-x64": "4.1.16", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", "@tailwindcss/oxide-linux-x64-musl": "4.1.16", "@tailwindcss/oxide-wasm32-wasi": "4.1.16", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" } }, "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg=="],
|
||||
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.16", "", { "os": "android", "cpu": "arm64" }, "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16", "", { "os": "linux", "cpu": "arm" }, "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.16", "", { "cpu": "none" }, "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg=="],
|
||||
|
||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.16", "", { "dependencies": { "@alloc/quick-lru": "5.2.0", "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "postcss": "8.5.6", "tailwindcss": "4.1.16" } }, "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A=="],
|
||||
|
||||
"@tanstack/query-core": ["@tanstack/query-core@5.90.5", "", {}, "sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w=="],
|
||||
|
||||
"@tanstack/react-query": ["@tanstack/react-query@5.90.5", "", { "dependencies": { "@tanstack/query-core": "5.90.5" }, "peerDependencies": { "react": "19.2.0" } }, "sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q=="],
|
||||
|
||||
"@trpc/client": ["@trpc/client@11.7.1", "", { "peerDependencies": { "@trpc/server": "11.7.1", "typescript": "5.9.3" } }, "sha512-uOnAjElKI892/U6aQMcBHYs3x7mme3Cvv1F87ytBL56rBvs7+DyK7r43zgaXKf13+GtPEI6ex5xjVUfyDW8XcQ=="],
|
||||
|
||||
"@trpc/react-query": ["@trpc/react-query@11.7.1", "", { "peerDependencies": { "@tanstack/react-query": "5.90.5", "@trpc/client": "11.7.1", "@trpc/server": "11.7.1", "react": "19.2.0", "react-dom": "19.2.0", "typescript": "5.9.3" } }, "sha512-dEHDjIqSTzO8nLlCbtiFBMBwhbSkK1QP7aYVo3nP3sYBna0b+iCtrPXdxVPCSopr9/aIqDTEh+dMRZa7yBgjfQ=="],
|
||||
|
||||
"@trpc/server": ["@trpc/server@11.7.1", "", { "peerDependencies": { "typescript": "5.9.3" } }, "sha512-N3U8LNLIP4g9C7LJ/sLkjuPHwqlvE3bnspzC4DEFVdvx2+usbn70P80E3wj5cjOTLhmhRiwJCSXhlB+MHfGeCw=="],
|
||||
|
||||
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||
|
||||
"@types/node": ["@types/node@20.19.24", "", { "dependencies": { "undici-types": "6.21.0" } }, "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "3.1.3" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.2", "", { "peerDependencies": { "@types/react": "19.2.2" } }, "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw=="],
|
||||
|
||||
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001752", "", {}, "sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g=="],
|
||||
|
||||
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
|
||||
|
||||
"cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="],
|
||||
|
||||
"copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "5.5.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||
|
||||
"drizzle-kit": ["drizzle-kit@0.30.6", "", { "dependencies": { "@drizzle-team/brocli": "0.10.2", "@esbuild-kit/esm-loader": "2.6.5", "esbuild": "0.19.12", "esbuild-register": "3.6.0", "gel": "2.1.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-U4wWit0fyZuGuP7iNmRleQyK2V8wCuv57vf5l3MnG4z4fzNTjY/U13M8owyQ5RavqvqxBifWORaR3wIUzlN64g=="],
|
||||
|
||||
"drizzle-orm": ["drizzle-orm@0.41.0", "", { "optionalDependencies": { "gel": "2.1.1", "postgres": "3.4.7" } }, "sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "4.2.11", "tapable": "2.3.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
|
||||
|
||||
"env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.11", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.11", "@esbuild/android-arm": "0.25.11", "@esbuild/android-arm64": "0.25.11", "@esbuild/android-x64": "0.25.11", "@esbuild/darwin-arm64": "0.25.11", "@esbuild/darwin-x64": "0.25.11", "@esbuild/freebsd-arm64": "0.25.11", "@esbuild/freebsd-x64": "0.25.11", "@esbuild/linux-arm": "0.25.11", "@esbuild/linux-arm64": "0.25.11", "@esbuild/linux-ia32": "0.25.11", "@esbuild/linux-loong64": "0.25.11", "@esbuild/linux-mips64el": "0.25.11", "@esbuild/linux-ppc64": "0.25.11", "@esbuild/linux-riscv64": "0.25.11", "@esbuild/linux-s390x": "0.25.11", "@esbuild/linux-x64": "0.25.11", "@esbuild/netbsd-arm64": "0.25.11", "@esbuild/netbsd-x64": "0.25.11", "@esbuild/openbsd-arm64": "0.25.11", "@esbuild/openbsd-x64": "0.25.11", "@esbuild/openharmony-arm64": "0.25.11", "@esbuild/sunos-x64": "0.25.11", "@esbuild/win32-arm64": "0.25.11", "@esbuild/win32-ia32": "0.25.11", "@esbuild/win32-x64": "0.25.11" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q=="],
|
||||
|
||||
"esbuild-register": ["esbuild-register@3.6.0", "", { "dependencies": { "debug": "4.4.3" }, "peerDependencies": { "esbuild": "0.19.12" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="],
|
||||
|
||||
"gel": ["gel@2.1.1", "", { "dependencies": { "@petamoriken/float16": "3.9.3", "debug": "4.4.3", "env-paths": "3.0.0", "semver": "7.7.3", "shell-quote": "1.8.3", "which": "4.0.0" }, "bin": { "gel": "dist/cli.mjs" } }, "sha512-Newg9X7mRYskoBjSw70l1YnJ/ZGbq64VPyR821H5WVkTGpHG2O0mQILxCeUhxdYERLFY9B4tUyKLyf3uMTjtKw=="],
|
||||
|
||||
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="],
|
||||
|
||||
"isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
|
||||
|
||||
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
||||
|
||||
"jose": ["jose@6.1.0", "", {}, "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
|
||||
|
||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
|
||||
|
||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
|
||||
|
||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
|
||||
|
||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
|
||||
|
||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
|
||||
|
||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
|
||||
|
||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
|
||||
|
||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
|
||||
|
||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"next": ["next@15.5.6", "", { "dependencies": { "@next/env": "15.5.6", "@swc/helpers": "0.5.15", "caniuse-lite": "1.0.30001752", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.6", "@next/swc-darwin-x64": "15.5.6", "@next/swc-linux-arm64-gnu": "15.5.6", "@next/swc-linux-arm64-musl": "15.5.6", "@next/swc-linux-x64-gnu": "15.5.6", "@next/swc-linux-x64-musl": "15.5.6", "@next/swc-win32-arm64-msvc": "15.5.6", "@next/swc-win32-x64-msvc": "15.5.6", "sharp": "0.34.4" }, "peerDependencies": { "react": "19.2.0", "react-dom": "19.2.0" }, "bin": { "next": "dist/bin/next" } }, "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ=="],
|
||||
|
||||
"next-auth": ["next-auth@5.0.0-beta.25", "", { "dependencies": { "@auth/core": "0.37.2" }, "peerDependencies": { "next": "15.5.6", "react": "19.2.0" } }, "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog=="],
|
||||
|
||||
"oauth4webapi": ["oauth4webapi@3.8.2", "", {}, "sha512-FzZZ+bht5X0FKe7Mwz3DAVAmlH1BV5blSak/lHMBKz0/EBMhX6B10GlQYI51+oRp8ObJaX0g6pXrAxZh5s8rjw=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "3.3.11", "picocolors": "1.1.1", "source-map-js": "1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="],
|
||||
|
||||
"preact": ["preact@10.24.3", "", {}, "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA=="],
|
||||
|
||||
"preact-render-to-string": ["preact-render-to-string@6.5.11", "", { "peerDependencies": { "preact": "10.24.3" } }, "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw=="],
|
||||
|
||||
"pretty-format": ["pretty-format@3.8.0", "", {}, "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="],
|
||||
|
||||
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
||||
|
||||
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "0.27.0" }, "peerDependencies": { "react": "19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
||||
|
||||
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
|
||||
|
||||
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||
|
||||
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="],
|
||||
|
||||
"sharp": ["sharp@0.34.4", "", { "dependencies": { "@img/colour": "1.0.0", "detect-libc": "2.1.2", "semver": "7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "1.1.2", "source-map": "0.6.1" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
|
||||
|
||||
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": "19.2.0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
|
||||
|
||||
"superjson": ["superjson@2.2.5", "", { "dependencies": { "copy-anything": "4.0.5" } }, "sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w=="],
|
||||
|
||||
"tailwindcss": ["tailwindcss@4.1.16", "", {}, "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA=="],
|
||||
|
||||
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"which": ["which@4.0.0", "", { "dependencies": { "isexe": "3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
|
||||
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
|
||||
|
||||
"drizzle-kit/esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
|
||||
|
||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "3.3.11", "picocolors": "1.1.1", "source-map-js": "1.2.1" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"next-auth/@auth/core": ["@auth/core@0.37.2", "", { "dependencies": { "@panva/hkdf": "1.2.1", "@types/cookie": "0.6.0", "cookie": "0.7.1", "jose": "5.10.0", "oauth4webapi": "3.8.2", "preact": "10.11.3", "preact-render-to-string": "5.2.3" } }, "sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.18.20", "", { "os": "android", "cpu": "x64" }, "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.18.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.18.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.18.20", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.18.20", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.18.20", "", { "os": "linux", "cpu": "arm" }, "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.18.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.18.20", "", { "os": "linux", "cpu": "ia32" }, "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.18.20", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.18.20", "", { "os": "linux", "cpu": "s390x" }, "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.18.20", "", { "os": "linux", "cpu": "x64" }, "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.18.20", "", { "os": "none", "cpu": "x64" }, "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.18.20", "", { "os": "openbsd", "cpu": "x64" }, "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.18.20", "", { "os": "sunos", "cpu": "x64" }, "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.18.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.18.20", "", { "os": "win32", "cpu": "ia32" }, "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g=="],
|
||||
|
||||
"@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="],
|
||||
|
||||
"drizzle-kit/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="],
|
||||
|
||||
"next-auth/@auth/core/jose": ["jose@5.10.0", "", {}, "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg=="],
|
||||
|
||||
"next-auth/@auth/core/preact": ["preact@10.11.3", "", {}, "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg=="],
|
||||
|
||||
"next-auth/@auth/core/preact-render-to-string": ["preact-render-to-string@5.2.3", "", { "dependencies": { "pretty-format": "3.8.0" }, "peerDependencies": { "preact": "10.11.3" } }, "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA=="],
|
||||
}
|
||||
}
|
||||
5
bench/install/next-env.d.ts
vendored
Normal file
5
bench/install/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
10
bench/install/next.config.js
Normal file
10
bench/install/next.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
|
||||
* for Docker builds.
|
||||
*/
|
||||
import "./src/env.js";
|
||||
|
||||
/** @type {import("next").NextConfig} */
|
||||
const config = {};
|
||||
|
||||
export default config;
|
||||
@@ -1,31 +1,52 @@
|
||||
{
|
||||
"name": "installbench",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "remix build",
|
||||
"dev": "remix dev",
|
||||
"start": "remix-serve build",
|
||||
"typecheck": "tsc",
|
||||
"clean": "rm -rf node_modules",
|
||||
"bench": "hyperfine --prepare 'rm -rf node_modules' --warmup 1 --runs 3 'bun install' 'pnpm install' 'yarn' 'npm install'"
|
||||
"build": "next build",
|
||||
"check": "biome check .",
|
||||
"check:unsafe": "biome check --write --unsafe .",
|
||||
"check:write": "biome check --write .",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:studio": "drizzle-kit studio",
|
||||
"dev": "next dev --turbo",
|
||||
"preview": "next build && next start",
|
||||
"start": "next start",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@remix-run/node": "^1.15.0",
|
||||
"@remix-run/react": "^1.15.0",
|
||||
"@remix-run/serve": "^1.15.0",
|
||||
"isbot": "^3.6.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"@auth/drizzle-adapter": "^1.7.2",
|
||||
"@t3-oss/env-nextjs": "^0.12.0",
|
||||
"@tanstack/react-query": "^5.69.0",
|
||||
"@trpc/client": "^11.0.0",
|
||||
"@trpc/react-query": "^11.0.0",
|
||||
"@trpc/server": "^11.0.0",
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"esbuild": "^0.25.11",
|
||||
"next": "^15.2.3",
|
||||
"next-auth": "5.0.0-beta.25",
|
||||
"postgres": "^3.4.4",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"server-only": "^0.0.1",
|
||||
"superjson": "^2.2.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@remix-run/dev": "^1.15.0",
|
||||
"@remix-run/eslint-config": "^1.15.0",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.8",
|
||||
"eslint": "^8.27.0",
|
||||
"typescript": "^4.8.4"
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@tailwindcss/postcss": "^4.0.15",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^4.0.15",
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "7.39.3"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
@@ -1,14 +0,0 @@
|
||||
/** @type {import('@remix-run/dev').AppConfig} */
|
||||
module.exports = {
|
||||
ignoredRouteFiles: ["**/.*"],
|
||||
// appDirectory: "app",
|
||||
// assetsBuildDirectory: "public/build",
|
||||
// serverBuildPath: "build/index.js",
|
||||
// publicPath: "/build/",
|
||||
future: {
|
||||
v2_errorBoundary: true,
|
||||
v2_meta: true,
|
||||
v2_normalizeFormMethod: true,
|
||||
v2_routeConvention: true,
|
||||
},
|
||||
};
|
||||
2
bench/install/remix.env.d.ts
vendored
2
bench/install/remix.env.d.ts
vendored
@@ -1,2 +0,0 @@
|
||||
/// <reference types="@remix-run/dev" />
|
||||
/// <reference types="@remix-run/node" />
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"compilerOptions": {
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2019"],
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"target": "ES2019",
|
||||
"strict": true,
|
||||
"allowJs": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./app/*"]
|
||||
},
|
||||
|
||||
// Remix takes care of building everything in `remix build`.
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,16 @@
|
||||
"": {
|
||||
"name": "react-hello-world",
|
||||
"dependencies": {
|
||||
"react": "next",
|
||||
"react-dom": "next",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
||||
|
||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
||||
|
||||
"react": ["react@18.3.0-next-b72ed698f-20230303", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-l6RbwXa9Peerh9pQEq62DDypxSQfavbybY0wV1vwZ63X0P5VaaEesZAz1KPpnVvXjTtQaOMQsIPvnQwmaVqzTQ=="],
|
||||
|
||||
"react-dom": ["react-dom@18.3.0-next-b72ed698f-20230303", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "0.24.0-next-b72ed698f-20230303" }, "peerDependencies": { "react": "18.3.0-next-b72ed698f-20230303" } }, "sha512-0Gh/gmTT6H8KxswIQB/8shdTTfs6QIu86nNqZf3Y0RBqIwgTVxRaQVz14/Fw4/Nt81nK/Jt6KT4bx3yvOxZDGQ=="],
|
||||
|
||||
"scheduler": ["scheduler@0.24.0-next-b72ed698f-20230303", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-ct4DMMFbc2kFxCdvbG+i/Jn1S1oqrIFSn2VX/mam+Ya0iuNy+lb8rgT7A+YBUqrQNDaNEqABYI2sOQgqoRxp7w=="],
|
||||
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
"description": "",
|
||||
"main": "react-hello-world.node.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build:workerd": "bun build react-hello-world.workerd.jsx --outfile=react-hello-world.workerd.js --format=esm --production && (echo '// MessageChannel polyfill for workerd'; echo 'if (typeof MessageChannel === \"undefined\") {'; echo ' globalThis.MessageChannel = class MessageChannel {'; echo ' constructor() {'; echo ' this.port1 = { onmessage: null, postMessage: () => {} };'; echo ' this.port2 = {'; echo ' postMessage: (msg) => {'; echo ' if (this.port1.onmessage) {'; echo ' queueMicrotask(() => this.port1.onmessage({ data: msg }));'; echo ' }'; echo ' }'; echo ' };'; echo ' }'; echo ' };'; echo '}'; cat react-hello-world.workerd.js) > temp.js && mv temp.js react-hello-world.workerd.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Colin McDonnell",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"react": "next",
|
||||
"react-dom": "next"
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Workerd = import "/workerd/workerd.capnp";
|
||||
|
||||
const config :Workerd.Config = (
|
||||
services = [
|
||||
(name = "main", worker = .mainWorker),
|
||||
],
|
||||
|
||||
sockets = [
|
||||
( name = "http",
|
||||
address = "*:3001",
|
||||
http = (),
|
||||
service = "main"
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
const mainWorker :Workerd.Worker = (
|
||||
modules = [
|
||||
(name = "worker", esModule = embed "react-hello-world.workerd.js"),
|
||||
],
|
||||
compatibilityDate = "2025-01-01",
|
||||
compatibilityFlags = ["nodejs_compat_v2"],
|
||||
);
|
||||
68
bench/react-hello-world/react-hello-world.workerd.js
Normal file
68
bench/react-hello-world/react-hello-world.workerd.js
Normal file
File diff suppressed because one or more lines are too long
40
bench/react-hello-world/react-hello-world.workerd.jsx
Normal file
40
bench/react-hello-world/react-hello-world.workerd.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// Cloudflare Workers version with export default fetch
|
||||
// Run with: workerd serve react-hello-world.workerd.config.capnp
|
||||
|
||||
// Polyfill MessageChannel for workerd
|
||||
if (typeof MessageChannel === 'undefined') {
|
||||
globalThis.MessageChannel = class MessageChannel {
|
||||
constructor() {
|
||||
this.port1 = { onmessage: null, postMessage: () => {} };
|
||||
this.port2 = {
|
||||
postMessage: (msg) => {
|
||||
if (this.port1.onmessage) {
|
||||
queueMicrotask(() => this.port1.onmessage({ data: msg }));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
import React from "react";
|
||||
import { renderToReadableStream } from "react-dom/server";
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "text/html",
|
||||
};
|
||||
|
||||
const App = () => (
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
<p>This is an example.</p>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
export default {
|
||||
async fetch(request) {
|
||||
return new Response(await renderToReadableStream(<App />), { headers });
|
||||
},
|
||||
};
|
||||
3
bun.lock
3
bun.lock
@@ -41,6 +41,7 @@
|
||||
},
|
||||
"overrides": {
|
||||
"@types/bun": "workspace:packages/@types/bun",
|
||||
"@types/node": "24.3.1",
|
||||
"bun-types": "workspace:packages/bun-types",
|
||||
},
|
||||
"packages": {
|
||||
@@ -160,7 +161,7 @@
|
||||
|
||||
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||
|
||||
"@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
|
||||
"@types/node": ["@types/node@24.3.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g=="],
|
||||
|
||||
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
|
||||
|
||||
|
||||
@@ -215,46 +215,6 @@ if(ENABLE_ASSERTIONS)
|
||||
DESCRIPTION "Do not eliminate null-pointer checks"
|
||||
-fno-delete-null-pointer-checks
|
||||
)
|
||||
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Enable libc++ assertions"
|
||||
_LIBCPP_ENABLE_ASSERTIONS=1
|
||||
_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE ${RELEASE}
|
||||
_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG ${DEBUG}
|
||||
)
|
||||
|
||||
# Nix glibc already sets _FORTIFY_SOURCE, don't override it
|
||||
if(NOT DEFINED ENV{NIX_CC})
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Enable fortified sources (Release only)"
|
||||
_FORTIFY_SOURCE=3 ${RELEASE}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LINUX)
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Enable glibc++ assertions"
|
||||
_GLIBCXX_ASSERTIONS=1
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Disable debug assertions"
|
||||
NDEBUG=1
|
||||
)
|
||||
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Disable libc++ assertions"
|
||||
_LIBCPP_ENABLE_ASSERTIONS=0
|
||||
_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE
|
||||
)
|
||||
|
||||
if(LINUX)
|
||||
register_compiler_definitions(
|
||||
DESCRIPTION "Disable glibc++ assertions"
|
||||
_GLIBCXX_ASSERTIONS=0
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- Diagnostics ---
|
||||
@@ -305,14 +265,6 @@ if(UNIX AND CI)
|
||||
)
|
||||
endif()
|
||||
|
||||
# --- Features ---
|
||||
|
||||
# Valgrind cannot handle SSE4.2 instructions
|
||||
# This is needed for picohttpparser
|
||||
if(ENABLE_VALGRIND AND ARCH STREQUAL "x64")
|
||||
register_compiler_definitions(__SSE4_2__=0)
|
||||
endif()
|
||||
|
||||
# --- Other ---
|
||||
|
||||
# Workaround for CMake and clang-cl bug.
|
||||
|
||||
@@ -136,13 +136,6 @@ else()
|
||||
set(WARNING WARNING)
|
||||
endif()
|
||||
|
||||
# TODO: This causes flaky zig builds in CI, so temporarily disable it.
|
||||
# if(CI)
|
||||
# set(DEFAULT_VENDOR_PATH ${CACHE_PATH}/vendor)
|
||||
# else()
|
||||
# set(DEFAULT_VENDOR_PATH ${CWD}/vendor)
|
||||
# endif()
|
||||
|
||||
optionx(VENDOR_PATH FILEPATH "The path to the vendor directory" DEFAULT ${CWD}/vendor)
|
||||
optionx(TMP_PATH FILEPATH "The path to the temporary directory" DEFAULT ${BUILD_PATH}/tmp)
|
||||
|
||||
@@ -917,10 +910,6 @@ function(register_compiler_flags)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(register_compiler_definitions)
|
||||
|
||||
endfunction()
|
||||
|
||||
# register_linker_flags()
|
||||
# Description:
|
||||
# Registers a linker flag, similar to `add_link_options()`.
|
||||
|
||||
@@ -140,11 +140,6 @@ if(ENABLE_ASAN AND ENABLE_LTO)
|
||||
setx(ENABLE_LTO OFF)
|
||||
endif()
|
||||
|
||||
if(USE_VALGRIND AND NOT USE_BASELINE)
|
||||
message(WARNING "If valgrind is enabled, baseline must also be enabled")
|
||||
setx(USE_BASELINE ON)
|
||||
endif()
|
||||
|
||||
if(BUILDKITE_COMMIT)
|
||||
set(DEFAULT_REVISION ${BUILDKITE_COMMIT})
|
||||
else()
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
"paths": ["src/bake/*.ts", "src/bake/*/*.{ts,css}"],
|
||||
"exclude": ["src/bake/generated.ts"]
|
||||
},
|
||||
{
|
||||
"output": "BunFrameworkReactSources.txt",
|
||||
"paths": ["packages/bun-framework-react/*.{ts,tsx,js,jsx}", "packages/bun-framework-react/src/**/*.{ts,tsx,js,jsx}"]
|
||||
},
|
||||
{
|
||||
"output": "BindgenSources.txt",
|
||||
"paths": ["src/**/*.bind.ts"]
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# https://cppcheck.sourceforge.io/
|
||||
|
||||
find_command(
|
||||
VARIABLE
|
||||
CPPCHECK_EXECUTABLE
|
||||
COMMAND
|
||||
cppcheck
|
||||
REQUIRED
|
||||
OFF
|
||||
)
|
||||
|
||||
set(CPPCHECK_COMMAND ${CPPCHECK_EXECUTABLE}
|
||||
--cppcheck-build-dir=${BUILD_PATH}/cppcheck
|
||||
--project=${BUILD_PATH}/compile_commands.json
|
||||
--clang=${CMAKE_CXX_COMPILER}
|
||||
--std=c++${CMAKE_CXX_STANDARD}
|
||||
--report-progress
|
||||
--showtime=summary
|
||||
)
|
||||
|
||||
register_command(
|
||||
TARGET
|
||||
cppcheck
|
||||
COMMENT
|
||||
"Running cppcheck"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory cppcheck
|
||||
&& ${CPPCHECK_COMMAND}
|
||||
CWD
|
||||
${BUILD_PATH}
|
||||
TARGETS
|
||||
${bun}
|
||||
)
|
||||
@@ -1,22 +0,0 @@
|
||||
find_command(
|
||||
VARIABLE
|
||||
CPPLINT_PROGRAM
|
||||
COMMAND
|
||||
cpplint
|
||||
REQUIRED
|
||||
OFF
|
||||
)
|
||||
|
||||
register_command(
|
||||
TARGET
|
||||
cpplint
|
||||
COMMENT
|
||||
"Running cpplint"
|
||||
COMMAND
|
||||
${CPPLINT_PROGRAM}
|
||||
${BUN_CPP_SOURCES}
|
||||
CWD
|
||||
${BUILD_PATH}
|
||||
TARGETS
|
||||
${bun}
|
||||
)
|
||||
@@ -1,67 +0,0 @@
|
||||
# IWYU = "Include What You Use"
|
||||
# https://include-what-you-use.org/
|
||||
|
||||
setx(IWYU_SOURCE_PATH ${CACHE_PATH}/iwyu-${LLVM_VERSION})
|
||||
setx(IWYU_BUILD_PATH ${IWYU_SOURCE_PATH}/build)
|
||||
setx(IWYU_PROGRAM ${IWYU_BUILD_PATH}/bin/include-what-you-use)
|
||||
|
||||
register_repository(
|
||||
NAME
|
||||
iwyu
|
||||
REPOSITORY
|
||||
include-what-you-use/include-what-you-use
|
||||
BRANCH
|
||||
clang_${LLVM_VERSION}
|
||||
PATH
|
||||
${IWYU_SOURCE_PATH}
|
||||
)
|
||||
|
||||
register_command(
|
||||
TARGET
|
||||
build-iwyu
|
||||
COMMENT
|
||||
"Building iwyu"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-B${IWYU_BUILD_PATH}
|
||||
-G${CMAKE_GENERATOR}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
|
||||
-DIWYU_LLVM_ROOT_PATH=${LLVM_PREFIX}
|
||||
&& ${CMAKE_COMMAND}
|
||||
--build ${IWYU_BUILD_PATH}
|
||||
CWD
|
||||
${IWYU_SOURCE_PATH}
|
||||
TARGETS
|
||||
clone-iwyu
|
||||
)
|
||||
|
||||
find_command(
|
||||
VARIABLE
|
||||
PYTHON_EXECUTABLE
|
||||
COMMAND
|
||||
python3
|
||||
python
|
||||
VERSION
|
||||
>=3.0.0
|
||||
REQUIRED
|
||||
OFF
|
||||
)
|
||||
|
||||
register_command(
|
||||
TARGET
|
||||
iwyu
|
||||
COMMENT
|
||||
"Running iwyu"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-E env IWYU_BINARY=${IWYU_PROGRAM}
|
||||
${PYTHON_EXECUTABLE}
|
||||
${IWYU_SOURCE_PATH}/iwyu_tool.py
|
||||
-p ${BUILD_PATH}
|
||||
CWD
|
||||
${BUILD_PATH}
|
||||
TARGETS
|
||||
build-iwyu
|
||||
${bun}
|
||||
)
|
||||
@@ -45,12 +45,6 @@ else()
|
||||
endif()
|
||||
|
||||
set(LLVM_ZIG_CODEGEN_THREADS 0)
|
||||
# This makes the build slower, so we turn it off for now.
|
||||
# if (DEBUG)
|
||||
# include(ProcessorCount)
|
||||
# ProcessorCount(CPU_COUNT)
|
||||
# set(LLVM_ZIG_CODEGEN_THREADS ${CPU_COUNT})
|
||||
# endif()
|
||||
|
||||
# --- Dependencies ---
|
||||
|
||||
@@ -71,9 +65,6 @@ set(BUN_DEPENDENCIES
|
||||
)
|
||||
|
||||
include(CloneZstd)
|
||||
# foreach(dependency ${BUN_DEPENDENCIES})
|
||||
# include(Clone${dependency})
|
||||
# endforeach()
|
||||
|
||||
# --- Codegen ---
|
||||
|
||||
@@ -819,7 +810,7 @@ set_target_properties(${bun} PROPERTIES
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
CXX_EXTENSIONS YES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
C_STANDARD 23
|
||||
C_STANDARD 17 # Cannot uprev to C23 because MSVC doesn't have support.
|
||||
C_STANDARD_REQUIRED YES
|
||||
VISIBILITY_INLINES_HIDDEN YES
|
||||
)
|
||||
@@ -944,7 +935,7 @@ if(NOT WIN32)
|
||||
if (NOT ABI STREQUAL "musl")
|
||||
target_compile_options(${bun} PUBLIC
|
||||
-fsanitize=null
|
||||
-fsanitize-recover=all
|
||||
-fno-sanitize-recover=all
|
||||
-fsanitize=bounds
|
||||
-fsanitize=return
|
||||
-fsanitize=nullability-arg
|
||||
@@ -999,6 +990,20 @@ if(NOT WIN32)
|
||||
)
|
||||
|
||||
if(ENABLE_ASAN)
|
||||
target_compile_options(${bun} PUBLIC
|
||||
-fsanitize=null
|
||||
-fno-sanitize-recover=all
|
||||
-fsanitize=bounds
|
||||
-fsanitize=return
|
||||
-fsanitize=nullability-arg
|
||||
-fsanitize=nullability-assign
|
||||
-fsanitize=nullability-return
|
||||
-fsanitize=returns-nonnull-attribute
|
||||
-fsanitize=unreachable
|
||||
)
|
||||
target_link_libraries(${bun} PRIVATE
|
||||
-fsanitize=null
|
||||
)
|
||||
target_compile_options(${bun} PUBLIC -fsanitize=address)
|
||||
target_link_libraries(${bun} PUBLIC -fsanitize=address)
|
||||
endif()
|
||||
@@ -1247,15 +1252,9 @@ if(LINUX)
|
||||
target_link_libraries(${bun} PUBLIC libatomic.so)
|
||||
endif()
|
||||
|
||||
if(USE_SYSTEM_ICU)
|
||||
target_link_libraries(${bun} PRIVATE libicudata.a)
|
||||
target_link_libraries(${bun} PRIVATE libicui18n.a)
|
||||
target_link_libraries(${bun} PRIVATE libicuuc.a)
|
||||
else()
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicudata.a)
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicui18n.a)
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicuuc.a)
|
||||
endif()
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicudata.a)
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicui18n.a)
|
||||
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libicuuc.a)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@@ -1308,32 +1307,32 @@ if(NOT BUN_CPP_ONLY)
|
||||
OUTPUTS
|
||||
${BUILD_PATH}/${bunStripExe}
|
||||
)
|
||||
|
||||
|
||||
# Then sign both executables on Windows
|
||||
if(WIN32 AND ENABLE_WINDOWS_CODESIGNING)
|
||||
set(SIGN_SCRIPT "${CMAKE_SOURCE_DIR}/.buildkite/scripts/sign-windows.ps1")
|
||||
|
||||
|
||||
# Verify signing script exists
|
||||
if(NOT EXISTS "${SIGN_SCRIPT}")
|
||||
message(FATAL_ERROR "Windows signing script not found: ${SIGN_SCRIPT}")
|
||||
endif()
|
||||
|
||||
|
||||
# Use PowerShell for Windows code signing (native Windows, no path issues)
|
||||
find_program(POWERSHELL_EXECUTABLE
|
||||
find_program(POWERSHELL_EXECUTABLE
|
||||
NAMES pwsh.exe powershell.exe
|
||||
PATHS
|
||||
PATHS
|
||||
"C:/Program Files/PowerShell/7"
|
||||
"C:/Program Files (x86)/PowerShell/7"
|
||||
"C:/Windows/System32/WindowsPowerShell/v1.0"
|
||||
DOC "Path to PowerShell executable"
|
||||
)
|
||||
|
||||
|
||||
if(NOT POWERSHELL_EXECUTABLE)
|
||||
set(POWERSHELL_EXECUTABLE "powershell.exe")
|
||||
endif()
|
||||
|
||||
|
||||
message(STATUS "Using PowerShell executable: ${POWERSHELL_EXECUTABLE}")
|
||||
|
||||
|
||||
# Sign both bun-profile.exe and bun.exe after stripping
|
||||
register_command(
|
||||
TARGET
|
||||
|
||||
@@ -4,7 +4,7 @@ register_repository(
|
||||
REPOSITORY
|
||||
ebiggers/libdeflate
|
||||
COMMIT
|
||||
96836d7d9d10e3e0d53e6edb54eb908514e336c4
|
||||
c8c56a20f8f621e6a966b716b31f1dedab6a41e3
|
||||
)
|
||||
|
||||
register_cmake_command(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.20 AS build
|
||||
FROM alpine:3.22 AS build
|
||||
|
||||
# https://github.com/oven-sh/bun/releases
|
||||
ARG BUN_VERSION=latest
|
||||
@@ -44,7 +44,7 @@ RUN apk --no-cache add ca-certificates curl dirmngr gpg gpg-agent unzip \
|
||||
&& rm -f "bun-linux-$build.zip" SHASUMS256.txt.asc SHASUMS256.txt \
|
||||
&& chmod +x /usr/local/bin/bun
|
||||
|
||||
FROM alpine:3.20
|
||||
FROM alpine:3.22
|
||||
|
||||
# Disable the runtime transpiler cache by default inside Docker containers.
|
||||
# On ephemeral containers, the cache is not useful
|
||||
|
||||
@@ -257,12 +257,13 @@ $ bun test --watch
|
||||
|
||||
Bun supports the following lifecycle hooks:
|
||||
|
||||
| Hook | Description |
|
||||
| ------------ | --------------------------- |
|
||||
| `beforeAll` | Runs once before all tests. |
|
||||
| `beforeEach` | Runs before each test. |
|
||||
| `afterEach` | Runs after each test. |
|
||||
| `afterAll` | Runs once after all tests. |
|
||||
| Hook | Description |
|
||||
| ---------------- | -------------------------------------------------------- |
|
||||
| `beforeAll` | Runs once before all tests. |
|
||||
| `beforeEach` | Runs before each test. |
|
||||
| `afterEach` | Runs after each test. |
|
||||
| `afterAll` | Runs once after all tests. |
|
||||
| `onTestFinished` | Runs after a test finishes, including after `afterEach`. |
|
||||
|
||||
These hooks can be defined inside test files, or in a separate file that is preloaded with the `--preload` flag.
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import { watch } from "fs";
|
||||
const watcher = watch(
|
||||
import.meta.dir,
|
||||
{ recursive: true },
|
||||
(event, filename) => {
|
||||
console.log(`Detected ${event} in ${filename}`);
|
||||
(event, relativePath) => {
|
||||
console.log(`Detected ${event} in ${relativePath}`);
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
@@ -249,6 +249,41 @@ This is useful for:
|
||||
|
||||
The `--concurrent` CLI flag will override this setting when specified.
|
||||
|
||||
### `test.onlyFailures`
|
||||
|
||||
When enabled, only failed tests are displayed in the output. This helps reduce noise in large test suites by hiding passing tests. Default `false`.
|
||||
|
||||
```toml
|
||||
[test]
|
||||
onlyFailures = true
|
||||
```
|
||||
|
||||
This is equivalent to using the `--only-failures` flag when running `bun test`.
|
||||
|
||||
### `test.reporter`
|
||||
|
||||
Configure the test reporter settings.
|
||||
|
||||
#### `test.reporter.dots`
|
||||
|
||||
Enable the dots reporter, which displays a compact output showing a dot for each test. Default `false`.
|
||||
|
||||
```toml
|
||||
[test.reporter]
|
||||
dots = true
|
||||
```
|
||||
|
||||
#### `test.reporter.junit`
|
||||
|
||||
Enable JUnit XML reporting and specify the output file path.
|
||||
|
||||
```toml
|
||||
[test.reporter]
|
||||
junit = "test-results.xml"
|
||||
```
|
||||
|
||||
This generates a JUnit XML report that can be consumed by CI systems and other tools.
|
||||
|
||||
### `test.randomize`
|
||||
|
||||
Run tests in random order. Default `false`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "bun",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.2",
|
||||
"workspaces": [
|
||||
"./packages/bun-types",
|
||||
"./packages/@types/bun"
|
||||
@@ -23,7 +23,8 @@
|
||||
},
|
||||
"resolutions": {
|
||||
"bun-types": "workspace:packages/bun-types",
|
||||
"@types/bun": "workspace:packages/@types/bun"
|
||||
"@types/bun": "workspace:packages/@types/bun",
|
||||
"@types/node": "24.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "bun --silent run build:debug",
|
||||
@@ -86,9 +87,10 @@
|
||||
"clean:zig": "rm -rf build/debug/cache/zig build/debug/CMakeCache.txt 'build/debug/*.o' .zig-cache zig-out || true",
|
||||
"machine:linux:ubuntu": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=ubuntu --release=25.04",
|
||||
"machine:linux:debian": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=debian --release=12",
|
||||
"machine:linux:alpine": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=alpine --release=3.21",
|
||||
"machine:linux:alpine": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=alpine --release=3.22",
|
||||
"machine:linux:amazonlinux": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=amazonlinux --release=2023",
|
||||
"machine:windows:2019": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=windows --release=2019",
|
||||
"machine:freebsd": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.large --os=freebsd --release=14.3",
|
||||
"sync-webkit-source": "bun ./scripts/sync-webkit-source.ts"
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/bun-framework-react/.gitignore
vendored
Normal file
1
packages/bun-framework-react/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
bun-framework-react*.tgz
|
||||
10
packages/bun-framework-react/README.md
Normal file
10
packages/bun-framework-react/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
<img src="https://bun.com/logo.png" height="36" />
|
||||
|
||||
# `bun-framework-react`
|
||||
|
||||
An implementation of the Bun Rendering API for React, with RSC (React Server Components)
|
||||
|
||||
1. `bun add bun-framework-react --dev`
|
||||
2. Make a `pages/index.tsx` file, with a page component defualt export
|
||||
3. Run `bun --app`
|
||||
4. Open [localhost:3000](https://localhost:3000) 🎉
|
||||
32
packages/bun-framework-react/bun.lock
Normal file
32
packages/bun-framework-react/bun.lock
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "bun-framework-react",
|
||||
"dependencies": {
|
||||
"react": "0.0.0-experimental-a757cb76-20251002",
|
||||
"react-dom": "0.0.0-experimental-a757cb76-20251002",
|
||||
"react-refresh": "0.0.0-experimental-a757cb76-20251002",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.13",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.1.9", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"react": ["react@0.0.0-experimental-a757cb76-20251002", "", {}, "sha512-7ZcE4sSUGgrXgUWa84iwC9DqwDFbQBgffFmu2DoNqFseruA/JjxQDXKwpV5acdxOM/0uzfSGrapHU3C3ZLiU2g=="],
|
||||
|
||||
"react-dom": ["react-dom@0.0.0-experimental-a757cb76-20251002", "", { "dependencies": { "scheduler": "0.0.0-experimental-a757cb76-20251002" }, "peerDependencies": { "react": "0.0.0-experimental-a757cb76-20251002" } }, "sha512-XjIkmW8mMx9kURHJUY+dhv1Ugan3RmEJIwrZEbAFcJA4S8RXL1wl+xsQJpDCh8kmeX/n25VAmFY8/j1MzqUHfA=="],
|
||||
|
||||
"react-refresh": ["react-refresh@0.0.0-experimental-a757cb76-20251002", "", {}, "sha512-uYd+N2W8/LymZQyY5u1BMWVvLlBV+5SxztBsFjOGuitE4x7sSCj8TwgS+8bxIEBucEVJglfOhDPCPohL/uEQdg=="],
|
||||
|
||||
"scheduler": ["scheduler@0.0.0-experimental-a757cb76-20251002", "", {}, "sha512-YCVGuzmF7u5HIpOdPFD4tZTPzQlOrtViag7uaWjJXfFx37C8sypfNeSXNXoYJeT/ICybxP1EsbHh2oByQHC2Cg=="],
|
||||
}
|
||||
}
|
||||
64
packages/bun-framework-react/client.tsx
Normal file
64
packages/bun-framework-react/client.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { onServerSideReload } from "bun:app/client";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
import { initialRscPayloadThen } from "./src/client/app.ts";
|
||||
import { router } from "./src/client/constants.ts";
|
||||
import { Root } from "./src/client/root.tsx";
|
||||
|
||||
hydrateRoot(document, <Root />, {
|
||||
onUncaughtError(e) {
|
||||
console.error(e);
|
||||
},
|
||||
});
|
||||
|
||||
const firstPageId = Date.now();
|
||||
{
|
||||
history.replaceState(firstPageId, "", location.href);
|
||||
initialRscPayloadThen(result => {
|
||||
if (router.hasNavigatedSinceDOMContentLoaded()) return;
|
||||
|
||||
// Collect the list of CSS files that were added from SSR
|
||||
const links = document.querySelectorAll<HTMLLinkElement>("link[data-bake-ssr]");
|
||||
router.css.clear();
|
||||
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
const link = links[i];
|
||||
if (!link) continue;
|
||||
const href = new URL(link.href).pathname;
|
||||
router.css.push(href);
|
||||
|
||||
// Hack: cannot add this to `cssFiles` because React owns the element, and
|
||||
// it will be removed when any navigation is performed.
|
||||
}
|
||||
|
||||
router.setCachedPage(firstPageId, {
|
||||
css: [...router.css.getList()],
|
||||
element: result,
|
||||
});
|
||||
});
|
||||
|
||||
if (document.startViewTransition !== undefined) {
|
||||
// View transitions are used by navigations to ensure that the page rerender
|
||||
// all happens in one operation. Additionally, developers may animate
|
||||
// different elements. The default fade animation is disabled so that the
|
||||
// out-of-the-box experience feels like there are no view transitions.
|
||||
// This is done client-side because a React error will unmount all elements.
|
||||
const sheet = new CSSStyleSheet();
|
||||
document.adoptedStyleSheets.push(sheet);
|
||||
sheet.replaceSync(":where(*)::view-transition-group(root){animation:none}");
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("popstate", async event => {
|
||||
const state = typeof event.state === "number" ? event.state : undefined;
|
||||
await router.navigate(location.href, state);
|
||||
});
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
// Frameworks can call `onServerSideReload` to hook into server-side hot
|
||||
// module reloading.
|
||||
onServerSideReload(async () => {
|
||||
const newId = Date.now();
|
||||
history.replaceState(newId, "", location.href);
|
||||
await router.navigate(location.href, newId);
|
||||
});
|
||||
}
|
||||
35
packages/bun-framework-react/index.ts
Normal file
35
packages/bun-framework-react/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { Framework } from "bun:app";
|
||||
|
||||
function resolve(specifier: string) {
|
||||
return Bun.fileURLToPath(import.meta.resolve(specifier));
|
||||
}
|
||||
|
||||
const framework: Framework = {
|
||||
serverComponents: {
|
||||
separateSSRGraph: true,
|
||||
serverRuntimeImportSource: resolve("./vendor/react-server-dom-bun/server.node.js"),
|
||||
},
|
||||
reactFastRefresh: {
|
||||
importSource: resolve("react-refresh/runtime"),
|
||||
},
|
||||
fileSystemRouterTypes: [
|
||||
{
|
||||
root: "pages",
|
||||
clientEntryPoint: resolve("./client.tsx"),
|
||||
serverEntryPoint: resolve("./server.tsx"),
|
||||
extensions: [".tsx", ".jsx"],
|
||||
style: "nextjs-pages",
|
||||
layouts: true,
|
||||
ignoreUnderscores: true,
|
||||
prefix: "/",
|
||||
ignoreDirs: ["node_modules", ".git"],
|
||||
},
|
||||
],
|
||||
// bundlerOptions: {
|
||||
// ssr: {
|
||||
// conditions: ["react-server"],
|
||||
// },
|
||||
// },
|
||||
};
|
||||
|
||||
export default framework;
|
||||
36
packages/bun-framework-react/package.json
Normal file
36
packages/bun-framework-react/package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "bun-framework-react",
|
||||
"version": "0.0.0-canary.10",
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.13",
|
||||
"@types/react-dom": "^19.1.9"
|
||||
},
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./package.json": "./package.json",
|
||||
"./ssr.tsx": "./ssr.tsx",
|
||||
"./server.tsx": "./server.tsx",
|
||||
"./client.tsx": "./client.tsx",
|
||||
"./*": "./src/components/*.tsx"
|
||||
},
|
||||
"description": "React framework integration with RSC, for the Bun Rendering API",
|
||||
"files": [
|
||||
"./vendor",
|
||||
"./src",
|
||||
"./*.ts",
|
||||
"./*.tsx",
|
||||
"./README.md"
|
||||
],
|
||||
"keywords": [
|
||||
"bun",
|
||||
"react",
|
||||
"framework",
|
||||
"bake"
|
||||
],
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"react": "0.0.0-experimental-a757cb76-20251002",
|
||||
"react-dom": "0.0.0-experimental-a757cb76-20251002",
|
||||
"react-refresh": "0.0.0-experimental-a757cb76-20251002"
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,24 @@
|
||||
import type { Bake } from "bun";
|
||||
import { renderToHtml, renderToStaticHtml } from "bun-framework-react/ssr.tsx" with { bunBakeGraph: "ssr" };
|
||||
import { serverManifest } from "bun:bake/server";
|
||||
import * as Bake from "bun:app";
|
||||
import { serverManifest } from "bun:app/server";
|
||||
import type { AsyncLocalStorage } from "node:async_hooks";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { renderToPipeableStream } from "react-server-dom-bun/server.node.unbundled.js";
|
||||
import type { RequestContext } from "../hmr-runtime-server";
|
||||
import type { RequestContext } from "../../src/bake/hmr-runtime-server.ts";
|
||||
import { renderToPipeableStream } from "./vendor/react-server-dom-bun/server.node.unbundled.js";
|
||||
|
||||
function assertReactComponent(Component: any) {
|
||||
function assertReactComponent(Component: unknown): asserts Component is React.JSXElementConstructor<unknown> {
|
||||
if (typeof Component !== "function") {
|
||||
console.log("Expected a React component", Component, typeof Component);
|
||||
throw new Error("Expected a React component");
|
||||
}
|
||||
}
|
||||
|
||||
// This function converts the route information into a React component tree.
|
||||
function getPage(meta: Bake.RouteMetadata & { request?: Request }, styles: readonly string[]) {
|
||||
function getPage(meta: Bake.RouteMetadata & { request?: Request | undefined }, styles: readonly string[]) {
|
||||
let route = component(meta.pageModule, meta.params, meta.request);
|
||||
|
||||
for (const layout of meta.layouts) {
|
||||
const Layout = layout.default;
|
||||
const Layout = layout.default as typeof layout.default & { displayName?: string };
|
||||
Layout.displayName ??= "Layout";
|
||||
if (import.meta.env.DEV) assertReactComponent(Layout);
|
||||
route = <Layout params={meta.params}>{route}</Layout>;
|
||||
}
|
||||
@@ -26,7 +27,6 @@ function getPage(meta: Bake.RouteMetadata & { request?: Request }, styles: reado
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Bun + React Server Components</title>
|
||||
{styles.map(url => (
|
||||
// `data-bake-ssr` is used on the client-side to construct the styles array.
|
||||
<link key={url} rel="stylesheet" href={url} data-bake-ssr />
|
||||
@@ -37,8 +37,12 @@ function getPage(meta: Bake.RouteMetadata & { request?: Request }, styles: reado
|
||||
);
|
||||
}
|
||||
|
||||
function component(mod: any, params: Record<string, string> | null, request?: Request) {
|
||||
function component(mod: any, params: Record<string, string | string[]> | null, request?: Request) {
|
||||
if (!mod || !mod.default) {
|
||||
throw new Error("Pages must have a default export that is a React component");
|
||||
}
|
||||
const Page = mod.default;
|
||||
|
||||
let props = {};
|
||||
if (import.meta.env.DEV) assertReactComponent(Page);
|
||||
|
||||
@@ -51,7 +55,6 @@ function component(mod: any, params: Record<string, string> | null, request?: Re
|
||||
props = method();
|
||||
}
|
||||
|
||||
// Pass request prop if mode is 'ssr'
|
||||
if (mod.mode === "ssr" && request) {
|
||||
props.request = request;
|
||||
}
|
||||
@@ -76,7 +79,7 @@ export async function render(
|
||||
const skipSSR = request.headers.get("Accept")?.includes("text/x-component");
|
||||
|
||||
// Check if the page module has a streaming export, default to false
|
||||
const streaming = meta.pageModule.streaming ?? false;
|
||||
const streaming = meta.pageModule?.streaming ?? false;
|
||||
|
||||
// Do not render <link> tags if the request is skipping SSR.
|
||||
const page = getPage(meta, skipSSR ? [] : meta.styles);
|
||||
@@ -104,7 +107,6 @@ export async function render(
|
||||
|
||||
// Mark as aborted and call the abort function
|
||||
signal.aborted = err;
|
||||
// @ts-expect-error
|
||||
signal.abort(err);
|
||||
rscPayload.destroy(err);
|
||||
},
|
||||
@@ -236,5 +238,5 @@ export const contentTypeToStaticFile = {
|
||||
export interface MiniAbortSignal {
|
||||
aborted: Error | undefined;
|
||||
/** Caller must set `aborted` to true before calling. */
|
||||
abort: () => void;
|
||||
abort: (reason?: any) => void;
|
||||
}
|
||||
96
packages/bun-framework-react/src/client/app.ts
Normal file
96
packages/bun-framework-react/src/client/app.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import type { ReactNode, SetStateAction } from "react";
|
||||
import { createFromReadableStream } from "../../vendor/react-server-dom-bun/client.browser.js";
|
||||
import { store, useStore, type Store } from "./store.ts";
|
||||
|
||||
export type NonNullishReactNode = Exclude<ReactNode, null | undefined>;
|
||||
export type RenderableRscPayload = Promise<NonNullishReactNode> | NonNullishReactNode;
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
function enqueueChunks(
|
||||
controller: ReadableStreamDefaultController<Uint8Array<ArrayBuffer>>,
|
||||
...chunks: (string | Uint8Array<ArrayBuffer>)[]
|
||||
) {
|
||||
for (let chunk of chunks) {
|
||||
if (typeof chunk === "string") {
|
||||
chunk = encoder.encode(chunk);
|
||||
}
|
||||
|
||||
controller.enqueue(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
export interface AppState {
|
||||
/**
|
||||
* The renderable RSC payload
|
||||
*/
|
||||
rsc: RenderableRscPayload;
|
||||
|
||||
/**
|
||||
* A controller that aborts on the first render
|
||||
*/
|
||||
abortOnRender?: AbortController | undefined;
|
||||
}
|
||||
|
||||
// The initial RSC payload is put into inline <script> tags that follow the pattern
|
||||
// `(self.__bun_f ??= []).push(chunk)`, which is converted into a ReadableStream
|
||||
// here for React hydration. Since inline scripts are executed immediately, and
|
||||
// this file is loaded asynchronously, the `__bun_f` becomes a clever way to
|
||||
// stream the arbitrary data while HTML is loading. In a static build, this is
|
||||
// setup as an array with one string.
|
||||
const initialRscPayload: Promise<NonNullishReactNode> =
|
||||
typeof document === "undefined"
|
||||
? Promise.resolve(false)
|
||||
: createFromReadableStream(
|
||||
new ReadableStream<NonNullishReactNode>({
|
||||
start(controller) {
|
||||
const bunF = (self.__bun_f ??= []);
|
||||
const originalPush = bunF.push;
|
||||
|
||||
bunF.push = function (this: typeof bunF, ...chunks: (string | Uint8Array<ArrayBuffer>)[]) {
|
||||
enqueueChunks(controller, ...chunks);
|
||||
return originalPush.apply(this, chunks);
|
||||
}.bind(bunF);
|
||||
|
||||
bunF.forEach(chunk => enqueueChunks(controller, chunk));
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
() => {
|
||||
controller.close();
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
} else {
|
||||
controller.close();
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__bun_f: Array<string | Uint8Array<ArrayBuffer>>;
|
||||
}
|
||||
}
|
||||
|
||||
const appStore: Store<AppState> = store<AppState>({
|
||||
rsc: initialRscPayload,
|
||||
});
|
||||
|
||||
export function setAppState(element: SetStateAction<AppState>): void {
|
||||
appStore.write(element);
|
||||
}
|
||||
|
||||
export function useAppState(): AppState {
|
||||
return useStore(appStore);
|
||||
}
|
||||
|
||||
export function getAppState(): AppState {
|
||||
return appStore.read();
|
||||
}
|
||||
|
||||
export function initialRscPayloadThen(then: (rsc: NonNullishReactNode) => void): void {
|
||||
void initialRscPayload.then(then);
|
||||
}
|
||||
3
packages/bun-framework-react/src/client/constants.ts
Normal file
3
packages/bun-framework-react/src/client/constants.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { Router } from "./router.ts";
|
||||
|
||||
export const router: Router = new Router();
|
||||
355
packages/bun-framework-react/src/client/css.ts
Normal file
355
packages/bun-framework-react/src/client/css.ts
Normal file
@@ -0,0 +1,355 @@
|
||||
export class BakeCSSManager {
|
||||
private readonly td = new TextDecoder();
|
||||
|
||||
// It is the framework's responsibility to ensure that client-side navigation
|
||||
// loads CSS files. The implementation here loads all CSS files as <link> tags,
|
||||
// and uses the ".disabled" property to enable/disable them.
|
||||
private readonly cssFiles = new Map<string, { promise: Promise<void> | null; link: HTMLLinkElement }>();
|
||||
private currentCssList: string[] | null = null;
|
||||
|
||||
public async set(list: string[]): Promise<void> {
|
||||
this.currentCssList = list;
|
||||
await this.ensureCssIsReady(this.currentCssList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual list instance. Mutating this list will update the current
|
||||
* CSS list (it is the actual array).
|
||||
*/
|
||||
public getList(): string[] {
|
||||
return (this.currentCssList ??= []);
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.currentCssList = [];
|
||||
}
|
||||
|
||||
public push(href: string): void {
|
||||
const arr = this.getList();
|
||||
arr.push(href);
|
||||
}
|
||||
|
||||
/** This function blocks until all CSS files are loaded. */
|
||||
ensureCssIsReady(cssList: string[] = this.currentCssList ?? []): Promise<void[]> | void {
|
||||
const wait: Promise<void>[] = [];
|
||||
|
||||
for (const href of cssList) {
|
||||
const existing = this.cssFiles.get(href);
|
||||
|
||||
if (existing) {
|
||||
const { promise, link } = existing;
|
||||
|
||||
if (promise) {
|
||||
wait.push(promise);
|
||||
}
|
||||
|
||||
link.disabled = false;
|
||||
} else {
|
||||
const link = document.createElement("link");
|
||||
let entry: { promise: Promise<void> | null; link: HTMLLinkElement };
|
||||
|
||||
const promise = new Promise<void>((resolve, reject) => {
|
||||
link.rel = "stylesheet";
|
||||
link.onload = resolve.bind(null, undefined);
|
||||
link.onerror = reject;
|
||||
link.href = href;
|
||||
document.head.appendChild(link);
|
||||
}).finally(() => {
|
||||
entry.promise = null;
|
||||
});
|
||||
|
||||
entry = { promise, link };
|
||||
this.cssFiles.set(href, entry);
|
||||
wait.push(promise);
|
||||
}
|
||||
}
|
||||
|
||||
if (wait.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Promise.all(wait);
|
||||
}
|
||||
|
||||
public disableUnusedCssFilesIfNeeded(): void {
|
||||
if (this.currentCssList) {
|
||||
this.disableUnusedCssFiles();
|
||||
}
|
||||
}
|
||||
|
||||
disableUnusedCssFiles(): void {
|
||||
// TODO: create a list of files that should be updated instead of a full loop
|
||||
for (const [href, { link }] of this.cssFiles) {
|
||||
if (!this.currentCssList!.includes(href)) {
|
||||
link.disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async readCssMetadata(
|
||||
stream: ReadableStream<Uint8Array<ArrayBuffer>>,
|
||||
): Promise<ReadableStream<Uint8Array<ArrayBuffer>>> {
|
||||
let reader: ReadableStreamBYOBReader;
|
||||
|
||||
try {
|
||||
// Using BYOB reader allows reading an exact amount of bytes, which allows
|
||||
// passing the stream to react without creating a wrapped stream.
|
||||
reader = stream.getReader({ mode: "byob" });
|
||||
} catch (e) {
|
||||
return this.readCssMetadataFallback(stream);
|
||||
}
|
||||
|
||||
const header = (await reader.read(new Uint32Array(1))).value;
|
||||
if (!header) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Did not read all bytes! This is a bug in bun-framework-react");
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
const first = header?.[0];
|
||||
if (first !== undefined && first > 0) {
|
||||
const cssRaw = (await reader.read(new Uint8Array(first))).value;
|
||||
if (!cssRaw) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Did not read all bytes! This is a bug in bun-framework-react");
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
this.set(this.td.decode(cssRaw).split("\n"));
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
reader.releaseLock();
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like readCssMetadata, but does NOT mutate the current CSS list. It returns
|
||||
* the remaining stream after consuming the CSS header and the parsed list of
|
||||
* CSS hrefs so callers can preload styles without switching the active list.
|
||||
*/
|
||||
async readCssMetadataForPrefetch(
|
||||
stream: ReadableStream<Uint8Array<ArrayBuffer>>,
|
||||
): Promise<{ stream: ReadableStream<Uint8Array<ArrayBuffer>>; list: string[] }> {
|
||||
let reader: ReadableStreamBYOBReader;
|
||||
|
||||
try {
|
||||
reader = stream.getReader({ mode: "byob" });
|
||||
} catch (e) {
|
||||
const s = await this.readCssMetadataFallbackForPrefetch(stream);
|
||||
return { stream: s.stream, list: s.list };
|
||||
}
|
||||
|
||||
const header = (await reader.read(new Uint32Array(1))).value;
|
||||
if (!header) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Did not read all bytes! This is a bug in bun-framework-react");
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
const first = header?.[0];
|
||||
let list: string[] = [];
|
||||
if (first !== undefined && first > 0) {
|
||||
const cssRaw = (await reader.read(new Uint8Array(first))).value;
|
||||
if (!cssRaw) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Did not read all bytes! This is a bug in bun-framework-react");
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
list = this.td.decode(cssRaw).split("\n");
|
||||
}
|
||||
reader.releaseLock();
|
||||
return { stream, list };
|
||||
}
|
||||
|
||||
// Prefetch fallback variant that does not mutate currentCssList.
|
||||
async readCssMetadataFallbackForPrefetch(
|
||||
stream: ReadableStream<Uint8Array<ArrayBuffer>>,
|
||||
): Promise<{ stream: ReadableStream<Uint8Array<ArrayBuffer>>; list: string[] }> {
|
||||
const reader = stream.getReader();
|
||||
const chunks: Uint8Array<ArrayBuffer>[] = [];
|
||||
let totalBytes = 0;
|
||||
const readChunk = async (size: number) => {
|
||||
while (totalBytes < size) {
|
||||
const { value, done } = await reader.read();
|
||||
if (!done) {
|
||||
chunks.push(value);
|
||||
totalBytes += value.byteLength;
|
||||
} else if (totalBytes < size) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Not enough bytes, expected " + size + " but got " + totalBytes);
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunks.length === 1) {
|
||||
const first = chunks[0]!;
|
||||
if (first.byteLength >= size) {
|
||||
chunks[0] = first.subarray(size);
|
||||
totalBytes -= size;
|
||||
return first.subarray(0, size);
|
||||
} else {
|
||||
chunks.length = 0;
|
||||
totalBytes = 0;
|
||||
return first;
|
||||
}
|
||||
} else {
|
||||
const buffer = new Uint8Array(size);
|
||||
let i = 0;
|
||||
let chunk: Uint8Array<ArrayBuffer> | undefined;
|
||||
let len;
|
||||
while (size > 0) {
|
||||
chunk = chunks.shift();
|
||||
if (!chunk) continue;
|
||||
const { byteLength } = chunk;
|
||||
len = Math.min(byteLength, size);
|
||||
buffer.set(len === byteLength ? chunk : chunk.subarray(0, len), i);
|
||||
i += len;
|
||||
size -= len;
|
||||
}
|
||||
|
||||
if (chunk !== undefined && len !== undefined && chunk.byteLength > len) {
|
||||
chunks.unshift(chunk.subarray(len));
|
||||
}
|
||||
|
||||
totalBytes -= size;
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
const header = new Uint32Array(await readChunk(4))[0];
|
||||
let list: string[] = [];
|
||||
|
||||
if (header === 0) {
|
||||
list = [];
|
||||
} else if (header !== undefined) {
|
||||
list = this.td.decode(await readChunk(header)).split("\n");
|
||||
}
|
||||
|
||||
if (chunks.length === 0) {
|
||||
return { stream, list };
|
||||
}
|
||||
|
||||
// New readable stream that includes the remaining data
|
||||
const remainingStream = new ReadableStream<Uint8Array<ArrayBuffer>>({
|
||||
async start(controller) {
|
||||
for (const chunk of chunks) {
|
||||
controller.enqueue(chunk);
|
||||
}
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) {
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
controller.enqueue(value);
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
reader.cancel();
|
||||
},
|
||||
});
|
||||
|
||||
return { stream: remainingStream, list };
|
||||
}
|
||||
// Safari does not support BYOB reader. When this is resolved, this fallback
|
||||
// should be kept for a few years since Safari on iOS is versioned to the OS.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=283065
|
||||
async readCssMetadataFallback(
|
||||
stream: ReadableStream<Uint8Array<ArrayBuffer>>,
|
||||
): Promise<ReadableStream<Uint8Array<ArrayBuffer>>> {
|
||||
const reader = stream.getReader();
|
||||
const chunks: Uint8Array<ArrayBuffer>[] = [];
|
||||
let totalBytes = 0;
|
||||
const readChunk = async (size: number) => {
|
||||
while (totalBytes < size) {
|
||||
const { value, done } = await reader.read();
|
||||
if (!done) {
|
||||
chunks.push(value);
|
||||
totalBytes += value.byteLength;
|
||||
} else if (totalBytes < size) {
|
||||
if (import.meta.env.DEV) {
|
||||
throw new Error("Not enough bytes, expected " + size + " but got " + totalBytes);
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunks.length === 1) {
|
||||
const first = chunks[0]!;
|
||||
if (first.byteLength >= size) {
|
||||
chunks[0] = first.subarray(size);
|
||||
totalBytes -= size;
|
||||
return first.subarray(0, size);
|
||||
} else {
|
||||
chunks.length = 0;
|
||||
totalBytes = 0;
|
||||
return first;
|
||||
}
|
||||
} else {
|
||||
const buffer = new Uint8Array(size);
|
||||
let i = 0;
|
||||
let chunk: Uint8Array<ArrayBuffer> | undefined;
|
||||
let len;
|
||||
while (size > 0) {
|
||||
chunk = chunks.shift();
|
||||
if (!chunk) continue;
|
||||
const { byteLength } = chunk;
|
||||
len = Math.min(byteLength, size);
|
||||
buffer.set(len === byteLength ? chunk : chunk.subarray(0, len), i);
|
||||
i += len;
|
||||
size -= len;
|
||||
}
|
||||
|
||||
if (chunk !== undefined && len !== undefined && chunk.byteLength > len) {
|
||||
chunks.unshift(chunk.subarray(len));
|
||||
}
|
||||
|
||||
totalBytes -= size;
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
const header = new Uint32Array(await readChunk(4))[0];
|
||||
|
||||
if (header === 0) {
|
||||
this.clear();
|
||||
} else if (header !== undefined) {
|
||||
this.set(this.td.decode(await readChunk(header)).split("\n"));
|
||||
}
|
||||
|
||||
if (chunks.length === 0) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
// New readable stream that includes the remaining data
|
||||
return new ReadableStream<Uint8Array<ArrayBuffer>>({
|
||||
async start(controller) {
|
||||
for (const chunk of chunks) {
|
||||
controller.enqueue(chunk);
|
||||
}
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) {
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
controller.enqueue(value);
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
reader.cancel();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
0
packages/bun-framework-react/src/client/entry.tsx
Normal file
0
packages/bun-framework-react/src/client/entry.tsx
Normal file
3
packages/bun-framework-react/src/client/lib/util.ts
Normal file
3
packages/bun-framework-react/src/client/lib/util.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function isThenable<T>(payload: PromiseLike<T> | unknown): payload is PromiseLike<T> {
|
||||
return payload !== null && typeof payload === "object" && "then" in payload;
|
||||
}
|
||||
29
packages/bun-framework-react/src/client/root.tsx
Normal file
29
packages/bun-framework-react/src/client/root.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { use, useLayoutEffect, type ReactNode } from "react";
|
||||
import { useAppState } from "./app.ts";
|
||||
import { router } from "./constants.ts";
|
||||
import { isThenable } from "./lib/util.ts";
|
||||
|
||||
// This is a function component that uses the `use` hook, which unwraps a
|
||||
// promise. The promise results in a component containing suspense boundaries.
|
||||
// This is the same logic that happens on the server, except there is also a
|
||||
// hook to update the promise when the client navigates. The `Root` component
|
||||
// also updates CSS files when navigating between routes.
|
||||
export function Root(): ReactNode {
|
||||
const app = useAppState();
|
||||
|
||||
// Layout effects are executed right before the browser paints,
|
||||
// which is the perfect time to make CSS visible.
|
||||
useLayoutEffect(() => {
|
||||
if (app.abortOnRender) {
|
||||
try {
|
||||
app.abortOnRender.abort();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
router.css.disableUnusedCssFilesIfNeeded();
|
||||
});
|
||||
});
|
||||
|
||||
return isThenable(app.rsc) ? use(app.rsc) : app.rsc;
|
||||
}
|
||||
215
packages/bun-framework-react/src/client/router.ts
Normal file
215
packages/bun-framework-react/src/client/router.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
import { flushSync } from "react-dom";
|
||||
import { createFromReadableStream } from "../../vendor/react-server-dom-bun/client.browser.js";
|
||||
import { getAppState, setAppState, type AppState, type NonNullishReactNode } from "./app.ts";
|
||||
import { BakeCSSManager } from "./css.ts";
|
||||
|
||||
export interface CachedPage {
|
||||
css: string[];
|
||||
element: NonNullishReactNode;
|
||||
}
|
||||
|
||||
export class Router {
|
||||
private lastNavigationId: number = 0;
|
||||
private lastNavigationController: AbortController | null = null;
|
||||
|
||||
// Keep a cache of page objects to avoid re-fetching a page when pressing the
|
||||
// back button. The cache is indexed by the date it was created.
|
||||
private readonly cachedPages = new Map<number, CachedPage>();
|
||||
|
||||
// Track in-flight RSC fetches keyed by the resolved request URL so that
|
||||
// navigations can adopt an existing stream instead of issuing a duplicate
|
||||
// request.
|
||||
private readonly inflight = new Map<
|
||||
string,
|
||||
{ controller: AbortController; css: string[]; model: Promise<NonNullishReactNode> }
|
||||
>();
|
||||
|
||||
public readonly css: BakeCSSManager = new BakeCSSManager();
|
||||
|
||||
public hasNavigatedSinceDOMContentLoaded(): boolean {
|
||||
return this.lastNavigationId !== 0;
|
||||
}
|
||||
|
||||
public setCachedPage(id: number, page: CachedPage): void {
|
||||
this.cachedPages.set(id, page);
|
||||
}
|
||||
|
||||
/** Start fetching an RSC payload for a given href without committing UI. */
|
||||
public async prefetch(href: string): Promise<void> {
|
||||
const requestUrl = this.computeRequestUrl(href);
|
||||
|
||||
if (this.inflight.has(requestUrl)) return;
|
||||
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(requestUrl, {
|
||||
headers: { Accept: "text/x-component" },
|
||||
signal,
|
||||
});
|
||||
if (!response.ok) return;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse CSS list without mutating the active CSS set, and keep the stream
|
||||
// intact for React consumption.
|
||||
const { stream, list } = await this.css.readCssMetadataForPrefetch(response.body!);
|
||||
|
||||
const model = createFromReadableStream(stream) as Promise<NonNullishReactNode>;
|
||||
|
||||
this.inflight.set(requestUrl, { controller, css: list, model });
|
||||
|
||||
// Cleanup when the model settles to avoid leaks (if we never navigate).
|
||||
void model.finally(() => {
|
||||
// Do not delete if it's currently adopted by a navigation (i.e. lastNavigationController === controller)
|
||||
if (this.inflight.get(requestUrl)?.controller === controller) return;
|
||||
this.inflight.delete(requestUrl);
|
||||
});
|
||||
}
|
||||
|
||||
private computeRequestUrl(href: string): string {
|
||||
const url = new URL(href, location.href);
|
||||
url.hash = "";
|
||||
if (import.meta.env.STATIC) {
|
||||
// For static, fetch the .rsc artifact
|
||||
const path = url.pathname.replace(/\/(?:index)?$/, "") + "/index.rsc";
|
||||
return new URL(path + url.search, location.origin).toString();
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
async navigate(href: string, cacheId: number | undefined): Promise<void> {
|
||||
const thisNavigationId = ++this.lastNavigationId;
|
||||
const olderController = this.lastNavigationController;
|
||||
|
||||
// If there is an in-flight prefetch for this href, adopt it.
|
||||
const requestUrl = this.computeRequestUrl(href);
|
||||
const adopted = this.inflight.get(requestUrl);
|
||||
this.lastNavigationController = adopted?.controller ?? new AbortController();
|
||||
|
||||
const signal = this.lastNavigationController.signal;
|
||||
|
||||
signal.addEventListener(
|
||||
"abort",
|
||||
() => {
|
||||
olderController?.abort();
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
|
||||
// If the page is cached, use the cached promise instead of fetching it again.
|
||||
const cached = cacheId !== undefined && this.cachedPages.get(cacheId);
|
||||
if (cached) {
|
||||
await this.css.set(cached.css);
|
||||
|
||||
const state: AppState = {
|
||||
rsc: cached.element,
|
||||
};
|
||||
|
||||
if (olderController?.signal.aborted === false) {
|
||||
state.abortOnRender = olderController;
|
||||
}
|
||||
|
||||
setAppState(state);
|
||||
return;
|
||||
}
|
||||
|
||||
let p: NonNullishReactNode;
|
||||
if (adopted) {
|
||||
// Adopt prefetch: set CSS list and await the same model.
|
||||
await this.css.set(adopted.css);
|
||||
const cssWaitPromise = this.css.ensureCssIsReady();
|
||||
{
|
||||
const result = await adopted.model;
|
||||
if (result == null) {
|
||||
throw new Error("RSC payload was empty");
|
||||
}
|
||||
p = result as NonNullishReactNode;
|
||||
}
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
if (cssWaitPromise) {
|
||||
await cssWaitPromise;
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
}
|
||||
// Remove from inflight now that it's adopted
|
||||
this.inflight.delete(requestUrl);
|
||||
} else {
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(requestUrl, {
|
||||
headers: { Accept: "text/x-component" },
|
||||
signal,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch ${href}: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
} catch (err) {
|
||||
if (thisNavigationId === this.lastNavigationId) {
|
||||
// Bail out to browser navigation if this fetch fails.
|
||||
console.error(err);
|
||||
location.href = href;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
let stream = response.body!;
|
||||
stream = await this.css.readCssMetadata(stream);
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
|
||||
const cssWaitPromise = this.css.ensureCssIsReady();
|
||||
{
|
||||
const model = createFromReadableStream(stream) as Promise<NonNullishReactNode | undefined | null>;
|
||||
const result = await model;
|
||||
if (result == null) {
|
||||
throw new Error("RSC payload was empty");
|
||||
}
|
||||
p = result as NonNullishReactNode;
|
||||
}
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
if (cssWaitPromise) {
|
||||
await cssWaitPromise;
|
||||
if (thisNavigationId !== this.lastNavigationId) return;
|
||||
}
|
||||
}
|
||||
|
||||
// Save this promise so that pressing the back button in the browser navigates
|
||||
// to the same instance of the old page, instead of re-fetching it.
|
||||
if (cacheId !== undefined) {
|
||||
this.cachedPages.set(cacheId, {
|
||||
css: [...this.css.getList()],
|
||||
element: p,
|
||||
});
|
||||
}
|
||||
|
||||
// Defer aborting a previous request until VERY late. If a previous stream is
|
||||
// aborted while rendering, it will cancel the render, resulting in a flash of
|
||||
// a blank page.
|
||||
if (olderController?.signal.aborted === false) {
|
||||
getAppState().abortOnRender = olderController;
|
||||
}
|
||||
|
||||
// Tell react about the new page promise
|
||||
if (document.startViewTransition) {
|
||||
document.startViewTransition(() => {
|
||||
flushSync(() => {
|
||||
if (thisNavigationId === this.lastNavigationId) {
|
||||
setAppState(old => ({
|
||||
rsc: p,
|
||||
abortOnRender: olderController ?? old.abortOnRender,
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setAppState(old => ({
|
||||
rsc: p,
|
||||
abortOnRender: olderController ?? old.abortOnRender,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
39
packages/bun-framework-react/src/client/store.ts
Normal file
39
packages/bun-framework-react/src/client/store.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useSyncExternalStore, type SetStateAction } from "react";
|
||||
|
||||
export interface Store<T> {
|
||||
read(): T;
|
||||
write(value: SetStateAction<T>): void;
|
||||
subscribe(callback: () => void): () => boolean;
|
||||
}
|
||||
|
||||
function notify(set: Set<() => void>) {
|
||||
for (const callback of set) callback();
|
||||
}
|
||||
|
||||
export function store<T>(init: T): Store<T> {
|
||||
let value = init;
|
||||
const subscribers = new Set<() => void>();
|
||||
|
||||
return {
|
||||
read() {
|
||||
return value;
|
||||
},
|
||||
|
||||
write(next) {
|
||||
const current = this.read();
|
||||
const resolved = next instanceof Function ? next(current) : next;
|
||||
if (Object.is(current, resolved)) return;
|
||||
value = resolved;
|
||||
notify(subscribers);
|
||||
},
|
||||
|
||||
subscribe(callback) {
|
||||
subscribers.add(callback);
|
||||
return () => subscribers.delete(callback);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function useStore<T>(store: Store<T>): T {
|
||||
return useSyncExternalStore(store.subscribe, store.read, store.read);
|
||||
}
|
||||
31
packages/bun-framework-react/src/components/link.tsx
Normal file
31
packages/bun-framework-react/src/components/link.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import { router } from "../client/constants.ts";
|
||||
|
||||
export interface LinkProps extends React.ComponentProps<"a"> {
|
||||
/**
|
||||
* The URL to navigate to
|
||||
*/
|
||||
href: string;
|
||||
}
|
||||
|
||||
export function Link(props: LinkProps): React.JSX.Element {
|
||||
return (
|
||||
<a
|
||||
{...props}
|
||||
onMouseEnter={e => {
|
||||
void router.prefetch(props.href).catch(() => {});
|
||||
if (props.onMouseEnter) props.onMouseEnter(e);
|
||||
}}
|
||||
onClick={async e => {
|
||||
if (props.onClick) {
|
||||
await (props.onClick(e) as void | Promise<void>);
|
||||
if (e.defaultPrevented) return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
await router.navigate(props.href, undefined);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
// This file is loaded in the SSR graph, meaning the `react-server` condition is
|
||||
// no longer set. This means we can import client components, using `react-dom`
|
||||
// to perform Server-side rendering (creating HTML) out of the RSC payload.
|
||||
import { ssrManifest } from "bun:bake/server";
|
||||
import { ssrManifest } from "bun:app/server";
|
||||
import { EventEmitter } from "node:events";
|
||||
import type { Readable } from "node:stream";
|
||||
import * as React from "react";
|
||||
import type { RenderToPipeableStreamOptions } from "react-dom/server";
|
||||
import { renderToPipeableStream } from "react-dom/server.node";
|
||||
import { createFromNodeStream, type Manifest } from "react-server-dom-bun/client.node.unbundled.js";
|
||||
import type { MiniAbortSignal } from "./server";
|
||||
|
||||
// Verify that React 19 is being used.
|
||||
if (!React.use) {
|
||||
throw new Error("Bun's React integration requires React 19");
|
||||
}
|
||||
import type { MiniAbortSignal } from "./server.tsx";
|
||||
import { createFromNodeStream, type Manifest } from "./vendor/react-server-dom-bun/client.node.unbundled.js";
|
||||
|
||||
const createFromNodeStreamOptions: Manifest = {
|
||||
moduleMap: ssrManifest,
|
||||
@@ -34,27 +30,29 @@ const createFromNodeStreamOptions: Manifest = {
|
||||
// - https://github.com/devongovett/rsc-html-stream
|
||||
export function renderToHtml(
|
||||
rscPayload: Readable,
|
||||
bootstrapModules: readonly string[],
|
||||
bootstrapModules: string[],
|
||||
signal: MiniAbortSignal,
|
||||
): ReadableStream {
|
||||
// Bun supports a special type of readable stream type called "direct",
|
||||
// which provides a raw handle to the controller. We can bypass all of
|
||||
// the Web Streams API (slow) and use the controller directly.
|
||||
let stream: RscInjectionStream | null = null;
|
||||
let abort: () => void;
|
||||
let abort: (reason?: any) => void;
|
||||
return new ReadableStream({
|
||||
type: "direct",
|
||||
pull(controller) {
|
||||
// `createFromNodeStream` turns the RSC payload into a React component.
|
||||
const promise = createFromNodeStream(rscPayload, {
|
||||
// React takes in a manifest mapping client-side assets
|
||||
// to the imports needed for server-side rendering.
|
||||
moduleMap: ssrManifest,
|
||||
moduleLoading: { prefix: "/" },
|
||||
});
|
||||
const promise: Promise<React.ReactNode> = createFromNodeStream(rscPayload, createFromNodeStreamOptions);
|
||||
|
||||
// The root is this "Root" component that unwraps the streamed promise
|
||||
// with `use`, and then returning the parsed React component for the UI.
|
||||
const Root: any = () => React.use(promise);
|
||||
const Root: React.JSXElementConstructor<{}> = () => React.use(promise);
|
||||
|
||||
// If the signal is already aborted, we should not proceed
|
||||
if (signal.aborted) {
|
||||
controller.close(signal.aborted);
|
||||
return Promise.reject(signal.aborted);
|
||||
}
|
||||
|
||||
// If the signal is already aborted, we should not proceed
|
||||
if (signal.aborted) {
|
||||
@@ -64,13 +62,20 @@ export function renderToHtml(
|
||||
|
||||
// `renderToPipeableStream` is what actually generates HTML.
|
||||
// Here is where React is told what script tags to inject.
|
||||
let pipe: (stream: any) => void;
|
||||
let pipe: (stream: NodeJS.WritableStream) => void;
|
||||
|
||||
stream = new RscInjectionStream(rscPayload, controller);
|
||||
|
||||
({ pipe, abort } = renderToPipeableStream(<Root />, {
|
||||
bootstrapModules,
|
||||
onShellReady() {
|
||||
// The shell (including <head>) has been fully rendered
|
||||
stream?.onShellReady();
|
||||
},
|
||||
onError(error) {
|
||||
if (!signal.aborted) {
|
||||
// Abort the rendering and close the stream
|
||||
signal.aborted = error;
|
||||
signal.aborted = error as Error;
|
||||
abort();
|
||||
if (signal.abort) signal.abort();
|
||||
if (stream) {
|
||||
@@ -80,7 +85,6 @@ export function renderToHtml(
|
||||
},
|
||||
}));
|
||||
|
||||
stream = new RscInjectionStream(rscPayload, controller);
|
||||
pipe(stream);
|
||||
|
||||
return stream.finished;
|
||||
@@ -97,16 +101,22 @@ export function renderToHtml(
|
||||
|
||||
// Static builds can not stream suspense boundaries as they finish, but instead
|
||||
// produce a single HTML blob. The approach is otherwise similar to `renderToHtml`.
|
||||
export function renderToStaticHtml(rscPayload: Readable, bootstrapModules: readonly string[]): Promise<Blob> {
|
||||
export function renderToStaticHtml(
|
||||
rscPayload: Readable,
|
||||
bootstrapModules: NonNullable<RenderToPipeableStreamOptions["bootstrapModules"]>,
|
||||
): Promise<Blob> {
|
||||
const stream = new StaticRscInjectionStream(rscPayload);
|
||||
const promise = createFromNodeStream(rscPayload, createFromNodeStreamOptions);
|
||||
const Root = () => React.use(promise);
|
||||
const promise = createFromNodeStream<React.ReactNode>(rscPayload, createFromNodeStreamOptions);
|
||||
|
||||
const Root: React.JSXElementConstructor<{}> = () => React.use(promise);
|
||||
|
||||
const { pipe } = renderToPipeableStream(<Root />, {
|
||||
bootstrapModules,
|
||||
// Only begin flowing HTML once all of it is ready. This tells React
|
||||
// to not emit the flight chunks, just the entire HTML.
|
||||
onAllReady: () => pipe(stream),
|
||||
});
|
||||
|
||||
return stream.result;
|
||||
}
|
||||
|
||||
@@ -116,14 +126,14 @@ const continueScriptTag = "<script>__bun_f.push(";
|
||||
|
||||
const enum HtmlState {
|
||||
/** HTML is flowing, it is not an okay time to inject RSC data. */
|
||||
Flowing,
|
||||
Flowing = 1,
|
||||
/** It is safe to inject RSC data. */
|
||||
Boundary,
|
||||
}
|
||||
|
||||
const enum RscState {
|
||||
/** No RSC data has been written yet */
|
||||
Waiting,
|
||||
Waiting = 1,
|
||||
/** Some but not all RSC data has been written */
|
||||
Paused,
|
||||
/** All RSC data has been written */
|
||||
@@ -142,11 +152,13 @@ class RscInjectionStream extends EventEmitter {
|
||||
rscHasEnded = false;
|
||||
/** Shared state for decoding RSC data into UTF-8 strings */
|
||||
decoder = new TextDecoder("utf-8", { fatal: true });
|
||||
/** Track if the shell (including head) has been fully rendered */
|
||||
shellReady = false;
|
||||
|
||||
/** Resolved when all data is written */
|
||||
finished: Promise<void>;
|
||||
finalize: () => void;
|
||||
reject: (err: any) => void;
|
||||
reject: (err: unknown) => void;
|
||||
|
||||
constructor(rscPayload: Readable, controller: ReadableStreamDirectController) {
|
||||
super();
|
||||
@@ -154,7 +166,7 @@ class RscInjectionStream extends EventEmitter {
|
||||
|
||||
const { resolve, promise, reject } = Promise.withResolvers<void>();
|
||||
this.finished = promise;
|
||||
this.finalize = x => (controller.close(), resolve(x));
|
||||
this.finalize = () => (controller.close(), resolve());
|
||||
this.reject = reject;
|
||||
|
||||
rscPayload.on("data", this.writeRscData.bind(this));
|
||||
@@ -170,8 +182,12 @@ class RscInjectionStream extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
write(data: Uint8Array) {
|
||||
if (import.meta.env.DEV && process.env.VERBOSE_SSR)
|
||||
onShellReady() {
|
||||
this.shellReady = true;
|
||||
}
|
||||
|
||||
write(data: Uint8Array<ArrayBuffer>) {
|
||||
if (import.meta.env.DEV && process.env.VERBOSE_SSR) {
|
||||
console.write(
|
||||
"write" +
|
||||
Bun.inspect(
|
||||
@@ -182,6 +198,8 @@ class RscInjectionStream extends EventEmitter {
|
||||
) +
|
||||
"\n",
|
||||
);
|
||||
}
|
||||
|
||||
if (endsWithClosingScript(data)) {
|
||||
// The HTML is not done yet, but it's a suitible time to inject RSC data.
|
||||
const { controller } = this;
|
||||
@@ -256,12 +274,14 @@ class RscInjectionStream extends EventEmitter {
|
||||
|
||||
destroy(e) {}
|
||||
|
||||
end(e) {}
|
||||
end() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
class StaticRscInjectionStream extends EventEmitter {
|
||||
rscPayloadChunks: Uint8Array[] = [];
|
||||
chunks: (Uint8Array | string)[] = [];
|
||||
rscPayloadChunks: Uint8Array<ArrayBuffer>[] = [];
|
||||
chunks: (Uint8Array<ArrayBuffer> | string)[] = [];
|
||||
result: Promise<Blob>;
|
||||
finalize: (blob: Blob) => void;
|
||||
reject: (error: Error) => void;
|
||||
@@ -276,7 +296,7 @@ class StaticRscInjectionStream extends EventEmitter {
|
||||
rscPayload.on("data", chunk => this.rscPayloadChunks.push(chunk));
|
||||
}
|
||||
|
||||
write(chunk) {
|
||||
write(chunk: Uint8Array<ArrayBuffer>) {
|
||||
this.chunks.push(chunk);
|
||||
}
|
||||
|
||||
@@ -285,7 +305,7 @@ class StaticRscInjectionStream extends EventEmitter {
|
||||
const lastChunk = this.chunks[this.chunks.length - 1];
|
||||
|
||||
// Release assertions for React's behavior. If these break there will be malformed HTML.
|
||||
if (typeof lastChunk === "string") {
|
||||
if (typeof lastChunk === "string" || !lastChunk) {
|
||||
this.destroy(new Error("The last chunk was expected to be a Uint8Array"));
|
||||
return;
|
||||
}
|
||||
@@ -305,7 +325,7 @@ class StaticRscInjectionStream extends EventEmitter {
|
||||
// Ignore flush requests from React.
|
||||
}
|
||||
|
||||
destroy(error) {
|
||||
destroy(error: Error) {
|
||||
this.reject(error);
|
||||
}
|
||||
}
|
||||
@@ -336,7 +356,7 @@ function writeManyFlightScriptData(
|
||||
decoder: TextDecoder,
|
||||
controller: { write: (str: string) => void },
|
||||
) {
|
||||
if (chunks.length === 1) return writeSingleFlightScriptData(chunks[0], decoder, controller);
|
||||
if (chunks.length === 1) return writeSingleFlightScriptData(chunks[0]!, decoder, controller);
|
||||
|
||||
let i = 0;
|
||||
try {
|
||||
@@ -355,6 +375,7 @@ function writeManyFlightScriptData(
|
||||
controller.write('Uint8Array.from(atob("');
|
||||
for (; i < chunks.length; i++) {
|
||||
const chunk = chunks[i];
|
||||
if (!chunk) continue;
|
||||
const base64 = btoa(String.fromCodePoint(...chunk));
|
||||
controller.write(base64.slice(1, -1));
|
||||
}
|
||||
24
packages/bun-framework-react/tsconfig.json
Normal file
24
packages/bun-framework-react/tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"moduleResolution": "NodeNext",
|
||||
"module": "NodeNext",
|
||||
"target": "ESNext",
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"noImplicitOverride": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"isolatedModules": true,
|
||||
"isolatedDeclarations": true,
|
||||
"declaration": true,
|
||||
"jsx": "react-jsx"
|
||||
}
|
||||
}
|
||||
1
packages/bun-framework-react/vendor/.prettierignore
vendored
Normal file
1
packages/bun-framework-react/vendor/.prettierignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*
|
||||
21
packages/bun-framework-react/vendor/react-server-dom-bun/LICENSE
vendored
Normal file
21
packages/bun-framework-react/vendor/react-server-dom-bun/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
5
packages/bun-framework-react/vendor/react-server-dom-bun/README.md
vendored
Normal file
5
packages/bun-framework-react/vendor/react-server-dom-bun/README.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# react-server-dom-bun
|
||||
|
||||
Experimental React Flight bindings for DOM using Bun.
|
||||
|
||||
**Use it at your own risk.**
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1
packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.d.ts
vendored
Normal file
1
packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export function createFromReadableStream<T>(readable: ReadableStream<T>): Promise<T>;
|
||||
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.js
vendored
Normal file
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.browser.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.browser.development.js');
|
||||
}
|
||||
3
packages/bun-framework-react/vendor/react-server-dom-bun/client.js
vendored
Normal file
3
packages/bun-framework-react/vendor/react-server-dom-bun/client.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./client.browser');
|
||||
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.js
vendored
Normal file
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.node.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.node.development.js');
|
||||
}
|
||||
20
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.d.ts
vendored
Normal file
20
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { SSRManifest } from "bun:app/server";
|
||||
import type { Readable } from "node:stream";
|
||||
|
||||
export interface Manifest {
|
||||
moduleMap: SSRManifest;
|
||||
moduleLoading?: ModuleLoading;
|
||||
}
|
||||
|
||||
export interface ModuleLoading {
|
||||
prefix: string;
|
||||
crossOrigin?: string;
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
encodeFormAction?: any;
|
||||
findSourceMapURL?: any;
|
||||
environmentName?: string;
|
||||
}
|
||||
|
||||
export function createFromNodeStream<T = any>(readable: Readable, manifest?: Manifest): Promise<T>;
|
||||
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.js
vendored
Normal file
7
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.node.unbundled.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-server-dom-bun-client.node.unbundled.development.js');
|
||||
}
|
||||
3
packages/bun-framework-react/vendor/react-server-dom-bun/esm/package.json
vendored
Normal file
3
packages/bun-framework-react/vendor/react-server-dom-bun/esm/package.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
12
packages/bun-framework-react/vendor/react-server-dom-bun/index.js
vendored
Normal file
12
packages/bun-framework-react/vendor/react-server-dom-bun/index.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
throw new Error('Use react-server-dom-bun/client instead.');
|
||||
91
packages/bun-framework-react/vendor/react-server-dom-bun/package.json
vendored
Normal file
91
packages/bun-framework-react/vendor/react-server-dom-bun/package.json
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"name": "react-server-dom-bun",
|
||||
"description": "React Server Components bindings for DOM using Bun. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
|
||||
"version": "0.0.0-364a46e8-20250924",
|
||||
"keywords": [
|
||||
"react"
|
||||
],
|
||||
"homepage": "https://react.dev/",
|
||||
"bugs": "https://github.com/facebook/react/issues",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"index.js",
|
||||
"plugin.js",
|
||||
"client.js",
|
||||
"client.browser.js",
|
||||
"client.node.js",
|
||||
"client.node.unbundled.js",
|
||||
"server.js",
|
||||
"server.browser.js",
|
||||
"server.node.js",
|
||||
"server.node.unbundled.js",
|
||||
"static.js",
|
||||
"static.browser.js",
|
||||
"static.node.js",
|
||||
"static.node.unbundled.js",
|
||||
"node-register.js",
|
||||
"cjs/",
|
||||
"esm/"
|
||||
],
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./plugin": "./plugin.js",
|
||||
"./client": {
|
||||
"node": "./client.node.js",
|
||||
"browser": "./client.browser.js",
|
||||
"default": "./client.browser.js"
|
||||
},
|
||||
"./client.browser": "./client.browser.js",
|
||||
"./client.node": "./client.node.js",
|
||||
"./client.node.unbundled": "./client.node.unbundled.js",
|
||||
"./server": {
|
||||
"react-server": {
|
||||
"deno": "./server.browser.js",
|
||||
"node": {
|
||||
"webpack": "./server.node.js",
|
||||
"default": "./server.node.unbundled.js"
|
||||
},
|
||||
"browser": "./server.browser.js"
|
||||
},
|
||||
"default": "./server.js"
|
||||
},
|
||||
"./server.browser": "./server.browser.js",
|
||||
"./server.node": "./server.node.js",
|
||||
"./server.node.unbundled": "./server.node.unbundled.js",
|
||||
"./static": {
|
||||
"react-server": {
|
||||
"deno": "./static.browser.js",
|
||||
"node": {
|
||||
"webpack": "./static.node.js",
|
||||
"default": "./static.node.unbundled.js"
|
||||
},
|
||||
"browser": "./static.browser.js"
|
||||
},
|
||||
"default": "./static.js"
|
||||
},
|
||||
"./static.browser": "./static.browser.js",
|
||||
"./static.node": "./static.node.js",
|
||||
"./static.node.unbundled": "./static.node.unbundled.js",
|
||||
"./node-loader": "./esm/react-server-dom-webpack-node-loader.production.js",
|
||||
"./node-register": "./node-register.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/react.git",
|
||||
"directory": "packages/react-server-dom-bun"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "19.2.0-canary-364a46e8-20250924",
|
||||
"react-dom": "19.2.0-canary-364a46e8-20250924"
|
||||
},
|
||||
"dependencies": {
|
||||
"neo-async": "^2.6.1"
|
||||
}
|
||||
}
|
||||
3
packages/bun-framework-react/vendor/react-server-dom-bun/plugin.js
vendored
Normal file
3
packages/bun-framework-react/vendor/react-server-dom-bun/plugin.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./cjs/react-server-dom-bun-plugin.js');
|
||||
17
packages/bun-framework-react/vendor/react-server-dom-bun/server.browser.js
vendored
Normal file
17
packages/bun-framework-react/vendor/react-server-dom-bun/server.browser.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.browser.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.browser.development.js');
|
||||
}
|
||||
|
||||
exports.renderToReadableStream = s.renderToReadableStream;
|
||||
exports.decodeReply = s.decodeReply;
|
||||
exports.decodeAction = s.decodeAction;
|
||||
exports.decodeFormState = s.decodeFormState;
|
||||
exports.registerServerReference = s.registerServerReference;
|
||||
exports.registerClientReference = s.registerClientReference;
|
||||
exports.createClientModuleProxy = s.createClientModuleProxy;
|
||||
exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;
|
||||
6
packages/bun-framework-react/vendor/react-server-dom-bun/server.js
vendored
Normal file
6
packages/bun-framework-react/vendor/react-server-dom-bun/server.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
throw new Error(
|
||||
'The React Server Writer cannot be used outside a react-server environment. ' +
|
||||
'You must configure Node.js using the `--conditions react-server` flag.'
|
||||
);
|
||||
20
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.js
vendored
Normal file
20
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.development.js');
|
||||
}
|
||||
|
||||
exports.renderToReadableStream = s.renderToReadableStream;
|
||||
exports.renderToPipeableStream = s.renderToPipeableStream;
|
||||
exports.decodeReply = s.decodeReply;
|
||||
exports.decodeReplyFromBusboy = s.decodeReplyFromBusboy;
|
||||
exports.decodeReplyFromAsyncIterable = s.decodeReplyFromAsyncIterable;
|
||||
exports.decodeAction = s.decodeAction;
|
||||
exports.decodeFormState = s.decodeFormState;
|
||||
exports.registerServerReference = s.registerServerReference;
|
||||
exports.registerClientReference = s.registerClientReference;
|
||||
exports.createClientModuleProxy = s.createClientModuleProxy;
|
||||
exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;
|
||||
23
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts
vendored
Normal file
23
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { ServerManifest } from "bun:app/server";
|
||||
import type { ReactElement } from "react";
|
||||
|
||||
export interface PipeableStream<T> {
|
||||
/** Returns the input, which should match the Node.js writable interface */
|
||||
pipe: <T extends NodeJS.WritableStream>(destination: T) => T;
|
||||
abort: () => void;
|
||||
}
|
||||
|
||||
export function renderToPipeableStream<T = any>(
|
||||
model: ReactElement,
|
||||
webpackMap: ServerManifest,
|
||||
options?: RenderToPipeableStreamOptions,
|
||||
): PipeableStream<T>;
|
||||
|
||||
export interface RenderToPipeableStreamOptions {
|
||||
onError?: (error: Error) => void;
|
||||
identifierPrefix?: string;
|
||||
onPostpone?: () => void;
|
||||
temporaryReferences?: any;
|
||||
environmentName?: string;
|
||||
filterStackFrame?: () => boolean;
|
||||
}
|
||||
20
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.js
vendored
Normal file
20
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.unbundled.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.unbundled.development.js');
|
||||
}
|
||||
|
||||
exports.renderToReadableStream = s.renderToReadableStream;
|
||||
exports.renderToPipeableStream = s.renderToPipeableStream;
|
||||
exports.decodeReply = s.decodeReply;
|
||||
exports.decodeReplyFromBusboy = s.decodeReplyFromBusboy;
|
||||
exports.decodeReplyFromAsyncIterable = s.decodeReplyFromAsyncIterable;
|
||||
exports.decodeAction = s.decodeAction;
|
||||
exports.decodeFormState = s.decodeFormState;
|
||||
exports.registerServerReference = s.registerServerReference;
|
||||
exports.registerClientReference = s.registerClientReference;
|
||||
exports.createClientModuleProxy = s.createClientModuleProxy;
|
||||
exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;
|
||||
12
packages/bun-framework-react/vendor/react-server-dom-bun/static.browser.js
vendored
Normal file
12
packages/bun-framework-react/vendor/react-server-dom-bun/static.browser.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.browser.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.browser.development.js');
|
||||
}
|
||||
|
||||
if (s.unstable_prerender) {
|
||||
exports.unstable_prerender = s.unstable_prerender;
|
||||
}
|
||||
6
packages/bun-framework-react/vendor/react-server-dom-bun/static.js
vendored
Normal file
6
packages/bun-framework-react/vendor/react-server-dom-bun/static.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
throw new Error(
|
||||
'The React Server Writer cannot be used outside a react-server environment. ' +
|
||||
'You must configure Node.js using the `--conditions react-server` flag.'
|
||||
);
|
||||
15
packages/bun-framework-react/vendor/react-server-dom-bun/static.node.js
vendored
Normal file
15
packages/bun-framework-react/vendor/react-server-dom-bun/static.node.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.development.js');
|
||||
}
|
||||
|
||||
if (s.unstable_prerender) {
|
||||
exports.unstable_prerender = s.unstable_prerender;
|
||||
}
|
||||
if (s.unstable_prerenderToNodeStream) {
|
||||
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
|
||||
}
|
||||
12
packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js
vendored
Normal file
12
packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var s;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.unbundled.production.js');
|
||||
} else {
|
||||
s = require('./cjs/react-server-dom-bun-server.node.unbundled.development.js');
|
||||
}
|
||||
|
||||
if (s.unstable_prerenderToNodeStream) {
|
||||
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
|
||||
}
|
||||
1550
packages/bun-types/app.d.ts
vendored
Normal file
1550
packages/bun-types/app.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
packages/bun-types/bun.d.ts
vendored
8
packages/bun-types/bun.d.ts
vendored
@@ -5791,11 +5791,11 @@ declare module "bun" {
|
||||
* @category Process Management
|
||||
*
|
||||
* ```js
|
||||
* const subprocess = Bun.spawn({
|
||||
* const proc = Bun.spawn({
|
||||
* cmd: ["echo", "hello"],
|
||||
* stdout: "pipe",
|
||||
* });
|
||||
* const text = await readableStreamToText(subprocess.stdout);
|
||||
* const text = await proc.stdout.text();
|
||||
* console.log(text); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
@@ -5829,8 +5829,8 @@ declare module "bun" {
|
||||
* Spawn a new process
|
||||
*
|
||||
* ```js
|
||||
* const {stdout} = Bun.spawn(["echo", "hello"]);
|
||||
* const text = await readableStreamToText(stdout);
|
||||
* const proc = Bun.spawn(["echo", "hello"]);
|
||||
* const text = await proc.stdout.text();
|
||||
* console.log(text); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
|
||||
278
packages/bun-types/experimental.d.ts
vendored
278
packages/bun-types/experimental.d.ts
vendored
@@ -1,278 +0,0 @@
|
||||
declare module "bun" {
|
||||
export namespace __experimental {
|
||||
/**
|
||||
* Base interface for static site generation route parameters.
|
||||
*
|
||||
* Supports both single string values and arrays of strings for dynamic route segments.
|
||||
* This is typically used for route parameters like `[slug]`, `[...rest]`, or `[id]`.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Simple slug parameter
|
||||
* type BlogParams = { slug: string };
|
||||
*
|
||||
* // Multiple parameters
|
||||
* type ProductParams = {
|
||||
* category: string;
|
||||
* id: string;
|
||||
* };
|
||||
*
|
||||
* // Catch-all routes with string arrays
|
||||
* type DocsParams = {
|
||||
* path: string[];
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export interface SSGParamsLike {
|
||||
[key: string]: string | string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object for a single static route to be generated.
|
||||
*
|
||||
* Each path object contains the parameters needed to render a specific
|
||||
* instance of a dynamic route at build time.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @template Params - The shape of route parameters for this path
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Single blog post path
|
||||
* const blogPath: SSGPath<{ slug: string }> = {
|
||||
* params: { slug: "my-first-post" }
|
||||
* };
|
||||
*
|
||||
* // Product page with multiple params
|
||||
* const productPath: SSGPath<{ category: string; id: string }> = {
|
||||
* params: {
|
||||
* category: "electronics",
|
||||
* id: "laptop-123"
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* // Documentation with catch-all route
|
||||
* const docsPath: SSGPath<{ path: string[] }> = {
|
||||
* params: { path: ["getting-started", "installation"] }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export interface SSGPath<Params extends SSGParamsLike = SSGParamsLike> {
|
||||
params: Params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array of static paths to be generated at build time.
|
||||
*
|
||||
* This type represents the collection of all route configurations
|
||||
* that should be pre-rendered for a dynamic route.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @template Params - The shape of route parameters for these paths
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Array of blog post paths
|
||||
* const blogPaths: SSGPaths<{ slug: string }> = [
|
||||
* { params: { slug: "introduction-to-bun" } },
|
||||
* { params: { slug: "performance-benchmarks" } },
|
||||
* { params: { slug: "getting-started-guide" } }
|
||||
* ];
|
||||
*
|
||||
* // Mixed parameter types
|
||||
* const productPaths: SSGPaths<{ category: string; id: string }> = [
|
||||
* { params: { category: "books", id: "javascript-guide" } },
|
||||
* { params: { category: "electronics", id: "smartphone-x" } }
|
||||
* ];
|
||||
* ```
|
||||
*/
|
||||
export type SSGPaths<Params extends SSGParamsLike = SSGParamsLike> = SSGPath<Params>[];
|
||||
|
||||
/**
|
||||
* Props interface for SSG page components.
|
||||
*
|
||||
* This interface defines the shape of props that will be passed to your
|
||||
* static page components during the build process. The `params` object
|
||||
* contains the route parameters extracted from the URL pattern.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @template Params - The shape of route parameters for this page
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Blog post component props
|
||||
* interface BlogPageProps extends SSGPageProps<{ slug: string }> {
|
||||
* // params: { slug: string } is automatically included
|
||||
* }
|
||||
*
|
||||
* // Product page component props
|
||||
* interface ProductPageProps extends SSGPageProps<{
|
||||
* category: string;
|
||||
* id: string;
|
||||
* }> {
|
||||
* // params: { category: string; id: string } is automatically included
|
||||
* }
|
||||
*
|
||||
* // Usage in component
|
||||
* function BlogPost({ params }: BlogPageProps) {
|
||||
* const { slug } = params; // TypeScript knows slug is a string
|
||||
* return <h1>Blog post: {slug}</h1>;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface SSGPageProps<Params extends SSGParamsLike = SSGParamsLike> {
|
||||
params: Params;
|
||||
}
|
||||
|
||||
/**
|
||||
* React component type for SSG pages that can be statically generated.
|
||||
*
|
||||
* This type represents a React component that receives SSG page props
|
||||
* and can be rendered at build time. The component can be either a regular
|
||||
* React component or an async React Server Component for advanced use cases
|
||||
* like data fetching during static generation.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @template Params - The shape of route parameters for this page component
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Regular synchronous SSG page component
|
||||
* const BlogPost: SSGPage<{ slug: string }> = ({ params }) => {
|
||||
* return (
|
||||
* <article>
|
||||
* <h1>Blog Post: {params.slug}</h1>
|
||||
* <p>This content was generated at build time!</p>
|
||||
* </article>
|
||||
* );
|
||||
* };
|
||||
*
|
||||
* // Async React Server Component for data fetching
|
||||
* const AsyncBlogPost: SSGPage<{ slug: string }> = async ({ params }) => {
|
||||
* // Fetch data during static generation
|
||||
* const post = await fetchBlogPost(params.slug);
|
||||
* const author = await fetchAuthor(post.authorId);
|
||||
*
|
||||
* return (
|
||||
* <article>
|
||||
* <h1>{post.title}</h1>
|
||||
* <p>By {author.name}</p>
|
||||
* <div dangerouslySetInnerHTML={{ __html: post.content }} />
|
||||
* </article>
|
||||
* );
|
||||
* };
|
||||
*
|
||||
* // Product page with multiple params and async data fetching
|
||||
* const ProductPage: SSGPage<{ category: string; id: string }> = async ({ params }) => {
|
||||
* const [product, reviews] = await Promise.all([
|
||||
* fetchProduct(params.category, params.id),
|
||||
* fetchProductReviews(params.id)
|
||||
* ]);
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <h1>{product.name}</h1>
|
||||
* <p>Category: {params.category}</p>
|
||||
* <p>Price: ${product.price}</p>
|
||||
* <div>
|
||||
* <h2>Reviews ({reviews.length})</h2>
|
||||
* {reviews.map(review => (
|
||||
* <div key={review.id}>{review.comment}</div>
|
||||
* ))}
|
||||
* </div>
|
||||
* </div>
|
||||
* );
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export type SSGPage<Params extends SSGParamsLike = SSGParamsLike> = import("react").ComponentType<
|
||||
SSGPageProps<Params>
|
||||
>;
|
||||
|
||||
/**
|
||||
* getStaticPaths is Bun's implementation of SSG (Static Site Generation) path determination.
|
||||
*
|
||||
* This function is called at your app's build time to determine which
|
||||
* dynamic routes should be pre-rendered as static pages. It returns an
|
||||
* array of path parameters that will be used to generate static pages for
|
||||
* dynamic routes (e.g., [slug].tsx, [category]/[id].tsx).
|
||||
*
|
||||
* The function can be either synchronous or asynchronous, allowing you to
|
||||
* fetch data from APIs, databases, or file systems to determine which paths
|
||||
* should be statically generated.
|
||||
*
|
||||
* @warning These APIs are experimental and might be moved/changed in future releases.
|
||||
*
|
||||
* @template Params - The shape of route parameters for the dynamic route
|
||||
*
|
||||
* @returns An object containing an array of paths to be statically generated
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // In pages/blog/[slug].tsx ———————————————————╮
|
||||
* export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => {
|
||||
* // Fetch all blog posts from your CMS or API at build time
|
||||
* const posts = await fetchBlogPosts();
|
||||
*
|
||||
* return {
|
||||
* paths: posts.map((post) => ({
|
||||
* params: { slug: post.slug }
|
||||
* }))
|
||||
* };
|
||||
* };
|
||||
*
|
||||
* // In pages/products/[category]/[id].tsx
|
||||
* export const getStaticPaths: GetStaticPaths<{
|
||||
* category: string;
|
||||
* id: string;
|
||||
* }> = async () => {
|
||||
* // Fetch products from database
|
||||
* const products = await db.products.findMany({
|
||||
* select: { id: true, category: { slug: true } }
|
||||
* });
|
||||
*
|
||||
* return {
|
||||
* paths: products.map(product => ({
|
||||
* params: {
|
||||
* category: product.category.slug,
|
||||
* id: product.id
|
||||
* }
|
||||
* }))
|
||||
* };
|
||||
* };
|
||||
*
|
||||
* // In pages/docs/[...path].tsx (catch-all route)
|
||||
* export const getStaticPaths: GetStaticPaths<{ path: string[] }> = async () => {
|
||||
* // Read documentation structure from file system
|
||||
* const docPaths = await getDocumentationPaths('./content/docs');
|
||||
*
|
||||
* return {
|
||||
* paths: docPaths.map(docPath => ({
|
||||
* params: { path: docPath.split('/') }
|
||||
* }))
|
||||
* };
|
||||
* };
|
||||
*
|
||||
* // Synchronous example with static data
|
||||
* export const getStaticPaths: GetStaticPaths<{ id: string }> = () => {
|
||||
* const staticIds = ['1', '2', '3', '4', '5'];
|
||||
*
|
||||
* return {
|
||||
* paths: staticIds.map(id => ({
|
||||
* params: { id }
|
||||
* }))
|
||||
* };
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export type GetStaticPaths<Params extends SSGParamsLike = SSGParamsLike> = () => MaybePromise<{
|
||||
paths: SSGPaths<Params>;
|
||||
}>;
|
||||
}
|
||||
}
|
||||
2
packages/bun-types/index.d.ts
vendored
2
packages/bun-types/index.d.ts
vendored
@@ -20,10 +20,10 @@
|
||||
/// <reference path="./deprecated.d.ts" />
|
||||
/// <reference path="./redis.d.ts" />
|
||||
/// <reference path="./shell.d.ts" />
|
||||
/// <reference path="./experimental.d.ts" />
|
||||
/// <reference path="./serve.d.ts" />
|
||||
/// <reference path="./sql.d.ts" />
|
||||
/// <reference path="./security.d.ts" />
|
||||
/// <reference path="./app.d.ts" />
|
||||
|
||||
/// <reference path="./bun.ns.d.ts" />
|
||||
|
||||
|
||||
10
packages/bun-types/serve.d.ts
vendored
10
packages/bun-types/serve.d.ts
vendored
@@ -202,6 +202,16 @@ declare module "bun" {
|
||||
*/
|
||||
isSubscribed(topic: string): boolean;
|
||||
|
||||
/**
|
||||
* Returns an array of all topics the client is currently subscribed to.
|
||||
*
|
||||
* @example
|
||||
* ws.subscribe("chat");
|
||||
* ws.subscribe("notifications");
|
||||
* console.log(ws.subscriptions); // ["chat", "notifications"]
|
||||
*/
|
||||
readonly subscriptions: string[];
|
||||
|
||||
/**
|
||||
* Batches `send()` and `publish()` operations, which makes it faster to send data.
|
||||
*
|
||||
|
||||
22
packages/bun-types/test.d.ts
vendored
22
packages/bun-types/test.d.ts
vendored
@@ -358,6 +358,28 @@ declare module "bun:test" {
|
||||
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
|
||||
options?: HookOptions,
|
||||
): void;
|
||||
/**
|
||||
* Runs a function after a test finishes, including after all afterEach hooks.
|
||||
*
|
||||
* This is useful for cleanup tasks that need to run at the very end of a test,
|
||||
* after all other hooks have completed.
|
||||
*
|
||||
* Can only be called inside a test, not in describe blocks.
|
||||
*
|
||||
* @example
|
||||
* test("my test", () => {
|
||||
* onTestFinished(() => {
|
||||
* // This runs after all afterEach hooks
|
||||
* console.log("Test finished!");
|
||||
* });
|
||||
* });
|
||||
*
|
||||
* @param fn the function to run
|
||||
*/
|
||||
export function onTestFinished(
|
||||
fn: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
|
||||
options?: HookOptions,
|
||||
): void;
|
||||
/**
|
||||
* Sets the default timeout for all tests in the current file. If a test specifies a timeout, it will
|
||||
* override this value. The default timeout is 5000ms (5 seconds).
|
||||
|
||||
@@ -203,8 +203,6 @@ STACK_OF(X509) *us_get_root_extra_cert_instances() {
|
||||
}
|
||||
|
||||
STACK_OF(X509) *us_get_root_system_cert_instances() {
|
||||
if (!us_should_use_system_ca())
|
||||
return NULL;
|
||||
// Ensure single-path initialization via us_internal_init_root_certs
|
||||
auto certs = us_get_default_ca_certificates();
|
||||
return certs->root_system_cert_instances;
|
||||
@@ -216,13 +214,9 @@ extern "C" X509_STORE *us_get_default_ca_store() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Only load system default paths when NODE_USE_SYSTEM_CA=1
|
||||
// Otherwise, rely on bundled certificates only (like Node.js behavior)
|
||||
if (us_should_use_system_ca()) {
|
||||
if (!X509_STORE_set_default_paths(store)) {
|
||||
X509_STORE_free(store);
|
||||
return NULL;
|
||||
}
|
||||
if (!X509_STORE_set_default_paths(store)) {
|
||||
X509_STORE_free(store);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
us_default_ca_certificates *default_ca_certificates = us_get_default_ca_certificates();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user